#include "util_hack.h"
#include "cuddInt.h"
Go to the source code of this file.
Defines | |
#define | ZDD_MV_OOM (Move *)1 |
Functions | |
static int cuddZddSymmSiftingAux | ARGS ((DdManager *table, int x, int x_low, int x_high)) |
static Move *cuddZddSymmSifting_up | ARGS ((DdManager *table, int x, int x_low, int initial_size)) |
static Move *cuddZddSymmSifting_down | ARGS ((DdManager *table, int x, int x_high, int initial_size)) |
static int cuddZddSymmSiftingBackward | ARGS ((DdManager *table, Move *moves, int size)) |
static int zdd_group_move | ARGS ((DdManager *table, int x, int y, Move **moves)) |
static int zdd_group_move_backward | ARGS ((DdManager *table, int x, int y)) |
static void cuddZddSymmSummary | ARGS ((DdManager *table, int lower, int upper, int *symvars, int *symgroups)) |
void | Cudd_zddSymmProfile (DdManager *table, int lower, int upper) |
int | cuddZddSymmCheck (DdManager *table, int x, int y) |
int | cuddZddSymmSifting (DdManager *table, int lower, int upper) |
int | cuddZddSymmSiftingConv (DdManager *table, int lower, int upper) |
static int | cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high) |
static int | cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high) |
static Move * | cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size) |
static Move * | cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size) |
static int | cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size) |
static int | zdd_group_move (DdManager *table, int x, int y, Move **moves) |
static int | zdd_group_move_backward (DdManager *table, int x, int y) |
static void | cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddZddSymm.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $" |
int * | zdd_entry |
int | zddTotalNumberSwapping |
static DdNode * | empty |
#define ZDD_MV_OOM (Move *)1 |
CFile***********************************************************************
FileName [cuddZddSymm.c]
PackageName [cudd]
Synopsis [Functions for symmetry-based ZDD variable reordering.]
Description [External procedures included in this module:
Internal procedures included in this module:
Static procedures included in this module:
]
SeeAlso [cuddSymmetry.c]
Author [Hyong-Kyoon Shin, In-Ho Moon]
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 50 of file cuddZddSymm.c.
static void cuddZddSymmSummary ARGS | ( | (DdManager *table, int lower, int upper, int *symvars, int *symgroups) | ) | [static] |
static int zdd_group_move_backward ARGS | ( | (DdManager *table, int x, int y) | ) | [static] |
static Move* cuddZddSymmSifting_down ARGS | ( | (DdManager *table, int x, int x_high, int initial_size) | ) | [static] |
static Move* cuddZddSymmSifting_up ARGS | ( | (DdManager *table, int x, int x_low, int initial_size) | ) | [static] |
static int cuddZddSymmSiftingConvAux ARGS | ( | (DdManager *table, int x, int x_low, int x_high) | ) | [static] |
AutomaticStart
void Cudd_zddSymmProfile | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Prints statistics on symmetric ZDD variables.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 114 of file cuddZddSymm.c.
00118 { 00119 int i, x, gbot; 00120 int TotalSymm = 0; 00121 int TotalSymmGroups = 0; 00122 int nvars; 00123 00124 nvars = table->sizeZ; 00125 00126 for (i = lower; i < upper; i++) { 00127 if (table->subtableZ[i].next != (unsigned) i) { 00128 x = i; 00129 (void) fprintf(table->out,"Group:"); 00130 do { 00131 (void) fprintf(table->out," %d", table->invpermZ[x]); 00132 TotalSymm++; 00133 gbot = x; 00134 x = table->subtableZ[x].next; 00135 } while (x != i); 00136 TotalSymmGroups++; 00137 #ifdef DD_DEBUG 00138 assert(table->subtableZ[gbot].next == (unsigned) i); 00139 #endif 00140 i = gbot; 00141 (void) fprintf(table->out,"\n"); 00142 } 00143 } 00144 (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); 00145 (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); 00146 00147 } /* end of Cudd_zddSymmProfile */
int cuddZddSymmCheck | ( | DdManager * | table, | |
int | x, | |||
int | y | |||
) |
Function********************************************************************
Synopsis [Checks for symmetry of x and y.]
Description [Checks for symmetry of x and y. Ignores projection functions, unless they are isolated. Returns 1 in case of symmetry; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 169 of file cuddZddSymm.c.
00173 { 00174 int i; 00175 DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; 00176 int yindex; 00177 int xsymmy = 1; 00178 int xsymmyp = 1; 00179 int arccount = 0; 00180 int TotalRefCount = 0; 00181 int symm_found; 00182 00183 empty = table->zero; 00184 00185 yindex = table->invpermZ[y]; 00186 for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { 00187 f = table->subtableZ[x].nodelist[i]; 00188 while (f != NULL) { 00189 /* Find f1, f0, f11, f10, f01, f00 */ 00190 f1 = cuddT(f); 00191 f0 = cuddE(f); 00192 if ((int) f1->index == yindex) { 00193 f11 = cuddT(f1); 00194 f10 = cuddE(f1); 00195 if (f10 != empty) 00196 arccount++; 00197 } else { 00198 if ((int) f0->index != yindex) { 00199 return(0); /* f bypasses layer y */ 00200 } 00201 f11 = empty; 00202 f10 = f1; 00203 } 00204 if ((int) f0->index == yindex) { 00205 f01 = cuddT(f0); 00206 f00 = cuddE(f0); 00207 if (f00 != empty) 00208 arccount++; 00209 } else { 00210 f01 = empty; 00211 f00 = f0; 00212 } 00213 if (f01 != f10) 00214 xsymmy = 0; 00215 if (f11 != f00) 00216 xsymmyp = 0; 00217 if ((xsymmy == 0) && (xsymmyp == 0)) 00218 return(0); 00219 00220 f = f->next; 00221 } /* for each element of the collision list */ 00222 } /* for each slot of the subtable */ 00223 00224 /* Calculate the total reference counts of y 00225 ** whose else arc is not empty. 00226 */ 00227 for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { 00228 f = table->subtableZ[y].nodelist[i]; 00229 while (f != NIL(DdNode)) { 00230 if (cuddE(f) != empty) 00231 TotalRefCount += f->ref; 00232 f = f->next; 00233 } 00234 } 00235 00236 symm_found = (arccount == TotalRefCount); 00237 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 00238 if (symm_found) { 00239 int xindex = table->invpermZ[x]; 00240 (void) fprintf(table->out, 00241 "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", 00242 xindex,yindex,x,y); 00243 } 00244 #endif 00245 00246 return(symm_found); 00247 00248 } /* end cuddZddSymmCheck */
int cuddZddSymmSifting | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
Function********************************************************************
Synopsis [Symmetric sifting algorithm for ZDDs.]
Description [Symmetric sifting algorithm. Assumes that no dead nodes are present.
Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [cuddZddSymmSiftingConv]
Definition at line 274 of file cuddZddSymm.c.
00278 { 00279 int i; 00280 int *var; 00281 int nvars; 00282 int x; 00283 int result; 00284 int symvars; 00285 int symgroups; 00286 int iteration; 00287 #ifdef DD_STATS 00288 int previousSize; 00289 #endif 00290 00291 nvars = table->sizeZ; 00292 00293 /* Find order in which to sift variables. */ 00294 var = NULL; 00295 zdd_entry = ALLOC(int, nvars); 00296 if (zdd_entry == NULL) { 00297 table->errorCode = CUDD_MEMORY_OUT; 00298 goto cuddZddSymmSiftingOutOfMem; 00299 } 00300 var = ALLOC(int, nvars); 00301 if (var == NULL) { 00302 table->errorCode = CUDD_MEMORY_OUT; 00303 goto cuddZddSymmSiftingOutOfMem; 00304 } 00305 00306 for (i = 0; i < nvars; i++) { 00307 x = table->permZ[i]; 00308 zdd_entry[i] = table->subtableZ[x].keys; 00309 var[i] = i; 00310 } 00311 00312 qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); 00313 00314 /* Initialize the symmetry of each subtable to itself. */ 00315 for (i = lower; i <= upper; i++) 00316 table->subtableZ[i].next = i; 00317 00318 iteration = ddMin(table->siftMaxVar, nvars); 00319 for (i = 0; i < iteration; i++) { 00320 if (zddTotalNumberSwapping >= table->siftMaxSwap) 00321 break; 00322 x = table->permZ[var[i]]; 00323 #ifdef DD_STATS 00324 previousSize = table->keysZ; 00325 #endif 00326 if (x < lower || x > upper) continue; 00327 if (table->subtableZ[x].next == (unsigned) x) { 00328 result = cuddZddSymmSiftingAux(table, x, lower, upper); 00329 if (!result) 00330 goto cuddZddSymmSiftingOutOfMem; 00331 #ifdef DD_STATS 00332 if (table->keysZ < (unsigned) previousSize) { 00333 (void) fprintf(table->out,"-"); 00334 } else if (table->keysZ > (unsigned) previousSize) { 00335 (void) fprintf(table->out,"+"); 00336 #ifdef DD_VERBOSE 00337 (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); 00338 #endif 00339 } else { 00340 (void) fprintf(table->out,"="); 00341 } 00342 fflush(table->out); 00343 #endif 00344 } 00345 } 00346 00347 FREE(var); 00348 FREE(zdd_entry); 00349 00350 cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); 00351 00352 #ifdef DD_STATS 00353 (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars); 00354 (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups); 00355 #endif 00356 00357 return(1+symvars); 00358 00359 cuddZddSymmSiftingOutOfMem: 00360 00361 if (zdd_entry != NULL) 00362 FREE(zdd_entry); 00363 if (var != NULL) 00364 FREE(var); 00365 00366 return(0); 00367 00368 } /* end of cuddZddSymmSifting */
static Move* cuddZddSymmSifting_down | ( | DdManager * | table, | |
int | x, | |||
int | x_high, | |||
int | initial_size | |||
) | [static] |
Function********************************************************************
Synopsis [Moves x down until either it reaches the bound (x_high) or the size of the ZDD heap increases too much.]
Description [Moves x down until either it reaches the bound (x_high) or the size of the ZDD heap increases too much. Assumes that x is the bottom of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; ZDD_MV_OOM if memory is full.]
SideEffects [None]
SeeAlso []
Definition at line 1310 of file cuddZddSymm.c.
01315 { 01316 Move *moves; 01317 Move *move; 01318 int y; 01319 int size; 01320 int limit_size = initial_size; 01321 int i, gxtop, gybot; 01322 01323 moves = NULL; 01324 y = cuddZddNextHigh(table, x); 01325 while (y <= x_high) { 01326 gybot = table->subtableZ[y].next; 01327 while (table->subtableZ[gybot].next != (unsigned) y) 01328 gybot = table->subtableZ[gybot].next; 01329 if (cuddZddSymmCheck(table, x, y)) { 01330 /* Symmetry found, attach symm groups */ 01331 gxtop = table->subtableZ[x].next; 01332 table->subtableZ[x].next = y; 01333 i = table->subtableZ[y].next; 01334 while (table->subtableZ[i].next != (unsigned) y) 01335 i = table->subtableZ[i].next; 01336 table->subtableZ[i].next = gxtop; 01337 } 01338 else if ((table->subtableZ[x].next == (unsigned) x) && 01339 (table->subtableZ[y].next == (unsigned) y)) { 01340 /* x and y have self symmetry */ 01341 size = cuddZddSwapInPlace(table, x, y); 01342 if (size == 0) 01343 goto cuddZddSymmSifting_downOutOfMem; 01344 move = (Move *)cuddDynamicAllocNode(table); 01345 if (move == NULL) 01346 goto cuddZddSymmSifting_downOutOfMem; 01347 move->x = x; 01348 move->y = y; 01349 move->size = size; 01350 move->next = moves; 01351 moves = move; 01352 if ((double)size > 01353 (double)limit_size * table->maxGrowth) 01354 return(moves); 01355 if (size < limit_size) 01356 limit_size = size; 01357 x = y; 01358 y = cuddZddNextHigh(table, x); 01359 } 01360 else { /* Group move */ 01361 size = zdd_group_move(table, x, y, &moves); 01362 if ((double)size > 01363 (double)limit_size * table->maxGrowth) 01364 return(moves); 01365 if (size < limit_size) 01366 limit_size = size; 01367 } 01368 x = gybot; 01369 y = cuddZddNextHigh(table, x); 01370 } 01371 01372 return(moves); 01373 01374 cuddZddSymmSifting_downOutOfMem: 01375 while (moves != NULL) { 01376 move = moves->next; 01377 cuddDeallocNode(table, (DdNode *)moves); 01378 moves = move; 01379 } 01380 return(ZDD_MV_OOM); 01381 01382 } /* end of cuddZddSymmSifting_down */
static Move* cuddZddSymmSifting_up | ( | DdManager * | table, | |
int | x, | |||
int | x_low, | |||
int | initial_size | |||
) | [static] |
Function********************************************************************
Synopsis [Moves x up until either it reaches the bound (x_low) or the size of the ZDD heap increases too much.]
Description [Moves x up until either it reaches the bound (x_low) or the size of the ZDD heap increases too much. Assumes that x is the top of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; ZDD_MV_OOM if memory is full.]
SideEffects [None]
SeeAlso []
Definition at line 1222 of file cuddZddSymm.c.
01227 { 01228 Move *moves; 01229 Move *move; 01230 int y; 01231 int size; 01232 int limit_size = initial_size; 01233 int i, gytop; 01234 01235 moves = NULL; 01236 y = cuddZddNextLow(table, x); 01237 while (y >= x_low) { 01238 gytop = table->subtableZ[y].next; 01239 if (cuddZddSymmCheck(table, y, x)) { 01240 /* Symmetry found, attach symm groups */ 01241 table->subtableZ[y].next = x; 01242 i = table->subtableZ[x].next; 01243 while (table->subtableZ[i].next != (unsigned) x) 01244 i = table->subtableZ[i].next; 01245 table->subtableZ[i].next = gytop; 01246 } 01247 else if ((table->subtableZ[x].next == (unsigned) x) && 01248 (table->subtableZ[y].next == (unsigned) y)) { 01249 /* x and y have self symmetry */ 01250 size = cuddZddSwapInPlace(table, y, x); 01251 if (size == 0) 01252 goto cuddZddSymmSifting_upOutOfMem; 01253 move = (Move *)cuddDynamicAllocNode(table); 01254 if (move == NULL) 01255 goto cuddZddSymmSifting_upOutOfMem; 01256 move->x = y; 01257 move->y = x; 01258 move->size = size; 01259 move->next = moves; 01260 moves = move; 01261 if ((double)size > 01262 (double)limit_size * table->maxGrowth) 01263 return(moves); 01264 if (size < limit_size) 01265 limit_size = size; 01266 } 01267 else { /* Group move */ 01268 size = zdd_group_move(table, y, x, &moves); 01269 if ((double)size > 01270 (double)limit_size * table->maxGrowth) 01271 return(moves); 01272 if (size < limit_size) 01273 limit_size = size; 01274 } 01275 x = gytop; 01276 y = cuddZddNextLow(table, x); 01277 } 01278 01279 return(moves); 01280 01281 cuddZddSymmSifting_upOutOfMem: 01282 while (moves != NULL) { 01283 move = moves->next; 01284 cuddDeallocNode(table, (DdNode *)moves); 01285 moves = move; 01286 } 01287 return(ZDD_MV_OOM); 01288 01289 } /* end of cuddZddSymmSifting_up */
static int cuddZddSymmSiftingAux | ( | DdManager * | table, | |
int | x, | |||
int | x_low, | |||
int | x_high | |||
) | [static] |
Function********************************************************************
Synopsis [Given x_low <= x <= x_high moves x up and down between the boundaries.]
Description [Given x_low <= x <= x_high moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is not part of a symmetry group. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 573 of file cuddZddSymm.c.
00578 { 00579 Move *move; 00580 Move *move_up; /* list of up move */ 00581 Move *move_down; /* list of down move */ 00582 int initial_size; 00583 int result; 00584 int i; 00585 int topbot; /* index to either top or bottom of symmetry group */ 00586 int init_group_size, final_group_size; 00587 00588 initial_size = table->keysZ; 00589 00590 move_down = NULL; 00591 move_up = NULL; 00592 00593 /* Look for consecutive symmetries above x. */ 00594 for (i = x; i > x_low; i--) { 00595 if (!cuddZddSymmCheck(table, i - 1, i)) 00596 break; 00597 /* find top of i-1's symmetry */ 00598 topbot = table->subtableZ[i - 1].next; 00599 table->subtableZ[i - 1].next = i; 00600 table->subtableZ[x].next = topbot; 00601 /* x is bottom of group so its symmetry is top of i-1's 00602 group */ 00603 i = topbot + 1; /* add 1 for i--, new i is top of symm group */ 00604 } 00605 /* Look for consecutive symmetries below x. */ 00606 for (i = x; i < x_high; i++) { 00607 if (!cuddZddSymmCheck(table, i, i + 1)) 00608 break; 00609 /* find bottom of i+1's symm group */ 00610 topbot = i + 1; 00611 while ((unsigned) topbot < table->subtableZ[topbot].next) 00612 topbot = table->subtableZ[topbot].next; 00613 00614 table->subtableZ[topbot].next = table->subtableZ[i].next; 00615 table->subtableZ[i].next = i + 1; 00616 i = topbot - 1; /* add 1 for i++, 00617 new i is bottom of symm group */ 00618 } 00619 00620 /* Now x maybe in the middle of a symmetry group. */ 00621 if (x == x_low) { /* Sift down */ 00622 /* Find bottom of x's symm group */ 00623 while ((unsigned) x < table->subtableZ[x].next) 00624 x = table->subtableZ[x].next; 00625 00626 i = table->subtableZ[x].next; 00627 init_group_size = x - i + 1; 00628 00629 move_down = cuddZddSymmSifting_down(table, x, x_high, 00630 initial_size); 00631 /* after that point x --> x_high, unless early term */ 00632 if (move_down == ZDD_MV_OOM) 00633 goto cuddZddSymmSiftingAuxOutOfMem; 00634 00635 if (move_down == NULL || 00636 table->subtableZ[move_down->y].next != move_down->y) { 00637 /* symmetry detected may have to make another complete 00638 pass */ 00639 if (move_down != NULL) 00640 x = move_down->y; 00641 else 00642 x = table->subtableZ[x].next; 00643 i = x; 00644 while ((unsigned) i < table->subtableZ[i].next) { 00645 i = table->subtableZ[i].next; 00646 } 00647 final_group_size = i - x + 1; 00648 00649 if (init_group_size == final_group_size) { 00650 /* No new symmetry groups detected, 00651 return to best position */ 00652 result = cuddZddSymmSiftingBackward(table, 00653 move_down, initial_size); 00654 } 00655 else { 00656 initial_size = table->keysZ; 00657 move_up = cuddZddSymmSifting_up(table, x, x_low, 00658 initial_size); 00659 result = cuddZddSymmSiftingBackward(table, move_up, 00660 initial_size); 00661 } 00662 } 00663 else { 00664 result = cuddZddSymmSiftingBackward(table, move_down, 00665 initial_size); 00666 /* move backward and stop at best position */ 00667 } 00668 if (!result) 00669 goto cuddZddSymmSiftingAuxOutOfMem; 00670 } 00671 else if (x == x_high) { /* Sift up */ 00672 /* Find top of x's symm group */ 00673 while ((unsigned) x < table->subtableZ[x].next) 00674 x = table->subtableZ[x].next; 00675 x = table->subtableZ[x].next; 00676 00677 i = x; 00678 while ((unsigned) i < table->subtableZ[i].next) { 00679 i = table->subtableZ[i].next; 00680 } 00681 init_group_size = i - x + 1; 00682 00683 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 00684 /* after that point x --> x_low, unless early term */ 00685 if (move_up == ZDD_MV_OOM) 00686 goto cuddZddSymmSiftingAuxOutOfMem; 00687 00688 if (move_up == NULL || 00689 table->subtableZ[move_up->x].next != move_up->x) { 00690 /* symmetry detected may have to make another complete 00691 pass */ 00692 if (move_up != NULL) 00693 x = move_up->x; 00694 else { 00695 while ((unsigned) x < table->subtableZ[x].next) 00696 x = table->subtableZ[x].next; 00697 } 00698 i = table->subtableZ[x].next; 00699 final_group_size = x - i + 1; 00700 00701 if (init_group_size == final_group_size) { 00702 /* No new symmetry groups detected, 00703 return to best position */ 00704 result = cuddZddSymmSiftingBackward(table, move_up, 00705 initial_size); 00706 } 00707 else { 00708 initial_size = table->keysZ; 00709 move_down = cuddZddSymmSifting_down(table, x, x_high, 00710 initial_size); 00711 result = cuddZddSymmSiftingBackward(table, move_down, 00712 initial_size); 00713 } 00714 } 00715 else { 00716 result = cuddZddSymmSiftingBackward(table, move_up, 00717 initial_size); 00718 /* move backward and stop at best position */ 00719 } 00720 if (!result) 00721 goto cuddZddSymmSiftingAuxOutOfMem; 00722 } 00723 else if ((x - x_low) > (x_high - x)) { /* must go down first: 00724 shorter */ 00725 /* Find bottom of x's symm group */ 00726 while ((unsigned) x < table->subtableZ[x].next) 00727 x = table->subtableZ[x].next; 00728 00729 move_down = cuddZddSymmSifting_down(table, x, x_high, 00730 initial_size); 00731 /* after that point x --> x_high, unless early term */ 00732 if (move_down == ZDD_MV_OOM) 00733 goto cuddZddSymmSiftingAuxOutOfMem; 00734 00735 if (move_down != NULL) { 00736 x = move_down->y; 00737 } 00738 else { 00739 x = table->subtableZ[x].next; 00740 } 00741 i = x; 00742 while ((unsigned) i < table->subtableZ[i].next) { 00743 i = table->subtableZ[i].next; 00744 } 00745 init_group_size = i - x + 1; 00746 00747 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 00748 if (move_up == ZDD_MV_OOM) 00749 goto cuddZddSymmSiftingAuxOutOfMem; 00750 00751 if (move_up == NULL || 00752 table->subtableZ[move_up->x].next != move_up->x) { 00753 /* symmetry detected may have to make another complete 00754 pass */ 00755 if (move_up != NULL) { 00756 x = move_up->x; 00757 } 00758 else { 00759 while ((unsigned) x < table->subtableZ[x].next) 00760 x = table->subtableZ[x].next; 00761 } 00762 i = table->subtableZ[x].next; 00763 final_group_size = x - i + 1; 00764 00765 if (init_group_size == final_group_size) { 00766 /* No new symmetry groups detected, 00767 return to best position */ 00768 result = cuddZddSymmSiftingBackward(table, move_up, 00769 initial_size); 00770 } 00771 else { 00772 while (move_down != NULL) { 00773 move = move_down->next; 00774 cuddDeallocNode(table, (DdNode *)move_down); 00775 move_down = move; 00776 } 00777 initial_size = table->keysZ; 00778 move_down = cuddZddSymmSifting_down(table, x, x_high, 00779 initial_size); 00780 result = cuddZddSymmSiftingBackward(table, move_down, 00781 initial_size); 00782 } 00783 } 00784 else { 00785 result = cuddZddSymmSiftingBackward(table, move_up, 00786 initial_size); 00787 /* move backward and stop at best position */ 00788 } 00789 if (!result) 00790 goto cuddZddSymmSiftingAuxOutOfMem; 00791 } 00792 else { /* moving up first:shorter */ 00793 /* Find top of x's symmetry group */ 00794 while ((unsigned) x < table->subtableZ[x].next) 00795 x = table->subtableZ[x].next; 00796 x = table->subtableZ[x].next; 00797 00798 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 00799 /* after that point x --> x_high, unless early term */ 00800 if (move_up == ZDD_MV_OOM) 00801 goto cuddZddSymmSiftingAuxOutOfMem; 00802 00803 if (move_up != NULL) { 00804 x = move_up->x; 00805 } 00806 else { 00807 while ((unsigned) x < table->subtableZ[x].next) 00808 x = table->subtableZ[x].next; 00809 } 00810 i = table->subtableZ[x].next; 00811 init_group_size = x - i + 1; 00812 00813 move_down = cuddZddSymmSifting_down(table, x, x_high, 00814 initial_size); 00815 if (move_down == ZDD_MV_OOM) 00816 goto cuddZddSymmSiftingAuxOutOfMem; 00817 00818 if (move_down == NULL || 00819 table->subtableZ[move_down->y].next != move_down->y) { 00820 /* symmetry detected may have to make another complete 00821 pass */ 00822 if (move_down != NULL) { 00823 x = move_down->y; 00824 } 00825 else { 00826 x = table->subtableZ[x].next; 00827 } 00828 i = x; 00829 while ((unsigned) i < table->subtableZ[i].next) { 00830 i = table->subtableZ[i].next; 00831 } 00832 final_group_size = i - x + 1; 00833 00834 if (init_group_size == final_group_size) { 00835 /* No new symmetries detected, 00836 go back to best position */ 00837 result = cuddZddSymmSiftingBackward(table, move_down, 00838 initial_size); 00839 } 00840 else { 00841 while (move_up != NULL) { 00842 move = move_up->next; 00843 cuddDeallocNode(table, (DdNode *)move_up); 00844 move_up = move; 00845 } 00846 initial_size = table->keysZ; 00847 move_up = cuddZddSymmSifting_up(table, x, x_low, 00848 initial_size); 00849 result = cuddZddSymmSiftingBackward(table, move_up, 00850 initial_size); 00851 } 00852 } 00853 else { 00854 result = cuddZddSymmSiftingBackward(table, move_down, 00855 initial_size); 00856 /* move backward and stop at best position */ 00857 } 00858 if (!result) 00859 goto cuddZddSymmSiftingAuxOutOfMem; 00860 } 00861 00862 while (move_down != NULL) { 00863 move = move_down->next; 00864 cuddDeallocNode(table, (DdNode *)move_down); 00865 move_down = move; 00866 } 00867 while (move_up != NULL) { 00868 move = move_up->next; 00869 cuddDeallocNode(table, (DdNode *)move_up); 00870 move_up = move; 00871 } 00872 00873 return(1); 00874 00875 cuddZddSymmSiftingAuxOutOfMem: 00876 if (move_down != ZDD_MV_OOM) { 00877 while (move_down != NULL) { 00878 move = move_down->next; 00879 cuddDeallocNode(table, (DdNode *)move_down); 00880 move_down = move; 00881 } 00882 } 00883 if (move_up != ZDD_MV_OOM) { 00884 while (move_up != NULL) { 00885 move = move_up->next; 00886 cuddDeallocNode(table, (DdNode *)move_up); 00887 move_up = move; 00888 } 00889 } 00890 00891 return(0); 00892 00893 } /* end of cuddZddSymmSiftingAux */
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 1401 of file cuddZddSymm.c.
01405 { 01406 int i; 01407 int i_best; 01408 Move *move; 01409 int res; 01410 01411 i_best = -1; 01412 for (move = moves, i = 0; move != NULL; move = move->next, i++) { 01413 if (move->size < size) { 01414 i_best = i; 01415 size = move->size; 01416 } 01417 } 01418 01419 for (move = moves, i = 0; move != NULL; move = move->next, i++) { 01420 if (i == i_best) break; 01421 if ((table->subtableZ[move->x].next == move->x) && 01422 (table->subtableZ[move->y].next == move->y)) { 01423 res = cuddZddSwapInPlace(table, move->x, move->y); 01424 if (!res) return(0); 01425 } 01426 else { /* Group move necessary */ 01427 res = zdd_group_move_backward(table, move->x, move->y); 01428 } 01429 if (i_best == -1 && res == size) 01430 break; 01431 } 01432 01433 return(1); 01434 01435 } /* end of cuddZddSymmSiftingBackward */
int cuddZddSymmSiftingConv | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
Function********************************************************************
Synopsis [Symmetric sifting to convergence algorithm for ZDDs.]
Description [Symmetric sifting to convergence algorithm for ZDDs. Assumes that no dead nodes are present.
Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [cuddZddSymmSifting]
Definition at line 395 of file cuddZddSymm.c.
00399 { 00400 int i; 00401 int *var; 00402 int nvars; 00403 int initialSize; 00404 int x; 00405 int result; 00406 int symvars; 00407 int symgroups; 00408 int classes; 00409 int iteration; 00410 #ifdef DD_STATS 00411 int previousSize; 00412 #endif 00413 00414 initialSize = table->keysZ; 00415 00416 nvars = table->sizeZ; 00417 00418 /* Find order in which to sift variables. */ 00419 var = NULL; 00420 zdd_entry = ALLOC(int, nvars); 00421 if (zdd_entry == NULL) { 00422 table->errorCode = CUDD_MEMORY_OUT; 00423 goto cuddZddSymmSiftingConvOutOfMem; 00424 } 00425 var = ALLOC(int, nvars); 00426 if (var == NULL) { 00427 table->errorCode = CUDD_MEMORY_OUT; 00428 goto cuddZddSymmSiftingConvOutOfMem; 00429 } 00430 00431 for (i = 0; i < nvars; i++) { 00432 x = table->permZ[i]; 00433 zdd_entry[i] = table->subtableZ[x].keys; 00434 var[i] = i; 00435 } 00436 00437 qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); 00438 00439 /* Initialize the symmetry of each subtable to itself 00440 ** for first pass of converging symmetric sifting. 00441 */ 00442 for (i = lower; i <= upper; i++) 00443 table->subtableZ[i].next = i; 00444 00445 iteration = ddMin(table->siftMaxVar, table->sizeZ); 00446 for (i = 0; i < iteration; i++) { 00447 if (zddTotalNumberSwapping >= table->siftMaxSwap) 00448 break; 00449 x = table->permZ[var[i]]; 00450 if (x < lower || x > upper) continue; 00451 /* Only sift if not in symmetry group already. */ 00452 if (table->subtableZ[x].next == (unsigned) x) { 00453 #ifdef DD_STATS 00454 previousSize = table->keysZ; 00455 #endif 00456 result = cuddZddSymmSiftingAux(table, x, lower, upper); 00457 if (!result) 00458 goto cuddZddSymmSiftingConvOutOfMem; 00459 #ifdef DD_STATS 00460 if (table->keysZ < (unsigned) previousSize) { 00461 (void) fprintf(table->out,"-"); 00462 } else if (table->keysZ > (unsigned) previousSize) { 00463 (void) fprintf(table->out,"+"); 00464 #ifdef DD_VERBOSE 00465 (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); 00466 #endif 00467 } else { 00468 (void) fprintf(table->out,"="); 00469 } 00470 fflush(table->out); 00471 #endif 00472 } 00473 } 00474 00475 /* Sifting now until convergence. */ 00476 while ((unsigned) initialSize > table->keysZ) { 00477 initialSize = table->keysZ; 00478 #ifdef DD_STATS 00479 (void) fprintf(table->out,"\n"); 00480 #endif 00481 /* Here we consider only one representative for each symmetry class. */ 00482 for (x = lower, classes = 0; x <= upper; x++, classes++) { 00483 while ((unsigned) x < table->subtableZ[x].next) 00484 x = table->subtableZ[x].next; 00485 /* Here x is the largest index in a group. 00486 ** Groups consists of adjacent variables. 00487 ** Hence, the next increment of x will move it to a new group. 00488 */ 00489 i = table->invpermZ[x]; 00490 zdd_entry[i] = table->subtableZ[x].keys; 00491 var[classes] = i; 00492 } 00493 00494 qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))cuddZddUniqueCompare); 00495 00496 /* Now sift. */ 00497 iteration = ddMin(table->siftMaxVar, nvars); 00498 for (i = 0; i < iteration; i++) { 00499 if (zddTotalNumberSwapping >= table->siftMaxSwap) 00500 break; 00501 x = table->permZ[var[i]]; 00502 if ((unsigned) x >= table->subtableZ[x].next) { 00503 #ifdef DD_STATS 00504 previousSize = table->keysZ; 00505 #endif 00506 result = cuddZddSymmSiftingConvAux(table, x, lower, upper); 00507 if (!result) 00508 goto cuddZddSymmSiftingConvOutOfMem; 00509 #ifdef DD_STATS 00510 if (table->keysZ < (unsigned) previousSize) { 00511 (void) fprintf(table->out,"-"); 00512 } else if (table->keysZ > (unsigned) previousSize) { 00513 (void) fprintf(table->out,"+"); 00514 #ifdef DD_VERBOSE 00515 (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); 00516 #endif 00517 } else { 00518 (void) fprintf(table->out,"="); 00519 } 00520 fflush(table->out); 00521 #endif 00522 } 00523 } /* for */ 00524 } 00525 00526 cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); 00527 00528 #ifdef DD_STATS 00529 (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", 00530 symvars); 00531 (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", 00532 symgroups); 00533 #endif 00534 00535 FREE(var); 00536 FREE(zdd_entry); 00537 00538 return(1+symvars); 00539 00540 cuddZddSymmSiftingConvOutOfMem: 00541 00542 if (zdd_entry != NULL) 00543 FREE(zdd_entry); 00544 if (var != NULL) 00545 FREE(var); 00546 00547 return(0); 00548 00549 } /* end of cuddZddSymmSiftingConv */
static int cuddZddSymmSiftingConvAux | ( | DdManager * | table, | |
int | x, | |||
int | x_low, | |||
int | x_high | |||
) | [static] |
Function********************************************************************
Synopsis [Given x_low <= x <= x_high moves x up and down between the boundaries.]
Description [Given x_low <= x <= x_high moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is either an isolated variable, or it is the bottom of a symmetry group. All symmetries may not have been found, because of exceeded growth limit. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 913 of file cuddZddSymm.c.
00918 { 00919 Move *move; 00920 Move *move_up; /* list of up move */ 00921 Move *move_down; /* list of down move */ 00922 int initial_size; 00923 int result; 00924 int i; 00925 int init_group_size, final_group_size; 00926 00927 initial_size = table->keysZ; 00928 00929 move_down = NULL; 00930 move_up = NULL; 00931 00932 if (x == x_low) { /* Sift down */ 00933 i = table->subtableZ[x].next; 00934 init_group_size = x - i + 1; 00935 00936 move_down = cuddZddSymmSifting_down(table, x, x_high, 00937 initial_size); 00938 /* after that point x --> x_high, unless early term */ 00939 if (move_down == ZDD_MV_OOM) 00940 goto cuddZddSymmSiftingConvAuxOutOfMem; 00941 00942 if (move_down == NULL || 00943 table->subtableZ[move_down->y].next != move_down->y) { 00944 /* symmetry detected may have to make another complete 00945 pass */ 00946 if (move_down != NULL) 00947 x = move_down->y; 00948 else { 00949 while ((unsigned) x < table->subtableZ[x].next); 00950 x = table->subtableZ[x].next; 00951 x = table->subtableZ[x].next; 00952 } 00953 i = x; 00954 while ((unsigned) i < table->subtableZ[i].next) { 00955 i = table->subtableZ[i].next; 00956 } 00957 final_group_size = i - x + 1; 00958 00959 if (init_group_size == final_group_size) { 00960 /* No new symmetries detected, 00961 go back to best position */ 00962 result = cuddZddSymmSiftingBackward(table, move_down, 00963 initial_size); 00964 } 00965 else { 00966 initial_size = table->keysZ; 00967 move_up = cuddZddSymmSifting_up(table, x, x_low, 00968 initial_size); 00969 result = cuddZddSymmSiftingBackward(table, move_up, 00970 initial_size); 00971 } 00972 } 00973 else { 00974 result = cuddZddSymmSiftingBackward(table, move_down, 00975 initial_size); 00976 /* move backward and stop at best position */ 00977 } 00978 if (!result) 00979 goto cuddZddSymmSiftingConvAuxOutOfMem; 00980 } 00981 else if (x == x_high) { /* Sift up */ 00982 /* Find top of x's symm group */ 00983 while ((unsigned) x < table->subtableZ[x].next) 00984 x = table->subtableZ[x].next; 00985 x = table->subtableZ[x].next; 00986 00987 i = x; 00988 while ((unsigned) i < table->subtableZ[i].next) { 00989 i = table->subtableZ[i].next; 00990 } 00991 init_group_size = i - x + 1; 00992 00993 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 00994 /* after that point x --> x_low, unless early term */ 00995 if (move_up == ZDD_MV_OOM) 00996 goto cuddZddSymmSiftingConvAuxOutOfMem; 00997 00998 if (move_up == NULL || 00999 table->subtableZ[move_up->x].next != move_up->x) { 01000 /* symmetry detected may have to make another complete 01001 pass */ 01002 if (move_up != NULL) 01003 x = move_up->x; 01004 else { 01005 while ((unsigned) x < table->subtableZ[x].next) 01006 x = table->subtableZ[x].next; 01007 } 01008 i = table->subtableZ[x].next; 01009 final_group_size = x - i + 1; 01010 01011 if (init_group_size == final_group_size) { 01012 /* No new symmetry groups detected, 01013 return to best position */ 01014 result = cuddZddSymmSiftingBackward(table, move_up, 01015 initial_size); 01016 } 01017 else { 01018 initial_size = table->keysZ; 01019 move_down = cuddZddSymmSifting_down(table, x, x_high, 01020 initial_size); 01021 result = cuddZddSymmSiftingBackward(table, move_down, 01022 initial_size); 01023 } 01024 } 01025 else { 01026 result = cuddZddSymmSiftingBackward(table, move_up, 01027 initial_size); 01028 /* move backward and stop at best position */ 01029 } 01030 if (!result) 01031 goto cuddZddSymmSiftingConvAuxOutOfMem; 01032 } 01033 else if ((x - x_low) > (x_high - x)) { /* must go down first: 01034 shorter */ 01035 move_down = cuddZddSymmSifting_down(table, x, x_high, 01036 initial_size); 01037 /* after that point x --> x_high */ 01038 if (move_down == ZDD_MV_OOM) 01039 goto cuddZddSymmSiftingConvAuxOutOfMem; 01040 01041 if (move_down != NULL) { 01042 x = move_down->y; 01043 } 01044 else { 01045 while ((unsigned) x < table->subtableZ[x].next) 01046 x = table->subtableZ[x].next; 01047 x = table->subtableZ[x].next; 01048 } 01049 i = x; 01050 while ((unsigned) i < table->subtableZ[i].next) { 01051 i = table->subtableZ[i].next; 01052 } 01053 init_group_size = i - x + 1; 01054 01055 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 01056 if (move_up == ZDD_MV_OOM) 01057 goto cuddZddSymmSiftingConvAuxOutOfMem; 01058 01059 if (move_up == NULL || 01060 table->subtableZ[move_up->x].next != move_up->x) { 01061 /* symmetry detected may have to make another complete 01062 pass */ 01063 if (move_up != NULL) { 01064 x = move_up->x; 01065 } 01066 else { 01067 while ((unsigned) x < table->subtableZ[x].next) 01068 x = table->subtableZ[x].next; 01069 } 01070 i = table->subtableZ[x].next; 01071 final_group_size = x - i + 1; 01072 01073 if (init_group_size == final_group_size) { 01074 /* No new symmetry groups detected, 01075 return to best position */ 01076 result = cuddZddSymmSiftingBackward(table, move_up, 01077 initial_size); 01078 } 01079 else { 01080 while (move_down != NULL) { 01081 move = move_down->next; 01082 cuddDeallocNode(table, (DdNode *)move_down); 01083 move_down = move; 01084 } 01085 initial_size = table->keysZ; 01086 move_down = cuddZddSymmSifting_down(table, x, x_high, 01087 initial_size); 01088 result = cuddZddSymmSiftingBackward(table, move_down, 01089 initial_size); 01090 } 01091 } 01092 else { 01093 result = cuddZddSymmSiftingBackward(table, move_up, 01094 initial_size); 01095 /* move backward and stop at best position */ 01096 } 01097 if (!result) 01098 goto cuddZddSymmSiftingConvAuxOutOfMem; 01099 } 01100 else { /* moving up first:shorter */ 01101 /* Find top of x's symmetry group */ 01102 x = table->subtableZ[x].next; 01103 01104 move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); 01105 /* after that point x --> x_high, unless early term */ 01106 if (move_up == ZDD_MV_OOM) 01107 goto cuddZddSymmSiftingConvAuxOutOfMem; 01108 01109 if (move_up != NULL) { 01110 x = move_up->x; 01111 } 01112 else { 01113 while ((unsigned) x < table->subtableZ[x].next) 01114 x = table->subtableZ[x].next; 01115 } 01116 i = table->subtableZ[x].next; 01117 init_group_size = x - i + 1; 01118 01119 move_down = cuddZddSymmSifting_down(table, x, x_high, 01120 initial_size); 01121 if (move_down == ZDD_MV_OOM) 01122 goto cuddZddSymmSiftingConvAuxOutOfMem; 01123 01124 if (move_down == NULL || 01125 table->subtableZ[move_down->y].next != move_down->y) { 01126 /* symmetry detected may have to make another complete 01127 pass */ 01128 if (move_down != NULL) { 01129 x = move_down->y; 01130 } 01131 else { 01132 while ((unsigned) x < table->subtableZ[x].next) 01133 x = table->subtableZ[x].next; 01134 x = table->subtableZ[x].next; 01135 } 01136 i = x; 01137 while ((unsigned) i < table->subtableZ[i].next) { 01138 i = table->subtableZ[i].next; 01139 } 01140 final_group_size = i - x + 1; 01141 01142 if (init_group_size == final_group_size) { 01143 /* No new symmetries detected, 01144 go back to best position */ 01145 result = cuddZddSymmSiftingBackward(table, move_down, 01146 initial_size); 01147 } 01148 else { 01149 while (move_up != NULL) { 01150 move = move_up->next; 01151 cuddDeallocNode(table, (DdNode *)move_up); 01152 move_up = move; 01153 } 01154 initial_size = table->keysZ; 01155 move_up = cuddZddSymmSifting_up(table, x, x_low, 01156 initial_size); 01157 result = cuddZddSymmSiftingBackward(table, move_up, 01158 initial_size); 01159 } 01160 } 01161 else { 01162 result = cuddZddSymmSiftingBackward(table, move_down, 01163 initial_size); 01164 /* move backward and stop at best position */ 01165 } 01166 if (!result) 01167 goto cuddZddSymmSiftingConvAuxOutOfMem; 01168 } 01169 01170 while (move_down != NULL) { 01171 move = move_down->next; 01172 cuddDeallocNode(table, (DdNode *)move_down); 01173 move_down = move; 01174 } 01175 while (move_up != NULL) { 01176 move = move_up->next; 01177 cuddDeallocNode(table, (DdNode *)move_up); 01178 move_up = move; 01179 } 01180 01181 return(1); 01182 01183 cuddZddSymmSiftingConvAuxOutOfMem: 01184 if (move_down != ZDD_MV_OOM) { 01185 while (move_down != NULL) { 01186 move = move_down->next; 01187 cuddDeallocNode(table, (DdNode *)move_down); 01188 move_down = move; 01189 } 01190 } 01191 if (move_up != ZDD_MV_OOM) { 01192 while (move_up != NULL) { 01193 move = move_up->next; 01194 cuddDeallocNode(table, (DdNode *)move_up); 01195 move_up = move; 01196 } 01197 } 01198 01199 return(0); 01200 01201 } /* end of cuddZddSymmSiftingConvAux */
static void cuddZddSymmSummary | ( | DdManager * | table, | |
int | lower, | |||
int | upper, | |||
int * | symvars, | |||
int * | symgroups | |||
) | [static] |
Function********************************************************************
Synopsis [Counts numbers of symmetric variables and symmetry groups.]
Description []
SideEffects [None]
Definition at line 1645 of file cuddZddSymm.c.
01651 { 01652 int i,x,gbot; 01653 int TotalSymm = 0; 01654 int TotalSymmGroups = 0; 01655 01656 for (i = lower; i <= upper; i++) { 01657 if (table->subtableZ[i].next != (unsigned) i) { 01658 TotalSymmGroups++; 01659 x = i; 01660 do { 01661 TotalSymm++; 01662 gbot = x; 01663 x = table->subtableZ[x].next; 01664 } while (x != i); 01665 #ifdef DD_DEBUG 01666 assert(table->subtableZ[gbot].next == (unsigned) i); 01667 #endif 01668 i = gbot; 01669 } 01670 } 01671 *symvars = TotalSymm; 01672 *symgroups = TotalSymmGroups; 01673 01674 return; 01675 01676 } /* end of cuddZddSymmSummary */
Function********************************************************************
Synopsis [Swaps two groups.]
Description [Swaps two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Updates the list of moves. Returns the number of keys in the table if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 1453 of file cuddZddSymm.c.
01458 { 01459 Move *move; 01460 int size; 01461 int i, temp, gxtop, gxbot, gytop, gybot, yprev; 01462 int swapx, swapy; 01463 01464 #ifdef DD_DEBUG 01465 assert(x < y); /* we assume that x < y */ 01466 #endif 01467 /* Find top and bottom for the two groups. */ 01468 gxtop = table->subtableZ[x].next; 01469 gytop = y; 01470 gxbot = x; 01471 gybot = table->subtableZ[y].next; 01472 while (table->subtableZ[gybot].next != (unsigned) y) 01473 gybot = table->subtableZ[gybot].next; 01474 yprev = gybot; 01475 01476 while (x <= y) { 01477 while (y > gxtop) { 01478 /* Set correct symmetries. */ 01479 temp = table->subtableZ[x].next; 01480 if (temp == x) 01481 temp = y; 01482 i = gxtop; 01483 for (;;) { 01484 if (table->subtableZ[i].next == (unsigned) x) { 01485 table->subtableZ[i].next = y; 01486 break; 01487 } else { 01488 i = table->subtableZ[i].next; 01489 } 01490 } 01491 if (table->subtableZ[y].next != (unsigned) y) { 01492 table->subtableZ[x].next = table->subtableZ[y].next; 01493 } else { 01494 table->subtableZ[x].next = x; 01495 } 01496 01497 if (yprev != y) { 01498 table->subtableZ[yprev].next = x; 01499 } else { 01500 yprev = x; 01501 } 01502 table->subtableZ[y].next = temp; 01503 01504 size = cuddZddSwapInPlace(table, x, y); 01505 if (size == 0) 01506 goto zdd_group_moveOutOfMem; 01507 swapx = x; 01508 swapy = y; 01509 y = x; 01510 x--; 01511 } /* while y > gxtop */ 01512 01513 /* Trying to find the next y. */ 01514 if (table->subtableZ[y].next <= (unsigned) y) { 01515 gybot = y; 01516 } else { 01517 y = table->subtableZ[y].next; 01518 } 01519 01520 yprev = gxtop; 01521 gxtop++; 01522 gxbot++; 01523 x = gxbot; 01524 } /* while x <= y, end of group movement */ 01525 move = (Move *)cuddDynamicAllocNode(table); 01526 if (move == NULL) 01527 goto zdd_group_moveOutOfMem; 01528 move->x = swapx; 01529 move->y = swapy; 01530 move->size = table->keysZ; 01531 move->next = *moves; 01532 *moves = move; 01533 01534 return(table->keysZ); 01535 01536 zdd_group_moveOutOfMem: 01537 while (*moves != NULL) { 01538 move = (*moves)->next; 01539 cuddDeallocNode(table, (DdNode *)(*moves)); 01540 *moves = move; 01541 } 01542 return(0); 01543 01544 } /* end of zdd_group_move */
static int zdd_group_move_backward | ( | DdManager * | table, | |
int | x, | |||
int | y | |||
) | [static] |
Function********************************************************************
Synopsis [Undoes the swap of two groups.]
Description [Undoes the swap of two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 1561 of file cuddZddSymm.c.
01565 { 01566 int size; 01567 int i, temp, gxtop, gxbot, gytop, gybot, yprev; 01568 01569 #ifdef DD_DEBUG 01570 assert(x < y); /* we assume that x < y */ 01571 #endif 01572 /* Find top and bottom of the two groups. */ 01573 gxtop = table->subtableZ[x].next; 01574 gytop = y; 01575 gxbot = x; 01576 gybot = table->subtableZ[y].next; 01577 while (table->subtableZ[gybot].next != (unsigned) y) 01578 gybot = table->subtableZ[gybot].next; 01579 yprev = gybot; 01580 01581 while (x <= y) { 01582 while (y > gxtop) { 01583 /* Set correct symmetries. */ 01584 temp = table->subtableZ[x].next; 01585 if (temp == x) 01586 temp = y; 01587 i = gxtop; 01588 for (;;) { 01589 if (table->subtableZ[i].next == (unsigned) x) { 01590 table->subtableZ[i].next = y; 01591 break; 01592 } else { 01593 i = table->subtableZ[i].next; 01594 } 01595 } 01596 if (table->subtableZ[y].next != (unsigned) y) { 01597 table->subtableZ[x].next = table->subtableZ[y].next; 01598 } else { 01599 table->subtableZ[x].next = x; 01600 } 01601 01602 if (yprev != y) { 01603 table->subtableZ[yprev].next = x; 01604 } else { 01605 yprev = x; 01606 } 01607 table->subtableZ[y].next = temp; 01608 01609 size = cuddZddSwapInPlace(table, x, y); 01610 if (size == 0) 01611 return(0); 01612 y = x; 01613 x--; 01614 } /* while y > gxtop */ 01615 01616 /* Trying to find the next y. */ 01617 if (table->subtableZ[y].next <= (unsigned) y) { 01618 gybot = y; 01619 } else { 01620 y = table->subtableZ[y].next; 01621 } 01622 01623 yprev = gxtop; 01624 gxtop++; 01625 gxbot++; 01626 x = gxbot; 01627 } /* while x <= y, end of group movement backward */ 01628 01629 return(size); 01630 01631 } /* end of zdd_group_move_backward */
char rcsid [] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $" [static] |
Definition at line 65 of file cuddZddSymm.c.
Definition at line 72 of file cuddZddSymm.c.
int* zdd_entry |
Definition at line 77 of file cuddZddReord.c.
Definition at line 79 of file cuddZddReord.c.