src/misc/extra/extraBddMisc.c File Reference

#include "extra.h"
Include dependency graph for extraBddMisc.c:

Go to the source code of this file.

Functions

static DdNodeextraTransferPermuteRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table, int *Permute)
static DdNodeextraTransferPermute (DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)
static DdNode *cuddBddPermuteRecur ARGS ((DdManager *manager, DdHashTable *table, DdNode *node, int *permut))
static void ddSupportStep (DdNode *f, int *support)
static void ddClearFlag (DdNode *f)
static DdNodeextraZddPrimes (DdManager *dd, DdNode *F)
DdNodeExtra_TransferPermute (DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
DdNodeExtra_TransferLevelByLevel (DdManager *ddSource, DdManager *ddDestination, DdNode *f)
DdNodeExtra_bddRemapUp (DdManager *dd, DdNode *bF)
DdNodeExtra_bddMove (DdManager *dd, DdNode *bF, int nVars)
void Extra_StopManager (DdManager *dd)
void Extra_bddPrint (DdManager *dd, DdNode *F)
int Extra_bddSuppSize (DdManager *dd, DdNode *bSupp)
int Extra_bddSuppContainVar (DdManager *dd, DdNode *bS, DdNode *bVar)
int Extra_bddSuppOverlapping (DdManager *dd, DdNode *S1, DdNode *S2)
int Extra_bddSuppDifferentVars (DdManager *dd, DdNode *S1, DdNode *S2, int DiffMax)
int Extra_bddSuppCheckContainment (DdManager *dd, DdNode *bL, DdNode *bH, DdNode **bLarge, DdNode **bSmall)
int * Extra_SupportArray (DdManager *dd, DdNode *f, int *support)
int * Extra_VectorSupportArray (DdManager *dd, DdNode **F, int n, int *support)
DdNodeExtra_bddFindOneCube (DdManager *dd, DdNode *bF)
DdNodeExtra_bddGetOneCube (DdManager *dd, DdNode *bFunc)
DdNodeExtra_bddComputeRangeCube (DdManager *dd, int iStart, int iStop)
DdNodeExtra_bddBitsToCube (DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
DdNodeExtra_bddSupportNegativeCube (DdManager *dd, DdNode *f)
int Extra_bddIsVar (DdNode *bFunc)
DdNodeExtra_bddCreateAnd (DdManager *dd, int nVars)
DdNodeExtra_bddCreateOr (DdManager *dd, int nVars)
DdNodeExtra_bddCreateExor (DdManager *dd, int nVars)
DdNodeExtra_zddPrimes (DdManager *dd, DdNode *F)
void Extra_bddPermuteArray (DdManager *manager, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
DdNodeextraBddMove (DdManager *dd, DdNode *bF, DdNode *bDist)
void extraDecomposeCover (DdManager *dd, DdNode *zC, DdNode **zC0, DdNode **zC1, DdNode **zC2)
DdNodeextraComposeCover (DdManager *dd, DdNode *zC0, DdNode *zC1, DdNode *zC2, int TopVar)
static DdNodecuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut)

Function Documentation

static DdNode* cuddBddPermuteRecur ARGS ( (DdManager *manager, DdHashTable *table, DdNode *node, int *permut)   )  [static]
static DdNode* cuddBddPermuteRecur ( DdManager manager,
DdHashTable table,
DdNode node,
int *  permut 
) [static]

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddPermute.]

Description [ Recursively puts the BDD in the order given in the array permut. Checks for trivial cases to terminate recursion, then splits on the children of this node. Once the solutions for the children are obtained, it puts into the current position the node from the rest of the BDD that should be here. Then returns this BDD. The key here is that the node being visited is NOT put in its proper place by this instance, but rather is switched when its proper position is reached in the recursion tree.

The DdNode * that is returned is the same BDD as passed in as node, but in the new order.]

SideEffects [None]

SeeAlso [Cudd_bddPermute cuddAddPermuteRecur]

Definition at line 1535 of file extraBddMisc.c.

01539 {
01540         DdNode *N, *T, *E;
01541         DdNode *res;
01542         int index;
01543 
01544         statLine( manager );
01545         N = Cudd_Regular( node );
01546 
01547         /* Check for terminal case of constant node. */
01548         if ( cuddIsConstant( N ) )
01549         {
01550                 return ( node );
01551         }
01552 
01553         /* If problem already solved, look up answer and return. */
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         /* Split and recur on children of this node. */
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         /* Move variable that should be in this position to this position
01576            ** by retrieving the single var BDD for that variable, and calling
01577            ** cuddBddIteRecur with the T and E we just created.
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         /* Do not keep the result if the reference count is only 1, since
01592            ** it will not be visited again.
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 }                                                               /* end of cuddBddPermuteRecur */

static void ddClearFlag ( DdNode f  )  [static]

Function********************************************************************

Synopsis [Performs a DFS from f, clearing the LSB of the next pointers.]

Description []

SideEffects [None]

SeeAlso [ddSupportStep ddDagInt]

Definition at line 1301 of file extraBddMisc.c.

01303 {
01304     if (!Cudd_IsComplement(f->next)) {
01305         return;
01306     }
01307     /* Clear visited flag. */
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 } /* end of ddClearFlag */

static void ddSupportStep ( DdNode f,
int *  support 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_Support.]

Description [Performs the recursive step of Cudd_Support. Performs a DFS from f. The support is accumulated in supp as a side effect. Uses the LSB of the then pointer as visited flag.]

SideEffects [None]

SeeAlso [ddClearFlag]

Definition at line 1270 of file extraBddMisc.c.

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     /* Mark as visited. */
01282     f->next = Cudd_Not(f->next);
01283     return;
01284 
01285 } /* end of ddSupportStep */

DdNode* Extra_bddBitsToCube ( DdManager dd,
int  Code,
int  CodeWidth,
DdNode **  pbVars,
int  fMsbFirst 
)

Function********************************************************************

Synopsis [Computes the cube of BDD variables corresponding to bits it the bit-code]

Description [Returns a bdd composed of elementary bdds found in array BddVars[] such that the bdd vars encode the number Value of bit length CodeWidth (if fMsbFirst is 1, the most significant bit is encoded with the first bdd variable). If the variables BddVars are not specified, takes the first CodeWidth variables of the manager]

SideEffects []

SeeAlso []

Definition at line 704 of file extraBddMisc.c.

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 }  /* end of Extra_bddBitsToCube */

DdNode* Extra_bddComputeRangeCube ( DdManager dd,
int  iStart,
int  iStop 
)

Function********************************************************************

Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]

Description []

SideEffects []

SeeAlso []

Definition at line 673 of file extraBddMisc.c.

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 }

DdNode* Extra_bddCreateAnd ( DdManager dd,
int  nVars 
)

Function********************************************************************

Synopsis [Creates AND composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 832 of file extraBddMisc.c.

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 }

DdNode* Extra_bddCreateExor ( DdManager dd,
int  nVars 
)

Function********************************************************************

Synopsis [Creates EXOR composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 882 of file extraBddMisc.c.

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 }

DdNode* Extra_bddCreateOr ( DdManager dd,
int  nVars 
)

Function********************************************************************

Synopsis [Creates OR composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 857 of file extraBddMisc.c.

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 }

DdNode* Extra_bddFindOneCube ( DdManager dd,
DdNode bF 
)

Function********************************************************************

Synopsis [Find any cube belonging to the on-set of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 579 of file extraBddMisc.c.

00580 {
00581     char * s_Temp;
00582     DdNode * bCube, * bTemp;
00583     int v;
00584 
00585     // get the vector of variables in the cube
00586     s_Temp = ALLOC( char, dd->size );
00587     Cudd_bddPickOneCube( dd, bF, s_Temp );
00588 
00589     // start the cube
00590     bCube = b1; Cudd_Ref( bCube );
00591     for ( v = 0; v < dd->size; v++ )
00592         if ( s_Temp[v] == 0 )
00593         {
00594 //          Cube &= !s_XVars[v];
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 //          Cube &=  s_XVars[v];
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 }

DdNode* Extra_bddGetOneCube ( DdManager dd,
DdNode bFunc 
)

Function********************************************************************

Synopsis [Returns one cube contained in the given BDD.]

Description [This function returns the cube with the smallest bits-to-integer value.]

SideEffects []

Definition at line 619 of file extraBddMisc.c.

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     // cofactor
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     // try to find the cube with the negative literal
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         // try to find the cube with the positive literal
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 }

int Extra_bddIsVar ( DdNode bFunc  ) 

Function********************************************************************

Synopsis [Returns 1 if the BDD is the BDD of elementary variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 813 of file extraBddMisc.c.

00814 {
00815     bFunc = Cudd_Regular( bFunc );
00816     if ( cuddIsConstant(bFunc) )
00817         return 0;
00818     return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
00819 }

DdNode* Extra_bddMove ( DdManager dd,
DdNode bF,
int  nVars 
)

Function********************************************************************

Synopsis [Moves the BDD by the given number of variables up or down.]

Description []

SideEffects []

SeeAlso [Extra_bddShift]

Definition at line 182 of file extraBddMisc.c.

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 } /* end of Extra_bddMove */

void Extra_bddPermuteArray ( DdManager manager,
DdNode **  bNodesIn,
DdNode **  bNodesOut,
int  nNodes,
int *  permut 
)

Function********************************************************************

Synopsis [Permutes the variables of the array of BDDs.]

Description [Given a permutation in array permut, creates a new BDD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. The DDs in the resulting array are already referenced.]

SideEffects [None]

SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]

Definition at line 935 of file extraBddMisc.c.

00936 {
00937         DdHashTable *table;
00938         int i, k;
00939         do
00940         {
00941                 manager->reordered = 0;
00942                 table = cuddHashTableInit( manager, 1, 2 );
00943 
00944                 /* permute the output functions one-by-one */
00945                 for ( i = 0; i < nNodes; i++ )
00946                 {
00947                         bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
00948                         if ( bNodesOut[i] == NULL )
00949                         {
00950                                 /* deref the array of the already computed outputs */
00951                                 for ( k = 0; k < i; k++ )
00952                                         Cudd_RecursiveDeref( manager, bNodesOut[k] );
00953                                 break;
00954                         }
00955                         cuddRef( bNodesOut[i] );
00956                 }
00957                 /* Dispose of local cache. */
00958                 cuddHashTableQuit( table );
00959         }
00960         while ( manager->reordered == 1 );
00961 }       /* end of Extra_bddPermuteArray */

void Extra_bddPrint ( DdManager dd,
DdNode F 
)

Function********************************************************************

Synopsis [Outputs the BDD in a readable format.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 240 of file extraBddMisc.c.

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 //          Output << " + ";
00271             printf( " + " );
00272 
00273         for ( i = 0; i < nVars; i++ )
00274             if ( Cube[i] == 0 )
00275                 printf( "[%d]'", i );
00276 //              printf( "%c'", (char)('a'+i) );
00277             else if ( Cube[i] == 1 )
00278                 printf( "[%d]", i );
00279 //              printf( "%c", (char)('a'+i) );
00280     }
00281 
00282 //  printf("\n");
00283 }

DdNode* Extra_bddRemapUp ( DdManager dd,
DdNode bF 
)

Function********************************************************************

Synopsis [Remaps the function to depend on the topmost variables on the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 140 of file extraBddMisc.c.

00143 {
00144     int * pPermute;
00145     DdNode * bSupp, * bTemp, * bRes;
00146     int Counter;
00147 
00148     pPermute = ALLOC( int, dd->size );
00149 
00150     // get support
00151     bSupp = Cudd_Support( dd, bF );    Cudd_Ref( bSupp );
00152 
00153     // create the variable map
00154     // to remap the DD into the upper part of the manager
00155     Counter = 0;
00156     for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
00157         pPermute[bTemp->index] = dd->invperm[Counter++];
00158 
00159     // transfer the BDD and remap it
00160     bRes = Cudd_bddPermute( dd, bF, pPermute );  Cudd_Ref( bRes );
00161 
00162     // remove support
00163     Cudd_RecursiveDeref( dd, bSupp );
00164 
00165     // return
00166     Cudd_Deref( bRes );
00167     free( pPermute );
00168     return bRes;
00169 }

int Extra_bddSuppCheckContainment ( DdManager dd,
DdNode bL,
DdNode bH,
DdNode **  bLarge,
DdNode **  bSmall 
)

Function********************************************************************

Synopsis [Checks the support containment.]

Description [This function returns 1 if one support is contained in another. In this case, bLarge (bSmall) is assigned to point to the larger (smaller) support. If the supports are identical, return 0 and does not assign the supports!]

SideEffects []

SeeAlso []

Definition at line 417 of file extraBddMisc.c.

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         { // Low component has no vars; High components has some vars
00432             fLcontainsH = 0;
00433             if ( fHcontainsL == 0 )
00434                 return 0;
00435             else
00436                 break;
00437         }
00438 
00439         if ( bSH == b1 )
00440         { // similarly
00441             fHcontainsL = 0;
00442             if ( fLcontainsH == 0 )
00443                 return 0;
00444             else
00445                 break;
00446         }
00447 
00448         // determine the topmost var of the supports by comparing their levels
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         { // they are on the same level
00456             // it does not tell us anything about their containment
00457             // skip this var
00458             bSL = cuddT(bSL);
00459             bSH = cuddT(bSH);
00460         }
00461         else if ( TopVar == bSL->index ) // and TopVar != bSH->index
00462         { // Low components is higher and contains more vars
00463             // it is not possible that High component contains Low
00464             fHcontainsL = 0;
00465             // skip this var
00466             bSL = cuddT(bSL);
00467         }
00468         else // if ( TopVar == bSH->index ) // and TopVar != bSL->index
00469         { // similarly
00470             fLcontainsH = 0;
00471             // skip this var
00472             bSH = cuddT(bSH);
00473         }
00474 
00475         // check the stopping condition
00476         if ( !fHcontainsL && !fLcontainsH )
00477             return 0;
00478     }
00479     // only one of them can be true at the same time
00480     assert( !fHcontainsL || !fLcontainsH );
00481     if ( fHcontainsL )
00482     {
00483         *bLarge = bH;
00484         *bSmall = bL;
00485     }
00486     else // fLcontainsH
00487     {
00488         *bLarge = bL;
00489         *bSmall = bH;
00490     }
00491     return 1;
00492 }

int Extra_bddSuppContainVar ( DdManager dd,
DdNode bS,
DdNode bVar 
)

Function********************************************************************

Synopsis [Returns 1 if the support contains the given BDD variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 320 of file extraBddMisc.c.

00321 { 
00322     for( ; bS != b1; bS = cuddT(bS) )
00323         if ( bS->index == bVar->index )
00324             return 1;
00325     return 0;
00326 }

int Extra_bddSuppDifferentVars ( DdManager dd,
DdNode S1,
DdNode S2,
int  DiffMax 
)

Function********************************************************************

Synopsis [Returns the number of different vars in two supports.]

Description [Counts the number of variables that appear in one support and does not appear in other support. If the number exceeds DiffMax, returns DiffMax.]

SideEffects []

SeeAlso []

Definition at line 367 of file extraBddMisc.c.

00368 {
00369     int Result = 0;
00370     while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00371     {
00372         // if the top vars are the same, this var is the same
00373         if ( S1->index == S2->index )
00374         {
00375             S1 = cuddT(S1);
00376             S2 = cuddT(S2);
00377             continue;
00378         }
00379         // the top var is different
00380         Result++;
00381 
00382         if ( Result >= DiffMax )
00383             return DiffMax;
00384 
00385         // if the top vars are different, skip the one, which is higher
00386         if ( dd->perm[S1->index] < dd->perm[S2->index] )
00387             S1 = cuddT(S1);
00388         else
00389             S2 = cuddT(S2);
00390     }
00391 
00392     // consider the remaining variables
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 }

DdNode* Extra_bddSupportNegativeCube ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Finds the support as a negative polarity cube.]

Description [Finds the variables on which a DD depends. Returns a BDD consisting of the product of the variables in the negative polarity if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_VectorSupport Cudd_Support]

Definition at line 738 of file extraBddMisc.c.

00739 {
00740         int *support;
00741         DdNode *res, *tmp, *var;
00742         int i, j;
00743         int size;
00744 
00745         /* Allocate and initialize support array for ddSupportStep. */
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         /* Compute support and clean up markers. */
00759         ddSupportStep( Cudd_Regular( f ), support );
00760         ddClearFlag( Cudd_Regular( f ) );
00761 
00762         /* Transform support from array to cube. */
00763         do
00764         {
00765                 dd->reordered = 0;
00766                 res = DD_ONE( dd );
00767                 cuddRef( res );
00768                 for ( j = size - 1; j >= 0; j-- )
00769                 {                                               /* for each level bottom-up */
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 }                                                               /* end of Extra_SupportNeg */

int Extra_bddSuppOverlapping ( DdManager dd,
DdNode S1,
DdNode S2 
)

Function********************************************************************

Synopsis [Returns 1 if two supports represented as BDD cubes are overlapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 339 of file extraBddMisc.c.

00340 {
00341     while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00342     {
00343         // if the top vars are the same, they intersect
00344         if ( S1->index == S2->index )
00345             return 1;
00346         // if the top vars are different, skip the one, which is higher
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 }

int Extra_bddSuppSize ( DdManager dd,
DdNode bSupp 
)

Function********************************************************************

Synopsis [Returns the size of the support.]

Description []

SideEffects []

SeeAlso []

Definition at line 295 of file extraBddMisc.c.

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 }

void Extra_StopManager ( DdManager dd  ) 

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 218 of file extraBddMisc.c.

00219 {
00220     int RetValue;
00221     // check for remaining references in the package
00222     RetValue = Cudd_CheckZeroRef( dd );
00223     if ( RetValue > 0 )
00224         printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
00225 //  Cudd_PrintInfo( dd, stdout );
00226     Cudd_Quit( dd );
00227 }

int* Extra_SupportArray ( DdManager dd,
DdNode f,
int *  support 
)

Function********************************************************************

Synopsis [Finds variables on which the DD depends and returns them as am array.]

Description [Finds the variables on which the DD depends. Returns an array with entries set to 1 for those variables that belong to the support; NULL otherwise. The array is allocated by the user and should have at least as many entries as the maximum number of variables in BDD and ZDD parts of the manager.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]

Definition at line 511 of file extraBddMisc.c.

00515 {
00516     int i, size;
00517 
00518     /* Initialize support array for ddSupportStep. */
00519     size = ddMax(dd->size, dd->sizeZ);
00520     for (i = 0; i < size; i++) 
00521         support[i] = 0;
00522     
00523     /* Compute support and clean up markers. */
00524     ddSupportStep(Cudd_Regular(f),support);
00525     ddClearFlag(Cudd_Regular(f));
00526 
00527     return(support);
00528 
00529 } /* end of Extra_SupportArray */

DdNode* Extra_TransferLevelByLevel ( DdManager ddSource,
DdManager ddDestination,
DdNode f 
)

Function********************************************************************

Synopsis [Transfers the BDD from one manager into another level by level.]

Description [Transfers the BDD from one manager into another while preserving the correspondence between variables level by level.]

SideEffects [None]

SeeAlso []

Definition at line 107 of file extraBddMisc.c.

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     // set up the variable permutation
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 }

DdNode* Extra_TransferPermute ( DdManager ddSource,
DdManager ddDestination,
DdNode f,
int *  Permute 
)

AutomaticEnd Function********************************************************************

Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]

Description [Convert a {A,B}DD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the {A,B}DD in the destination manager if successful; NULL otherwise. The i-th entry in the array Permute tells what is the index of the i-th variable from the old manager in the new manager.]

SideEffects [None]

SeeAlso []

Definition at line 82 of file extraBddMisc.c.

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 }                               /* end of Extra_TransferPermute */

int* Extra_VectorSupportArray ( DdManager dd,
DdNode **  F,
int  n,
int *  support 
)

Function********************************************************************

Synopsis [Finds the variables on which a set of DDs depends.]

Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_ClassifySupport]

Definition at line 546 of file extraBddMisc.c.

00551 {
00552     int i, size;
00553 
00554     /* Allocate and initialize support array for ddSupportStep. */
00555     size = ddMax( dd->size, dd->sizeZ );
00556     for ( i = 0; i < size; i++ )
00557         support[i] = 0;
00558 
00559     /* Compute support and clean up markers. */
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 }

DdNode* Extra_zddPrimes ( DdManager dd,
DdNode F 
)

Function********************************************************************

Synopsis [Computes the set of primes as a ZDD.]

Description []

SideEffects []

SeeAlso []

Definition at line 907 of file extraBddMisc.c.

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 } /* end of Extra_zddPrimes */

DdNode* extraBddMove ( DdManager dd,
DdNode bF,
DdNode bDist 
)

Function********************************************************************

Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]

Description []

SideEffects []

SeeAlso []

Definition at line 979 of file extraBddMisc.c.

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         // cofactor the functions
01005         if ( bFR != bF ) // bFunc is complemented 
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         /* only bRes0 and bRes1 are referenced at this point */
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         /* insert the result into cache */
01042         cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
01043         cuddDeref( bRes );
01044         return bRes;
01045     }
01046 } /* end of extraBddMove */

DdNode* extraComposeCover ( DdManager dd,
DdNode zC0,
DdNode zC1,
DdNode zC2,
int  TopVar 
)

Function********************************************************************

Synopsis [Composed three subcovers into one ZDD.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1331 of file extraBddMisc.c.

01337 {
01338     DdNode * zRes, * zTemp;
01339     /* compose with-neg-var and without-var using the neg ZDD var */
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     /* compose with-pos-var and previous result using the pos ZDD var */
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 } /* extraComposeCover */

void extraDecomposeCover ( DdManager dd,
DdNode zC,
DdNode **  zC0,
DdNode **  zC1,
DdNode **  zC2 
)

Function********************************************************************

Synopsis [Finds three cofactors of the cover w.r.t. to the topmost variable.]

Description [Finds three cofactors of the cover w.r.t. to the topmost variable. Does not check the cover for being a constant. Assumes that ZDD variables encoding positive and negative polarities are adjacent in the variable order. Is different from cuddZddGetCofactors3() in that it does not compute the cofactors w.r.t. the given variable but takes the cofactors with respent to the topmost variable. This function is more efficient when used in recursive procedures because it does not require referencing of the resulting cofactors (compare cuddZddProduct() and extraZddPrimeProduct()).]

SideEffects [None]

SeeAlso [cuddZddGetCofactors3]

Definition at line 1068 of file extraBddMisc.c.

01074 {
01075     if ( (zC->index & 1) == 0 ) 
01076     { /* the top variable is present in positive polarity and maybe in negative */
01077 
01078         DdNode *Temp = cuddE( zC );
01079         *zC1  = cuddT( zC );
01080         if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
01081         {   /* Temp is not a terminal node 
01082              * top var is present in negative polarity */
01083             *zC2 = cuddE( Temp );
01084             *zC0 = cuddT( Temp );
01085         }
01086         else
01087         {   /* top var is not present in negative polarity */
01088             *zC2 = Temp;
01089             *zC0 = dd->zero;
01090         }
01091     }
01092     else 
01093     { /* the top variable is present only in negative */
01094         *zC1 = dd->zero;
01095         *zC2 = cuddE( zC );
01096         *zC0 = cuddT( zC );
01097     }
01098 } /* extraDecomposeCover */

DdNode * extraTransferPermute ( DdManager ddS,
DdManager ddD,
DdNode f,
int *  Permute 
) [static]

Function********************************************************************

Synopsis [Convert a BDD from a manager to another one.]

Description [Convert a BDD from a manager to another one. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Extra_TransferPermute]

Definition at line 1117 of file extraBddMisc.c.

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     /* Dereference all elements in the table and dispose of the table.
01132        ** This must be done also if res is NULL to avoid leaks in case of
01133        ** reordering. */
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 }                               /* end of extraTransferPermute */

static DdNode * extraTransferPermuteRecur ( DdManager ddS,
DdManager ddD,
DdNode f,
st_table table,
int *  Permute 
) [static]

CFile****************************************************************

FileName [extraBddMisc.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [extra]

Synopsis [DD-based utilities.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - June 20, 2005.]

Revision [

Id
extraBddMisc.c,v 1.4 2005/10/04 00:19:54 alanmi Exp

]AutomaticStart

Function********************************************************************

Synopsis [Performs the recursive step of Extra_TransferPermute.]

Description [Performs the recursive step of Extra_TransferPermute. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [extraTransferPermute]

Definition at line 1173 of file extraBddMisc.c.

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     /* Trivial cases. */
01190     if ( Cudd_IsConstant( f ) )
01191         return ( Cudd_NotCond( one, comple ) );
01192 
01193 
01194     /* Make canonical to increase the utilization of the cache. */
01195     f = Cudd_NotCond( f, comple );
01196     /* Now f is a regular pointer to a non-constant node. */
01197 
01198     /* Check the cache. */
01199     if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) )
01200         return ( Cudd_NotCond( res, comple ) );
01201 
01202     /* Recursive step. */
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 }                               /* end of extraTransferPermuteRecur */

DdNode * extraZddPrimes ( DdManager dd,
DdNode F 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of prime computation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1376 of file extraBddMisc.c.

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     /* check cache */
01386     zRes = cuddCacheLookup1Zdd(dd, extraZddPrimes, F);
01387     if (zRes)
01388         return(zRes);
01389         {
01390                 /* temporary variables */
01391                 DdNode *bF01, *zP0, *zP1;
01392                 /* three components of the prime set */
01393                 DdNode *zResE, *zResP, *zResN;
01394                 int fIsComp = Cudd_IsComplement( F );
01395 
01396                 /* find cofactors of F */
01397                 DdNode * bF0 = Cudd_NotCond( Cudd_E( F ), fIsComp );
01398                 DdNode * bF1 = Cudd_NotCond( Cudd_T( F ), fIsComp );
01399 
01400                 /* find the intersection of cofactors */
01401                 bF01 = cuddBddAndRecur( dd, bF0, bF1 );
01402                 if ( bF01 == NULL ) return NULL;
01403                 cuddRef( bF01 );
01404 
01405                 /* solve the problems for cofactors */
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                 /* check for local unateness */
01424                 if ( bF01 == bF0 )       /* unate increasing */
01425                 {
01426                         /* intersection is useless */
01427                         cuddDeref( bF01 );
01428                         /* the primes of intersection are the primes of F0 */
01429                         zResE = zP0;
01430                         /* there are no primes with negative var */
01431                         zResN = dd->zero;
01432                         cuddRef( zResN );
01433                         /* primes with positive var are primes of F1 that are not primes of F01 */
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 ) /* unate decreasing */
01446                 {
01447                         /* intersection is useless */
01448                         cuddDeref( bF01 );
01449                         /* the primes of intersection are the primes of F1 */
01450                         zResE = zP1;
01451                         /* there are no primes with positive var */
01452                         zResP = dd->zero;
01453                         cuddRef( zResP );
01454                         /* primes with negative var are primes of F0 that are not primes of F01 */
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 /* not unate */
01467                 {
01468                         /* primes without the top var are primes of F10 */
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                         /* primes with the negative top var are those of P0 that are not in F10 */
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                         /* primes with the positive top var are those of P1 that are not in F10 */
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                 /* insert the result into cache */
01509                 cuddCacheInsert1(dd, extraZddPrimes, F, zRes);
01510                 return zRes;
01511         }
01512 } /* end of extraZddPrimes */


Generated on Tue Jan 5 12:19:14 2010 for abc70930 by  doxygen 1.6.1