SVF
Functions | Variables
mtrGroup.c File Reference
#include "CUDD/util.h"
#include "CUDD/mtrInt.h"

Go to the source code of this file.

Functions

static int mtrShiftHL (MtrNode *node, int shift)
 
MtrNodeMtr_InitGroupTree (int lower, int size)
 
MtrNodeMtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int size, unsigned int flags)
 
MtrNodeMtr_DissolveGroup (MtrNode *group)
 
MtrNodeMtr_FindGroup (MtrNode *root, unsigned int low, unsigned int size)
 
int Mtr_SwapGroups (MtrNode *first, MtrNode *second)
 
void Mtr_ReorderGroups (MtrNode *treenode, int *permutation)
 
void Mtr_PrintGroups (MtrNode *root, int silent)
 
int Mtr_PrintGroupedOrder (MtrNode *root, int *invperm, FILE *fp)
 
MtrNodeMtr_ReadGroups (FILE *fp, int nleaves)
 

Variables

static char rcsid [] MTR_UNUSED = "$Id: mtrGroup.c,v 1.21 2012/02/05 01:06:19 fabio Exp $"
 

Function Documentation

◆ Mtr_DissolveGroup()

MtrNode* Mtr_DissolveGroup ( MtrNode group)

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

Synopsis [Merges the children of `group' with the children of its parent.]

Description [Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise.]

SideEffects [None]

SeeAlso [Mtr_MakeGroup]

Definition at line 349 of file mtrGroup.c.

351 {
352  MtrNode *parent;
353  MtrNode *last;
354 
355  parent = group->parent;
356 
357  if (parent == NULL) return(NULL);
358  if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return(NULL);
359 
360  /* Make all children of group children of its parent, and make
361  ** last point to the last child of group. */
362  for (last = group->child; last->younger != NULL; last = last->younger) {
363  last->parent = parent;
364  }
365  last->parent = parent;
366 
367  last->younger = group->younger;
368  if (group->younger != NULL) {
369  group->younger->elder = last;
370  }
371 
372  group->child->elder = group->elder;
373  if (group == parent->child) {
374  parent->child = group->child;
375  } else {
376  group->elder->younger = group->child;
377  }
378 
379  Mtr_DeallocNode(group);
380  return(parent);
381 
382 } /* end of Mtr_DissolveGroup */
#define MTR_TERMINAL
Definition: mtr.h:95
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
Definition: mtr.h:126
void Mtr_DeallocNode(MtrNode *node)
Definition: mtrBasic.c:139
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_FindGroup()

MtrNode* Mtr_FindGroup ( MtrNode root,
unsigned int  low,
unsigned int  size 
)

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

Synopsis [Finds a group with size leaves starting at low, if it exists.]

Description [Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 401 of file mtrGroup.c.

405 {
406  MtrNode *node;
407 
408 #ifdef MTR_DEBUG
409  /* We cannot have a non-empty proper subgroup of a singleton set. */
410  assert(!MTR_TEST(root,MTR_TERMINAL));
411 #endif
412 
413  /* Sanity check. */
414  if (size < 1) return(NULL);
415 
416  /* Check whether current group includes the group sought. This
417  ** check is necessary at the top-level call. In the subsequent
418  ** calls it is redundant. */
419  if (low < (unsigned int) root->low ||
420  low + size > (unsigned int) (root->low + root->size))
421  return(NULL);
422 
423  if (root->size == size && root->low == low)
424  return(root);
425 
426  if (root->child == NULL)
427  return(NULL);
428 
429  /* Find all chidren of root that are included in the new group. If
430  ** the group of any child entirely contains the new group, call
431  ** Mtr_MakeGroup recursively. */
432  node = root->child;
433  while (low >= (unsigned int) (node->low + node->size)) {
434  node = node->younger;
435  }
436  if (low + size <= (unsigned int) (node->low + node->size)) {
437  /* The group is contained in the group of node. */
438  node = Mtr_FindGroup(node, low, size);
439  return(node);
440  } else {
441  return(NULL);
442  }
443 
444 } /* end of Mtr_FindGroup */
#define MTR_TERMINAL
Definition: mtr.h:95
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord low
Definition: mtr.h:128
MtrNode * Mtr_FindGroup(MtrNode *root, unsigned int low, unsigned int size)
Definition: mtrGroup.c:401
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_InitGroupTree()

MtrNode* Mtr_InitGroupTree ( int  lower,
int  size 
)

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

Synopsis [Allocate new tree.]

Description [Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root.]

SideEffects [None]

SeeAlso [Mtr_InitTree Mtr_FreeTree]

Definition at line 120 of file mtrGroup.c.

123 {
124  MtrNode *root;
125 
126  root = Mtr_InitTree();
127  if (root == NULL) return(NULL);
128  root->flags = MTR_DEFAULT;
129  root->low = lower;
130  root->size = size;
131  return(root);
132 
133 } /* end of Mtr_InitGroupTree */
MtrHalfWord flags
Definition: mtr.h:127
MtrHalfWord size
Definition: mtr.h:129
#define MTR_DEFAULT
Definition: mtr.h:94
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
MtrNode * Mtr_InitTree(void)
Definition: mtrBasic.c:160

◆ Mtr_MakeGroup()

MtrNode* Mtr_MakeGroup ( MtrNode root,
unsigned int  low,
unsigned int  size,
unsigned int  flags 
)

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

Synopsis [Makes a new group with size leaves starting at low.]

Description [Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned.]

SideEffects [None]

SeeAlso [Mtr_DissolveGroup Mtr_ReadGroups Mtr_FindGroup]

Definition at line 156 of file mtrGroup.c.

161 {
162  MtrNode *node,
163  *first,
164  *last,
165  *previous,
166  *newn;
167 
168  /* Sanity check. */
169  if (size == 0)
170  return(NULL);
171 
172  /* Check whether current group includes new group. This check is
173  ** necessary at the top-level call. In the subsequent calls it is
174  ** redundant. */
175  if (low < (unsigned int) root->low ||
176  low + size > (unsigned int) (root->low + root->size))
177  return(NULL);
178 
179  /* At this point we know that the new group is contained
180  ** in the group of root. We have two possible cases here:
181  ** - root is a terminal node;
182  ** - root has children. */
183 
184  /* Root has no children: create a new group. */
185  if (root->child == NULL) {
186  newn = Mtr_AllocNode();
187  if (newn == NULL) return(NULL); /* out of memory */
188  newn->low = low;
189  newn->size = size;
190  newn->flags = flags;
191  newn->parent = root;
192  newn->elder = newn->younger = newn->child = NULL;
193  root->child = newn;
194  return(newn);
195  }
196 
197  /* Root has children: Find all children of root that are included
198  ** in the new group. If the group of any child entirely contains
199  ** the new group, call Mtr_MakeGroup recursively. */
200  previous = NULL;
201  first = root->child; /* guaranteed to be non-NULL */
202  while (first != NULL && low >= (unsigned int) (first->low + first->size)) {
203  previous = first;
204  first = first->younger;
205  }
206  if (first == NULL) {
207  /* We have scanned the entire list and we need to append a new
208  ** child at the end of it. Previous points to the last child
209  ** of root. */
210  newn = Mtr_AllocNode();
211  if (newn == NULL) return(NULL); /* out of memory */
212  newn->low = low;
213  newn->size = size;
214  newn->flags = flags;
215  newn->parent = root;
216  newn->elder = previous;
217  previous->younger = newn;
218  newn->younger = newn->child = NULL;
219  return(newn);
220  }
221  /* Here first is non-NULL and low < first->low + first->size. */
222  if (low >= (unsigned int) first->low &&
223  low + size <= (unsigned int) (first->low + first->size)) {
224  /* The new group is contained in the group of first. */
225  newn = Mtr_MakeGroup(first, low, size, flags);
226  return(newn);
227  } else if (low + size <= first->low) {
228  /* The new group is entirely contained in the gap between
229  ** previous and first. */
230  newn = Mtr_AllocNode();
231  if (newn == NULL) return(NULL); /* out of memory */
232  newn->low = low;
233  newn->size = size;
234  newn->flags = flags;
235  newn->child = NULL;
236  newn->parent = root;
237  newn->elder = previous;
238  newn->younger = first;
239  first->elder = newn;
240  if (previous != NULL) {
241  previous->younger = newn;
242  } else {
243  root->child = newn;
244  }
245  return(newn);
246  } else if (low < (unsigned int) first->low &&
247  low + size < (unsigned int) (first->low + first->size)) {
248  /* Trying to cut an existing group: not allowed. */
249  return(NULL);
250  } else if (low > first->low) {
251  /* The new group neither is contained in the group of first
252  ** (this was tested above) nor contains it. It is therefore
253  ** trying to cut an existing group: not allowed. */
254  return(NULL);
255  }
256 
257  /* First holds the pointer to the first child contained in the new
258  ** group. Here low <= first->low and low + size >= first->low +
259  ** first->size. One of the two inequalities is strict. */
260  last = first->younger;
261  while (last != NULL &&
262  (unsigned int) (last->low + last->size) < low + size) {
263  last = last->younger;
264  }
265  if (last == NULL) {
266  /* All the chilren of root from first onward become children
267  ** of the new group. */
268  newn = Mtr_AllocNode();
269  if (newn == NULL) return(NULL); /* out of memory */
270  newn->low = low;
271  newn->size = size;
272  newn->flags = flags;
273  newn->child = first;
274  newn->parent = root;
275  newn->elder = previous;
276  newn->younger = NULL;
277  first->elder = NULL;
278  if (previous != NULL) {
279  previous->younger = newn;
280  } else {
281  root->child = newn;
282  }
283  last = first;
284  while (last != NULL) {
285  last->parent = newn;
286  last = last->younger;
287  }
288  return(newn);
289  }
290 
291  /* Here last != NULL and low + size <= last->low + last->size. */
292  if (low + size - 1 >= (unsigned int) last->low &&
293  low + size < (unsigned int) (last->low + last->size)) {
294  /* Trying to cut an existing group: not allowed. */
295  return(NULL);
296  }
297 
298  /* First and last point to the first and last of the children of
299  ** root that are included in the new group. Allocate a new node
300  ** and make all children of root between first and last chidren of
301  ** the new node. Previous points to the child of root immediately
302  ** preceeding first. If it is NULL, then first is the first child
303  ** of root. */
304  newn = Mtr_AllocNode();
305  if (newn == NULL) return(NULL); /* out of memory */
306  newn->low = low;
307  newn->size = size;
308  newn->flags = flags;
309  newn->child = first;
310  newn->parent = root;
311  if (previous == NULL) {
312  root->child = newn;
313  } else {
314  previous->younger = newn;
315  }
316  newn->elder = previous;
317  newn->younger = last->younger;
318  if (last->younger != NULL) {
319  last->younger->elder = newn;
320  }
321  last->younger = NULL;
322  first->elder = NULL;
323  for (node = first; node != NULL; node = node->younger) {
324  node->parent = newn;
325  }
326 
327  return(newn);
328 
329 } /* end of Mtr_MakeGroup */
MtrHalfWord flags
Definition: mtr.h:127
MtrHalfWord size
Definition: mtr.h:129
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int size, unsigned int flags)
Definition: mtrGroup.c:156
MtrNode * Mtr_AllocNode(void)
Definition: mtrBasic.c:117
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_PrintGroupedOrder()

int Mtr_PrintGroupedOrder ( MtrNode root,
int *  invperm,
FILE *  fp 
)

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

Synopsis [Prints the variable order as a parenthesized list.]

Description [Prints the variable order as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.

  • F: MTR_FIXED
  • N: MTR_NEWNODE
  • S: MTR_SOFT

The second argument, gives the map from levels to variable indices. ]

SideEffects [None]

SeeAlso [Mtr_PrintGroups]

Definition at line 662 of file mtrGroup.c.

666 {
667  MtrNode *child;
668  MtrHalfWord level;
669  int retval;
670 
671  assert(root != NULL);
672  assert(root->younger == NULL || root->younger->elder == root);
673  assert(root->elder == NULL || root->elder->younger == root);
674  retval = fprintf(fp,"(");
675  if (retval == EOF) return(0);
676  level = root->low;
677  child = root->child;
678  while (child != NULL) {
679  assert(child->low >= root->low && (child->low + child->size) <= (root->low + root->size));
680  assert(child->parent == root);
681  while (level < child->low) {
682  retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : "");
683  if (retval == EOF) return(0);
684  level++;
685  }
686  retval = Mtr_PrintGroupedOrder(child,invperm,fp);
687  if (retval == 0) return(0);
688  level += child->size;
689  if (level < root->low + root->size - 1) {
690  retval = fprintf(fp,",");
691  if (retval == EOF) return(0);
692  }
693  child = child->younger;
694  }
695  while (level < root->low + root->size) {
696  retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : "");
697  if (retval == EOF) return(0);
698  level++;
699  }
700  if (root->flags != MTR_DEFAULT) {
701  retval = fprintf(fp,"|");
702  if (retval == EOF) return(0);
703  if (MTR_TEST(root,MTR_FIXED)) {
704  retval = fprintf(fp,"F");
705  if (retval == EOF) return(0);
706  }
707  if (MTR_TEST(root,MTR_NEWNODE)) {
708  retval = fprintf(fp,"N");
709  if (retval == EOF) return(0);
710  }
711  if (MTR_TEST(root,MTR_SOFT)) {
712  retval = fprintf(fp,"S");
713  if (retval == EOF) return(0);
714  }
715  }
716  retval = fprintf(fp,")");
717  if (retval == EOF) return(0);
718  if (root->parent == NULL) {
719  retval = fprintf(fp,"\n");
720  if (retval == EOF) return(0);
721  }
722  assert((root->flags &~(MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
723  return(1);
724 
725 } /* end of Mtr_PrintGroupedOrder */
MtrHalfWord flags
Definition: mtr.h:127
unsigned short MtrHalfWord
Definition: mtr.h:123
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
#define MTR_FIXED
Definition: mtr.h:97
struct MtrNode * parent
Definition: mtr.h:131
#define MTR_DEFAULT
Definition: mtr.h:94
struct MtrNode * elder
Definition: mtr.h:133
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
#define MTR_NEWNODE
Definition: mtr.h:98
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
int Mtr_PrintGroupedOrder(MtrNode *root, int *invperm, FILE *fp)
Definition: mtrGroup.c:662
struct MtrNode * child
Definition: mtr.h:132
#define MTR_SOFT
Definition: mtr.h:96

◆ Mtr_PrintGroups()

void Mtr_PrintGroups ( MtrNode root,
int  silent 
)

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

Synopsis [Prints the groups as a parenthesized list.]

Description [Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.

  • F: MTR_FIXED
  • N: MTR_NEWNODE
  • S: MTR_SOFT

The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. ]

SideEffects [None]

SeeAlso [Mtr_PrintTree]

Definition at line 595 of file mtrGroup.c.

598 {
599  MtrNode *node;
600 
601  assert(root != NULL);
602  assert(root->younger == NULL || root->younger->elder == root);
603  assert(root->elder == NULL || root->elder->younger == root);
604 #if SIZEOF_VOID_P == 8
605  if (!silent) (void) printf("(%u",root->low);
606 #else
607  if (!silent) (void) printf("(%hu",root->low);
608 #endif
609  if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
610  if (!silent) (void) printf(",");
611  } else {
612  node = root->child;
613  while (node != NULL) {
614  assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size));
615  assert(node->parent == root);
616  Mtr_PrintGroups(node,silent);
617  node = node->younger;
618  }
619  }
620  if (!silent) {
621 #if SIZEOF_VOID_P == 8
622  (void) printf("%u", root->low + root->size - 1);
623 #else
624  (void) printf("%hu", root->low + root->size - 1);
625 #endif
626  if (root->flags != MTR_DEFAULT) {
627  (void) printf("|");
628  if (MTR_TEST(root,MTR_FIXED)) (void) printf("F");
629  if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N");
630  if (MTR_TEST(root,MTR_SOFT)) (void) printf("S");
631  }
632  (void) printf(")");
633  if (root->parent == NULL) (void) printf("\n");
634  }
635  assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
636  return;
637 
638 } /* end of Mtr_PrintGroups */
#define MTR_TERMINAL
Definition: mtr.h:95
MtrHalfWord flags
Definition: mtr.h:127
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
#define MTR_FIXED
Definition: mtr.h:97
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:595
struct MtrNode * parent
Definition: mtr.h:131
#define MTR_DEFAULT
Definition: mtr.h:94
struct MtrNode * elder
Definition: mtr.h:133
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
#define MTR_NEWNODE
Definition: mtr.h:98
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132
#define MTR_SOFT
Definition: mtr.h:96

◆ Mtr_ReadGroups()

MtrNode* Mtr_ReadGroups ( FILE *  fp,
int  nleaves 
)

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

Synopsis [Reads groups from a file and creates a group tree.]

Description [Reads groups from a file and creates a group tree. Each group is specified by three fields: <xmp> low size flags. </xmp> Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):

  • D: MTR_DEFAULT
  • F: MTR_FIXED
  • N: MTR_NEWNODE
  • S: MTR_SOFT
  • T: MTR_TERMINAL

Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Mtr_InitGroupTree Mtr_MakeGroup]

Definition at line 756 of file mtrGroup.c.

759 {
760  int low;
761  int size;
762  int err;
763  unsigned int flags;
764  MtrNode *root;
765  MtrNode *node;
766  char attrib[8*sizeof(unsigned int)+1];
767  char *c;
768 
769  root = Mtr_InitGroupTree(0,nleaves);
770  if (root == NULL) return NULL;
771 
772  while (! feof(fp)) {
773  /* Read a triple and check for consistency. */
774  err = fscanf(fp, "%d %d %s", &low, &size, attrib);
775  if (err == EOF) {
776  break;
777  } else if (err != 3) {
778  Mtr_FreeTree(root);
779  return(NULL);
780  } else if (low < 0 || low+size > nleaves || size < 1) {
781  Mtr_FreeTree(root);
782  return(NULL);
783  } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) {
784  /* Not enough bits in the flags word to store these many
785  ** attributes. */
786  Mtr_FreeTree(root);
787  return(NULL);
788  }
789 
790  /* Parse the flag string. Currently all flags are permitted,
791  ** to make debugging easier. Normally, specifying NEWNODE
792  ** wouldn't be allowed. */
793  flags = MTR_DEFAULT;
794  for (c=attrib; *c != 0; c++) {
795  switch (*c) {
796  case 'D':
797  break;
798  case 'F':
799  flags |= MTR_FIXED;
800  break;
801  case 'N':
802  flags |= MTR_NEWNODE;
803  break;
804  case 'S':
805  flags |= MTR_SOFT;
806  break;
807  case 'T':
808  flags |= MTR_TERMINAL;
809  break;
810  default:
811  return NULL;
812  }
813  }
814  node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size,
815  flags);
816  if (node == NULL) {
817  Mtr_FreeTree(root);
818  return(NULL);
819  }
820  }
821 
822  return(root);
823 
824 } /* end of Mtr_ReadGroups */
#define MTR_TERMINAL
Definition: mtr.h:95
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:120
unsigned short MtrHalfWord
Definition: mtr.h:123
void Mtr_FreeTree(MtrNode *node)
Definition: mtrBasic.c:187
#define MTR_FIXED
Definition: mtr.h:97
#define MTR_DEFAULT
Definition: mtr.h:94
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int size, unsigned int flags)
Definition: mtrGroup.c:156
#define MTR_NEWNODE
Definition: mtr.h:98
Definition: mtr.h:126
int strlen()
#define MTR_SOFT
Definition: mtr.h:96

◆ Mtr_ReorderGroups()

void Mtr_ReorderGroups ( MtrNode treenode,
int *  permutation 
)

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

Synopsis [Fix variable tree at the end of tree sifting.]

Description [Fix the levels in the variable tree sorting siblings according to them. It should be called on a non-NULL tree. It then maintains this invariant. It applies insertion sorting to the list of siblings The order is determined by permutation, which is used to find the new level of the node index. Index must refer to the first variable in the group.]

SideEffects [The tree is modified.]

SeeAlso []

Definition at line 524 of file mtrGroup.c.

527 {
528  MtrNode *auxnode;
529  /* Initialize sorted list to first element. */
530  MtrNode *sorted = treenode;
531  sorted->low = permutation[sorted->index];
532  if (sorted->child != NULL)
533  Mtr_ReorderGroups(sorted->child, permutation);
534 
535  auxnode = treenode->younger;
536  while (auxnode != NULL) {
537  MtrNode *rightplace;
538  MtrNode *moving = auxnode;
539  auxnode->low = permutation[auxnode->index];
540  if (auxnode->child != NULL)
541  Mtr_ReorderGroups(auxnode->child, permutation);
542  rightplace = auxnode->elder;
543  /* Find insertion point. */
544  while (rightplace != NULL && auxnode->low < rightplace->low)
545  rightplace = rightplace->elder;
546  auxnode = auxnode->younger;
547  if (auxnode != NULL) {
548  auxnode->elder = moving->elder;
549  auxnode->elder->younger = auxnode;
550  } else {
551  moving->elder->younger = NULL;
552  }
553  if (rightplace == NULL) { /* Move to head of sorted list. */
554  sorted->elder = moving;
555  moving->elder = NULL;
556  moving->younger = sorted;
557  sorted = moving;
558  } else { /* Splice. */
559  moving->elder = rightplace;
560  moving->younger = rightplace->younger;
561  if (rightplace->younger != NULL)
562  rightplace->younger->elder = moving;
563  rightplace->younger = moving;
564  }
565  }
566  /* Fix parent. */
567  if (sorted->parent != NULL)
568  sorted->parent->child = sorted;
569 
570 } /* end of Mtr_ReorderGroups */
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
void Mtr_ReorderGroups(MtrNode *treenode, int *permutation)
Definition: mtrGroup.c:524
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_SwapGroups()

int Mtr_SwapGroups ( MtrNode first,
MtrNode second 
)

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

Synopsis [Swaps two children of a tree node.]

Description [Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 462 of file mtrGroup.c.

465 {
466  MtrNode *node;
467  MtrNode *parent;
468  int sizeFirst;
469  int sizeSecond;
470 
471  if (second->younger == first) { /* make first first */
472  node = first;
473  first = second;
474  second = node;
475  } else if (first->younger != second) { /* non-adjacent */
476  return(0);
477  }
478 
479  sizeFirst = first->size;
480  sizeSecond = second->size;
481 
482  /* Swap the two nodes. */
483  parent = first->parent;
484  if (parent == NULL || second->parent != parent) return(0);
485  if (parent->child == first) {
486  parent->child = second;
487  } else { /* first->elder != NULL */
488  first->elder->younger = second;
489  }
490  if (second->younger != NULL) {
491  second->younger->elder = first;
492  }
493  first->younger = second->younger;
494  second->elder = first->elder;
495  first->elder = second;
496  second->younger = first;
497 
498  /* Adjust the high and low fields. */
499  if (!mtrShiftHL(first,sizeSecond)) return(0);
500  if (!mtrShiftHL(second,-sizeFirst)) return(0);
501 
502  return(1);
503 
504 } /* end of Mtr_SwapGroups */
MtrHalfWord size
Definition: mtr.h:129
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
Definition: mtr.h:126
static int mtrShiftHL(MtrNode *node, int shift)
Definition: mtrGroup.c:851
struct MtrNode * child
Definition: mtr.h:132

◆ mtrShiftHL()

static int mtrShiftHL ( MtrNode node,
int  shift 
)
static

AutomaticStart

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

Synopsis [Adjusts the low fields of a node and its descendants.]

Description [Adjusts the low fields of a node and its descendants. Adds shift to low of each node. Checks that no out-of-bounds values result. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 851 of file mtrGroup.c.

854 {
855  MtrNode *auxnode;
856  int low;
857 
858  low = (int) node->low;
859 
860 
861  low += shift;
862 
863  if (low < 0 || low + (int) (node->size - 1) > (int) MTR_MAXHIGH) return(0);
864 
865  node->low = (MtrHalfWord) low;
866 
867  if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) {
868  auxnode = node->child;
869  do {
870  if (!mtrShiftHL(auxnode,shift)) return(0);
871  auxnode = auxnode->younger;
872  } while (auxnode != NULL);
873  }
874 
875  return(1);
876 
877 } /* end of mtrShiftHL */
#define MTR_MAXHIGH
Definition: mtr.h:107
#define MTR_TERMINAL
Definition: mtr.h:95
unsigned short MtrHalfWord
Definition: mtr.h:123
MtrHalfWord size
Definition: mtr.h:129
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
static int mtrShiftHL(MtrNode *node, int shift)
Definition: mtrGroup.c:851
struct MtrNode * child
Definition: mtr.h:132
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(dvf dda.cpp) else() add_executable(dvf dda.cpp) target_link_libraries(dvf Svf Cudd $
Definition: CMakeLists.txt:2

Variable Documentation

◆ MTR_UNUSED

char rcsid [] MTR_UNUSED = "$Id: mtrGroup.c,v 1.21 2012/02/05 01:06:19 fabio Exp $"
static

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

FileName [mtrGroup.c]

PackageName [mtr]

Synopsis [Functions to support group specification for reordering.]

Description [External procedures included in this module:

Static procedures included in this module:

  • mtrShiftHL

]

SeeAlso [cudd package]

Author [Fabio Somenzi]

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

All rights reserved.

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

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

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

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

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

Definition at line 84 of file mtrGroup.c.