00001 
00021 #include "abc.h"
00022 #include "dec.h"
00023 #include "dsd.h"
00024 #include "cut.h"
00025 
00029   
00030 #define RST_RANDOM_UNSIGNED   ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
00031 
00032 typedef struct Abc_ManRst_t_   Abc_ManRst_t;
00033 struct Abc_ManRst_t_
00034 {
00035     
00036     Abc_Ntk_t *      pNtk;              
00037     
00038     int              nCutMax;           
00039     int              fUpdateLevel;      
00040     int              fUseZeros;         
00041     int              fVerbose;          
00042     
00043     DdManager *      dd;                
00044     Dsd_Manager_t *  pManDsd;           
00045     Vec_Ptr_t *      vVisited;          
00046     Vec_Ptr_t *      vLeaves;           
00047     Vec_Ptr_t *      vDecs;             
00048     Vec_Ptr_t *      vTemp;             
00049     Vec_Int_t *      vSims;             
00050     Vec_Int_t *      vRands;            
00051     Vec_Int_t *      vOnes;             
00052     Vec_Int_t *      vBinate;           
00053     Vec_Int_t *      vTwos;             
00054     
00055     int              nLastGain;
00056     int              nCutsConsidered;
00057     int              nCutsExplored;
00058     int              nNodesConsidered;
00059     int              nNodesRestructured;
00060     int              nNodesGained;
00061     
00062     int              timeCut;
00063     int              timeBdd;
00064     int              timeDsd;
00065     int              timeEval;
00066     int              timeRes;
00067     int              timeNtk;
00068     int              timeTotal;
00069 };
00070 
00071 static Dec_Graph_t * Abc_NodeResubstitute( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList );
00072 
00073 static Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList );
00074 static Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCut );
00075 static Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded );
00076 
00077 static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag );
00078 static Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose );
00079 static void Abc_NtkManRstStop( Abc_ManRst_t * p );
00080 static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
00081 
00085 
00097 int Abc_NtkRestructure( Abc_Ntk_t * pNtk, int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose )
00098 {
00099     ProgressBar * pProgress;
00100     Abc_ManRst_t * pManRst;
00101     Cut_Man_t * pManCut;
00102     Cut_Cut_t * pCutList;
00103     Dec_Graph_t * pGraph;
00104     Abc_Obj_t * pNode;
00105     int clk, clkStart = clock();
00106     int fMulti = 1;
00107     int fResub = 0;
00108     int i, nNodes;
00109 
00110     assert( Abc_NtkIsStrash(pNtk) );
00111     
00112     Abc_AigCleanup(pNtk->pManFunc);
00113     Abc_NtkCleanCopy(pNtk);
00114 
00115     
00116     if ( fUpdateLevel )
00117         Abc_NtkStartReverseLevels( pNtk, 0 );
00118 
00119     
00120     pManRst = Abc_NtkManRstStart( nCutMax, fUpdateLevel, fUseZeros, fVerbose );
00121     pManRst->pNtk = pNtk;
00122     
00123 clk = clock();
00124     pManCut = Abc_NtkStartCutManForRestruct( pNtk, nCutMax, fMulti );
00125 pManRst->timeCut += clock() - clk;
00126 
00127 
00128     
00129     nNodes = Abc_NtkObjNumMax(pNtk);
00130     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00131     Abc_NtkForEachNode( pNtk, pNode, i )
00132     {
00133         Extra_ProgressBarUpdate( pProgress, i, NULL );
00134         
00135 
00136 
00137         
00138         if ( Abc_NodeIsPersistant(pNode) )
00139             continue;
00140         
00141 
00142 
00143         
00144         if ( Abc_ObjFanoutNum(pNode) > 1000 )
00145             continue;
00146         
00147         if ( i >= nNodes )
00148             break;
00149         
00150 clk = clock();
00151         pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 ); 
00152 pManRst->timeCut += clock() - clk;
00153 
00154         
00155 clk = clock();
00156         if ( fResub )
00157             pGraph = Abc_NodeResubstitute( pManRst, pNode, pCutList );
00158         else
00159             pGraph = Abc_NodeRestructure( pManRst, pNode, pCutList );
00160 pManRst->timeRes += clock() - clk;
00161         if ( pGraph == NULL )
00162             continue;
00163 
00164         
00165 clk = clock();
00166         Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, pManRst->nLastGain );
00167 pManRst->timeNtk += clock() - clk;
00168         Dec_GraphFree( pGraph );
00169     }
00170     Extra_ProgressBarStop( pProgress );
00171 pManRst->timeTotal = clock() - clkStart;
00172 
00173     
00174 
00175         Abc_NtkManRstPrintStats( pManRst );
00176     
00177     Cut_ManStop( pManCut );
00178     Abc_NtkManRstStop( pManRst );
00179     
00180     Abc_NtkReassignIds( pNtk );
00181 
00182     
00183     if ( fUpdateLevel )
00184         Abc_NtkStopReverseLevels( pNtk );
00185     else
00186         Abc_NtkLevel( pNtk );
00187     
00188     if ( !Abc_NtkCheck( pNtk ) )
00189     {
00190         printf( "Abc_NtkRefactor: The network check has failed.\n" );
00191         return 0;
00192     }
00193     return 1;
00194 }
00195 
00207 void Abc_RestructNodeDivisors( Abc_ManRst_t * p, Abc_Obj_t * pRoot, int nNodesSaved )
00208 {
00209     Abc_Obj_t * pNode, * pFanout;
00210     int i, k;
00211     
00212     Vec_PtrClear( p->vDecs );
00213     Vec_PtrForEachEntry( p->vLeaves, pNode, i )
00214     {
00215         Vec_PtrPush( p->vDecs, pNode );
00216         assert( pNode->fMarkC == 0 );
00217         pNode->fMarkC = 1;
00218     }
00219     
00220     Vec_PtrForEachEntry( p->vDecs, pNode, i )
00221     {
00222         
00223         Abc_ObjForEachFanout( pNode, pFanout, k )
00224         {
00225             if ( pFanout->fMarkC || Abc_ObjIsPo(pFanout) )
00226                 continue;
00227             if ( Abc_ObjFanin0(pFanout)->fMarkC && Abc_ObjFanin1(pFanout)->fMarkC )
00228             {
00229                 Vec_PtrPush( p->vDecs, pFanout );
00230                 pFanout->fMarkC = 1;
00231             }
00232         }
00233     }
00234     
00235     Vec_PtrForEachEntry( p->vDecs, pNode, i )
00236         pNode->fMarkC = 0;
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263     printf( "%d\n", Vec_PtrSize(p->vDecs)-nNodesSaved-Vec_PtrSize(p->vLeaves) );
00264 }
00265 
00266 
00278 Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList )
00279 {
00280     Dec_Graph_t * pGraph;
00281     Cut_Cut_t * pCut;
00282 
00283     p->nNodesConsidered++;
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292     
00293     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
00294     {
00295         if ( pCut->nLeaves < 4 )
00296             continue;
00297         if ( pGraph = Abc_NodeRestructureCut( p, pNode, pCut ) )
00298             return pGraph;
00299     }
00300     return NULL;
00301 }
00302 
00314 Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
00315 {
00316     Dec_Graph_t * pGraph;
00317     Dsd_Node_t * pNodeDsd;
00318     Abc_Obj_t * pLeaf;
00319     DdNode * bFunc;
00320     int nNodesSaved, nNodesAdded;
00321     int Required, nMaxSize, clk, i;
00322     int fVeryVerbose = 0;
00323 
00324     p->nCutsConsidered++;
00325 
00326     
00327     Required = p->fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY;
00328 
00329     
00330     Vec_PtrClear( p->vLeaves );
00331     for ( i = 0; i < (int)pCut->nLeaves; i++ )
00332     {
00333         pLeaf = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
00334         if ( pLeaf == NULL )  
00335             return NULL;
00336         Vec_PtrPush( p->vLeaves, pLeaf );
00337     }
00338 
00339     if ( pRoot->Id == 29 )
00340     {
00341         int x = 0;
00342     }
00343 
00344 clk = clock();
00345     
00346 
00347     
00348     bFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pRoot, p->vLeaves, p->vVisited );  Cudd_Ref( bFunc );
00349 p->timeBdd += clock() - clk;
00350 
00351     
00352     if ( Cudd_IsConstant(bFunc) )
00353     {
00354         p->nLastGain = Abc_NodeMffcSize( pRoot );
00355         p->nNodesGained += p->nLastGain;
00356         p->nNodesRestructured++;
00357         Cudd_RecursiveDeref( p->dd, bFunc );
00358         if ( Cudd_IsComplement(bFunc) )
00359             return Dec_GraphCreateConst0();
00360         return Dec_GraphCreateConst1();
00361     }
00362 
00363 clk = clock();
00364     
00365     pNodeDsd = Dsd_DecomposeOne( p->pManDsd, bFunc );
00366 p->timeDsd += clock() - clk;
00367 
00368     
00369     Dsd_TreeNodeGetInfoOne( pNodeDsd, NULL, &nMaxSize );
00370     if ( nMaxSize > 3 )
00371     {
00372         Cudd_RecursiveDeref( p->dd, bFunc );
00373         return NULL;
00374     }
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386     p->nCutsExplored++;
00387 
00388     
00389     
00390     Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00391         pLeaf->vFanouts.nSize++;
00392     
00393     Abc_NtkIncrementTravId( pRoot->pNtk );
00394     nNodesSaved = Abc_NodeMffcLabelAig( pRoot );
00395     
00396     Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00397         pLeaf->vFanouts.nSize--;
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422     
00423 clk = clock();
00424     if ( nMaxSize > 3 )
00425         pGraph = NULL;
00426     else
00427         pGraph = Abc_NodeEvaluateDsd( p, pNodeDsd, pRoot, Required, nNodesSaved, &nNodesAdded );
00428 
00429 p->timeEval += clock() - clk;
00430 
00431     
00432     if ( pGraph == NULL || nNodesAdded == -1 || nNodesAdded == nNodesSaved && !p->fUseZeros )
00433     {
00434         Cudd_RecursiveDeref( p->dd, bFunc );
00435         if ( pGraph ) Dec_GraphFree( pGraph );
00436         return NULL;
00437     }
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448     
00449     p->nLastGain = nNodesSaved - nNodesAdded;
00450     p->nNodesGained += p->nLastGain;
00451     p->nNodesRestructured++;
00452 
00453     
00454     if ( fVeryVerbose )
00455     {
00456         printf( "Node %6s : ",  Abc_ObjName(pRoot) );
00457         printf( "Cone = %2d. ", p->vLeaves->nSize );
00458         printf( "BDD = %2d. ",  Cudd_DagSize(bFunc) );
00459         printf( "FF = %2d. ",   1 + Dec_GraphNodeNum(pGraph) );
00460         printf( "MFFC = %2d. ", nNodesSaved );
00461         printf( "Add = %2d. ",  nNodesAdded );
00462         printf( "GAIN = %2d. ", p->nLastGain );
00463         printf( "\n" );
00464     }
00465     Cudd_RecursiveDeref( p->dd, bFunc );
00466     return pGraph;
00467 }
00468 
00469 
00482 void Abc_NodeEdgeDsdPermute( Dec_Graph_t * pGraph, Abc_ManRst_t * pManRst, Vec_Int_t * vEdges, int fExor )
00483 {
00484     Dec_Edge_t eNode1, eNode2, eNode3;
00485     Abc_Obj_t * pNode1, * pNode2, * pNode3, * pTemp;
00486     int LeftBound = 0, RightBound, i;
00487     
00488     RightBound = Vec_IntSize(vEdges) - 2;
00489     assert( LeftBound <= RightBound );
00490     if ( LeftBound == RightBound )
00491         return;
00492     
00493     eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound + 1) );
00494     eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound    ) );
00495     pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00496     pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00497     pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00498     pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00499     
00500     if ( pNode1 == NULL )
00501         return;
00502     
00503     for ( i = RightBound; i >= LeftBound; i-- )
00504     {
00505         
00506         eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, i) );
00507         pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00508         pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00509         if ( pNode3 == NULL )
00510             continue;
00511         
00512         if ( fExor )
00513         {
00514             if ( pNode1 && pNode3 )
00515             {
00516                 pTemp = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode3, NULL );
00517                 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00518                     continue;
00519 
00520                 if ( pNode3 == pNode2 )
00521                     return;
00522                 Vec_IntWriteEntry( vEdges, i,          Dec_EdgeToInt(eNode2) );
00523                 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00524                 return;
00525             }
00526         }
00527         else
00528         {
00529             if ( pNode1 && pNode3 )
00530             {
00531                 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00532                 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00533                     continue;
00534 
00535                 if ( eNode3.Node == eNode2.Node )
00536                     return;
00537                 Vec_IntWriteEntry( vEdges, i,          Dec_EdgeToInt(eNode2) );
00538                 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00539                 return;
00540             }
00541         }
00542     }
00543 }
00544 
00556 void Abc_NodeEdgeDsdPushOrdered( Dec_Graph_t * pGraph, Vec_Int_t * vEdges, int Edge )
00557 {
00558     int i, NodeOld, NodeNew;
00559     vEdges->nSize++;
00560     for ( i = vEdges->nSize-2; i >= 0; i-- )
00561     {
00562         NodeOld = Dec_IntToEdge(vEdges->pArray[i]).Node;
00563         NodeNew = Dec_IntToEdge(Edge).Node;
00564         
00565         if ( Dec_GraphNode(pGraph, NodeOld)->Level <= Dec_GraphNode(pGraph, NodeNew)->Level )
00566             vEdges->pArray[i+1] = vEdges->pArray[i];
00567         else
00568             break;
00569     }
00570     vEdges->pArray[i+1] = Edge;
00571 }
00572 
00584 Dec_Edge_t Abc_NodeEvaluateDsd_rec( Dec_Graph_t * pGraph, Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, int Required, int nNodesSaved, int * pnNodesAdded )
00585 {
00586     Dec_Edge_t eNode1, eNode2, eNode3, eResult, eQuit = { 0, 2006 };
00587     Abc_Obj_t * pNode1, * pNode2, * pNode3, * pNode4, * pTemp;
00588     Dsd_Node_t * pChildDsd;
00589     Dsd_Type_t DecType;
00590     Vec_Int_t * vEdges;
00591     int Level1, Level2, Level3, Level4;
00592     int i, Index, fCompl, Type;
00593 
00594     
00595     fCompl   = Dsd_IsComplement( pNodeDsd );
00596     pNodeDsd = Dsd_Regular( pNodeDsd );
00597 
00598     
00599     DecType = Dsd_NodeReadType( pNodeDsd );
00600     if ( DecType == DSD_NODE_BUF )
00601     {
00602         Index = Dsd_NodeReadFunc(pNodeDsd)->index;
00603         assert( Index < Dec_GraphLeaveNum(pGraph) );
00604         eResult = Dec_EdgeCreate( Index, fCompl );
00605         return eResult;
00606     }
00607     assert( DecType == DSD_NODE_OR || DecType == DSD_NODE_EXOR || DecType == DSD_NODE_PRIME );
00608 
00609     
00610     vEdges = Vec_IntAlloc( Dsd_NodeReadDecsNum(pNodeDsd) );
00611     Dsd_NodeForEachChild( pNodeDsd, i, pChildDsd )
00612     {
00613         eResult = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pChildDsd, Required, nNodesSaved, pnNodesAdded );
00614         if ( eResult.Node == eQuit.Node ) 
00615         {
00616             Vec_IntFree( vEdges );
00617             return eQuit;
00618         }
00619         
00620         if ( DecType == DSD_NODE_PRIME )
00621             Vec_IntPush( vEdges, Dec_EdgeToInt(eResult) );
00622         else
00623             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eResult) );
00624     }
00625     
00626 
00627 
00628     
00629     if ( DecType == DSD_NODE_OR )
00630     {
00631         
00632         assert( Vec_IntSize(vEdges) > 1 );
00633         while ( Vec_IntSize(vEdges) > 1 )
00634         {
00635             
00636             if ( Vec_IntSize(vEdges) > 2 )
00637                 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 0 );
00638             
00639             eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00640             eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00641             pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00642             pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00643             pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00644             pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00645             
00646             pNode3 = NULL;
00647             if ( pNode1 && pNode2 )
00648             {
00649                 pNode3 = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); 
00650                 pNode3 = !pNode3? NULL : Abc_ObjNot(pNode3);
00651             }
00652             
00653             eNode3 = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 );
00654             
00655             Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00656             Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00657             Dec_GraphNode( pGraph, eNode3.Node )->Level = 1 + ABC_MAX(Level1, Level2);
00658             
00659             if ( pNode3 )
00660             {
00661                 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00662                 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00663                 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00664             }
00665             if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00666             {
00667                 (*pnNodesAdded)++;
00668                 if ( *pnNodesAdded > nNodesSaved )
00669                 {
00670                     Vec_IntFree( vEdges );
00671                     return eQuit;
00672                 }
00673             }
00674             
00675             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00676         }
00677         
00678         eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00679         Vec_IntFree( vEdges );
00680         
00681         eResult.fCompl ^= fCompl;
00682         return eResult;
00683     }
00684     if ( DecType == DSD_NODE_EXOR )
00685     {
00686         
00687         assert( Vec_IntSize(vEdges) > 1 );
00688         while ( Vec_IntSize(vEdges) > 1 )
00689         {
00690             
00691             if ( Vec_IntSize(vEdges) > 2 )
00692                 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 1 );
00693             
00694             eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00695             eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00696             pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00697             pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00698             pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00699             pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00700             
00701             Type = 0;
00702             pNode3 = NULL;
00703             if ( pNode1 && pNode2 )
00704                 pNode3 = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, &Type ); 
00705             
00706             eNode3 = Dec_GraphAddNodeXor( pGraph, eNode1, eNode2, Type ); 
00707             
00708             Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00709             Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00710             Dec_GraphNode( pGraph, eNode3.Node )->Level = 2 + ABC_MAX(Level1, Level2);
00711             
00712             if ( pNode3 )
00713             {
00714                 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00715                 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00716                 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00717             }
00718             if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00719             {
00720                 (*pnNodesAdded)++;
00721                 if ( !pNode1 || !pNode2 )
00722                     (*pnNodesAdded) += 2;
00723                 else if ( Type == 0 )
00724                 {
00725                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00726                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00727                         (*pnNodesAdded)++;
00728                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode2 );
00729                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00730                         (*pnNodesAdded)++;
00731                 }
00732                 else
00733                 {
00734                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00735                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00736                         (*pnNodesAdded)++;
00737                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00738                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00739                         (*pnNodesAdded)++;
00740                 }
00741                 if ( *pnNodesAdded > nNodesSaved )
00742                 {
00743                     Vec_IntFree( vEdges );
00744                     return eQuit;
00745                 }
00746             }
00747             
00748             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00749         }
00750         
00751         eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00752         Vec_IntFree( vEdges );
00753         
00754         eResult.fCompl ^= fCompl;
00755         return eResult;
00756     }
00757     if ( DecType == DSD_NODE_PRIME )
00758     {
00759         DdNode * bLocal, * bVar, * bCofT, * bCofE;
00760         bLocal = Dsd_TreeGetPrimeFunction( pManRst->dd, pNodeDsd );  Cudd_Ref( bLocal );
00761 
00762 
00763         bVar  = pManRst->dd->vars[0];
00764         bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00765         bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00766         if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00767         {
00768             Cudd_RecursiveDeref( pManRst->dd, bCofE );
00769             Cudd_RecursiveDeref( pManRst->dd, bCofT );
00770             bVar  = pManRst->dd->vars[1];
00771             bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00772             bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00773             if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00774             {
00775                 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00776                 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00777                 bVar  = pManRst->dd->vars[2];
00778                 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00779                 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00780                 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00781                 {
00782                     Cudd_RecursiveDeref( pManRst->dd, bCofE );
00783                     Cudd_RecursiveDeref( pManRst->dd, bCofT );
00784                     Cudd_RecursiveDeref( pManRst->dd, bLocal );
00785                     Vec_IntFree( vEdges );
00786                     return eQuit;
00787                 }
00788             }
00789         }
00790         Cudd_RecursiveDeref( pManRst->dd, bLocal );
00791         
00792 
00793         
00794         eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, bVar->index) );
00795         eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofT)->index) );
00796         eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofE)->index) );
00797         
00798         eNode2.fCompl ^= Cudd_IsComplement(bCofT);
00799         eNode3.fCompl ^= Cudd_IsComplement(bCofE);
00800 
00801         
00802         Cudd_RecursiveDeref( pManRst->dd, bCofE );
00803         Cudd_RecursiveDeref( pManRst->dd, bCofT );
00804 
00805         
00806         pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00807         pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00808         pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00809         pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00810         pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00811         pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00812 
00813         
00814         Type = 0;
00815         pNode4 = NULL;
00816         if ( pNode1 && pNode2 && pNode3 )
00817             pNode4 = Abc_AigMuxLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, pNode3, &Type ); 
00818 
00819         
00820         eResult = Dec_GraphAddNodeMux( pGraph, eNode1, eNode2, eNode3, Type ); 
00821 
00822         
00823         Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00824         Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00825         Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00826         Dec_GraphNode( pGraph, eResult.Node )->Level = 2 + ABC_MAX( ABC_MAX(Level1, Level2), Level3 );
00827         
00828         if ( pNode4 )
00829         {
00830             Dec_GraphNode( pGraph, eResult.Node )->pFunc = Abc_ObjNotCond(pNode4, eResult.fCompl);
00831             Level4 = Dec_GraphNode( pGraph, eResult.Node )->Level;
00832             assert( Required == ABC_INFINITY || Level4 == (int)Abc_ObjRegular(pNode4)->Level );
00833         }
00834         if ( !pNode4 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode4)) )
00835         {
00836             (*pnNodesAdded)++;
00837             if ( Type == 0 ) 
00838             {
00839                 if ( !pNode1 || !pNode2 )
00840                     (*pnNodesAdded)++;
00841                 else
00842                 {
00843                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00844                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00845                         (*pnNodesAdded)++;
00846                 }
00847                 if ( !pNode1 || !pNode3 )
00848                     (*pnNodesAdded)++;
00849                 else
00850                 {
00851                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode3 );
00852                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00853                         (*pnNodesAdded)++;
00854                 }
00855             }
00856             else
00857             {
00858                 if ( !pNode1 || !pNode2 )
00859                     (*pnNodesAdded)++;
00860                 else
00861                 {
00862                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00863                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00864                         (*pnNodesAdded)++;
00865                 }
00866                 if ( !pNode1 || !pNode3 )
00867                     (*pnNodesAdded)++;
00868                 else
00869                 {
00870                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00871                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00872                         (*pnNodesAdded)++;
00873                 }
00874             }
00875             if ( *pnNodesAdded > nNodesSaved )
00876             {
00877                 Vec_IntFree( vEdges );
00878                 return eQuit;
00879             }
00880         }
00881 
00882         Vec_IntFree( vEdges );
00883         
00884         eResult.fCompl ^= fCompl;
00885         return eResult;
00886     }
00887     Vec_IntFree( vEdges );
00888     return eQuit;
00889 }
00890 
00902 Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded )
00903 {
00904     Dec_Graph_t * pGraph;
00905     Dec_Edge_t gEdge;
00906     Abc_Obj_t * pLeaf;
00907     Dec_Node_t * pNode;
00908     int i;
00909 
00910     
00911     pGraph = Dec_GraphCreate( Vec_PtrSize(pManRst->vLeaves) );
00912     Dec_GraphForEachLeaf( pGraph, pNode, i )
00913     {
00914         pLeaf = Vec_PtrEntry( pManRst->vLeaves, i );
00915         pNode->pFunc = pLeaf;
00916         pNode->Level = pLeaf->Level;
00917     }
00918 
00919     
00920     *pnNodesAdded = 0;
00921     gEdge = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pNodeDsd, Required, nNodesSaved, pnNodesAdded );
00922     if ( gEdge.Node > 1000 ) 
00923     {
00924         *pnNodesAdded = -1;
00925         Dec_GraphFree( pGraph );
00926         return NULL;
00927     }
00928 
00929     
00930     pLeaf = Dec_GraphNode( pGraph, gEdge.Node )->pFunc;
00931     if ( Abc_ObjRegular(pLeaf) == pRoot )
00932     {
00933         *pnNodesAdded = -1;
00934         Dec_GraphFree( pGraph );
00935         return NULL;
00936     }
00937 
00938     Dec_GraphSetRoot( pGraph, gEdge );
00939     return pGraph;
00940 }
00941 
00942 
00943 
00955 Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag )
00956 {
00957     static Cut_Params_t Params, * pParams = &Params;
00958     Cut_Man_t * pManCut;
00959     Abc_Obj_t * pObj;
00960     int i;
00961     
00962     memset( pParams, 0, sizeof(Cut_Params_t) );
00963     pParams->nVarsMax  = nCutMax; 
00964     pParams->nKeepMax  = 250;     
00965     pParams->fTruth    = 0;       
00966     pParams->fFilter   = 1;       
00967     pParams->fSeq      = 0;       
00968     pParams->fDrop     = 0;       
00969     pParams->fDag      = fDag;    
00970     pParams->fTree     = 0;       
00971     pParams->fVerbose  = 0;       
00972     pParams->nIdsMax   = Abc_NtkObjNumMax( pNtk );
00973     pManCut = Cut_ManStart( pParams );
00974     if ( pParams->fDrop )
00975         Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
00976     
00977     Abc_NtkForEachCi( pNtk, pObj, i )
00978         if ( Abc_ObjFanoutNum(pObj) > 0 )
00979             Cut_NodeSetTriv( pManCut, pObj->Id );
00980     return pManCut;
00981 }
00982 
00994 Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose )
00995 {
00996     Abc_ManRst_t * p;
00997     p = ALLOC( Abc_ManRst_t, 1 );
00998     memset( p, 0, sizeof(Abc_ManRst_t) );
00999     
01000     p->nCutMax      = nCutMax;
01001     p->fUpdateLevel = fUpdateLevel;
01002     p->fUseZeros    = fUseZeros;
01003     p->fVerbose     = fVerbose;
01004     
01005     p->dd = Cudd_Init( p->nCutMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
01006     Cudd_zddVarsFromBddVars( p->dd, 2 );
01007     
01008     p->pManDsd = Dsd_ManagerStart( p->dd, p->dd->size, 0 );
01009     
01010     p->vVisited     = Vec_PtrAlloc( 100 );
01011     p->vLeaves      = Vec_PtrAlloc( 100 );
01012     p->vDecs        = Vec_PtrAlloc( 100 );
01013     p->vTemp        = Vec_PtrAlloc( 100 );
01014     p->vSims        = Vec_IntAlloc( 100 );
01015     p->vOnes        = Vec_IntAlloc( 100 );
01016     p->vBinate      = Vec_IntAlloc( 100 );
01017     p->vTwos        = Vec_IntAlloc( 100 );
01018     p->vRands       = Vec_IntAlloc( 20 );
01019     
01020     {
01021         int i;
01022         for ( i = 0; i < 20; i++ )
01023             Vec_IntPush( p->vRands, (int)RST_RANDOM_UNSIGNED );
01024     }
01025     return p;
01026 }
01027 
01039 void Abc_NtkManRstStop( Abc_ManRst_t * p )
01040 {
01041     Dsd_ManagerStop( p->pManDsd );
01042     Extra_StopManager( p->dd );
01043     Vec_PtrFree( p->vDecs );
01044     Vec_PtrFree( p->vLeaves );
01045     Vec_PtrFree( p->vVisited );
01046     Vec_PtrFree( p->vTemp );
01047     Vec_IntFree( p->vSims );
01048     Vec_IntFree( p->vOnes );
01049     Vec_IntFree( p->vBinate );
01050     Vec_IntFree( p->vTwos );
01051     Vec_IntFree( p->vRands );
01052     free( p );
01053 }
01054 
01066 void Abc_NtkManRstPrintStats( Abc_ManRst_t * p )
01067 {
01068     printf( "Refactoring statistics:\n" );
01069     printf( "Nodes considered   = %8d.\n", p->nNodesConsidered   );
01070     printf( "Cuts considered    = %8d.\n", p->nCutsConsidered    );
01071     printf( "Cuts explored      = %8d.\n", p->nCutsExplored      );
01072     printf( "Nodes restructured = %8d.\n", p->nNodesRestructured );
01073     printf( "Calculated gain    = %8d.\n", p->nNodesGained       );
01074     PRT( "Cuts       ", p->timeCut );
01075     PRT( "Resynthesis", p->timeRes );
01076     PRT( "    BDD    ", p->timeBdd );
01077     PRT( "    DSD    ", p->timeDsd );
01078     PRT( "    Eval   ", p->timeEval );
01079     PRT( "AIG update ", p->timeNtk );
01080     PRT( "TOTAL      ", p->timeTotal );
01081 }
01082 
01083 
01095 int Abc_Abc_NodeResubCollectDivs( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
01096 {
01097     Abc_Obj_t * pNode, * pFanout;
01098     int i, k;
01099     
01100     Vec_PtrClear( p->vDecs );
01101     Abc_NtkIncrementTravId( pRoot->pNtk );
01102     for ( i = 0; i < (int)pCut->nLeaves; i++ )
01103     {
01104         pNode = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
01105         if ( pNode == NULL )  
01106             return 0;
01107         Vec_PtrPush( p->vDecs, pNode );
01108         Abc_NodeSetTravIdCurrent( pNode );        
01109     }
01110     
01111     Vec_PtrForEachEntry( p->vDecs, pNode, i )
01112     {
01113         
01114         Abc_ObjForEachFanout( pNode, pFanout, k )
01115         {
01116             if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsPo(pFanout) )
01117                 continue;
01118             if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) )
01119             {
01120                 Vec_PtrPush( p->vDecs, pFanout );
01121                 Abc_NodeSetTravIdCurrent( pFanout );     
01122             }
01123         }
01124     }
01125     return 1;
01126 }
01127 
01139 int Abc_NodeResubMffc_rec( Abc_Obj_t * pNode )
01140 {
01141     if ( Abc_NodeIsTravIdCurrent(pNode) )
01142         return 0;
01143     Abc_NodeSetTravIdCurrent( pNode ); 
01144     return 1 + Abc_NodeResubMffc_rec( Abc_ObjFanin0(pNode) ) +
01145         Abc_NodeResubMffc_rec( Abc_ObjFanin1(pNode) );
01146 }
01147 
01159 int Abc_NodeResubMffc( Abc_ManRst_t * p, Vec_Ptr_t * vDecs, int nLeaves, Abc_Obj_t * pRoot )
01160 {
01161     Abc_Obj_t * pObj;
01162     int Counter, i, k;
01163     
01164     Abc_NtkIncrementTravId( pRoot->pNtk );
01165     
01166     Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01167         Abc_NodeSetTravIdCurrent( pObj ); 
01168     
01169     assert( Abc_NodeIsTravIdPrevious(pRoot) );
01170     Counter = Abc_NodeResubMffc_rec( pRoot );
01171     
01172     Vec_PtrClear( p->vTemp );
01173     k = 0;
01174     Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01175         if ( Abc_NodeIsTravIdCurrent(pObj) )
01176             Vec_PtrPush( p->vTemp, pObj );
01177         else
01178             Vec_PtrWriteEntry( vDecs, k++, pObj );
01179     
01180     Vec_PtrForEachEntry( p->vTemp, pObj, i )
01181         Vec_PtrWriteEntry( vDecs, k++, pObj );
01182     assert( k == Vec_PtrSize(p->vDecs) );
01183     assert( pRoot == Vec_PtrEntryLast(p->vDecs) );
01184     return Counter;
01185 }
01186 
01198 void Abc_NodeMffcSimulate( Vec_Ptr_t * vDecs, int nLeaves, Vec_Int_t * vRands, Vec_Int_t * vSims )
01199 {
01200     Abc_Obj_t * pObj;
01201     unsigned uData0, uData1, uData;
01202     int i;
01203     
01204     Vec_IntClear( vSims );
01205     Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01206     {
01207         uData = (unsigned)Vec_IntEntry( vRands, i );
01208         pObj->pData = (void *)uData;
01209         Vec_IntPush( vSims, uData );
01210     }
01211     
01212     Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01213     {
01214         uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
01215         uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData;
01216         uData = (Abc_ObjFaninC0(pObj)? ~uData0 : uData0) & (Abc_ObjFaninC1(pObj)? ~uData1 : uData1);
01217         pObj->pData = (void *)uData;
01218         Vec_IntPush( vSims, uData );
01219     }
01220 }
01221 
01233 int Abc_NodeCheckFull( Abc_ManRst_t * p, Dec_Graph_t * pGraph )
01234 {
01235     return 1;
01236 }
01248 Dec_Graph_t * Abc_NodeMffcConstants( Abc_ManRst_t * p, Vec_Int_t * vSims )
01249 {
01250     Dec_Graph_t * pGraph;
01251     unsigned uRoot;
01252     
01253     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01254     
01255     if ( uRoot == 0 )
01256         pGraph = Dec_GraphCreateConst0();
01257     else if ( uRoot == ~(unsigned)0 )
01258         pGraph = Dec_GraphCreateConst1();
01259     
01260     if ( Abc_NodeCheckFull( p, pGraph ) )
01261         return pGraph;
01262     Dec_GraphFree( pGraph );
01263     return NULL;
01264 }
01265 
01277 Dec_Graph_t * Abc_NodeMffcSingleVar( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01278 {
01279     Dec_Graph_t * pGraph;
01280     unsigned uRoot, uNode;
01281     int i;
01282 
01283     Vec_IntClear( vOnes );
01284     Vec_IntClear( p->vBinate );
01285     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01286     for ( i = 0; i < nNodes; i++ )
01287     {
01288         uNode = (unsigned)Vec_IntEntry( vSims, i );
01289         if ( uRoot == uNode || uRoot == ~uNode )
01290         {
01291             pGraph = Dec_GraphCreate( 1 );
01292             Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, i );
01293             Dec_GraphSetRoot( pGraph, Dec_IntToEdge( (int)(uRoot == ~uNode) ) );
01294             
01295             if ( Abc_NodeCheckFull( p, pGraph ) )
01296                 return pGraph;
01297             Dec_GraphFree( pGraph );
01298         }
01299         if ( (uRoot & uNode) == 0 )
01300             Vec_IntPush( vOnes, i << 1 );
01301         else if ( (uRoot & ~uNode) == 0 )
01302             Vec_IntPush( vOnes, (i << 1) + 1 );
01303         else
01304             Vec_IntPush( p->vBinate, i );
01305     }    
01306     return NULL;
01307 }
01308 
01320 Dec_Graph_t * Abc_NodeMffcSingleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01321 {
01322     Dec_Graph_t * pGraph;
01323     Dec_Edge_t eNode0, eNode1, eRoot;
01324     unsigned uRoot;
01325     int i, k;
01326     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01327     for ( i = 0; i < vOnes->nSize; i++ )
01328         for ( k = i+1; k < vOnes->nSize; k++ )
01329             if ( ~uRoot == ((unsigned)vOnes->pArray[i] | (unsigned)vOnes->pArray[k]) )
01330             {
01331                 eNode0 = Dec_IntToEdge( vOnes->pArray[i] ^ 1 );
01332                 eNode1 = Dec_IntToEdge( vOnes->pArray[k] ^ 1 );
01333                 pGraph = Dec_GraphCreate( 2 );
01334                 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, eNode0.Node );
01335                 Dec_GraphNode( pGraph, 1 )->pFunc = Vec_PtrEntry( p->vDecs, eNode1.Node );
01336                 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
01337                 Dec_GraphSetRoot( pGraph, eRoot );
01338                 if ( Abc_NodeCheckFull( p, pGraph ) )
01339                     return pGraph;
01340                 Dec_GraphFree( pGraph );
01341             }
01342     return NULL;
01343 }
01344 
01356 Dec_Graph_t * Abc_NodeMffcDoubleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01357 {
01358 
01359 
01360 
01361 
01362 
01363     return NULL;
01364 }
01365 
01377 Dec_Graph_t * Abc_NodeResubEval( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
01378 {
01379     Dec_Graph_t * pGraph;
01380     int nNodesSaved;
01381 
01382     
01383     if ( !Abc_Abc_NodeResubCollectDivs( p, pRoot, pCut ) )
01384         return NULL;
01385 
01386     
01387     nNodesSaved = Abc_NodeResubMffc( p, p->vDecs, pCut->nLeaves, pRoot );
01388     assert( nNodesSaved > 0 );
01389 
01390     
01391     Abc_NodeMffcSimulate( p->vDecs, pCut->nLeaves, p->vRands, p->vSims );
01392 
01393     
01394     pGraph = Abc_NodeMffcConstants( p, p->vSims );
01395     if ( pGraph )
01396     {
01397         p->nNodesGained += nNodesSaved;
01398         p->nNodesRestructured++;
01399         return pGraph;
01400     }
01401 
01402     
01403     pGraph = Abc_NodeMffcSingleVar( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01404     if ( pGraph )
01405     {
01406         p->nNodesGained += nNodesSaved;
01407         p->nNodesRestructured++;
01408         return pGraph;
01409     }
01410     if ( nNodesSaved == 1 )
01411         return NULL;
01412 
01413     
01414     pGraph = Abc_NodeMffcSingleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01415     if ( pGraph )
01416     {
01417         p->nNodesGained += nNodesSaved - 1;
01418         p->nNodesRestructured++;
01419         return pGraph;
01420     }
01421     if ( nNodesSaved == 2 )
01422         return NULL;
01423 
01424     
01425     pGraph = Abc_NodeMffcDoubleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01426     if ( pGraph )
01427     {
01428         p->nNodesGained += nNodesSaved - 2;
01429         p->nNodesRestructured++;
01430         return pGraph;
01431     }
01432     if ( nNodesSaved == 3 )
01433         return NULL;
01434 
01435 
01436 
01437 
01438 
01439 
01440 
01441 
01442 
01443 
01444     return NULL;
01445 }
01446 
01458 Dec_Graph_t * Abc_NodeResubstitute( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList )
01459 {
01460     Dec_Graph_t * pGraph, * pGraphBest = NULL;
01461     Cut_Cut_t * pCut;
01462     int nCuts;
01463     p->nNodesConsidered++;
01464 
01465     
01466     nCuts = 0;
01467     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01468         nCuts += (int)(pCut->nLeaves > 3);
01469     printf( "-----------------------------------\n" );
01470     printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts );
01471 
01472     
01473     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01474     {
01475         if ( pCut->nLeaves < 4 )
01476             continue;
01477         pGraph = Abc_NodeResubEval( p, pNode, pCut );
01478         if ( pGraph == NULL )
01479             continue;
01480         if ( !pGraphBest || Dec_GraphNodeNum(pGraph) < Dec_GraphNodeNum(pGraphBest) )
01481         {
01482             if ( pGraphBest ) 
01483                 Dec_GraphFree(pGraphBest);
01484             pGraphBest = pGraph;
01485         }
01486         else
01487             Dec_GraphFree(pGraph);
01488     }
01489     return pGraphBest;
01490 }
01491 
01495 
01496