00001
00035 #include "util_hack.h"
00036 #include "cuddInt.h"
00037
00038
00039
00040
00041
00042 #define CUDD_SWAP_MOVE 0
00043 #define CUDD_LINEAR_TRANSFORM_MOVE 1
00044 #define CUDD_INVERSE_TRANSFORM_MOVE 2
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef lint
00061 static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
00062 #endif
00063
00064 extern int *zdd_entry;
00065 extern int zddTotalNumberSwapping;
00066 static int zddTotalNumberLinearTr;
00067 static DdNode *empty;
00068
00069
00070
00071
00072
00073
00074
00077
00078
00079
00080
00081 static int cuddZddLinearAux ARGS((DdManager *table, int x, int xLow, int xHigh));
00082 static Move * cuddZddLinearUp ARGS((DdManager *table, int y, int xLow, Move *prevMoves));
00083 static Move * cuddZddLinearDown ARGS((DdManager *table, int x, int xHigh, Move *prevMoves));
00084 static int cuddZddLinearBackward ARGS((DdManager *table, int size, Move *moves));
00085 static Move* cuddZddUndoMoves ARGS((DdManager *table, Move *moves));
00086
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00123 int
00124 cuddZddLinearSifting(
00125 DdManager * table,
00126 int lower,
00127 int upper)
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
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
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,"+");
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 }
00200
00201
00202
00203
00204
00205
00206
00222 int
00223 cuddZddLinearInPlace(
00224 DdManager * table,
00225 int x,
00226 int y)
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
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
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
00268
00269
00270
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 cuddSatDec(f1->ref);
00281 f0 = cuddE(f);
00282 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 }
00293 }
00294
00295
00296
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 }
00306 }
00307
00308
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
00320
00321
00322
00323
00324 posn = ddHash(f11, f0, yshift);
00325 f->next = ylist[posn];
00326 ylist[posn] = f;
00327 newykeys++;
00328 f = next;
00329 }
00330
00331
00332
00333
00334 f = g;
00335 while (f != NULL) {
00336 #ifdef DD_COUNT
00337 table->swapSteps++;
00338 #endif
00339 next = f->next;
00340
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
00354 if (f01 == empty) {
00355 newf1 = f10;
00356 cuddSatInc(newf1->ref);
00357 } else {
00358
00359 posn = ddHash(f01, f10, yshift);
00360
00361 newf1 = ylist[posn];
00362
00363 while (newf1 != NULL) {
00364 if (cuddT(newf1) == f01 && cuddE(newf1) == f10 &&
00365 (int) newf1->index == yindex) {
00366 cuddSatInc(newf1->ref);
00367 break;
00368 }
00369 newf1 = newf1->next;
00370 }
00371 if (newf1 == NULL) {
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
00379
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
00391
00392 if (f11 == empty) {
00393 newf0 = f00;
00394 cuddSatInc(newf0->ref);
00395 } else {
00396
00397 posn = ddHash(f11, f00, yshift);
00398
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;
00405 }
00406 newf0 = newf0->next;
00407 }
00408 if (newf0 == NULL) {
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
00415
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
00427
00428
00429
00430 posn = ddHash(newf1, newf0, xshift);
00431 newxkeys++;
00432 f->next = xlist[posn];
00433 xlist[posn] = f;
00434 f = next;
00435 }
00436
00437
00438
00439
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) {
00455 if (previous == NULL)
00456 ylist[i] = next;
00457 else
00458 previous->next = next;
00459 f1 = cuddT(f);
00460 cuddSatDec(f1->ref);
00461
00462 posn = ddHash(f1, empty, yshift);
00463
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;
00470 }
00471 newf1 = newf1->next;
00472 }
00473 if (newf1 == NULL) {
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
00480
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
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 }
00503 }
00504
00505
00506 table->subtableZ[x].keys = newxkeys;
00507 table->subtableZ[y].keys = newykeys;
00508
00509 table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
00510
00511
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 }
00528
00529
00544 static int
00545 cuddZddLinearAux(
00546 DdManager * table,
00547 int x,
00548 int xLow,
00549 int xHigh)
00550 {
00551 Move *move;
00552 Move *moveUp;
00553 Move *moveDown;
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
00570 if (moveDown == (Move *) CUDD_OUT_OF_MEM)
00571 goto cuddZddLinearAuxOutOfMem;
00572
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
00580 if (moveUp == (Move *) CUDD_OUT_OF_MEM)
00581 goto cuddZddLinearAuxOutOfMem;
00582
00583 result = cuddZddLinearBackward(table, initial_size, moveUp);
00584 if (!result)
00585 goto cuddZddLinearAuxOutOfMem;
00586
00587 } else if ((x - xLow) > (xHigh - x)) {
00588 moveDown = cuddZddLinearDown(table, x, xHigh, NULL);
00589
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
00600 result = cuddZddLinearBackward(table, initial_size, moveUp);
00601 if (!result)
00602 goto cuddZddLinearAuxOutOfMem;
00603
00604 } else {
00605 moveUp = cuddZddLinearUp(table, x, xLow, NULL);
00606
00607 if (moveUp == (Move *) CUDD_OUT_OF_MEM)
00608 goto cuddZddLinearAuxOutOfMem;
00609
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
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 }
00655
00656
00671 static Move *
00672 cuddZddLinearUp(
00673 DdManager * table,
00674 int y,
00675 int xLow,
00676 Move * prevMoves)
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
00705
00706
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 }
00740
00741
00756 static Move *
00757 cuddZddLinearDown(
00758 DdManager * table,
00759 int x,
00760 int xHigh,
00761 Move * prevMoves)
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
00790
00791
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 }
00823
00824
00840 static int
00841 cuddZddLinearBackward(
00842 DdManager * table,
00843 int size,
00844 Move * moves)
00845 {
00846 Move *move;
00847 int res;
00848
00849
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 }
00874
00875
00888 static Move*
00889 cuddZddUndoMoves(
00890 DdManager * table,
00891 Move * moves)
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 {
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 }
00939