abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddZddGroup.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddZddGroup.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Functions for ZDD group sifting.]
8 
9  Description [External procedures included in this file:
10  <ul>
11  <li> Cudd_MakeZddTreeNode()
12  </ul>
13  Internal procedures included in this file:
14  <ul>
15  <li> cuddZddTreeSifting()
16  </ul>
17  Static procedures included in this module:
18  <ul>
19  <li> zddTreeSiftingAux()
20  <li> zddCountInternalMtrNodes()
21  <li> zddReorderChildren()
22  <li> zddFindNodeHiLo()
23  <li> zddUniqueCompareGroup()
24  <li> zddGroupSifting()
25  <li> zddGroupSiftingAux()
26  <li> zddGroupSiftingUp()
27  <li> zddGroupSiftingDown()
28  <li> zddGroupMove()
29  <li> zddGroupMoveBackward()
30  <li> zddGroupSiftingBackward()
31  <li> zddMergeGroups()
32  </ul>]
33 
34  Author [Fabio Somenzi]
35 
36  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
37 
38  All rights reserved.
39 
40  Redistribution and use in source and binary forms, with or without
41  modification, are permitted provided that the following conditions
42  are met:
43 
44  Redistributions of source code must retain the above copyright
45  notice, this list of conditions and the following disclaimer.
46 
47  Redistributions in binary form must reproduce the above copyright
48  notice, this list of conditions and the following disclaimer in the
49  documentation and/or other materials provided with the distribution.
50 
51  Neither the name of the University of Colorado nor the names of its
52  contributors may be used to endorse or promote products derived from
53  this software without specific prior written permission.
54 
55  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
56  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
57  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
58  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
59  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
60  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
61  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
63  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
65  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66  POSSIBILITY OF SUCH DAMAGE.]
67 
68 ******************************************************************************/
69 
70 #include "misc/util/util_hack.h"
71 #include "cuddInt.h"
72 
74 
75 
76 
77 /*---------------------------------------------------------------------------*/
78 /* Constant declarations */
79 /*---------------------------------------------------------------------------*/
80 
81 /*---------------------------------------------------------------------------*/
82 /* Stucture declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 /*---------------------------------------------------------------------------*/
86 /* Type declarations */
87 /*---------------------------------------------------------------------------*/
88 
89 /*---------------------------------------------------------------------------*/
90 /* Variable declarations */
91 /*---------------------------------------------------------------------------*/
92 
93 #ifndef lint
94 static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.20 2009/02/19 16:25:36 fabio Exp $";
95 #endif
96 
97 static int *entry;
98 extern int zddTotalNumberSwapping;
99 #ifdef DD_STATS
100 static int extsymmcalls;
101 static int extsymm;
102 static int secdiffcalls;
103 static int secdiff;
104 static int secdiffmisfire;
105 #endif
106 #ifdef DD_DEBUG
107 static int pr = 0; /* flag to enable printing while debugging */
108  /* by depositing a 1 into it */
109 #endif
110 
111 /*---------------------------------------------------------------------------*/
112 /* Macro declarations */
113 /*---------------------------------------------------------------------------*/
114 
115 /**AutomaticStart*************************************************************/
116 
117 /*---------------------------------------------------------------------------*/
118 /* Static function prototypes */
119 /*---------------------------------------------------------------------------*/
120 
121 static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method);
122 #ifdef DD_STATS
123 static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode);
124 #endif
125 static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method);
126 static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper);
127 static int zddUniqueCompareGroup (int *ptrX, int *ptrY);
128 static int zddGroupSifting (DdManager *table, int lower, int upper);
129 static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh);
130 static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves);
131 static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves);
132 static int zddGroupMove (DdManager *table, int x, int y, Move **moves);
133 static int zddGroupMoveBackward (DdManager *table, int x, int y);
134 static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size);
135 static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high);
136 
137 /**AutomaticEnd***************************************************************/
138 
139 
140 /*---------------------------------------------------------------------------*/
141 /* Definition of exported functions */
142 /*---------------------------------------------------------------------------*/
143 
144 
145 /**Function********************************************************************
146 
147  Synopsis [Creates a new ZDD variable group.]
148 
149  Description [Creates a new ZDD variable group. The group starts at
150  variable and contains size variables. The parameter low is the index
151  of the first variable. If the variable already exists, its current
152  position in the order is known to the manager. If the variable does
153  not exist yet, the position is assumed to be the same as the index.
154  The group tree is created if it does not exist yet.
155  Returns a pointer to the group if successful; NULL otherwise.]
156 
157  SideEffects [The ZDD variable tree is changed.]
158 
159  SeeAlso [Cudd_MakeTreeNode]
160 
161 ******************************************************************************/
162 MtrNode *
164  DdManager * dd /* manager */,
165  unsigned int low /* index of the first group variable */,
166  unsigned int size /* number of variables in the group */,
167  unsigned int type /* MTR_DEFAULT or MTR_FIXED */)
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 */
211 
212 
213 /*---------------------------------------------------------------------------*/
214 /* Definition of internal functions */
215 /*---------------------------------------------------------------------------*/
216 
217 
218 /**Function********************************************************************
219 
220  Synopsis [Tree sifting algorithm for ZDDs.]
221 
222  Description [Tree sifting algorithm for ZDDs. Assumes that a tree
223  representing a group hierarchy is passed as a parameter. It then
224  reorders each group in postorder fashion by calling
225  zddTreeSiftingAux. Assumes that no dead nodes are present. Returns
226  1 if successful; 0 otherwise.]
227 
228  SideEffects [None]
229 
230 ******************************************************************************/
231 int
233  DdManager * table /* DD table */,
234  Cudd_ReorderingType method /* reordering method for the groups of leaves */)
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 */
331 
332 
333 /*---------------------------------------------------------------------------*/
334 /* Definition of static functions */
335 /*---------------------------------------------------------------------------*/
336 
337 
338 /**Function********************************************************************
339 
340  Synopsis [Visits the group tree and reorders each group.]
341 
342  Description [Recursively visits the group tree and reorders each
343  group in postorder fashion. Returns 1 if successful; 0 otherwise.]
344 
345  SideEffects [None]
346 
347 ******************************************************************************/
348 static int
350  DdManager * table,
351  MtrNode * treenode,
352  Cudd_ReorderingType method)
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 */
379 
380 
381 #ifdef DD_STATS
382 /**Function********************************************************************
383 
384  Synopsis [Counts the number of internal nodes of the group tree.]
385 
386  Description [Counts the number of internal nodes of the group tree.
387  Returns the count.]
388 
389  SideEffects [None]
390 
391 ******************************************************************************/
392 static int
393 zddCountInternalMtrNodes(
394  DdManager * table,
395  MtrNode * treenode)
396 {
397  MtrNode *auxnode;
398  int count,nodeCount;
399 
400 
401  nodeCount = 0;
402  auxnode = treenode;
403  while (auxnode != NULL) {
404  if (!(MTR_TEST(auxnode,MTR_TERMINAL))) {
405  nodeCount++;
406  count = zddCountInternalMtrNodes(table,auxnode->child);
407  nodeCount += count;
408  }
409  auxnode = auxnode->younger;
410  }
411 
412  return(nodeCount);
413 
414 } /* end of zddCountInternalMtrNodes */
415 #endif
416 
417 
418 /**Function********************************************************************
419 
420  Synopsis [Reorders the children of a group tree node according to
421  the options.]
422 
423  Description [Reorders the children of a group tree node according to
424  the options. After reordering puts all the variables in the group
425  and/or its descendents in a single group. This allows hierarchical
426  reordering. If the variables in the group do not exist yet, simply
427  does nothing. Returns 1 if successful; 0 otherwise.]
428 
429  SideEffects [None]
430 
431 ******************************************************************************/
432 static int
434  DdManager * table,
435  MtrNode * treenode,
436  Cudd_ReorderingType method)
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 */
516 
517 
518 /**Function********************************************************************
519 
520  Synopsis [Finds the lower and upper bounds of the group represented
521  by treenode.]
522 
523  Description [Finds the lower and upper bounds of the group represented
524  by treenode. The high and low fields of treenode are indices. From
525  those we need to derive the current positions, and find maximum and
526  minimum.]
527 
528  SideEffects [The bounds are returned as side effects.]
529 
530  SeeAlso []
531 
532 ******************************************************************************/
533 static void
535  DdManager * table,
536  MtrNode * treenode,
537  int * lower,
538  int * upper)
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 */
594 
595 
596 /**Function********************************************************************
597 
598  Synopsis [Comparison function used by qsort.]
599 
600  Description [Comparison function used by qsort to order the variables
601  according to the number of keys in the subtables. Returns the
602  difference in number of keys between the two variables being
603  compared.]
604 
605  SideEffects [None]
606 
607 ******************************************************************************/
608 static int
610  int * ptrX,
611  int * ptrY)
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 */
621 
622 
623 /**Function********************************************************************
624 
625  Synopsis [Sifts from treenode->low to treenode->high.]
626 
627  Description [Sifts from treenode->low to treenode->high. If
628  croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the
629  end of the initial sifting. If a group is created, it is then sifted
630  again. After sifting one variable, the group that contains it is
631  dissolved. Returns 1 in case of success; 0 otherwise.]
632 
633  SideEffects [None]
634 
635 ******************************************************************************/
636 static int
638  DdManager * table,
639  int lower,
640  int upper)
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 */
748 
749 
750 /**Function********************************************************************
751 
752  Synopsis [Sifts one variable up and down until it has taken all
753  positions. Checks for aggregation.]
754 
755  Description [Sifts one variable up and down until it has taken all
756  positions. Checks for aggregation. There may be at most two sweeps,
757  even if the group grows. Assumes that x is either an isolated
758  variable, or it is the bottom of a group. All groups may not have
759  been found. The variable being moved is returned to the best position
760  seen during sifting. Returns 1 in case of success; 0 otherwise.]
761 
762  SideEffects [None]
763 
764 ******************************************************************************/
765 static int
767  DdManager * table,
768  int x,
769  int xLow,
770  int xHigh)
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 */
897 
898 
899 /**Function********************************************************************
900 
901  Synopsis [Sifts up a variable until either it reaches position xLow
902  or the size of the DD heap increases too much.]
903 
904  Description [Sifts up a variable until either it reaches position
905  xLow or the size of the DD heap increases too much. Assumes that y is
906  the top of a group (or a singleton). Checks y for aggregation to the
907  adjacent variables. Records all the moves that are appended to the
908  list of moves received as input and returned as a side effect.
909  Returns 1 in case of success; 0 otherwise.]
910 
911  SideEffects [None]
912 
913 ******************************************************************************/
914 static int
916  DdManager * table,
917  int y,
918  int xLow,
919  Move ** moves)
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 */
978 
979 
980 /**Function********************************************************************
981 
982  Synopsis [Sifts down a variable until it reaches position xHigh.]
983 
984  Description [Sifts down a variable until it reaches position xHigh.
985  Assumes that x is the bottom of a group (or a singleton). Records
986  all the moves. Returns 1 in case of success; 0 otherwise.]
987 
988  SideEffects [None]
989 
990 ******************************************************************************/
991 static int
993  DdManager * table,
994  int x,
995  int xHigh,
996  Move ** moves)
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 */
1065 
1066 
1067 /**Function********************************************************************
1068 
1069  Synopsis [Swaps two groups and records the move.]
1070 
1071  Description [Swaps two groups and records the move. Returns the
1072  number of keys in the DD table in case of success; 0 otherwise.]
1073 
1074  SideEffects [None]
1075 
1076 ******************************************************************************/
1077 static int
1079  DdManager * table,
1080  int x,
1081  int y,
1082  Move ** moves)
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 */
1171 
1172 
1173 /**Function********************************************************************
1174 
1175  Synopsis [Undoes the swap two groups.]
1176 
1177  Description [Undoes the swap two groups. Returns 1 in case of
1178  success; 0 otherwise.]
1179 
1180  SideEffects [None]
1181 
1182 ******************************************************************************/
1183 static int
1185  DdManager * table,
1186  int x,
1187  int y)
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 */
1244 
1245 
1246 /**Function********************************************************************
1247 
1248  Synopsis [Determines the best position for a variables and returns
1249  it there.]
1250 
1251  Description [Determines the best position for a variables and returns
1252  it there. Returns 1 in case of success; 0 otherwise.]
1253 
1254  SideEffects [None]
1255 
1256 ******************************************************************************/
1257 static int
1259  DdManager * table,
1260  Move * moves,
1261  int size)
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 */
1293 
1294 
1295 /**Function********************************************************************
1296 
1297  Synopsis [Merges groups in the DD table.]
1298 
1299  Description [Creates a single group from low to high and adjusts the
1300  idex field of the tree node.]
1301 
1302  SideEffects [None]
1303 
1304 ******************************************************************************/
1305 static void
1307  DdManager * table,
1308  MtrNode * treenode,
1309  int low,
1310  int high)
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 */
1341 
1342 
1344 
#define MTR_MAXHIGH
Definition: mtr.h:112
#define MTR_TERMINAL
Definition: mtr.h:100
Cudd_AggregationType groupcheck
Definition: cuddInt.h:426
unsigned int keys
Definition: cuddInt.h:330
MtrHalfWord flags
Definition: mtr.h:132
static int zddGroupMove(DdManager *table, int x, int y, Move **moves)
unsigned short MtrHalfWord
Definition: mtr.h:128
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddCheck.c:747
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
static int zddGroupSifting(DdManager *table, int lower, int upper)
Definition: cuddZddGroup.c:637
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
MtrHalfWord size
Definition: mtr.h:134
int siftMaxSwap
Definition: cuddInt.h:412
int * invpermZ
Definition: cuddInt.h:389
static int zddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:433
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
Definition: cuddInt.h:492
static int * entry
Definition: cuddZddGroup.c:97
double maxGrowth
Definition: cuddInt.h:413
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
#define MTR_FIXED
Definition: mtr.h:102
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static void zddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
Definition: cuddZddGroup.c:534
int * permZ
Definition: cuddInt.h:387
struct MtrNode * parent
Definition: mtr.h:136
static int zddGroupSiftingUp(DdManager *table, int y, int xLow, Move **moves)
Definition: cuddZddGroup.c:915
#define MTR_DEFAULT
Definition: mtr.h:99
MtrNode * tree
Definition: cuddInt.h:424
#define MTR_TEST(node, flag)
Definition: mtr.h:155
struct MtrNode * younger
Definition: mtr.h:139
int cuddZddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:423
int cuddZddLinearSifting(DdManager *table, int lower, int upper)
Definition: cuddZddLin.c:156
MtrHalfWord index
Definition: mtr.h:135
static int zddGroupSiftingBackward(DdManager *table, Move *moves, int size)
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int zddUniqueCompareGroup(int *ptrX, int *ptrY)
Definition: cuddZddGroup.c:609
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define ddMax(x, y)
Definition: cuddInt.h:832
MtrNode * Cudd_MakeZddTreeNode(DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
Definition: cuddZddGroup.c:163
static int zddGroupSiftingDown(DdManager *table, int x, int xHigh, Move **moves)
Definition: cuddZddGroup.c:992
static int size
Definition: cuddSign.c:86
int cuddZddSifting(DdManager *table, int lower, int upper)
Definition: cuddZddReord.c:867
#define ddMin(x, y)
Definition: cuddInt.h:818
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
MtrHalfWord low
Definition: mtr.h:133
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
Definition: mtr.h:131
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:537
int siftMaxVar
Definition: cuddInt.h:411
int cuddZddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddZddSymm.c:302
static int zddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddGroup.c:766
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:121
int sizeZ
Definition: cuddInt.h:362
int cuddZddTreeSifting(DdManager *table, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:232
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdHalfWord y
Definition: cuddInt.h:494
unsigned int next
Definition: cuddInt.h:333
int cuddZddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
Definition: cuddZddReord.c:746
MtrNode * treeZ
Definition: cuddInt.h:425
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:349
struct Move * next
Definition: cuddInt.h:497
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddZddGroup.c:94
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
static int result
Definition: cuddGenetic.c:125
void Cudd_FreeZddTree(DdManager *dd)
Definition: cuddAPI.c:2252
static void zddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
Definition: mtrGroup.c:158
static int zddGroupMoveBackward(DdManager *table, int x, int y)
unsigned int keysZ
Definition: cuddInt.h:370
Cudd_ReorderingType
Definition: cudd.h:151
struct MtrNode * child
Definition: mtr.h:137
int * perm
Definition: cuddInt.h:386
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:435
int size
Definition: cuddInt.h:496
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366