00001
00019 #include "extra.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #define _TABLESIZE_COF 51113
00035 typedef struct
00036 {
00037 unsigned Sign;
00038 DdNode * Arg1;
00039 } _HashEntry_cof;
00040 _HashEntry_cof HHTable1[_TABLESIZE_COF];
00041
00042
00043 #define _TABLESIZE_MINT 15113
00044 typedef struct
00045 {
00046 DdNode * Arg1;
00047 unsigned Arg2;
00048 unsigned Res;
00049 } _HashEntry_mint;
00050 _HashEntry_mint HHTable2[_TABLESIZE_MINT];
00051
00052 typedef struct
00053 {
00054 int nEdges;
00055 DdNode * bSum;
00056 } traventry;
00057
00058
00059 static unsigned s_Signature = 1;
00060
00061 static int s_CutLevel = 0;
00062
00063
00064
00065
00066
00067
00068
00069 static int s_MaxDepth = 5;
00070
00071 static int s_nVarsBest;
00072 static int s_VarOrderBest[32];
00073 static int s_VarOrderCur[32];
00074
00075
00076 static DdNode * s_Field[8][256];
00077 static DdNode * s_Encoded;
00078 static DdNode * s_VarAll;
00079 static int s_MultiStart;
00080
00081
00082 static DdNode ** s_pbTemp;
00083
00084 static int s_BackTracks;
00085 static int s_BackTrackLimit = 100;
00086
00087 static DdNode * s_Terminal;
00088
00089
00090 static int s_EncodingVarsLevel;
00091
00092
00093
00094
00095
00096
00097
00100
00101
00102
00103
00104 static DdNode * CreateTheCodes_rec( DdManager * dd, DdNode * bEncoded, int Level, DdNode ** pCVars );
00105 static void EvaluateEncodings_rec( DdManager * dd, DdNode * bVarsCol, int nVarsCol, int nMulti, int Level );
00106
00107 static DdNode * ComputeVarSetAndCountMinterms( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost );
00108 static DdNode * ComputeVarSetAndCountMinterms2( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost );
00109 unsigned Extra_CountCofactorMinterms( DdManager * dd, DdNode * bFunc, DdNode * bVarsCof, DdNode * bVarsAll );
00110 static unsigned Extra_CountMintermsSimple( DdNode * bFunc, unsigned max );
00111
00112 static void CountNodeVisits_rec( DdManager * dd, DdNode * aFunc, st_table * Visited );
00113 static void CollectNodesAndComputePaths_rec( DdManager * dd, DdNode * aFunc, DdNode * bCube, st_table * Visited, st_table * CutNodes );
00114
00118
00119
00120
00121
00134 DdNode *
00135 Extra_bddEncodingBinary(
00136 DdManager * dd,
00137 DdNode ** pbFuncs,
00138 int nFuncs,
00139 DdNode ** pbVars,
00140 int nVars )
00141 {
00142 int i;
00143 DdNode * bResult;
00144 DdNode * bCube, * bTemp, * bProd;
00145
00146 assert( nVars >= Extra_Base2Log(nFuncs) );
00147
00148 bResult = b0; Cudd_Ref( bResult );
00149 for ( i = 0; i < nFuncs; i++ )
00150 {
00151 bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube );
00152 bProd = Cudd_bddAnd( dd, bCube, pbFuncs[i] ); Cudd_Ref( bProd );
00153 Cudd_RecursiveDeref( dd, bCube );
00154
00155 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
00156 Cudd_RecursiveDeref( dd, bTemp );
00157 Cudd_RecursiveDeref( dd, bProd );
00158 }
00159
00160 Cudd_Deref( bResult );
00161 return bResult;
00162 }
00163
00164
00180 DdNode *
00181 Extra_bddEncodingNonStrict(
00182 DdManager * dd,
00183 DdNode ** pbColumns,
00184 int nColumns,
00185 DdNode * bVarsCol,
00186 DdNode ** pCVars,
00187 int nMulti,
00188 int * pSimple )
00189 {
00190 DdNode * bEncoded, * bResult;
00191 int nVarsCol = Cudd_SupportSize(dd,bVarsCol);
00192 long clk;
00193
00194
00195 assert( nMulti < 32 );
00196
00197
00198 bEncoded = Extra_bddEncodingBinary( dd, pbColumns, nColumns, pCVars, nMulti ); Cudd_Ref( bEncoded );
00199
00200
00201
00202 s_Terminal = b0;
00203
00204 s_EncodingVarsLevel = dd->invperm[pCVars[0]->index];
00205
00206
00207 s_BackTracks = 0;
00208
00209 s_Field[0][0] = b1;
00210
00211 s_nVarsBest = 0;
00212
00213
00214 s_Encoded = bEncoded;
00215
00216 s_VarAll = bVarsCol;
00217
00218 s_MultiStart = nMulti;
00219
00220
00221 clk = clock();
00222
00223 if ( nColumns > 2 )
00224 EvaluateEncodings_rec( dd, bVarsCol, nVarsCol, nMulti, 1 );
00225
00226
00227
00228
00229 s_pbTemp = (DdNode **) malloc( nColumns * sizeof(DdNode *) );
00230
00231
00232 bResult = CreateTheCodes_rec( dd, bEncoded, 0, pCVars ); Cudd_Ref( bResult );
00233
00234
00235
00236 Cudd_RecursiveDeref( dd, bEncoded );
00237
00238
00239 free( s_pbTemp );
00240
00241 *pSimple = s_nVarsBest;
00242 Cudd_Deref( bResult );
00243 return bResult;
00244 }
00245
00260 st_table * Extra_bddNodePathsUnderCut( DdManager * dd, DdNode * bFunc, int CutLevel )
00261 {
00262 st_table * Visited;
00263 st_table * CutNodes;
00264 st_table * Result;
00265 DdNode * aFunc;
00266
00267 s_CutLevel = CutLevel;
00268
00269 Result = st_init_table(st_ptrcmp,st_ptrhash);
00270
00271 if ( Cudd_IsConstant( bFunc ) )
00272 {
00273 if ( bFunc == b1 )
00274 {
00275 st_insert( Result, (char*)b1, (char*)b1 );
00276 Cudd_Ref( b1 );
00277 Cudd_Ref( b1 );
00278 }
00279 else
00280 {
00281 st_insert( Result, (char*)b0, (char*)b0 );
00282 Cudd_Ref( b0 );
00283 Cudd_Ref( b0 );
00284 }
00285 return Result;
00286 }
00287
00288
00289 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
00290
00291
00292
00293 Visited = st_init_table(st_ptrcmp,st_ptrhash);
00294 CutNodes = st_init_table(st_ptrcmp,st_ptrhash);
00295
00296 CountNodeVisits_rec( dd, aFunc, Visited );
00297
00298
00299 CollectNodesAndComputePaths_rec( dd, aFunc, b1, Visited, CutNodes );
00300
00301
00302 {
00303 st_generator * gen;
00304 DdNode * aNode;
00305 traventry * p;
00306 st_foreach_item( Visited, gen, (char**)&aNode, (char**)&p )
00307 {
00308 Cudd_RecursiveDeref( dd, p->bSum );
00309 free( p );
00310 }
00311 st_free_table( Visited );
00312 }
00313
00314
00315 {
00316 st_generator * gen;
00317 DdNode * aNode, * bNode, * bSum;
00318 st_foreach_item( CutNodes, gen, (char**)&aNode, (char**)&bSum)
00319 {
00320
00321 bNode = Cudd_addBddPattern( dd, aNode ); Cudd_Ref( bNode );
00322 st_insert( Result, (char*)bNode, (char*)bSum );
00323
00324 }
00325 st_free_table( CutNodes );
00326 }
00327
00328
00329 Cudd_RecursiveDeref( dd, aFunc );
00330
00331
00332 return Result;
00333
00334 }
00335
00352 int Extra_bddNodePathsUnderCutArray( DdManager * dd, DdNode ** paNodes, DdNode ** pbCubes, int nNodes, DdNode ** paNodesRes, DdNode ** pbCubesRes, int CutLevel )
00353 {
00354 st_table * Visited;
00355 st_table * CutNodes;
00356 int i, Counter;
00357
00358 s_CutLevel = CutLevel;
00359
00360
00361 assert( nNodes > 0 );
00362 if ( nNodes == 1 && Cudd_IsConstant( paNodes[0] ) )
00363 {
00364 if ( paNodes[0] == a1 )
00365 {
00366 paNodesRes[0] = a1; Cudd_Ref( a1 );
00367 pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
00368 }
00369 else
00370 {
00371 paNodesRes[0] = a0; Cudd_Ref( a0 );
00372 pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
00373 }
00374 return 1;
00375 }
00376
00377
00378
00379 CutNodes = st_init_table(st_ptrcmp,st_ptrhash);
00380 Visited = st_init_table(st_ptrcmp,st_ptrhash);
00381
00382 for ( i = 0; i < nNodes; i++ )
00383 CountNodeVisits_rec( dd, paNodes[i], Visited );
00384
00385
00386 for ( i = 0; i < nNodes; i++ )
00387 CollectNodesAndComputePaths_rec( dd, paNodes[i], pbCubes[i], Visited, CutNodes );
00388
00389
00390 {
00391 st_generator * gen;
00392 DdNode * aNode;
00393 traventry * p;
00394 st_foreach_item( Visited, gen, (char**)&aNode, (char**)&p )
00395 {
00396 Cudd_RecursiveDeref( dd, p->bSum );
00397 free( p );
00398 }
00399 st_free_table( Visited );
00400 }
00401
00402
00403 {
00404 st_generator * gen;
00405 DdNode * aNode, * bSum;
00406 Counter = 0;
00407 st_foreach_item( CutNodes, gen, (char**)&aNode, (char**)&bSum)
00408 {
00409 paNodesRes[Counter] = aNode; Cudd_Ref( aNode );
00410 pbCubesRes[Counter] = bSum;
00411 Counter++;
00412 }
00413 st_free_table( CutNodes );
00414 }
00415
00416
00417 return Counter;
00418
00419 }
00420
00432 void extraCollectNodes( DdNode * Func, st_table * tNodes )
00433 {
00434 DdNode * FuncR;
00435 FuncR = Cudd_Regular(Func);
00436 if ( st_find_or_add( tNodes, (char*)FuncR, NULL ) )
00437 return;
00438 if ( cuddIsConstant(FuncR) )
00439 return;
00440 extraCollectNodes( cuddE(FuncR), tNodes );
00441 extraCollectNodes( cuddT(FuncR), tNodes );
00442 }
00443
00455 st_table * Extra_CollectNodes( DdNode * Func )
00456 {
00457 st_table * tNodes;
00458 tNodes = st_init_table( st_ptrcmp, st_ptrhash );
00459 extraCollectNodes( Func, tNodes );
00460 return tNodes;
00461 }
00462
00477 void extraProfileUpdateTopLevel( st_table * tNodeTopRef, int TopLevelNew, DdNode * node )
00478 {
00479 int * pTopLevel;
00480
00481 if ( st_find_or_add( tNodeTopRef, (char*)node, (char***)&pTopLevel ) )
00482 {
00483
00484 if ( *pTopLevel > TopLevelNew )
00485 *pTopLevel = TopLevelNew;
00486 }
00487 else
00488 {
00489
00490 *pTopLevel = TopLevelNew;
00491 }
00492 }
00516 int Extra_ProfileWidth( DdManager * dd, DdNode * Func, int * pProfile, int CutLevel )
00517 {
00518 st_generator * gen;
00519 st_table * tNodeTopRef;
00520 st_table * tNodes;
00521 DdNode * node;
00522 DdNode * nodeR;
00523 int LevelStart, Limit;
00524 int i, size;
00525 int WidthMax;
00526
00527
00528 tNodeTopRef = st_init_table(st_ptrcmp,st_ptrhash);
00529
00530 extraProfileUpdateTopLevel( tNodeTopRef, 0, Func );
00531
00532
00533 tNodes = Extra_CollectNodes( Func );
00534
00535
00536 st_foreach_item( tNodes, gen, (char**)&node, NULL )
00537 {
00538
00539 nodeR = Cudd_Regular(node);
00540 if ( cuddIsConstant(nodeR) )
00541 continue;
00542
00543 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddE(nodeR) );
00544 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddT(nodeR) );
00545 }
00546 st_free_table( tNodes );
00547
00548
00549 size = ddMax(dd->size, dd->sizeZ) + 1;
00550 for ( i = 0; i < size; i++ )
00551 pProfile[i] = 0;
00552
00553
00554 st_foreach_item( tNodeTopRef, gen, (char**)&node, (char**)&LevelStart )
00555 {
00556 nodeR = Cudd_Regular(node);
00557 Limit = (cuddIsConstant(nodeR))? dd->size: dd->perm[nodeR->index];
00558 for ( i = LevelStart; i <= Limit; i++ )
00559 pProfile[i]++;
00560 }
00561
00562 if ( CutLevel != -1 && CutLevel != 0 )
00563 size = CutLevel;
00564
00565
00566 WidthMax = 0;
00567 for ( i = 0; i < size; i++ )
00568 if ( WidthMax < pProfile[i] )
00569 WidthMax = pProfile[i];
00570
00571
00572 st_free_table( tNodeTopRef );
00573
00574 return WidthMax;
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00596 DdNode * CreateTheCodes_rec( DdManager * dd, DdNode * bEncoded, int Level, DdNode ** pCVars )
00597
00598
00599
00600 {
00601 DdNode * bRes;
00602 if ( Level == s_nVarsBest )
00603 {
00604
00605 st_table * CutNodes;
00606 int nCols;
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 CutNodes = Extra_bddNodePathsUnderCut( dd, bEncoded, s_EncodingVarsLevel );
00628
00629
00630
00631
00632
00633 {
00634 st_generator * gen;
00635 DdNode * bColumn, * bCode;
00636 nCols = 0;
00637 st_foreach_item( CutNodes, gen, (char**)&bCode, (char**)&bColumn )
00638 {
00639 if ( bCode == b0 )
00640 {
00641 Cudd_RecursiveDeref( dd, bColumn );
00642 Cudd_RecursiveDeref( dd, bCode );
00643 continue;
00644 }
00645 else
00646 {
00647 s_pbTemp[ nCols ] = bColumn;
00648 Cudd_RecursiveDeref( dd, bCode );
00649 nCols++;
00650 }
00651 }
00652 st_free_table( CutNodes );
00653
00654 }
00655
00656
00657 if ( s_MultiStart-Level == 0 )
00658 {
00659 assert( nCols == 1 );
00660
00661 bRes = s_pbTemp[0]; Cudd_Ref( bRes );
00662 }
00663 else
00664 {
00665 bRes = Extra_bddEncodingBinary( dd, s_pbTemp, nCols, pCVars+Level, s_MultiStart-Level ); Cudd_Ref( bRes );
00666 }
00667
00668
00669 {
00670 int i;
00671 for ( i = 0; i < nCols; i++ )
00672 Cudd_RecursiveDeref( dd, s_pbTemp[i] );
00673 }
00674 }
00675 else
00676 {
00677
00678 DdNode * bCof0, * bCof1;
00679 DdNode * bRes0, * bRes1;
00680 DdNode * bProd0, * bProd1;
00681 DdNode * bTemp;
00682 DdNode * bVarNext = dd->vars[ s_VarOrderBest[Level] ];
00683
00684 bCof0 = Cudd_Cofactor( dd, bEncoded, Cudd_Not( bVarNext ) ); Cudd_Ref( bCof0 );
00685 bCof1 = Cudd_Cofactor( dd, bEncoded, bVarNext ); Cudd_Ref( bCof1 );
00686
00687
00688 bRes0 = CreateTheCodes_rec( dd, bCof0, Level+1, pCVars ); Cudd_Ref( bRes0 );
00689 bRes1 = CreateTheCodes_rec( dd, bCof1, Level+1, pCVars ); Cudd_Ref( bRes1 );
00690
00691 Cudd_RecursiveDeref( dd, bCof0 );
00692 Cudd_RecursiveDeref( dd, bCof1 );
00693
00694
00695
00696 bProd0 = Cudd_bddAnd( dd, Cudd_Not(bVarNext), Cudd_Not(pCVars[Level]) ); Cudd_Ref( bProd0 );
00697 bProd1 = Cudd_bddAnd( dd, bVarNext , pCVars[Level] ); Cudd_Ref( bProd1 );
00698
00699 bProd0 = Cudd_bddAnd( dd, bTemp = bProd0, bRes0 ); Cudd_Ref( bProd0 );
00700 Cudd_RecursiveDeref( dd, bTemp );
00701 Cudd_RecursiveDeref( dd, bRes0 );
00702
00703 bProd1 = Cudd_bddAnd( dd, bTemp = bProd1, bRes1 ); Cudd_Ref( bProd1 );
00704 Cudd_RecursiveDeref( dd, bTemp );
00705 Cudd_RecursiveDeref( dd, bRes1 );
00706
00707 bRes = Cudd_bddOr( dd, bProd0, bProd1 ); Cudd_Ref( bRes );
00708
00709 Cudd_RecursiveDeref( dd, bProd0 );
00710 Cudd_RecursiveDeref( dd, bProd1 );
00711 }
00712 Cudd_Deref( bRes );
00713 return bRes;
00714 }
00715
00727 void EvaluateEncodings_rec( DdManager * dd, DdNode * bVarsCol, int nVarsCol, int nMulti, int Level )
00728
00729
00730
00731
00732
00733 {
00734 int i, k;
00735 int nEntries = (1<<(Level-1));
00736 DdNode * bVars0, * bVars1;
00737 unsigned nMint0, nMint1;
00738 DdNode * bTempV;
00739 DdNode * bVarTop;
00740 int fBreak;
00741
00742
00743
00744 if ( Level > s_MaxDepth )
00745 return;
00746
00747
00748 if ( bVarsCol == b1 )
00749 return;
00750
00751 if ( s_BackTracks > s_BackTrackLimit )
00752 return;
00753
00754 s_BackTracks++;
00755
00756
00757 for ( bTempV = bVarsCol; bTempV != b1; bTempV = cuddT(bTempV) )
00758 {
00759
00760 bVarTop = dd->vars[bTempV->index];
00761
00762
00763 s_VarOrderCur[Level-1] = bTempV->index;
00764
00765
00766 fBreak = 0;
00767 for ( i = 0; i < nEntries; i++ )
00768 {
00769 bVars0 = ComputeVarSetAndCountMinterms( dd, s_Field[Level-1][i], Cudd_Not(bVarTop), &nMint0 );
00770 Cudd_Ref( bVars0 );
00771
00772 if ( nMint0 > Extra_Power2( nMulti-1 ) )
00773 {
00774
00775 Cudd_RecursiveDeref( dd, bVars0 );
00776 fBreak = 1;
00777 break;
00778 }
00779
00780 bVars1 = ComputeVarSetAndCountMinterms( dd, s_Field[Level-1][i], bVarTop, &nMint1 );
00781 Cudd_Ref( bVars1 );
00782
00783 if ( nMint1 > Extra_Power2( nMulti-1 ) )
00784 {
00785
00786 Cudd_RecursiveDeref( dd, bVars0 );
00787 Cudd_RecursiveDeref( dd, bVars1 );
00788 fBreak = 1;
00789 break;
00790 }
00791
00792
00793 s_Field[Level][2*i + 0] = bVars0;
00794 s_Field[Level][2*i + 1] = bVars1;
00795 }
00796
00797 if ( !fBreak )
00798 {
00799 DdNode * bVarsRem;
00800
00801
00802 if ( s_nVarsBest < Level )
00803 {
00804 s_nVarsBest = Level;
00805
00806 for ( k = 0; k < Level; k++ )
00807 s_VarOrderBest[k] = s_VarOrderCur[k];
00808 }
00809
00810
00811
00812 if ( nMulti-1 > 0 )
00813 {
00814 bVarsRem = Cudd_bddExistAbstract( dd, bVarsCol, bVarTop ); Cudd_Ref( bVarsRem );
00815 EvaluateEncodings_rec( dd, bVarsRem, nVarsCol-1, nMulti-1, Level+1 );
00816 Cudd_RecursiveDeref( dd, bVarsRem );
00817 }
00818 }
00819
00820
00821 for ( k = 0; k < i; k++ )
00822 {
00823 Cudd_RecursiveDeref( dd, s_Field[Level][2*k + 0] );
00824 Cudd_RecursiveDeref( dd, s_Field[Level][2*k + 1] );
00825 }
00826
00827
00828 if ( s_nVarsBest == s_MaxDepth )
00829 return;
00830
00831
00832 if ( s_nVarsBest == s_MultiStart )
00833 return;
00834 }
00835
00836 }
00837
00849 DdNode * ComputeVarSetAndCountMinterms( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost )
00850
00851
00852
00853 {
00854 DdNode * bVarsRes;
00855
00856
00857 bVarsRes = Cudd_bddAnd( dd, bVars, bVarTop ); Cudd_Ref( bVarsRes );
00858
00859
00860 s_Signature++;
00861 *Cost = Extra_CountCofactorMinterms( dd, s_Encoded, bVarsRes, s_VarAll );
00862
00863 Cudd_Deref( bVarsRes );
00864
00865 return bVarsRes;
00866 }
00867
00879 DdNode * ComputeVarSetAndCountMinterms2( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost )
00880 {
00881 DdNode * bVarsRes;
00882 DdNode * bCof, * bFun;
00883
00884 bVarsRes = Cudd_bddAnd( dd, bVars, bVarTop ); Cudd_Ref( bVarsRes );
00885
00886 bCof = Cudd_Cofactor( dd, s_Encoded, bVarsRes ); Cudd_Ref( bCof );
00887 bFun = Cudd_bddExistAbstract( dd, bCof, s_VarAll ); Cudd_Ref( bFun );
00888 *Cost = (unsigned)Cudd_CountMinterm( dd, bFun, s_MultiStart );
00889 Cudd_RecursiveDeref( dd, bFun );
00890 Cudd_RecursiveDeref( dd, bCof );
00891
00892 Cudd_Deref( bVarsRes );
00893
00894 return bVarsRes;
00895 }
00896
00897
00907 unsigned Extra_CountCofactorMinterms( DdManager * dd, DdNode * bFunc, DdNode * bVarsCof, DdNode * bVarsAll )
00908
00909
00910
00911
00912 {
00913 unsigned HKey;
00914 DdNode * bFuncR;
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 bFuncR = Cudd_Regular(bFunc);
00930
00931 HKey = hashKey2( s_Signature, bFunc, _TABLESIZE_COF );
00932 for ( ; HHTable1[HKey].Sign == s_Signature; HKey = (HKey+1) % _TABLESIZE_COF )
00933
00934 if ( HHTable1[HKey].Arg1 == bFunc )
00935 return 0;
00936
00937
00938
00939 if ( dd->perm[bFuncR->index] >= s_EncodingVarsLevel )
00940 {
00941
00942
00943
00944
00945
00946 assert( HHTable1[HKey].Sign != s_Signature );
00947 HHTable1[HKey].Sign = s_Signature;
00948
00949 HHTable1[HKey].Arg1 = bFunc;
00950
00951 return Extra_CountMintermsSimple( bFunc, (1<<s_MultiStart) );
00952 }
00953 else
00954 {
00955 DdNode * bFunc0, * bFunc1;
00956 DdNode * bVarsCof0, * bVarsCof1;
00957 DdNode * bVarsCofR = Cudd_Regular(bVarsCof);
00958 unsigned Res;
00959
00960
00961 int LevelF = dd->perm[bFuncR->index];
00962 int LevelC = cuddI(dd,bVarsCofR->index);
00963 int LevelA = dd->perm[bVarsAll->index];
00964
00965 int LevelTop = LevelF;
00966
00967 if ( LevelTop > LevelC )
00968 LevelTop = LevelC;
00969
00970 if ( LevelTop > LevelA )
00971 LevelTop = LevelA;
00972
00973
00974 assert( !( LevelTop == LevelF || LevelTop == LevelC ) || LevelTop == LevelA );
00975
00976
00977 if ( LevelTop == LevelF )
00978 {
00979 if ( bFuncR != bFunc )
00980 {
00981 bFunc0 = Cudd_Not( cuddE(bFuncR) );
00982 bFunc1 = Cudd_Not( cuddT(bFuncR) );
00983 }
00984 else
00985 {
00986 bFunc0 = cuddE(bFuncR);
00987 bFunc1 = cuddT(bFuncR);
00988 }
00989 }
00990 else
00991 bFunc0 = bFunc1 = bFunc;
00992
00993
00994 if ( LevelTop == LevelC )
00995 {
00996 if ( bVarsCofR != bVarsCof )
00997 {
00998 bVarsCof0 = Cudd_Not( cuddE(bVarsCofR) );
00999 bVarsCof1 = Cudd_Not( cuddT(bVarsCofR) );
01000 }
01001 else
01002 {
01003 bVarsCof0 = cuddE(bVarsCofR);
01004 bVarsCof1 = cuddT(bVarsCofR);
01005 }
01006 }
01007 else
01008 bVarsCof0 = bVarsCof1 = bVarsCof;
01009
01010
01011
01012
01013
01014
01015 Res = 0;
01016 if ( LevelTop == LevelC )
01017 {
01018 if ( bVarsCof1 == b0 )
01019 {
01020 if ( bFunc0 != b0 )
01021 Res = Extra_CountCofactorMinterms( dd, bFunc0, bVarsCof0, cuddT(bVarsAll) );
01022 }
01023 else
01024 {
01025 if ( bFunc1 != b0 )
01026 Res = Extra_CountCofactorMinterms( dd, bFunc1, bVarsCof1, cuddT(bVarsAll) );
01027 }
01028 }
01029 else
01030 {
01031 if ( bFunc0 != b0 )
01032 Res += Extra_CountCofactorMinterms( dd, bFunc0, bVarsCof0, cuddT(bVarsAll) );
01033
01034 if ( bFunc1 != b0 )
01035 Res += Extra_CountCofactorMinterms( dd, bFunc1, bVarsCof1, cuddT(bVarsAll) );
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045 for ( ; HHTable1[HKey].Sign == s_Signature; HKey = (HKey+1) % _TABLESIZE_COF );
01046 assert( HHTable1[HKey].Sign != s_Signature );
01047 HHTable1[HKey].Sign = s_Signature;
01048
01049 HHTable1[HKey].Arg1 = bFunc;
01050
01051 return Res;
01052 }
01053 }
01054
01066 unsigned Extra_CountMintermsSimple( DdNode * bFunc, unsigned max )
01067 {
01068 unsigned HKey;
01069
01070
01071 if ( Cudd_IsComplement(bFunc) )
01072 return max - Extra_CountMintermsSimple( Cudd_Not(bFunc), max );
01073
01074
01075 if ( cuddIsConstant(bFunc) )
01076 return ((bFunc==s_Terminal)? 0: max);
01077
01078
01079 HKey = hashKey2( bFunc, max, _TABLESIZE_MINT );
01080 if ( HHTable2[HKey].Arg1 == bFunc && HHTable2[HKey].Arg2 == max )
01081 return HHTable2[HKey].Res;
01082 else
01083 {
01084
01085 unsigned min = (Extra_CountMintermsSimple( cuddE(bFunc), max ) >> 1) +
01086 (Extra_CountMintermsSimple( cuddT(bFunc), max ) >> 1);
01087
01088 HHTable2[HKey].Arg1 = bFunc;
01089 HHTable2[HKey].Arg2 = max;
01090 HHTable2[HKey].Res = min;
01091
01092 return min;
01093 }
01094 }
01095
01096
01110 void CountNodeVisits_rec( DdManager * dd, DdNode * aFunc, st_table * Visited )
01111
01112 {
01113 traventry * p;
01114 char **slot;
01115 if ( st_find_or_add(Visited, (char*)aFunc, &slot) )
01116 {
01117 p = (traventry*) *slot;
01118
01119 p->nEdges++;
01120 return;
01121 }
01122
01123 assert( !Cudd_IsComplement(aFunc) );
01124
01125
01126 p = (traventry *) malloc( sizeof(traventry) );
01127
01128 p->bSum = b0; Cudd_Ref( b0 );
01129
01130 p->nEdges = 1;
01131
01132 *slot = (char*)p;
01133
01134
01135 if ( cuddI(dd,aFunc->index) < s_CutLevel )
01136 {
01137 CountNodeVisits_rec( dd, cuddE(aFunc), Visited );
01138 CountNodeVisits_rec( dd, cuddT(aFunc), Visited );
01139 }
01140 }
01141
01142
01156 void CollectNodesAndComputePaths_rec( DdManager * dd, DdNode * aFunc, DdNode * bCube, st_table * Visited, st_table * CutNodes )
01157 {
01158
01159 DdNode * bTemp;
01160 traventry * p;
01161 char **slot;
01162 if ( st_find_or_add(Visited, (char*)aFunc, &slot) )
01163 {
01164
01165 p = (traventry*) *slot;
01166
01167
01168 assert( p->nEdges > 0 );
01169
01170
01171 p->bSum = Cudd_bddOr( dd, bTemp = p->bSum, bCube ); Cudd_Ref( p->bSum );
01172 Cudd_RecursiveDeref( dd, bTemp );
01173
01174
01175 p->nEdges--;
01176
01177
01178 if ( p->nEdges )
01179 return;
01180 else
01181 {
01182
01183
01184 if ( cuddI(dd,aFunc->index) < s_CutLevel )
01185 {
01186 DdNode * bCube0, * bCube1;
01187
01188
01189 DdNode * bVarTop = dd->vars[aFunc->index];
01190
01191
01192 bCube0 = Cudd_bddAnd( dd, p->bSum, Cudd_Not( bVarTop ) ); Cudd_Ref( bCube0 );
01193 bCube1 = Cudd_bddAnd( dd, p->bSum, bVarTop ); Cudd_Ref( bCube1 );
01194
01195
01196 CollectNodesAndComputePaths_rec( dd, cuddE(aFunc), bCube0, Visited, CutNodes );
01197 CollectNodesAndComputePaths_rec( dd, cuddT(aFunc), bCube1, Visited, CutNodes );
01198
01199
01200 Cudd_RecursiveDeref( dd, bCube0 );
01201 Cudd_RecursiveDeref( dd, bCube1 );
01202 return;
01203 }
01204 else
01205 {
01206
01207
01208
01209
01210 if ( st_find_or_add(CutNodes, (char*)aFunc, &slot) )
01211 {
01212 assert( 0 );
01213 }
01214 *slot = (char*) p->bSum; Cudd_Ref( p->bSum );
01215
01216 return;
01217 }
01218 }
01219 }
01220
01221
01222 assert(0);
01223
01224 }
01225
01226
01227