/**CFile**************************************************************** FileName [fraigVec.c] PackageName [FRAIG: Functionally reduced AND-INV graphs.] Synopsis [Vector of FRAIG nodes.] Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>] Affiliation [UC Berkeley] Date [Ver. 2.0. Started - October 1, 2004] Revision [$Id: fraigVec.c,v 1.7 2005/07/08 01:01:34 alanmi Exp $] ***********************************************************************/ #include "fraigInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Allocates a vector with the given capacity.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fraig_NodeVec_t * Fraig_NodeVecAlloc( int nCap ) { Fraig_NodeVec_t * p; p = ABC_ALLOC( Fraig_NodeVec_t, 1 ); if ( nCap > 0 && nCap < 8 ) nCap = 8; p->nSize = 0; p->nCap = nCap; p->pArray = p->nCap? ABC_ALLOC( Fraig_Node_t *, p->nCap ) : NULL; return p; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecFree( Fraig_NodeVec_t * p ) { ABC_FREE( p->pArray ); ABC_FREE( p ); } /**Function************************************************************* Synopsis [Duplicates the integer array.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fraig_NodeVec_t * Fraig_NodeVecDup( Fraig_NodeVec_t * pVec ) { Fraig_NodeVec_t * p; p = ABC_ALLOC( Fraig_NodeVec_t, 1 ); p->nSize = pVec->nSize; p->nCap = pVec->nCap; p->pArray = p->nCap? ABC_ALLOC( Fraig_Node_t *, p->nCap ) : NULL; memcpy( p->pArray, pVec->pArray, sizeof(Fraig_Node_t *) * pVec->nSize ); return p; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fraig_Node_t ** Fraig_NodeVecReadArray( Fraig_NodeVec_t * p ) { return p->pArray; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecReadSize( Fraig_NodeVec_t * p ) { return p->nSize; } /**Function************************************************************* Synopsis [Resizes the vector to the given capacity.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecGrow( Fraig_NodeVec_t * p, int nCapMin ) { if ( p->nCap >= nCapMin ) return; p->pArray = ABC_REALLOC( Fraig_Node_t *, p->pArray, nCapMin ); p->nCap = nCapMin; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecShrink( Fraig_NodeVec_t * p, int nSizeNew ) { assert( p->nSize >= nSizeNew ); p->nSize = nSizeNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecClear( Fraig_NodeVec_t * p ) { p->nSize = 0; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecPush( Fraig_NodeVec_t * p, Fraig_Node_t * Entry ) { if ( p->nSize == p->nCap ) { if ( p->nCap < 16 ) Fraig_NodeVecGrow( p, 16 ); else Fraig_NodeVecGrow( p, 2 * p->nCap ); } p->pArray[p->nSize++] = Entry; } /**Function************************************************************* Synopsis [Add the element while ensuring uniqueness.] Description [Returns 1 if the element was found, and 0 if it was new. ] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecPushUnique( Fraig_NodeVec_t * p, Fraig_Node_t * Entry ) { int i; for ( i = 0; i < p->nSize; i++ ) if ( p->pArray[i] == Entry ) return 1; Fraig_NodeVecPush( p, Entry ); return 0; } /**Function************************************************************* Synopsis [Inserts a new node in the order by arrival times.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecPushOrder( Fraig_NodeVec_t * p, Fraig_Node_t * pNode ) { Fraig_Node_t * pNode1, * pNode2; int i; Fraig_NodeVecPush( p, pNode ); // find the p of the node for ( i = p->nSize-1; i > 0; i-- ) { pNode1 = p->pArray[i ]; pNode2 = p->pArray[i-1]; if ( pNode1 >= pNode2 ) break; p->pArray[i ] = pNode2; p->pArray[i-1] = pNode1; } } /**Function************************************************************* Synopsis [Add the element while ensuring uniqueness in the order.] Description [Returns 1 if the element was found, and 0 if it was new. ] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecPushUniqueOrder( Fraig_NodeVec_t * p, Fraig_Node_t * pNode ) { int i; for ( i = 0; i < p->nSize; i++ ) if ( p->pArray[i] == pNode ) return 1; Fraig_NodeVecPushOrder( p, pNode ); return 0; } /**Function************************************************************* Synopsis [Inserts a new node in the order by arrival times.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecPushOrderByLevel( Fraig_NodeVec_t * p, Fraig_Node_t * pNode ) { Fraig_Node_t * pNode1, * pNode2; int i; Fraig_NodeVecPush( p, pNode ); // find the p of the node for ( i = p->nSize-1; i > 0; i-- ) { pNode1 = p->pArray[i ]; pNode2 = p->pArray[i-1]; if ( Fraig_Regular(pNode1)->Level <= Fraig_Regular(pNode2)->Level ) break; p->pArray[i ] = pNode2; p->pArray[i-1] = pNode1; } } /**Function************************************************************* Synopsis [Add the element while ensuring uniqueness in the order.] Description [Returns 1 if the element was found, and 0 if it was new. ] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecPushUniqueOrderByLevel( Fraig_NodeVec_t * p, Fraig_Node_t * pNode ) { int i; for ( i = 0; i < p->nSize; i++ ) if ( p->pArray[i] == pNode ) return 1; Fraig_NodeVecPushOrderByLevel( p, pNode ); return 0; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fraig_Node_t * Fraig_NodeVecPop( Fraig_NodeVec_t * p ) { return p->pArray[--p->nSize]; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecRemove( Fraig_NodeVec_t * p, Fraig_Node_t * Entry ) { int i; for ( i = 0; i < p->nSize; i++ ) if ( p->pArray[i] == Entry ) break; assert( i < p->nSize ); for ( i++; i < p->nSize; i++ ) p->pArray[i-1] = p->pArray[i]; p->nSize--; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecWriteEntry( Fraig_NodeVec_t * p, int i, Fraig_Node_t * Entry ) { assert( i >= 0 && i < p->nSize ); p->pArray[i] = Entry; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fraig_Node_t * Fraig_NodeVecReadEntry( Fraig_NodeVec_t * p, int i ) { assert( i >= 0 && i < p->nSize ); return p->pArray[i]; } /**Function************************************************************* Synopsis [Comparison procedure for two clauses.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecCompareLevelsIncreasing( Fraig_Node_t ** pp1, Fraig_Node_t ** pp2 ) { int Level1 = Fraig_Regular(*pp1)->Level; int Level2 = Fraig_Regular(*pp2)->Level; if ( Level1 < Level2 ) return -1; if ( Level1 > Level2 ) return 1; return 0; } /**Function************************************************************* Synopsis [Comparison procedure for two clauses.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecCompareLevelsDecreasing( Fraig_Node_t ** pp1, Fraig_Node_t ** pp2 ) { int Level1 = Fraig_Regular(*pp1)->Level; int Level2 = Fraig_Regular(*pp2)->Level; if ( Level1 > Level2 ) return -1; if ( Level1 < Level2 ) return 1; return 0; } /**Function************************************************************* Synopsis [Comparison procedure for two clauses.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecCompareNumbers( Fraig_Node_t ** pp1, Fraig_Node_t ** pp2 ) { int Num1 = Fraig_Regular(*pp1)->Num; int Num2 = Fraig_Regular(*pp2)->Num; if ( Num1 < Num2 ) return -1; if ( Num1 > Num2 ) return 1; return 0; } /**Function************************************************************* Synopsis [Comparison procedure for two clauses.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fraig_NodeVecCompareRefCounts( Fraig_Node_t ** pp1, Fraig_Node_t ** pp2 ) { int nRefs1 = Fraig_Regular(*pp1)->nRefs; int nRefs2 = Fraig_Regular(*pp2)->nRefs; if ( nRefs1 < nRefs2 ) return -1; if ( nRefs1 > nRefs2 ) return 1; nRefs1 = Fraig_Regular(*pp1)->Level; nRefs2 = Fraig_Regular(*pp2)->Level; if ( nRefs1 < nRefs2 ) return -1; if ( nRefs1 > nRefs2 ) return 1; return 0; } /**Function************************************************************* Synopsis [Sorting the entries by their integer value.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecSortByLevel( Fraig_NodeVec_t * p, int fIncreasing ) { if ( fIncreasing ) qsort( (void *)p->pArray, p->nSize, sizeof(Fraig_Node_t *), (int (*)(const void *, const void *)) Fraig_NodeVecCompareLevelsIncreasing ); else qsort( (void *)p->pArray, p->nSize, sizeof(Fraig_Node_t *), (int (*)(const void *, const void *)) Fraig_NodeVecCompareLevelsDecreasing ); } /**Function************************************************************* Synopsis [Sorting the entries by their integer value.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecSortByNumber( Fraig_NodeVec_t * p ) { qsort( (void *)p->pArray, p->nSize, sizeof(Fraig_Node_t *), (int (*)(const void *, const void *)) Fraig_NodeVecCompareNumbers ); } /**Function************************************************************* Synopsis [Sorting the entries by their integer value.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_NodeVecSortByRefCount( Fraig_NodeVec_t * p ) { qsort( (void *)p->pArray, p->nSize, sizeof(Fraig_Node_t *), (int (*)(const void *, const void *)) Fraig_NodeVecCompareRefCounts ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END