#include "util_hack.h"
#include "cuddInt.h"
Go to the source code of this file.
Defines | |
#define | CUDD_SWAP_MOVE 0 |
#define | CUDD_LINEAR_TRANSFORM_MOVE 1 |
#define | CUDD_INVERSE_TRANSFORM_MOVE 2 |
Functions | |
static int cuddZddLinearAux | ARGS ((DdManager *table, int x, int xLow, int xHigh)) |
static Move *cuddZddLinearUp | ARGS ((DdManager *table, int y, int xLow, Move *prevMoves)) |
static Move *cuddZddLinearDown | ARGS ((DdManager *table, int x, int xHigh, Move *prevMoves)) |
static int cuddZddLinearBackward | ARGS ((DdManager *table, int size, Move *moves)) |
static Move *cuddZddUndoMoves | ARGS ((DdManager *table, Move *moves)) |
int | cuddZddLinearSifting (DdManager *table, int lower, int upper) |
int | cuddZddLinearInPlace (DdManager *table, int x, int y) |
static int | cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh) |
static Move * | cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves) |
static Move * | cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves) |
static int | cuddZddLinearBackward (DdManager *table, int size, Move *moves) |
static Move * | cuddZddUndoMoves (DdManager *table, Move *moves) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $" |
int * | zdd_entry |
int | zddTotalNumberSwapping |
static int | zddTotalNumberLinearTr |
static DdNode * | empty |
#define CUDD_INVERSE_TRANSFORM_MOVE 2 |
Definition at line 44 of file cuddZddLin.c.
#define CUDD_LINEAR_TRANSFORM_MOVE 1 |
Definition at line 43 of file cuddZddLin.c.
#define CUDD_SWAP_MOVE 0 |
CFile***********************************************************************
FileName [cuddZddLin.c]
PackageName [cudd]
Synopsis [Procedures for dynamic variable ordering of ZDDs.]
Description [Internal procedures included in this module:
Static procedures included in this module:
]
SeeAlso [cuddLinear.c cuddZddReord.c]
Author [Fabio Somenzi]
Copyright [ This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]
Definition at line 42 of file cuddZddLin.c.
static Move* cuddZddLinearDown ARGS | ( | (DdManager *table, int x, int xHigh, Move *prevMoves) | ) | [static] |
static int cuddZddLinearAux ARGS | ( | (DdManager *table, int x, int xLow, int xHigh) | ) | [static] |
AutomaticStart
static int cuddZddLinearAux | ( | DdManager * | table, | |
int | x, | |||
int | xLow, | |||
int | xHigh | |||
) | [static] |
Function********************************************************************
Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]
Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 545 of file cuddZddLin.c.
00550 { 00551 Move *move; 00552 Move *moveUp; /* list of up move */ 00553 Move *moveDown; /* list of down move */ 00554 00555 int initial_size; 00556 int result; 00557 00558 initial_size = table->keysZ; 00559 00560 #ifdef DD_DEBUG 00561 assert(table->subtableZ[x].keys > 0); 00562 #endif 00563 00564 moveDown = NULL; 00565 moveUp = NULL; 00566 00567 if (x == xLow) { 00568 moveDown = cuddZddLinearDown(table, x, xHigh, NULL); 00569 /* At this point x --> xHigh. */ 00570 if (moveDown == (Move *) CUDD_OUT_OF_MEM) 00571 goto cuddZddLinearAuxOutOfMem; 00572 /* Move backward and stop at best position. */ 00573 result = cuddZddLinearBackward(table, initial_size, moveDown); 00574 if (!result) 00575 goto cuddZddLinearAuxOutOfMem; 00576 00577 } else if (x == xHigh) { 00578 moveUp = cuddZddLinearUp(table, x, xLow, NULL); 00579 /* At this point x --> xLow. */ 00580 if (moveUp == (Move *) CUDD_OUT_OF_MEM) 00581 goto cuddZddLinearAuxOutOfMem; 00582 /* Move backward and stop at best position. */ 00583 result = cuddZddLinearBackward(table, initial_size, moveUp); 00584 if (!result) 00585 goto cuddZddLinearAuxOutOfMem; 00586 00587 } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ 00588 moveDown = cuddZddLinearDown(table, x, xHigh, NULL); 00589 /* At this point x --> xHigh. */ 00590 if (moveDown == (Move *) CUDD_OUT_OF_MEM) 00591 goto cuddZddLinearAuxOutOfMem; 00592 moveUp = cuddZddUndoMoves(table,moveDown); 00593 #ifdef DD_DEBUG 00594 assert(moveUp == NULL || moveUp->x == x); 00595 #endif 00596 moveUp = cuddZddLinearUp(table, x, xLow, moveUp); 00597 if (moveUp == (Move *) CUDD_OUT_OF_MEM) 00598 goto cuddZddLinearAuxOutOfMem; 00599 /* Move backward and stop at best position. */ 00600 result = cuddZddLinearBackward(table, initial_size, moveUp); 00601 if (!result) 00602 goto cuddZddLinearAuxOutOfMem; 00603 00604 } else { 00605 moveUp = cuddZddLinearUp(table, x, xLow, NULL); 00606 /* At this point x --> xHigh. */ 00607 if (moveUp == (Move *) CUDD_OUT_OF_MEM) 00608 goto cuddZddLinearAuxOutOfMem; 00609 /* Then move up. */ 00610 moveDown = cuddZddUndoMoves(table,moveUp); 00611 #ifdef DD_DEBUG 00612 assert(moveDown == NULL || moveDown->y == x); 00613 #endif 00614 moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); 00615 if (moveDown == (Move *) CUDD_OUT_OF_MEM) 00616 goto cuddZddLinearAuxOutOfMem; 00617 /* Move backward and stop at best position. */ 00618 result = cuddZddLinearBackward(table, initial_size, moveDown); 00619 if (!result) 00620 goto cuddZddLinearAuxOutOfMem; 00621 } 00622 00623 while (moveDown != NULL) { 00624 move = moveDown->next; 00625 cuddDeallocNode(table, (DdNode *)moveDown); 00626 moveDown = move; 00627 } 00628 while (moveUp != NULL) { 00629 move = moveUp->next; 00630 cuddDeallocNode(table, (DdNode *)moveUp); 00631 moveUp = move; 00632 } 00633 00634 return(1); 00635 00636 cuddZddLinearAuxOutOfMem: 00637 if (moveDown != (Move *) CUDD_OUT_OF_MEM) { 00638 while (moveDown != NULL) { 00639 move = moveDown->next; 00640 cuddDeallocNode(table, (DdNode *)moveDown); 00641 moveDown = move; 00642 } 00643 } 00644 if (moveUp != (Move *) CUDD_OUT_OF_MEM) { 00645 while (moveUp != NULL) { 00646 move = moveUp->next; 00647 cuddDeallocNode(table, (DdNode *)moveUp); 00648 moveUp = move; 00649 } 00650 } 00651 00652 return(0); 00653 00654 } /* end of cuddZddLinearAux */
Function********************************************************************
Synopsis [Given a set of moves, returns the ZDD heap to the position giving the minimum size.]
Description [Given a set of moves, returns the ZDD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 841 of file cuddZddLin.c.
00845 { 00846 Move *move; 00847 int res; 00848 00849 /* Find the minimum size among moves. */ 00850 for (move = moves; move != NULL; move = move->next) { 00851 if (move->size < size) { 00852 size = move->size; 00853 } 00854 } 00855 00856 for (move = moves; move != NULL; move = move->next) { 00857 if (move->size == size) return(1); 00858 if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { 00859 res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); 00860 if (!res) return(0); 00861 } 00862 res = cuddZddSwapInPlace(table, move->x, move->y); 00863 if (!res) 00864 return(0); 00865 if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { 00866 res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); 00867 if (!res) return(0); 00868 } 00869 } 00870 00871 return(1); 00872 00873 } /* end of cuddZddLinearBackward */
Function********************************************************************
Synopsis [Sifts a variable down and applies the XOR transformation.]
Description [Sifts a variable down. Moves x down until either it reaches the bound (xHigh) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]
SideEffects [None]
SeeAlso []
Definition at line 757 of file cuddZddLin.c.
00762 { 00763 Move *moves; 00764 Move *move; 00765 int y; 00766 int size, newsize; 00767 int limitSize; 00768 00769 moves = prevMoves; 00770 limitSize = table->keysZ; 00771 00772 y = cuddZddNextHigh(table, x); 00773 while (y <= xHigh) { 00774 size = cuddZddSwapInPlace(table, x, y); 00775 if (size == 0) 00776 goto cuddZddLinearDownOutOfMem; 00777 newsize = cuddZddLinearInPlace(table, x, y); 00778 if (newsize == 0) 00779 goto cuddZddLinearDownOutOfMem; 00780 move = (Move *) cuddDynamicAllocNode(table); 00781 if (move == NULL) 00782 goto cuddZddLinearDownOutOfMem; 00783 move->x = x; 00784 move->y = y; 00785 move->next = moves; 00786 moves = move; 00787 move->flags = CUDD_SWAP_MOVE; 00788 if (newsize > size) { 00789 /* Undo transformation. The transformation we apply is 00790 ** its own inverse. Hence, we just apply the transformation 00791 ** again. 00792 */ 00793 newsize = cuddZddLinearInPlace(table,x,y); 00794 if (newsize == 0) goto cuddZddLinearDownOutOfMem; 00795 if (newsize != size) { 00796 (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); 00797 } 00798 } else { 00799 size = newsize; 00800 move->flags = CUDD_LINEAR_TRANSFORM_MOVE; 00801 } 00802 move->size = size; 00803 00804 if ((double)size > (double)limitSize * table->maxGrowth) 00805 break; 00806 if (size < limitSize) 00807 limitSize = size; 00808 00809 x = y; 00810 y = cuddZddNextHigh(table, x); 00811 } 00812 return(moves); 00813 00814 cuddZddLinearDownOutOfMem: 00815 while (moves != NULL) { 00816 move = moves->next; 00817 cuddDeallocNode(table, (DdNode *)moves); 00818 moves = move; 00819 } 00820 return((Move *) CUDD_OUT_OF_MEM); 00821 00822 } /* end of cuddZddLinearDown */
int cuddZddLinearInPlace | ( | DdManager * | table, | |
int | x, | |||
int | y | |||
) |
Function********************************************************************
Synopsis [Linearly combines two adjacent variables.]
Description [Linearly combines two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddZddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [cuddZddSwapInPlace cuddLinearInPlace]
Definition at line 223 of file cuddZddLin.c.
00227 { 00228 DdNodePtr *xlist, *ylist; 00229 int xindex, yindex; 00230 int xslots, yslots; 00231 int xshift, yshift; 00232 int oldxkeys, oldykeys; 00233 int newxkeys, newykeys; 00234 int i; 00235 int posn; 00236 DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; 00237 DdNode *newf1, *newf0, *g, *next, *previous; 00238 DdNode *special; 00239 00240 #ifdef DD_DEBUG 00241 assert(x < y); 00242 assert(cuddZddNextHigh(table,x) == y); 00243 assert(table->subtableZ[x].keys != 0); 00244 assert(table->subtableZ[y].keys != 0); 00245 assert(table->subtableZ[x].dead == 0); 00246 assert(table->subtableZ[y].dead == 0); 00247 #endif 00248 00249 zddTotalNumberLinearTr++; 00250 00251 /* Get parameters of x subtable. */ 00252 xindex = table->invpermZ[x]; 00253 xlist = table->subtableZ[x].nodelist; 00254 oldxkeys = table->subtableZ[x].keys; 00255 xslots = table->subtableZ[x].slots; 00256 xshift = table->subtableZ[x].shift; 00257 newxkeys = 0; 00258 00259 /* Get parameters of y subtable. */ 00260 yindex = table->invpermZ[y]; 00261 ylist = table->subtableZ[y].nodelist; 00262 oldykeys = table->subtableZ[y].keys; 00263 yslots = table->subtableZ[y].slots; 00264 yshift = table->subtableZ[y].shift; 00265 newykeys = oldykeys; 00266 00267 /* The nodes in the x layer are put in two chains. The chain 00268 ** pointed by g holds the normal nodes. When re-expressed they stay 00269 ** in the x list. The chain pointed by special holds the elements 00270 ** that will move to the y list. 00271 */ 00272 g = special = NULL; 00273 for (i = 0; i < xslots; i++) { 00274 f = xlist[i]; 00275 if (f == NULL) continue; 00276 xlist[i] = NULL; 00277 while (f != NULL) { 00278 next = f->next; 00279 f1 = cuddT(f); 00280 /* if (f1->index == yindex) */ cuddSatDec(f1->ref); 00281 f0 = cuddE(f); 00282 /* if (f0->index == yindex) */ cuddSatDec(f0->ref); 00283 if ((int) f1->index == yindex && cuddE(f1) == empty && 00284 (int) f0->index != yindex) { 00285 f->next = special; 00286 special = f; 00287 } else { 00288 f->next = g; 00289 g = f; 00290 } 00291 f = next; 00292 } /* while there are elements in the collision chain */ 00293 } /* for each slot of the x subtable */ 00294 00295 /* Mark y nodes with pointers from above x. We mark them by 00296 ** changing their index to x. 00297 */ 00298 for (i = 0; i < yslots; i++) { 00299 f = ylist[i]; 00300 while (f != NULL) { 00301 if (f->ref != 0) { 00302 f->index = xindex; 00303 } 00304 f = f->next; 00305 } /* while there are elements in the collision chain */ 00306 } /* for each slot of the y subtable */ 00307 00308 /* Move special nodes to the y list. */ 00309 f = special; 00310 while (f != NULL) { 00311 next = f->next; 00312 f1 = cuddT(f); 00313 f11 = cuddT(f1); 00314 cuddT(f) = f11; 00315 cuddSatInc(f11->ref); 00316 f0 = cuddE(f); 00317 cuddSatInc(f0->ref); 00318 f->index = yindex; 00319 /* Insert at the beginning of the list so that it will be 00320 ** found first if there is a duplicate. The duplicate will 00321 ** eventually be moved or garbage collected. No node 00322 ** re-expression will add a pointer to it. 00323 */ 00324 posn = ddHash(f11, f0, yshift); 00325 f->next = ylist[posn]; 00326 ylist[posn] = f; 00327 newykeys++; 00328 f = next; 00329 } 00330 00331 /* Take care of the remaining x nodes that must be re-expressed. 00332 ** They form a linked list pointed by g. 00333 */ 00334 f = g; 00335 while (f != NULL) { 00336 #ifdef DD_COUNT 00337 table->swapSteps++; 00338 #endif 00339 next = f->next; 00340 /* Find f1, f0, f11, f10, f01, f00. */ 00341 f1 = cuddT(f); 00342 if ((int) f1->index == yindex || (int) f1->index == xindex) { 00343 f11 = cuddT(f1); f10 = cuddE(f1); 00344 } else { 00345 f11 = empty; f10 = f1; 00346 } 00347 f0 = cuddE(f); 00348 if ((int) f0->index == yindex || (int) f0->index == xindex) { 00349 f01 = cuddT(f0); f00 = cuddE(f0); 00350 } else { 00351 f01 = empty; f00 = f0; 00352 } 00353 /* Create the new T child. */ 00354 if (f01 == empty) { 00355 newf1 = f10; 00356 cuddSatInc(newf1->ref); 00357 } else { 00358 /* Check ylist for triple (yindex, f01, f10). */ 00359 posn = ddHash(f01, f10, yshift); 00360 /* For each element newf1 in collision list ylist[posn]. */ 00361 newf1 = ylist[posn]; 00362 /* Search the collision chain skipping the marked nodes. */ 00363 while (newf1 != NULL) { 00364 if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && 00365 (int) newf1->index == yindex) { 00366 cuddSatInc(newf1->ref); 00367 break; /* match */ 00368 } 00369 newf1 = newf1->next; 00370 } /* while newf1 */ 00371 if (newf1 == NULL) { /* no match */ 00372 newf1 = cuddDynamicAllocNode(table); 00373 if (newf1 == NULL) 00374 goto zddSwapOutOfMem; 00375 newf1->index = yindex; newf1->ref = 1; 00376 cuddT(newf1) = f01; 00377 cuddE(newf1) = f10; 00378 /* Insert newf1 in the collision list ylist[pos]; 00379 ** increase the ref counts of f01 and f10 00380 */ 00381 newykeys++; 00382 newf1->next = ylist[posn]; 00383 ylist[posn] = newf1; 00384 cuddSatInc(f01->ref); 00385 cuddSatInc(f10->ref); 00386 } 00387 } 00388 cuddT(f) = newf1; 00389 00390 /* Do the same for f0. */ 00391 /* Create the new E child. */ 00392 if (f11 == empty) { 00393 newf0 = f00; 00394 cuddSatInc(newf0->ref); 00395 } else { 00396 /* Check ylist for triple (yindex, f11, f00). */ 00397 posn = ddHash(f11, f00, yshift); 00398 /* For each element newf0 in collision list ylist[posn]. */ 00399 newf0 = ylist[posn]; 00400 while (newf0 != NULL) { 00401 if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && 00402 (int) newf0->index == yindex) { 00403 cuddSatInc(newf0->ref); 00404 break; /* match */ 00405 } 00406 newf0 = newf0->next; 00407 } /* while newf0 */ 00408 if (newf0 == NULL) { /* no match */ 00409 newf0 = cuddDynamicAllocNode(table); 00410 if (newf0 == NULL) 00411 goto zddSwapOutOfMem; 00412 newf0->index = yindex; newf0->ref = 1; 00413 cuddT(newf0) = f11; cuddE(newf0) = f00; 00414 /* Insert newf0 in the collision list ylist[posn]; 00415 ** increase the ref counts of f11 and f00. 00416 */ 00417 newykeys++; 00418 newf0->next = ylist[posn]; 00419 ylist[posn] = newf0; 00420 cuddSatInc(f11->ref); 00421 cuddSatInc(f00->ref); 00422 } 00423 } 00424 cuddE(f) = newf0; 00425 00426 /* Re-insert the modified f in xlist. 00427 ** The modified f does not already exists in xlist. 00428 ** (Because of the uniqueness of the cofactors.) 00429 */ 00430 posn = ddHash(newf1, newf0, xshift); 00431 newxkeys++; 00432 f->next = xlist[posn]; 00433 xlist[posn] = f; 00434 f = next; 00435 } /* while f != NULL */ 00436 00437 /* GC the y layer and move the marked nodes to the x list. */ 00438 00439 /* For each node f in ylist. */ 00440 for (i = 0; i < yslots; i++) { 00441 previous = NULL; 00442 f = ylist[i]; 00443 while (f != NULL) { 00444 next = f->next; 00445 if (f->ref == 0) { 00446 cuddSatDec(cuddT(f)->ref); 00447 cuddSatDec(cuddE(f)->ref); 00448 cuddDeallocNode(table, f); 00449 newykeys--; 00450 if (previous == NULL) 00451 ylist[i] = next; 00452 else 00453 previous->next = next; 00454 } else if ((int) f->index == xindex) { /* move marked node */ 00455 if (previous == NULL) 00456 ylist[i] = next; 00457 else 00458 previous->next = next; 00459 f1 = cuddT(f); 00460 cuddSatDec(f1->ref); 00461 /* Check ylist for triple (yindex, f1, empty). */ 00462 posn = ddHash(f1, empty, yshift); 00463 /* For each element newf1 in collision list ylist[posn]. */ 00464 newf1 = ylist[posn]; 00465 while (newf1 != NULL) { 00466 if (cuddT(newf1) == f1 && cuddE(newf1) == empty && 00467 (int) newf1->index == yindex) { 00468 cuddSatInc(newf1->ref); 00469 break; /* match */ 00470 } 00471 newf1 = newf1->next; 00472 } /* while newf1 */ 00473 if (newf1 == NULL) { /* no match */ 00474 newf1 = cuddDynamicAllocNode(table); 00475 if (newf1 == NULL) 00476 goto zddSwapOutOfMem; 00477 newf1->index = yindex; newf1->ref = 1; 00478 cuddT(newf1) = f1; cuddE(newf1) = empty; 00479 /* Insert newf1 in the collision list ylist[posn]; 00480 ** increase the ref counts of f1 and empty. 00481 */ 00482 newykeys++; 00483 newf1->next = ylist[posn]; 00484 ylist[posn] = newf1; 00485 if (posn == i && previous == NULL) 00486 previous = newf1; 00487 cuddSatInc(f1->ref); 00488 cuddSatInc(empty->ref); 00489 } 00490 cuddT(f) = newf1; 00491 f0 = cuddE(f); 00492 /* Insert f in x list. */ 00493 posn = ddHash(newf1, f0, xshift); 00494 newxkeys++; 00495 newykeys--; 00496 f->next = xlist[posn]; 00497 xlist[posn] = f; 00498 } else { 00499 previous = f; 00500 } 00501 f = next; 00502 } /* while f */ 00503 } /* for i */ 00504 00505 /* Set the appropriate fields in table. */ 00506 table->subtableZ[x].keys = newxkeys; 00507 table->subtableZ[y].keys = newykeys; 00508 00509 table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; 00510 00511 /* Update univ section; univ[x] remains the same. */ 00512 table->univ[y] = cuddT(table->univ[x]); 00513 00514 #if 0 00515 (void) fprintf(table->out,"x = %d y = %d\n", x, y); 00516 (void) Cudd_DebugCheck(table); 00517 (void) Cudd_CheckKeys(table); 00518 #endif 00519 00520 return (table->keysZ); 00521 00522 zddSwapOutOfMem: 00523 (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); 00524 00525 return (0); 00526 00527 } /* end of cuddZddLinearInPlace */
int cuddZddLinearSifting | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Implementation of the linear sifting algorithm for ZDDs.]
Description [Implementation of the linear sifting algorithm for ZDDs. Assumes that no dead nodes are present.
Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 124 of file cuddZddLin.c.
00128 { 00129 int i; 00130 int *var; 00131 int size; 00132 int x; 00133 int result; 00134 #ifdef DD_STATS 00135 int previousSize; 00136 #endif 00137 00138 size = table->sizeZ; 00139 empty = table->zero; 00140 00141 /* Find order in which to sift variables. */ 00142 var = NULL; 00143 zdd_entry = ALLOC(int, size); 00144 if (zdd_entry == NULL) { 00145 table->errorCode = CUDD_MEMORY_OUT; 00146 goto cuddZddSiftingOutOfMem; 00147 } 00148 var = ALLOC(int, size); 00149 if (var == NULL) { 00150 table->errorCode = CUDD_MEMORY_OUT; 00151 goto cuddZddSiftingOutOfMem; 00152 } 00153 00154 for (i = 0; i < size; i++) { 00155 x = table->permZ[i]; 00156 zdd_entry[i] = table->subtableZ[x].keys; 00157 var[i] = i; 00158 } 00159 00160 qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); 00161 00162 /* Now sift. */ 00163 for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { 00164 if (zddTotalNumberSwapping >= table->siftMaxSwap) 00165 break; 00166 x = table->permZ[var[i]]; 00167 if (x < lower || x > upper) continue; 00168 #ifdef DD_STATS 00169 previousSize = table->keysZ; 00170 #endif 00171 result = cuddZddLinearAux(table, x, lower, upper); 00172 if (!result) 00173 goto cuddZddSiftingOutOfMem; 00174 #ifdef DD_STATS 00175 if (table->keysZ < (unsigned) previousSize) { 00176 (void) fprintf(table->out,"-"); 00177 } else if (table->keysZ > (unsigned) previousSize) { 00178 (void) fprintf(table->out,"+"); /* should never happen */ 00179 (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); 00180 } else { 00181 (void) fprintf(table->out,"="); 00182 } 00183 fflush(table->out); 00184 #endif 00185 } 00186 00187 FREE(var); 00188 FREE(zdd_entry); 00189 00190 return(1); 00191 00192 cuddZddSiftingOutOfMem: 00193 00194 if (zdd_entry != NULL) FREE(zdd_entry); 00195 if (var != NULL) FREE(var); 00196 00197 return(0); 00198 00199 } /* end of cuddZddLinearSifting */
Function********************************************************************
Synopsis [Sifts a variable up applying the XOR transformation.]
Description [Sifts a variable up applying the XOR transformation. Moves y up until either it reaches the bound (xLow) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]
SideEffects [None]
SeeAlso []
Definition at line 672 of file cuddZddLin.c.
00677 { 00678 Move *moves; 00679 Move *move; 00680 int x; 00681 int size, newsize; 00682 int limitSize; 00683 00684 moves = prevMoves; 00685 limitSize = table->keysZ; 00686 00687 x = cuddZddNextLow(table, y); 00688 while (x >= xLow) { 00689 size = cuddZddSwapInPlace(table, x, y); 00690 if (size == 0) 00691 goto cuddZddLinearUpOutOfMem; 00692 newsize = cuddZddLinearInPlace(table, x, y); 00693 if (newsize == 0) 00694 goto cuddZddLinearUpOutOfMem; 00695 move = (Move *) cuddDynamicAllocNode(table); 00696 if (move == NULL) 00697 goto cuddZddLinearUpOutOfMem; 00698 move->x = x; 00699 move->y = y; 00700 move->next = moves; 00701 moves = move; 00702 move->flags = CUDD_SWAP_MOVE; 00703 if (newsize > size) { 00704 /* Undo transformation. The transformation we apply is 00705 ** its own inverse. Hence, we just apply the transformation 00706 ** again. 00707 */ 00708 newsize = cuddZddLinearInPlace(table,x,y); 00709 if (newsize == 0) goto cuddZddLinearUpOutOfMem; 00710 #ifdef DD_DEBUG 00711 if (newsize != size) { 00712 (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); 00713 } 00714 #endif 00715 } else { 00716 size = newsize; 00717 move->flags = CUDD_LINEAR_TRANSFORM_MOVE; 00718 } 00719 move->size = size; 00720 00721 if ((double)size > (double)limitSize * table->maxGrowth) 00722 break; 00723 if (size < limitSize) 00724 limitSize = size; 00725 00726 y = x; 00727 x = cuddZddNextLow(table, y); 00728 } 00729 return(moves); 00730 00731 cuddZddLinearUpOutOfMem: 00732 while (moves != NULL) { 00733 move = moves->next; 00734 cuddDeallocNode(table, (DdNode *)moves); 00735 moves = move; 00736 } 00737 return((Move *) CUDD_OUT_OF_MEM); 00738 00739 } /* end of cuddZddLinearUp */
Function********************************************************************
Synopsis [Given a set of moves, returns the ZDD heap to the order in effect before the moves.]
Description [Given a set of moves, returns the ZDD heap to the order in effect before the moves. Returns 1 in case of success; 0 otherwise.]
SideEffects [None]
Definition at line 889 of file cuddZddLin.c.
00892 { 00893 Move *invmoves = NULL; 00894 Move *move; 00895 Move *invmove; 00896 int size; 00897 00898 for (move = moves; move != NULL; move = move->next) { 00899 invmove = (Move *) cuddDynamicAllocNode(table); 00900 if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; 00901 invmove->x = move->x; 00902 invmove->y = move->y; 00903 invmove->next = invmoves; 00904 invmoves = invmove; 00905 if (move->flags == CUDD_SWAP_MOVE) { 00906 invmove->flags = CUDD_SWAP_MOVE; 00907 size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); 00908 if (!size) goto cuddZddUndoMovesOutOfMem; 00909 } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { 00910 invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; 00911 size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); 00912 if (!size) goto cuddZddUndoMovesOutOfMem; 00913 size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); 00914 if (!size) goto cuddZddUndoMovesOutOfMem; 00915 } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ 00916 #ifdef DD_DEBUG 00917 (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); 00918 #endif 00919 invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; 00920 size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); 00921 if (!size) goto cuddZddUndoMovesOutOfMem; 00922 size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); 00923 if (!size) goto cuddZddUndoMovesOutOfMem; 00924 } 00925 invmove->size = size; 00926 } 00927 00928 return(invmoves); 00929 00930 cuddZddUndoMovesOutOfMem: 00931 while (invmoves != NULL) { 00932 move = invmoves->next; 00933 cuddDeallocNode(table, (DdNode *) invmoves); 00934 invmoves = move; 00935 } 00936 return((Move *) CUDD_OUT_OF_MEM); 00937 00938 } /* end of cuddZddUndoMoves */
char rcsid [] DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $" [static] |
Definition at line 61 of file cuddZddLin.c.
Definition at line 67 of file cuddZddLin.c.
int* zdd_entry |
Definition at line 77 of file cuddZddReord.c.
int zddTotalNumberLinearTr [static] |
Definition at line 66 of file cuddZddLin.c.
Definition at line 79 of file cuddZddReord.c.