示例#1
0
/**Function********************************************************************

  Synopsis    [Creates a new ZDD variable group.]

  Description [Creates a new ZDD variable group. The group starts at
  variable and contains size variables. The parameter low is the index
  of the first variable. If the variable already exists, its current
  position in the order is known to the manager. If the variable does
  not exist yet, the position is assumed to be the same as the index.
  The group tree is created if it does not exist yet.
  Returns a pointer to the group if successful; NULL otherwise.]

  SideEffects [The ZDD variable tree is changed.]

  SeeAlso     [Cudd_MakeTreeNode]

******************************************************************************/
MtrNode *
Cudd_MakeZddTreeNode(
  DdManager * dd /* manager */,
  unsigned int  low /* index of the first group variable */,
  unsigned int  size /* number of variables in the group */,
  unsigned int  type /* MTR_DEFAULT or MTR_FIXED */)
{
    MtrNode *group;
    MtrNode *tree;
    unsigned int level;

    /* If the variable does not exist yet, the position is assumed to be
    ** the same as the index. Therefore, applications that rely on
    ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
    ** variables have to create the variables before they group them.
    */
    level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;

    if (level + size - 1> (int) MTR_MAXHIGH)
	return(NULL);

    /* If the tree does not exist yet, create it. */
    tree = dd->treeZ;
    if (tree == NULL) {
	dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ);
	if (tree == NULL)
	    return(NULL);
	tree->index = dd->invpermZ[0];
    }

    /* Extend the upper bound of the tree if necessary. This allows the
    ** application to create groups even before the variables are created.
    */
    tree->size = ddMax(tree->size, level + size);

    /* Create the group. */
    group = Mtr_MakeGroup(tree, level, size, type);
    if (group == NULL)
	return(NULL);

    /* Initialize the index field to the index of the variable currently
    ** in position low. This field will be updated by the reordering
    ** procedure to provide a handle to the group once it has been moved.
    */
    group->index = (MtrHalfWord) low;

    return(group);

} /* end of Cudd_MakeZddTreeNode */
示例#2
0
/**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):
  <ul>
  <li>D: MTR_DEFAULT
  <li>F: MTR_FIXED
  <li>N: MTR_NEWNODE
  <li>S: MTR_SOFT
  <li>T: MTR_TERMINAL
  </ul>
  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]

******************************************************************************/
MtrNode *
Mtr_ReadGroups(
  FILE * fp /* file pointer */,
  int  nleaves /* number of leaves of the new tree */)
{
    int low;
    int size;
    int err;
    unsigned int flags;
    MtrNode *root;
    MtrNode *node;
    char attrib[8*sizeof(unsigned int)+1];
    char *c;

    root = Mtr_InitGroupTree(0,nleaves);
    if (root == NULL) return NULL;

    while (! feof(fp)) {
	/* Read a triple and check for consistency. */
	err = fscanf(fp, "%d %d %s", &low, &size, attrib);
	if (err == EOF) {
	    break;
	} else if (err != 3) {
	    return(NULL);
	} else if (low < 0 || low+size > nleaves || size < 1) {
	    return(NULL);
	} else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) {
	    /* Not enough bits in the flags word to store these many
	    ** attributes. */
	    return(NULL);
	}

	/* Parse the flag string. Currently all flags are permitted,
	** to make debugging easier. Normally, specifying NEWNODE
	** wouldn't be allowed. */
	flags = MTR_DEFAULT;
	for (c=attrib; *c != 0; c++) {
	    switch (*c) {
	    case 'D':
		break;
	    case 'F':
		flags |= MTR_FIXED;
		break;
	    case 'N':
		flags |= MTR_NEWNODE;
		break;
	    case 'S':
		flags |= MTR_SOFT;
		break;
	    case 'T':
		flags |= MTR_TERMINAL;
		break;
	    default:
		return NULL;
	    }
	}
	node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size,
			     flags);
	if (node == NULL) return(NULL);
    }

    return(root);

} /* end of Mtr_ReadGroups */
示例#3
0
文件: testmtr.c 项目: graydon/iimc
/**Function********************************************************************

  Synopsis    [Main program for testmtr.]

  Description [Main program for testmtr.  Performs initialization.
  Reads command line options and network(s).  Builds some simple trees
  and prints them out.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
main(
  int  argc,
  char ** argv)
{
    MtrNode *root,
	    *node;
    int	    i,
	    c,
	    pr = 0;
    FILE    *fp;
    const char *file = NULL;
    
    while ((c = getopt(argc, argv, "Mhp:")) != EOF) {
	switch(c) {
	case 'M':
	    break;
	case 'p':
	    pr = atoi(optarg);
	    break;
	case 'h':
	default:
            printHeader(argc, argv);
	    usage(argv[0]);
	    break;
	}
    }

    if (argc - optind == 0) {
	file = "-";
    } else if (argc - optind == 1) {
	file = argv[optind];
    } else {
        printHeader(argc, argv);
	usage(argv[0]);
    }
    if (pr > 0)
        printHeader(argc, argv);

    /* Create and print a simple tree. */
    root = Mtr_InitTree();
    root->flags = 0;
    node = Mtr_CreateFirstChild(root);
    node->flags = 1;
    node = Mtr_CreateLastChild(root);
    node->flags = 2;
    node = Mtr_CreateFirstChild(root);
    node->flags = 3;
    node = Mtr_AllocNode();
    node->child = NULL;
    node->flags = 4;
    Mtr_MakeNextSibling(root->child,node);
    if (pr > 0) {
        Mtr_PrintTree(root);
        (void) printf("#------------------------\n");
    }
    Mtr_FreeTree(root);

    /* Create an initial tree in which all variables belong to one group. */
    root = Mtr_InitGroupTree(0,12);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    }
    node = Mtr_MakeGroup(root,0,6,MTR_DEFAULT);
    node = Mtr_MakeGroup(root,6,6,MTR_DEFAULT);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    }
    for (i = 0; i < 6; i+=2) {
	node = Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT);
    }
    node = Mtr_MakeGroup(root,0,12,MTR_FIXED);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
        /* Print a partial tree. */
        (void) printf("#  ");
        Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n");
    }
    node = Mtr_FindGroup(root,0,6);
    node = Mtr_DissolveGroup(node);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    }
    node = Mtr_FindGroup(root,4,2);
    if (!Mtr_SwapGroups(node,node->younger)) {
	(void) printf("error in Mtr_SwapGroups\n");
	return 3;
    }
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0);
        (void) printf("#------------------------\n");
    }
    Mtr_FreeTree(root);

    /* Create a group tree with fixed subgroups. */
    root = Mtr_InitGroupTree(0,4);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    }
    node = Mtr_MakeGroup(root,0,2,MTR_FIXED);
    node = Mtr_MakeGroup(root,2,2,MTR_FIXED);
    if (pr > 0) {
        Mtr_PrintTree(root); (void) printf("#  ");
        Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    }
    Mtr_FreeTree(root);
    if (pr > 0) {
        (void) printf("#------------------------\n");
    }

    /* Open input file. */
    fp = open_file(file, "r");
    root = Mtr_ReadGroups(fp,12);
    fclose(fp);
    if (pr > 0) {
        if (root) {
            Mtr_PrintTree(root); (void) printf("#  ");
            Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
        } else {
            (void) printf("error in group file\n");
        }
    }
    Mtr_FreeTree(root);

    return 0;

} /* end of main */
示例#4
0
/**Function********************************************************************

  Synopsis    [Tree sifting algorithm for ZDDs.]

  Description [Tree sifting algorithm for ZDDs. Assumes that a tree
  representing a group hierarchy is passed as a parameter. It then
  reorders each group in postorder fashion by calling
  zddTreeSiftingAux.  Assumes that no dead nodes are present.  Returns
  1 if successful; 0 otherwise.]

  SideEffects [None]

******************************************************************************/
int
cuddZddTreeSifting(
  DdManager * table /* DD table */,
  Cudd_ReorderingType method /* reordering method for the groups of leaves */)
{
    int i;
    int nvars;
    int result;
    int tempTree;

    /* If no tree is provided we create a temporary one in which all
    ** variables are in a single group. After reordering this tree is
    ** destroyed.
    */
    tempTree = table->treeZ == NULL;
    if (tempTree) {
	table->treeZ = Mtr_InitGroupTree(0,table->sizeZ);
	table->treeZ->index = table->invpermZ[0];
    }
    nvars = table->sizeZ;

#ifdef DD_DEBUG
    if (pr > 0 && !tempTree)
	(void) fprintf(table->out,"cuddZddTreeSifting:");
    Mtr_PrintGroups(table->treeZ,pr <= 0);
#endif
#if 0
    /* Debugging code. */
    if (table->tree && table->treeZ) {
	(void) fprintf(table->out,"\n");
	Mtr_PrintGroups(table->tree, 0);
	cuddPrintVarGroups(table,table->tree,0,0);
	for (i = 0; i < table->size; i++) {
	    (void) fprintf(table->out,"%s%d",
			   (i == 0) ? "" : ",", table->invperm[i]);
	}
	(void) fprintf(table->out,"\n");
	for (i = 0; i < table->size; i++) {
	    (void) fprintf(table->out,"%s%d",
			   (i == 0) ? "" : ",", table->perm[i]);
	}
	(void) fprintf(table->out,"\n\n");
	Mtr_PrintGroups(table->treeZ,0);
	cuddPrintVarGroups(table,table->treeZ,1,0);
	for (i = 0; i < table->sizeZ; i++) {
	    (void) fprintf(table->out,"%s%d",
			   (i == 0) ? "" : ",", table->invpermZ[i]);
	}
	(void) fprintf(table->out,"\n");
	for (i = 0; i < table->sizeZ; i++) {
	    (void) fprintf(table->out,"%s%d",
			   (i == 0) ? "" : ",", table->permZ[i]);
	}
	(void) fprintf(table->out,"\n");
    }
    /* End of debugging code. */
#endif
#ifdef DD_STATS
    extsymmcalls = 0;
    extsymm = 0;
    secdiffcalls = 0;
    secdiff = 0;
    secdiffmisfire = 0;

    (void) fprintf(table->out,"\n");
    if (!tempTree)
	(void) fprintf(table->out,"#:IM_NODES  %8d: group tree nodes\n",
		       zddCountInternalMtrNodes(table,table->treeZ));
#endif

    /* Initialize the group of each subtable to itself. Initially
    ** there are no groups. Groups are created according to the tree
    ** structure in postorder fashion.
    */
    for (i = 0; i < nvars; i++)
        table->subtableZ[i].next = i;

    /* Reorder. */
    result = zddTreeSiftingAux(table, table->treeZ, method);

#ifdef DD_STATS		/* print stats */
    if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
	(table->groupcheck == CUDD_GROUP_CHECK7 ||
	 table->groupcheck == CUDD_GROUP_CHECK5)) {
	(void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
	(void) fprintf(table->out,"extsymm = %d",extsymm);
    }
    if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
	table->groupcheck == CUDD_GROUP_CHECK7) {
	(void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
	(void) fprintf(table->out,"secdiff = %d\n",secdiff);
	(void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
    }
#endif

    if (tempTree)
	Cudd_FreeZddTree(table);
    return(result);

} /* end of cuddZddTreeSifting */
示例#5
0
/**Function********************************************************************

  Synopsis    [Main program for testmtr.]

  Description [Main program for testmtr.  Performs initialization.
  Reads command line options and network(s).  Builds some simple trees
  and prints them out.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
main(
  int  argc,
  char ** argv)
{
    MtrNode *root,
	    *node;
    int	    i,
	    c,
	    pr = 0;
    FILE    *fp;
    char    *file = NULL;
    
    (void) printf("# %s\n", TESTMTR_VERSION);
    /* Echo command line and arguments. */
    (void) printf("#");
    for(i = 0; i < argc; i++) {
	(void) printf(" %s", argv[i]);
    }
    (void) printf("\n");
    (void) fflush(stdout);

    while ((c = getopt(argc, argv, "Mhp:")) != EOF) {
	switch(c) {
	case 'M':
#ifdef MNEMOSYNE
	    (void) mnem_setrecording(0);
#endif
	    break;
	case 'p':
	    pr = atoi(optarg);
	    break;
	case 'h':
	default:
	    usage(argv[0]);
	    break;
	}
    }

    if (argc - optind == 0) {
	file = "-";
    } else if (argc - optind == 1) {
	file = argv[optind];
    } else {
	usage(argv[0]);
    }

    /* Create and print a simple tree. */
    root = Mtr_InitTree();
    root->flags = 0;
    node = Mtr_CreateFirstChild(root);
    node->flags = 1;
    node = Mtr_CreateLastChild(root);
    node->flags = 2;
    node = Mtr_CreateFirstChild(root);
    node->flags = 3;
    node = Mtr_AllocNode();
    node->flags = 4;
    Mtr_MakeNextSibling(root->child,node);
    Mtr_PrintTree(root);
    Mtr_FreeTree(root);
    (void) printf("#------------------------\n");

    /* Create an initial tree in which all variables belong to one group. */
    root = Mtr_InitGroupTree(0,12);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    node = Mtr_MakeGroup(root,0,6,MTR_DEFAULT);
    node = Mtr_MakeGroup(root,6,6,MTR_DEFAULT);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    for (i = 0; i < 6; i+=2) {
	node = Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT);
    }
    node = Mtr_MakeGroup(root,0,12,MTR_FIXED);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    /* Print a partial tree. */
    (void) printf("#  ");
    Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n");
    node = Mtr_FindGroup(root,0,6);
    node = Mtr_DissolveGroup(node);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    node = Mtr_FindGroup(root,4,2);
    if (!Mtr_SwapGroups(node,node->younger)) {
	(void) printf("error in Mtr_SwapGroups\n");
	exit(3);
    }
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0);
    Mtr_FreeTree(root);
    (void) printf("#------------------------\n");

    /* Create a group tree with fixed subgroups. */
    root = Mtr_InitGroupTree(0,4);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    node = Mtr_MakeGroup(root,0,2,MTR_FIXED);
    node = Mtr_MakeGroup(root,2,2,MTR_FIXED);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
    Mtr_FreeTree(root);
    (void) printf("#------------------------\n");

    /* Open input file. */
    fp = open_file(file, "r");
    root = Mtr_ReadGroups(fp,12);
    Mtr_PrintTree(root); (void) printf("#  ");
    Mtr_PrintGroups(root,pr == 0); (void) printf("\n");

    Mtr_FreeTree(root);

#ifdef MNEMOSYNE
    mnem_writestats();
#endif

    exit(0);
    /* NOTREACHED */

} /* end of main */