SVF
cuddZddSymm.c
Go to the documentation of this file.
1 
70 #include "CUDD/util.h"
71 #include "CUDD/cuddInt.h"
72 
73 /*---------------------------------------------------------------------------*/
74 /* Constant declarations */
75 /*---------------------------------------------------------------------------*/
76 
77 #define ZDD_MV_OOM (Move *)1
78 
79 /*---------------------------------------------------------------------------*/
80 /* Stucture declarations */
81 /*---------------------------------------------------------------------------*/
82 
83 /*---------------------------------------------------------------------------*/
84 /* Type declarations */
85 /*---------------------------------------------------------------------------*/
86 
87 /*---------------------------------------------------------------------------*/
88 /* Variable declarations */
89 /*---------------------------------------------------------------------------*/
90 
91 #ifndef lint
92 static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.31 2012/02/05 01:07:19 fabio Exp $";
93 #endif
94 
95 extern int *zdd_entry;
96 
97 extern int zddTotalNumberSwapping;
98 
99 static DdNode *empty;
100 
101 /*---------------------------------------------------------------------------*/
102 /* Macro declarations */
103 /*---------------------------------------------------------------------------*/
104 
105 
108 /*---------------------------------------------------------------------------*/
109 /* Static function prototypes */
110 /*---------------------------------------------------------------------------*/
111 
112 static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high);
113 static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high);
114 static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size);
115 static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size);
116 static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size);
117 static int zdd_group_move (DdManager *table, int x, int y, Move **moves);
118 static int zdd_group_move_backward (DdManager *table, int x, int y);
119 static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups);
120 
124 /*---------------------------------------------------------------------------*/
125 /* Definition of exported functions */
126 /*---------------------------------------------------------------------------*/
127 
128 
140 void
142  DdManager * table,
143  int lower,
144  int upper)
145 {
146  int i, x, gbot;
147  int TotalSymm = 0;
148  int TotalSymmGroups = 0;
149 
150  for (i = lower; i < upper; i++) {
151  if (table->subtableZ[i].next != (unsigned) i) {
152  x = i;
153  (void) fprintf(table->out,"Group:");
154  do {
155  (void) fprintf(table->out," %d", table->invpermZ[x]);
156  TotalSymm++;
157  gbot = x;
158  x = table->subtableZ[x].next;
159  } while (x != i);
160  TotalSymmGroups++;
161 #ifdef DD_DEBUG
162  assert(table->subtableZ[gbot].next == (unsigned) i);
163 #endif
164  i = gbot;
165  (void) fprintf(table->out,"\n");
166  }
167  }
168  (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm);
169  (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups);
170 
171 } /* end of Cudd_zddSymmProfile */
172 
173 
174 /*---------------------------------------------------------------------------*/
175 /* Definition of internal functions */
176 /*---------------------------------------------------------------------------*/
177 
178 
192 int
194  DdManager * table,
195  int x,
196  int y)
197 {
198  int i;
199  DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10;
200  int yindex;
201  int xsymmy = 1;
202  int xsymmyp = 1;
203  int arccount = 0;
204  int TotalRefCount = 0;
205  int symm_found;
206 
207  empty = table->zero;
208 
209  yindex = table->invpermZ[y];
210  for (i = table->subtableZ[x].slots - 1; i >= 0; i--) {
211  f = table->subtableZ[x].nodelist[i];
212  while (f != NULL) {
213  /* Find f1, f0, f11, f10, f01, f00 */
214  f1 = cuddT(f);
215  f0 = cuddE(f);
216  if ((int) f1->index == yindex) {
217  f11 = cuddT(f1);
218  f10 = cuddE(f1);
219  if (f10 != empty)
220  arccount++;
221  } else {
222  if ((int) f0->index != yindex) {
223  return(0); /* f bypasses layer y */
224  }
225  f11 = empty;
226  f10 = f1;
227  }
228  if ((int) f0->index == yindex) {
229  f01 = cuddT(f0);
230  f00 = cuddE(f0);
231  if (f00 != empty)
232  arccount++;
233  } else {
234  f01 = empty;
235  f00 = f0;
236  }
237  if (f01 != f10)
238  xsymmy = 0;
239  if (f11 != f00)
240  xsymmyp = 0;
241  if ((xsymmy == 0) && (xsymmyp == 0))
242  return(0);
243 
244  f = f->next;
245  } /* for each element of the collision list */
246  } /* for each slot of the subtable */
247 
248  /* Calculate the total reference counts of y
249  ** whose else arc is not empty.
250  */
251  for (i = table->subtableZ[y].slots - 1; i >= 0; i--) {
252  f = table->subtableZ[y].nodelist[i];
253  while (f != NIL(DdNode)) {
254  if (cuddE(f) != empty)
255  TotalRefCount += f->ref;
256  f = f->next;
257  }
258  }
259 
260  symm_found = (arccount == TotalRefCount);
261 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
262  if (symm_found) {
263  int xindex = table->invpermZ[x];
264  (void) fprintf(table->out,
265  "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
266  xindex,yindex,x,y);
267  }
268 #endif
269 
270  return(symm_found);
271 
272 } /* end cuddZddSymmCheck */
273 
274 
297 int
299  DdManager * table,
300  int lower,
301  int upper)
302 {
303  int i;
304  int *var;
305  int nvars;
306  int x;
307  int result;
308  int symvars;
309  int symgroups;
310  int iteration;
311 #ifdef DD_STATS
312  int previousSize;
313 #endif
314 
315  nvars = table->sizeZ;
316 
317  /* Find order in which to sift variables. */
318  var = NULL;
319  zdd_entry = ALLOC(int, nvars);
320  if (zdd_entry == NULL) {
321  table->errorCode = CUDD_MEMORY_OUT;
322  goto cuddZddSymmSiftingOutOfMem;
323  }
324  var = ALLOC(int, nvars);
325  if (var == NULL) {
326  table->errorCode = CUDD_MEMORY_OUT;
327  goto cuddZddSymmSiftingOutOfMem;
328  }
329 
330  for (i = 0; i < nvars; i++) {
331  x = table->permZ[i];
332  zdd_entry[i] = table->subtableZ[x].keys;
333  var[i] = i;
334  }
335 
336  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
337 
338  /* Initialize the symmetry of each subtable to itself. */
339  for (i = lower; i <= upper; i++)
340  table->subtableZ[i].next = i;
341 
342  iteration = ddMin(table->siftMaxVar, nvars);
343  for (i = 0; i < iteration; i++) {
344  if (zddTotalNumberSwapping >= table->siftMaxSwap)
345  break;
346  if (util_cpu_time() - table->startTime > table->timeLimit) {
347  table->autoDynZ = 0; /* prevent further reordering */
348  break;
349  }
350  x = table->permZ[var[i]];
351 #ifdef DD_STATS
352  previousSize = table->keysZ;
353 #endif
354  if (x < lower || x > upper) continue;
355  if (table->subtableZ[x].next == (unsigned) x) {
356  result = cuddZddSymmSiftingAux(table, x, lower, upper);
357  if (!result)
358  goto cuddZddSymmSiftingOutOfMem;
359 #ifdef DD_STATS
360  if (table->keysZ < (unsigned) previousSize) {
361  (void) fprintf(table->out,"-");
362  } else if (table->keysZ > (unsigned) previousSize) {
363  (void) fprintf(table->out,"+");
364 #ifdef DD_VERBOSE
365  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
366 #endif
367  } else {
368  (void) fprintf(table->out,"=");
369  }
370  fflush(table->out);
371 #endif
372  }
373  }
374 
375  FREE(var);
376  FREE(zdd_entry);
377 
378  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
379 
380 #ifdef DD_STATS
381  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars);
382  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups);
383 #endif
384 
385  return(1+symvars);
386 
387 cuddZddSymmSiftingOutOfMem:
388 
389  if (zdd_entry != NULL)
390  FREE(zdd_entry);
391  if (var != NULL)
392  FREE(var);
393 
394  return(0);
395 
396 } /* end of cuddZddSymmSifting */
397 
398 
422 int
424  DdManager * table,
425  int lower,
426  int upper)
427 {
428  int i;
429  int *var;
430  int nvars;
431  int initialSize;
432  int x;
433  int result;
434  int symvars;
435  int symgroups;
436  int classes;
437  int iteration;
438 #ifdef DD_STATS
439  int previousSize;
440 #endif
441 
442  initialSize = table->keysZ;
443 
444  nvars = table->sizeZ;
445 
446  /* Find order in which to sift variables. */
447  var = NULL;
448  zdd_entry = ALLOC(int, nvars);
449  if (zdd_entry == NULL) {
450  table->errorCode = CUDD_MEMORY_OUT;
451  goto cuddZddSymmSiftingConvOutOfMem;
452  }
453  var = ALLOC(int, nvars);
454  if (var == NULL) {
455  table->errorCode = CUDD_MEMORY_OUT;
456  goto cuddZddSymmSiftingConvOutOfMem;
457  }
458 
459  for (i = 0; i < nvars; i++) {
460  x = table->permZ[i];
461  zdd_entry[i] = table->subtableZ[x].keys;
462  var[i] = i;
463  }
464 
465  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
466 
467  /* Initialize the symmetry of each subtable to itself
468  ** for first pass of converging symmetric sifting.
469  */
470  for (i = lower; i <= upper; i++)
471  table->subtableZ[i].next = i;
472 
473  iteration = ddMin(table->siftMaxVar, table->sizeZ);
474  for (i = 0; i < iteration; i++) {
475  if (zddTotalNumberSwapping >= table->siftMaxSwap)
476  break;
477  if (util_cpu_time() - table->startTime > table->timeLimit) {
478  table->autoDynZ = 0; /* prevent further reordering */
479  break;
480  }
481  x = table->permZ[var[i]];
482  if (x < lower || x > upper) continue;
483  /* Only sift if not in symmetry group already. */
484  if (table->subtableZ[x].next == (unsigned) x) {
485 #ifdef DD_STATS
486  previousSize = table->keysZ;
487 #endif
488  result = cuddZddSymmSiftingAux(table, x, lower, upper);
489  if (!result)
490  goto cuddZddSymmSiftingConvOutOfMem;
491 #ifdef DD_STATS
492  if (table->keysZ < (unsigned) previousSize) {
493  (void) fprintf(table->out,"-");
494  } else if (table->keysZ > (unsigned) previousSize) {
495  (void) fprintf(table->out,"+");
496 #ifdef DD_VERBOSE
497  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
498 #endif
499  } else {
500  (void) fprintf(table->out,"=");
501  }
502  fflush(table->out);
503 #endif
504  }
505  }
506 
507  /* Sifting now until convergence. */
508  while ((unsigned) initialSize > table->keysZ) {
509  initialSize = table->keysZ;
510 #ifdef DD_STATS
511  (void) fprintf(table->out,"\n");
512 #endif
513  /* Here we consider only one representative for each symmetry class. */
514  for (x = lower, classes = 0; x <= upper; x++, classes++) {
515  while ((unsigned) x < table->subtableZ[x].next)
516  x = table->subtableZ[x].next;
517  /* Here x is the largest index in a group.
518  ** Groups consists of adjacent variables.
519  ** Hence, the next increment of x will move it to a new group.
520  */
521  i = table->invpermZ[x];
522  zdd_entry[i] = table->subtableZ[x].keys;
523  var[classes] = i;
524  }
525 
526  qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare);
527 
528  /* Now sift. */
529  iteration = ddMin(table->siftMaxVar, nvars);
530  for (i = 0; i < iteration; i++) {
531  if (zddTotalNumberSwapping >= table->siftMaxSwap)
532  break;
533  if (util_cpu_time() - table->startTime > table->timeLimit) {
534  table->autoDynZ = 0; /* prevent further reordering */
535  break;
536  }
537  x = table->permZ[var[i]];
538  if ((unsigned) x >= table->subtableZ[x].next) {
539 #ifdef DD_STATS
540  previousSize = table->keysZ;
541 #endif
542  result = cuddZddSymmSiftingConvAux(table, x, lower, upper);
543  if (!result)
544  goto cuddZddSymmSiftingConvOutOfMem;
545 #ifdef DD_STATS
546  if (table->keysZ < (unsigned) previousSize) {
547  (void) fprintf(table->out,"-");
548  } else if (table->keysZ > (unsigned) previousSize) {
549  (void) fprintf(table->out,"+");
550 #ifdef DD_VERBOSE
551  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
552 #endif
553  } else {
554  (void) fprintf(table->out,"=");
555  }
556  fflush(table->out);
557 #endif
558  }
559  } /* for */
560  }
561 
562  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
563 
564 #ifdef DD_STATS
565  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",
566  symvars);
567  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",
568  symgroups);
569 #endif
570 
571  FREE(var);
572  FREE(zdd_entry);
573 
574  return(1+symvars);
575 
576 cuddZddSymmSiftingConvOutOfMem:
577 
578  if (zdd_entry != NULL)
579  FREE(zdd_entry);
580  if (var != NULL)
581  FREE(var);
582 
583  return(0);
584 
585 } /* end of cuddZddSymmSiftingConv */
586 
587 
588 /*---------------------------------------------------------------------------*/
589 /* Definition of static functions */
590 /*---------------------------------------------------------------------------*/
591 
592 
608 static int
610  DdManager * table,
611  int x,
612  int x_low,
613  int x_high)
614 {
615  Move *move;
616  Move *move_up; /* list of up move */
617  Move *move_down; /* list of down move */
618  int initial_size;
619  int result;
620  int i;
621  int topbot; /* index to either top or bottom of symmetry group */
622  int init_group_size, final_group_size;
623 
624  initial_size = table->keysZ;
625 
626  move_down = NULL;
627  move_up = NULL;
628 
629  /* Look for consecutive symmetries above x. */
630  for (i = x; i > x_low; i--) {
631  if (!cuddZddSymmCheck(table, i - 1, i))
632  break;
633  /* find top of i-1's symmetry */
634  topbot = table->subtableZ[i - 1].next;
635  table->subtableZ[i - 1].next = i;
636  table->subtableZ[x].next = topbot;
637  /* x is bottom of group so its symmetry is top of i-1's
638  group */
639  i = topbot + 1; /* add 1 for i--, new i is top of symm group */
640  }
641  /* Look for consecutive symmetries below x. */
642  for (i = x; i < x_high; i++) {
643  if (!cuddZddSymmCheck(table, i, i + 1))
644  break;
645  /* find bottom of i+1's symm group */
646  topbot = i + 1;
647  while ((unsigned) topbot < table->subtableZ[topbot].next)
648  topbot = table->subtableZ[topbot].next;
649 
650  table->subtableZ[topbot].next = table->subtableZ[i].next;
651  table->subtableZ[i].next = i + 1;
652  i = topbot - 1; /* add 1 for i++,
653  new i is bottom of symm group */
654  }
655 
656  /* Now x maybe in the middle of a symmetry group. */
657  if (x == x_low) { /* Sift down */
658  /* Find bottom of x's symm group */
659  while ((unsigned) x < table->subtableZ[x].next)
660  x = table->subtableZ[x].next;
661 
662  i = table->subtableZ[x].next;
663  init_group_size = x - i + 1;
664 
665  move_down = cuddZddSymmSifting_down(table, x, x_high,
666  initial_size);
667  /* after that point x --> x_high, unless early term */
668  if (move_down == ZDD_MV_OOM)
669  goto cuddZddSymmSiftingAuxOutOfMem;
670 
671  if (move_down == NULL ||
672  table->subtableZ[move_down->y].next != move_down->y) {
673  /* symmetry detected may have to make another complete
674  pass */
675  if (move_down != NULL)
676  x = move_down->y;
677  else
678  x = table->subtableZ[x].next;
679  i = x;
680  while ((unsigned) i < table->subtableZ[i].next) {
681  i = table->subtableZ[i].next;
682  }
683  final_group_size = i - x + 1;
684 
685  if (init_group_size == final_group_size) {
686  /* No new symmetry groups detected,
687  return to best position */
688  result = cuddZddSymmSiftingBackward(table,
689  move_down, initial_size);
690  }
691  else {
692  initial_size = table->keysZ;
693  move_up = cuddZddSymmSifting_up(table, x, x_low,
694  initial_size);
695  result = cuddZddSymmSiftingBackward(table, move_up,
696  initial_size);
697  }
698  }
699  else {
700  result = cuddZddSymmSiftingBackward(table, move_down,
701  initial_size);
702  /* move backward and stop at best position */
703  }
704  if (!result)
705  goto cuddZddSymmSiftingAuxOutOfMem;
706  }
707  else if (x == x_high) { /* Sift up */
708  /* Find top of x's symm group */
709  while ((unsigned) x < table->subtableZ[x].next)
710  x = table->subtableZ[x].next;
711  x = table->subtableZ[x].next;
712 
713  i = x;
714  while ((unsigned) i < table->subtableZ[i].next) {
715  i = table->subtableZ[i].next;
716  }
717  init_group_size = i - x + 1;
718 
719  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
720  /* after that point x --> x_low, unless early term */
721  if (move_up == ZDD_MV_OOM)
722  goto cuddZddSymmSiftingAuxOutOfMem;
723 
724  if (move_up == NULL ||
725  table->subtableZ[move_up->x].next != move_up->x) {
726  /* symmetry detected may have to make another complete
727  pass */
728  if (move_up != NULL)
729  x = move_up->x;
730  else {
731  while ((unsigned) x < table->subtableZ[x].next)
732  x = table->subtableZ[x].next;
733  }
734  i = table->subtableZ[x].next;
735  final_group_size = x - i + 1;
736 
737  if (init_group_size == final_group_size) {
738  /* No new symmetry groups detected,
739  return to best position */
740  result = cuddZddSymmSiftingBackward(table, move_up,
741  initial_size);
742  }
743  else {
744  initial_size = table->keysZ;
745  move_down = cuddZddSymmSifting_down(table, x, x_high,
746  initial_size);
747  result = cuddZddSymmSiftingBackward(table, move_down,
748  initial_size);
749  }
750  }
751  else {
752  result = cuddZddSymmSiftingBackward(table, move_up,
753  initial_size);
754  /* move backward and stop at best position */
755  }
756  if (!result)
757  goto cuddZddSymmSiftingAuxOutOfMem;
758  }
759  else if ((x - x_low) > (x_high - x)) { /* must go down first:
760  shorter */
761  /* Find bottom of x's symm group */
762  while ((unsigned) x < table->subtableZ[x].next)
763  x = table->subtableZ[x].next;
764 
765  move_down = cuddZddSymmSifting_down(table, x, x_high,
766  initial_size);
767  /* after that point x --> x_high, unless early term */
768  if (move_down == ZDD_MV_OOM)
769  goto cuddZddSymmSiftingAuxOutOfMem;
770 
771  if (move_down != NULL) {
772  x = move_down->y;
773  }
774  else {
775  x = table->subtableZ[x].next;
776  }
777  i = x;
778  while ((unsigned) i < table->subtableZ[i].next) {
779  i = table->subtableZ[i].next;
780  }
781  init_group_size = i - x + 1;
782 
783  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
784  if (move_up == ZDD_MV_OOM)
785  goto cuddZddSymmSiftingAuxOutOfMem;
786 
787  if (move_up == NULL ||
788  table->subtableZ[move_up->x].next != move_up->x) {
789  /* symmetry detected may have to make another complete
790  pass */
791  if (move_up != NULL) {
792  x = move_up->x;
793  }
794  else {
795  while ((unsigned) x < table->subtableZ[x].next)
796  x = table->subtableZ[x].next;
797  }
798  i = table->subtableZ[x].next;
799  final_group_size = x - i + 1;
800 
801  if (init_group_size == final_group_size) {
802  /* No new symmetry groups detected,
803  return to best position */
804  result = cuddZddSymmSiftingBackward(table, move_up,
805  initial_size);
806  }
807  else {
808  while (move_down != NULL) {
809  move = move_down->next;
810  cuddDeallocMove(table, move_down);
811  move_down = move;
812  }
813  initial_size = table->keysZ;
814  move_down = cuddZddSymmSifting_down(table, x, x_high,
815  initial_size);
816  result = cuddZddSymmSiftingBackward(table, move_down,
817  initial_size);
818  }
819  }
820  else {
821  result = cuddZddSymmSiftingBackward(table, move_up,
822  initial_size);
823  /* move backward and stop at best position */
824  }
825  if (!result)
826  goto cuddZddSymmSiftingAuxOutOfMem;
827  }
828  else { /* moving up first:shorter */
829  /* Find top of x's symmetry group */
830  while ((unsigned) x < table->subtableZ[x].next)
831  x = table->subtableZ[x].next;
832  x = table->subtableZ[x].next;
833 
834  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
835  /* after that point x --> x_high, unless early term */
836  if (move_up == ZDD_MV_OOM)
837  goto cuddZddSymmSiftingAuxOutOfMem;
838 
839  if (move_up != NULL) {
840  x = move_up->x;
841  }
842  else {
843  while ((unsigned) x < table->subtableZ[x].next)
844  x = table->subtableZ[x].next;
845  }
846  i = table->subtableZ[x].next;
847  init_group_size = x - i + 1;
848 
849  move_down = cuddZddSymmSifting_down(table, x, x_high,
850  initial_size);
851  if (move_down == ZDD_MV_OOM)
852  goto cuddZddSymmSiftingAuxOutOfMem;
853 
854  if (move_down == NULL ||
855  table->subtableZ[move_down->y].next != move_down->y) {
856  /* symmetry detected may have to make another complete
857  pass */
858  if (move_down != NULL) {
859  x = move_down->y;
860  }
861  else {
862  x = table->subtableZ[x].next;
863  }
864  i = x;
865  while ((unsigned) i < table->subtableZ[i].next) {
866  i = table->subtableZ[i].next;
867  }
868  final_group_size = i - x + 1;
869 
870  if (init_group_size == final_group_size) {
871  /* No new symmetries detected,
872  go back to best position */
873  result = cuddZddSymmSiftingBackward(table, move_down,
874  initial_size);
875  }
876  else {
877  while (move_up != NULL) {
878  move = move_up->next;
879  cuddDeallocMove(table, move_up);
880  move_up = move;
881  }
882  initial_size = table->keysZ;
883  move_up = cuddZddSymmSifting_up(table, x, x_low,
884  initial_size);
885  result = cuddZddSymmSiftingBackward(table, move_up,
886  initial_size);
887  }
888  }
889  else {
890  result = cuddZddSymmSiftingBackward(table, move_down,
891  initial_size);
892  /* move backward and stop at best position */
893  }
894  if (!result)
895  goto cuddZddSymmSiftingAuxOutOfMem;
896  }
897 
898  while (move_down != NULL) {
899  move = move_down->next;
900  cuddDeallocMove(table, move_down);
901  move_down = move;
902  }
903  while (move_up != NULL) {
904  move = move_up->next;
905  cuddDeallocMove(table, move_up);
906  move_up = move;
907  }
908 
909  return(1);
910 
911 cuddZddSymmSiftingAuxOutOfMem:
912  if (move_down != ZDD_MV_OOM) {
913  while (move_down != NULL) {
914  move = move_down->next;
915  cuddDeallocMove(table, move_down);
916  move_down = move;
917  }
918  }
919  if (move_up != ZDD_MV_OOM) {
920  while (move_up != NULL) {
921  move = move_up->next;
922  cuddDeallocMove(table, move_up);
923  move_up = move;
924  }
925  }
926 
927  return(0);
928 
929 } /* end of cuddZddSymmSiftingAux */
930 
931 
948 static int
950  DdManager * table,
951  int x,
952  int x_low,
953  int x_high)
954 {
955  Move *move;
956  Move *move_up; /* list of up move */
957  Move *move_down; /* list of down move */
958  int initial_size;
959  int result;
960  int i;
961  int init_group_size, final_group_size;
962 
963  initial_size = table->keysZ;
964 
965  move_down = NULL;
966  move_up = NULL;
967 
968  if (x == x_low) { /* Sift down */
969  i = table->subtableZ[x].next;
970  init_group_size = x - i + 1;
971 
972  move_down = cuddZddSymmSifting_down(table, x, x_high,
973  initial_size);
974  /* after that point x --> x_high, unless early term */
975  if (move_down == ZDD_MV_OOM)
976  goto cuddZddSymmSiftingConvAuxOutOfMem;
977 
978  if (move_down == NULL ||
979  table->subtableZ[move_down->y].next != move_down->y) {
980  /* symmetry detected may have to make another complete
981  pass */
982  if (move_down != NULL)
983  x = move_down->y;
984  else {
985  while ((unsigned) x < table->subtableZ[x].next)
986  x = table->subtableZ[x].next;
987  x = table->subtableZ[x].next;
988  }
989  i = x;
990  while ((unsigned) i < table->subtableZ[i].next) {
991  i = table->subtableZ[i].next;
992  }
993  final_group_size = i - x + 1;
994 
995  if (init_group_size == final_group_size) {
996  /* No new symmetries detected,
997  go back to best position */
998  result = cuddZddSymmSiftingBackward(table, move_down,
999  initial_size);
1000  }
1001  else {
1002  initial_size = table->keysZ;
1003  move_up = cuddZddSymmSifting_up(table, x, x_low,
1004  initial_size);
1005  result = cuddZddSymmSiftingBackward(table, move_up,
1006  initial_size);
1007  }
1008  }
1009  else {
1010  result = cuddZddSymmSiftingBackward(table, move_down,
1011  initial_size);
1012  /* move backward and stop at best position */
1013  }
1014  if (!result)
1015  goto cuddZddSymmSiftingConvAuxOutOfMem;
1016  }
1017  else if (x == x_high) { /* Sift up */
1018  /* Find top of x's symm group */
1019  while ((unsigned) x < table->subtableZ[x].next)
1020  x = table->subtableZ[x].next;
1021  x = table->subtableZ[x].next;
1022 
1023  i = x;
1024  while ((unsigned) i < table->subtableZ[i].next) {
1025  i = table->subtableZ[i].next;
1026  }
1027  init_group_size = i - x + 1;
1028 
1029  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
1030  /* after that point x --> x_low, unless early term */
1031  if (move_up == ZDD_MV_OOM)
1032  goto cuddZddSymmSiftingConvAuxOutOfMem;
1033 
1034  if (move_up == NULL ||
1035  table->subtableZ[move_up->x].next != move_up->x) {
1036  /* symmetry detected may have to make another complete
1037  pass */
1038  if (move_up != NULL)
1039  x = move_up->x;
1040  else {
1041  while ((unsigned) x < table->subtableZ[x].next)
1042  x = table->subtableZ[x].next;
1043  }
1044  i = table->subtableZ[x].next;
1045  final_group_size = x - i + 1;
1046 
1047  if (init_group_size == final_group_size) {
1048  /* No new symmetry groups detected,
1049  return to best position */
1050  result = cuddZddSymmSiftingBackward(table, move_up,
1051  initial_size);
1052  }
1053  else {
1054  initial_size = table->keysZ;
1055  move_down = cuddZddSymmSifting_down(table, x, x_high,
1056  initial_size);
1057  result = cuddZddSymmSiftingBackward(table, move_down,
1058  initial_size);
1059  }
1060  }
1061  else {
1062  result = cuddZddSymmSiftingBackward(table, move_up,
1063  initial_size);
1064  /* move backward and stop at best position */
1065  }
1066  if (!result)
1067  goto cuddZddSymmSiftingConvAuxOutOfMem;
1068  }
1069  else if ((x - x_low) > (x_high - x)) { /* must go down first:
1070  shorter */
1071  move_down = cuddZddSymmSifting_down(table, x, x_high,
1072  initial_size);
1073  /* after that point x --> x_high */
1074  if (move_down == ZDD_MV_OOM)
1075  goto cuddZddSymmSiftingConvAuxOutOfMem;
1076 
1077  if (move_down != NULL) {
1078  x = move_down->y;
1079  }
1080  else {
1081  while ((unsigned) x < table->subtableZ[x].next)
1082  x = table->subtableZ[x].next;
1083  x = table->subtableZ[x].next;
1084  }
1085  i = x;
1086  while ((unsigned) i < table->subtableZ[i].next) {
1087  i = table->subtableZ[i].next;
1088  }
1089  init_group_size = i - x + 1;
1090 
1091  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
1092  if (move_up == ZDD_MV_OOM)
1093  goto cuddZddSymmSiftingConvAuxOutOfMem;
1094 
1095  if (move_up == NULL ||
1096  table->subtableZ[move_up->x].next != move_up->x) {
1097  /* symmetry detected may have to make another complete
1098  pass */
1099  if (move_up != NULL) {
1100  x = move_up->x;
1101  }
1102  else {
1103  while ((unsigned) x < table->subtableZ[x].next)
1104  x = table->subtableZ[x].next;
1105  }
1106  i = table->subtableZ[x].next;
1107  final_group_size = x - i + 1;
1108 
1109  if (init_group_size == final_group_size) {
1110  /* No new symmetry groups detected,
1111  return to best position */
1112  result = cuddZddSymmSiftingBackward(table, move_up,
1113  initial_size);
1114  }
1115  else {
1116  while (move_down != NULL) {
1117  move = move_down->next;
1118  cuddDeallocMove(table, move_down);
1119  move_down = move;
1120  }
1121  initial_size = table->keysZ;
1122  move_down = cuddZddSymmSifting_down(table, x, x_high,
1123  initial_size);
1124  result = cuddZddSymmSiftingBackward(table, move_down,
1125  initial_size);
1126  }
1127  }
1128  else {
1129  result = cuddZddSymmSiftingBackward(table, move_up,
1130  initial_size);
1131  /* move backward and stop at best position */
1132  }
1133  if (!result)
1134  goto cuddZddSymmSiftingConvAuxOutOfMem;
1135  }
1136  else { /* moving up first:shorter */
1137  /* Find top of x's symmetry group */
1138  x = table->subtableZ[x].next;
1139 
1140  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
1141  /* after that point x --> x_high, unless early term */
1142  if (move_up == ZDD_MV_OOM)
1143  goto cuddZddSymmSiftingConvAuxOutOfMem;
1144 
1145  if (move_up != NULL) {
1146  x = move_up->x;
1147  }
1148  else {
1149  while ((unsigned) x < table->subtableZ[x].next)
1150  x = table->subtableZ[x].next;
1151  }
1152  i = table->subtableZ[x].next;
1153  init_group_size = x - i + 1;
1154 
1155  move_down = cuddZddSymmSifting_down(table, x, x_high,
1156  initial_size);
1157  if (move_down == ZDD_MV_OOM)
1158  goto cuddZddSymmSiftingConvAuxOutOfMem;
1159 
1160  if (move_down == NULL ||
1161  table->subtableZ[move_down->y].next != move_down->y) {
1162  /* symmetry detected may have to make another complete
1163  pass */
1164  if (move_down != NULL) {
1165  x = move_down->y;
1166  }
1167  else {
1168  while ((unsigned) x < table->subtableZ[x].next)
1169  x = table->subtableZ[x].next;
1170  x = table->subtableZ[x].next;
1171  }
1172  i = x;
1173  while ((unsigned) i < table->subtableZ[i].next) {
1174  i = table->subtableZ[i].next;
1175  }
1176  final_group_size = i - x + 1;
1177 
1178  if (init_group_size == final_group_size) {
1179  /* No new symmetries detected,
1180  go back to best position */
1181  result = cuddZddSymmSiftingBackward(table, move_down,
1182  initial_size);
1183  }
1184  else {
1185  while (move_up != NULL) {
1186  move = move_up->next;
1187  cuddDeallocMove(table, move_up);
1188  move_up = move;
1189  }
1190  initial_size = table->keysZ;
1191  move_up = cuddZddSymmSifting_up(table, x, x_low,
1192  initial_size);
1193  result = cuddZddSymmSiftingBackward(table, move_up,
1194  initial_size);
1195  }
1196  }
1197  else {
1198  result = cuddZddSymmSiftingBackward(table, move_down,
1199  initial_size);
1200  /* move backward and stop at best position */
1201  }
1202  if (!result)
1203  goto cuddZddSymmSiftingConvAuxOutOfMem;
1204  }
1205 
1206  while (move_down != NULL) {
1207  move = move_down->next;
1208  cuddDeallocMove(table, move_down);
1209  move_down = move;
1210  }
1211  while (move_up != NULL) {
1212  move = move_up->next;
1213  cuddDeallocMove(table, move_up);
1214  move_up = move;
1215  }
1216 
1217  return(1);
1218 
1219 cuddZddSymmSiftingConvAuxOutOfMem:
1220  if (move_down != ZDD_MV_OOM) {
1221  while (move_down != NULL) {
1222  move = move_down->next;
1223  cuddDeallocMove(table, move_down);
1224  move_down = move;
1225  }
1226  }
1227  if (move_up != ZDD_MV_OOM) {
1228  while (move_up != NULL) {
1229  move = move_up->next;
1230  cuddDeallocMove(table, move_up);
1231  move_up = move;
1232  }
1233  }
1234 
1235  return(0);
1236 
1237 } /* end of cuddZddSymmSiftingConvAux */
1238 
1239 
1257 static Move *
1259  DdManager * table,
1260  int x,
1261  int x_low,
1262  int initial_size)
1263 {
1264  Move *moves;
1265  Move *move;
1266  int y;
1267  int size;
1268  int limit_size = initial_size;
1269  int i, gytop;
1270 
1271  moves = NULL;
1272  y = cuddZddNextLow(table, x);
1273  while (y >= x_low) {
1274  gytop = table->subtableZ[y].next;
1275  if (cuddZddSymmCheck(table, y, x)) {
1276  /* Symmetry found, attach symm groups */
1277  table->subtableZ[y].next = x;
1278  i = table->subtableZ[x].next;
1279  while (table->subtableZ[i].next != (unsigned) x)
1280  i = table->subtableZ[i].next;
1281  table->subtableZ[i].next = gytop;
1282  }
1283  else if ((table->subtableZ[x].next == (unsigned) x) &&
1284  (table->subtableZ[y].next == (unsigned) y)) {
1285  /* x and y have self symmetry */
1286  size = cuddZddSwapInPlace(table, y, x);
1287  if (size == 0)
1288  goto cuddZddSymmSifting_upOutOfMem;
1289  move = (Move *)cuddDynamicAllocNode(table);
1290  if (move == NULL)
1291  goto cuddZddSymmSifting_upOutOfMem;
1292  move->x = y;
1293  move->y = x;
1294  move->size = size;
1295  move->next = moves;
1296  moves = move;
1297  if ((double)size >
1298  (double)limit_size * table->maxGrowth)
1299  return(moves);
1300  if (size < limit_size)
1301  limit_size = size;
1302  }
1303  else { /* Group move */
1304  size = zdd_group_move(table, y, x, &moves);
1305  if ((double)size >
1306  (double)limit_size * table->maxGrowth)
1307  return(moves);
1308  if (size < limit_size)
1309  limit_size = size;
1310  }
1311  x = gytop;
1312  y = cuddZddNextLow(table, x);
1313  }
1314 
1315  return(moves);
1316 
1317 cuddZddSymmSifting_upOutOfMem:
1318  while (moves != NULL) {
1319  move = moves->next;
1320  cuddDeallocMove(table, moves);
1321  moves = move;
1322  }
1323  return(ZDD_MV_OOM);
1324 
1325 } /* end of cuddZddSymmSifting_up */
1326 
1327 
1345 static Move *
1347  DdManager * table,
1348  int x,
1349  int x_high,
1350  int initial_size)
1351 {
1352  Move *moves;
1353  Move *move;
1354  int y;
1355  int size;
1356  int limit_size = initial_size;
1357  int i, gxtop, gybot;
1358 
1359  moves = NULL;
1360  y = cuddZddNextHigh(table, x);
1361  while (y <= x_high) {
1362  gybot = table->subtableZ[y].next;
1363  while (table->subtableZ[gybot].next != (unsigned) y)
1364  gybot = table->subtableZ[gybot].next;
1365  if (cuddZddSymmCheck(table, x, y)) {
1366  /* Symmetry found, attach symm groups */
1367  gxtop = table->subtableZ[x].next;
1368  table->subtableZ[x].next = y;
1369  i = table->subtableZ[y].next;
1370  while (table->subtableZ[i].next != (unsigned) y)
1371  i = table->subtableZ[i].next;
1372  table->subtableZ[i].next = gxtop;
1373  }
1374  else if ((table->subtableZ[x].next == (unsigned) x) &&
1375  (table->subtableZ[y].next == (unsigned) y)) {
1376  /* x and y have self symmetry */
1377  size = cuddZddSwapInPlace(table, x, y);
1378  if (size == 0)
1379  goto cuddZddSymmSifting_downOutOfMem;
1380  move = (Move *)cuddDynamicAllocNode(table);
1381  if (move == NULL)
1382  goto cuddZddSymmSifting_downOutOfMem;
1383  move->x = x;
1384  move->y = y;
1385  move->size = size;
1386  move->next = moves;
1387  moves = move;
1388  if ((double)size >
1389  (double)limit_size * table->maxGrowth)
1390  return(moves);
1391  if (size < limit_size)
1392  limit_size = size;
1393  x = y;
1394  y = cuddZddNextHigh(table, x);
1395  }
1396  else { /* Group move */
1397  size = zdd_group_move(table, x, y, &moves);
1398  if ((double)size >
1399  (double)limit_size * table->maxGrowth)
1400  return(moves);
1401  if (size < limit_size)
1402  limit_size = size;
1403  }
1404  x = gybot;
1405  y = cuddZddNextHigh(table, x);
1406  }
1407 
1408  return(moves);
1409 
1410 cuddZddSymmSifting_downOutOfMem:
1411  while (moves != NULL) {
1412  move = moves->next;
1413  cuddDeallocMove(table, moves);
1414  moves = move;
1415  }
1416  return(ZDD_MV_OOM);
1417 
1418 } /* end of cuddZddSymmSifting_down */
1419 
1420 
1436 static int
1438  DdManager * table,
1439  Move * moves,
1440  int size)
1441 {
1442  int i;
1443  int i_best;
1444  Move *move;
1445  int res;
1446 
1447  i_best = -1;
1448  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
1449  if (move->size < size) {
1450  i_best = i;
1451  size = move->size;
1452  }
1453  }
1454 
1455  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
1456  if (i == i_best) break;
1457  if ((table->subtableZ[move->x].next == move->x) &&
1458  (table->subtableZ[move->y].next == move->y)) {
1459  res = cuddZddSwapInPlace(table, move->x, move->y);
1460  if (!res) return(0);
1461  }
1462  else { /* Group move necessary */
1463  res = zdd_group_move_backward(table, move->x, move->y);
1464  }
1465  if (i_best == -1 && res == size)
1466  break;
1467  }
1468 
1469  return(1);
1470 
1471 } /* end of cuddZddSymmSiftingBackward */
1472 
1473 
1488 static int
1490  DdManager * table,
1491  int x,
1492  int y,
1493  Move ** moves)
1494 {
1495  Move *move;
1496  int size;
1497  int i, temp, gxtop, gxbot, gybot, yprev;
1498  int swapx, swapy;
1499 
1500 #ifdef DD_DEBUG
1501  assert(x < y); /* we assume that x < y */
1502 #endif
1503  /* Find top and bottom for the two groups. */
1504  gxtop = table->subtableZ[x].next;
1505  gxbot = x;
1506  gybot = table->subtableZ[y].next;
1507  while (table->subtableZ[gybot].next != (unsigned) y)
1508  gybot = table->subtableZ[gybot].next;
1509  yprev = gybot;
1510 
1511  while (x <= y) {
1512  while (y > gxtop) {
1513  /* Set correct symmetries. */
1514  temp = table->subtableZ[x].next;
1515  if (temp == x)
1516  temp = y;
1517  i = gxtop;
1518  for (;;) {
1519  if (table->subtableZ[i].next == (unsigned) x) {
1520  table->subtableZ[i].next = y;
1521  break;
1522  } else {
1523  i = table->subtableZ[i].next;
1524  }
1525  }
1526  if (table->subtableZ[y].next != (unsigned) y) {
1527  table->subtableZ[x].next = table->subtableZ[y].next;
1528  } else {
1529  table->subtableZ[x].next = x;
1530  }
1531 
1532  if (yprev != y) {
1533  table->subtableZ[yprev].next = x;
1534  } else {
1535  yprev = x;
1536  }
1537  table->subtableZ[y].next = temp;
1538 
1539  size = cuddZddSwapInPlace(table, x, y);
1540  if (size == 0)
1541  goto zdd_group_moveOutOfMem;
1542  swapx = x;
1543  swapy = y;
1544  y = x;
1545  x--;
1546  } /* while y > gxtop */
1547 
1548  /* Trying to find the next y. */
1549  if (table->subtableZ[y].next <= (unsigned) y) {
1550  gybot = y;
1551  } else {
1552  y = table->subtableZ[y].next;
1553  }
1554 
1555  yprev = gxtop;
1556  gxtop++;
1557  gxbot++;
1558  x = gxbot;
1559  } /* while x <= y, end of group movement */
1560  move = (Move *)cuddDynamicAllocNode(table);
1561  if (move == NULL)
1562  goto zdd_group_moveOutOfMem;
1563  move->x = swapx;
1564  move->y = swapy;
1565  move->size = table->keysZ;
1566  move->next = *moves;
1567  *moves = move;
1568 
1569  return(table->keysZ);
1570 
1571 zdd_group_moveOutOfMem:
1572  while (*moves != NULL) {
1573  move = (*moves)->next;
1574  cuddDeallocMove(table, *moves);
1575  *moves = move;
1576  }
1577  return(0);
1578 
1579 } /* end of zdd_group_move */
1580 
1581 
1595 static int
1597  DdManager * table,
1598  int x,
1599  int y)
1600 {
1601  int size;
1602  int i, temp, gxtop, gxbot, gybot, yprev;
1603 
1604 #ifdef DD_DEBUG
1605  assert(x < y); /* we assume that x < y */
1606 #endif
1607  /* Find top and bottom of the two groups. */
1608  gxtop = table->subtableZ[x].next;
1609  gxbot = x;
1610  gybot = table->subtableZ[y].next;
1611  while (table->subtableZ[gybot].next != (unsigned) y)
1612  gybot = table->subtableZ[gybot].next;
1613  yprev = gybot;
1614 
1615  while (x <= y) {
1616  while (y > gxtop) {
1617  /* Set correct symmetries. */
1618  temp = table->subtableZ[x].next;
1619  if (temp == x)
1620  temp = y;
1621  i = gxtop;
1622  for (;;) {
1623  if (table->subtableZ[i].next == (unsigned) x) {
1624  table->subtableZ[i].next = y;
1625  break;
1626  } else {
1627  i = table->subtableZ[i].next;
1628  }
1629  }
1630  if (table->subtableZ[y].next != (unsigned) y) {
1631  table->subtableZ[x].next = table->subtableZ[y].next;
1632  } else {
1633  table->subtableZ[x].next = x;
1634  }
1635 
1636  if (yprev != y) {
1637  table->subtableZ[yprev].next = x;
1638  } else {
1639  yprev = x;
1640  }
1641  table->subtableZ[y].next = temp;
1642 
1643  size = cuddZddSwapInPlace(table, x, y);
1644  if (size == 0)
1645  return(0);
1646  y = x;
1647  x--;
1648  } /* while y > gxtop */
1649 
1650  /* Trying to find the next y. */
1651  if (table->subtableZ[y].next <= (unsigned) y) {
1652  gybot = y;
1653  } else {
1654  y = table->subtableZ[y].next;
1655  }
1656 
1657  yprev = gxtop;
1658  gxtop++;
1659  gxbot++;
1660  x = gxbot;
1661  } /* while x <= y, end of group movement backward */
1662 
1663  return(size);
1664 
1665 } /* end of zdd_group_move_backward */
1666 
1667 
1678 static void
1680  DdManager * table,
1681  int lower,
1682  int upper,
1683  int * symvars,
1684  int * symgroups)
1685 {
1686  int i,x,gbot;
1687  int TotalSymm = 0;
1688  int TotalSymmGroups = 0;
1689 
1690  for (i = lower; i <= upper; i++) {
1691  if (table->subtableZ[i].next != (unsigned) i) {
1692  TotalSymmGroups++;
1693  x = i;
1694  do {
1695  TotalSymm++;
1696  gbot = x;
1697  x = table->subtableZ[x].next;
1698  } while (x != i);
1699 #ifdef DD_DEBUG
1700  assert(table->subtableZ[gbot].next == (unsigned) i);
1701 #endif
1702  i = gbot;
1703  }
1704  }
1705  *symvars = TotalSymm;
1706  *symgroups = TotalSymmGroups;
1707 
1708  return;
1709 
1710 } /* end of cuddZddSymmSummary */
1711 
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
static char rcsid [] DD_UNUSED
Definition: cuddZddSymm.c:92
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
int cuddZddSymmCheck(DdManager *table, int x, int y)
Definition: cuddZddSymm.c:193
DdNode * zero
Definition: cuddInt.h:330
double maxGrowth
Definition: cuddInt.h:397
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
int * zdd_entry
Definition: cuddZddReord.c:104
int * permZ
Definition: cuddInt.h:370
int cuddZddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:298
static Move * cuddZddSymmSifting_down(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddZddSymm.c:1346
static int cuddZddSymmSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddZddSymm.c:1437
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
#define NIL(type)
Definition: util.h:44
static DdNode * empty
Definition: cuddZddSymm.c:99
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
void Cudd_zddSymmProfile(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:141
DdHalfWord x
Definition: cuddInt.h:470
DdNode * next
Definition: cudd.h:273
static int zdd_group_move(DdManager *table, int x, int y, Move **moves)
Definition: cuddZddSymm.c:1489
DdNode ** nodelist
Definition: cuddInt.h:311
#define ddMin(x, y)
Definition: cuddInt.h:771
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
long util_cpu_time(void)
Definition: cpu_time.c:34
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int siftMaxVar
Definition: cuddInt.h:395
int cuddZddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:423
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddZddSymm.c:1679
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
#define cuddE(node)
Definition: cuddInt.h:625
struct Move * next
Definition: cuddInt.h:474
#define ZDD_MV_OOM
Definition: cuddZddSymm.c:77
static int result
Definition: cuddGenetic.c:121
static Move * cuddZddSymmSifting_up(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddZddSymm.c:1258
unsigned int keysZ
Definition: cuddInt.h:354
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:609
static int cuddZddSymmSiftingConvAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:949
unsigned long timeLimit
Definition: cuddInt.h:427
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:455
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:431
int size
Definition: cuddInt.h:473
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int zdd_group_move_backward(DdManager *table, int x, int y)
Definition: cuddZddSymm.c:1596
DdSubtable * subtableZ
Definition: cuddInt.h:350