You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
450 lines
13 KiB
450 lines
13 KiB
/**CFile***********************************************************************
|
|
|
|
FileName [mtrBasic.c]
|
|
|
|
PackageName [mtr]
|
|
|
|
Synopsis [Basic manipulation of multiway branching trees.]
|
|
|
|
Description [External procedures included in this module:
|
|
<ul>
|
|
<li> Mtr_AllocNode()
|
|
<li> Mtr_DeallocNode()
|
|
<li> Mtr_InitTree()
|
|
<li> Mtr_FreeTree()
|
|
<li> Mtr_CopyTree()
|
|
<li> Mtr_MakeFirstChild()
|
|
<li> Mtr_MakeLastChild()
|
|
<li> Mtr_CreateFirstChild()
|
|
<li> Mtr_CreateLastChild()
|
|
<li> Mtr_MakeNextSibling()
|
|
<li> Mtr_PrintTree()
|
|
</ul>
|
|
]
|
|
|
|
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.]
|
|
|
|
******************************************************************************/
|
|
|
|
#include "util.h"
|
|
#include "mtrInt.h"
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Constant declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Stucture declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Type declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Variable declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.15 2012/02/05 01:06:19 fabio Exp $";
|
|
#endif
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Macro declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/**AutomaticStart*************************************************************/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Static function prototypes */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/**AutomaticEnd***************************************************************/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of exported functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Allocates new tree node.]
|
|
|
|
Description [Allocates new tree node. Returns pointer to node.]
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso [Mtr_DeallocNode]
|
|
|
|
******************************************************************************/
|
|
MtrNode *
|
|
Mtr_AllocNode(void)
|
|
{
|
|
MtrNode *node;
|
|
|
|
node = ALLOC(MtrNode,1);
|
|
return node;
|
|
|
|
} /* Mtr_AllocNode */
|
|
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Deallocates tree node.]
|
|
|
|
Description []
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso [Mtr_AllocNode]
|
|
|
|
******************************************************************************/
|
|
void
|
|
Mtr_DeallocNode(
|
|
MtrNode * node /* node to be deallocated */)
|
|
{
|
|
FREE(node);
|
|
return;
|
|
|
|
} /* end of Mtr_DeallocNode */
|
|
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Initializes tree with one node.]
|
|
|
|
Description [Initializes tree with one node. Returns pointer to node.]
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso [Mtr_FreeTree Mtr_InitGroupTree]
|
|
|
|
******************************************************************************/
|
|
MtrNode *
|
|
Mtr_InitTree(void)
|
|
{
|
|
MtrNode *node;
|
|
|
|
node = Mtr_AllocNode();
|
|
if (node == NULL) return(NULL);
|
|
|
|
node->parent = node->child = node->elder = node->younger = NULL;
|
|
node->flags = 0;
|
|
|
|
return(node);
|
|
|
|
} /* end of Mtr_InitTree */
|
|
|
|
|
|
/**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 */
|
|
|
|
|
|
/**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]
|
|
|
|
******************************************************************************/
|
|
MtrNode *
|
|
Mtr_CopyTree(
|
|
MtrNode * node,
|
|
int expansion)
|
|
{
|
|
MtrNode *copy;
|
|
|
|
if (node == NULL) return(NULL);
|
|
if (expansion < 1) return(NULL);
|
|
copy = Mtr_AllocNode();
|
|
if (copy == NULL) return(NULL);
|
|
copy->parent = copy->elder = copy->child = copy->younger = NULL;
|
|
if (node->child != NULL) {
|
|
copy->child = Mtr_CopyTree(node->child, expansion);
|
|
if (copy->child == NULL) {
|
|
Mtr_DeallocNode(copy);
|
|
return(NULL);
|
|
}
|
|
}
|
|
if (node->younger != NULL) {
|
|
copy->younger = Mtr_CopyTree(node->younger, expansion);
|
|
if (copy->younger == NULL) {
|
|
Mtr_FreeTree(copy);
|
|
return(NULL);
|
|
}
|
|
}
|
|
copy->flags = node->flags;
|
|
copy->low = node->low * expansion;
|
|
copy->size = node->size * expansion;
|
|
copy->index = node->index * expansion;
|
|
if (copy->younger) copy->younger->elder = copy;
|
|
if (copy->child) {
|
|
MtrNode *auxnode = copy->child;
|
|
while (auxnode != NULL) {
|
|
auxnode->parent = copy;
|
|
auxnode = auxnode->younger;
|
|
}
|
|
}
|
|
return(copy);
|
|
|
|
} /* end of Mtr_CopyTree */
|
|
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Makes child the first child of parent.]
|
|
|
|
Description []
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild]
|
|
|
|
******************************************************************************/
|
|
void
|
|
Mtr_MakeFirstChild(
|
|
MtrNode * parent,
|
|
MtrNode * child)
|
|
{
|
|
child->parent = parent;
|
|
child->younger = parent->child;
|
|
child->elder = NULL;
|
|
if (parent->child != NULL) {
|
|
#ifdef MTR_DEBUG
|
|
assert(parent->child->elder == NULL);
|
|
#endif
|
|
parent->child->elder = child;
|
|
}
|
|
parent->child = child;
|
|
return;
|
|
|
|
} /* end of Mtr_MakeFirstChild */
|
|
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Makes child the last child of parent.]
|
|
|
|
Description []
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild]
|
|
|
|
******************************************************************************/
|
|
void
|
|
Mtr_MakeLastChild(
|
|
MtrNode * parent,
|
|
MtrNode * child)
|
|
{
|
|
MtrNode *node;
|
|
|
|
child->younger = NULL;
|
|
|
|
if (parent->child == NULL) {
|
|
parent->child = child;
|
|
child->elder = NULL;
|
|
} else {
|
|
for (node = parent->child;
|
|
node->younger != NULL;
|
|
node = node->younger);
|
|
node->younger = child;
|
|
child->elder = node;
|
|
}
|
|
child->parent = parent;
|
|
return;
|
|
|
|
} /* end of Mtr_MakeLastChild */
|
|
|
|
|
|
/**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]
|
|
|
|
******************************************************************************/
|
|
MtrNode *
|
|
Mtr_CreateFirstChild(
|
|
MtrNode * parent)
|
|
{
|
|
MtrNode *child;
|
|
|
|
child = Mtr_AllocNode();
|
|
if (child == NULL) return(NULL);
|
|
|
|
child->child = NULL;
|
|
child->flags = 0;
|
|
Mtr_MakeFirstChild(parent,child);
|
|
return(child);
|
|
|
|
} /* end of Mtr_CreateFirstChild */
|
|
|
|
|
|
/**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]
|
|
|
|
******************************************************************************/
|
|
MtrNode *
|
|
Mtr_CreateLastChild(
|
|
MtrNode * parent)
|
|
{
|
|
MtrNode *child;
|
|
|
|
child = Mtr_AllocNode();
|
|
if (child == NULL) return(NULL);
|
|
|
|
child->child = NULL;
|
|
child->flags = 0;
|
|
Mtr_MakeLastChild(parent,child);
|
|
return(child);
|
|
|
|
} /* end of Mtr_CreateLastChild */
|
|
|
|
|
|
/**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 []
|
|
|
|
******************************************************************************/
|
|
void
|
|
Mtr_MakeNextSibling(
|
|
MtrNode * first,
|
|
MtrNode * second)
|
|
{
|
|
second->parent = first->parent;
|
|
second->elder = first;
|
|
second->younger = first->younger;
|
|
if (first->younger != NULL) {
|
|
first->younger->elder = second;
|
|
}
|
|
first->younger = second;
|
|
return;
|
|
|
|
} /* end of Mtr_MakeNextSibling */
|
|
|
|
|
|
/**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 */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of internal functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of static functions */
|
|
/*---------------------------------------------------------------------------*/
|