/**Function******************************************************************** Synopsis [Visits the group tree and reorders each group.] Description [Recursively visits the group tree and reorders each group in postorder fashion. Returns 1 if successful; 0 otherwise.] SideEffects [None] ******************************************************************************/ static int zddTreeSiftingAux( DdManager * table, MtrNode * treenode, Cudd_ReorderingType method) { MtrNode *auxnode; int res; #ifdef DD_DEBUG Mtr_PrintGroups(treenode,1); #endif auxnode = treenode; while (auxnode != NULL) { if (auxnode->child != NULL) { if (!zddTreeSiftingAux(table, auxnode->child, method)) return(0); res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); if (res == 0) return(0); } else if (auxnode->size > 1) { if (!zddReorderChildren(table, auxnode, method)) return(0); } auxnode = auxnode->younger; } return(1); } /* end of zddTreeSiftingAux */
/**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 */
/**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 */
/**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 */
/**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 */