00001
00019 #include "mapperInt.h"
00020
00024
00025
00026 #define MAP_CUTS_MAX_COMPUTE 1000
00027
00028 #define MAP_CUTS_MAX_USE 250
00029
00030
00031 typedef struct Map_CutTableStrutct_t Map_CutTable_t;
00032 struct Map_CutTableStrutct_t
00033 {
00034 Map_Cut_t ** pBins;
00035 int nBins;
00036 int * pCuts;
00037 int nCuts;
00038 Map_Cut_t ** pArray;
00039 Map_Cut_t ** pCuts1;
00040 Map_Cut_t ** pCuts2;
00041 };
00042
00043
00044 static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 };
00045
00046 static Map_Cut_t * Map_CutCompute( Map_Man_t * p, Map_CutTable_t * pTable, Map_Node_t * pNode );
00047 static void Map_CutFilter( Map_Man_t * p, Map_Node_t * pNode );
00048 static Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable, Map_Cut_t * pList1, Map_Cut_t * pList2, int fComp1, int fComp2 );
00049 static int Map_CutMergeTwo( Map_Cut_t * pCut1, Map_Cut_t * pCut2, Map_Node_t * ppNodes[], int nNodesMax );
00050 static Map_Cut_t * Map_CutUnionLists( Map_Cut_t * pList1, Map_Cut_t * pList2 );
00051 static int Map_CutBelongsToList( Map_Cut_t * pList, Map_Node_t * ppNodes[], int nNodes );
00052
00053 static void Map_CutListPrint( Map_Man_t * pMan, Map_Node_t * pRoot );
00054 static void Map_CutListPrint2( Map_Man_t * pMan, Map_Node_t * pRoot );
00055 static void Map_CutPrint_( Map_Man_t * pMan, Map_Cut_t * pCut, Map_Node_t * pRoot );
00056
00057 static Map_CutTable_t * Map_CutTableStart( Map_Man_t * pMan );
00058 static void Map_CutTableStop( Map_CutTable_t * p );
00059 static unsigned Map_CutTableHash( Map_Node_t * ppNodes[], int nNodes );
00060 static int Map_CutTableLookup( Map_CutTable_t * p, Map_Node_t * ppNodes[], int nNodes );
00061 static Map_Cut_t * Map_CutTableConsider( Map_Man_t * pMan, Map_CutTable_t * p, Map_Node_t * ppNodes[], int nNodes );
00062 static void Map_CutTableRestart( Map_CutTable_t * p );
00063
00064 static Map_Cut_t * Map_CutSortCuts( Map_Man_t * pMan, Map_CutTable_t * p, Map_Cut_t * pList );
00065 static int Map_CutList2Array( Map_Cut_t ** pArray, Map_Cut_t * pList );
00066 static Map_Cut_t * Map_CutArray2List( Map_Cut_t ** pArray, int nCuts );
00067
00068 static unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Map_Cut_t * pTemp0, Map_Cut_t * pTemp1, int fComp0, int fComp1 );
00069
00070
00071 #define Map_ListForEachCut( pList, pCut ) \
00072 for ( pCut = pList; \
00073 pCut; \
00074 pCut = pCut->pNext )
00075 #define Map_ListForEachCutSafe( pList, pCut, pCut2 ) \
00076 for ( pCut = pList, \
00077 pCut2 = pCut? pCut->pNext: NULL; \
00078 pCut; \
00079 pCut = pCut2, \
00080 pCut2 = pCut? pCut->pNext: NULL )
00081
00085
00110 void Map_MappingCuts( Map_Man_t * p )
00111 {
00112 ProgressBar * pProgress;
00113 Map_CutTable_t * pTable;
00114 Map_Node_t * pNode;
00115 Map_Cut_t * pCut;
00116 int nCuts, nNodes, i;
00117 int clk = clock();
00118
00119 assert( p->nVarsMax > 1 && p->nVarsMax < 7 );
00120 for ( i = 0; i < p->nInputs; i++ )
00121 {
00122 pCut = Map_CutAlloc( p );
00123 pCut->nLeaves = 1;
00124 pCut->ppLeaves[0] = p->pInputs[i];
00125 p->pInputs[i]->pCuts = pCut;
00126 p->pInputs[i]->pCutBest[0] = NULL;
00127 p->pInputs[i]->pCutBest[1] = pCut;
00128 pCut->uTruth = 0xAAAAAAAA;
00129 pCut->M[0].AreaFlow = 0.0;
00130 pCut->M[1].AreaFlow = 0.0;
00131 }
00132
00133
00134 nNodes = p->vAnds->nSize;
00135 pProgress = Extra_ProgressBarStart( stdout, nNodes );
00136 pTable = Map_CutTableStart( p );
00137 for ( i = 0; i < nNodes; i++ )
00138 {
00139 pNode = p->vAnds->pArray[i];
00140 if ( !Map_NodeIsAnd( pNode ) )
00141 continue;
00142 Map_CutCompute( p, pTable, pNode );
00143 Extra_ProgressBarUpdate( pProgress, i, "Cuts ..." );
00144 }
00145 Extra_ProgressBarStop( pProgress );
00146 Map_CutTableStop( pTable );
00147
00148
00149 if ( p->fVerbose )
00150 {
00151 nCuts = Map_MappingCountAllCuts(p);
00152 printf( "Nodes = %6d. Total %d-feasible cuts = %10d. Per node = %.1f. ",
00153 p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes );
00154 PRT( "Time", clock() - clk );
00155 }
00156
00157
00158
00159 }
00160
00172 Map_Cut_t * Map_CutCompute( Map_Man_t * p, Map_CutTable_t * pTable, Map_Node_t * pNode )
00173 {
00174 Map_Node_t * pTemp;
00175 Map_Cut_t * pList, * pList1, * pList2;
00176 Map_Cut_t * pCut;
00177
00178
00179 if ( pNode->pCuts )
00180 return pNode->pCuts;
00181
00182
00183 pList1 = Map_Regular(pNode->p1)->pCuts;
00184 pList2 = Map_Regular(pNode->p2)->pCuts;
00185
00186 pList = Map_CutMergeLists( p, pTable, pList1, pList2,
00187 Map_IsComplement(pNode->p1), Map_IsComplement(pNode->p2) );
00188
00189 assert( pList );
00190
00191 if ( pNode->pRepr == NULL )
00192 {
00193 for ( pTemp = pNode->pNextE; pTemp; pTemp = pTemp->pNextE )
00194 {
00195 assert( pTemp->pCuts );
00196 pList = Map_CutUnionLists( pList, pTemp->pCuts );
00197 assert( pTemp->pCuts );
00198 pList = Map_CutSortCuts( p, pTable, pList );
00199 }
00200 }
00201
00202 pCut = Map_CutAlloc( p );
00203 pCut->nLeaves = 1;
00204 pCut->ppLeaves[0] = pNode;
00205 pCut->uTruth = 0xAAAAAAAA;
00206
00207 pCut->pNext = pList;
00208
00209 pNode->pCuts = pCut;
00210
00211 Map_CutFilter( p, pNode );
00212
00213 if ( pNode->pRepr && Map_NodeComparePhase(pNode, pNode->pRepr) )
00214 {
00215 Map_ListForEachCut( pNode->pCuts, pCut )
00216 pCut->Phase = 1;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 return pCut;
00229 }
00230
00242 void Map_CutFilter( Map_Man_t * p, Map_Node_t * pNode )
00243 {
00244 Map_Cut_t * pTemp, * pPrev, * pCut, * pCut2;
00245 int i, k, Counter;
00246
00247 Counter = 0;
00248 pPrev = pNode->pCuts;
00249 Map_ListForEachCutSafe( pNode->pCuts->pNext, pCut, pCut2 )
00250 {
00251
00252 for ( pTemp = pNode->pCuts->pNext; pTemp != pCut; pTemp = pTemp->pNext )
00253 {
00254
00255 for ( i = 0; i < pTemp->nLeaves; i++ )
00256 {
00257 for ( k = 0; k < pCut->nLeaves; k++ )
00258 if ( pTemp->ppLeaves[i] == pCut->ppLeaves[k] )
00259 break;
00260 if ( k == pCut->nLeaves )
00261 break;
00262 }
00263 if ( i == pTemp->nLeaves )
00264 {
00265 Counter++;
00266 break;
00267 }
00268 }
00269 if ( pTemp != pCut )
00270 {
00271 pPrev->pNext = pCut->pNext;
00272
00273 Map_CutFree( p, pCut );
00274 }
00275 else
00276 pPrev = pCut;
00277 }
00278
00279 }
00280
00292 Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
00293 Map_Cut_t * pList1, Map_Cut_t * pList2, int fComp1, int fComp2 )
00294 {
00295 Map_Node_t * ppNodes[6];
00296 Map_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL };
00297 Map_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2;
00298 int nNodes, Counter, i;
00299 Map_Cut_t ** ppArray1, ** ppArray2, ** ppArray3;
00300 int nCuts1, nCuts2, nCuts3, k, fComp3;
00301
00302 ppArray1 = pTable->pCuts1;
00303 ppArray2 = pTable->pCuts2;
00304 nCuts1 = Map_CutList2Array( ppArray1, pList1 );
00305 nCuts2 = Map_CutList2Array( ppArray2, pList2 );
00306
00307 if ( nCuts1 > nCuts2 )
00308 {
00309 ppArray3 = ppArray1;
00310 ppArray1 = ppArray2;
00311 ppArray2 = ppArray3;
00312
00313 nCuts3 = nCuts1;
00314 nCuts1 = nCuts2;
00315 nCuts2 = nCuts3;
00316
00317 fComp3 = fComp1;
00318 fComp1 = fComp2;
00319 fComp2 = fComp3;
00320 }
00321
00322
00323
00324 Map_CutTableRestart( pTable );
00325
00326 Counter = 0;
00327
00328
00329 for ( i = 0; i < nCuts1; i++ )
00330 {
00331 for ( k = 0; k <= i; k++ )
00332 {
00333 pTemp1 = ppArray1[i];
00334 pTemp2 = ppArray2[k];
00335
00336 if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00337 {
00338 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00339 continue;
00340 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00341 continue;
00342 }
00343
00344
00345 nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00346 if ( nNodes == 0 )
00347 continue;
00348
00349 pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00350 if ( pCut == NULL )
00351 continue;
00352
00353 pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00354 pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00355
00356
00357
00358 pCut->pNext = pLists[pCut->nLeaves];
00359 pLists[pCut->nLeaves] = pCut;
00360
00361 Counter++;
00362 if ( Counter == MAP_CUTS_MAX_COMPUTE )
00363 goto QUITS;
00364 }
00365 for ( k = 0; k < i; k++ )
00366 {
00367 pTemp1 = ppArray1[k];
00368 pTemp2 = ppArray2[i];
00369
00370 if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00371 {
00372 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00373 continue;
00374 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00375 continue;
00376 }
00377
00378
00379 nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00380 if ( nNodes == 0 )
00381 continue;
00382
00383 pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00384 if ( pCut == NULL )
00385 continue;
00386
00387 pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00388 pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00389
00390
00391
00392 pCut->pNext = pLists[pCut->nLeaves];
00393 pLists[pCut->nLeaves] = pCut;
00394
00395 Counter++;
00396 if ( Counter == MAP_CUTS_MAX_COMPUTE )
00397 goto QUITS;
00398 }
00399 }
00400
00401 for ( i = nCuts1; i < nCuts2; i++ )
00402 for ( k = 0; k < nCuts1; k++ )
00403 {
00404 pTemp1 = ppArray1[k];
00405 pTemp2 = ppArray2[i];
00406
00407 if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00408 {
00409 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00410 continue;
00411 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00412 continue;
00413 }
00414
00415
00416 nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00417 if ( nNodes == 0 )
00418 continue;
00419
00420 pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00421 if ( pCut == NULL )
00422 continue;
00423
00424 pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00425 pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00426
00427
00428
00429 pCut->pNext = pLists[pCut->nLeaves];
00430 pLists[pCut->nLeaves] = pCut;
00431
00432 Counter++;
00433 if ( Counter == MAP_CUTS_MAX_COMPUTE )
00434 goto QUITS;
00435 }
00436 QUITS :
00437
00438 pListNew = NULL;
00439 ppListNew = &pListNew;
00440 for ( i = 1; i <= p->nVarsMax; i++ )
00441 {
00442 if ( pLists[i] == NULL )
00443 continue;
00444
00445 for ( pPrev = pLists[i], pCut = pPrev->pNext; pCut;
00446 pPrev = pCut, pCut = pCut->pNext );
00447
00448 *ppListNew = pLists[i];
00449 ppListNew = &pPrev->pNext;
00450 }
00451 *ppListNew = NULL;
00452
00453 pListNew = Map_CutSortCuts( p, pTable, pListNew );
00454 return pListNew;
00455 }
00456
00457
00469 Map_Cut_t * Map_CutMergeLists2( Map_Man_t * p, Map_CutTable_t * pTable,
00470 Map_Cut_t * pList1, Map_Cut_t * pList2, int fComp1, int fComp2 )
00471 {
00472 Map_Node_t * ppNodes[6];
00473 Map_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL };
00474 Map_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2;
00475 int nNodes, Counter, i;
00476
00477
00478 Map_CutTableRestart( pTable );
00479
00480 Counter = 0;
00481 for ( pTemp1 = pList1; pTemp1; pTemp1 = pTemp1->pNext )
00482 for ( pTemp2 = pList2; pTemp2; pTemp2 = pTemp2->pNext )
00483 {
00484
00485 nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00486 if ( nNodes == 0 )
00487 continue;
00488
00489 pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00490 if ( pCut == NULL )
00491 continue;
00492
00493 pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00494 pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00495
00496 pCut->pNext = pLists[pCut->nLeaves];
00497 pLists[pCut->nLeaves] = pCut;
00498
00499 Counter++;
00500 if ( Counter == MAP_CUTS_MAX_COMPUTE )
00501 goto QUITS;
00502 }
00503 QUITS :
00504
00505 pListNew = NULL;
00506 ppListNew = &pListNew;
00507 for ( i = 1; i <= p->nVarsMax; i++ )
00508 {
00509 if ( pLists[i] == NULL )
00510 continue;
00511
00512 for ( pPrev = pLists[i], pCut = pPrev->pNext; pCut;
00513 pPrev = pCut, pCut = pCut->pNext );
00514
00515 *ppListNew = pLists[i];
00516 ppListNew = &pPrev->pNext;
00517 }
00518 *ppListNew = NULL;
00519
00520 pListNew = Map_CutSortCuts( p, pTable, pListNew );
00521 return pListNew;
00522 }
00523
00536 int Map_CutMergeTwo( Map_Cut_t * pCut1, Map_Cut_t * pCut2, Map_Node_t * ppNodes[], int nNodesMax )
00537 {
00538 Map_Node_t * pNodeTemp;
00539 int nTotal, i, k, min, fMismatch;
00540
00541
00542 if ( pCut1->nLeaves == nNodesMax )
00543 {
00544 if ( pCut2->nLeaves == nNodesMax )
00545 {
00546
00547 for ( i = 0; i < nNodesMax; i++ )
00548 if ( pCut1->ppLeaves[i] != pCut2->ppLeaves[i] )
00549 return 0;
00550
00551 for ( i = 0; i < nNodesMax; i++ )
00552 ppNodes[i] = pCut1->ppLeaves[i];
00553 return nNodesMax;
00554 }
00555 else if ( pCut2->nLeaves == nNodesMax - 1 )
00556 {
00557
00558 fMismatch = 0;
00559 for ( i = 0; i < nNodesMax; i++ )
00560 if ( pCut1->ppLeaves[i] != pCut2->ppLeaves[i - fMismatch] )
00561 {
00562 if ( fMismatch == 1 )
00563 return 0;
00564 fMismatch = 1;
00565 }
00566
00567 for ( i = 0; i < nNodesMax; i++ )
00568 ppNodes[i] = pCut1->ppLeaves[i];
00569 return nNodesMax;
00570 }
00571 }
00572 else if ( pCut1->nLeaves == nNodesMax - 1 && pCut2->nLeaves == nNodesMax )
00573 {
00574
00575 fMismatch = 0;
00576 for ( i = 0; i < nNodesMax; i++ )
00577 if ( pCut1->ppLeaves[i - fMismatch] != pCut2->ppLeaves[i] )
00578 {
00579 if ( fMismatch == 1 )
00580 return 0;
00581 fMismatch = 1;
00582 }
00583
00584 for ( i = 0; i < nNodesMax; i++ )
00585 ppNodes[i] = pCut2->ppLeaves[i];
00586 return nNodesMax;
00587 }
00588
00589
00590 nTotal = pCut1->nLeaves;
00591 for ( i = 0; i < pCut2->nLeaves; i++ )
00592 {
00593
00594 for ( k = 0; k < pCut1->nLeaves; k++ )
00595 if ( pCut2->ppLeaves[i] == pCut1->ppLeaves[k] )
00596 break;
00597 if ( k < pCut1->nLeaves )
00598 continue;
00599
00600 if ( nTotal == nNodesMax )
00601 return 0;
00602 ppNodes[nTotal++] = pCut2->ppLeaves[i];
00603 }
00604
00605
00606
00607 for ( k = 0; k < pCut1->nLeaves; k++ )
00608 ppNodes[k] = pCut1->ppLeaves[k];
00609
00610
00611 for ( i = 0; i < nTotal - 1; i++ )
00612 {
00613 min = i;
00614 for ( k = i+1; k < nTotal; k++ )
00615
00616 if ( ppNodes[k]->Num < ppNodes[min]->Num )
00617 min = k;
00618 pNodeTemp = ppNodes[i];
00619 ppNodes[i] = ppNodes[min];
00620 ppNodes[min] = pNodeTemp;
00621 }
00622
00623 return nTotal;
00624 }
00625
00637 Map_Cut_t * Map_CutUnionLists( Map_Cut_t * pList1, Map_Cut_t * pList2 )
00638 {
00639 Map_Cut_t * pTemp, * pRoot;
00640
00641 pRoot = pList1;
00642 Map_ListForEachCut( pList1, pTemp )
00643 pRoot = pTemp;
00644
00645 assert( pRoot->pNext == NULL );
00646 pRoot->pNext = pList2->pNext;
00647 pList2->pNext = NULL;
00648 return pList1;
00649 }
00650
00651
00664 int Map_CutBelongsToList( Map_Cut_t * pList, Map_Node_t * ppNodes[], int nNodes )
00665 {
00666 Map_Cut_t * pTemp;
00667 int i;
00668 for ( pTemp = pList; pTemp; pTemp = pTemp->pNext )
00669 {
00670 for ( i = 0; i < nNodes; i++ )
00671 if ( pTemp->ppLeaves[i] != ppNodes[i] )
00672 break;
00673 if ( i == nNodes )
00674 return 1;
00675 }
00676 return 0;
00677 }
00678
00690 int Map_MappingCountAllCuts( Map_Man_t * pMan )
00691 {
00692 Map_Node_t * pNode;
00693 Map_Cut_t * pCut;
00694 int i, nCuts;
00695
00696
00697 nCuts = 0;
00698 for ( i = 0; i < pMan->nBins; i++ )
00699 for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext )
00700 for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext )
00701 if ( pCut->nLeaves > 1 )
00702 {
00703 nCuts++;
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 }
00717
00718
00719
00720
00721 return nCuts;
00722 }
00723
00724
00736 void Map_CutListPrint( Map_Man_t * pMan, Map_Node_t * pRoot )
00737 {
00738 Map_Cut_t * pTemp;
00739 int Counter;
00740 for ( Counter = 0, pTemp = pRoot->pCuts; pTemp; pTemp = pTemp->pNext, Counter++ )
00741 {
00742 printf( "%2d : ", Counter + 1 );
00743 Map_CutPrint_( pMan, pTemp, pRoot );
00744 }
00745 }
00746
00758 void Map_CutListPrint2( Map_Man_t * pMan, Map_Node_t * pRoot )
00759 {
00760 Map_Cut_t * pTemp;
00761 int Counter;
00762 for ( Counter = 0, pTemp = pRoot->pCuts; pTemp; pTemp = pTemp->pNext, Counter++ )
00763 {
00764 printf( "%2d : ", Counter + 1 );
00765 Map_CutPrint_( pMan, pTemp, pRoot );
00766 }
00767 }
00768
00780 void Map_CutPrint_( Map_Man_t * pMan, Map_Cut_t * pCut, Map_Node_t * pRoot )
00781 {
00782 int i;
00783 printf( "(%3d) {", pRoot->Num );
00784 for ( i = 0; i < pMan->nVarsMax; i++ )
00785 if ( pCut->ppLeaves[i] )
00786 printf( " %3d", pCut->ppLeaves[i]->Num );
00787 printf( " }\n" );
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00808 Map_CutTable_t * Map_CutTableStart( Map_Man_t * pMan )
00809 {
00810 Map_CutTable_t * p;
00811
00812 p = ALLOC( Map_CutTable_t, 1 );
00813 memset( p, 0, sizeof(Map_CutTable_t) );
00814 p->nBins = Cudd_Prime( 10 * MAP_CUTS_MAX_COMPUTE );
00815 p->pBins = ALLOC( Map_Cut_t *, p->nBins );
00816 memset( p->pBins, 0, sizeof(Map_Cut_t *) * p->nBins );
00817 p->pCuts = ALLOC( int, 2 * MAP_CUTS_MAX_COMPUTE );
00818 p->pArray = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00819 p->pCuts1 = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00820 p->pCuts2 = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00821 return p;
00822 }
00823
00835 void Map_CutTableStop( Map_CutTable_t * p )
00836 {
00837 free( p->pCuts1 );
00838 free( p->pCuts2 );
00839 free( p->pArray );
00840 free( p->pBins );
00841 free( p->pCuts );
00842 free( p );
00843 }
00844
00856 unsigned Map_CutTableHash( Map_Node_t * ppNodes[], int nNodes )
00857 {
00858 unsigned uRes;
00859 int i;
00860 uRes = 0;
00861 for ( i = 0; i < nNodes; i++ )
00862 uRes += s_HashPrimes[i] * ppNodes[i]->Num;
00863 return uRes;
00864 }
00865
00878 int Map_CutTableLookup( Map_CutTable_t * p, Map_Node_t * ppNodes[], int nNodes )
00879 {
00880 Map_Cut_t * pCut;
00881 unsigned Key;
00882 int b, i;
00883
00884 Key = Map_CutTableHash(ppNodes, nNodes) % p->nBins;
00885 for ( b = Key; p->pBins[b]; b = (b+1) % p->nBins )
00886 {
00887 pCut = p->pBins[b];
00888 if ( pCut->nLeaves != nNodes )
00889 continue;
00890 for ( i = 0; i < nNodes; i++ )
00891 if ( pCut->ppLeaves[i] != ppNodes[i] )
00892 break;
00893 if ( i == nNodes )
00894 return -1;
00895 }
00896 return b;
00897 }
00898
00899
00911 Map_Cut_t * Map_CutTableConsider( Map_Man_t * pMan, Map_CutTable_t * p, Map_Node_t * ppNodes[], int nNodes )
00912 {
00913 Map_Cut_t * pCut;
00914 int Place, i;
00915
00916
00917 Place = Map_CutTableLookup( p, ppNodes, nNodes );
00918 if ( Place == -1 )
00919 return NULL;
00920 assert( nNodes > 0 );
00921
00922
00923 pCut = Map_CutAlloc( pMan );
00924
00925 pCut->nLeaves = nNodes;
00926 for ( i = 0; i < nNodes; i++ )
00927 pCut->ppLeaves[i] = ppNodes[i];
00928
00929 assert( p->pBins[Place] == NULL );
00930 p->pBins[Place] = pCut;
00931
00932 p->pCuts[ p->nCuts++ ] = Place;
00933 return pCut;
00934 }
00935
00948 void Map_CutTableRestart( Map_CutTable_t * p )
00949 {
00950 int i;
00951 for ( i = 0; i < p->nCuts; i++ )
00952 {
00953 assert( p->pBins[ p->pCuts[i] ] );
00954 p->pBins[ p->pCuts[i] ] = NULL;
00955 }
00956 p->nCuts = 0;
00957 }
00958
00959
00960
00972 int Map_CutSortCutsCompare( Map_Cut_t ** pC1, Map_Cut_t ** pC2 )
00973 {
00974 if ( (*pC1)->nLeaves < (*pC2)->nLeaves )
00975 return -1;
00976 if ( (*pC1)->nLeaves > (*pC2)->nLeaves )
00977 return 1;
00978 return 0;
00979 }
00980
00992 Map_Cut_t * Map_CutSortCuts( Map_Man_t * pMan, Map_CutTable_t * p, Map_Cut_t * pList )
00993 {
00994 Map_Cut_t * pListNew;
00995 int nCuts, i;
00996
00997
00998 nCuts = Map_CutList2Array( p->pCuts1, pList );
00999 assert( nCuts <= MAP_CUTS_MAX_COMPUTE );
01000
01001
01002 qsort( (void *)p->pCuts1, nCuts, sizeof(Map_Cut_t *),
01003 (int (*)(const void *, const void *)) Map_CutSortCutsCompare );
01004
01005
01006 if ( nCuts > MAP_CUTS_MAX_USE - 1 )
01007 {
01008
01009 for ( i = MAP_CUTS_MAX_USE - 1; i < nCuts; i++ )
01010 Extra_MmFixedEntryRecycle( pMan->mmCuts, (char *)p->pCuts1[i] );
01011
01012 nCuts = MAP_CUTS_MAX_USE - 1;
01013 }
01014 pListNew = Map_CutArray2List( p->pCuts1, nCuts );
01015 return pListNew;
01016 }
01017
01029 int Map_CutList2Array( Map_Cut_t ** pArray, Map_Cut_t * pList )
01030 {
01031 int i;
01032 for ( i = 0; pList; pList = pList->pNext, i++ )
01033 pArray[i] = pList;
01034 return i;
01035 }
01036
01048 Map_Cut_t * Map_CutArray2List( Map_Cut_t ** pArray, int nCuts )
01049 {
01050 Map_Cut_t * pListNew, ** ppListNew;
01051 int i;
01052 pListNew = NULL;
01053 ppListNew = &pListNew;
01054 for ( i = 0; i < nCuts; i++ )
01055 {
01056
01057 *ppListNew = pArray[i];
01058 ppListNew = &pArray[i]->pNext;
01059 }
01060
01061
01062 *ppListNew = NULL;
01063 return pListNew;
01064 }
01065
01066
01078 unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Map_Cut_t * pTemp0, Map_Cut_t * pTemp1, int fComp0, int fComp1 )
01079 {
01080 static unsigned ** pPerms53 = NULL;
01081 static unsigned ** pPerms54 = NULL;
01082
01083 unsigned uPhase, uTruth, uTruth0, uTruth1;
01084 int i, k;
01085
01086 if ( pPerms53 == NULL )
01087 {
01088 pPerms53 = (unsigned **)Extra_TruthPerm53();
01089 pPerms54 = (unsigned **)Extra_TruthPerm54();
01090 }
01091
01092
01093 if ( pTemp0->nLeaves == pCut->nLeaves )
01094 uTruth0 = pTemp0->uTruth;
01095 else
01096 {
01097 assert( pTemp0->nLeaves < pCut->nLeaves );
01098 uPhase = 0;
01099 for ( i = 0; i < (int)pTemp0->nLeaves; i++ )
01100 {
01101 for ( k = 0; k < pCut->nLeaves; k++ )
01102 if ( pTemp0->ppLeaves[i] == pCut->ppLeaves[k] )
01103 break;
01104 uPhase |= (1 << k);
01105 }
01106 assert( uPhase < 32 );
01107 if ( pTemp0->nLeaves == 4 )
01108 {
01109 if ( uPhase == 31-16 )
01110 uTruth0 = pTemp0->uTruth;
01111 else if ( uPhase == 31-8 )
01112 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][0];
01113 else if ( uPhase == 31-4 )
01114 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][1];
01115 else if ( uPhase == 31-2 )
01116 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][2];
01117 else if ( uPhase == 31-1 )
01118 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][3];
01119 else
01120 assert( 0 );
01121 }
01122 else
01123 uTruth0 = pPerms53[pTemp0->uTruth & 0xFF][uPhase];
01124 }
01125 uTruth0 = fComp0? ~uTruth0: uTruth0;
01126
01127
01128 if ( pTemp1->nLeaves == pCut->nLeaves )
01129 uTruth1 = pTemp1->uTruth;
01130 else
01131 {
01132 assert( pTemp1->nLeaves < pCut->nLeaves );
01133 uPhase = 0;
01134 for ( i = 0; i < (int)pTemp1->nLeaves; i++ )
01135 {
01136 for ( k = 0; k < pCut->nLeaves; k++ )
01137 if ( pTemp1->ppLeaves[i] == pCut->ppLeaves[k] )
01138 break;
01139 uPhase |= (1 << k);
01140 }
01141 assert( uPhase < 32 );
01142 if ( pTemp1->nLeaves == 4 )
01143 {
01144 if ( uPhase == 31-16 )
01145 uTruth1 = pTemp1->uTruth;
01146 else if ( uPhase == 31-8 )
01147 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][0];
01148 else if ( uPhase == 31-4 )
01149 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][1];
01150 else if ( uPhase == 31-2 )
01151 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][2];
01152 else if ( uPhase == 31-1 )
01153 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][3];
01154 else
01155 assert( 0 );
01156 }
01157 else
01158 uTruth1 = pPerms53[pTemp1->uTruth & 0xFF][uPhase];
01159 }
01160 uTruth1 = fComp1? ~uTruth1: uTruth1;
01161 uTruth = uTruth0 & uTruth1;
01162 return uTruth;
01163 }
01164
01168