diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2005-07-29 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2005-07-29 08:01:00 -0700 |
commit | 888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc (patch) | |
tree | 11d48c9e9069f54dc300c3571ae63c744c802c50 /src/sat/fraig/fraigFeed.c | |
parent | 7f94414388cce67bd3cc1a6d6269f0ed31ed0d06 (diff) | |
download | abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.gz abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.bz2 abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.zip |
Version abc50729
Diffstat (limited to 'src/sat/fraig/fraigFeed.c')
-rw-r--r-- | src/sat/fraig/fraigFeed.c | 772 |
1 files changed, 772 insertions, 0 deletions
diff --git a/src/sat/fraig/fraigFeed.c b/src/sat/fraig/fraigFeed.c new file mode 100644 index 00000000..0a950aba --- /dev/null +++ b/src/sat/fraig/fraigFeed.c @@ -0,0 +1,772 @@ +/**CFile**************************************************************** + + FileName [fraigFeed.c] + + PackageName [FRAIG: Functionally reduced AND-INV graphs.] + + Synopsis [Procedures to support the solver feedback.] + + Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>] + + Affiliation [UC Berkeley] + + Date [Ver. 2.0. Started - October 1, 2004] + + Revision [$Id: fraigFeed.c,v 1.8 2005/07/08 01:01:31 alanmi Exp $] + +***********************************************************************/ + +#include "fraigInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars ); +static int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi ); +static void Fraig_FeedBackVerify( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew ); + +static void Fraig_FeedBackCovering( Fraig_Man_t * p, Msat_IntVec_t * vPats ); +static Fraig_NodeVec_t * Fraig_FeedBackCoveringStart( Fraig_Man_t * pMan ); +static int Fraig_GetSmallestColumn( int * pHits, int nHits ); +static int Fraig_GetHittingPattern( unsigned * pSims, int nWords ); +static void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat ); +static void Fraig_FeedBackCheckTable( Fraig_Man_t * p ); +static void Fraig_FeedBackCheckTableF0( Fraig_Man_t * p ); +static void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Initializes the feedback information.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBackInit( Fraig_Man_t * p ) +{ + p->vCones = Fraig_NodeVecAlloc( 500 ); + p->vPatsReal = Msat_IntVecAlloc( 1000 ); + p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims ); + memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna ); + p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims ); + p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims ); +} + +/**Function************************************************************* + + Synopsis [Processes the feedback from teh solver.] + + Description [Array pModel gives the value of each variable in the SAT + solver. Array vVars is the array of integer numbers of variables + involves in this conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBack( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars, Fraig_Node_t * pOld, Fraig_Node_t * pNew ) +{ + int nVarsPi, nWords; + int i, clk = clock(); + + // get the number of PI vars in the feedback (also sets the PI values) + nVarsPi = Fraig_FeedBackPrepare( p, pModel, vVars ); + + // set the PI values + nWords = Fraig_FeedBackInsert( p, nVarsPi ); + assert( p->iWordStart + nWords <= p->nWordsDyna ); + + // resimulates the words from p->iWordStart to iWordStop + for ( i = 1; i < p->vNodes->nSize; i++ ) + if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) ) + Fraig_NodeSimulate( p->vNodes->pArray[i], p->iWordStart, p->iWordStart + nWords, 0 ); + + if ( p->fDoSparse ) + Fraig_TableRehashF0( p, 0 ); + + if ( !p->fChoicing ) + Fraig_FeedBackVerify( p, pOld, pNew ); + + // if there is no room left, compress the patterns + if ( p->iWordStart + nWords == p->nWordsDyna ) + p->iWordStart = Fraig_FeedBackCompress( p ); + else // otherwise, update the starting word + p->iWordStart += nWords; + +p->timeFeed += clock() - clk; +} + +/**Function************************************************************* + + Synopsis [Get the number and values of the PI variables.] + + Description [Returns the number of PI variables involved in this feedback. + Fills in the internal presence and value data for the primary inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars ) +{ + Fraig_Node_t * pNode; + int i, nVars, nVarsPis, * pVars; + + // clean the presence flag for all PIs + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + pNode = p->vInputs->pArray[i]; + pNode->fFeedUse = 0; + } + + // get the variables involved in the feedback + nVars = Msat_IntVecReadSize(vVars); + pVars = Msat_IntVecReadArray(vVars); + + // set the values for the present variables + nVarsPis = 0; + for ( i = 0; i < nVars; i++ ) + { + pNode = p->vNodes->pArray[ pVars[i] ]; + if ( !Fraig_NodeIsVar(pNode) ) + continue; + // set its value + pNode->fFeedUse = 1; + pNode->fFeedVal = !MSAT_LITSIGN(pModel[pVars[i]]); + nVarsPis++; + } + return nVarsPis; +} + +/**Function************************************************************* + + Synopsis [Inserts the new simulation patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi ) +{ + Fraig_Node_t * pNode; + int nWords, iPatFlip, nPatFlipLimit, i, w; + int fUseNoPats = 0; + int fUse2Pats = 0; + + // get the number of words + if ( fUse2Pats ) + nWords = FRAIG_NUM_WORDS( 2 * nVarsPi + 1 ); + else if ( fUseNoPats ) + nWords = 1; + else + nWords = FRAIG_NUM_WORDS( nVarsPi + 1 ); + // update the number of words if they do not fit into the simulation info + if ( nWords > p->nWordsDyna - p->iWordStart ) + nWords = p->nWordsDyna - p->iWordStart; + // determine the bound on the flipping bit + nPatFlipLimit = nWords * 32 - 2; + + // mark the real pattern + Msat_IntVecPush( p->vPatsReal, p->iWordStart * 32 ); + // record the real pattern + Fraig_BitStringSetBit( p->pSimsReal, p->iWordStart * 32 ); + + // set the values at the PIs + iPatFlip = 1; + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + pNode = p->vInputs->pArray[i]; + for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ ) + if ( !pNode->fFeedUse ) + pNode->puSimD[w] = FRAIG_RANDOM_UNSIGNED; + else if ( pNode->fFeedVal ) + pNode->puSimD[w] = FRAIG_FULL; + else // if ( !pNode->fFeedVal ) + pNode->puSimD[w] = 0; + + if ( fUse2Pats ) + { + // flip two patterns + if ( pNode->fFeedUse && 2 * iPatFlip < nPatFlipLimit ) + { + Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip - 1 ); + Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip ); + Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip + 1 ); + iPatFlip++; + } + } + else if ( fUseNoPats ) + { + } + else + { + // flip the diagonal + if ( pNode->fFeedUse && iPatFlip < nPatFlipLimit ) + { + Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, iPatFlip ); + iPatFlip++; + // Extra_PrintBinary( stdout, &pNode->puSimD, 45 ); printf( "\n" ); + } + } + // clean the use mask + pNode->fFeedUse = 0; + + // add the info to the D hash value of the PIs + for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ ) + pNode->uHashD ^= pNode->puSimD[w] * s_FraigPrimes[w]; + + } + return nWords; +} + + +/**Function************************************************************* + + Synopsis [Checks that the SAT solver pattern indeed distinquishes the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBackVerify( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew ) +{ + int fValue1, fValue2, iPat; + iPat = Msat_IntVecReadEntry( p->vPatsReal, Msat_IntVecReadSize(p->vPatsReal)-1 ); + fValue1 = (Fraig_BitStringHasBit( pOld->puSimD, iPat )); + fValue2 = (Fraig_BitStringHasBit( pNew->puSimD, iPat )); +/* +Fraig_PrintNode( p, pOld ); +printf( "\n" ); +Fraig_PrintNode( p, pNew ); +printf( "\n" ); +*/ +// assert( fValue1 != fValue2 ); +} + +/**Function************************************************************* + + Synopsis [Compress the simulation patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_FeedBackCompress( Fraig_Man_t * p ) +{ + unsigned * pSims; + unsigned uHash; + int i, w, t, nPats, * pPats; + int fPerformChecks = (p->nBTLimit == -1); + + // solve the covering problem + if ( fPerformChecks ) + { + Fraig_FeedBackCheckTable( p ); + if ( p->fDoSparse ) + Fraig_FeedBackCheckTableF0( p ); + } + + // solve the covering problem + Fraig_FeedBackCovering( p, p->vPatsReal ); + + + // get the number of additional patterns + nPats = Msat_IntVecReadSize( p->vPatsReal ); + pPats = Msat_IntVecReadArray( p->vPatsReal ); + // get the new starting word + p->iWordStart = FRAIG_NUM_WORDS( p->iPatsPerm + nPats ); + + // set the simulation info for the PIs + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + // get hold of the simulation info for this PI + pSims = p->vInputs->pArray[i]->puSimD; + // clean the storage for the new patterns + for ( w = p->iWordPerm; w < p->iWordStart; w++ ) + p->pSimsTemp[w] = 0; + // set the patterns + for ( t = 0; t < nPats; t++ ) + if ( Fraig_BitStringHasBit( pSims, pPats[t] ) ) + { + // check if this pattern falls into temporary storage + if ( p->iPatsPerm + t < p->iWordPerm * 32 ) + Fraig_BitStringSetBit( pSims, p->iPatsPerm + t ); + else + Fraig_BitStringSetBit( p->pSimsTemp, p->iPatsPerm + t ); + } + // copy the pattern + for ( w = p->iWordPerm; w < p->iWordStart; w++ ) + pSims[w] = p->pSimsTemp[w]; + // recompute the hashing info + uHash = 0; + for ( w = 0; w < p->iWordStart; w++ ) + uHash ^= pSims[w] * s_FraigPrimes[w]; + p->vInputs->pArray[i]->uHashD = uHash; + } + + // update info about the permanently stored patterns + p->iWordPerm = p->iWordStart; + p->iPatsPerm += nPats; + assert( p->iWordPerm == FRAIG_NUM_WORDS( p->iPatsPerm ) ); + + // resimulate and recompute the hash values + for ( i = 1; i < p->vNodes->nSize; i++ ) + if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) ) + { + p->vNodes->pArray[i]->uHashD = 0; + Fraig_NodeSimulate( p->vNodes->pArray[i], 0, p->iWordPerm, 0 ); + } + + // double-check that the nodes are still distinguished + if ( fPerformChecks ) + Fraig_FeedBackCheckTable( p ); + + // rehash the values in the F0 table + if ( p->fDoSparse ) + { + Fraig_TableRehashF0( p, 0 ); + if ( fPerformChecks ) + Fraig_FeedBackCheckTableF0( p ); + } + + // check if we need to resize the simulation info + // if less than FRAIG_WORDS_STORE words are left, reallocate simulation info + if ( p->iWordPerm + FRAIG_WORDS_STORE > p->nWordsDyna ) + Fraig_ReallocateSimulationInfo( p ); + + // set the real patterns + Msat_IntVecClear( p->vPatsReal ); + memset( p->pSimsReal, 0, sizeof(unsigned)*p->nWordsDyna ); + for ( w = 0; w < p->iWordPerm; w++ ) + p->pSimsReal[w] = FRAIG_FULL; + if ( p->iPatsPerm % 32 > 0 ) + p->pSimsReal[p->iWordPerm-1] = FRAIG_MASK( p->iPatsPerm % 32 ); +// printf( "The number of permanent words = %d.\n", p->iWordPerm ); + return p->iWordStart; +} + + + + +/**Function************************************************************* + + Synopsis [Checks the correctness of the functional simulation table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBackCovering( Fraig_Man_t * p, Msat_IntVec_t * vPats ) +{ + Fraig_NodeVec_t * vColumns; + unsigned * pSims; + int * pHits, iPat, iCol, i; + int nOnesTotal, nSolStarting; + int fVeryVerbose = 0; + + // collect the pairs to be distinguished + vColumns = Fraig_FeedBackCoveringStart( p ); + // collect the number of 1s in each simulation vector + nOnesTotal = 0; + pHits = ALLOC( int, vColumns->nSize ); + for ( i = 0; i < vColumns->nSize; i++ ) + { + pSims = (unsigned *)vColumns->pArray[i]; + pHits[i] = Fraig_BitStringCountOnes( pSims, p->iWordStart ); + nOnesTotal += pHits[i]; +// assert( pHits[i] > 0 ); + } + + // go through the patterns + nSolStarting = Msat_IntVecReadSize(vPats); + while ( (iCol = Fraig_GetSmallestColumn( pHits, vColumns->nSize )) != -1 ) + { + // find the pattern, which hits this column + iPat = Fraig_GetHittingPattern( (unsigned *)vColumns->pArray[iCol], p->iWordStart ); + // cancel the columns covered by this pattern + Fraig_CancelCoveredColumns( vColumns, pHits, iPat ); + // save the pattern + Msat_IntVecPush( vPats, iPat ); + } + + // free the set of columns + for ( i = 0; i < vColumns->nSize; i++ ) + Fraig_MemFixedEntryRecycle( p->mmSims, (char *)vColumns->pArray[i] ); + + // print stats related to the covering problem + if ( p->fVerbose && fVeryVerbose ) + { + printf( "%3d\\%3d\\%3d ", p->nWordsRand, p->nWordsDyna, p->iWordPerm ); + printf( "Col (pairs) = %5d. ", vColumns->nSize ); + printf( "Row (pats) = %5d. ", p->iWordStart * 32 ); + printf( "Dns = %6.2f %%. ", vColumns->nSize==0? 0.0 : 100.0 * nOnesTotal / vColumns->nSize / p->iWordStart / 32 ); + printf( "Sol = %3d (%3d). ", Msat_IntVecReadSize(vPats), nSolStarting ); + printf( "\n" ); + } + Fraig_NodeVecFree( vColumns ); + free( pHits ); +} + + +/**Function************************************************************* + + Synopsis [Checks the correctness of the functional simulation table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fraig_NodeVec_t * Fraig_FeedBackCoveringStart( Fraig_Man_t * p ) +{ + Fraig_NodeVec_t * vColumns; + Fraig_HashTable_t * pT = p->pTableF; + Fraig_Node_t * pEntF, * pEntD; + unsigned * pSims; + unsigned * pUnsigned1, * pUnsigned2; + int i, k, m, w;//, nOnes; + + // start the set of columns + vColumns = Fraig_NodeVecAlloc( 100 ); + + // go through the pairs of nodes to be distinguished + for ( i = 0; i < pT->nBins; i++ ) + Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF ) + { + p->vCones->nSize = 0; + Fraig_TableBinForEachEntryD( pEntF, pEntD ) + Fraig_NodeVecPush( p->vCones, pEntD ); + if ( p->vCones->nSize == 1 ) + continue; + + for ( k = 0; k < p->vCones->nSize; k++ ) + for ( m = k+1; m < p->vCones->nSize; m++ ) + { + if ( !Fraig_CompareSimInfoUnderMask( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0, p->pSimsReal ) ) + continue; + + // primary simulation patterns (counter-examples) cannot distinguish this pair + // get memory to store the feasible simulation patterns + pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims ); + // find the pattern that distinguish this column, exept the primary ones + pUnsigned1 = p->vCones->pArray[k]->puSimD; + pUnsigned2 = p->vCones->pArray[m]->puSimD; + for ( w = 0; w < p->iWordStart; w++ ) + pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w]; + // store the pattern + Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims ); +// nOnes = Fraig_BitStringCountOnes(pSims, p->iWordStart); +// assert( nOnes > 0 ); + } + } + + // if the flag is not set, do not consider sparse nodes in p->pTableF0 + if ( !p->fDoSparse ) + return vColumns; + + // recalculate their hash values based on p->pSimsReal + pT = p->pTableF0; + for ( i = 0; i < pT->nBins; i++ ) + Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF ) + { + pSims = pEntF->puSimD; + pEntF->uHashD = 0; + for ( w = 0; w < p->iWordStart; w++ ) + pEntF->uHashD ^= (pSims[w] & p->pSimsReal[w]) * s_FraigPrimes[w]; + } + + // rehash the table using these values + Fraig_TableRehashF0( p, 1 ); + + // collect the classes of equivalent node pairs + for ( i = 0; i < pT->nBins; i++ ) + Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF ) + { + p->vCones->nSize = 0; + Fraig_TableBinForEachEntryD( pEntF, pEntD ) + Fraig_NodeVecPush( p->vCones, pEntD ); + if ( p->vCones->nSize == 1 ) + continue; + + // primary simulation patterns (counter-examples) cannot distinguish all these pairs + for ( k = 0; k < p->vCones->nSize; k++ ) + for ( m = k+1; m < p->vCones->nSize; m++ ) + { + // get memory to store the feasible simulation patterns + pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims ); + // find the patterns that are not distinquished + pUnsigned1 = p->vCones->pArray[k]->puSimD; + pUnsigned2 = p->vCones->pArray[m]->puSimD; + for ( w = 0; w < p->iWordStart; w++ ) + pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w]; + // store the pattern + Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims ); +// nOnes = Fraig_BitStringCountOnes(pSims, p->iWordStart); +// assert( nOnes > 0 ); + } + } + return vColumns; +} + +/**Function************************************************************* + + Synopsis [Selects the column, which has the smallest number of hits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_GetSmallestColumn( int * pHits, int nHits ) +{ + int i, iColMin = -1, nHitsMin = 1000000; + for ( i = 0; i < nHits; i++ ) + { + // skip covered columns + if ( pHits[i] == 0 ) + continue; + // take the column if it can only be covered by one pattern + if ( pHits[i] == 1 ) + return i; + // find the column, which requires the smallest number of patterns + if ( nHitsMin > pHits[i] ) + { + nHitsMin = pHits[i]; + iColMin = i; + } + } + return iColMin; +} + +/**Function************************************************************* + + Synopsis [Select the pattern, which hits this column.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_GetHittingPattern( unsigned * pSims, int nWords ) +{ + int i, b; + for ( i = 0; i < nWords; i++ ) + { + if ( pSims[i] == 0 ) + continue; + for ( b = 0; b < 32; b++ ) + if ( pSims[i] & (1 << b) ) + return i * 32 + b; + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Cancel covered patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat ) +{ + unsigned * pSims; + int i; + for ( i = 0; i < vColumns->nSize; i++ ) + { + pSims = (unsigned *)vColumns->pArray[i]; + if ( Fraig_BitStringHasBit( pSims, iPat ) ) + pHits[i] = 0; + } +} + + +/**Function************************************************************* + + Synopsis [Checks the correctness of the functional simulation table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBackCheckTable( Fraig_Man_t * p ) +{ + Fraig_HashTable_t * pT = p->pTableF; + Fraig_Node_t * pEntF, * pEntD; + int i, k, m, nPairs; + int clk = clock(); + + nPairs = 0; + for ( i = 0; i < pT->nBins; i++ ) + Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF ) + { + p->vCones->nSize = 0; + Fraig_TableBinForEachEntryD( pEntF, pEntD ) + Fraig_NodeVecPush( p->vCones, pEntD ); + if ( p->vCones->nSize == 1 ) + continue; + for ( k = 0; k < p->vCones->nSize; k++ ) + for ( m = k+1; m < p->vCones->nSize; m++ ) + { + if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) ) + printf( "Nodes %d and %d have the same D simulation info.\n", + p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num ); + nPairs++; + } + } +// printf( "\nThe total of %d node pairs have been verified.\n", nPairs ); +} + +/**Function************************************************************* + + Synopsis [Checks the correctness of the functional simulation table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_FeedBackCheckTableF0( Fraig_Man_t * p ) +{ + Fraig_HashTable_t * pT = p->pTableF0; + Fraig_Node_t * pEntF; + int i, k, m, nPairs; + + nPairs = 0; + for ( i = 0; i < pT->nBins; i++ ) + { + p->vCones->nSize = 0; + Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF ) + Fraig_NodeVecPush( p->vCones, pEntF ); + if ( p->vCones->nSize == 1 ) + continue; + for ( k = 0; k < p->vCones->nSize; k++ ) + for ( m = k+1; m < p->vCones->nSize; m++ ) + { + if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) ) + printf( "Nodes %d and %d have the same D simulation info.\n", + p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num ); + nPairs++; + } + } +// printf( "\nThe total of %d node pairs have been verified.\n", nPairs ); +} + +/**Function************************************************************* + + Synopsis [Doubles the size of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p ) +{ + Fraig_MemFixed_t * mmSimsNew; // new memory manager for simulation info + Fraig_Node_t * pNode; + unsigned * pSimsNew; + unsigned uSignOld; + int i; + + // allocate a new memory manager + p->nWordsDyna *= 2; + mmSimsNew = Fraig_MemFixedStart( sizeof(unsigned) * (p->nWordsRand + p->nWordsDyna) ); + + // set the new data for the constant node + pNode = p->pConst1; + pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); + pNode->puSimD = pNode->puSimR + p->nWordsRand; + memset( pNode->puSimR, 0, sizeof(unsigned) * p->nWordsRand ); + memset( pNode->puSimD, 0, sizeof(unsigned) * p->nWordsDyna ); + + // copy the simulation info of the PIs + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + pNode = p->vInputs->pArray[i]; + // copy the simulation info + pSimsNew = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); + memmove( pSimsNew, pNode->puSimR, sizeof(unsigned) * (p->nWordsRand + p->iWordStart) ); + // attach the new info + pNode->puSimR = pSimsNew; + pNode->puSimD = pNode->puSimR + p->nWordsRand; + // signatures remain without changes + } + + // replace the manager to free up some memory + Fraig_MemFixedStop( p->mmSims, 0 ); + p->mmSims = mmSimsNew; + + // resimulate the internal nodes (this should lead to the same signatures) + for ( i = 1; i < p->vNodes->nSize; i++ ) + { + pNode = p->vNodes->pArray[i]; + if ( !Fraig_NodeIsAnd(pNode) ) + continue; + // allocate memory for the simulation info + pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); + pNode->puSimD = pNode->puSimR + p->nWordsRand; + // derive random simulation info + uSignOld = pNode->uHashR; + pNode->uHashR = 0; + Fraig_NodeSimulate( pNode, 0, p->nWordsRand, 1 ); + assert( uSignOld == pNode->uHashR ); + // derive dynamic simulation info + uSignOld = pNode->uHashD; + pNode->uHashD = 0; + Fraig_NodeSimulate( pNode, 0, p->iWordStart, 0 ); + assert( uSignOld == pNode->uHashD ); + } + + // realloc temporary storage + p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); + memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna ); + p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); + p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |