00001
00022 #include "extra.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define DD_GET_SYMM_VARS_TAG 0x0a
00045
00048
00049
00050
00051
00054
00055
00056
00057
00070 Extra_SymmInfo_t * Extra_SymmPairsCompute(
00071 DdManager * dd,
00072 DdNode * bFunc)
00073 {
00074 DdNode * bSupp;
00075 DdNode * zRes;
00076 Extra_SymmInfo_t * p;
00077
00078 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
00079 zRes = Extra_zddSymmPairsCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
00080
00081 p = Extra_SymmPairsCreateFromZdd( dd, zRes, bSupp );
00082
00083 Cudd_RecursiveDeref( dd, bSupp );
00084 Cudd_RecursiveDerefZdd( dd, zRes );
00085
00086 return p;
00087
00088 }
00089
00090
00102 DdNode * Extra_zddSymmPairsCompute(
00103 DdManager * dd,
00104 DdNode * bF,
00105 DdNode * bVars)
00106 {
00107 DdNode * res;
00108 do {
00109 dd->reordered = 0;
00110 res = extraZddSymmPairsCompute( dd, bF, bVars );
00111 } while (dd->reordered == 1);
00112 return(res);
00113
00114 }
00115
00127 DdNode * Extra_zddGetSymmetricVars(
00128 DdManager * dd,
00129 DdNode * bF,
00130 DdNode * bG,
00131 DdNode * bVars)
00132 {
00133 DdNode * res;
00134 do {
00135 dd->reordered = 0;
00136 res = extraZddGetSymmetricVars( dd, bF, bG, bVars );
00137 } while (dd->reordered == 1);
00138 return(res);
00139
00140 }
00141
00142
00154 DdNode * Extra_zddGetSingletons(
00155 DdManager * dd,
00156 DdNode * bVars)
00157 {
00158 DdNode * res;
00159 do {
00160 dd->reordered = 0;
00161 res = extraZddGetSingletons( dd, bVars );
00162 } while (dd->reordered == 1);
00163 return(res);
00164
00165 }
00166
00178 DdNode * Extra_bddReduceVarSet(
00179 DdManager * dd,
00180 DdNode * bVars,
00181 DdNode * bF)
00182 {
00183 DdNode * res;
00184 do {
00185 dd->reordered = 0;
00186 res = extraBddReduceVarSet( dd, bVars, bF );
00187 } while (dd->reordered == 1);
00188 return(res);
00189
00190 }
00191
00192
00204 Extra_SymmInfo_t * Extra_SymmPairsAllocate( int nVars )
00205 {
00206 int i;
00207 Extra_SymmInfo_t * p;
00208
00209
00210 p = ALLOC( Extra_SymmInfo_t, 1 );
00211 memset( p, 0, sizeof(Extra_SymmInfo_t) );
00212 p->nVars = nVars;
00213 p->pVars = ALLOC( int, nVars );
00214 p->pSymms = ALLOC( char *, nVars );
00215 p->pSymms[0] = ALLOC( char , nVars * nVars );
00216 memset( p->pSymms[0], 0, nVars * nVars * sizeof(char) );
00217
00218 for ( i = 1; i < nVars; i++ )
00219 p->pSymms[i] = p->pSymms[i-1] + nVars;
00220
00221 return p;
00222 }
00223
00235 void Extra_SymmPairsDissolve( Extra_SymmInfo_t * p )
00236 {
00237 free( p->pVars );
00238 free( p->pSymms[0] );
00239 free( p->pSymms );
00240 free( p );
00241 }
00242
00254 void Extra_SymmPairsPrint( Extra_SymmInfo_t * p )
00255 {
00256 int i, k;
00257 printf( "\n" );
00258 for ( i = 0; i < p->nVars; i++ )
00259 {
00260 for ( k = 0; k <= i; k++ )
00261 printf( " " );
00262 for ( k = i+1; k < p->nVars; k++ )
00263 if ( p->pSymms[i][k] )
00264 printf( "1" );
00265 else
00266 printf( "." );
00267 printf( "\n" );
00268 }
00269 }
00270
00271
00285 Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp )
00286 {
00287 int i;
00288 int nSuppSize;
00289 Extra_SymmInfo_t * p;
00290 int * pMapVars2Nums;
00291 DdNode * bTemp;
00292 DdNode * zSet, * zCube, * zTemp;
00293 int iVar1, iVar2;
00294
00295 nSuppSize = Extra_bddSuppSize( dd, bSupp );
00296
00297
00298 p = Extra_SymmPairsAllocate( nSuppSize );
00299
00300
00301 pMapVars2Nums = ALLOC( int, dd->size );
00302 memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
00303
00304
00305 p->nVarsMax = dd->size;
00306
00307 p->nNodes = 0;
00308 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00309 {
00310 p->pVars[i] = bTemp->index;
00311 pMapVars2Nums[bTemp->index] = i;
00312 }
00313
00314
00315 zSet = zPairs; Cudd_Ref( zSet );
00316 while ( zSet != z0 )
00317 {
00318
00319 zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
00320
00321
00322 assert( cuddT( cuddT(zCube) ) == z1 );
00323 iVar1 = zCube->index/2;
00324 iVar2 = cuddT(zCube)->index/2;
00325 if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] )
00326 p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1;
00327 else
00328 p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1;
00329
00330 p->nSymms ++;
00331
00332
00333 zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
00334 Cudd_RecursiveDerefZdd( dd, zTemp );
00335 Cudd_RecursiveDerefZdd( dd, zCube );
00336
00337 }
00338 Cudd_RecursiveDerefZdd( dd, zSet );
00339
00340 FREE( pMapVars2Nums );
00341 return p;
00342
00343 }
00344
00345
00357 int Extra_bddCheckVarsSymmetric(
00358 DdManager * dd,
00359 DdNode * bF,
00360 int iVar1,
00361 int iVar2)
00362 {
00363 DdNode * bVars;
00364 int Res;
00365
00366
00367
00368 assert( iVar1 != iVar2 );
00369 assert( iVar1 < dd->size );
00370 assert( iVar2 < dd->size );
00371
00372 bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] ); Cudd_Ref( bVars );
00373
00374 Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 );
00375
00376 Cudd_RecursiveDeref( dd, bVars );
00377
00378 return Res;
00379 }
00380
00381
00393 Extra_SymmInfo_t * Extra_SymmPairsComputeNaive( DdManager * dd, DdNode * bFunc )
00394 {
00395 DdNode * bSupp, * bTemp;
00396 int nSuppSize;
00397 Extra_SymmInfo_t * p;
00398 int i, k;
00399
00400
00401 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
00402 nSuppSize = Extra_bddSuppSize( dd, bSupp );
00403
00404
00405
00406
00407
00408 p = Extra_SymmPairsAllocate( nSuppSize );
00409
00410
00411 p->nVarsMax = dd->size;
00412 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00413 p->pVars[i] = bTemp->index;
00414
00415
00416 for ( i = 0; i < nSuppSize; i++ )
00417 for ( k = i+1; k < nSuppSize; k++ )
00418 {
00419 p->pSymms[k][i] = p->pSymms[i][k] = Extra_bddCheckVarsSymmetricNaive( dd, bFunc, p->pVars[i], p->pVars[k] );
00420 if ( p->pSymms[i][k] )
00421 p->nSymms++;
00422 }
00423
00424 Cudd_RecursiveDeref( dd, bSupp );
00425 return p;
00426
00427 }
00428
00440 int Extra_bddCheckVarsSymmetricNaive(
00441 DdManager * dd,
00442 DdNode * bF,
00443 int iVar1,
00444 int iVar2)
00445 {
00446 DdNode * bCube1, * bCube2;
00447 DdNode * bCof01, * bCof10;
00448 int Res;
00449
00450 assert( iVar1 != iVar2 );
00451 assert( iVar1 < dd->size );
00452 assert( iVar2 < dd->size );
00453
00454 bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] ); Cudd_Ref( bCube1 );
00455 bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] ); Cudd_Ref( bCube2 );
00456
00457 bCof01 = Cudd_Cofactor( dd, bF, bCube1 ); Cudd_Ref( bCof01 );
00458 bCof10 = Cudd_Cofactor( dd, bF, bCube2 ); Cudd_Ref( bCof10 );
00459
00460 Res = (int)( bCof10 == bCof01 );
00461
00462 Cudd_RecursiveDeref( dd, bCof01 );
00463 Cudd_RecursiveDeref( dd, bCof10 );
00464 Cudd_RecursiveDeref( dd, bCube1 );
00465 Cudd_RecursiveDeref( dd, bCube2 );
00466
00467 return Res;
00468 }
00469
00470
00485 DdNode* Extra_zddTuplesFromBdd(
00486 DdManager * dd,
00487 int K,
00488 DdNode * bVarsN)
00489 {
00490 DdNode *zRes;
00491 int autoDynZ;
00492
00493 autoDynZ = dd->autoDynZ;
00494 dd->autoDynZ = 0;
00495
00496 do {
00497
00498
00499 DdNode *bVarSet = bVarsN, *bVarsK = bVarsN;
00500 int nVars = 0, i;
00501
00502
00503 while ( bVarSet != b1 )
00504 {
00505 nVars++;
00506
00507 if ( cuddE( bVarSet ) != b0 )
00508 return NULL;
00509 bVarSet = cuddT( bVarSet );
00510 }
00511
00512
00513
00514 if ( K > nVars )
00515 return NULL;
00516
00517
00518
00519
00520 for ( i = 0; i < nVars-K; i++ )
00521 bVarsK = cuddT( bVarsK );
00522
00523 dd->reordered = 0;
00524 zRes = extraZddTuplesFromBdd(dd, bVarsK, bVarsN );
00525
00526 } while (dd->reordered == 1);
00527 dd->autoDynZ = autoDynZ;
00528 return zRes;
00529
00530 }
00531
00543 DdNode* Extra_zddSelectOneSubset(
00544 DdManager * dd,
00545 DdNode * zS)
00546 {
00547 DdNode *res;
00548 do {
00549 dd->reordered = 0;
00550 res = extraZddSelectOneSubset(dd, zS);
00551 } while (dd->reordered == 1);
00552 return(res);
00553
00554 }
00555
00556
00557
00558
00559
00560
00576 DdNode *
00577 extraZddSymmPairsCompute(
00578 DdManager * dd,
00579 DdNode * bFunc,
00580 DdNode * bVars )
00581 {
00582 DdNode * zRes;
00583 DdNode * bFR = Cudd_Regular(bFunc);
00584
00585 if ( cuddIsConstant(bFR) )
00586 {
00587 int nVars, i;
00588
00589
00590 nVars = Extra_bddSuppSize( dd, bVars );
00591 if ( nVars < 2 )
00592 return z0;
00593 else
00594 {
00595 DdNode * bVarsK;
00596
00597
00598 bVarsK = bVars;
00599 for ( i = 0; i < nVars-2; i++ )
00600 bVarsK = cuddT( bVarsK );
00601 return extraZddTuplesFromBdd( dd, bVarsK, bVars );
00602 }
00603 }
00604 assert( bVars != b1 );
00605
00606 if ( zRes = cuddCacheLookup2Zdd(dd, extraZddSymmPairsCompute, bFunc, bVars) )
00607 return zRes;
00608 else
00609 {
00610 DdNode * zRes0, * zRes1;
00611 DdNode * zTemp, * zPlus, * zSymmVars;
00612 DdNode * bF0, * bF1;
00613 DdNode * bVarsNew;
00614 int nVarsExtra;
00615 int LevelF;
00616
00617
00618
00619
00620 nVarsExtra = 0;
00621 LevelF = dd->perm[bFR->index];
00622 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00623 nVarsExtra++;
00624
00625 assert( bFR->index == bVarsNew->index );
00626
00627
00628 if ( bFR != bFunc )
00629 {
00630 bF0 = Cudd_Not( cuddE(bFR) );
00631 bF1 = Cudd_Not( cuddT(bFR) );
00632 }
00633 else
00634 {
00635 bF0 = cuddE(bFR);
00636 bF1 = cuddT(bFR);
00637 }
00638
00639
00640 zRes0 = extraZddSymmPairsCompute( dd, bF0, cuddT(bVarsNew) );
00641 if ( zRes0 == NULL )
00642 return NULL;
00643 cuddRef( zRes0 );
00644
00645
00646
00647 if ( zRes0 == z0 )
00648 zRes = zRes0;
00649 else
00650 {
00651 zRes1 = extraZddSymmPairsCompute( dd, bF1, cuddT(bVarsNew) );
00652 if ( zRes1 == NULL )
00653 {
00654 Cudd_RecursiveDerefZdd( dd, zRes0 );
00655 return NULL;
00656 }
00657 cuddRef( zRes1 );
00658
00659
00660
00661
00662 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00663 if ( zRes == NULL )
00664 {
00665 Cudd_RecursiveDerefZdd( dd, zRes0 );
00666 Cudd_RecursiveDerefZdd( dd, zRes1 );
00667 return NULL;
00668 }
00669 cuddRef( zRes );
00670 Cudd_RecursiveDerefZdd( dd, zRes0 );
00671 Cudd_RecursiveDerefZdd( dd, zRes1 );
00672 }
00673
00674
00675
00676
00677 zSymmVars = extraZddGetSymmetricVars( dd, bF1, bF0, cuddT(bVarsNew) );
00678 if ( zSymmVars == NULL )
00679 {
00680 Cudd_RecursiveDerefZdd( dd, zRes );
00681 return NULL;
00682 }
00683 cuddRef( zSymmVars );
00684
00685
00686
00687
00688
00689 if ( zSymmVars == z0 )
00690 Cudd_RecursiveDerefZdd( dd, zSymmVars );
00691 else
00692 {
00693 zPlus = cuddZddGetNode( dd, 2*bFR->index, zSymmVars, z0 );
00694 if ( zPlus == NULL )
00695 {
00696 Cudd_RecursiveDerefZdd( dd, zRes );
00697 Cudd_RecursiveDerefZdd( dd, zSymmVars );
00698 return NULL;
00699 }
00700 cuddRef( zPlus );
00701 cuddDeref( zSymmVars );
00702
00703
00704 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00705 if ( zRes == NULL )
00706 {
00707 Cudd_RecursiveDerefZdd( dd, zTemp );
00708 Cudd_RecursiveDerefZdd( dd, zPlus );
00709 return NULL;
00710 }
00711 cuddRef( zRes );
00712 Cudd_RecursiveDerefZdd( dd, zTemp );
00713 Cudd_RecursiveDerefZdd( dd, zPlus );
00714 }
00715
00716
00717
00718
00719
00720
00721 if ( nVarsExtra )
00722 {
00723
00724
00725
00726
00727 DdNode * bVarsExtra;
00728 int nVars;
00729
00730
00731 bVarsExtra = extraBddReduceVarSet( dd, bVars, bFunc );
00732 if ( bVarsExtra == NULL )
00733 {
00734 Cudd_RecursiveDerefZdd( dd, zRes );
00735 return NULL;
00736 }
00737 cuddRef( bVarsExtra );
00738
00739
00740 nVars = Extra_bddSuppSize( dd, bVarsExtra );
00741 if ( nVars < 2 )
00742 {
00743 Cudd_RecursiveDeref( dd, bVarsExtra );
00744 }
00745 else
00746 {
00747 int i;
00748 DdNode * bVarsK;
00749
00750
00751 bVarsK = bVarsExtra;
00752 for ( i = 0; i < nVars-2; i++ )
00753 bVarsK = cuddT( bVarsK );
00754
00755
00756 zPlus = extraZddTuplesFromBdd( dd, bVarsK, bVarsExtra );
00757 if ( zPlus == NULL )
00758 {
00759 Cudd_RecursiveDeref( dd, bVarsExtra );
00760 Cudd_RecursiveDerefZdd( dd, zRes );
00761 return NULL;
00762 }
00763 cuddRef( zPlus );
00764 Cudd_RecursiveDeref( dd, bVarsExtra );
00765
00766
00767 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00768 if ( zRes == NULL )
00769 {
00770 Cudd_RecursiveDerefZdd( dd, zTemp );
00771 Cudd_RecursiveDerefZdd( dd, zPlus );
00772 return NULL;
00773 }
00774 cuddRef( zRes );
00775 Cudd_RecursiveDerefZdd( dd, zTemp );
00776 Cudd_RecursiveDerefZdd( dd, zPlus );
00777 }
00778 }
00779 cuddDeref( zRes );
00780
00781
00782
00783 cuddCacheInsert2(dd, extraZddSymmPairsCompute, bFunc, bVars, zRes);
00784 return zRes;
00785 }
00786 }
00787
00801 DdNode * extraZddGetSymmetricVars(
00802 DdManager * dd,
00803 DdNode * bF,
00804 DdNode * bG,
00805 DdNode * bVars)
00806 {
00807 DdNode * zRes;
00808 DdNode * bFR = Cudd_Regular(bF);
00809 DdNode * bGR = Cudd_Regular(bG);
00810
00811 if ( cuddIsConstant(bFR) && cuddIsConstant(bGR) )
00812 {
00813 if ( bF == bG )
00814 return extraZddGetSingletons( dd, bVars );
00815 else
00816 return z0;
00817 }
00818 assert( bVars != b1 );
00819
00820 if ( zRes = cuddCacheLookupZdd(dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars) )
00821 return zRes;
00822 else
00823 {
00824 DdNode * zRes0, * zRes1;
00825 DdNode * zPlus, * zTemp;
00826 DdNode * bF0, * bF1;
00827 DdNode * bG0, * bG1;
00828 DdNode * bVarsNew;
00829
00830 int LevelF = cuddI(dd,bFR->index);
00831 int LevelG = cuddI(dd,bGR->index);
00832 int LevelFG;
00833
00834 if ( LevelF < LevelG )
00835 LevelFG = LevelF;
00836 else
00837 LevelFG = LevelG;
00838
00839
00840 assert( LevelFG < dd->size );
00841
00842
00843
00844 for ( bVarsNew = bVars; LevelFG > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) );
00845 assert( LevelFG == dd->perm[bVarsNew->index] );
00846
00847
00848 if ( LevelF == LevelFG )
00849 {
00850 if ( bFR != bF )
00851 {
00852 bF0 = Cudd_Not( cuddE(bFR) );
00853 bF1 = Cudd_Not( cuddT(bFR) );
00854 }
00855 else
00856 {
00857 bF0 = cuddE(bFR);
00858 bF1 = cuddT(bFR);
00859 }
00860 }
00861 else
00862 bF0 = bF1 = bF;
00863
00864 if ( LevelG == LevelFG )
00865 {
00866 if ( bGR != bG )
00867 {
00868 bG0 = Cudd_Not( cuddE(bGR) );
00869 bG1 = Cudd_Not( cuddT(bGR) );
00870 }
00871 else
00872 {
00873 bG0 = cuddE(bGR);
00874 bG1 = cuddT(bGR);
00875 }
00876 }
00877 else
00878 bG0 = bG1 = bG;
00879
00880
00881 zRes0 = extraZddGetSymmetricVars( dd, bF0, bG0, cuddT(bVarsNew) );
00882 if ( zRes0 == NULL )
00883 return NULL;
00884 cuddRef( zRes0 );
00885
00886
00887
00888 if ( zRes0 == z0 )
00889 zRes = zRes0;
00890 else
00891 {
00892 zRes1 = extraZddGetSymmetricVars( dd, bF1, bG1, cuddT(bVarsNew) );
00893 if ( zRes1 == NULL )
00894 {
00895 Cudd_RecursiveDerefZdd( dd, zRes0 );
00896 return NULL;
00897 }
00898 cuddRef( zRes1 );
00899
00900
00901
00902 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00903 if ( zRes == NULL )
00904 {
00905 Cudd_RecursiveDerefZdd( dd, zRes0 );
00906 Cudd_RecursiveDerefZdd( dd, zRes1 );
00907 return NULL;
00908 }
00909 cuddRef( zRes );
00910 Cudd_RecursiveDerefZdd( dd, zRes0 );
00911 Cudd_RecursiveDerefZdd( dd, zRes1 );
00912 }
00913
00914
00915 if ( bF0 == bG1 )
00916 {
00917 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
00918 if ( zPlus == NULL )
00919 {
00920 Cudd_RecursiveDerefZdd( dd, zRes );
00921 return NULL;
00922 }
00923 cuddRef( zPlus );
00924
00925
00926 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00927 if ( zRes == NULL )
00928 {
00929 Cudd_RecursiveDerefZdd( dd, zTemp );
00930 Cudd_RecursiveDerefZdd( dd, zPlus );
00931 return NULL;
00932 }
00933 cuddRef( zRes );
00934 Cudd_RecursiveDerefZdd( dd, zTemp );
00935 Cudd_RecursiveDerefZdd( dd, zPlus );
00936 }
00937
00938 if ( bF == bG && bVars != bVarsNew )
00939 {
00940
00941
00942
00943 DdNode * bVarsExtra;
00944
00945 assert( LevelFG > dd->perm[bVars->index] );
00946
00947
00948 bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsNew );
00949 if ( bVarsExtra == NULL )
00950 {
00951 Cudd_RecursiveDerefZdd( dd, zRes );
00952 return NULL;
00953 }
00954 cuddRef( bVarsExtra );
00955
00956 zPlus = extraZddGetSingletons( dd, bVarsExtra );
00957 if ( zPlus == NULL )
00958 {
00959 Cudd_RecursiveDeref( dd, bVarsExtra );
00960 Cudd_RecursiveDerefZdd( dd, zRes );
00961 return NULL;
00962 }
00963 cuddRef( zPlus );
00964 Cudd_RecursiveDeref( dd, bVarsExtra );
00965
00966
00967 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00968 if ( zRes == NULL )
00969 {
00970 Cudd_RecursiveDerefZdd( dd, zTemp );
00971 Cudd_RecursiveDerefZdd( dd, zPlus );
00972 return NULL;
00973 }
00974 cuddRef( zRes );
00975 Cudd_RecursiveDerefZdd( dd, zTemp );
00976 Cudd_RecursiveDerefZdd( dd, zPlus );
00977 }
00978 cuddDeref( zRes );
00979
00980 cuddCacheInsert( dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars, zRes );
00981 return zRes;
00982 }
00983 }
00984
00985
00998 DdNode * extraZddGetSingletons(
00999 DdManager * dd,
01000 DdNode * bVars)
01001 {
01002 DdNode * zRes;
01003
01004 if ( bVars == b1 )
01005
01006 return z1;
01007
01008 if ( zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletons, bVars) )
01009 return zRes;
01010 else
01011 {
01012 DdNode * zTemp, * zPlus;
01013
01014
01015 zRes = extraZddGetSingletons( dd, cuddT(bVars) );
01016 if ( zRes == NULL )
01017 return NULL;
01018 cuddRef( zRes );
01019
01020 zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
01021 if ( zPlus == NULL )
01022 {
01023 Cudd_RecursiveDerefZdd( dd, zRes );
01024 return NULL;
01025 }
01026 cuddRef( zPlus );
01027
01028
01029 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
01030 if ( zRes == NULL )
01031 {
01032 Cudd_RecursiveDerefZdd( dd, zTemp );
01033 Cudd_RecursiveDerefZdd( dd, zPlus );
01034 return NULL;
01035 }
01036 cuddRef( zRes );
01037 Cudd_RecursiveDerefZdd( dd, zTemp );
01038 Cudd_RecursiveDerefZdd( dd, zPlus );
01039 cuddDeref( zRes );
01040
01041 cuddCacheInsert1( dd, extraZddGetSingletons, bVars, zRes );
01042 return zRes;
01043 }
01044 }
01045
01046
01059 DdNode * extraBddReduceVarSet(
01060 DdManager * dd,
01061 DdNode * bVars,
01062 DdNode * bF)
01063 {
01064 DdNode * bRes;
01065 DdNode * bFR = Cudd_Regular(bF);
01066
01067 if ( cuddIsConstant(bFR) || bVars == b1 )
01068 return bVars;
01069
01070 if ( bRes = cuddCacheLookup2(dd, extraBddReduceVarSet, bVars, bF) )
01071 return bRes;
01072 else
01073 {
01074 DdNode * bF0, * bF1;
01075 DdNode * bVarsThis, * bVarsLower, * bTemp;
01076 int LevelF;
01077
01078
01079 LevelF = dd->perm[bFR->index];
01080 for ( bVarsThis = bVars; LevelF > cuddI(dd,bVarsThis->index); bVarsThis = cuddT(bVarsThis) );
01081
01082 if ( LevelF == cuddI(dd,bVarsThis->index) )
01083 bVarsLower = cuddT(bVarsThis);
01084 else
01085 bVarsLower = bVarsThis;
01086
01087
01088 if ( bFR != bF )
01089 {
01090 bF0 = Cudd_Not( cuddE(bFR) );
01091 bF1 = Cudd_Not( cuddT(bFR) );
01092 }
01093 else
01094 {
01095 bF0 = cuddE(bFR);
01096 bF1 = cuddT(bFR);
01097 }
01098
01099
01100 bRes = extraBddReduceVarSet( dd, bVarsLower, bF0 );
01101 if ( bRes == NULL )
01102 return NULL;
01103 cuddRef( bRes );
01104
01105 bRes = extraBddReduceVarSet( dd, bTemp = bRes, bF1 );
01106 if ( bRes == NULL )
01107 {
01108 Cudd_RecursiveDeref( dd, bTemp );
01109 return NULL;
01110 }
01111 cuddRef( bRes );
01112 Cudd_RecursiveDeref( dd, bTemp );
01113
01114
01115
01116 if ( bVarsThis != bVars )
01117 {
01118 DdNode * bVarsExtra;
01119
01120
01121 bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsThis );
01122 if ( bVarsExtra == NULL )
01123 {
01124 Cudd_RecursiveDeref( dd, bRes );
01125 return NULL;
01126 }
01127 cuddRef( bVarsExtra );
01128
01129
01130 bRes = cuddBddAndRecur( dd, bTemp = bRes, bVarsExtra );
01131 if ( bRes == NULL )
01132 {
01133 Cudd_RecursiveDeref( dd, bTemp );
01134 Cudd_RecursiveDeref( dd, bVarsExtra );
01135 return NULL;
01136 }
01137 cuddRef( bRes );
01138 Cudd_RecursiveDeref( dd, bTemp );
01139 Cudd_RecursiveDeref( dd, bVarsExtra );
01140 }
01141 cuddDeref( bRes );
01142
01143 cuddCacheInsert2( dd, extraBddReduceVarSet, bVars, bF, bRes );
01144 return bRes;
01145 }
01146 }
01147
01148
01166 DdNode * extraBddCheckVarsSymmetric(
01167 DdManager * dd,
01168 DdNode * bF,
01169 DdNode * bVars)
01170 {
01171 DdNode * bRes;
01172
01173 if ( bF == b0 )
01174 return b1;
01175
01176 assert( bVars != b1 );
01177
01178 if ( bRes = cuddCacheLookup2(dd, extraBddCheckVarsSymmetric, bF, bVars) )
01179 return bRes;
01180 else
01181 {
01182 DdNode * bRes0, * bRes1;
01183 DdNode * bF0, * bF1;
01184 DdNode * bFR = Cudd_Regular(bF);
01185 int LevelF = cuddI(dd,bFR->index);
01186
01187 DdNode * bVarsR = Cudd_Regular(bVars);
01188 int fVar1Pres;
01189 int iLev1;
01190 int iLev2;
01191
01192 if ( bVarsR != bVars )
01193 {
01194 assert( cuddT(bVarsR) == b1 );
01195 fVar1Pres = 1;
01196 iLev1 = -1;
01197 iLev2 = dd->perm[bVarsR->index];
01198 }
01199 else
01200 {
01201 fVar1Pres = 0;
01202 if ( cuddT(bVars) == b1 )
01203 {
01204 iLev1 = -1;
01205 iLev2 = dd->perm[bVars->index];
01206 }
01207 else
01208 {
01209 assert( cuddT(cuddT(bVars)) == b1 );
01210 iLev1 = dd->perm[bVars->index];
01211 iLev2 = dd->perm[cuddT(bVars)->index];
01212 }
01213 }
01214
01215
01216
01217 if ( LevelF < iLev2 )
01218 {
01219 if ( bFR != bF )
01220 {
01221 bF0 = Cudd_Not( cuddE(bFR) );
01222 bF1 = Cudd_Not( cuddT(bFR) );
01223 }
01224 else
01225 {
01226 bF0 = cuddE(bFR);
01227 bF1 = cuddT(bFR);
01228 }
01229 }
01230 else
01231 bF0 = bF1 = NULL;
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 if ( LevelF < iLev1 )
01242 {
01243
01244
01245
01246 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
01247
01248 assert( bRes0 != z0 );
01249 if ( bRes0 == b0 )
01250 bRes = b0;
01251 else
01252 bRes = extraBddCheckVarsSymmetric( dd, bF1, bVars );
01253
01254 assert( bRes != z0 );
01255 }
01256
01257 else if ( LevelF == iLev1 )
01258 {
01259 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, Cudd_Not( cuddT(bVars) ) );
01260 if ( bRes0 == b0 )
01261 bRes = b0;
01262 else
01263 {
01264 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, Cudd_Not( cuddT(bVars) ) );
01265 if ( bRes1 == b0 )
01266 bRes = b0;
01267 else
01268 {
01269
01270 if ( bRes0 == z0 || bRes1 == z0 )
01271 bRes = b1;
01272 else
01273 bRes = b0;
01274 }
01275 }
01276 }
01277
01278 else if ( LevelF < iLev2 )
01279 {
01280 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
01281 if ( bRes0 == b0 )
01282 bRes = b0;
01283 else
01284 {
01285 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, bVars );
01286 if ( bRes1 == b0 )
01287 bRes = b0;
01288 else
01289 {
01290
01291
01292 if ( bRes0 == z0 || bRes1 == z0 )
01293 bRes = z0;
01294 else
01295 bRes = b1;
01296 }
01297 }
01298 }
01299
01300 else if ( LevelF == iLev2 )
01301 {
01302
01303
01304
01305
01306 if ( fVar1Pres )
01307
01308 bRes = z0;
01309 else
01310 bRes = b0;
01311 }
01312
01313 else
01314 {
01315
01316
01317
01318 bRes = b1;
01319 }
01320
01321 cuddCacheInsert2(dd, extraBddCheckVarsSymmetric, bF, bVars, bRes);
01322 return bRes;
01323 }
01324 }
01325
01338 DdNode* extraZddTuplesFromBdd(
01339 DdManager * dd,
01340 DdNode * bVarsK,
01341 DdNode * bVarsN)
01342 {
01343 DdNode *zRes, *zRes0, *zRes1;
01344 statLine(dd);
01345
01346
01347
01348
01349
01350
01351
01352 if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
01353 return z0;
01354 if ( bVarsN == b1 )
01355 return z1;
01356
01357
01358 zRes = cuddCacheLookup2Zdd(dd, extraZddTuplesFromBdd, bVarsK, bVarsN);
01359 if (zRes)
01360 return(zRes);
01361
01362
01363
01364 zRes0 = extraZddTuplesFromBdd( dd, bVarsK, cuddT(bVarsN) );
01365 if ( zRes0 == NULL )
01366 return NULL;
01367 cuddRef( zRes0 );
01368
01369
01370
01371 if ( bVarsK == b1 )
01372 {
01373 zRes1 = z0;
01374 cuddRef( zRes1 );
01375 }
01376 else
01377 {
01378 zRes1 = extraZddTuplesFromBdd( dd, cuddT(bVarsK), cuddT(bVarsN) );
01379 if ( zRes1 == NULL )
01380 {
01381 Cudd_RecursiveDerefZdd( dd, zRes0 );
01382 return NULL;
01383 }
01384 cuddRef( zRes1 );
01385 }
01386
01387
01388 zRes = cuddZddGetNode( dd, 2*bVarsN->index, zRes1, zRes0 );
01389 if ( zRes == NULL )
01390 {
01391 Cudd_RecursiveDerefZdd( dd, zRes0 );
01392 Cudd_RecursiveDerefZdd( dd, zRes1 );
01393 return NULL;
01394 }
01395 cuddDeref( zRes0 );
01396 cuddDeref( zRes1 );
01397
01398
01399 cuddCacheInsert2(dd, extraZddTuplesFromBdd, bVarsK, bVarsN, zRes);
01400 return zRes;
01401
01402 }
01403
01404
01416 DdNode * extraZddSelectOneSubset(
01417 DdManager * dd,
01418 DdNode * zS )
01419
01420
01421 {
01422 DdNode * zRes;
01423
01424 if ( zS == z0 ) return z0;
01425 if ( zS == z1 ) return z1;
01426
01427
01428 if ( zRes = cuddCacheLookup1Zdd( dd, extraZddSelectOneSubset, zS ) )
01429 return zRes;
01430 else
01431 {
01432 DdNode * zS0, * zS1, * zTemp;
01433
01434 zS0 = cuddE(zS);
01435 zS1 = cuddT(zS);
01436
01437 if ( zS0 != z0 )
01438 {
01439 zRes = extraZddSelectOneSubset( dd, zS0 );
01440 if ( zRes == NULL )
01441 return NULL;
01442 }
01443 else
01444 {
01445 assert( zS1 != z0 );
01446 zRes = extraZddSelectOneSubset( dd, zS1 );
01447 if ( zRes == NULL )
01448 return NULL;
01449 cuddRef( zRes );
01450
01451 zRes = cuddZddGetNode( dd, zS->index, zTemp = zRes, z0 );
01452 if ( zRes == NULL )
01453 {
01454 Cudd_RecursiveDerefZdd( dd, zTemp );
01455 return NULL;
01456 }
01457 cuddDeref( zTemp );
01458 }
01459
01460
01461 cuddCacheInsert1( dd, extraZddSelectOneSubset, zS, zRes );
01462 return zRes;
01463 }
01464 }
01465
01466
01467
01468
01469