abc/src/bdd/cudd/cuddExport.c
/**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]

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




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 . 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 . ]
int
Cudd_DumpDDcal(
  DdManager * dd ,
  int  n ,
  DdNode ** f ,
  char ** inames ,
  char ** onames ,
  FILE * fp )
{
    DdNode        *support = NULL;
    DdNode        *scan;
    int           *sorted = NULL;
    int           nvars = dd->size;
    st__table      *visited = NULL;
    int           retval;
    int           i;
    st__generator  *gen;
    ptruint       refAddr, diff, mask;
    visited = st__init_table( st__ptrcmp, st__ptrhash);
    if (visited == NULL) goto failure;
    for (i = 0; i < n; i++) {
        retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
        if (retval == 0) goto failure;
    }
    refAddr = (ptruint) Cudd_Regular(f[0]);
    diff = 0;
    gen = st__init_gen(visited);
    while ( st__gen(gen, (const char **)&scan, NULL)) {
        diff |= refAddr ^ (ptruint) scan;
    }
    st__free_gen(gen);
    for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) {
        mask = (1 << i) - 1;
        if (diff <= mask) break;
    }
    st__free_table(visited);
    visited = NULL;
    sorted = ABC_ALLOC(int,nvars);
    if (sorted == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        goto failure;
    }
    for (i = 0; i < nvars; i++) sorted[i] = 0;
    support = Cudd_VectorSupport(dd,f,n);
    if (support == NULL) goto failure;
    cuddRef(support);
    scan = support;
    while (!cuddIsConstant(scan)) {
        sorted[scan->index] = 1;
        scan = cuddT(scan);
    }
    Cudd_RecursiveDeref(dd,support);
    support = NULL; 
    for (i = 0; i < nvars; i++) {
        if (sorted[dd->invperm[i]]) {
            if (inames == NULL || inames[dd->invperm[i]] == NULL) {
                retval = fprintf(fp,"v%d", dd->invperm[i]);
            } else {
                retval = fprintf(fp,"%s", inames[dd->invperm[i]]);
            }
            if (retval == EOF) goto failure;
        }
        retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * ");
        if (retval == EOF) goto failure;
    }
    ABC_FREE(sorted);
    sorted = NULL;
    visited = st__init_table( st__ptrcmp, st__ptrhash);
    if (visited == NULL) goto failure;
    for (i = 0; i < n; i++) {
        retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask);
        if (retval == 0) goto failure;
        if (onames == NULL) {
            retval = fprintf(fp, "f%d = ", i);
        } else {
            retval = fprintf(fp, "%s = ", onames[i]);
        }
        if (retval == EOF) goto failure;
        retval = fprintf(fp, "n%p%s\n",
                         (void *) (((ptruint) f[i] & mask) /
                         (ptruint) sizeof(DdNode)),
                         Cudd_IsComplement(f[i]) ? "'" : "");
        if (retval == EOF) goto failure;
    }
    retval = fprintf(fp, "[");
    if (retval == EOF) goto failure;
    for (i = 0; i < n; i++) {
        if (onames == NULL) {
            retval = fprintf(fp, "f%d", i);
        } else {
            retval = fprintf(fp, "%s", onames[i]);
        }
        retval = fprintf(fp, "%s", i == n-1 ? "" : " ");
        if (retval == EOF) goto failure;
    }
    retval = fprintf(fp, "]\n");
    if (retval == EOF) goto failure;
    if ( visited )
        st__free_table(visited);
    return(1);
failure:
    if (sorted != NULL) ABC_FREE(sorted);
    if (support != NULL) Cudd_RecursiveDeref(dd,support);
    if (visited != NULL) st__free_table(visited);
    return(0);
}
int Cudd_DumpDDcal ( DdManager * dd , int n , DdNode * * f , char * * inames , char * * onames , FILE * fp ) { DdNode * support = NULL ; DdNode * scan ; int * sorted = NULL ; int nvars = dd -> size ; st__table * visited = NULL ; int retval ; int i ; st__generator * gen ; ptruint refAddr , diff , mask ; visited = st__init_table ( st__ptrcmp , st__ptrhash ) ; if ( visited == NULL ) goto failure ; for ( i = 0 ; i < n ; i ++ ) { retval = cuddCollectNodes ( Cudd_Regular ( f [ i ] ) , visited ) ; if ( retval == 0 ) goto failure ; } refAddr = ( ptruint ) Cudd_Regular ( f [ 0 ] ) ; diff = 0 ; gen = st__init_gen ( visited ) ; while ( st__gen ( gen , ( const char * * ) & scan , NULL ) ) { diff |= refAddr ^ ( ptruint ) scan ; } st__free_gen ( gen ) ; for ( i = 0 ; ( unsigned ) i < 8 * sizeof ( ptruint ) ; i += 4 ) { mask = ( 1 << i ) - 1 ; if ( diff <= mask ) break ; } st__free_table ( visited ) ; visited = NULL ; sorted = ABC_ALLOC ( int , nvars ) ; if ( sorted == NULL ) { dd -> errorCode = CUDD_MEMORY_OUT ; goto failure ; } for ( i = 0 ; i < nvars ; i ++ ) sorted [ i ] = 0 ; support = Cudd_VectorSupport ( dd , f , n ) ; if ( support == NULL ) goto failure ; cuddRef ( support ) ; scan = support ; while ( ! cuddIsConstant ( scan ) ) { sorted [ scan -> index ] = 1 ; scan = cuddT ( scan ) ; } Cudd_RecursiveDeref ( dd , support ) ; support = NULL ; for ( i = 0 ; i < nvars ; i ++ ) { if ( sorted [ dd -> invperm [ i ] ] ) { if ( inames == NULL || inames [ dd -> invperm [ i ] ] == NULL ) { retval = fprintf ( fp , " " , dd -> invperm [ i ] ) ; } else { retval = fprintf ( fp , " " , inames [ dd -> invperm [ i ] ] ) ; } if ( retval == EOF ) goto failure ; } retval = fprintf ( fp , " " , i == nvars - 1 ? " \n " : " " ) ; if ( retval == EOF ) goto failure ; } ABC_FREE ( sorted ) ; sorted = NULL ; visited = st__init_table ( st__ptrcmp , st__ptrhash ) ; if ( visited == NULL ) goto failure ; for ( i = 0 ; i < n ; i ++ ) { retval = ddDoDumpDDcal ( dd , Cudd_Regular ( f [ i ] ) , fp , visited , inames , mask ) ; if ( retval == 0 ) goto failure ; if ( onames == NULL ) { retval = fprintf ( fp , " " , i ) ; } else { retval = fprintf ( fp , " " , onames [ i ] ) ; } if ( retval == EOF ) goto failure ; retval = fprintf ( fp , " \n " , ( void * ) ( ( ( ptruint ) f [ i ] & mask ) / ( ptruint ) sizeof ( DdNode ) ) , Cudd_IsComplement ( f [ i ] ) ? " " : " " ) ; if ( retval == EOF ) goto failure ; } retval = fprintf ( fp , " " ) ; if ( retval == EOF ) goto failure ; for ( i = 0 ; i < n ; i ++ ) { if ( onames == NULL ) { retval = fprintf ( fp , " " , i ) ; } else { retval = fprintf ( fp , " " , onames [ i ] ) ; } retval = fprintf ( fp , " " , i == n - 1 ? " " : " " ) ; if ( retval == EOF ) goto failure ; } retval = fprintf ( fp , " \n " ) ; if ( retval == EOF ) goto failure ; if ( visited ) st__free_table ( visited ) ; return ( 1 ) ; failure : if ( sorted != NULL ) ABC_FREE ( sorted ) ; if ( support != NULL ) Cudd_RecursiveDeref ( dd , support ) ; if ( visited != NULL ) st__free_table ( visited ) ; return ( 0 ) ; }
Function
Synopsis    [Writes a DDcal file representing the argument BDDs.]
Function Synopsis [ Writes a DDcal file representing the argument BDDs . ]
/* manager */ /* number of output nodes to be dumped */ /* array of output nodes to be dumped */ /* array of input names (or NULL) */ /* array of output names (or NULL) */ /* pointer to the dump file */ /* Initialize symbol table for visited nodes. */ /* Collect all the nodes of this DD in the symbol table. */ /* Find how many most significant hex digits are identical
    ** in the addresses of all the nodes. Build a mask based
    ** on this knowledge, so that digits that carry no information
    ** will not be printed. This is done in two steps.
    **  1. We scan the symbol table to find the bits that differ
    **     in at least 2 addresses.
    **  2. We choose one of the possible masks. There are 8 possible
    **     masks for 32-bit integer, and 16 possible masks for 64-bit
    **     integers.
    */ /* Find the bits that are different. */ /* Choose the mask. */ /* Build a bit array with the support of f. */ /* Take the union of the supports of each output function. */ /* so that we do not try to free it in case of failure */ /* Initialize symbol table for visited nodes. */ /* Call the function that really gets the job done. */ /* Write trailer and return. */