SVF
Classes | Macros | Typedefs | Functions
mtr.h File Reference

Go to the source code of this file.

Classes

struct  MtrNode
 

Macros

#define SIZEOF_VOID_P   4
 
#define SIZEOF_INT   4
 
#define MTR_INLINE
 
#define MTR_UNUSED
 
#define MTR_DEFAULT   0x00000000
 
#define MTR_TERMINAL   0x00000001
 
#define MTR_SOFT   0x00000002
 
#define MTR_FIXED   0x00000004
 
#define MTR_NEWNODE   0x00000008
 
#define MTR_MAXHIGH   ((MtrHalfWord) ~0)
 
#define MTR_SET(node, flag)   (node->flags |= (flag))
 
#define MTR_RESET(node, flag)   (node->flags &= ~ (flag))
 
#define MTR_TEST(node, flag)   (node->flags & (flag))
 

Typedefs

typedef unsigned short MtrHalfWord
 
typedef struct MtrNode MtrNode
 

Functions

MtrNodeMtr_AllocNode (void)
 
void Mtr_DeallocNode (MtrNode *node)
 
MtrNodeMtr_InitTree (void)
 
void Mtr_FreeTree (MtrNode *node)
 
MtrNodeMtr_CopyTree (MtrNode *node, int expansion)
 
void Mtr_MakeFirstChild (MtrNode *parent, MtrNode *child)
 
void Mtr_MakeLastChild (MtrNode *parent, MtrNode *child)
 
MtrNodeMtr_CreateFirstChild (MtrNode *parent)
 
MtrNodeMtr_CreateLastChild (MtrNode *parent)
 
void Mtr_MakeNextSibling (MtrNode *first, MtrNode *second)
 
void Mtr_PrintTree (MtrNode *node)
 
MtrNodeMtr_InitGroupTree (int lower, int size)
 
MtrNodeMtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
 
MtrNodeMtr_DissolveGroup (MtrNode *group)
 
MtrNodeMtr_FindGroup (MtrNode *root, unsigned int low, unsigned int high)
 
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)
 

Macro Definition Documentation

◆ MTR_DEFAULT

#define MTR_DEFAULT   0x00000000

Definition at line 94 of file mtr.h.

◆ MTR_FIXED

#define MTR_FIXED   0x00000004

Definition at line 97 of file mtr.h.

◆ MTR_INLINE

#define MTR_INLINE

Definition at line 89 of file mtr.h.

◆ MTR_MAXHIGH

#define MTR_MAXHIGH   ((MtrHalfWord) ~0)

Definition at line 107 of file mtr.h.

◆ MTR_NEWNODE

#define MTR_NEWNODE   0x00000008

Definition at line 98 of file mtr.h.

◆ MTR_RESET

#define MTR_RESET (   node,
  flag 
)    (node->flags &= ~ (flag))

Definition at line 149 of file mtr.h.

◆ MTR_SET

#define MTR_SET (   node,
  flag 
)    (node->flags |= (flag))

Definition at line 148 of file mtr.h.

◆ MTR_SOFT

#define MTR_SOFT   0x00000002

Definition at line 96 of file mtr.h.

◆ MTR_TERMINAL

#define MTR_TERMINAL   0x00000001

Definition at line 95 of file mtr.h.

◆ MTR_TEST

#define MTR_TEST (   node,
  flag 
)    (node->flags & (flag))

Definition at line 150 of file mtr.h.

◆ MTR_UNUSED

#define MTR_UNUSED

Definition at line 90 of file mtr.h.

◆ SIZEOF_INT

#define SIZEOF_INT   4

Definition at line 78 of file mtr.h.

◆ SIZEOF_VOID_P

#define SIZEOF_VOID_P   4

CHeaderFile*****************************************************************

FileName [mtr.h]

PackageName [mtr]

Synopsis [Multiway-branch tree manipulation]

Description [This package provides two layers of functions. Functions of the lower level manipulate multiway-branch trees, implemented according to the classical scheme whereby each node points to its first child and its previous and next siblings. These functions are collected in mtrBasic.c.

Functions of the upper layer deal with group trees, that is the trees used by group sifting to represent the grouping of variables. These functions are collected in mtrGroup.c.]

SeeAlso [The CUDD package documentation; specifically on group sifting.]

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.]

Revision [

Id
mtr.h,v 1.17 2012/02/05 01:06:19 fabio Exp

]

Definition at line 75 of file mtr.h.

Typedef Documentation

◆ MtrHalfWord

typedef unsigned short MtrHalfWord

Definition at line 123 of file mtr.h.

◆ MtrNode

typedef struct MtrNode MtrNode

Function Documentation

◆ Mtr_AllocNode()

MtrNode* Mtr_AllocNode ( void  )

AutomaticStart

AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Allocates new tree node.]

Description [Allocates new tree node. Returns pointer to node.]

SideEffects [None]

SeeAlso [Mtr_DeallocNode]

Definition at line 117 of file mtrBasic.c.

118 {
119  MtrNode *node;
120 
121  node = ALLOC(MtrNode,1);
122  return node;
123 
124 } /* Mtr_AllocNode */
#define ALLOC(type, num)
Definition: util.h:76
Definition: mtr.h:126

◆ Mtr_CopyTree()

MtrNode* Mtr_CopyTree ( MtrNode node,
int  expansion 
)

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

Synopsis [Makes a copy of tree.]

Description [Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Mtr_InitTree]

Definition at line 214 of file mtrBasic.c.

217 {
218  MtrNode *copy;
219 
220  if (node == NULL) return(NULL);
221  if (expansion < 1) return(NULL);
222  copy = Mtr_AllocNode();
223  if (copy == NULL) return(NULL);
224  copy->parent = copy->elder = copy->child = copy->younger = NULL;
225  if (node->child != NULL) {
226  copy->child = Mtr_CopyTree(node->child, expansion);
227  if (copy->child == NULL) {
228  Mtr_DeallocNode(copy);
229  return(NULL);
230  }
231  }
232  if (node->younger != NULL) {
233  copy->younger = Mtr_CopyTree(node->younger, expansion);
234  if (copy->younger == NULL) {
235  Mtr_FreeTree(copy);
236  return(NULL);
237  }
238  }
239  copy->flags = node->flags;
240  copy->low = node->low * expansion;
241  copy->size = node->size * expansion;
242  copy->index = node->index * expansion;
243  if (copy->younger) copy->younger->elder = copy;
244  if (copy->child) {
245  MtrNode *auxnode = copy->child;
246  while (auxnode != NULL) {
247  auxnode->parent = copy;
248  auxnode = auxnode->younger;
249  }
250  }
251  return(copy);
252 
253 } /* end of Mtr_CopyTree */
MtrHalfWord flags
Definition: mtr.h:127
MtrHalfWord size
Definition: mtr.h:129
MtrNode * Mtr_CopyTree(MtrNode *node, int expansion)
Definition: mtrBasic.c:214
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
void Mtr_DeallocNode(MtrNode *node)
Definition: mtrBasic.c:139
MtrHalfWord index
Definition: mtr.h:130
MtrNode * Mtr_AllocNode(void)
Definition: mtrBasic.c:117
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
void Mtr_FreeTree(MtrNode *node)
Definition: mtrBasic.c:187
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_CreateFirstChild()

MtrNode* Mtr_CreateFirstChild ( MtrNode parent)

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

Synopsis [Creates a new node and makes it the first child of parent.]

Description [Creates a new node and makes it the first child of parent. Returns pointer to new child.]

SideEffects [None]

SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild]

Definition at line 336 of file mtrBasic.c.

338 {
339  MtrNode *child;
340 
341  child = Mtr_AllocNode();
342  if (child == NULL) return(NULL);
343 
344  child->child = NULL;
345  child->flags = 0;
346  Mtr_MakeFirstChild(parent,child);
347  return(child);
348 
349 } /* end of Mtr_CreateFirstChild */
MtrHalfWord flags
Definition: mtr.h:127
MtrNode * Mtr_AllocNode(void)
Definition: mtrBasic.c:117
Definition: mtr.h:126
void Mtr_MakeFirstChild(MtrNode *parent, MtrNode *child)
Definition: mtrBasic.c:268
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_CreateLastChild()

MtrNode* Mtr_CreateLastChild ( MtrNode parent)

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

Synopsis [Creates a new node and makes it the last child of parent.]

Description [Creates a new node and makes it the last child of parent. Returns pointer to new child.]

SideEffects [None]

SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild]

Definition at line 365 of file mtrBasic.c.

367 {
368  MtrNode *child;
369 
370  child = Mtr_AllocNode();
371  if (child == NULL) return(NULL);
372 
373  child->child = NULL;
374  child->flags = 0;
375  Mtr_MakeLastChild(parent,child);
376  return(child);
377 
378 } /* end of Mtr_CreateLastChild */
MtrHalfWord flags
Definition: mtr.h:127
void Mtr_MakeLastChild(MtrNode *parent, MtrNode *child)
Definition: mtrBasic.c:299
MtrNode * Mtr_AllocNode(void)
Definition: mtrBasic.c:117
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_DeallocNode()

void Mtr_DeallocNode ( MtrNode node)

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

Synopsis [Deallocates tree node.]

Description []

SideEffects [None]

SeeAlso [Mtr_AllocNode]

Definition at line 139 of file mtrBasic.c.

141 {
142  FREE(node);
143  return;
144 
145 } /* end of Mtr_DeallocNode */
#define FREE(obj)
Definition: util.h:80

◆ 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_FreeTree()

void Mtr_FreeTree ( MtrNode node)

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

Synopsis [Disposes of tree rooted at node.]

Description []

SideEffects [None]

SeeAlso [Mtr_InitTree]

Definition at line 187 of file mtrBasic.c.

189 {
190  if (node == NULL) return;
191  if (! MTR_TEST(node,MTR_TERMINAL)) Mtr_FreeTree(node->child);
192  Mtr_FreeTree(node->younger);
193  Mtr_DeallocNode(node);
194  return;
195 
196 } /* end of Mtr_FreeTree */
#define MTR_TERMINAL
Definition: mtr.h:95
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
void Mtr_DeallocNode(MtrNode *node)
Definition: mtrBasic.c:139
void Mtr_FreeTree(MtrNode *node)
Definition: mtrBasic.c:187
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_InitTree()

MtrNode* Mtr_InitTree ( void  )

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

Synopsis [Initializes tree with one node.]

Description [Initializes tree with one node. Returns pointer to node.]

SideEffects [None]

SeeAlso [Mtr_FreeTree Mtr_InitGroupTree]

Definition at line 160 of file mtrBasic.c.

161 {
162  MtrNode *node;
163 
164  node = Mtr_AllocNode();
165  if (node == NULL) return(NULL);
166 
167  node->parent = node->child = node->elder = node->younger = NULL;
168  node->flags = 0;
169 
170  return(node);
171 
172 } /* end of Mtr_InitTree */
MtrHalfWord flags
Definition: mtr.h:127
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
MtrNode * Mtr_AllocNode(void)
Definition: mtrBasic.c:117
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_MakeFirstChild()

void Mtr_MakeFirstChild ( MtrNode parent,
MtrNode child 
)

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

Synopsis [Makes child the first child of parent.]

Description []

SideEffects [None]

SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild]

Definition at line 268 of file mtrBasic.c.

271 {
272  child->parent = parent;
273  child->younger = parent->child;
274  child->elder = NULL;
275  if (parent->child != NULL) {
276 #ifdef MTR_DEBUG
277  assert(parent->child->elder == NULL);
278 #endif
279  parent->child->elder = child;
280  }
281  parent->child = child;
282  return;
283 
284 } /* end of Mtr_MakeFirstChild */
#define assert(ex)
Definition: util.h:141
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134
struct MtrNode * child
Definition: mtr.h:132

◆ 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_MakeLastChild()

void Mtr_MakeLastChild ( MtrNode parent,
MtrNode child 
)

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

Synopsis [Makes child the last child of parent.]

Description []

SideEffects [None]

SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild]

Definition at line 299 of file mtrBasic.c.

302 {
303  MtrNode *node;
304 
305  child->younger = NULL;
306 
307  if (parent->child == NULL) {
308  parent->child = child;
309  child->elder = NULL;
310  } else {
311  for (node = parent->child;
312  node->younger != NULL;
313  node = node->younger);
314  node->younger = child;
315  child->elder = node;
316  }
317  child->parent = parent;
318  return;
319 
320 } /* end of Mtr_MakeLastChild */
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
struct MtrNode * child
Definition: mtr.h:132

◆ Mtr_MakeNextSibling()

void Mtr_MakeNextSibling ( MtrNode first,
MtrNode second 
)

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

Synopsis [Makes second the next sibling of first.]

Description [Makes second the next sibling of first. Second becomes a child of the parent of first.]

SideEffects [None]

SeeAlso []

Definition at line 394 of file mtrBasic.c.

397 {
398  second->parent = first->parent;
399  second->elder = first;
400  second->younger = first->younger;
401  if (first->younger != NULL) {
402  first->younger->elder = second;
403  }
404  first->younger = second;
405  return;
406 
407 } /* end of Mtr_MakeNextSibling */
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * elder
Definition: mtr.h:133
struct MtrNode * younger
Definition: mtr.h:134

◆ 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_PrintTree()

void Mtr_PrintTree ( MtrNode node)

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

Synopsis [Prints a tree, one node per line.]

Description []

SideEffects [None]

SeeAlso [Mtr_PrintGroups]

Definition at line 422 of file mtrBasic.c.

424 {
425  if (node == NULL) return;
426  (void) fprintf(stdout,
427 #if SIZEOF_VOID_P == 8
428  "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n",
429  (unsigned long) node, (unsigned long) node->child,
430  (unsigned long) node->younger, (unsigned long) node->elder,
431  (unsigned long) node->parent, node->flags, node->low, node->size);
432 #else
433  "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n",
434  (unsigned) node, (unsigned) node->child,
435  (unsigned) node->younger, (unsigned) node->elder,
436  (unsigned) node->parent, node->flags, node->low, node->size);
437 #endif
438  if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child);
439  Mtr_PrintTree(node->younger);
440  return;
441 
442 } /* end of Mtr_PrintTree */
void Mtr_PrintTree(MtrNode *node)
Definition: mtrBasic.c:422
#define MTR_TERMINAL
Definition: mtr.h:95
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
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord low
Definition: mtr.h:128
#define SIZEOF_VOID_P
Definition: mtr.h:75
struct MtrNode * child
Definition: mtr.h:132

◆ 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