abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddZddGroup.c File Reference
#include "misc/util/util_hack.h"
#include "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
ABC_NAMESPACE_IMPL_START char
rcsid[] 
DD_UNUSED = "$Id: cuddZddGroup.c,v 1.20 2009/02/19 16:25:36 fabio Exp $"
 
static int * entry
 
int zddTotalNumberSwapping
 

Function Documentation

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 163 of file cuddZddGroup.c.

168 {
169  MtrNode *group;
170  MtrNode *tree;
171  unsigned int level;
172 
173  /* If the variable does not exist yet, the position is assumed to be
174  ** the same as the index. Therefore, applications that rely on
175  ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
176  ** variables have to create the variables before they group them.
177  */
178  level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;
179 
180  if (level + size - 1> (int) MTR_MAXHIGH)
181  return(NULL);
182 
183  /* If the tree does not exist yet, create it. */
184  tree = dd->treeZ;
185  if (tree == NULL) {
186  dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ);
187  if (tree == NULL)
188  return(NULL);
189  tree->index = dd->invpermZ[0];
190  }
191 
192  /* Extend the upper bound of the tree if necessary. This allows the
193  ** application to create groups even before the variables are created.
194  */
195  tree->size = ddMax(tree->size, level + size);
196 
197  /* Create the group. */
198  group = Mtr_MakeGroup(tree, level, size, type);
199  if (group == NULL)
200  return(NULL);
201 
202  /* Initialize the index field to the index of the variable currently
203  ** in position low. This field will be updated by the reordering
204  ** procedure to provide a handle to the group once it has been moved.
205  */
206  group->index = (MtrHalfWord) low;
207 
208  return(group);
209 
210 } /* end of Cudd_MakeZddTreeNode */
#define MTR_MAXHIGH
Definition: mtr.h:112
unsigned short MtrHalfWord
Definition: mtr.h:128
MtrHalfWord size
Definition: mtr.h:134
int * invpermZ
Definition: cuddInt.h:389
int * permZ
Definition: cuddInt.h:387
MtrHalfWord index
Definition: mtr.h:135
#define ddMax(x, y)
Definition: cuddInt.h:832
static int size
Definition: cuddSign.c:86
Definition: mtr.h:131
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:121
int sizeZ
Definition: cuddInt.h:362
MtrNode * treeZ
Definition: cuddInt.h:425
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
Definition: mtrGroup.c:158
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 232 of file cuddZddGroup.c.

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

539 {
540  int low;
541  int high;
542 
543  /* Check whether no variables in this group already exist.
544  ** If so, return immediately. The calling procedure will know from
545  ** the values of upper that no reordering is needed.
546  */
547  if ((int) treenode->low >= table->sizeZ) {
548  *lower = table->sizeZ;
549  *upper = -1;
550  return;
551  }
552 
553  *lower = low = (unsigned int) table->permZ[treenode->index];
554  high = (int) (low + treenode->size - 1);
555 
556  if (high >= table->sizeZ) {
557  /* This is the case of a partially existing group. The aim is to
558  ** reorder as many variables as safely possible. If the tree
559  ** node is terminal, we just reorder the subset of the group
560  ** that is currently in existence. If the group has
561  ** subgroups, then we only reorder those subgroups that are
562  ** fully instantiated. This way we avoid breaking up a group.
563  */
564  MtrNode *auxnode = treenode->child;
565  if (auxnode == NULL) {
566  *upper = (unsigned int) table->sizeZ - 1;
567  } else {
568  /* Search the subgroup that strands the table->sizeZ line.
569  ** If the first group starts at 0 and goes past table->sizeZ
570  ** upper will get -1, thus correctly signaling that no reordering
571  ** should take place.
572  */
573  while (auxnode != NULL) {
574  int thisLower = table->permZ[auxnode->low];
575  int thisUpper = thisLower + auxnode->size - 1;
576  if (thisUpper >= table->sizeZ && thisLower < table->sizeZ)
577  *upper = (unsigned int) thisLower - 1;
578  auxnode = auxnode->younger;
579  }
580  }
581  } else {
582  /* Normal case: All the variables of the group exist. */
583  *upper = (unsigned int) high;
584  }
585 
586 #ifdef DD_DEBUG
587  /* Make sure that all variables in group are contiguous. */
588  assert(treenode->size >= *upper - *lower + 1);
589 #endif
590 
591  return;
592 
593 } /* end of zddFindNodeHiLo */
MtrHalfWord size
Definition: mtr.h:134
int * permZ
Definition: cuddInt.h:387
struct MtrNode * younger
Definition: mtr.h:139
MtrHalfWord index
Definition: mtr.h:135
MtrHalfWord low
Definition: mtr.h:133
Definition: mtr.h:131
int sizeZ
Definition: cuddInt.h:362
#define assert(ex)
Definition: util_old.h:213
struct MtrNode * child
Definition: mtr.h:137
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=-1,swapy=-1;
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:564
Definition: cuddInt.h:492
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
#define MTR_DEFAULT
Definition: mtr.h:99
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
unsigned int keysZ
Definition: cuddInt.h:370
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:435
int size
Definition: cuddInt.h:496
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 */
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
FILE * out
Definition: cuddInt.h:441
static int size
Definition: cuddSign.c:86
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
unsigned int next
Definition: cuddInt.h:333
#define assert(ex)
Definition: util_old.h:213
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:435
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 637 of file cuddZddGroup.c.

641 {
642  int *var;
643  int i,j,x,xInit;
644  int nvars;
645  int classes;
646  int result;
647  int *sifted;
648 #ifdef DD_STATS
649  unsigned previousSize;
650 #endif
651  int xindex;
652 
653  nvars = table->sizeZ;
654 
655  /* Order variables to sift. */
656  entry = NULL;
657  sifted = NULL;
658  var = ABC_ALLOC(int,nvars);
659  if (var == NULL) {
660  table->errorCode = CUDD_MEMORY_OUT;
661  goto zddGroupSiftingOutOfMem;
662  }
663  entry = ABC_ALLOC(int,nvars);
664  if (entry == NULL) {
665  table->errorCode = CUDD_MEMORY_OUT;
666  goto zddGroupSiftingOutOfMem;
667  }
668  sifted = ABC_ALLOC(int,nvars);
669  if (sifted == NULL) {
670  table->errorCode = CUDD_MEMORY_OUT;
671  goto zddGroupSiftingOutOfMem;
672  }
673 
674  /* Here we consider only one representative for each group. */
675  for (i = 0, classes = 0; i < nvars; i++) {
676  sifted[i] = 0;
677  x = table->permZ[i];
678  if ((unsigned) x >= table->subtableZ[x].next) {
679  entry[i] = table->subtableZ[x].keys;
680  var[classes] = i;
681  classes++;
682  }
683  }
684 
685  qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup);
686 
687  /* Now sift. */
688  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
689  if (zddTotalNumberSwapping >= table->siftMaxSwap)
690  break;
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  ABC_FREE(sifted);
735  ABC_FREE(var);
736  ABC_FREE(entry);
737 
738  return(1);
739 
740 zddGroupSiftingOutOfMem:
741  if (entry != NULL) ABC_FREE(entry);
742  if (var != NULL) ABC_FREE(var);
743  if (sifted != NULL) ABC_FREE(sifted);
744 
745  return(0);
746 
747 } /* end of zddGroupSifting */
unsigned int keys
Definition: cuddInt.h:330
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
int siftMaxSwap
Definition: cuddInt.h:412
int * invpermZ
Definition: cuddInt.h:389
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
static int * entry
Definition: cuddZddGroup.c:97
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
FILE * out
Definition: cuddInt.h:441
static int zddUniqueCompareGroup(int *ptrX, int *ptrY)
Definition: cuddZddGroup.c:609
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
static int zddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddGroup.c:766
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int next
Definition: cuddInt.h:333
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
unsigned int keysZ
Definition: cuddInt.h:370
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366
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:564
Definition: cuddInt.h:492
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:441
DdHalfWord x
Definition: cuddInt.h:493
static int zddGroupSiftingDown(DdManager *table, int x, int xHigh, Move **moves)
Definition: cuddZddGroup.c:992
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
unsigned int keysZ
Definition: cuddInt.h:370
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 */
Definition: cuddInt.h:492
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
FILE * out
Definition: cuddInt.h:441
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
static int zddGroupMoveBackward(DdManager *table, int x, int y)
int size
Definition: cuddInt.h:496
DdSubtable * subtableZ
Definition: cuddInt.h:366
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:564
Definition: cuddInt.h:492
double maxGrowth
Definition: cuddInt.h:413
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
#define MTR_DEFAULT
Definition: mtr.h:99
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
unsigned int keysZ
Definition: cuddInt.h:370
int size
Definition: cuddInt.h:496
DdSubtable * subtableZ
Definition: cuddInt.h:366
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:564
Definition: cuddInt.h:492
double maxGrowth
Definition: cuddInt.h:413
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
#define MTR_DEFAULT
Definition: mtr.h:99
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
unsigned int keysZ
Definition: cuddInt.h:370
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:435
int size
Definition: cuddInt.h:496
DdSubtable * subtableZ
Definition: cuddInt.h:366
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:389
struct MtrNode * parent
Definition: mtr.h:136
MtrHalfWord index
Definition: mtr.h:135
Definition: mtr.h:131
unsigned int next
Definition: cuddInt.h:333
MtrNode * treeZ
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 433 of file cuddZddGroup.c.

437 {
438  int lower;
439  int upper = -1;
440  int result;
441  unsigned int initialSize;
442 
443  zddFindNodeHiLo(table,treenode,&lower,&upper);
444  /* If upper == -1 these variables do not exist yet. */
445  if (upper == -1)
446  return(1);
447 
448  if (treenode->flags == MTR_FIXED) {
449  result = 1;
450  } else {
451 #ifdef DD_STATS
452  (void) fprintf(table->out," ");
453 #endif
454  switch (method) {
455  case CUDD_REORDER_RANDOM:
457  result = cuddZddSwapping(table,lower,upper,method);
458  break;
459  case CUDD_REORDER_SIFT:
460  result = cuddZddSifting(table,lower,upper);
461  break;
463  do {
464  initialSize = table->keysZ;
465  result = cuddZddSifting(table,lower,upper);
466  if (initialSize <= table->keysZ)
467  break;
468 #ifdef DD_STATS
469  else
470  (void) fprintf(table->out,"\n");
471 #endif
472  } while (result != 0);
473  break;
475  result = cuddZddSymmSifting(table,lower,upper);
476  break;
478  result = cuddZddSymmSiftingConv(table,lower,upper);
479  break;
481  result = zddGroupSifting(table,lower,upper);
482  break;
483  case CUDD_REORDER_LINEAR:
484  result = cuddZddLinearSifting(table,lower,upper);
485  break;
487  do {
488  initialSize = table->keysZ;
489  result = cuddZddLinearSifting(table,lower,upper);
490  if (initialSize <= table->keysZ)
491  break;
492 #ifdef DD_STATS
493  else
494  (void) fprintf(table->out,"\n");
495 #endif
496  } while (result != 0);
497  break;
498  default:
499  return(0);
500  }
501  }
502 
503  /* Create a single group for all the variables that were sifted,
504  ** so that they will be treated as a single block by successive
505  ** invocations of zddGroupSifting.
506  */
507  zddMergeGroups(table,treenode,lower,upper);
508 
509 #ifdef DD_DEBUG
510  if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:");
511 #endif
512 
513  return(result);
514 
515 } /* end of zddReorderChildren */
MtrHalfWord flags
Definition: mtr.h:132
static int zddGroupSifting(DdManager *table, int lower, int upper)
Definition: cuddZddGroup.c:637
#define MTR_FIXED
Definition: mtr.h:102
static void zddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
Definition: cuddZddGroup.c:534
int cuddZddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:423
int cuddZddLinearSifting(DdManager *table, int lower, int upper)
Definition: cuddZddLin.c:156
FILE * out
Definition: cuddInt.h:441
int cuddZddSifting(DdManager *table, int lower, int upper)
Definition: cuddZddReord.c:867
int cuddZddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:302
int cuddZddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
Definition: cuddZddReord.c:746
static int result
Definition: cuddGenetic.c:125
static void zddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
unsigned int keysZ
Definition: cuddInt.h:370
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 349 of file cuddZddGroup.c.

353 {
354  MtrNode *auxnode;
355  int res;
356 
357 #ifdef DD_DEBUG
358  Mtr_PrintGroups(treenode,1);
359 #endif
360 
361  auxnode = treenode;
362  while (auxnode != NULL) {
363  if (auxnode->child != NULL) {
364  if (!zddTreeSiftingAux(table, auxnode->child, method))
365  return(0);
366  res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT);
367  if (res == 0)
368  return(0);
369  } else if (auxnode->size > 1) {
370  if (!zddReorderChildren(table, auxnode, method))
371  return(0);
372  }
373  auxnode = auxnode->younger;
374  }
375 
376  return(1);
377 
378 } /* end of zddTreeSiftingAux */
MtrHalfWord size
Definition: mtr.h:134
static int zddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:433
struct MtrNode * younger
Definition: mtr.h:139
Definition: mtr.h:131
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:537
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:349
struct MtrNode * child
Definition: mtr.h:137
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 609 of file cuddZddGroup.c.

612 {
613 #if 0
614  if (entry[*ptrY] == entry[*ptrX]) {
615  return((*ptrX) - (*ptrY));
616  }
617 #endif
618  return(entry[*ptrY] - entry[*ptrX]);
619 
620 } /* end of zddUniqueCompareGroup */
static int * entry
Definition: cuddZddGroup.c:97

Variable Documentation

ABC_NAMESPACE_IMPL_START char rcsid [] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.20 2009/02/19 16:25:36 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-2004, 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 94 of file cuddZddGroup.c.

int* entry
static

Definition at line 97 of file cuddZddGroup.c.

int zddTotalNumberSwapping

Definition at line 110 of file cuddZddReord.c.