#include "util.h"
#include "cuddInt.h"
Go to the source code of this file.
Functions | |
static int | zp2 (DdManager *zdd, DdNode *f, st_table *t) |
static void | zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list) |
static void | zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list) |
int | Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node) |
int | Cudd_zddPrintCover (DdManager *zdd, DdNode *node) |
int | Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr) |
DdGen * | Cudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path) |
int | Cudd_zddNextPath (DdGen *gen, int **path) |
char * | Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str) |
int | Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp) |
int | cuddZddP (DdManager *zdd, DdNode *f) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddZddUtil.c,v 1.27 2009/03/08 02:49:02 fabio Exp $" |
char* Cudd_zddCoverPathToString | ( | DdManager * | zdd, | |
int * | path, | |||
char * | str | |||
) |
Function********************************************************************
Synopsis [Converts a path of a ZDD representing a cover to a string.]
Description [Converts a path of a ZDD representing a cover to a string. The string represents an implicant of the cover. The path is typically produced by Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL otherwise. If the str input is NULL, it allocates a new string. The string passed to this function must have enough room for all variables and for the terminator.]
SideEffects [None]
SeeAlso [Cudd_zddForeachPath]
Definition at line 471 of file cuddZddUtil.c.
00476 { 00477 int nvars = zdd->sizeZ; 00478 int i; 00479 char *res; 00480 00481 if (nvars & 1) return(NULL); 00482 nvars >>= 1; 00483 if (str == NULL) { 00484 res = ALLOC(char, nvars+1); 00485 if (res == NULL) return(NULL); 00486 } else { 00487 res = str; 00488 } 00489 for (i = 0; i < nvars; i++) { 00490 int v = (path[2*i] << 2) | path[2*i+1]; 00491 switch (v) { 00492 case 0: 00493 case 2: 00494 case 8: 00495 case 10: 00496 res[i] = '-'; 00497 break; 00498 case 1: 00499 case 9: 00500 res[i] = '0'; 00501 break; 00502 case 4: 00503 case 6: 00504 res[i] = '1'; 00505 break; 00506 default: 00507 res[i] = '?'; 00508 } 00509 } 00510 res[nvars] = 0; 00511 00512 return(res); 00513 00514 } /* end of Cudd_zddCoverPathToString */
int Cudd_zddDumpDot | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Writes a dot file representing the argument ZDDs.]
Description [Writes a file representing the argument ZDDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following convention to draw arcs:
The dot options are chosen so that the drawing fits on a letter-size sheet. ]
SideEffects [None]
SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug]
Definition at line 545 of file cuddZddUtil.c.
00552 { 00553 DdNode *support = NULL; 00554 DdNode *scan; 00555 int *sorted = NULL; 00556 int nvars = dd->sizeZ; 00557 st_table *visited = NULL; 00558 st_generator *gen; 00559 int retval; 00560 int i, j; 00561 int slots; 00562 DdNodePtr *nodelist; 00563 long refAddr, diff, mask; 00564 00565 /* Build a bit array with the support of f. */ 00566 sorted = ALLOC(int,nvars); 00567 if (sorted == NULL) { 00568 dd->errorCode = CUDD_MEMORY_OUT; 00569 goto failure; 00570 } 00571 for (i = 0; i < nvars; i++) sorted[i] = 0; 00572 00573 /* Take the union of the supports of each output function. */ 00574 for (i = 0; i < n; i++) { 00575 support = Cudd_Support(dd,f[i]); 00576 if (support == NULL) goto failure; 00577 cuddRef(support); 00578 scan = support; 00579 while (!cuddIsConstant(scan)) { 00580 sorted[scan->index] = 1; 00581 scan = cuddT(scan); 00582 } 00583 Cudd_RecursiveDeref(dd,support); 00584 } 00585 support = NULL; /* so that we do not try to free it in case of failure */ 00586 00587 /* Initialize symbol table for visited nodes. */ 00588 visited = st_init_table(st_ptrcmp, st_ptrhash); 00589 if (visited == NULL) goto failure; 00590 00591 /* Collect all the nodes of this DD in the symbol table. */ 00592 for (i = 0; i < n; i++) { 00593 retval = cuddCollectNodes(f[i],visited); 00594 if (retval == 0) goto failure; 00595 } 00596 00597 /* Find how many most significant hex digits are identical 00598 ** in the addresses of all the nodes. Build a mask based 00599 ** on this knowledge, so that digits that carry no information 00600 ** will not be printed. This is done in two steps. 00601 ** 1. We scan the symbol table to find the bits that differ 00602 ** in at least 2 addresses. 00603 ** 2. We choose one of the possible masks. There are 8 possible 00604 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00605 ** integers. 00606 */ 00607 00608 /* Find the bits that are different. */ 00609 refAddr = (long) f[0]; 00610 diff = 0; 00611 gen = st_init_gen(visited); 00612 while (st_gen(gen, &scan, NULL)) { 00613 diff |= refAddr ^ (long) scan; 00614 } 00615 st_free_gen(gen); 00616 00617 /* Choose the mask. */ 00618 for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { 00619 mask = (1 << i) - 1; 00620 if (diff <= mask) break; 00621 } 00622 00623 /* Write the header and the global attributes. */ 00624 retval = fprintf(fp,"digraph \"ZDD\" {\n"); 00625 if (retval == EOF) return(0); 00626 retval = fprintf(fp, 00627 "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); 00628 if (retval == EOF) return(0); 00629 00630 /* Write the input name subgraph by scanning the support array. */ 00631 retval = fprintf(fp,"{ node [shape = plaintext];\n"); 00632 if (retval == EOF) goto failure; 00633 retval = fprintf(fp," edge [style = invis];\n"); 00634 if (retval == EOF) goto failure; 00635 /* We use a name ("CONST NODES") with an embedded blank, because 00636 ** it is unlikely to appear as an input name. 00637 */ 00638 retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); 00639 if (retval == EOF) goto failure; 00640 for (i = 0; i < nvars; i++) { 00641 if (sorted[dd->invpermZ[i]]) { 00642 if (inames == NULL) { 00643 retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); 00644 } else { 00645 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); 00646 } 00647 if (retval == EOF) goto failure; 00648 } 00649 } 00650 retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); 00651 if (retval == EOF) goto failure; 00652 00653 /* Write the output node subgraph. */ 00654 retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); 00655 if (retval == EOF) goto failure; 00656 for (i = 0; i < n; i++) { 00657 if (onames == NULL) { 00658 retval = fprintf(fp,"\"F%d\"", i); 00659 } else { 00660 retval = fprintf(fp,"\" %s \"", onames[i]); 00661 } 00662 if (retval == EOF) goto failure; 00663 if (i == n - 1) { 00664 retval = fprintf(fp,"; }\n"); 00665 } else { 00666 retval = fprintf(fp," -> "); 00667 } 00668 if (retval == EOF) goto failure; 00669 } 00670 00671 /* Write rank info: All nodes with the same index have the same rank. */ 00672 for (i = 0; i < nvars; i++) { 00673 if (sorted[dd->invpermZ[i]]) { 00674 retval = fprintf(fp,"{ rank = same; "); 00675 if (retval == EOF) goto failure; 00676 if (inames == NULL) { 00677 retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); 00678 } else { 00679 retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); 00680 } 00681 if (retval == EOF) goto failure; 00682 nodelist = dd->subtableZ[i].nodelist; 00683 slots = dd->subtableZ[i].slots; 00684 for (j = 0; j < slots; j++) { 00685 scan = nodelist[j]; 00686 while (scan != NULL) { 00687 if (st_is_member(visited,(char *) scan)) { 00688 retval = fprintf(fp,"\"%p\";\n", (void *) 00689 ((mask & (ptrint) scan) / 00690 sizeof(DdNode))); 00691 if (retval == EOF) goto failure; 00692 } 00693 scan = scan->next; 00694 } 00695 } 00696 retval = fprintf(fp,"}\n"); 00697 if (retval == EOF) goto failure; 00698 } 00699 } 00700 00701 /* All constants have the same rank. */ 00702 retval = fprintf(fp, 00703 "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); 00704 if (retval == EOF) goto failure; 00705 nodelist = dd->constants.nodelist; 00706 slots = dd->constants.slots; 00707 for (j = 0; j < slots; j++) { 00708 scan = nodelist[j]; 00709 while (scan != NULL) { 00710 if (st_is_member(visited,(char *) scan)) { 00711 retval = fprintf(fp,"\"%p\";\n", (void *) 00712 ((mask & (ptrint) scan) / sizeof(DdNode))); 00713 if (retval == EOF) goto failure; 00714 } 00715 scan = scan->next; 00716 } 00717 } 00718 retval = fprintf(fp,"}\n}\n"); 00719 if (retval == EOF) goto failure; 00720 00721 /* Write edge info. */ 00722 /* Edges from the output nodes. */ 00723 for (i = 0; i < n; i++) { 00724 if (onames == NULL) { 00725 retval = fprintf(fp,"\"F%d\"", i); 00726 } else { 00727 retval = fprintf(fp,"\" %s \"", onames[i]); 00728 } 00729 if (retval == EOF) goto failure; 00730 retval = fprintf(fp," -> \"%p\" [style = solid];\n", 00731 (void *) ((mask & (ptrint) f[i]) / 00732 sizeof(DdNode))); 00733 if (retval == EOF) goto failure; 00734 } 00735 00736 /* Edges from internal nodes. */ 00737 for (i = 0; i < nvars; i++) { 00738 if (sorted[dd->invpermZ[i]]) { 00739 nodelist = dd->subtableZ[i].nodelist; 00740 slots = dd->subtableZ[i].slots; 00741 for (j = 0; j < slots; j++) { 00742 scan = nodelist[j]; 00743 while (scan != NULL) { 00744 if (st_is_member(visited,(char *) scan)) { 00745 retval = fprintf(fp, 00746 "\"%p\" -> \"%p\";\n", 00747 (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), 00748 (void *) ((mask & (ptrint) cuddT(scan)) / 00749 sizeof(DdNode))); 00750 if (retval == EOF) goto failure; 00751 retval = fprintf(fp, 00752 "\"%p\" -> \"%p\" [style = dashed];\n", 00753 (void *) ((mask & (ptrint) scan) 00754 / sizeof(DdNode)), 00755 (void *) ((mask & (ptrint) 00756 cuddE(scan)) / 00757 sizeof(DdNode))); 00758 if (retval == EOF) goto failure; 00759 } 00760 scan = scan->next; 00761 } 00762 } 00763 } 00764 } 00765 00766 /* Write constant labels. */ 00767 nodelist = dd->constants.nodelist; 00768 slots = dd->constants.slots; 00769 for (j = 0; j < slots; j++) { 00770 scan = nodelist[j]; 00771 while (scan != NULL) { 00772 if (st_is_member(visited,(char *) scan)) { 00773 retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", 00774 (void *) ((mask & (ptrint) scan) / 00775 sizeof(DdNode)), 00776 cuddV(scan)); 00777 if (retval == EOF) goto failure; 00778 } 00779 scan = scan->next; 00780 } 00781 } 00782 00783 /* Write trailer and return. */ 00784 retval = fprintf(fp,"}\n"); 00785 if (retval == EOF) goto failure; 00786 00787 st_free_table(visited); 00788 FREE(sorted); 00789 return(1); 00790 00791 failure: 00792 if (sorted != NULL) FREE(sorted); 00793 if (visited != NULL) st_free_table(visited); 00794 return(0); 00795 00796 } /* end of Cudd_zddDumpBlif */
Function********************************************************************
Synopsis [Finds the first path of a ZDD.]
Description [Defines an iterator on the paths of a ZDD and finds its first path. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
A path is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc out of a node, and 2 stands for the absence of a node. The size of the array equals the number of variables in the manager at the time Cudd_zddFirstCube is called.
The paths that end in the empty terminal are not enumerated.]
SideEffects [The first path is returned as a side effect.]
SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree Cudd_IsGenEmpty]
Definition at line 271 of file cuddZddUtil.c.
00275 { 00276 DdGen *gen; 00277 DdNode *top, *next, *prev; 00278 int i; 00279 int nvars; 00280 00281 /* Sanity Check. */ 00282 if (zdd == NULL || f == NULL) return(NULL); 00283 00284 /* Allocate generator an initialize it. */ 00285 gen = ALLOC(DdGen,1); 00286 if (gen == NULL) { 00287 zdd->errorCode = CUDD_MEMORY_OUT; 00288 return(NULL); 00289 } 00290 00291 gen->manager = zdd; 00292 gen->type = CUDD_GEN_ZDD_PATHS; 00293 gen->status = CUDD_GEN_EMPTY; 00294 gen->gen.cubes.cube = NULL; 00295 gen->gen.cubes.value = DD_ZERO_VAL; 00296 gen->stack.sp = 0; 00297 gen->stack.stack = NULL; 00298 gen->node = NULL; 00299 00300 nvars = zdd->sizeZ; 00301 gen->gen.cubes.cube = ALLOC(int,nvars); 00302 if (gen->gen.cubes.cube == NULL) { 00303 zdd->errorCode = CUDD_MEMORY_OUT; 00304 FREE(gen); 00305 return(NULL); 00306 } 00307 for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; 00308 00309 /* The maximum stack depth is one plus the number of variables. 00310 ** because a path may have nodes at all levels, including the 00311 ** constant level. 00312 */ 00313 gen->stack.stack = ALLOC(DdNodePtr, nvars+1); 00314 if (gen->stack.stack == NULL) { 00315 zdd->errorCode = CUDD_MEMORY_OUT; 00316 FREE(gen->gen.cubes.cube); 00317 FREE(gen); 00318 return(NULL); 00319 } 00320 for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; 00321 00322 /* Find the first path of the ZDD. */ 00323 gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; 00324 00325 while (1) { 00326 top = gen->stack.stack[gen->stack.sp-1]; 00327 if (!cuddIsConstant(Cudd_Regular(top))) { 00328 /* Take the else branch first. */ 00329 gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; 00330 next = cuddE(Cudd_Regular(top)); 00331 gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; 00332 } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { 00333 /* Backtrack. */ 00334 while (1) { 00335 if (gen->stack.sp == 1) { 00336 /* The current node has no predecessor. */ 00337 gen->status = CUDD_GEN_EMPTY; 00338 gen->stack.sp--; 00339 goto done; 00340 } 00341 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00342 next = cuddT(prev); 00343 if (next != top) { /* follow the then branch next */ 00344 gen->gen.cubes.cube[prev->index] = 1; 00345 gen->stack.stack[gen->stack.sp-1] = next; 00346 break; 00347 } 00348 /* Pop the stack and try again. */ 00349 gen->gen.cubes.cube[prev->index] = 2; 00350 gen->stack.sp--; 00351 top = gen->stack.stack[gen->stack.sp-1]; 00352 } 00353 } else { 00354 gen->status = CUDD_GEN_NONEMPTY; 00355 gen->gen.cubes.value = cuddV(Cudd_Regular(top)); 00356 goto done; 00357 } 00358 } 00359 00360 done: 00361 *path = gen->gen.cubes.cube; 00362 return(gen); 00363 00364 } /* end of Cudd_zddFirstPath */
int Cudd_zddNextPath | ( | DdGen * | gen, | |
int ** | path | |||
) |
Function********************************************************************
Synopsis [Generates the next path of a ZDD.]
Description [Generates the next path of a ZDD onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The path is returned as a side effect. The generator is modified.]
SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree Cudd_IsGenEmpty]
Definition at line 383 of file cuddZddUtil.c.
00386 { 00387 DdNode *top, *next, *prev; 00388 DdManager *zdd = gen->manager; 00389 00390 /* Backtrack from previously reached terminal node. */ 00391 while (1) { 00392 if (gen->stack.sp == 1) { 00393 /* The current node has no predecessor. */ 00394 gen->status = CUDD_GEN_EMPTY; 00395 gen->stack.sp--; 00396 goto done; 00397 } 00398 top = gen->stack.stack[gen->stack.sp-1]; 00399 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00400 next = cuddT(prev); 00401 if (next != top) { /* follow the then branch next */ 00402 gen->gen.cubes.cube[prev->index] = 1; 00403 gen->stack.stack[gen->stack.sp-1] = next; 00404 break; 00405 } 00406 /* Pop the stack and try again. */ 00407 gen->gen.cubes.cube[prev->index] = 2; 00408 gen->stack.sp--; 00409 } 00410 00411 while (1) { 00412 top = gen->stack.stack[gen->stack.sp-1]; 00413 if (!cuddIsConstant(Cudd_Regular(top))) { 00414 /* Take the else branch first. */ 00415 gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; 00416 next = cuddE(Cudd_Regular(top)); 00417 gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; 00418 } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { 00419 /* Backtrack. */ 00420 while (1) { 00421 if (gen->stack.sp == 1) { 00422 /* The current node has no predecessor. */ 00423 gen->status = CUDD_GEN_EMPTY; 00424 gen->stack.sp--; 00425 goto done; 00426 } 00427 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00428 next = cuddT(prev); 00429 if (next != top) { /* follow the then branch next */ 00430 gen->gen.cubes.cube[prev->index] = 1; 00431 gen->stack.stack[gen->stack.sp-1] = next; 00432 break; 00433 } 00434 /* Pop the stack and try again. */ 00435 gen->gen.cubes.cube[prev->index] = 2; 00436 gen->stack.sp--; 00437 top = gen->stack.stack[gen->stack.sp-1]; 00438 } 00439 } else { 00440 gen->status = CUDD_GEN_NONEMPTY; 00441 gen->gen.cubes.value = cuddV(Cudd_Regular(top)); 00442 goto done; 00443 } 00444 } 00445 00446 done: 00447 if (gen->status == CUDD_GEN_EMPTY) return(0); 00448 *path = gen->gen.cubes.cube; 00449 return(1); 00450 00451 } /* end of Cudd_zddNextPath */
Function********************************************************************
Synopsis [Prints a sum of products from a ZDD representing a cover.]
Description [Prints a sum of products from a ZDD representing a cover. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPrintMinterm]
Definition at line 165 of file cuddZddUtil.c.
00168 { 00169 int i, size; 00170 int *list; 00171 00172 size = (int)zdd->sizeZ; 00173 if (size % 2 != 0) return(0); /* number of variables should be even */ 00174 list = ALLOC(int, size); 00175 if (list == NULL) { 00176 zdd->errorCode = CUDD_MEMORY_OUT; 00177 return(0); 00178 } 00179 for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ 00180 zddPrintCoverAux(zdd, node, 0, list); 00181 FREE(list); 00182 return(1); 00183 00184 } /* end of Cudd_zddPrintCover */
Function********************************************************************
Synopsis [Prints to the standard output a ZDD and its statistics.]
Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes and the number of minterms. (The number of minterms is also the number of combinations in the set.) The statistics are printed if pr > 0. Specifically:
Returns 1 if successful; 0 otherwise. ]
SideEffects [None]
SeeAlso []
Definition at line 211 of file cuddZddUtil.c.
00216 { 00217 DdNode *empty = DD_ZERO(zdd); 00218 int nodes; 00219 double minterms; 00220 int retval = 1; 00221 00222 if (f == empty && pr > 0) { 00223 (void) fprintf(zdd->out,": is the empty ZDD\n"); 00224 (void) fflush(zdd->out); 00225 return(1); 00226 } 00227 00228 if (pr > 0) { 00229 nodes = Cudd_zddDagSize(f); 00230 if (nodes == CUDD_OUT_OF_MEM) retval = 0; 00231 minterms = Cudd_zddCountMinterm(zdd, f, n); 00232 if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; 00233 (void) fprintf(zdd->out,": %d nodes %g minterms\n", 00234 nodes, minterms); 00235 if (pr > 2) 00236 if (!cuddZddP(zdd, f)) retval = 0; 00237 if (pr == 2 || pr > 3) { 00238 if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; 00239 (void) fprintf(zdd->out,"\n"); 00240 } 00241 (void) fflush(zdd->out); 00242 } 00243 return(retval); 00244 00245 } /* end of Cudd_zddPrintDebug */
AutomaticEnd Function********************************************************************
Synopsis [Prints a disjoint sum of product form for a ZDD.]
Description [Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover]
Definition at line 131 of file cuddZddUtil.c.
00134 { 00135 int i, size; 00136 int *list; 00137 00138 size = (int)zdd->sizeZ; 00139 list = ALLOC(int, size); 00140 if (list == NULL) { 00141 zdd->errorCode = CUDD_MEMORY_OUT; 00142 return(0); 00143 } 00144 for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ 00145 zdd_print_minterm_aux(zdd, node, 0, list); 00146 FREE(list); 00147 return(1); 00148 00149 } /* end of Cudd_zddPrintMinterm */
Function********************************************************************
Synopsis [Prints a ZDD to the standard output. One line per node is printed.]
Description [Prints a ZDD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPrintDebug]
Definition at line 818 of file cuddZddUtil.c.
00821 { 00822 int retval; 00823 st_table *table = st_init_table(st_ptrcmp, st_ptrhash); 00824 00825 if (table == NULL) return(0); 00826 00827 retval = zp2(zdd, f, table); 00828 st_free_table(table); 00829 (void) fputc('\n', zdd->out); 00830 return(retval); 00831 00832 } /* end of cuddZddP */
static void zdd_print_minterm_aux | ( | DdManager * | zdd, | |
DdNode * | node, | |||
int | level, | |||
int * | list | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_zddPrintMinterm.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 934 of file cuddZddUtil.c.
00939 { 00940 DdNode *Nv, *Nnv; 00941 int i, v; 00942 DdNode *base = DD_ONE(zdd); 00943 00944 if (Cudd_IsConstant(node)) { 00945 if (node == base) { 00946 /* Check for missing variable. */ 00947 if (level != zdd->sizeZ) { 00948 list[zdd->invpermZ[level]] = 0; 00949 zdd_print_minterm_aux(zdd, node, level + 1, list); 00950 return; 00951 } 00952 /* Terminal case: Print one cube based on the current recursion 00953 ** path. 00954 */ 00955 for (i = 0; i < zdd->sizeZ; i++) { 00956 v = list[i]; 00957 if (v == 0) 00958 (void) fprintf(zdd->out,"0"); 00959 else if (v == 1) 00960 (void) fprintf(zdd->out,"1"); 00961 else if (v == 3) 00962 (void) fprintf(zdd->out,"@"); /* should never happen */ 00963 else 00964 (void) fprintf(zdd->out,"-"); 00965 } 00966 (void) fprintf(zdd->out," 1\n"); 00967 } 00968 } else { 00969 /* Check for missing variable. */ 00970 if (level != cuddIZ(zdd,node->index)) { 00971 list[zdd->invpermZ[level]] = 0; 00972 zdd_print_minterm_aux(zdd, node, level + 1, list); 00973 return; 00974 } 00975 00976 Nnv = cuddE(node); 00977 Nv = cuddT(node); 00978 if (Nv == Nnv) { 00979 list[node->index] = 2; 00980 zdd_print_minterm_aux(zdd, Nnv, level + 1, list); 00981 return; 00982 } 00983 00984 list[node->index] = 1; 00985 zdd_print_minterm_aux(zdd, Nv, level + 1, list); 00986 list[node->index] = 0; 00987 zdd_print_minterm_aux(zdd, Nnv, level + 1, list); 00988 } 00989 return; 00990 00991 } /* end of zdd_print_minterm_aux */
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_zddPrintCover.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 1006 of file cuddZddUtil.c.
01011 { 01012 DdNode *Nv, *Nnv; 01013 int i, v; 01014 DdNode *base = DD_ONE(zdd); 01015 01016 if (Cudd_IsConstant(node)) { 01017 if (node == base) { 01018 /* Check for missing variable. */ 01019 if (level != zdd->sizeZ) { 01020 list[zdd->invpermZ[level]] = 0; 01021 zddPrintCoverAux(zdd, node, level + 1, list); 01022 return; 01023 } 01024 /* Terminal case: Print one cube based on the current recursion 01025 ** path. 01026 */ 01027 for (i = 0; i < zdd->sizeZ; i += 2) { 01028 v = list[i] * 4 + list[i+1]; 01029 if (v == 0) 01030 (void) putc('-',zdd->out); 01031 else if (v == 4) 01032 (void) putc('1',zdd->out); 01033 else if (v == 1) 01034 (void) putc('0',zdd->out); 01035 else 01036 (void) putc('@',zdd->out); /* should never happen */ 01037 } 01038 (void) fprintf(zdd->out," 1\n"); 01039 } 01040 } else { 01041 /* Check for missing variable. */ 01042 if (level != cuddIZ(zdd,node->index)) { 01043 list[zdd->invpermZ[level]] = 0; 01044 zddPrintCoverAux(zdd, node, level + 1, list); 01045 return; 01046 } 01047 01048 Nnv = cuddE(node); 01049 Nv = cuddT(node); 01050 if (Nv == Nnv) { 01051 list[node->index] = 2; 01052 zddPrintCoverAux(zdd, Nnv, level + 1, list); 01053 return; 01054 } 01055 01056 list[node->index] = 1; 01057 zddPrintCoverAux(zdd, Nv, level + 1, list); 01058 list[node->index] = 0; 01059 zddPrintCoverAux(zdd, Nnv, level + 1, list); 01060 } 01061 return; 01062 01063 } /* end of zddPrintCoverAux */
AutomaticStart
Function********************************************************************
Synopsis [Performs the recursive step of cuddZddP.]
Description [Performs the recursive step of cuddZddP. Returns 1 in case of success; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 853 of file cuddZddUtil.c.
00857 { 00858 DdNode *n; 00859 int T, E; 00860 DdNode *base = DD_ONE(zdd); 00861 00862 if (f == NULL) 00863 return(0); 00864 00865 if (Cudd_IsConstant(f)) { 00866 (void)fprintf(zdd->out, "ID = %d\n", (f == base)); 00867 return(1); 00868 } 00869 if (st_is_member(t, (char *)f) == 1) 00870 return(1); 00871 00872 if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) 00873 return(0); 00874 00875 #if SIZEOF_VOID_P == 8 00876 (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", 00877 (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); 00878 #else 00879 (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", 00880 (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); 00881 #endif 00882 00883 n = cuddT(f); 00884 if (Cudd_IsConstant(n)) { 00885 (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); 00886 T = 1; 00887 } else { 00888 #if SIZEOF_VOID_P == 8 00889 (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / 00890 (ptruint) sizeof(DdNode)); 00891 #else 00892 (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / 00893 (ptruint) sizeof(DdNode)); 00894 #endif 00895 T = 0; 00896 } 00897 00898 n = cuddE(f); 00899 if (Cudd_IsConstant(n)) { 00900 (void) fprintf(zdd->out, "E = %d\n", (n == base)); 00901 E = 1; 00902 } else { 00903 #if SIZEOF_VOID_P == 8 00904 (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / 00905 (ptruint) sizeof(DdNode)); 00906 #else 00907 (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / 00908 (ptruint) sizeof(DdNode)); 00909 #endif 00910 E = 0; 00911 } 00912 00913 if (E == 0) 00914 if (zp2(zdd, cuddE(f), t) == 0) return(0); 00915 if (T == 0) 00916 if (zp2(zdd, cuddT(f), t) == 0) return(0); 00917 return(1); 00918 00919 } /* end of zp2 */
char rcsid [] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.27 2009/03/08 02:49:02 fabio Exp $" [static] |
CFile***********************************************************************
FileName [cuddZddUtil.c]
PackageName [cudd]
Synopsis [Utility functions for ZDDs.]
Description [External procedures included in this module:
Internal procedures included in this module:
Static procedures included in this module:
]
SeeAlso []
Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi]
Copyright [Copyright (c) 1995-2004, 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.]
Definition at line 92 of file cuddZddUtil.c.