/**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]

******************************************************************************/
MtrNode *
Mtr_DissolveGroup(
  MtrNode * group /* group to be dissolved */)
{
    MtrNode *parent;
    MtrNode *last;

    parent = group->parent;

    if (parent == NULL) return(NULL);
    if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return(NULL);

    /* Make all children of group children of its parent, and make
    ** last point to the last child of group. */
    for (last = group->child; last->younger != NULL; last = last->younger) {
	last->parent = parent;
    }
    last->parent = parent;

    last->younger = group->younger;
    if (group->younger != NULL) {
	group->younger->elder = last;
    }

    group->child->elder = group->elder;
    if (group == parent->child) {
	parent->child = group->child;
    } else {
	group->elder->younger = group->child;
    }

    Mtr_DeallocNode(group);
    return(parent);

} /* end of Mtr_DissolveGroup */
Exemple #2
0
/**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     []

******************************************************************************/
static int
mtrShiftHL(
  MtrNode * node /* group tree node */,
  int  shift /* amount by which low should be changed */)
{
    MtrNode *auxnode;
    int low;

    low = (int) node->low;


    low += shift;

    if (low < 0 || low + (int) (node->size - 1) > (int) MTR_MAXHIGH) return(0);

    node->low = (MtrHalfWord) low;

    if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) {
	auxnode = node->child;
	do {
	    if (!mtrShiftHL(auxnode,shift)) return(0);
	    auxnode = auxnode->younger;
	} while (auxnode != NULL);
    }

    return(1);

} /* end of mtrShiftHL */
Exemple #3
0
/**Function********************************************************************

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

  Description []

  SideEffects [None]

  SeeAlso     [Mtr_PrintGroups]

******************************************************************************/
void
Mtr_PrintTree(
  MtrNode * node)
{
    if (node == NULL) return;
    (void) fprintf(stdout,
#if NUSMV_SIZEOF_VOID_P == 8
    "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%d S=%d\n",
    /* NuSMV: add begin */
    (util_ptruint) node, (util_ptruint) node->child,
    (util_ptruint) node->younger, (util_ptruint) node->elder,
    (util_ptruint) node->parent, node->flags, node->low, node->size);
      /* WAS: (unsigned long) node, (unsigned long) node->child,
              (unsigned long) node->younger, (unsigned long) node->elder,
              (unsigned long) node->parent, node->flags, node->low, node->size); */
    /* NuSMV: add end */

#else
    "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%d S=%d\n",
    (unsigned) node, (unsigned) node->child,
    (unsigned) node->younger, (unsigned) node->elder,
    (unsigned) node->parent, node->flags, node->low, node->size);
#endif
    if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child);
    Mtr_PrintTree(node->younger);
    return;

} /* end of Mtr_PrintTree */
Exemple #4
0
/**Function********************************************************************

  Synopsis    [Disposes of tree rooted at node.]

  Description []

  SideEffects [None]

  SeeAlso     [Mtr_InitTree]

******************************************************************************/
void
Mtr_FreeTree(
  MtrNode * node)
{
    if (node == NULL) return;
    if (! MTR_TEST(node,MTR_TERMINAL)) Mtr_FreeTree(node->child);
    Mtr_FreeTree(node->younger);
    Mtr_DeallocNode(node);
    return;

} /* end of Mtr_FreeTree */
Exemple #5
0
/**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.
  <ul>
  <li>F: MTR_FIXED
  <li>N: MTR_NEWNODE
  <li>S: MTR_SOFT
  </ul>
  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]

******************************************************************************/
void
Mtr_PrintGroups(
  MtrNode * root /* root of the group tree */,
  int  silent /* flag to check tree syntax only */)
{
    MtrNode *node;

    assert(root != NULL);
    assert(root->younger == NULL || root->younger->elder == root);
    assert(root->elder == NULL || root->elder->younger == root);
    if (!silent) (void) printf("(%d",root->low);
    if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
	if (!silent) (void) printf(",");
    } else {
	node = root->child;
	while (node != NULL) {
	    assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size));
	    assert(node->parent == root);
	    Mtr_PrintGroups(node,silent);
	    node = node->younger;
	}
    }
    if (!silent) {
	(void) printf("%d", root->low + root->size - 1);
	if (root->flags != MTR_DEFAULT) {
	    (void) printf("|");
	    if (MTR_TEST(root,MTR_FIXED)) (void) printf("F");
	    if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N");
	    if (MTR_TEST(root,MTR_SOFT)) (void) printf("S");
	}
	(void) printf(")");
	if (root->parent == NULL) (void) printf("\n");
    }
    assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
    return;

} /* end of Mtr_PrintGroups */
Exemple #6
0
/**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     []

******************************************************************************/
MtrNode *
Mtr_FindGroup(
  MtrNode * root /* root of the group tree */,
  unsigned int  low /* lower bound of the group */,
  unsigned int  size /* upper bound of the group */)
{
    MtrNode *node;

#ifdef MTR_DEBUG
    /* We cannot have a non-empty proper subgroup of a singleton set. */
    assert(!MTR_TEST(root,MTR_TERMINAL));
#endif

    /* Sanity check. */
    if (size < 1) return(NULL);

    /* Check whether current group includes the group sought.  This
    ** check is necessary at the top-level call.  In the subsequent
    ** calls it is redundant. */
    if (low < (unsigned int) root->low ||
	low + size > (unsigned int) (root->low + root->size))
	return(NULL);

    if (root->size == size && root->low == low)
	return(root);

    if (root->child == NULL)
	return(NULL);

    /* Find all chidren of root that are included in the new group. If
    ** the group of any child entirely contains the new group, call
    ** Mtr_MakeGroup recursively.  */
    node = root->child;
    while (low >= (unsigned int) (node->low + node->size)) {
	node = node->younger;
    }
    if (low + size <= (unsigned int) (node->low + node->size)) {
	/* The group is contained in the group of node. */
	node = Mtr_FindGroup(node, low, size);
	return(node);
    } else {
	return(NULL);
    }

} /* end of Mtr_FindGroup */
Exemple #7
0
/**Function********************************************************************

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

  Description []

  SideEffects [None]

  SeeAlso     [Mtr_PrintGroups]

******************************************************************************/
void
Mtr_PrintTree(
  MtrNode * node)
{
    if (node == NULL) return;
    (void) fprintf(stdout,
#if SIZEOF_VOID_P == 8
    "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n",
    (unsigned long) node, (unsigned long) node->child,
    (unsigned long) node->younger, (unsigned long) node->elder,
    (unsigned long) node->parent, node->flags, node->low, node->size);
#else
    "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n",
    (unsigned) node, (unsigned) node->child,
    (unsigned) node->younger, (unsigned) node->elder,
    (unsigned) node->parent, node->flags, node->low, node->size);
#endif
    if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child);
    Mtr_PrintTree(node->younger);
    return;

} /* end of Mtr_PrintTree */
Exemple #8
0
/**Function********************************************************************

  Synopsis    [Counts the number of internal nodes of the group tree.]

  Description [Counts the number of internal nodes of the group tree.
  Returns the count.]

  SideEffects [None]

******************************************************************************/
static int
zddCountInternalMtrNodes(
  DdManager * table,
  MtrNode * treenode)
{
    MtrNode *auxnode;
    int     count,nodeCount;


    nodeCount = 0;
    auxnode = treenode;
    while (auxnode != NULL) {
	if (!(MTR_TEST(auxnode,MTR_TERMINAL))) {
	    nodeCount++;
	    count = zddCountInternalMtrNodes(table,auxnode->child);
	    nodeCount += count;
	}
	auxnode = auxnode->younger;
    }

    return(nodeCount);

} /* end of zddCountInternalMtrNodes */
Exemple #9
0
/**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]

******************************************************************************/
MtrNode *
Mtr_DissolveGroup(
  MtrNode * group /* group to be dissolved */)
{
    MtrNode *parent;
    MtrNode *last;

    parent = group->parent;

    if (parent == NULL) return(NULL); 

#if 1 
    /* NuSmv change begins */
    if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) {
      if (group->younger != NULL) {
	group->younger->elder = group->elder;
      }
      if (group->elder != NULL) {
	group->elder->younger = group->younger;
      }

      if (parent->child == group) { 
	if (group->elder != NULL) {
	  fprintf(stderr, "FAILING GROUP: low=%d, idx=%d, size=%d\n", 
		  group->low, group->index, group->size);
	  fprintf(stderr, "Elder that should be null: low=%d, idx=%d, size=%d\n", 
		  group->elder->low, group->elder->index, group->elder->size);

	  assert(0);
	  assert(0);
	}
	parent->child = group->younger;
      }
      
      Mtr_DeallocNode(group);

      return parent;
    }
    /* NuSmv change ends */
#else
    if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return NULL; 
#endif

    /* Make all children of group children of its parent, and make
    ** last point to the last child of group. */
    for (last = group->child; last->younger != NULL; last = last->younger) {
	last->parent = parent;
    }
    last->parent = parent;

    last->younger = group->younger;
    if (group->younger != NULL) {
	group->younger->elder = last;
    }

    group->child->elder = group->elder;
    if (group == parent->child) {
	parent->child = group->child;
    } else {
	group->elder->younger = group->child;
    }

    Mtr_DeallocNode(group);
    return(parent);

} /* end of Mtr_DissolveGroup */