SVF
Functions | Variables
cuddZddGroup.c File Reference
#include "CUDD/util.h"
#include "CUDD/cuddInt.h"

Go to the source code of this file.

Functions

static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper)
 
static int zddUniqueCompareGroup (int *ptrX, int *ptrY)
 
static int zddGroupSifting (DdManager *table, int lower, int upper)
 
static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves)
 
static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves)
 
static int zddGroupMove (DdManager *table, int x, int y, Move **moves)
 
static int zddGroupMoveBackward (DdManager *table, int x, int y)
 
static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size)
 
static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high)
 
MtrNodeCudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
 
int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method)
 

Variables

static char rcsid [] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"
 
static int * entry
 
int zddTotalNumberSwapping
 

Function Documentation

◆ Cudd_MakeZddTreeNode()

MtrNode* Cudd_MakeZddTreeNode ( DdManager dd,
unsigned int  low,
unsigned int  size,
unsigned int  type 
)

AutomaticEnd Function********************************************************************

Synopsis [Creates a new ZDD variable group.]

Description [Creates a new ZDD variable group. The group starts at variable and contains size variables. The parameter low is the index of the first variable. If the variable already exists, its current position in the order is known to the manager. If the variable does not exist yet, the position is assumed to be the same as the index. The group tree is created if it does not exist yet. Returns a pointer to the group if successful; NULL otherwise.]

SideEffects [The ZDD variable tree is changed.]

SeeAlso [Cudd_MakeTreeNode]

Definition at line 159 of file cuddZddGroup.c.

164 {
165  MtrNode *group;
166  MtrNode *tree;
167  unsigned int level;
168 
169  /* If the variable does not exist yet, the position is assumed to be
170  ** the same as the index. Therefore, applications that rely on
171  ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
172  ** variables have to create the variables before they group them.
173  */
174  level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;
175 
176  if (level + size - 1> (int) MTR_MAXHIGH)
177  return(NULL);
178 
179  /* If the tree does not exist yet, create it. */
180  tree = dd->treeZ;
181  if (tree == NULL) {
182  dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ);
183  if (tree == NULL)
184  return(NULL);
185  tree->index = dd->invpermZ[0];
186  }
187 
188  /* Extend the upper bound of the tree if necessary. This allows the
189  ** application to create groups even before the variables are created.
190  */
191  tree->size = ddMax(tree->size, level + size);
192 
193  /* Create the group. */
194  group = Mtr_MakeGroup(tree, level, size, type);
195  if (group == NULL)
196  return(NULL);
197 
198  /* Initialize the index field to the index of the variable currently
199  ** in position low. This field will be updated by the reordering
200  ** procedure to provide a handle to the group once it has been moved.
201  */
202  group->index = (MtrHalfWord) low;
203 
204  return(group);
205 
206 } /* end of Cudd_MakeZddTreeNode */
#define MTR_MAXHIGH
Definition: mtr.h:107
unsigned short MtrHalfWord
Definition: mtr.h:123
MtrHalfWord size
Definition: mtr.h:129
int * invpermZ
Definition: cuddInt.h:372
int * permZ
Definition: cuddInt.h:370
MtrHalfWord index
Definition: mtr.h:130
#define ddMax(x, y)
Definition: cuddInt.h:785
Definition: mtr.h:126
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:120
int sizeZ
Definition: cuddInt.h:346
MtrNode * treeZ
Definition: cuddInt.h:409
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
Definition: mtrGroup.c:156

◆ cuddZddTreeSifting()

int cuddZddTreeSifting ( DdManager table,
Cudd_ReorderingType  method 
)

Function********************************************************************

Synopsis [Tree sifting algorithm for ZDDs.]

Description [Tree sifting algorithm for ZDDs. Assumes that a tree representing a group hierarchy is passed as a parameter. It then reorders each group in postorder fashion by calling zddTreeSiftingAux. Assumes that no dead nodes are present. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 228 of file cuddZddGroup.c.

231 {
232  int i;
233  int nvars;
234  int result;
235  int tempTree;
236 
237  /* If no tree is provided we create a temporary one in which all
238  ** variables are in a single group. After reordering this tree is
239  ** destroyed.
240  */
241  tempTree = table->treeZ == NULL;
242  if (tempTree) {
243  table->treeZ = Mtr_InitGroupTree(0,table->sizeZ);
244  table->treeZ->index = table->invpermZ[0];
245  }
246  nvars = table->sizeZ;
247 
248 #ifdef DD_DEBUG
249  if (pr > 0 && !tempTree)
250  (void) fprintf(table->out,"cuddZddTreeSifting:");
251  Mtr_PrintGroups(table->treeZ,pr <= 0);
252 #endif
253 #if 0
254  /* Debugging code. */
255  if (table->tree && table->treeZ) {
256  (void) fprintf(table->out,"\n");
257  Mtr_PrintGroups(table->tree, 0);
258  cuddPrintVarGroups(table,table->tree,0,0);
259  for (i = 0; i < table->size; i++) {
260  (void) fprintf(table->out,"%s%d",
261  (i == 0) ? "" : ",", table->invperm[i]);
262  }
263  (void) fprintf(table->out,"\n");
264  for (i = 0; i < table->size; i++) {
265  (void) fprintf(table->out,"%s%d",
266  (i == 0) ? "" : ",", table->perm[i]);
267  }
268  (void) fprintf(table->out,"\n\n");
269  Mtr_PrintGroups(table->treeZ,0);
270  cuddPrintVarGroups(table,table->treeZ,1,0);
271  for (i = 0; i < table->sizeZ; i++) {
272  (void) fprintf(table->out,"%s%d",
273  (i == 0) ? "" : ",", table->invpermZ[i]);
274  }
275  (void) fprintf(table->out,"\n");
276  for (i = 0; i < table->sizeZ; i++) {
277  (void) fprintf(table->out,"%s%d",
278  (i == 0) ? "" : ",", table->permZ[i]);
279  }
280  (void) fprintf(table->out,"\n");
281  }
282  /* End of debugging code. */
283 #endif
284 #ifdef DD_STATS
285  extsymmcalls = 0;
286  extsymm = 0;
287  secdiffcalls = 0;
288  secdiff = 0;
289  secdiffmisfire = 0;
290 
291  (void) fprintf(table->out,"\n");
292  if (!tempTree)
293  (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n",
294  zddCountInternalMtrNodes(table,table->treeZ));
295 #endif
296 
297  /* Initialize the group of each subtable to itself. Initially
298  ** there are no groups. Groups are created according to the tree
299  ** structure in postorder fashion.
300  */
301  for (i = 0; i < nvars; i++)
302  table->subtableZ[i].next = i;
303 
304  /* Reorder. */
305  result = zddTreeSiftingAux(table, table->treeZ, method);
306 
307 #ifdef DD_STATS /* print stats */
308  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
309  (table->groupcheck == CUDD_GROUP_CHECK7 ||
310  table->groupcheck == CUDD_GROUP_CHECK5)) {
311  (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
312  (void) fprintf(table->out,"extsymm = %d",extsymm);
313  }
314  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
315  table->groupcheck == CUDD_GROUP_CHECK7) {
316  (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
317  (void) fprintf(table->out,"secdiff = %d\n",secdiff);
318  (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
319  }
320 #endif
321 
322  if (tempTree)
323  Cudd_FreeZddTree(table);
324  return(result);
325 
326 } /* end of cuddZddTreeSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
int * permZ
Definition: cuddInt.h:370
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddCheck.c:749
MtrNode * tree
Definition: cuddInt.h:408
MtrHalfWord index
Definition: mtr.h:130
FILE * out
Definition: cuddInt.h:423
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:595
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:120
int sizeZ
Definition: cuddInt.h:346
unsigned int next
Definition: cuddInt.h:317
MtrNode * treeZ
Definition: cuddInt.h:409
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:345
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
void Cudd_FreeZddTree(DdManager *dd)
Definition: cuddAPI.c:2534
int * perm
Definition: cuddInt.h:369
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddFindNodeHiLo()

static void zddFindNodeHiLo ( DdManager table,
MtrNode treenode,
int *  lower,
int *  upper 
)
static

Function********************************************************************

Synopsis [Finds the lower and upper bounds of the group represented by treenode.]

Description [Finds the lower and upper bounds of the group represented by treenode. The high and low fields of treenode are indices. From those we need to derive the current positions, and find maximum and minimum.]

SideEffects [The bounds are returned as side effects.]

SeeAlso []

Definition at line 530 of file cuddZddGroup.c.

535 {
536  int low;
537  int high;
538 
539  /* Check whether no variables in this group already exist.
540  ** If so, return immediately. The calling procedure will know from
541  ** the values of upper that no reordering is needed.
542  */
543  if ((int) treenode->low >= table->sizeZ) {
544  *lower = table->sizeZ;
545  *upper = -1;
546  return;
547  }
548 
549  *lower = low = (unsigned int) table->permZ[treenode->index];
550  high = (int) (low + treenode->size - 1);
551 
552  if (high >= table->sizeZ) {
553  /* This is the case of a partially existing group. The aim is to
554  ** reorder as many variables as safely possible. If the tree
555  ** node is terminal, we just reorder the subset of the group
556  ** that is currently in existence. If the group has
557  ** subgroups, then we only reorder those subgroups that are
558  ** fully instantiated. This way we avoid breaking up a group.
559  */
560  MtrNode *auxnode = treenode->child;
561  if (auxnode == NULL) {
562  *upper = (unsigned int) table->sizeZ - 1;
563  } else {
564  /* Search the subgroup that strands the table->sizeZ line.
565  ** If the first group starts at 0 and goes past table->sizeZ
566  ** upper will get -1, thus correctly signaling that no reordering
567  ** should take place.
568  */
569  while (auxnode != NULL) {
570  int thisLower = table->permZ[auxnode->low];
571  int thisUpper = thisLower + auxnode->size - 1;
572  if (thisUpper >= table->sizeZ && thisLower < table->sizeZ)
573  *upper = (unsigned int) thisLower - 1;
574  auxnode = auxnode->younger;
575  }
576  }
577  } else {
578  /* Normal case: All the variables of the group exist. */
579  *upper = (unsigned int) high;
580  }
581 
582 #ifdef DD_DEBUG
583  /* Make sure that all variables in group are contiguous. */
584  assert(treenode->size >= *upper - *lower + 1);
585 #endif
586 
587  return;
588 
589 } /* end of zddFindNodeHiLo */
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
int * permZ
Definition: cuddInt.h:370
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
int sizeZ
Definition: cuddInt.h:346
struct MtrNode * child
Definition: mtr.h:132

◆ zddGroupMove()

static int zddGroupMove ( DdManager table,
int  x,
int  y,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Swaps two groups and records the move.]

Description [Swaps two groups and records the move. Returns the number of keys in the DD table in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 1078 of file cuddZddGroup.c.

1083 {
1084  Move *move;
1085  int size;
1086  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1087  int swapx,swapy;
1088 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1089  int initialSize,bestSize;
1090 #endif
1091 
1092 #ifdef DD_DEBUG
1093  /* We assume that x < y */
1094  assert(x < y);
1095 #endif
1096  /* Find top, bottom, and size for the two groups. */
1097  xbot = x;
1098  xtop = table->subtableZ[x].next;
1099  xsize = xbot - xtop + 1;
1100  ybot = y;
1101  while ((unsigned) ybot < table->subtableZ[ybot].next)
1102  ybot = table->subtableZ[ybot].next;
1103  ytop = y;
1104  ysize = ybot - ytop + 1;
1105 
1106 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1107  initialSize = bestSize = table->keysZ;
1108 #endif
1109  /* Sift the variables of the second group up through the first group */
1110  for (i = 1; i <= ysize; i++) {
1111  for (j = 1; j <= xsize; j++) {
1112  size = cuddZddSwapInPlace(table,x,y);
1113  if (size == 0) goto zddGroupMoveOutOfMem;
1114 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1115  if (size < bestSize)
1116  bestSize = size;
1117 #endif
1118  swapx = x; swapy = y;
1119  y = x;
1120  x = cuddZddNextLow(table,y);
1121  }
1122  y = ytop + i;
1123  x = cuddZddNextLow(table,y);
1124  }
1125 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1126  if ((bestSize < initialSize) && (bestSize < size))
1127  (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size);
1128 #endif
1129 
1130  /* fix groups */
1131  y = xtop; /* ytop is now where xtop used to be */
1132  for (i = 0; i < ysize - 1; i++) {
1133  table->subtableZ[y].next = cuddZddNextHigh(table,y);
1134  y = cuddZddNextHigh(table,y);
1135  }
1136  table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
1137  /* it to top of its group */
1138  x = cuddZddNextHigh(table,y);
1139  newxtop = x;
1140  for (i = 0; i < xsize - 1; i++) {
1141  table->subtableZ[x].next = cuddZddNextHigh(table,x);
1142  x = cuddZddNextHigh(table,x);
1143  }
1144  table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
1145  /* it to top of its group */
1146 #ifdef DD_DEBUG
1147  if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n");
1148 #endif
1149 
1150  /* Store group move */
1151  move = (Move *) cuddDynamicAllocNode(table);
1152  if (move == NULL) goto zddGroupMoveOutOfMem;
1153  move->x = swapx;
1154  move->y = swapy;
1155  move->flags = MTR_DEFAULT;
1156  move->size = table->keysZ;
1157  move->next = *moves;
1158  *moves = move;
1159 
1160  return(table->keysZ);
1161 
1162 zddGroupMoveOutOfMem:
1163  while (*moves != NULL) {
1164  move = (*moves)->next;
1165  cuddDeallocMove(table, *moves);
1166  *moves = move;
1167  }
1168  return(0);
1169 
1170 } /* end of zddGroupMove */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:431
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupMoveBackward()

static int zddGroupMoveBackward ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Undoes the swap two groups.]

Description [Undoes the swap two groups. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 1184 of file cuddZddGroup.c.

1188 {
1189  int size;
1190  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1191 
1192 
1193 #ifdef DD_DEBUG
1194  /* We assume that x < y */
1195  assert(x < y);
1196 #endif
1197 
1198  /* Find top, bottom, and size for the two groups. */
1199  xbot = x;
1200  xtop = table->subtableZ[x].next;
1201  xsize = xbot - xtop + 1;
1202  ybot = y;
1203  while ((unsigned) ybot < table->subtableZ[ybot].next)
1204  ybot = table->subtableZ[ybot].next;
1205  ytop = y;
1206  ysize = ybot - ytop + 1;
1207 
1208  /* Sift the variables of the second group up through the first group */
1209  for (i = 1; i <= ysize; i++) {
1210  for (j = 1; j <= xsize; j++) {
1211  size = cuddZddSwapInPlace(table,x,y);
1212  if (size == 0)
1213  return(0);
1214  y = x;
1215  x = cuddZddNextLow(table,y);
1216  }
1217  y = ytop + i;
1218  x = cuddZddNextLow(table,y);
1219  }
1220 
1221  /* fix groups */
1222  y = xtop;
1223  for (i = 0; i < ysize - 1; i++) {
1224  table->subtableZ[y].next = cuddZddNextHigh(table,y);
1225  y = cuddZddNextHigh(table,y);
1226  }
1227  table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
1228  /* to its top */
1229  x = cuddZddNextHigh(table,y);
1230  newxtop = x;
1231  for (i = 0; i < xsize - 1; i++) {
1232  table->subtableZ[x].next = cuddZddNextHigh(table,x);
1233  x = cuddZddNextHigh(table,x);
1234  }
1235  table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
1236  /* to its top */
1237 #ifdef DD_DEBUG
1238  if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n");
1239 #endif
1240 
1241  return(1);
1242 
1243 } /* end of zddGroupMoveBackward */
#define assert(ex)
Definition: util.h:141
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
FILE * out
Definition: cuddInt.h:423
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
unsigned int next
Definition: cuddInt.h:317
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:431
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSifting()

static int zddGroupSifting ( DdManager table,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Sifts from treenode->low to treenode->high.]

Description [Sifts from treenode->low to treenode->high. If croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the end of the initial sifting. If a group is created, it is then sifted again. After sifting one variable, the group that contains it is dissolved. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 633 of file cuddZddGroup.c.

637 {
638  int *var;
639  int i,j,x,xInit;
640  int nvars;
641  int classes;
642  int result;
643  int *sifted;
644 #ifdef DD_STATS
645  unsigned previousSize;
646 #endif
647  int xindex;
648 
649  nvars = table->sizeZ;
650 
651  /* Order variables to sift. */
652  entry = NULL;
653  sifted = NULL;
654  var = ALLOC(int,nvars);
655  if (var == NULL) {
656  table->errorCode = CUDD_MEMORY_OUT;
657  goto zddGroupSiftingOutOfMem;
658  }
659  entry = ALLOC(int,nvars);
660  if (entry == NULL) {
661  table->errorCode = CUDD_MEMORY_OUT;
662  goto zddGroupSiftingOutOfMem;
663  }
664  sifted = ALLOC(int,nvars);
665  if (sifted == NULL) {
666  table->errorCode = CUDD_MEMORY_OUT;
667  goto zddGroupSiftingOutOfMem;
668  }
669 
670  /* Here we consider only one representative for each group. */
671  for (i = 0, classes = 0; i < nvars; i++) {
672  sifted[i] = 0;
673  x = table->permZ[i];
674  if ((unsigned) x >= table->subtableZ[x].next) {
675  entry[i] = table->subtableZ[x].keys;
676  var[classes] = i;
677  classes++;
678  }
679  }
680 
681  qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup);
682 
683  /* Now sift. */
684  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
685  if (zddTotalNumberSwapping >= table->siftMaxSwap)
686  break;
687  if (util_cpu_time() - table->startTime > table->timeLimit) {
688  table->autoDynZ = 0; /* prevent further reordering */
689  break;
690  }
691  xindex = var[i];
692  if (sifted[xindex] == 1) /* variable already sifted as part of group */
693  continue;
694  x = table->permZ[xindex]; /* find current level of this variable */
695  if (x < lower || x > upper)
696  continue;
697 #ifdef DD_STATS
698  previousSize = table->keysZ;
699 #endif
700 #ifdef DD_DEBUG
701  /* x is bottom of group */
702  assert((unsigned) x >= table->subtableZ[x].next);
703 #endif
704  result = zddGroupSiftingAux(table,x,lower,upper);
705  if (!result) goto zddGroupSiftingOutOfMem;
706 
707 #ifdef DD_STATS
708  if (table->keysZ < previousSize) {
709  (void) fprintf(table->out,"-");
710  } else if (table->keysZ > previousSize) {
711  (void) fprintf(table->out,"+");
712  } else {
713  (void) fprintf(table->out,"=");
714  }
715  fflush(table->out);
716 #endif
717 
718  /* Mark variables in the group just sifted. */
719  x = table->permZ[xindex];
720  if ((unsigned) x != table->subtableZ[x].next) {
721  xInit = x;
722  do {
723  j = table->invpermZ[x];
724  sifted[j] = 1;
725  x = table->subtableZ[x].next;
726  } while (x != xInit);
727  }
728 
729 #ifdef DD_DEBUG
730  if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:");
731 #endif
732  } /* for */
733 
734  FREE(sifted);
735  FREE(var);
736  FREE(entry);
737 
738  return(1);
739 
740 zddGroupSiftingOutOfMem:
741  if (entry != NULL) FREE(entry);
742  if (var != NULL) FREE(var);
743  if (sifted != NULL) FREE(sifted);
744 
745  return(0);
746 
747 } /* end of zddGroupSifting */
unsigned int keys
Definition: cuddInt.h:314
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
#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
static int * entry
Definition: cuddZddGroup.c:93
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int zddUniqueCompareGroup(int *ptrX, int *ptrY)
Definition: cuddZddGroup.c:605
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int zddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddGroup.c:766
int sizeZ
Definition: cuddInt.h:346
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingAux()

static int zddGroupSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Sifts one variable up and down until it has taken all positions. Checks for aggregation.]

Description [Sifts one variable up and down until it has taken all positions. Checks for aggregation. There may be at most two sweeps, even if the group grows. Assumes that x is either an isolated variable, or it is the bottom of a group. All groups may not have been found. The variable being moved is returned to the best position seen during sifting. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 766 of file cuddZddGroup.c.

771 {
772  Move *move;
773  Move *moves; /* list of moves */
774  int initialSize;
775  int result;
776 
777 
778 #ifdef DD_DEBUG
779  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh);
780  assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */
781 #endif
782 
783  initialSize = table->keysZ;
784  moves = NULL;
785 
786  if (x == xLow) { /* Sift down */
787 #ifdef DD_DEBUG
788  /* x must be a singleton */
789  assert((unsigned) x == table->subtableZ[x].next);
790 #endif
791  if (x == xHigh) return(1); /* just one variable */
792 
793  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
794  goto zddGroupSiftingAuxOutOfMem;
795  /* at this point x == xHigh, unless early term */
796 
797  /* move backward and stop at best position */
798  result = zddGroupSiftingBackward(table,moves,initialSize);
799 #ifdef DD_DEBUG
800  assert(table->keysZ <= (unsigned) initialSize);
801 #endif
802  if (!result) goto zddGroupSiftingAuxOutOfMem;
803 
804  } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */
805 #ifdef DD_DEBUG
806  /* x is bottom of group */
807  assert((unsigned) x >= table->subtableZ[x].next);
808 #endif
809  /* Find top of x's group */
810  x = table->subtableZ[x].next;
811 
812  if (!zddGroupSiftingUp(table,x,xLow,&moves))
813  goto zddGroupSiftingAuxOutOfMem;
814  /* at this point x == xLow, unless early term */
815 
816  /* move backward and stop at best position */
817  result = zddGroupSiftingBackward(table,moves,initialSize);
818 #ifdef DD_DEBUG
819  assert(table->keysZ <= (unsigned) initialSize);
820 #endif
821  if (!result) goto zddGroupSiftingAuxOutOfMem;
822 
823  } else if (x - xLow > xHigh - x) { /* must go down first: shorter */
824  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
825  goto zddGroupSiftingAuxOutOfMem;
826  /* at this point x == xHigh, unless early term */
827 
828  /* Find top of group */
829  if (moves) {
830  x = moves->y;
831  }
832  while ((unsigned) x < table->subtableZ[x].next)
833  x = table->subtableZ[x].next;
834  x = table->subtableZ[x].next;
835 #ifdef DD_DEBUG
836  /* x should be the top of a group */
837  assert((unsigned) x <= table->subtableZ[x].next);
838 #endif
839 
840  if (!zddGroupSiftingUp(table,x,xLow,&moves))
841  goto zddGroupSiftingAuxOutOfMem;
842 
843  /* move backward and stop at best position */
844  result = zddGroupSiftingBackward(table,moves,initialSize);
845 #ifdef DD_DEBUG
846  assert(table->keysZ <= (unsigned) initialSize);
847 #endif
848  if (!result) goto zddGroupSiftingAuxOutOfMem;
849 
850  } else { /* moving up first: shorter */
851  /* Find top of x's group */
852  x = table->subtableZ[x].next;
853 
854  if (!zddGroupSiftingUp(table,x,xLow,&moves))
855  goto zddGroupSiftingAuxOutOfMem;
856  /* at this point x == xHigh, unless early term */
857 
858  if (moves) {
859  x = moves->x;
860  }
861  while ((unsigned) x < table->subtableZ[x].next)
862  x = table->subtableZ[x].next;
863 #ifdef DD_DEBUG
864  /* x is bottom of a group */
865  assert((unsigned) x >= table->subtableZ[x].next);
866 #endif
867 
868  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
869  goto zddGroupSiftingAuxOutOfMem;
870 
871  /* move backward and stop at best position */
872  result = zddGroupSiftingBackward(table,moves,initialSize);
873 #ifdef DD_DEBUG
874  assert(table->keysZ <= (unsigned) initialSize);
875 #endif
876  if (!result) goto zddGroupSiftingAuxOutOfMem;
877  }
878 
879  while (moves != NULL) {
880  move = moves->next;
881  cuddDeallocMove(table, moves);
882  moves = move;
883  }
884 
885  return(1);
886 
887 zddGroupSiftingAuxOutOfMem:
888  while (moves != NULL) {
889  move = moves->next;
890  cuddDeallocMove(table, moves);
891  moves = move;
892  }
893 
894  return(0);
895 
896 } /* end of zddGroupSiftingAux */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static int zddGroupSiftingUp(DdManager *table, int y, int xLow, Move **moves)
Definition: cuddZddGroup.c:915
static int zddGroupSiftingBackward(DdManager *table, Move *moves, int size)
FILE * out
Definition: cuddInt.h:423
DdHalfWord x
Definition: cuddInt.h:470
static int zddGroupSiftingDown(DdManager *table, int x, int xHigh, Move **moves)
Definition: cuddZddGroup.c:992
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingBackward()

static int zddGroupSiftingBackward ( DdManager table,
Move moves,
int  size 
)
static

Function********************************************************************

Synopsis [Determines the best position for a variables and returns it there.]

Description [Determines the best position for a variables and returns it there. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 1258 of file cuddZddGroup.c.

1262 {
1263  Move *move;
1264  int res;
1265 
1266 
1267  for (move = moves; move != NULL; move = move->next) {
1268  if (move->size < size) {
1269  size = move->size;
1270  }
1271  }
1272 
1273  for (move = moves; move != NULL; move = move->next) {
1274  if (move->size == size) return(1);
1275  if ((table->subtableZ[move->x].next == move->x) &&
1276  (table->subtableZ[move->y].next == move->y)) {
1277  res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
1278  if (!res) return(0);
1279 #ifdef DD_DEBUG
1280  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n");
1281  assert(table->subtableZ[move->x].next == move->x);
1282  assert(table->subtableZ[move->y].next == move->y);
1283 #endif
1284  } else { /* Group move necessary */
1285  res = zddGroupMoveBackward(table,(int)move->x,(int)move->y);
1286  if (!res) return(0);
1287  }
1288  }
1289 
1290  return(1);
1291 
1292 } /* end of zddGroupSiftingBackward */
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
FILE * out
Definition: cuddInt.h:423
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
static int zddGroupMoveBackward(DdManager *table, int x, int y)
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingDown()

static int zddGroupSiftingDown ( DdManager table,
int  x,
int  xHigh,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts down a variable until it reaches position xHigh.]

Description [Sifts down a variable until it reaches position xHigh. Assumes that x is the bottom of a group (or a singleton). Records all the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 992 of file cuddZddGroup.c.

997 {
998  Move *move;
999  int y;
1000  int size;
1001  int limitSize;
1002  int gybot;
1003 
1004 
1005  /* Initialize R */
1006  limitSize = size = table->keysZ;
1007  y = cuddZddNextHigh(table,x);
1008  while (y <= xHigh) {
1009  /* Find bottom of y group. */
1010  gybot = table->subtableZ[y].next;
1011  while (table->subtableZ[gybot].next != (unsigned) y)
1012  gybot = table->subtableZ[gybot].next;
1013 
1014  if (table->subtableZ[x].next == (unsigned) x &&
1015  table->subtableZ[y].next == (unsigned) y) {
1016  /* x and y are self groups */
1017  size = cuddZddSwapInPlace(table,x,y);
1018 #ifdef DD_DEBUG
1019  assert(table->subtableZ[x].next == (unsigned) x);
1020  assert(table->subtableZ[y].next == (unsigned) y);
1021 #endif
1022  if (size == 0) goto zddGroupSiftingDownOutOfMem;
1023 
1024  /* Record move. */
1025  move = (Move *) cuddDynamicAllocNode(table);
1026  if (move == NULL) goto zddGroupSiftingDownOutOfMem;
1027  move->x = x;
1028  move->y = y;
1029  move->flags = MTR_DEFAULT;
1030  move->size = size;
1031  move->next = *moves;
1032  *moves = move;
1033 
1034 #ifdef DD_DEBUG
1035  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n");
1036 #endif
1037  if ((double) size > (double) limitSize * table->maxGrowth)
1038  return(1);
1039  if (size < limitSize) limitSize = size;
1040  x = y;
1041  y = cuddZddNextHigh(table,x);
1042  } else { /* Group move */
1043  size = zddGroupMove(table,x,y,moves);
1044  if (size == 0) goto zddGroupSiftingDownOutOfMem;
1045  if ((double) size > (double) limitSize * table->maxGrowth)
1046  return(1);
1047  if (size < limitSize) limitSize = size;
1048  }
1049  x = gybot;
1050  y = cuddZddNextHigh(table,x);
1051  }
1052 
1053  return(1);
1054 
1055 zddGroupSiftingDownOutOfMem:
1056  while (*moves != NULL) {
1057  move = (*moves)->next;
1058  cuddDeallocMove(table, *moves);
1059  *moves = move;
1060  }
1061 
1062  return(0);
1063 
1064 } /* end of zddGroupSiftingDown */
static int zddGroupMove(DdManager *table, int x, int y, Move **moves)
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
double maxGrowth
Definition: cuddInt.h:397
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingUp()

static int zddGroupSiftingUp ( DdManager table,
int  y,
int  xLow,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much.]

Description [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much. Assumes that y is the top of a group (or a singleton). Checks y for aggregation to the adjacent variables. Records all the moves that are appended to the list of moves received as input and returned as a side effect. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 915 of file cuddZddGroup.c.

920 {
921  Move *move;
922  int x;
923  int size;
924  int gxtop;
925  int limitSize;
926 
927  limitSize = table->keysZ;
928 
929  x = cuddZddNextLow(table,y);
930  while (x >= xLow) {
931  gxtop = table->subtableZ[x].next;
932  if (table->subtableZ[x].next == (unsigned) x &&
933  table->subtableZ[y].next == (unsigned) y) {
934  /* x and y are self groups */
935  size = cuddZddSwapInPlace(table,x,y);
936 #ifdef DD_DEBUG
937  assert(table->subtableZ[x].next == (unsigned) x);
938  assert(table->subtableZ[y].next == (unsigned) y);
939 #endif
940  if (size == 0) goto zddGroupSiftingUpOutOfMem;
941  move = (Move *)cuddDynamicAllocNode(table);
942  if (move == NULL) goto zddGroupSiftingUpOutOfMem;
943  move->x = x;
944  move->y = y;
945  move->flags = MTR_DEFAULT;
946  move->size = size;
947  move->next = *moves;
948  *moves = move;
949 
950 #ifdef DD_DEBUG
951  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n");
952 #endif
953  if ((double) size > (double) limitSize * table->maxGrowth)
954  return(1);
955  if (size < limitSize) limitSize = size;
956  } else { /* group move */
957  size = zddGroupMove(table,x,y,moves);
958  if (size == 0) goto zddGroupSiftingUpOutOfMem;
959  if ((double) size > (double) limitSize * table->maxGrowth)
960  return(1);
961  if (size < limitSize) limitSize = size;
962  }
963  y = gxtop;
964  x = cuddZddNextLow(table,y);
965  }
966 
967  return(1);
968 
969 zddGroupSiftingUpOutOfMem:
970  while (*moves != NULL) {
971  move = (*moves)->next;
972  cuddDeallocMove(table, *moves);
973  *moves = move;
974  }
975  return(0);
976 
977 } /* end of zddGroupSiftingUp */
static int zddGroupMove(DdManager *table, int x, int y, Move **moves)
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
double maxGrowth
Definition: cuddInt.h:397
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:480
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:431
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddMergeGroups()

static void zddMergeGroups ( DdManager table,
MtrNode treenode,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Merges groups in the DD table.]

Description [Creates a single group from low to high and adjusts the idex field of the tree node.]

SideEffects [None]

Definition at line 1306 of file cuddZddGroup.c.

1311 {
1312  int i;
1313  MtrNode *auxnode;
1314  int saveindex;
1315  int newindex;
1316 
1317  /* Merge all variables from low to high in one group, unless
1318  ** this is the topmost group. In such a case we do not merge lest
1319  ** we lose the symmetry information. */
1320  if (treenode != table->treeZ) {
1321  for (i = low; i < high; i++)
1322  table->subtableZ[i].next = i+1;
1323  table->subtableZ[high].next = low;
1324  }
1325 
1326  /* Adjust the index fields of the tree nodes. If a node is the
1327  ** first child of its parent, then the parent may also need adjustment. */
1328  saveindex = treenode->index;
1329  newindex = table->invpermZ[low];
1330  auxnode = treenode;
1331  do {
1332  auxnode->index = newindex;
1333  if (auxnode->parent == NULL ||
1334  (int) auxnode->parent->index != saveindex)
1335  break;
1336  auxnode = auxnode->parent;
1337  } while (1);
1338  return;
1339 
1340 } /* end of zddMergeGroups */
int * invpermZ
Definition: cuddInt.h:372
struct MtrNode * parent
Definition: mtr.h:131
MtrHalfWord index
Definition: mtr.h:130
Definition: mtr.h:126
unsigned int next
Definition: cuddInt.h:317
MtrNode * treeZ
Definition: cuddInt.h:409
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddReorderChildren()

static int zddReorderChildren ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

Function********************************************************************

Synopsis [Reorders the children of a group tree node according to the options.]

Description [Reorders the children of a group tree node according to the options. After reordering puts all the variables in the group and/or its descendents in a single group. This allows hierarchical reordering. If the variables in the group do not exist yet, simply does nothing. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 429 of file cuddZddGroup.c.

433 {
434  int lower;
435  int upper;
436  int result;
437  unsigned int initialSize;
438 
439  zddFindNodeHiLo(table,treenode,&lower,&upper);
440  /* If upper == -1 these variables do not exist yet. */
441  if (upper == -1)
442  return(1);
443 
444  if (treenode->flags == MTR_FIXED) {
445  result = 1;
446  } else {
447 #ifdef DD_STATS
448  (void) fprintf(table->out," ");
449 #endif
450  switch (method) {
451  case CUDD_REORDER_RANDOM:
453  result = cuddZddSwapping(table,lower,upper,method);
454  break;
455  case CUDD_REORDER_SIFT:
456  result = cuddZddSifting(table,lower,upper);
457  break;
459  do {
460  initialSize = table->keysZ;
461  result = cuddZddSifting(table,lower,upper);
462  if (initialSize <= table->keysZ)
463  break;
464 #ifdef DD_STATS
465  else
466  (void) fprintf(table->out,"\n");
467 #endif
468  } while (result != 0);
469  break;
471  result = cuddZddSymmSifting(table,lower,upper);
472  break;
474  result = cuddZddSymmSiftingConv(table,lower,upper);
475  break;
477  result = zddGroupSifting(table,lower,upper);
478  break;
479  case CUDD_REORDER_LINEAR:
480  result = cuddZddLinearSifting(table,lower,upper);
481  break;
483  do {
484  initialSize = table->keysZ;
485  result = cuddZddLinearSifting(table,lower,upper);
486  if (initialSize <= table->keysZ)
487  break;
488 #ifdef DD_STATS
489  else
490  (void) fprintf(table->out,"\n");
491 #endif
492  } while (result != 0);
493  break;
494  default:
495  return(0);
496  }
497  }
498 
499  /* Create a single group for all the variables that were sifted,
500  ** so that they will be treated as a single block by successive
501  ** invocations of zddGroupSifting.
502  */
503  zddMergeGroups(table,treenode,lower,upper);
504 
505 #ifdef DD_DEBUG
506  if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:");
507 #endif
508 
509  return(result);
510 
511 } /* end of zddReorderChildren */
MtrHalfWord flags
Definition: mtr.h:127
static int zddGroupSifting(DdManager *table, int lower, int upper)
Definition: cuddZddGroup.c:633
#define MTR_FIXED
Definition: mtr.h:97
static void zddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
Definition: cuddZddGroup.c:530
int cuddZddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:423
int cuddZddLinearSifting(DdManager *table, int lower, int upper)
Definition: cuddZddLin.c:152
FILE * out
Definition: cuddInt.h:423
int cuddZddSifting(DdManager *table, int lower, int upper)
Definition: cuddZddReord.c:863
int cuddZddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:298
int cuddZddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
Definition: cuddZddReord.c:742
static int result
Definition: cuddGenetic.c:121
static void zddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
unsigned int keysZ
Definition: cuddInt.h:354

◆ zddTreeSiftingAux()

static int zddTreeSiftingAux ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Visits the group tree and reorders each group.]

Description [Recursively visits the group tree and reorders each group in postorder fashion. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 345 of file cuddZddGroup.c.

349 {
350  MtrNode *auxnode;
351  int res;
352 
353 #ifdef DD_DEBUG
354  Mtr_PrintGroups(treenode,1);
355 #endif
356 
357  auxnode = treenode;
358  while (auxnode != NULL) {
359  if (auxnode->child != NULL) {
360  if (!zddTreeSiftingAux(table, auxnode->child, method))
361  return(0);
362  res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT);
363  if (res == 0)
364  return(0);
365  } else if (auxnode->size > 1) {
366  if (!zddReorderChildren(table, auxnode, method))
367  return(0);
368  }
369  auxnode = auxnode->younger;
370  }
371 
372  return(1);
373 
374 } /* end of zddTreeSiftingAux */
MtrHalfWord size
Definition: mtr.h:129
static int zddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:429
struct MtrNode * younger
Definition: mtr.h:134
Definition: mtr.h:126
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:595
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:345
struct MtrNode * child
Definition: mtr.h:132

◆ zddUniqueCompareGroup()

static int zddUniqueCompareGroup ( int *  ptrX,
int *  ptrY 
)
static

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 605 of file cuddZddGroup.c.

608 {
609 #if 0
610  if (entry[*ptrY] == entry[*ptrX]) {
611  return((*ptrX) - (*ptrY));
612  }
613 #endif
614  return(entry[*ptrY] - entry[*ptrX]);
615 
616 } /* end of zddUniqueCompareGroup */
static int * entry
Definition: cuddZddGroup.c:93

Variable Documentation

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"
static

CFile***********************************************************************

FileName [cuddZddGroup.c]

PackageName [cudd]

Synopsis [Functions for ZDD group sifting.]

Description [External procedures included in this file:

Internal procedures included in this file:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 90 of file cuddZddGroup.c.

◆ entry

int* entry
static

Definition at line 93 of file cuddZddGroup.c.

◆ zddTotalNumberSwapping

int zddTotalNumberSwapping

Definition at line 106 of file cuddZddReord.c.