00001
00019 #include "fraigInt.h"
00020
00024
00025 static void Fraig_TableResizeS( Fraig_HashTable_t * p );
00026 static void Fraig_TableResizeF( Fraig_HashTable_t * p, int fUseSimR );
00027
00031
00043 Fraig_HashTable_t * Fraig_HashTableCreate( int nSize )
00044 {
00045 Fraig_HashTable_t * p;
00046
00047 p = ALLOC( Fraig_HashTable_t, 1 );
00048 memset( p, 0, sizeof(Fraig_HashTable_t) );
00049
00050 p->nBins = Cudd_PrimeFraig(nSize);
00051 p->pBins = ALLOC( Fraig_Node_t *, p->nBins );
00052 memset( p->pBins, 0, sizeof(Fraig_Node_t *) * p->nBins );
00053 return p;
00054 }
00055
00067 void Fraig_HashTableFree( Fraig_HashTable_t * p )
00068 {
00069 FREE( p->pBins );
00070 FREE( p );
00071 }
00072
00087 int Fraig_HashTableLookupS( Fraig_Man_t * pMan, Fraig_Node_t * p1, Fraig_Node_t * p2, Fraig_Node_t ** ppNodeRes )
00088 {
00089 Fraig_HashTable_t * p = pMan->pTableS;
00090 Fraig_Node_t * pEnt;
00091 unsigned Key;
00092
00093
00094 if ( Fraig_Regular(p1)->Num > Fraig_Regular(p2)->Num )
00095 pEnt = p1, p1 = p2, p2 = pEnt;
00096
00097 Key = Fraig_HashKey2( p1, p2, p->nBins );
00098 Fraig_TableBinForEachEntryS( p->pBins[Key], pEnt )
00099 if ( pEnt->p1 == p1 && pEnt->p2 == p2 )
00100 {
00101 *ppNodeRes = pEnt;
00102 return 1;
00103 }
00104
00105 if ( p->nEntries >= 2 * p->nBins )
00106 {
00107 Fraig_TableResizeS( p );
00108 Key = Fraig_HashKey2( p1, p2, p->nBins );
00109 }
00110
00111 pEnt = Fraig_NodeCreate( pMan, p1, p2 );
00112
00113 pEnt->pNextS = p->pBins[Key];
00114 p->pBins[Key] = pEnt;
00115 *ppNodeRes = pEnt;
00116 p->nEntries++;
00117 return 0;
00118 }
00119
00120
00133 Fraig_Node_t * Fraig_HashTableLookupF( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00134 {
00135 Fraig_HashTable_t * p = pMan->pTableF;
00136 Fraig_Node_t * pEnt, * pEntD;
00137 unsigned Key;
00138
00139
00140 Key = pNode->uHashR % p->nBins;
00141 Fraig_TableBinForEachEntryF( p->pBins[Key], pEnt )
00142 {
00143
00144 if ( !Fraig_CompareSimInfo( pNode, pEnt, pMan->nWordsRand, 1 ) )
00145 continue;
00146
00147 Fraig_TableBinForEachEntryD( pEnt, pEntD )
00148 {
00149
00150 if ( !Fraig_CompareSimInfo( pNode, pEntD, pMan->iWordStart, 0 ) )
00151 continue;
00152
00153 return pEntD;
00154 }
00155
00156
00157 pNode->pNextD = pEnt->pNextD;
00158 pEnt->pNextD = pNode;
00159
00160 return NULL;
00161 }
00162
00163
00164 if ( p->nEntries >= 2 * p->nBins )
00165 {
00166 Fraig_TableResizeF( p, 1 );
00167 Key = pNode->uHashR % p->nBins;
00168 }
00169
00170
00171 pNode->pNextF = p->pBins[Key];
00172 p->pBins[Key] = pNode;
00173 p->nEntries++;
00174
00175 return NULL;
00176 }
00177
00190 Fraig_Node_t * Fraig_HashTableLookupF0( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00191 {
00192 Fraig_HashTable_t * p = pMan->pTableF0;
00193 Fraig_Node_t * pEnt;
00194 unsigned Key;
00195
00196
00197 Key = pNode->uHashD % p->nBins;
00198 Fraig_TableBinForEachEntryF( p->pBins[Key], pEnt )
00199 {
00200
00201 if ( !Fraig_CompareSimInfo( pNode, pEnt, pMan->iWordStart, 0 ) )
00202 continue;
00203
00204 return pEnt;
00205 }
00206
00207
00208 if ( p->nEntries >= 2 * p->nBins )
00209 {
00210 Fraig_TableResizeF( p, 0 );
00211 Key = pNode->uHashD % p->nBins;
00212 }
00213
00214
00215 pNode->pNextF = p->pBins[Key];
00216 p->pBins[Key] = pNode;
00217 p->nEntries++;
00218
00219 return NULL;
00220 }
00221
00234 void Fraig_HashTableInsertF0( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00235 {
00236 Fraig_HashTable_t * p = pMan->pTableF0;
00237 unsigned Key = pNode->uHashD % p->nBins;
00238
00239 pNode->pNextF = p->pBins[Key];
00240 p->pBins[Key] = pNode;
00241 p->nEntries++;
00242 }
00243
00244
00256 void Fraig_TableResizeS( Fraig_HashTable_t * p )
00257 {
00258 Fraig_Node_t ** pBinsNew;
00259 Fraig_Node_t * pEnt, * pEnt2;
00260 int nBinsNew, Counter, i, clk;
00261 unsigned Key;
00262
00263 clk = clock();
00264
00265 nBinsNew = Cudd_PrimeFraig(2 * p->nBins);
00266
00267 pBinsNew = ALLOC( Fraig_Node_t *, nBinsNew );
00268 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * nBinsNew );
00269
00270 Counter = 0;
00271 for ( i = 0; i < p->nBins; i++ )
00272 Fraig_TableBinForEachEntrySafeS( p->pBins[i], pEnt, pEnt2 )
00273 {
00274 Key = Fraig_HashKey2( pEnt->p1, pEnt->p2, nBinsNew );
00275 pEnt->pNextS = pBinsNew[Key];
00276 pBinsNew[Key] = pEnt;
00277 Counter++;
00278 }
00279 assert( Counter == p->nEntries );
00280
00281
00282
00283 free( p->pBins );
00284 p->pBins = pBinsNew;
00285 p->nBins = nBinsNew;
00286 }
00287
00299 void Fraig_TableResizeF( Fraig_HashTable_t * p, int fUseSimR )
00300 {
00301 Fraig_Node_t ** pBinsNew;
00302 Fraig_Node_t * pEnt, * pEnt2;
00303 int nBinsNew, Counter, i, clk;
00304 unsigned Key;
00305
00306 clk = clock();
00307
00308 nBinsNew = Cudd_PrimeFraig(2 * p->nBins);
00309
00310 pBinsNew = ALLOC( Fraig_Node_t *, nBinsNew );
00311 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * nBinsNew );
00312
00313 Counter = 0;
00314 for ( i = 0; i < p->nBins; i++ )
00315 Fraig_TableBinForEachEntrySafeF( p->pBins[i], pEnt, pEnt2 )
00316 {
00317 if ( fUseSimR )
00318 Key = pEnt->uHashR % nBinsNew;
00319 else
00320 Key = pEnt->uHashD % nBinsNew;
00321 pEnt->pNextF = pBinsNew[Key];
00322 pBinsNew[Key] = pEnt;
00323 Counter++;
00324 }
00325 assert( Counter == p->nEntries );
00326
00327
00328
00329 free( p->pBins );
00330 p->pBins = pBinsNew;
00331 p->nBins = nBinsNew;
00332 }
00333
00334
00346 int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand )
00347 {
00348 int i;
00349 assert( !Fraig_IsComplement(pNode1) );
00350 assert( !Fraig_IsComplement(pNode2) );
00351 if ( fUseRand )
00352 {
00353
00354 if ( pNode1->uHashR != pNode2->uHashR )
00355 return 0;
00356
00357 for ( i = 0; i < iWordLast; i++ )
00358 if ( pNode1->puSimR[i] != pNode2->puSimR[i] )
00359 return 0;
00360 }
00361 else
00362 {
00363
00364 if ( pNode1->uHashD != pNode2->uHashD )
00365 return 0;
00366
00367 for ( i = 0; i < iWordLast; i++ )
00368 if ( pNode1->puSimD[i] != pNode2->puSimD[i] )
00369 return 0;
00370 }
00371 return 1;
00372 }
00373
00385 int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand )
00386 {
00387 int i, v;
00388 assert( !Fraig_IsComplement(pNode1) );
00389 assert( !Fraig_IsComplement(pNode2) );
00390
00391 fCompl ^= pNode1->fInv;
00392 fCompl ^= pNode2->fInv;
00393
00394 if ( fCompl )
00395 {
00396 if ( fUseRand )
00397 {
00398 for ( i = 0; i < iWordLast; i++ )
00399 if ( pNode1->puSimR[i] != ~pNode2->puSimR[i] )
00400 for ( v = 0; v < 32; v++ )
00401 if ( (pNode1->puSimR[i] ^ ~pNode2->puSimR[i]) & (1 << v) )
00402 return i * 32 + v;
00403 }
00404 else
00405 {
00406 for ( i = 0; i < iWordLast; i++ )
00407 if ( pNode1->puSimD[i] != ~pNode2->puSimD[i] )
00408 for ( v = 0; v < 32; v++ )
00409 if ( (pNode1->puSimD[i] ^ ~pNode2->puSimD[i]) & (1 << v) )
00410 return i * 32 + v;
00411 }
00412 }
00413 else
00414 {
00415 if ( fUseRand )
00416 {
00417 for ( i = 0; i < iWordLast; i++ )
00418 if ( pNode1->puSimR[i] != pNode2->puSimR[i] )
00419 for ( v = 0; v < 32; v++ )
00420 if ( (pNode1->puSimR[i] ^ pNode2->puSimR[i]) & (1 << v) )
00421 return i * 32 + v;
00422 }
00423 else
00424 {
00425 for ( i = 0; i < iWordLast; i++ )
00426 if ( pNode1->puSimD[i] != pNode2->puSimD[i] )
00427 for ( v = 0; v < 32; v++ )
00428 if ( (pNode1->puSimD[i] ^ pNode2->puSimD[i]) & (1 << v) )
00429 return i * 32 + v;
00430 }
00431 }
00432 return -1;
00433 }
00434
00446 int Fraig_CompareSimInfoUnderMask( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask )
00447 {
00448 unsigned * pSims1, * pSims2;
00449 int i;
00450 assert( !Fraig_IsComplement(pNode1) );
00451 assert( !Fraig_IsComplement(pNode2) );
00452
00453 pSims1 = fUseRand? pNode1->puSimR : pNode1->puSimD;
00454 pSims2 = fUseRand? pNode2->puSimR : pNode2->puSimD;
00455
00456 for ( i = 0; i < iWordLast; i++ )
00457 if ( (pSims1[i] & puMask[i]) != (pSims2[i] & puMask[i]) )
00458 return 0;
00459 return 1;
00460 }
00461
00473 void Fraig_CollectXors( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask )
00474 {
00475 unsigned * pSims1, * pSims2;
00476 int i;
00477 assert( !Fraig_IsComplement(pNode1) );
00478 assert( !Fraig_IsComplement(pNode2) );
00479
00480 pSims1 = fUseRand? pNode1->puSimR : pNode1->puSimD;
00481 pSims2 = fUseRand? pNode2->puSimR : pNode2->puSimD;
00482
00483 for ( i = 0; i < iWordLast; i++ )
00484 puMask[i] = ( pSims1[i] ^ pSims2[i] );
00485 }
00486
00487
00499 void Fraig_TablePrintStatsS( Fraig_Man_t * pMan )
00500 {
00501 Fraig_HashTable_t * pT = pMan->pTableS;
00502 Fraig_Node_t * pNode;
00503 int i, Counter;
00504
00505 printf( "Structural table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
00506 for ( i = 0; i < pT->nBins; i++ )
00507 {
00508 Counter = 0;
00509 Fraig_TableBinForEachEntryS( pT->pBins[i], pNode )
00510 Counter++;
00511 if ( Counter > 1 )
00512 {
00513 printf( "%d ", Counter );
00514 if ( Counter > 50 )
00515 printf( "{%d} ", i );
00516 }
00517 }
00518 printf( "\n" );
00519 }
00520
00532 void Fraig_TablePrintStatsF( Fraig_Man_t * pMan )
00533 {
00534 Fraig_HashTable_t * pT = pMan->pTableF;
00535 Fraig_Node_t * pNode;
00536 int i, Counter;
00537
00538 printf( "Functional table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
00539 for ( i = 0; i < pT->nBins; i++ )
00540 {
00541 Counter = 0;
00542 Fraig_TableBinForEachEntryF( pT->pBins[i], pNode )
00543 Counter++;
00544 if ( Counter > 1 )
00545 printf( "{%d} ", Counter );
00546 }
00547 printf( "\n" );
00548 }
00549
00561 void Fraig_TablePrintStatsF0( Fraig_Man_t * pMan )
00562 {
00563 Fraig_HashTable_t * pT = pMan->pTableF0;
00564 Fraig_Node_t * pNode;
00565 int i, Counter;
00566
00567 printf( "Zero-node table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
00568 for ( i = 0; i < pT->nBins; i++ )
00569 {
00570 Counter = 0;
00571 Fraig_TableBinForEachEntryF( pT->pBins[i], pNode )
00572 Counter++;
00573 if ( Counter == 0 )
00574 continue;
00575
00576
00577
00578
00579
00580 }
00581 printf( "\n" );
00582 }
00583
00599 int Fraig_TableRehashF0( Fraig_Man_t * pMan, int fLinkEquiv )
00600 {
00601 Fraig_HashTable_t * pT = pMan->pTableF0;
00602 Fraig_Node_t ** pBinsNew;
00603 Fraig_Node_t * pEntF, * pEntF2, * pEnt, * pEntD2, * pEntN;
00604 int ReturnValue, Counter, i;
00605 unsigned Key;
00606
00607
00608 pBinsNew = ALLOC( Fraig_Node_t *, pT->nBins );
00609 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * pT->nBins );
00610
00611
00612
00613 Counter = 0;
00614 ReturnValue = 0;
00615 for ( i = 0; i < pT->nBins; i++ )
00616 Fraig_TableBinForEachEntrySafeF( pT->pBins[i], pEntF, pEntF2 )
00617 Fraig_TableBinForEachEntrySafeD( pEntF, pEnt, pEntD2 )
00618 {
00619
00620 Key = pEnt->uHashD % pT->nBins;
00621 if ( fLinkEquiv )
00622 {
00623
00624 Fraig_TableBinForEachEntryF( pBinsNew[Key], pEntN )
00625 {
00626
00627 if ( pEnt->uHashD != pEntN->uHashD )
00628 continue;
00629
00630 pEnt->pNextD = pEntN->pNextD;
00631 pEntN->pNextD = pEnt;
00632 ReturnValue = 1;
00633 Counter++;
00634 break;
00635 }
00636 if ( pEntN != NULL )
00637 continue;
00638
00639 }
00640
00641 pEnt->pNextF = pBinsNew[Key];
00642 pBinsNew[Key] = pEnt;
00643 pEnt->pNextD = NULL;
00644 Counter++;
00645 }
00646 assert( Counter == pT->nEntries );
00647
00648 free( pT->pBins );
00649 pT->pBins = pBinsNew;
00650 return ReturnValue;
00651 }
00652
00656
00657