00001
00021 #include "extra.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00046
00047
00048
00049
00050
00051 static DdNode * extraTransferPermuteRecur( DdManager * ddS, DdManager * ddD, DdNode * f, st_table * table, int * Permute );
00052 static DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute );
00053 static DdNode * cuddBddPermuteRecur ARGS( ( DdManager * manager, DdHashTable * table, DdNode * node, int *permut ) );
00054
00055
00056 static void ddSupportStep(DdNode *f, int *support);
00057 static void ddClearFlag(DdNode *f);
00058
00059 static DdNode* extraZddPrimes( DdManager *dd, DdNode* F );
00060
00063
00064
00065
00066
00082 DdNode * Extra_TransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute )
00083 {
00084 DdNode * bRes;
00085 do
00086 {
00087 ddDestination->reordered = 0;
00088 bRes = extraTransferPermute( ddSource, ddDestination, f, Permute );
00089 }
00090 while ( ddDestination->reordered == 1 );
00091 return ( bRes );
00092
00093 }
00094
00107 DdNode * Extra_TransferLevelByLevel( DdManager * ddSource, DdManager * ddDestination, DdNode * f )
00108 {
00109 DdNode * bRes;
00110 int * pPermute;
00111 int nMin, nMax, i;
00112
00113 nMin = ddMin(ddSource->size, ddDestination->size);
00114 nMax = ddMax(ddSource->size, ddDestination->size);
00115 pPermute = ALLOC( int, nMax );
00116
00117 for ( i = 0; i < nMin; i++ )
00118 pPermute[ ddSource->invperm[i] ] = ddDestination->invperm[i];
00119 if ( ddSource->size > ddDestination->size )
00120 {
00121 for ( ; i < nMax; i++ )
00122 pPermute[ ddSource->invperm[i] ] = -1;
00123 }
00124 bRes = Extra_TransferPermute( ddSource, ddDestination, f, pPermute );
00125 FREE( pPermute );
00126 return bRes;
00127 }
00128
00140 DdNode * Extra_bddRemapUp(
00141 DdManager * dd,
00142 DdNode * bF )
00143 {
00144 int * pPermute;
00145 DdNode * bSupp, * bTemp, * bRes;
00146 int Counter;
00147
00148 pPermute = ALLOC( int, dd->size );
00149
00150
00151 bSupp = Cudd_Support( dd, bF ); Cudd_Ref( bSupp );
00152
00153
00154
00155 Counter = 0;
00156 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
00157 pPermute[bTemp->index] = dd->invperm[Counter++];
00158
00159
00160 bRes = Cudd_bddPermute( dd, bF, pPermute ); Cudd_Ref( bRes );
00161
00162
00163 Cudd_RecursiveDeref( dd, bSupp );
00164
00165
00166 Cudd_Deref( bRes );
00167 free( pPermute );
00168 return bRes;
00169 }
00170
00182 DdNode * Extra_bddMove(
00183 DdManager * dd,
00184 DdNode * bF,
00185 int nVars)
00186 {
00187 DdNode * res;
00188 DdNode * bVars;
00189 if ( nVars == 0 )
00190 return bF;
00191 if ( Cudd_IsConstant(bF) )
00192 return bF;
00193 assert( nVars <= dd->size );
00194 if ( nVars > 0 )
00195 bVars = dd->vars[nVars];
00196 else
00197 bVars = Cudd_Not(dd->vars[-nVars]);
00198
00199 do {
00200 dd->reordered = 0;
00201 res = extraBddMove( dd, bF, bVars );
00202 } while (dd->reordered == 1);
00203 return(res);
00204
00205 }
00206
00218 void Extra_StopManager( DdManager * dd )
00219 {
00220 int RetValue;
00221
00222 RetValue = Cudd_CheckZeroRef( dd );
00223 if ( RetValue > 0 )
00224 printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
00225
00226 Cudd_Quit( dd );
00227 }
00228
00240 void Extra_bddPrint( DdManager * dd, DdNode * F )
00241 {
00242 DdGen * Gen;
00243 int * Cube;
00244 CUDD_VALUE_TYPE Value;
00245 int nVars = dd->size;
00246 int fFirstCube = 1;
00247 int i;
00248
00249 if ( F == NULL )
00250 {
00251 printf("NULL");
00252 return;
00253 }
00254 if ( F == b0 )
00255 {
00256 printf("Constant 0");
00257 return;
00258 }
00259 if ( F == b1 )
00260 {
00261 printf("Constant 1");
00262 return;
00263 }
00264
00265 Cudd_ForeachCube( dd, F, Gen, Cube, Value )
00266 {
00267 if ( fFirstCube )
00268 fFirstCube = 0;
00269 else
00270
00271 printf( " + " );
00272
00273 for ( i = 0; i < nVars; i++ )
00274 if ( Cube[i] == 0 )
00275 printf( "[%d]'", i );
00276
00277 else if ( Cube[i] == 1 )
00278 printf( "[%d]", i );
00279
00280 }
00281
00282
00283 }
00295 int Extra_bddSuppSize( DdManager * dd, DdNode * bSupp )
00296 {
00297 int Counter = 0;
00298 while ( bSupp != b1 )
00299 {
00300 assert( !Cudd_IsComplement(bSupp) );
00301 assert( cuddE(bSupp) == b0 );
00302
00303 bSupp = cuddT(bSupp);
00304 Counter++;
00305 }
00306 return Counter;
00307 }
00308
00320 int Extra_bddSuppContainVar( DdManager * dd, DdNode * bS, DdNode * bVar )
00321 {
00322 for( ; bS != b1; bS = cuddT(bS) )
00323 if ( bS->index == bVar->index )
00324 return 1;
00325 return 0;
00326 }
00327
00339 int Extra_bddSuppOverlapping( DdManager * dd, DdNode * S1, DdNode * S2 )
00340 {
00341 while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00342 {
00343
00344 if ( S1->index == S2->index )
00345 return 1;
00346
00347 if ( dd->perm[S1->index] < dd->perm[S2->index] )
00348 S1 = cuddT(S1);
00349 else
00350 S2 = cuddT(S2);
00351 }
00352 return 0;
00353 }
00354
00367 int Extra_bddSuppDifferentVars( DdManager * dd, DdNode * S1, DdNode * S2, int DiffMax )
00368 {
00369 int Result = 0;
00370 while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00371 {
00372
00373 if ( S1->index == S2->index )
00374 {
00375 S1 = cuddT(S1);
00376 S2 = cuddT(S2);
00377 continue;
00378 }
00379
00380 Result++;
00381
00382 if ( Result >= DiffMax )
00383 return DiffMax;
00384
00385
00386 if ( dd->perm[S1->index] < dd->perm[S2->index] )
00387 S1 = cuddT(S1);
00388 else
00389 S2 = cuddT(S2);
00390 }
00391
00392
00393 if ( S1->index != CUDD_CONST_INDEX )
00394 Result += Extra_bddSuppSize(dd,S1);
00395 else if ( S2->index != CUDD_CONST_INDEX )
00396 Result += Extra_bddSuppSize(dd,S2);
00397
00398 if ( Result >= DiffMax )
00399 return DiffMax;
00400 return Result;
00401 }
00402
00403
00417 int Extra_bddSuppCheckContainment( DdManager * dd, DdNode * bL, DdNode * bH, DdNode ** bLarge, DdNode ** bSmall )
00418 {
00419 DdNode * bSL = bL;
00420 DdNode * bSH = bH;
00421 int fLcontainsH = 1;
00422 int fHcontainsL = 1;
00423 int TopVar;
00424
00425 if ( bSL == bSH )
00426 return 0;
00427
00428 while ( bSL != b1 || bSH != b1 )
00429 {
00430 if ( bSL == b1 )
00431 {
00432 fLcontainsH = 0;
00433 if ( fHcontainsL == 0 )
00434 return 0;
00435 else
00436 break;
00437 }
00438
00439 if ( bSH == b1 )
00440 {
00441 fHcontainsL = 0;
00442 if ( fLcontainsH == 0 )
00443 return 0;
00444 else
00445 break;
00446 }
00447
00448
00449 if ( dd->perm[bSL->index] < dd->perm[bSH->index] )
00450 TopVar = bSL->index;
00451 else
00452 TopVar = bSH->index;
00453
00454 if ( TopVar == bSL->index && TopVar == bSH->index )
00455 {
00456
00457
00458 bSL = cuddT(bSL);
00459 bSH = cuddT(bSH);
00460 }
00461 else if ( TopVar == bSL->index )
00462 {
00463
00464 fHcontainsL = 0;
00465
00466 bSL = cuddT(bSL);
00467 }
00468 else
00469 {
00470 fLcontainsH = 0;
00471
00472 bSH = cuddT(bSH);
00473 }
00474
00475
00476 if ( !fHcontainsL && !fLcontainsH )
00477 return 0;
00478 }
00479
00480 assert( !fHcontainsL || !fLcontainsH );
00481 if ( fHcontainsL )
00482 {
00483 *bLarge = bH;
00484 *bSmall = bL;
00485 }
00486 else
00487 {
00488 *bLarge = bL;
00489 *bSmall = bH;
00490 }
00491 return 1;
00492 }
00493
00494
00510 int *
00511 Extra_SupportArray(
00512 DdManager * dd,
00513 DdNode * f,
00514 int * support )
00515 {
00516 int i, size;
00517
00518
00519 size = ddMax(dd->size, dd->sizeZ);
00520 for (i = 0; i < size; i++)
00521 support[i] = 0;
00522
00523
00524 ddSupportStep(Cudd_Regular(f),support);
00525 ddClearFlag(Cudd_Regular(f));
00526
00527 return(support);
00528
00529 }
00530
00545 int *
00546 Extra_VectorSupportArray(
00547 DdManager * dd,
00548 DdNode ** F,
00549 int n,
00550 int * support )
00551 {
00552 int i, size;
00553
00554
00555 size = ddMax( dd->size, dd->sizeZ );
00556 for ( i = 0; i < size; i++ )
00557 support[i] = 0;
00558
00559
00560 for ( i = 0; i < n; i++ )
00561 ddSupportStep( Cudd_Regular(F[i]), support );
00562 for ( i = 0; i < n; i++ )
00563 ddClearFlag( Cudd_Regular(F[i]) );
00564
00565 return support;
00566 }
00567
00579 DdNode * Extra_bddFindOneCube( DdManager * dd, DdNode * bF )
00580 {
00581 char * s_Temp;
00582 DdNode * bCube, * bTemp;
00583 int v;
00584
00585
00586 s_Temp = ALLOC( char, dd->size );
00587 Cudd_bddPickOneCube( dd, bF, s_Temp );
00588
00589
00590 bCube = b1; Cudd_Ref( bCube );
00591 for ( v = 0; v < dd->size; v++ )
00592 if ( s_Temp[v] == 0 )
00593 {
00594
00595 bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(dd->vars[v]) ); Cudd_Ref( bCube );
00596 Cudd_RecursiveDeref( dd, bTemp );
00597 }
00598 else if ( s_Temp[v] == 1 )
00599 {
00600
00601 bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[v] ); Cudd_Ref( bCube );
00602 Cudd_RecursiveDeref( dd, bTemp );
00603 }
00604 Cudd_Deref(bCube);
00605 free( s_Temp );
00606 return bCube;
00607 }
00608
00619 DdNode * Extra_bddGetOneCube( DdManager * dd, DdNode * bFunc )
00620 {
00621 DdNode * bFuncR, * bFunc0, * bFunc1;
00622 DdNode * bRes0, * bRes1, * bRes;
00623
00624 bFuncR = Cudd_Regular(bFunc);
00625 if ( cuddIsConstant(bFuncR) )
00626 return bFunc;
00627
00628
00629 if ( Cudd_IsComplement(bFunc) )
00630 {
00631 bFunc0 = Cudd_Not( cuddE(bFuncR) );
00632 bFunc1 = Cudd_Not( cuddT(bFuncR) );
00633 }
00634 else
00635 {
00636 bFunc0 = cuddE(bFuncR);
00637 bFunc1 = cuddT(bFuncR);
00638 }
00639
00640
00641 bRes0 = Extra_bddGetOneCube( dd, bFunc0 ); Cudd_Ref( bRes0 );
00642
00643 if ( bRes0 != b0 )
00644 {
00645 bRes = Cudd_bddAnd( dd, bRes0, Cudd_Not(dd->vars[bFuncR->index]) ); Cudd_Ref( bRes );
00646 Cudd_RecursiveDeref( dd, bRes0 );
00647 }
00648 else
00649 {
00650 Cudd_RecursiveDeref( dd, bRes0 );
00651
00652 bRes1 = Extra_bddGetOneCube( dd, bFunc1 ); Cudd_Ref( bRes1 );
00653 assert( bRes1 != b0 );
00654 bRes = Cudd_bddAnd( dd, bRes1, dd->vars[bFuncR->index] ); Cudd_Ref( bRes );
00655 Cudd_RecursiveDeref( dd, bRes1 );
00656 }
00657
00658 Cudd_Deref( bRes );
00659 return bRes;
00660 }
00661
00673 DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int iStop )
00674 {
00675 DdNode * bTemp, * bProd;
00676 int i;
00677 assert( iStart <= iStop );
00678 assert( iStart >= 0 && iStart <= dd->size );
00679 assert( iStop >= 0 && iStop <= dd->size );
00680 bProd = b1; Cudd_Ref( bProd );
00681 for ( i = iStart; i < iStop; i++ )
00682 {
00683 bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] ); Cudd_Ref( bProd );
00684 Cudd_RecursiveDeref( dd, bTemp );
00685 }
00686 Cudd_Deref( bProd );
00687 return bProd;
00688 }
00689
00704 DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst )
00705 {
00706 int z;
00707 DdNode * bTemp, * bVar, * bVarBdd, * bResult;
00708
00709 bResult = b1; Cudd_Ref( bResult );
00710 for ( z = 0; z < CodeWidth; z++ )
00711 {
00712 bVarBdd = (pbVars)? pbVars[z]: dd->vars[z];
00713 if ( fMsbFirst )
00714 bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (CodeWidth-1-z)))==0 );
00715 else
00716 bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (z)))==0 );
00717 bResult = Cudd_bddAnd( dd, bTemp = bResult, bVar ); Cudd_Ref( bResult );
00718 Cudd_RecursiveDeref( dd, bTemp );
00719 }
00720 Cudd_Deref( bResult );
00721
00722 return bResult;
00723 }
00724
00738 DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f )
00739 {
00740 int *support;
00741 DdNode *res, *tmp, *var;
00742 int i, j;
00743 int size;
00744
00745
00746 size = ddMax( dd->size, dd->sizeZ );
00747 support = ALLOC( int, size );
00748 if ( support == NULL )
00749 {
00750 dd->errorCode = CUDD_MEMORY_OUT;
00751 return ( NULL );
00752 }
00753 for ( i = 0; i < size; i++ )
00754 {
00755 support[i] = 0;
00756 }
00757
00758
00759 ddSupportStep( Cudd_Regular( f ), support );
00760 ddClearFlag( Cudd_Regular( f ) );
00761
00762
00763 do
00764 {
00765 dd->reordered = 0;
00766 res = DD_ONE( dd );
00767 cuddRef( res );
00768 for ( j = size - 1; j >= 0; j-- )
00769 {
00770 i = ( j >= dd->size ) ? j : dd->invperm[j];
00771 if ( support[i] == 1 )
00772 {
00773 var = cuddUniqueInter( dd, i, dd->one, Cudd_Not( dd->one ) );
00775 var = Cudd_Not(var);
00777 cuddRef( var );
00778 tmp = cuddBddAndRecur( dd, res, var );
00779 if ( tmp == NULL )
00780 {
00781 Cudd_RecursiveDeref( dd, res );
00782 Cudd_RecursiveDeref( dd, var );
00783 res = NULL;
00784 break;
00785 }
00786 cuddRef( tmp );
00787 Cudd_RecursiveDeref( dd, res );
00788 Cudd_RecursiveDeref( dd, var );
00789 res = tmp;
00790 }
00791 }
00792 }
00793 while ( dd->reordered == 1 );
00794
00795 FREE( support );
00796 if ( res != NULL )
00797 cuddDeref( res );
00798 return ( res );
00799
00800 }
00801
00813 int Extra_bddIsVar( DdNode * bFunc )
00814 {
00815 bFunc = Cudd_Regular( bFunc );
00816 if ( cuddIsConstant(bFunc) )
00817 return 0;
00818 return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
00819 }
00820
00832 DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars )
00833 {
00834 DdNode * bFunc, * bTemp;
00835 int i;
00836 bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
00837 for ( i = 0; i < nVars; i++ )
00838 {
00839 bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
00840 Cudd_RecursiveDeref( dd, bTemp );
00841 }
00842 Cudd_Deref( bFunc );
00843 return bFunc;
00844 }
00845
00857 DdNode * Extra_bddCreateOr( DdManager * dd, int nVars )
00858 {
00859 DdNode * bFunc, * bTemp;
00860 int i;
00861 bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
00862 for ( i = 0; i < nVars; i++ )
00863 {
00864 bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
00865 Cudd_RecursiveDeref( dd, bTemp );
00866 }
00867 Cudd_Deref( bFunc );
00868 return bFunc;
00869 }
00870
00882 DdNode * Extra_bddCreateExor( DdManager * dd, int nVars )
00883 {
00884 DdNode * bFunc, * bTemp;
00885 int i;
00886 bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
00887 for ( i = 0; i < nVars; i++ )
00888 {
00889 bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
00890 Cudd_RecursiveDeref( dd, bTemp );
00891 }
00892 Cudd_Deref( bFunc );
00893 return bFunc;
00894 }
00895
00907 DdNode * Extra_zddPrimes( DdManager * dd, DdNode * F )
00908 {
00909 DdNode *res;
00910 do {
00911 dd->reordered = 0;
00912 res = extraZddPrimes(dd, F);
00913 if ( dd->reordered == 1 )
00914 printf("\nReordering in Extra_zddPrimes()\n");
00915 } while (dd->reordered == 1);
00916 return(res);
00917
00918 }
00919
00935 void Extra_bddPermuteArray( DdManager * manager, DdNode ** bNodesIn, DdNode ** bNodesOut, int nNodes, int *permut )
00936 {
00937 DdHashTable *table;
00938 int i, k;
00939 do
00940 {
00941 manager->reordered = 0;
00942 table = cuddHashTableInit( manager, 1, 2 );
00943
00944
00945 for ( i = 0; i < nNodes; i++ )
00946 {
00947 bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
00948 if ( bNodesOut[i] == NULL )
00949 {
00950
00951 for ( k = 0; k < i; k++ )
00952 Cudd_RecursiveDeref( manager, bNodesOut[k] );
00953 break;
00954 }
00955 cuddRef( bNodesOut[i] );
00956 }
00957
00958 cuddHashTableQuit( table );
00959 }
00960 while ( manager->reordered == 1 );
00961 }
00962
00963
00964
00965
00966
00967
00979 DdNode * extraBddMove(
00980 DdManager * dd,
00981 DdNode * bF,
00982 DdNode * bDist)
00983 {
00984 DdNode * bRes;
00985
00986 if ( Cudd_IsConstant(bF) )
00987 return bF;
00988
00989 if ( bRes = cuddCacheLookup2(dd, extraBddMove, bF, bDist) )
00990 return bRes;
00991 else
00992 {
00993 DdNode * bRes0, * bRes1;
00994 DdNode * bF0, * bF1;
00995 DdNode * bFR = Cudd_Regular(bF);
00996 int VarNew;
00997
00998 if ( Cudd_IsComplement(bDist) )
00999 VarNew = bFR->index - Cudd_Not(bDist)->index;
01000 else
01001 VarNew = bFR->index + bDist->index;
01002 assert( VarNew < dd->size );
01003
01004
01005 if ( bFR != bF )
01006 {
01007 bF0 = Cudd_Not( cuddE(bFR) );
01008 bF1 = Cudd_Not( cuddT(bFR) );
01009 }
01010 else
01011 {
01012 bF0 = cuddE(bFR);
01013 bF1 = cuddT(bFR);
01014 }
01015
01016 bRes0 = extraBddMove( dd, bF0, bDist );
01017 if ( bRes0 == NULL )
01018 return NULL;
01019 cuddRef( bRes0 );
01020
01021 bRes1 = extraBddMove( dd, bF1, bDist );
01022 if ( bRes1 == NULL )
01023 {
01024 Cudd_RecursiveDeref( dd, bRes0 );
01025 return NULL;
01026 }
01027 cuddRef( bRes1 );
01028
01029
01030 bRes = cuddBddIteRecur( dd, dd->vars[VarNew], bRes1, bRes0 );
01031 if ( bRes == NULL )
01032 {
01033 Cudd_RecursiveDeref( dd, bRes0 );
01034 Cudd_RecursiveDeref( dd, bRes1 );
01035 return NULL;
01036 }
01037 cuddRef( bRes );
01038 Cudd_RecursiveDeref( dd, bRes0 );
01039 Cudd_RecursiveDeref( dd, bRes1 );
01040
01041
01042 cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
01043 cuddDeref( bRes );
01044 return bRes;
01045 }
01046 }
01047
01048
01067 void
01068 extraDecomposeCover(
01069 DdManager* dd,
01070 DdNode* zC,
01071 DdNode** zC0,
01072 DdNode** zC1,
01073 DdNode** zC2 )
01074 {
01075 if ( (zC->index & 1) == 0 )
01076 {
01077
01078 DdNode *Temp = cuddE( zC );
01079 *zC1 = cuddT( zC );
01080 if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
01081 {
01082
01083 *zC2 = cuddE( Temp );
01084 *zC0 = cuddT( Temp );
01085 }
01086 else
01087 {
01088 *zC2 = Temp;
01089 *zC0 = dd->zero;
01090 }
01091 }
01092 else
01093 {
01094 *zC1 = dd->zero;
01095 *zC2 = cuddE( zC );
01096 *zC0 = cuddT( zC );
01097 }
01098 }
01099
01100
01101
01102
01103
01117 DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
01118 {
01119 DdNode *res;
01120 st_table *table = NULL;
01121 st_generator *gen = NULL;
01122 DdNode *key, *value;
01123
01124 table = st_init_table( st_ptrcmp, st_ptrhash );
01125 if ( table == NULL )
01126 goto failure;
01127 res = extraTransferPermuteRecur( ddS, ddD, f, table, Permute );
01128 if ( res != NULL )
01129 cuddRef( res );
01130
01131
01132
01133
01134 gen = st_init_gen( table );
01135 if ( gen == NULL )
01136 goto failure;
01137 while ( st_gen( gen, ( char ** ) &key, ( char ** ) &value ) )
01138 {
01139 Cudd_RecursiveDeref( ddD, value );
01140 }
01141 st_free_gen( gen );
01142 gen = NULL;
01143 st_free_table( table );
01144 table = NULL;
01145
01146 if ( res != NULL )
01147 cuddDeref( res );
01148 return ( res );
01149
01150 failure:
01151 if ( table != NULL )
01152 st_free_table( table );
01153 if ( gen != NULL )
01154 st_free_gen( gen );
01155 return ( NULL );
01156
01157 }
01158
01159
01172 static DdNode *
01173 extraTransferPermuteRecur(
01174 DdManager * ddS,
01175 DdManager * ddD,
01176 DdNode * f,
01177 st_table * table,
01178 int * Permute )
01179 {
01180 DdNode *ft, *fe, *t, *e, *var, *res;
01181 DdNode *one, *zero;
01182 int index;
01183 int comple = 0;
01184
01185 statLine( ddD );
01186 one = DD_ONE( ddD );
01187 comple = Cudd_IsComplement( f );
01188
01189
01190 if ( Cudd_IsConstant( f ) )
01191 return ( Cudd_NotCond( one, comple ) );
01192
01193
01194
01195 f = Cudd_NotCond( f, comple );
01196
01197
01198
01199 if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) )
01200 return ( Cudd_NotCond( res, comple ) );
01201
01202
01203 if ( Permute )
01204 index = Permute[f->index];
01205 else
01206 index = f->index;
01207
01208 ft = cuddT( f );
01209 fe = cuddE( f );
01210
01211 t = extraTransferPermuteRecur( ddS, ddD, ft, table, Permute );
01212 if ( t == NULL )
01213 {
01214 return ( NULL );
01215 }
01216 cuddRef( t );
01217
01218 e = extraTransferPermuteRecur( ddS, ddD, fe, table, Permute );
01219 if ( e == NULL )
01220 {
01221 Cudd_RecursiveDeref( ddD, t );
01222 return ( NULL );
01223 }
01224 cuddRef( e );
01225
01226 zero = Cudd_Not(ddD->one);
01227 var = cuddUniqueInter( ddD, index, one, zero );
01228 if ( var == NULL )
01229 {
01230 Cudd_RecursiveDeref( ddD, t );
01231 Cudd_RecursiveDeref( ddD, e );
01232 return ( NULL );
01233 }
01234 res = cuddBddIteRecur( ddD, var, t, e );
01235
01236 if ( res == NULL )
01237 {
01238 Cudd_RecursiveDeref( ddD, t );
01239 Cudd_RecursiveDeref( ddD, e );
01240 return ( NULL );
01241 }
01242 cuddRef( res );
01243 Cudd_RecursiveDeref( ddD, t );
01244 Cudd_RecursiveDeref( ddD, e );
01245
01246 if ( st_add_direct( table, ( char * ) f, ( char * ) res ) ==
01247 ST_OUT_OF_MEM )
01248 {
01249 Cudd_RecursiveDeref( ddD, res );
01250 return ( NULL );
01251 }
01252 return ( Cudd_NotCond( res, comple ) );
01253
01254 }
01255
01269 static void
01270 ddSupportStep(
01271 DdNode * f,
01272 int * support)
01273 {
01274 if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
01275 return;
01276 }
01277
01278 support[f->index] = 1;
01279 ddSupportStep(cuddT(f),support);
01280 ddSupportStep(Cudd_Regular(cuddE(f)),support);
01281
01282 f->next = Cudd_Not(f->next);
01283 return;
01284
01285 }
01286
01287
01300 static void
01301 ddClearFlag(
01302 DdNode * f)
01303 {
01304 if (!Cudd_IsComplement(f->next)) {
01305 return;
01306 }
01307
01308 f->next = Cudd_Regular(f->next);
01309 if (cuddIsConstant(f)) {
01310 return;
01311 }
01312 ddClearFlag(cuddT(f));
01313 ddClearFlag(Cudd_Regular(cuddE(f)));
01314 return;
01315
01316 }
01317
01318
01330 DdNode *
01331 extraComposeCover(
01332 DdManager* dd,
01333 DdNode* zC0,
01334 DdNode* zC1,
01335 DdNode* zC2,
01336 int TopVar)
01337 {
01338 DdNode * zRes, * zTemp;
01339
01340 zTemp = cuddZddGetNode( dd, 2*TopVar + 1, zC0, zC2 );
01341 if ( zTemp == NULL )
01342 {
01343 Cudd_RecursiveDerefZdd(dd, zC0);
01344 Cudd_RecursiveDerefZdd(dd, zC1);
01345 Cudd_RecursiveDerefZdd(dd, zC2);
01346 return NULL;
01347 }
01348 cuddRef( zTemp );
01349 cuddDeref( zC0 );
01350 cuddDeref( zC2 );
01351
01352
01353 zRes = cuddZddGetNode( dd, 2*TopVar, zC1, zTemp );
01354 if ( zRes == NULL )
01355 {
01356 Cudd_RecursiveDerefZdd(dd, zC1);
01357 Cudd_RecursiveDerefZdd(dd, zTemp);
01358 return NULL;
01359 }
01360 cuddDeref( zC1 );
01361 cuddDeref( zTemp );
01362 return zRes;
01363 }
01364
01376 DdNode* extraZddPrimes( DdManager *dd, DdNode* F )
01377 {
01378 DdNode *zRes;
01379
01380 if ( F == Cudd_Not( dd->one ) )
01381 return dd->zero;
01382 if ( F == dd->one )
01383 return dd->one;
01384
01385
01386 zRes = cuddCacheLookup1Zdd(dd, extraZddPrimes, F);
01387 if (zRes)
01388 return(zRes);
01389 {
01390
01391 DdNode *bF01, *zP0, *zP1;
01392
01393 DdNode *zResE, *zResP, *zResN;
01394 int fIsComp = Cudd_IsComplement( F );
01395
01396
01397 DdNode * bF0 = Cudd_NotCond( Cudd_E( F ), fIsComp );
01398 DdNode * bF1 = Cudd_NotCond( Cudd_T( F ), fIsComp );
01399
01400
01401 bF01 = cuddBddAndRecur( dd, bF0, bF1 );
01402 if ( bF01 == NULL ) return NULL;
01403 cuddRef( bF01 );
01404
01405
01406 zP0 = extraZddPrimes( dd, bF0 );
01407 if ( zP0 == NULL )
01408 {
01409 Cudd_RecursiveDeref( dd, bF01 );
01410 return NULL;
01411 }
01412 cuddRef( zP0 );
01413
01414 zP1 = extraZddPrimes( dd, bF1 );
01415 if ( zP1 == NULL )
01416 {
01417 Cudd_RecursiveDeref( dd, bF01 );
01418 Cudd_RecursiveDerefZdd( dd, zP0 );
01419 return NULL;
01420 }
01421 cuddRef( zP1 );
01422
01423
01424 if ( bF01 == bF0 )
01425 {
01426
01427 cuddDeref( bF01 );
01428
01429 zResE = zP0;
01430
01431 zResN = dd->zero;
01432 cuddRef( zResN );
01433
01434 zResP = cuddZddDiff( dd, zP1, zP0 );
01435 if ( zResP == NULL )
01436 {
01437 Cudd_RecursiveDerefZdd( dd, zResE );
01438 Cudd_RecursiveDerefZdd( dd, zResN );
01439 Cudd_RecursiveDerefZdd( dd, zP1 );
01440 return NULL;
01441 }
01442 cuddRef( zResP );
01443 Cudd_RecursiveDerefZdd( dd, zP1 );
01444 }
01445 else if ( bF01 == bF1 )
01446 {
01447
01448 cuddDeref( bF01 );
01449
01450 zResE = zP1;
01451
01452 zResP = dd->zero;
01453 cuddRef( zResP );
01454
01455 zResN = cuddZddDiff( dd, zP0, zP1 );
01456 if ( zResN == NULL )
01457 {
01458 Cudd_RecursiveDerefZdd( dd, zResE );
01459 Cudd_RecursiveDerefZdd( dd, zResP );
01460 Cudd_RecursiveDerefZdd( dd, zP0 );
01461 return NULL;
01462 }
01463 cuddRef( zResN );
01464 Cudd_RecursiveDerefZdd( dd, zP0 );
01465 }
01466 else
01467 {
01468
01469 zResE = extraZddPrimes( dd, bF01 );
01470 if ( zResE == NULL )
01471 {
01472 Cudd_RecursiveDerefZdd( dd, bF01 );
01473 Cudd_RecursiveDerefZdd( dd, zP0 );
01474 Cudd_RecursiveDerefZdd( dd, zP1 );
01475 return NULL;
01476 }
01477 cuddRef( zResE );
01478 Cudd_RecursiveDeref( dd, bF01 );
01479
01480
01481 zResN = cuddZddDiff( dd, zP0, zResE );
01482 if ( zResN == NULL )
01483 {
01484 Cudd_RecursiveDerefZdd( dd, zResE );
01485 Cudd_RecursiveDerefZdd( dd, zP0 );
01486 Cudd_RecursiveDerefZdd( dd, zP1 );
01487 return NULL;
01488 }
01489 cuddRef( zResN );
01490 Cudd_RecursiveDerefZdd( dd, zP0 );
01491
01492
01493 zResP = cuddZddDiff( dd, zP1, zResE );
01494 if ( zResP == NULL )
01495 {
01496 Cudd_RecursiveDerefZdd( dd, zResE );
01497 Cudd_RecursiveDerefZdd( dd, zResN );
01498 Cudd_RecursiveDerefZdd( dd, zP1 );
01499 return NULL;
01500 }
01501 cuddRef( zResP );
01502 Cudd_RecursiveDerefZdd( dd, zP1 );
01503 }
01504
01505 zRes = extraComposeCover( dd, zResN, zResP, zResE, Cudd_Regular(F)->index );
01506 if ( zRes == NULL ) return NULL;
01507
01508
01509 cuddCacheInsert1(dd, extraZddPrimes, F, zRes);
01510 return zRes;
01511 }
01512 }
01513
01534 static DdNode *
01535 cuddBddPermuteRecur( DdManager * manager ,
01536 DdHashTable * table ,
01537 DdNode * node ,
01538 int *permut )
01539 {
01540 DdNode *N, *T, *E;
01541 DdNode *res;
01542 int index;
01543
01544 statLine( manager );
01545 N = Cudd_Regular( node );
01546
01547
01548 if ( cuddIsConstant( N ) )
01549 {
01550 return ( node );
01551 }
01552
01553
01554 if ( N->ref != 1 && ( res = cuddHashTableLookup1( table, N ) ) != NULL )
01555 {
01556 #ifdef DD_DEBUG
01557 bddPermuteRecurHits++;
01558 #endif
01559 return ( Cudd_NotCond( res, N != node ) );
01560 }
01561
01562
01563 T = cuddBddPermuteRecur( manager, table, cuddT( N ), permut );
01564 if ( T == NULL )
01565 return ( NULL );
01566 cuddRef( T );
01567 E = cuddBddPermuteRecur( manager, table, cuddE( N ), permut );
01568 if ( E == NULL )
01569 {
01570 Cudd_IterDerefBdd( manager, T );
01571 return ( NULL );
01572 }
01573 cuddRef( E );
01574
01575
01576
01577
01578
01579 index = permut[N->index];
01580 res = cuddBddIteRecur( manager, manager->vars[index], T, E );
01581 if ( res == NULL )
01582 {
01583 Cudd_IterDerefBdd( manager, T );
01584 Cudd_IterDerefBdd( manager, E );
01585 return ( NULL );
01586 }
01587 cuddRef( res );
01588 Cudd_IterDerefBdd( manager, T );
01589 Cudd_IterDerefBdd( manager, E );
01590
01591
01592
01593
01594 if ( N->ref != 1 )
01595 {
01596 ptrint fanout = ( ptrint ) N->ref;
01597 cuddSatDec( fanout );
01598 if ( !cuddHashTableInsert1( table, N, res, fanout ) )
01599 {
01600 Cudd_IterDerefBdd( manager, res );
01601 return ( NULL );
01602 }
01603 }
01604 cuddDeref( res );
01605 return ( Cudd_NotCond( res, N != node ) );
01606
01607 }
01608
01609
01613
01614