src/bdd/cudd/cuddExport.c File Reference

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

Go to the source code of this file.

Functions

static int ddDoDumpBlif ARGS ((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names))
static int ddDoDumpDaVinci ARGS ((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask))
static int ddDoDumpFactoredForm ARGS ((DdManager *dd, DdNode *f, FILE *fp, char **names))
int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp)
int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names)
static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)
static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)
static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names)

Variables

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

Function Documentation

static int ddDoDumpFactoredForm ARGS ( (DdManager *dd, DdNode *f, FILE *fp, char **names)   )  [static]
static int ddDoDumpDDcal ARGS ( (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)   )  [static]
static int ddDoDumpBlif ARGS ( (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names)   )  [static]

AutomaticStart

int Cudd_DumpBlif ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
char *  mname,
FILE *  fp 
)

AutomaticEnd Function********************************************************************

Synopsis [Writes a blif file representing the argument BDDs.]

Description [Writes a blif file representing the argument BDDs as a network of multiplexers. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlif does not close the file: This is the caller responsibility. Cudd_DumpBlif 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.]

SideEffects [None]

SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 105 of file cuddExport.c.

00113 {
00114     DdNode      *support = NULL;
00115     DdNode      *scan;
00116     int         *sorted = NULL;
00117     int         nvars = dd->size;
00118     int         retval;
00119     int         i;
00120 
00121     /* Build a bit array with the support of f. */
00122     sorted = ALLOC(int,nvars);
00123     if (sorted == NULL) {
00124         dd->errorCode = CUDD_MEMORY_OUT;
00125         goto failure;
00126     }
00127     for (i = 0; i < nvars; i++) sorted[i] = 0;
00128 
00129     /* Take the union of the supports of each output function. */
00130     support = Cudd_VectorSupport(dd,f,n);
00131     if (support == NULL) goto failure;
00132     cuddRef(support);
00133     scan = support;
00134     while (!cuddIsConstant(scan)) {
00135         sorted[scan->index] = 1;
00136         scan = cuddT(scan);
00137     }
00138     Cudd_RecursiveDeref(dd,support);
00139     support = NULL; /* so that we do not try to free it in case of failure */
00140 
00141     /* Write the header (.model .inputs .outputs). */
00142     if (mname == NULL) {
00143         retval = fprintf(fp,".model DD\n.inputs");
00144     } else {
00145         retval = fprintf(fp,".model %s\n.inputs",mname);
00146     }
00147     if (retval == EOF) return(0);
00148 
00149     /* Write the input list by scanning the support array. */
00150     for (i = 0; i < nvars; i++) {
00151         if (sorted[i]) {
00152             if (inames == NULL) {
00153                 retval = fprintf(fp," %d", i);
00154             } else {
00155                 retval = fprintf(fp," %s", inames[i]);
00156             }
00157             if (retval == EOF) goto failure;
00158         }
00159     }
00160     FREE(sorted);
00161     sorted = NULL;
00162 
00163     /* Write the .output line. */
00164     retval = fprintf(fp,"\n.outputs");
00165     if (retval == EOF) goto failure;
00166     for (i = 0; i < n; i++) {
00167         if (onames == NULL) {
00168             retval = fprintf(fp," f%d", i);
00169         } else {
00170             retval = fprintf(fp," %s", onames[i]);
00171         }
00172         if (retval == EOF) goto failure;
00173     }
00174     retval = fprintf(fp,"\n");
00175     if (retval == EOF) goto failure;
00176 
00177     retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp);
00178     if (retval == 0) goto failure;
00179 
00180     /* Write trailer and return. */
00181     retval = fprintf(fp,".end\n");
00182     if (retval == EOF) goto failure;
00183 
00184     return(1);
00185 
00186 failure:
00187     if (sorted != NULL) FREE(sorted);
00188     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00189     return(0);
00190 
00191 } /* end of Cudd_DumpBlif */

int Cudd_DumpBlifBody ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a blif body representing the argument BDDs.]

Description [Writes a blif body representing the argument BDDs as a network of multiplexers. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlif does not close the file: This is the caller responsibility. Cudd_DumpBlif 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. This function prints out only .names part.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 216 of file cuddExport.c.

00223 {
00224     st_table    *visited = NULL;
00225     int         retval;
00226     int         i;
00227 
00228     /* Initialize symbol table for visited nodes. */
00229     visited = st_init_table(st_ptrcmp, st_ptrhash);
00230     if (visited == NULL) goto failure;
00231 
00232     /* Call the function that really gets the job done. */
00233     for (i = 0; i < n; i++) {
00234         retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames);
00235         if (retval == 0) goto failure;
00236     }
00237 
00238     /* To account for the possible complement on the root,
00239     ** we put either a buffer or an inverter at the output of
00240     ** the multiplexer representing the top node.
00241     */
00242     for (i = 0; i < n; i++) {
00243         if (onames == NULL) {
00244             retval = fprintf(fp,
00245 #if SIZEOF_VOID_P == 8
00246                 ".names %lx f%d\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i);
00247 #else
00248                 ".names %x f%d\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), i);
00249 #endif
00250         } else {
00251             retval = fprintf(fp,
00252 #if SIZEOF_VOID_P == 8
00253                 ".names %lx %s\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), onames[i]);
00254 #else
00255                 ".names %x %s\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), onames[i]);
00256 #endif
00257         }
00258         if (retval == EOF) goto failure;
00259         if (Cudd_IsComplement(f[i])) {
00260             retval = fprintf(fp,"0 1\n");
00261         } else {
00262             retval = fprintf(fp,"1 1\n");
00263         }
00264         if (retval == EOF) goto failure;
00265     }
00266 
00267     st_free_table(visited);
00268     return(1);
00269 
00270 failure:
00271     if (visited != NULL) st_free_table(visited);
00272     return(0);
00273 
00274 } /* end of Cudd_DumpBlifBody */

int Cudd_DumpDaVinci ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a daVinci file representing the argument BDDs.]

Description [Writes a daVinci file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDaVinci does not close the file: This is the caller responsibility. Cudd_DumpDaVinci 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.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal Cudd_DumpFactoredForm]

Definition at line 583 of file cuddExport.c.

00590 {
00591     DdNode      *support = NULL;
00592     DdNode      *scan;
00593     st_table    *visited = NULL;
00594     int         retval;
00595     int         i;
00596     st_generator *gen;
00597     long        refAddr, diff, mask;
00598 
00599     /* Initialize symbol table for visited nodes. */
00600     visited = st_init_table(st_ptrcmp, st_ptrhash);
00601     if (visited == NULL) goto failure;
00602 
00603     /* Collect all the nodes of this DD in the symbol table. */
00604     for (i = 0; i < n; i++) {
00605         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00606         if (retval == 0) goto failure;
00607     }
00608 
00609     /* Find how many most significant hex digits are identical
00610     ** in the addresses of all the nodes. Build a mask based
00611     ** on this knowledge, so that digits that carry no information
00612     ** will not be printed. This is done in two steps.
00613     **  1. We scan the symbol table to find the bits that differ
00614     **     in at least 2 addresses.
00615     **  2. We choose one of the possible masks. There are 8 possible
00616     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00617     **     integers.
00618     */
00619 
00620     /* Find the bits that are different. */
00621     refAddr = (long) Cudd_Regular(f[0]);
00622     diff = 0;
00623     gen = st_init_gen(visited);
00624     while (st_gen(gen, (char **) &scan, NULL)) {
00625         diff |= refAddr ^ (long) scan;
00626     }
00627     st_free_gen(gen);
00628 
00629     /* Choose the mask. */
00630     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00631         mask = (1 << i) - 1;
00632         if (diff <= mask) break;
00633     }
00634     st_free_table(visited);
00635 
00636     /* Initialize symbol table for visited nodes. */
00637     visited = st_init_table(st_ptrcmp, st_ptrhash);
00638     if (visited == NULL) goto failure;
00639 
00640     retval = fprintf(fp, "[");
00641     if (retval == EOF) goto failure;
00642     /* Call the function that really gets the job done. */
00643     for (i = 0; i < n; i++) {
00644         if (onames == NULL) {
00645             retval = fprintf(fp,
00646                              "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],",
00647                              i,i);
00648         } else {
00649             retval = fprintf(fp,
00650                              "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],",
00651                              onames[i], onames[i]);
00652         }
00653         if (retval == EOF) goto failure;
00654         retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],",
00655                          Cudd_IsComplement(f[i]) ? "red" : "blue");
00656         if (retval == EOF) goto failure;
00657         retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask);
00658         if (retval == 0) goto failure;
00659         retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ",");
00660         if (retval == EOF) goto failure;
00661     }
00662 
00663     /* Write trailer and return. */
00664     retval = fprintf(fp, "]\n");
00665     if (retval == EOF) goto failure;
00666 
00667     st_free_table(visited);
00668     return(1);
00669 
00670 failure:
00671     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00672     if (visited != NULL) st_free_table(visited);
00673     return(0);
00674 
00675 } /* end of Cudd_DumpDaVinci */

int Cudd_DumpDDcal ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a DDcal file representing the argument BDDs.]

Description [Writes a DDcal file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDDcal does not close the file: This is the caller responsibility. Cudd_DumpDDcal 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.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 697 of file cuddExport.c.

00704 {
00705     DdNode      *support = NULL;
00706     DdNode      *scan;
00707     int         *sorted = NULL;
00708     int         nvars = dd->size;
00709     st_table    *visited = NULL;
00710     int         retval;
00711     int         i;
00712     st_generator *gen;
00713     long        refAddr, diff, mask;
00714 
00715     /* Initialize symbol table for visited nodes. */
00716     visited = st_init_table(st_ptrcmp, st_ptrhash);
00717     if (visited == NULL) goto failure;
00718 
00719     /* Collect all the nodes of this DD in the symbol table. */
00720     for (i = 0; i < n; i++) {
00721         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00722         if (retval == 0) goto failure;
00723     }
00724 
00725     /* Find how many most significant hex digits are identical
00726     ** in the addresses of all the nodes. Build a mask based
00727     ** on this knowledge, so that digits that carry no information
00728     ** will not be printed. This is done in two steps.
00729     **  1. We scan the symbol table to find the bits that differ
00730     **     in at least 2 addresses.
00731     **  2. We choose one of the possible masks. There are 8 possible
00732     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00733     **     integers.
00734     */
00735 
00736     /* Find the bits that are different. */
00737     refAddr = (long) Cudd_Regular(f[0]);
00738     diff = 0;
00739     gen = st_init_gen(visited);
00740     while (st_gen(gen, (char **) &scan, NULL)) {
00741         diff |= refAddr ^ (long) scan;
00742     }
00743     st_free_gen(gen);
00744 
00745     /* Choose the mask. */
00746     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00747         mask = (1 << i) - 1;
00748         if (diff <= mask) break;
00749     }
00750     st_free_table(visited);
00751 
00752     /* Build a bit array with the support of f. */
00753     sorted = ALLOC(int,nvars);
00754     if (sorted == NULL) {
00755         dd->errorCode = CUDD_MEMORY_OUT;
00756         goto failure;
00757     }
00758     for (i = 0; i < nvars; i++) sorted[i] = 0;
00759 
00760     /* Take the union of the supports of each output function. */
00761     support = Cudd_VectorSupport(dd,f,n);
00762     if (support == NULL) goto failure;
00763     cuddRef(support);
00764     scan = support;
00765     while (!cuddIsConstant(scan)) {
00766         sorted[scan->index] = 1;
00767         scan = cuddT(scan);
00768     }
00769     Cudd_RecursiveDeref(dd,support);
00770     support = NULL; /* so that we do not try to free it in case of failure */
00771     for (i = 0; i < nvars; i++) {
00772         if (sorted[dd->invperm[i]]) {
00773             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00774                 retval = fprintf(fp,"v%d", dd->invperm[i]);
00775             } else {
00776                 retval = fprintf(fp,"%s", inames[dd->invperm[i]]);
00777             }
00778             if (retval == EOF) goto failure;
00779         }
00780         retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * ");
00781         if (retval == EOF) goto failure;
00782     }
00783     FREE(sorted);
00784     sorted = NULL;
00785 
00786     /* Initialize symbol table for visited nodes. */
00787     visited = st_init_table(st_ptrcmp, st_ptrhash);
00788     if (visited == NULL) goto failure;
00789 
00790     /* Call the function that really gets the job done. */
00791     for (i = 0; i < n; i++) {
00792         retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask);
00793         if (retval == 0) goto failure;
00794         if (onames == NULL) {
00795             retval = fprintf(fp, "f%d = ", i);
00796         } else {
00797             retval = fprintf(fp, "%s = ", onames[i]);
00798         }
00799         if (retval == EOF) goto failure;
00800         retval = fprintf(fp, "n%lx%s\n",
00801                          ((long) f[i] & mask) / sizeof(DdNode),
00802                          Cudd_IsComplement(f[i]) ? "'" : "");
00803         if (retval == EOF) goto failure;
00804     }
00805 
00806     /* Write trailer and return. */
00807     retval = fprintf(fp, "[");
00808     if (retval == EOF) goto failure;
00809     for (i = 0; i < n; i++) {
00810         if (onames == NULL) {
00811             retval = fprintf(fp, "f%d", i);
00812         } else {
00813             retval = fprintf(fp, "%s", onames[i]);
00814         }
00815         retval = fprintf(fp, "%s", i == n-1 ? "" : " ");
00816         if (retval == EOF) goto failure;
00817     }
00818     retval = fprintf(fp, "]\n");
00819     if (retval == EOF) goto failure;
00820 
00821     st_free_table(visited);
00822     return(1);
00823 
00824 failure:
00825     if (sorted != NULL) FREE(sorted);
00826     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00827     if (visited != NULL) st_free_table(visited);
00828     return(0);
00829 
00830 } /* end of Cudd_DumpDDcal */

int Cudd_DumpDot ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a dot file representing the argument DDs.]

Description [Writes a file representing the argument DDs 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_DumpDot does not close the file: This is the caller responsibility. Cudd_DumpDot 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_DumpDot uses the following convention to draw arcs:

  • solid line: THEN arcs;
  • dotted line: complement arcs;
  • dashed line: regular ELSE arcs.

The dot options are chosen so that the drawing fits on a letter-size sheet. ]

SideEffects [None]

SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 307 of file cuddExport.c.

00314 {
00315     DdNode      *support = NULL;
00316     DdNode      *scan;
00317     int         *sorted = NULL;
00318     int         nvars = dd->size;
00319     st_table    *visited = NULL;
00320     st_generator *gen = NULL;
00321     int         retval;
00322     int         i, j;
00323     int         slots;
00324     DdNodePtr   *nodelist;
00325     long        refAddr, diff, mask;
00326 
00327     /* Build a bit array with the support of f. */
00328     sorted = ALLOC(int,nvars);
00329     if (sorted == NULL) {
00330         dd->errorCode = CUDD_MEMORY_OUT;
00331         goto failure;
00332     }
00333     for (i = 0; i < nvars; i++) sorted[i] = 0;
00334 
00335     /* Take the union of the supports of each output function. */
00336     support = Cudd_VectorSupport(dd,f,n);
00337     if (support == NULL) goto failure;
00338     cuddRef(support);
00339     scan = support;
00340     while (!cuddIsConstant(scan)) {
00341         sorted[scan->index] = 1;
00342         scan = cuddT(scan);
00343     }
00344     Cudd_RecursiveDeref(dd,support);
00345     support = NULL; /* so that we do not try to free it in case of failure */
00346 
00347     /* Initialize symbol table for visited nodes. */
00348     visited = st_init_table(st_ptrcmp, st_ptrhash);
00349     if (visited == NULL) goto failure;
00350 
00351     /* Collect all the nodes of this DD in the symbol table. */
00352     for (i = 0; i < n; i++) {
00353         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00354         if (retval == 0) goto failure;
00355     }
00356 
00357     /* Find how many most significant hex digits are identical
00358     ** in the addresses of all the nodes. Build a mask based
00359     ** on this knowledge, so that digits that carry no information
00360     ** will not be printed. This is done in two steps.
00361     **  1. We scan the symbol table to find the bits that differ
00362     **     in at least 2 addresses.
00363     **  2. We choose one of the possible masks. There are 8 possible
00364     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00365     **     integers.
00366     */
00367 
00368     /* Find the bits that are different. */
00369     refAddr = (long) Cudd_Regular(f[0]);
00370     diff = 0;
00371     gen = st_init_gen(visited);
00372     if (gen == NULL) goto failure;
00373     while (st_gen(gen, (char **) &scan, NULL)) {
00374         diff |= refAddr ^ (long) scan;
00375     }
00376     st_free_gen(gen); gen = NULL;
00377 
00378     /* Choose the mask. */
00379     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00380         mask = (1 << i) - 1;
00381         if (diff <= mask) break;
00382     }
00383 
00384     /* Write the header and the global attributes. */
00385     retval = fprintf(fp,"digraph \"DD\" {\n");
00386     if (retval == EOF) return(0);
00387     retval = fprintf(fp,
00388         "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n");
00389     if (retval == EOF) return(0);
00390 
00391     /* Write the input name subgraph by scanning the support array. */
00392     retval = fprintf(fp,"{ node [shape = plaintext];\n");
00393     if (retval == EOF) goto failure;
00394     retval = fprintf(fp,"  edge [style = invis];\n");
00395     if (retval == EOF) goto failure;
00396     /* We use a name ("CONST NODES") with an embedded blank, because
00397     ** it is unlikely to appear as an input name.
00398     */
00399     retval = fprintf(fp,"  \"CONST NODES\" [style = invis];\n");
00400     if (retval == EOF) goto failure;
00401     for (i = 0; i < nvars; i++) {
00402         if (sorted[dd->invperm[i]]) {
00403             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00404                 retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]);
00405             } else {
00406                 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]);
00407             }
00408             if (retval == EOF) goto failure;
00409         }
00410     }
00411     retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
00412     if (retval == EOF) goto failure;
00413 
00414     /* Write the output node subgraph. */
00415     retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n");
00416     if (retval == EOF) goto failure;
00417     for (i = 0; i < n; i++) {
00418         if (onames == NULL) {
00419             retval = fprintf(fp,"\"F%d\"", i);
00420         } else {
00421             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00422         }
00423         if (retval == EOF) goto failure;
00424         if (i == n - 1) {
00425             retval = fprintf(fp,"; }\n");
00426         } else {
00427             retval = fprintf(fp," -> ");
00428         }
00429         if (retval == EOF) goto failure;
00430     }
00431 
00432     /* Write rank info: All nodes with the same index have the same rank. */
00433     for (i = 0; i < nvars; i++) {
00434         if (sorted[dd->invperm[i]]) {
00435             retval = fprintf(fp,"{ rank = same; ");
00436             if (retval == EOF) goto failure;
00437             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00438                 retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]);
00439             } else {
00440                 retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]);
00441             }
00442             if (retval == EOF) goto failure;
00443             nodelist = dd->subtables[i].nodelist;
00444             slots = dd->subtables[i].slots;
00445             for (j = 0; j < slots; j++) {
00446                 scan = nodelist[j];
00447                 while (scan != NULL) {
00448                     if (st_is_member(visited,(char *) scan)) {
00449                         retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
00450                         if (retval == EOF) goto failure;
00451                     }
00452                     scan = scan->next;
00453                 }
00454             }
00455             retval = fprintf(fp,"}\n");
00456             if (retval == EOF) goto failure;
00457         }
00458     }
00459 
00460     /* All constants have the same rank. */
00461     retval = fprintf(fp,
00462         "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; ");
00463     if (retval == EOF) goto failure;
00464     nodelist = dd->constants.nodelist;
00465     slots = dd->constants.slots;
00466     for (j = 0; j < slots; j++) {
00467         scan = nodelist[j];
00468         while (scan != NULL) {
00469             if (st_is_member(visited,(char *) scan)) {
00470                 retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
00471                 if (retval == EOF) goto failure;
00472             }
00473             scan = scan->next;
00474         }
00475     }
00476     retval = fprintf(fp,"}\n}\n");
00477     if (retval == EOF) goto failure;
00478 
00479     /* Write edge info. */
00480     /* Edges from the output nodes. */
00481     for (i = 0; i < n; i++) {
00482         if (onames == NULL) {
00483             retval = fprintf(fp,"\"F%d\"", i);
00484         } else {
00485             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00486         }
00487         if (retval == EOF) goto failure;
00488         /* Account for the possible complement on the root. */
00489         if (Cudd_IsComplement(f[i])) {
00490             retval = fprintf(fp," -> \"%lx\" [style = dotted];\n",
00491                 (mask & (long) f[i]) / sizeof(DdNode));
00492         } else {
00493             retval = fprintf(fp," -> \"%lx\" [style = solid];\n",
00494                 (mask & (long) f[i]) / sizeof(DdNode));
00495         }
00496         if (retval == EOF) goto failure;
00497     }
00498 
00499     /* Edges from internal nodes. */
00500     for (i = 0; i < nvars; i++) {
00501         if (sorted[dd->invperm[i]]) {
00502             nodelist = dd->subtables[i].nodelist;
00503             slots = dd->subtables[i].slots;
00504             for (j = 0; j < slots; j++) {
00505                 scan = nodelist[j];
00506                 while (scan != NULL) {
00507                     if (st_is_member(visited,(char *) scan)) {
00508                         retval = fprintf(fp,
00509                             "\"%lx\" -> \"%lx\";\n",
00510                             (mask & (long) scan) / sizeof(DdNode),
00511                             (mask & (long) cuddT(scan)) / sizeof(DdNode));
00512                         if (retval == EOF) goto failure;
00513                         if (Cudd_IsComplement(cuddE(scan))) {
00514                             retval = fprintf(fp,
00515                                 "\"%lx\" -> \"%lx\" [style = dotted];\n",
00516                                 (mask & (long) scan) / sizeof(DdNode),
00517                                 (mask & (long) cuddE(scan)) / sizeof(DdNode));
00518                         } else {
00519                             retval = fprintf(fp,
00520                                 "\"%lx\" -> \"%lx\" [style = dashed];\n",
00521                                 (mask & (long) scan) / sizeof(DdNode),
00522                                 (mask & (long) cuddE(scan)) / sizeof(DdNode));
00523                         }
00524                         if (retval == EOF) goto failure;
00525                     }
00526                     scan = scan->next;
00527                 }
00528             }
00529         }
00530     }
00531 
00532     /* Write constant labels. */
00533     nodelist = dd->constants.nodelist;
00534     slots = dd->constants.slots;
00535     for (j = 0; j < slots; j++) {
00536         scan = nodelist[j];
00537         while (scan != NULL) {
00538             if (st_is_member(visited,(char *) scan)) {
00539                 retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n",
00540                     (mask & (long) scan) / sizeof(DdNode), cuddV(scan));
00541                 if (retval == EOF) goto failure;
00542             }
00543             scan = scan->next;
00544         }
00545     }
00546 
00547     /* Write trailer and return. */
00548     retval = fprintf(fp,"}\n");
00549     if (retval == EOF) goto failure;
00550 
00551     st_free_table(visited);
00552     FREE(sorted);
00553     return(1);
00554 
00555 failure:
00556     if (sorted != NULL) FREE(sorted);
00557     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00558     if (visited != NULL) st_free_table(visited);
00559     return(0);
00560 
00561 } /* end of Cudd_DumpDot */

int Cudd_DumpFactoredForm ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes factored forms representing the argument BDDs.]

Description [Writes factored forms representing the argument BDDs. The format of the factored form is the one used in the genlib files for technology mapping in sis. It returns 1 in case of success; 0 otherwise (e.g., file system full). Cudd_DumpFactoredForm does not close the file: This is the caller responsibility. Caution must be exercised because a factored form may be exponentially larger than the argument BDD. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpDDcal]

Definition at line 854 of file cuddExport.c.

00861 {
00862     int         retval;
00863     int         i;
00864 
00865     /* Call the function that really gets the job done. */
00866     for (i = 0; i < n; i++) {
00867         if (onames == NULL) {
00868             retval = fprintf(fp, "f%d = ", i);
00869         } else {
00870             retval = fprintf(fp, "%s = ", onames[i]);
00871         }
00872         if (retval == EOF) return(0);
00873         if (f[i] == DD_ONE(dd)) {
00874             retval = fprintf(fp, "CONST1");
00875             if (retval == EOF) return(0);
00876         } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) {
00877             retval = fprintf(fp, "CONST0");
00878             if (retval == EOF) return(0);
00879         } else {
00880             retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : "");
00881             if (retval == EOF) return(0);
00882             retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames);
00883             if (retval == 0) return(0);
00884             retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : "");
00885             if (retval == EOF) return(0);
00886         }
00887         retval = fprintf(fp, "%s", i == n-1 ? "" : "\n");
00888         if (retval == EOF) return(0);
00889     }
00890 
00891     return(1);
00892 
00893 } /* end of Cudd_DumpFactoredForm */

static int ddDoDumpBlif ( DdManager dd,
DdNode f,
FILE *  fp,
st_table visited,
char **  names 
) [static]

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

Synopsis [Performs the recursive step of Cudd_DumpBlif.]

Description [Performs the recursive step of Cudd_DumpBlif. Traverses the BDD f and writes a multiplexer-network description to the file pointed by fp in blif format. f is assumed to be a regular pointer and ddDoDumpBlif guarantees this assumption in the recursive calls.]

SideEffects [None]

SeeAlso []

Definition at line 921 of file cuddExport.c.

00927 {
00928     DdNode      *T, *E;
00929     int         retval;
00930 
00931 #ifdef DD_DEBUG
00932     assert(!Cudd_IsComplement(f));
00933 #endif
00934 
00935     /* If already visited, nothing to do. */
00936     if (st_is_member(visited, (char *) f) == 1)
00937         return(1);
00938 
00939     /* Check for abnormal condition that should never happen. */
00940     if (f == NULL)
00941         return(0);
00942 
00943     /* Mark node as visited. */
00944     if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
00945         return(0);
00946 
00947     /* Check for special case: If constant node, generate constant 1. */
00948     if (f == DD_ONE(dd)) {
00949 #if SIZEOF_VOID_P == 8
00950         retval = fprintf(fp, ".names %lx\n1\n",(unsigned long) f / (unsigned long) sizeof(DdNode));
00951 #else
00952         retval = fprintf(fp, ".names %x\n1\n",(unsigned) f / (unsigned) sizeof(DdNode));
00953 #endif
00954         if (retval == EOF) {
00955             return(0);
00956         } else {
00957             return(1);
00958         }
00959     }
00960 
00961     /* Check whether this is an ADD. We deal with 0-1 ADDs, but not
00962     ** with the general case.
00963     */
00964     if (f == DD_ZERO(dd)) {
00965 #if SIZEOF_VOID_P == 8
00966         retval = fprintf(fp, ".names %lx\n",(unsigned long) f / (unsigned long) sizeof(DdNode));
00967 #else
00968         retval = fprintf(fp, ".names %x\n",(unsigned) f / (unsigned) sizeof(DdNode));
00969 #endif
00970         if (retval == EOF) {
00971             return(0);
00972         } else {
00973             return(1);
00974         }
00975     }
00976     if (cuddIsConstant(f))
00977         return(0);
00978 
00979     /* Recursive calls. */
00980     T = cuddT(f);
00981     retval = ddDoDumpBlif(dd,T,fp,visited,names);
00982     if (retval != 1) return(retval);
00983     E = Cudd_Regular(cuddE(f));
00984     retval = ddDoDumpBlif(dd,E,fp,visited,names);
00985     if (retval != 1) return(retval);
00986 
00987     /* Write multiplexer taking complement arc into account. */
00988     if (names != NULL) {
00989         retval = fprintf(fp,".names %s", names[f->index]);
00990     } else {
00991         retval = fprintf(fp,".names %d", f->index);
00992     }
00993     if (retval == EOF)
00994         return(0);
00995 
00996 #if SIZEOF_VOID_P == 8
00997     if (Cudd_IsComplement(cuddE(f))) {
00998         retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n",
00999             (unsigned long) T / (unsigned long) sizeof(DdNode),
01000             (unsigned long) E / (unsigned long) sizeof(DdNode),
01001             (unsigned long) f / (unsigned long) sizeof(DdNode));
01002     } else {
01003         retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n",
01004             (unsigned long) T / (unsigned long) sizeof(DdNode),
01005             (unsigned long) E / (unsigned long) sizeof(DdNode),
01006             (unsigned long) f / (unsigned long) sizeof(DdNode));
01007     }
01008 #else
01009     if (Cudd_IsComplement(cuddE(f))) {
01010         retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n",
01011             (unsigned) T / (unsigned) sizeof(DdNode),
01012             (unsigned) E / (unsigned) sizeof(DdNode),
01013             (unsigned) f / (unsigned) sizeof(DdNode));
01014     } else {
01015         retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n",
01016             (unsigned) T / (unsigned) sizeof(DdNode),
01017             (unsigned) E / (unsigned) sizeof(DdNode),
01018             (unsigned) f / (unsigned) sizeof(DdNode));
01019     }
01020 #endif
01021     if (retval == EOF) {
01022         return(0);
01023     } else {
01024         return(1);
01025     }
01026 
01027 } /* end of ddDoDumpBlif */

static int ddDoDumpDaVinci ( DdManager dd,
DdNode f,
FILE *  fp,
st_table visited,
char **  names,
long  mask 
) [static]

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

Synopsis [Performs the recursive step of Cudd_DumpDaVinci.]

Description [Performs the recursive step of Cudd_DumpDaVinci. Traverses the BDD f and writes a term expression to the file pointed by fp in daVinci format. f is assumed to be a regular pointer and ddDoDumpDaVinci guarantees this assumption in the recursive calls.]

SideEffects [None]

SeeAlso []

Definition at line 1045 of file cuddExport.c.

01052 {
01053     DdNode      *T, *E;
01054     int         retval;
01055     long        id;
01056 
01057 #ifdef DD_DEBUG
01058     assert(!Cudd_IsComplement(f));
01059 #endif
01060 
01061     id = ((long) f & mask) / sizeof(DdNode);
01062 
01063     /* If already visited, insert a reference. */
01064     if (st_is_member(visited, (char *) f) == 1) {
01065         retval = fprintf(fp,"r(\"%lx\")", id);
01066         if (retval == EOF) {
01067             return(0);
01068         } else {
01069             return(1);
01070         }
01071     }
01072 
01073     /* Check for abnormal condition that should never happen. */
01074     if (f == NULL)
01075         return(0);
01076 
01077     /* Mark node as visited. */
01078     if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
01079         return(0);
01080 
01081     /* Check for special case: If constant node, generate constant 1. */
01082     if (Cudd_IsConstant(f)) {
01083         retval = fprintf(fp, "l(\"%lx\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", id, cuddV(f));
01084         if (retval == EOF) {
01085             return(0);
01086         } else {
01087             return(1);
01088         }
01089     }
01090 
01091     /* Recursive calls. */
01092     if (names != NULL) {
01093         retval = fprintf(fp,
01094                          "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%s\"),",
01095                          id, names[f->index]);
01096     } else {
01097         retval = fprintf(fp,
01098                          "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%d\"),",
01099                          id, f->index);
01100     }
01101     retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],");
01102     if (retval == EOF) return(0);
01103     T = cuddT(f);
01104     retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask);
01105     if (retval != 1) return(retval);
01106     retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],",
01107                      Cudd_IsComplement(cuddE(f)) ? "red" : "green");
01108     if (retval == EOF) return(0);
01109     E = Cudd_Regular(cuddE(f));
01110     retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask);
01111     if (retval != 1) return(retval);
01112 
01113     retval = fprintf(fp,")]))");
01114     if (retval == EOF) {
01115         return(0);
01116     } else {
01117         return(1);
01118     }
01119 
01120 } /* end of ddDoDumpDaVinci */

static int ddDoDumpDDcal ( DdManager dd,
DdNode f,
FILE *  fp,
st_table visited,
char **  names,
long  mask 
) [static]

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

Synopsis [Performs the recursive step of Cudd_DumpDDcal.]

Description [Performs the recursive step of Cudd_DumpDDcal. Traverses the BDD f and writes a line for each node to the file pointed by fp in DDcal format. f is assumed to be a regular pointer and ddDoDumpDDcal guarantees this assumption in the recursive calls.]

SideEffects [None]

SeeAlso []

Definition at line 1138 of file cuddExport.c.

01145 {
01146     DdNode      *T, *E;
01147     int         retval;
01148     long        id, idT, idE;
01149 
01150 #ifdef DD_DEBUG
01151     assert(!Cudd_IsComplement(f));
01152 #endif
01153 
01154     id = ((long) f & mask) / sizeof(DdNode);
01155 
01156     /* If already visited, do nothing. */
01157     if (st_is_member(visited, (char *) f) == 1) {
01158         return(1);
01159     }
01160 
01161     /* Check for abnormal condition that should never happen. */
01162     if (f == NULL)
01163         return(0);
01164 
01165     /* Mark node as visited. */
01166     if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
01167         return(0);
01168 
01169     /* Check for special case: If constant node, assign constant. */
01170     if (Cudd_IsConstant(f)) {
01171         if (f != DD_ONE(dd) && f != DD_ZERO(dd))
01172             return(0);
01173         retval = fprintf(fp, "n%lx = %g\n", id, cuddV(f));
01174         if (retval == EOF) {
01175             return(0);
01176         } else {
01177             return(1);
01178         }
01179     }
01180 
01181     /* Recursive calls. */
01182     T = cuddT(f);
01183     retval = ddDoDumpDDcal(dd,T,fp,visited,names,mask);
01184     if (retval != 1) return(retval);
01185     E = Cudd_Regular(cuddE(f));
01186     retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask);
01187     if (retval != 1) return(retval);
01188     idT = ((long) T & mask) / sizeof(DdNode);
01189     idE = ((long) E & mask) / sizeof(DdNode);
01190     if (names != NULL) {
01191         retval = fprintf(fp, "n%lx = %s * n%lx + %s' * n%lx%s\n",
01192                          id, names[f->index], idT, names[f->index],
01193                          idE, Cudd_IsComplement(cuddE(f)) ? "'" : "");
01194     } else {
01195         retval = fprintf(fp, "n%lx = v%d * n%lx + v%d' * n%lx%s\n",
01196                          id, f->index, idT, f->index,
01197                          idE, Cudd_IsComplement(cuddE(f)) ? "'" : "");
01198     }
01199     if (retval == EOF) {
01200         return(0);
01201     } else {
01202         return(1);
01203     }
01204 
01205 } /* end of ddDoDumpDDcal */

static int ddDoDumpFactoredForm ( DdManager dd,
DdNode f,
FILE *  fp,
char **  names 
) [static]

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

Synopsis [Performs the recursive step of Cudd_DumpFactoredForm.]

Description [Performs the recursive step of Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored form for each node to the file pointed by fp in terms of the factored forms of the children. Constants are propagated, and absorption is applied. f is assumed to be a regular pointer and ddDoDumpFActoredForm guarantees this assumption in the recursive calls.]

SideEffects [None]

SeeAlso [Cudd_DumpFactoredForm]

Definition at line 1226 of file cuddExport.c.

01231 {
01232     DdNode      *T, *E;
01233     int         retval;
01234 
01235 #ifdef DD_DEBUG
01236     assert(!Cudd_IsComplement(f));
01237     assert(!Cudd_IsConstant(f));
01238 #endif
01239 
01240     /* Check for abnormal condition that should never happen. */
01241     if (f == NULL)
01242         return(0);
01243 
01244     /* Recursive calls. */
01245     T = cuddT(f);
01246     E = cuddE(f);
01247     if (T != DD_ZERO(dd)) {
01248         if (E != DD_ONE(dd)) {
01249             if (names != NULL) {
01250                 retval = fprintf(fp, "%s", names[f->index]);
01251             } else {
01252                 retval = fprintf(fp, "x%d", f->index);
01253             }
01254             if (retval == EOF) return(0);
01255         }
01256         if (T != DD_ONE(dd)) {
01257             retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : "");
01258             if (retval == EOF) return(0);
01259             retval = ddDoDumpFactoredForm(dd,T,fp,names);
01260             if (retval != 1) return(retval);
01261             retval = fprintf(fp, ")");
01262             if (retval == EOF) return(0);
01263         }
01264         if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1);
01265         retval = fprintf(fp, " + ");
01266         if (retval == EOF) return(0);
01267     }
01268     E = Cudd_Regular(E);
01269     if (T != DD_ONE(dd)) {
01270         if (names != NULL) {
01271             retval = fprintf(fp, "!%s", names[f->index]);
01272         } else {
01273             retval = fprintf(fp, "!x%d", f->index);
01274         }
01275         if (retval == EOF) return(0);
01276     }
01277     if (E != DD_ONE(dd)) {
01278         retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "",
01279                          E != cuddE(f) ? "!" : "");
01280         if (retval == EOF) return(0);
01281         retval = ddDoDumpFactoredForm(dd,E,fp,names);
01282         if (retval != 1) return(retval);
01283         retval = fprintf(fp, ")");
01284         if (retval == EOF) return(0);
01285     }
01286     return(1);
01287 
01288 } /* end of ddDoDumpFactoredForm */


Variable Documentation

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

CFile***********************************************************************

FileName [cuddExport.c]

PackageName [cudd]

Synopsis [Export functions.]

Description [External procedures included in this module:

Internal procedures included in this module:

procedures included in this module:

]

Author [Fabio Somenzi]

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 58 of file cuddExport.c.


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