src/cuBdd/cuddZddUtil.c File Reference

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

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)
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)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.27 2009/03/08 02:49:02 fabio Exp $"

Function Documentation

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:

  • 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 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 */

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 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 */

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 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 */

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 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 */

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 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 */

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 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 */

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 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 */

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

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 */


Variable Documentation

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.


Generated on Tue Jan 12 13:57:22 2010 for glu-2.2 by  doxygen 1.6.1