src/bdd/cudd/cuddZddUtil.c File Reference

#include "util_hack.h"
#include "cuddInt.h"
Include dependency graph for cuddZddUtil.c:

Go to the source code of this file.

Functions

static int zp2 ARGS ((DdManager *zdd, DdNode *f, st_table *t))
static void zdd_print_minterm_aux ARGS ((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)
DdGenCudd_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)
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)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"

Function Documentation

static void zddPrintCoverAux ARGS ( (DdManager *zdd, DdNode *node, int level, int *list)   )  [static]
static int zp2 ARGS ( (DdManager *zdd, DdNode *f, st_table *t)   )  [static]

AutomaticStart

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 440 of file cuddZddUtil.c.

00445 {
00446     int nvars = zdd->sizeZ;
00447     int i;
00448     char *res;
00449 
00450     if (nvars & 1) return(NULL);
00451     nvars >>= 1;
00452     if (str == NULL) {
00453         res = ALLOC(char, nvars+1);
00454         if (res == NULL) return(NULL);
00455     } else {
00456         res = str;
00457     }
00458     for (i = 0; i < nvars; i++) {
00459         int v = (path[2*i] << 2) | path[2*i+1];
00460         switch (v) {
00461         case 0:
00462         case 2:
00463         case 8:
00464         case 10:
00465             res[i] = '-';
00466             break;
00467         case 1:
00468         case 9:
00469             res[i] = '0';
00470             break;
00471         case 4:
00472         case 6:
00473             res[i] = '1';
00474             break;
00475         default:
00476             res[i] = '?';
00477         }
00478     }
00479     res[nvars] = 0;
00480 
00481     return(res);
00482 
00483 } /* 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:

  • solid line: THEN arcs;
  • dashed line: ELSE 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 514 of file cuddZddUtil.c.

00521 {
00522     DdNode      *support = NULL;
00523     DdNode      *scan;
00524     int         *sorted = NULL;
00525     int         nvars = dd->sizeZ;
00526     st_table    *visited = NULL;
00527     st_generator *gen;
00528     int         retval;
00529     int         i, j;
00530     int         slots;
00531     DdNodePtr   *nodelist;
00532     long        refAddr, diff, mask;
00533 
00534     /* Build a bit array with the support of f. */
00535     sorted = ALLOC(int,nvars);
00536     if (sorted == NULL) {
00537         dd->errorCode = CUDD_MEMORY_OUT;
00538         goto failure;
00539     }
00540     for (i = 0; i < nvars; i++) sorted[i] = 0;
00541 
00542     /* Take the union of the supports of each output function. */
00543     for (i = 0; i < n; i++) {
00544         support = Cudd_Support(dd,f[i]);
00545         if (support == NULL) goto failure;
00546         cuddRef(support);
00547         scan = support;
00548         while (!cuddIsConstant(scan)) {
00549             sorted[scan->index] = 1;
00550             scan = cuddT(scan);
00551         }
00552         Cudd_RecursiveDeref(dd,support);
00553     }
00554     support = NULL; /* so that we do not try to free it in case of failure */
00555 
00556     /* Initialize symbol table for visited nodes. */
00557     visited = st_init_table(st_ptrcmp, st_ptrhash);
00558     if (visited == NULL) goto failure;
00559 
00560     /* Collect all the nodes of this DD in the symbol table. */
00561     for (i = 0; i < n; i++) {
00562         retval = cuddCollectNodes(f[i],visited);
00563         if (retval == 0) goto failure;
00564     }
00565 
00566     /* Find how many most significant hex digits are identical
00567     ** in the addresses of all the nodes. Build a mask based
00568     ** on this knowledge, so that digits that carry no information
00569     ** will not be printed. This is done in two steps.
00570     **  1. We scan the symbol table to find the bits that differ
00571     **     in at least 2 addresses.
00572     **  2. We choose one of the possible masks. There are 8 possible
00573     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00574     **     integers.
00575     */
00576 
00577     /* Find the bits that are different. */
00578     refAddr = (long) f[0];
00579     diff = 0;
00580     gen = st_init_gen(visited);
00581     while (st_gen(gen, (char **) &scan, NULL)) {
00582         diff |= refAddr ^ (long) scan;
00583     }
00584     st_free_gen(gen);
00585 
00586     /* Choose the mask. */
00587     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00588         mask = (1 << i) - 1;
00589         if (diff <= mask) break;
00590     }
00591 
00592     /* Write the header and the global attributes. */
00593     retval = fprintf(fp,"digraph \"ZDD\" {\n");
00594     if (retval == EOF) return(0);
00595     retval = fprintf(fp,
00596         "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n");
00597     if (retval == EOF) return(0);
00598 
00599     /* Write the input name subgraph by scanning the support array. */
00600     retval = fprintf(fp,"{ node [shape = plaintext];\n");
00601     if (retval == EOF) goto failure;
00602     retval = fprintf(fp,"  edge [style = invis];\n");
00603     if (retval == EOF) goto failure;
00604     /* We use a name ("CONST NODES") with an embedded blank, because
00605     ** it is unlikely to appear as an input name.
00606     */
00607     retval = fprintf(fp,"  \"CONST NODES\" [style = invis];\n");
00608     if (retval == EOF) goto failure;
00609     for (i = 0; i < nvars; i++) {
00610         if (sorted[dd->invpermZ[i]]) {
00611             if (inames == NULL) {
00612                 retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]);
00613             } else {
00614                 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]);
00615             }
00616             if (retval == EOF) goto failure;
00617         }
00618     }
00619     retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
00620     if (retval == EOF) goto failure;
00621 
00622     /* Write the output node subgraph. */
00623     retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n");
00624     if (retval == EOF) goto failure;
00625     for (i = 0; i < n; i++) {
00626         if (onames == NULL) {
00627             retval = fprintf(fp,"\"F%d\"", i);
00628         } else {
00629             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00630         }
00631         if (retval == EOF) goto failure;
00632         if (i == n - 1) {
00633             retval = fprintf(fp,"; }\n");
00634         } else {
00635             retval = fprintf(fp," -> ");
00636         }
00637         if (retval == EOF) goto failure;
00638     }
00639 
00640     /* Write rank info: All nodes with the same index have the same rank. */
00641     for (i = 0; i < nvars; i++) {
00642         if (sorted[dd->invpermZ[i]]) {
00643             retval = fprintf(fp,"{ rank = same; ");
00644             if (retval == EOF) goto failure;
00645             if (inames == NULL) {
00646                 retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]);
00647             } else {
00648                 retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]);
00649             }
00650             if (retval == EOF) goto failure;
00651             nodelist = dd->subtableZ[i].nodelist;
00652             slots = dd->subtableZ[i].slots;
00653             for (j = 0; j < slots; j++) {
00654                 scan = nodelist[j];
00655                 while (scan != NULL) {
00656                     if (st_is_member(visited,(char *) scan)) {
00657                         retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
00658                         if (retval == EOF) goto failure;
00659                     }
00660                     scan = scan->next;
00661                 }
00662             }
00663             retval = fprintf(fp,"}\n");
00664             if (retval == EOF) goto failure;
00665         }
00666     }
00667 
00668     /* All constants have the same rank. */
00669     retval = fprintf(fp,
00670         "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; ");
00671     if (retval == EOF) goto failure;
00672     nodelist = dd->constants.nodelist;
00673     slots = dd->constants.slots;
00674     for (j = 0; j < slots; j++) {
00675         scan = nodelist[j];
00676         while (scan != NULL) {
00677             if (st_is_member(visited,(char *) scan)) {
00678                 retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
00679                 if (retval == EOF) goto failure;
00680             }
00681             scan = scan->next;
00682         }
00683     }
00684     retval = fprintf(fp,"}\n}\n");
00685     if (retval == EOF) goto failure;
00686 
00687     /* Write edge info. */
00688     /* Edges from the output nodes. */
00689     for (i = 0; i < n; i++) {
00690         if (onames == NULL) {
00691             retval = fprintf(fp,"\"F%d\"", i);
00692         } else {
00693             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00694         }
00695         if (retval == EOF) goto failure;
00696         retval = fprintf(fp," -> \"%lx\" [style = solid];\n",
00697                          (mask & (long) f[i]) / sizeof(DdNode));
00698         if (retval == EOF) goto failure;
00699     }
00700 
00701     /* Edges from internal nodes. */
00702     for (i = 0; i < nvars; i++) {
00703         if (sorted[dd->invpermZ[i]]) {
00704             nodelist = dd->subtableZ[i].nodelist;
00705             slots = dd->subtableZ[i].slots;
00706             for (j = 0; j < slots; j++) {
00707                 scan = nodelist[j];
00708                 while (scan != NULL) {
00709                     if (st_is_member(visited,(char *) scan)) {
00710                         retval = fprintf(fp,
00711                             "\"%lx\" -> \"%lx\";\n",
00712                             (mask & (long) scan) / sizeof(DdNode),
00713                             (mask & (long) cuddT(scan)) / sizeof(DdNode));
00714                         if (retval == EOF) goto failure;
00715                         retval = fprintf(fp,
00716                                          "\"%lx\" -> \"%lx\" [style = dashed];\n",
00717                                          (mask & (long) scan) / sizeof(DdNode),
00718                                          (mask & (long) cuddE(scan)) / sizeof(DdNode));
00719                         if (retval == EOF) goto failure;
00720                     }
00721                     scan = scan->next;
00722                 }
00723             }
00724         }
00725     }
00726 
00727     /* Write constant labels. */
00728     nodelist = dd->constants.nodelist;
00729     slots = dd->constants.slots;
00730     for (j = 0; j < slots; j++) {
00731         scan = nodelist[j];
00732         while (scan != NULL) {
00733             if (st_is_member(visited,(char *) scan)) {
00734                 retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n",
00735                     (mask & (long) scan) / sizeof(DdNode), cuddV(scan));
00736                 if (retval == EOF) goto failure;
00737             }
00738             scan = scan->next;
00739         }
00740     }
00741 
00742     /* Write trailer and return. */
00743     retval = fprintf(fp,"}\n");
00744     if (retval == EOF) goto failure;
00745 
00746     st_free_table(visited);
00747     FREE(sorted);
00748     return(1);
00749 
00750 failure:
00751     if (sorted != NULL) FREE(sorted);
00752     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00753     if (visited != NULL) st_free_table(visited);
00754     return(0);
00755 
00756 } /* end of Cudd_zddDumpBlif */

DdGen* Cudd_zddFirstPath ( DdManager zdd,
DdNode f,
int **  path 
)

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 240 of file cuddZddUtil.c.

00244 {
00245     DdGen *gen;
00246     DdNode *top, *next, *prev;
00247     int i;
00248     int nvars;
00249 
00250     /* Sanity Check. */
00251     if (zdd == NULL || f == NULL) return(NULL);
00252 
00253     /* Allocate generator an initialize it. */
00254     gen = ALLOC(DdGen,1);
00255     if (gen == NULL) {
00256         zdd->errorCode = CUDD_MEMORY_OUT;
00257         return(NULL);
00258     }
00259 
00260     gen->manager = zdd;
00261     gen->type = CUDD_GEN_ZDD_PATHS;
00262     gen->status = CUDD_GEN_EMPTY;
00263     gen->gen.cubes.cube = NULL;
00264     gen->gen.cubes.value = DD_ZERO_VAL;
00265     gen->stack.sp = 0;
00266     gen->stack.stack = NULL;
00267     gen->node = NULL;
00268 
00269     nvars = zdd->sizeZ;
00270     gen->gen.cubes.cube = ALLOC(int,nvars);
00271     if (gen->gen.cubes.cube == NULL) {
00272         zdd->errorCode = CUDD_MEMORY_OUT;
00273         FREE(gen);
00274         return(NULL);
00275     }
00276     for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
00277 
00278     /* The maximum stack depth is one plus the number of variables.
00279     ** because a path may have nodes at all levels, including the
00280     ** constant level.
00281     */
00282     gen->stack.stack = ALLOC(DdNode *, nvars+1);
00283     if (gen->stack.stack == NULL) {
00284         zdd->errorCode = CUDD_MEMORY_OUT;
00285         FREE(gen->gen.cubes.cube);
00286         FREE(gen);
00287         return(NULL);
00288     }
00289     for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
00290 
00291     /* Find the first path of the ZDD. */
00292     gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
00293 
00294     while (1) {
00295         top = gen->stack.stack[gen->stack.sp-1];
00296         if (!cuddIsConstant(top)) {
00297             /* Take the else branch first. */
00298             gen->gen.cubes.cube[top->index] = 0;
00299             next = cuddE(top);
00300             gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
00301         } else if (top == DD_ZERO(zdd)) {
00302             /* Backtrack. */
00303             while (1) {
00304                 if (gen->stack.sp == 1) {
00305                     /* The current node has no predecessor. */
00306                     gen->status = CUDD_GEN_EMPTY;
00307                     gen->stack.sp--;
00308                     goto done;
00309                 }
00310                 prev = gen->stack.stack[gen->stack.sp-2];
00311                 next = cuddT(prev);
00312                 if (next != top) { /* follow the then branch next */
00313                     gen->gen.cubes.cube[prev->index] = 1;
00314                     gen->stack.stack[gen->stack.sp-1] = next;
00315                     break;
00316                 }
00317                 /* Pop the stack and try again. */
00318                 gen->gen.cubes.cube[prev->index] = 2;
00319                 gen->stack.sp--;
00320                 top = gen->stack.stack[gen->stack.sp-1];
00321             }
00322         } else {
00323             gen->status = CUDD_GEN_NONEMPTY;
00324             gen->gen.cubes.value = cuddV(top);
00325             goto done;
00326         }
00327     }
00328 
00329 done:
00330     *path = gen->gen.cubes.cube;
00331     return(gen);
00332 
00333 } /* 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 352 of file cuddZddUtil.c.

00355 {
00356     DdNode *top, *next, *prev;
00357     DdManager *zdd = gen->manager;
00358 
00359     /* Backtrack from previously reached terminal node. */
00360     while (1) {
00361         if (gen->stack.sp == 1) {
00362             /* The current node has no predecessor. */
00363             gen->status = CUDD_GEN_EMPTY;
00364             gen->stack.sp--;
00365             goto done;
00366         }
00367         top = gen->stack.stack[gen->stack.sp-1];
00368         prev = gen->stack.stack[gen->stack.sp-2];
00369         next = cuddT(prev);
00370         if (next != top) { /* follow the then branch next */
00371             gen->gen.cubes.cube[prev->index] = 1;
00372             gen->stack.stack[gen->stack.sp-1] = next;
00373             break;
00374         }
00375         /* Pop the stack and try again. */
00376         gen->gen.cubes.cube[prev->index] = 2;
00377         gen->stack.sp--;
00378     }
00379 
00380     while (1) {
00381         top = gen->stack.stack[gen->stack.sp-1];
00382         if (!cuddIsConstant(top)) {
00383             /* Take the else branch first. */
00384             gen->gen.cubes.cube[top->index] = 0;
00385             next = cuddE(top);
00386             gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
00387         } else if (top == DD_ZERO(zdd)) {
00388             /* Backtrack. */
00389             while (1) {
00390                 if (gen->stack.sp == 1) {
00391                     /* The current node has no predecessor. */
00392                     gen->status = CUDD_GEN_EMPTY;
00393                     gen->stack.sp--;
00394                     goto done;
00395                 }
00396                 prev = gen->stack.stack[gen->stack.sp-2];
00397                 next = cuddT(prev);
00398                 if (next != top) { /* follow the then branch next */
00399                     gen->gen.cubes.cube[prev->index] = 1;
00400                     gen->stack.stack[gen->stack.sp-1] = next;
00401                     break;
00402                 }
00403                 /* Pop the stack and try again. */
00404                 gen->gen.cubes.cube[prev->index] = 2;
00405                 gen->stack.sp--;
00406                 top = gen->stack.stack[gen->stack.sp-1];
00407             }
00408         } else {
00409             gen->status = CUDD_GEN_NONEMPTY;
00410             gen->gen.cubes.value = cuddV(top);
00411             goto done;
00412         }
00413     }
00414 
00415 done:
00416     if (gen->status == CUDD_GEN_EMPTY) return(0);
00417     *path = gen->gen.cubes.cube;
00418     return(1);
00419 
00420 } /* end of Cudd_zddNextPath */

int Cudd_zddPrintCover ( DdManager zdd,
DdNode node 
)

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 134 of file cuddZddUtil.c.

00137 {
00138     int         i, size;
00139     int         *list;
00140 
00141     size = (int)zdd->sizeZ;
00142     if (size % 2 != 0) return(0); /* number of variables should be even */
00143     list = ALLOC(int, size);
00144     if (list == NULL) {
00145         zdd->errorCode = CUDD_MEMORY_OUT;
00146         return(0);
00147     }
00148     for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */
00149     zddPrintCoverAux(zdd, node, 0, list);
00150     FREE(list);
00151     return(1);
00152 
00153 } /* end of Cudd_zddPrintCover */

int Cudd_zddPrintDebug ( DdManager zdd,
DdNode f,
int  n,
int  pr 
)

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:

  • pr = 0 : prints nothing
  • pr = 1 : prints counts of nodes and minterms
  • pr = 2 : prints counts + disjoint sum of products
  • pr = 3 : prints counts + list of nodes
  • pr > 3 : prints counts + disjoint sum of products + list of nodes

Returns 1 if successful; 0 otherwise. ]

SideEffects [None]

SeeAlso []

Definition at line 180 of file cuddZddUtil.c.

00185 {
00186     DdNode      *empty = DD_ZERO(zdd);
00187     int         nodes;
00188     double      minterms;
00189     int         retval = 1;
00190 
00191     if (f == empty && pr > 0) {
00192         (void) fprintf(zdd->out,": is the empty ZDD\n");
00193         (void) fflush(zdd->out);
00194         return(1);
00195     }
00196 
00197     if (pr > 0) {
00198         nodes = Cudd_zddDagSize(f);
00199         if (nodes == CUDD_OUT_OF_MEM) retval = 0;
00200         minterms = Cudd_zddCountMinterm(zdd, f, n);
00201         if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0;
00202         (void) fprintf(zdd->out,": %d nodes %g minterms\n",
00203                        nodes, minterms);
00204         if (pr > 2)
00205             if (!cuddZddP(zdd, f)) retval = 0;
00206         if (pr == 2 || pr > 3) {
00207             if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0;
00208             (void) fprintf(zdd->out,"\n");
00209         }
00210         (void) fflush(zdd->out);
00211     }
00212     return(retval);
00213 
00214 } /* end of Cudd_zddPrintDebug */

int Cudd_zddPrintMinterm ( DdManager zdd,
DdNode node 
)

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 100 of file cuddZddUtil.c.

00103 {
00104     int         i, size;
00105     int         *list;
00106 
00107     size = (int)zdd->sizeZ;
00108     list = ALLOC(int, size);
00109     if (list == NULL) {
00110         zdd->errorCode = CUDD_MEMORY_OUT;
00111         return(0);
00112     }
00113     for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */
00114     zdd_print_minterm_aux(zdd, node, 0, list);
00115     FREE(list);
00116     return(1);
00117 
00118 } /* end of Cudd_zddPrintMinterm */

int cuddZddP ( DdManager zdd,
DdNode f 
)

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 778 of file cuddZddUtil.c.

00781 {
00782     int retval;
00783     st_table *table = st_init_table(st_ptrcmp, st_ptrhash);
00784 
00785     if (table == NULL) return(0);
00786 
00787     retval = zp2(zdd, f, table);
00788     st_free_table(table);
00789     (void) fputc('\n', zdd->out);
00790     return(retval);
00791 
00792 } /* 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 892 of file cuddZddUtil.c.

00897 {
00898     DdNode      *Nv, *Nnv;
00899     int         i, v;
00900     DdNode      *base = DD_ONE(zdd);
00901 
00902     if (Cudd_IsConstant(node)) {
00903         if (node == base) {
00904             /* Check for missing variable. */
00905             if (level != zdd->sizeZ) {
00906                 list[zdd->invpermZ[level]] = 0;
00907                 zdd_print_minterm_aux(zdd, node, level + 1, list);
00908                 return;
00909             }
00910             /* Terminal case: Print one cube based on the current recursion
00911             ** path.
00912             */
00913             for (i = 0; i < zdd->sizeZ; i++) {
00914                 v = list[i];
00915                 if (v == 0)
00916                     (void) fprintf(zdd->out,"0");
00917                 else if (v == 1)
00918                     (void) fprintf(zdd->out,"1");
00919                 else if (v == 3)
00920                     (void) fprintf(zdd->out,"@");       /* should never happen */
00921                 else
00922                     (void) fprintf(zdd->out,"-");
00923             }
00924             (void) fprintf(zdd->out," 1\n");
00925         }
00926     } else {
00927         /* Check for missing variable. */
00928         if (level != cuddIZ(zdd,node->index)) {
00929             list[zdd->invpermZ[level]] = 0;
00930             zdd_print_minterm_aux(zdd, node, level + 1, list);
00931             return;
00932         }
00933 
00934         Nnv = cuddE(node);
00935         Nv = cuddT(node);
00936         if (Nv == Nnv) {
00937             list[node->index] = 2;
00938             zdd_print_minterm_aux(zdd, Nnv, level + 1, list);
00939             return;
00940         }
00941 
00942         list[node->index] = 1;
00943         zdd_print_minterm_aux(zdd, Nv, level + 1, list);
00944         list[node->index] = 0;
00945         zdd_print_minterm_aux(zdd, Nnv, level + 1, list);
00946     }
00947     return;
00948 
00949 } /* end of zdd_print_minterm_aux */

static void zddPrintCoverAux ( DdManager zdd,
DdNode node,
int  level,
int *  list 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddPrintCover.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 964 of file cuddZddUtil.c.

00969 {
00970     DdNode      *Nv, *Nnv;
00971     int         i, v;
00972     DdNode      *base = DD_ONE(zdd);
00973 
00974     if (Cudd_IsConstant(node)) {
00975         if (node == base) {
00976             /* Check for missing variable. */
00977             if (level != zdd->sizeZ) {
00978                 list[zdd->invpermZ[level]] = 0;
00979                 zddPrintCoverAux(zdd, node, level + 1, list);
00980                 return;
00981             }
00982             /* Terminal case: Print one cube based on the current recursion
00983             ** path.
00984             */
00985             for (i = 0; i < zdd->sizeZ; i += 2) {
00986                 v = list[i] * 4 + list[i+1];
00987                 if (v == 0)
00988                     (void) putc('-',zdd->out);
00989                 else if (v == 4)
00990                     (void) putc('1',zdd->out);
00991                 else if (v == 1)
00992                     (void) putc('0',zdd->out);
00993                 else
00994                     (void) putc('@',zdd->out); /* should never happen */
00995             }
00996             (void) fprintf(zdd->out," 1\n");
00997         }
00998     } else {
00999         /* Check for missing variable. */
01000         if (level != cuddIZ(zdd,node->index)) {
01001             list[zdd->invpermZ[level]] = 0;
01002             zddPrintCoverAux(zdd, node, level + 1, list);
01003             return;
01004         }
01005 
01006         Nnv = cuddE(node);
01007         Nv = cuddT(node);
01008         if (Nv == Nnv) {
01009             list[node->index] = 2;
01010             zddPrintCoverAux(zdd, Nnv, level + 1, list);
01011             return;
01012         }
01013 
01014         list[node->index] = 1;
01015         zddPrintCoverAux(zdd, Nv, level + 1, list);
01016         list[node->index] = 0;
01017         zddPrintCoverAux(zdd, Nnv, level + 1, list);
01018     }
01019     return;
01020 
01021 } /* end of zddPrintCoverAux */

static int zp2 ( DdManager zdd,
DdNode f,
st_table t 
) [static]

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 813 of file cuddZddUtil.c.

00817 {
00818     DdNode      *n;
00819     int         T, E;
00820     DdNode      *base = DD_ONE(zdd);
00821     
00822     if (f == NULL)
00823         return(0);
00824 
00825     if (Cudd_IsConstant(f)) {
00826         (void)fprintf(zdd->out, "ID = %d\n", (f == base));
00827         return(1);
00828     }
00829     if (st_is_member(t, (char *)f) == 1)
00830         return(1);
00831 
00832     if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM)
00833         return(0);
00834 
00835 #if SIZEOF_VOID_P == 8
00836     (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %d\tr = %d\t",
00837         (unsigned long)f / (unsigned long) sizeof(DdNode), f->index, f->ref);
00838 #else
00839     (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t",
00840         (unsigned)f / (unsigned) sizeof(DdNode), f->index, f->ref);
00841 #endif
00842 
00843     n = cuddT(f);
00844     if (Cudd_IsConstant(n)) {
00845         (void) fprintf(zdd->out, "T = %d\t\t", (n == base));
00846         T = 1;
00847     } else {
00848 #if SIZEOF_VOID_P == 8
00849         (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n /
00850                        (unsigned long) sizeof(DdNode));
00851 #else
00852         (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode));
00853 #endif
00854         T = 0;
00855     }
00856 
00857     n = cuddE(f);
00858     if (Cudd_IsConstant(n)) {
00859         (void) fprintf(zdd->out, "E = %d\n", (n == base));
00860         E = 1;
00861     } else {
00862 #if SIZEOF_VOID_P == 8
00863         (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n /
00864                       (unsigned long) sizeof(DdNode));
00865 #else
00866         (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode));
00867 #endif
00868         E = 0;
00869     }
00870 
00871     if (E == 0)
00872         if (zp2(zdd, cuddE(f), t) == 0) return(0);
00873     if (T == 0)
00874         if (zp2(zdd, cuddT(f), t) == 0) return(0);
00875     return(1);
00876 
00877 } /* end of zp2 */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang 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]

Copyright [ This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]

Definition at line 61 of file cuddZddUtil.c.


Generated on Tue Jan 5 12:18:58 2010 for abc70930 by  doxygen 1.6.1