#include "extra.h"
Go to the source code of this file.
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 */
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 }
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 }
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 }
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 }
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 }
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 }
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 */
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 }
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 }
Function********************************************************************
Synopsis [Returns 1 if the support contains the given BDD variable.]
Description []
SideEffects []
SeeAlso []
Definition at line 320 of file extraBddMisc.c.
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 }
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 */
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 }
Function********************************************************************
Synopsis [Returns the size of the support.]
Description []
SideEffects []
SeeAlso []
Definition at line 295 of file extraBddMisc.c.
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 }
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 */
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 */
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 }
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 */
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 */
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 [
]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 */
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 */