Exemple #1
0
static int _reverse_merge_func(VALUE k, VALUE v, VALUE self_st) {
  st_table* t = (st_table*)self_st;
  if (!st_is_member(t, k)) {
    st_insert(t, (st_data_t)k, (st_data_t)v);
  }
  return ST_CONTINUE;
}
Exemple #2
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cuddaux_NodesBelowLevelRecur.]

  Description [Performs the recursive step of
  Cuddaux_NodesBelowLevelRecur.  F is supposed to be a regular
  node. Returns 1 if successful, NULL otherwise.
  The background node is not put in the list if take_background==0 ]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static int
cuddauxNodesBelowLevelRecur(DdManager* manager, DdNode* F, int level,
			    cuddaux_list_t** plist, st_table* visited,
			    size_t max, size_t* psize,
			    bool take_background)
{
  int topF,res;

  if ((!take_background && F==DD_BACKGROUND(manager)) || st_is_member(visited, (char *) F) == 1){
    return 1;
  }
  topF = cuddI(manager,F->index);
  if (topF < level){
    res = cuddauxNodesBelowLevelRecur(manager, Cudd_Regular(cuddT(F)), level, plist, visited, max, psize, take_background);
    if (res==0) return 0;
    if (max == 0 || *psize<max){
      res = cuddauxNodesBelowLevelRecur(manager, Cudd_Regular(cuddE(F)), level, plist, visited, max, psize, take_background);
      if (res==0) return 0;
    }
  }
  else {
    res = cuddaux_list_add(plist,F);
    (*psize)++;
    if (res==0) return 0;
  }
  if (st_add_direct(visited, (char *) F, NULL) == ST_OUT_OF_MEM){
    cuddaux_list_free(*plist);
    return 0;
  }
  return 1;
}
/**Function*************************************************************

  Synopsis    [Inserts the AIG node corresponding to the BDD node into the hash table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static void Cudd2_SetArg( Aig_Obj_t * pNode, void * pResult )
{
    assert( s_pCuddMan != NULL );
    if ( st_is_member( s_pCuddMan->pTable, (char *)Aig_Regular(pResult) ) )
        return;
    pNode = Aig_NotCond( pNode,  Aig_IsComplement(pResult) );
    st_insert( s_pCuddMan->pTable, (char *)Aig_Regular(pResult), (char *)pNode );
}
Exemple #4
0
/**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     []

******************************************************************************/
static int
zp2(
  DdManager * zdd,
  DdNode * f,
  st_table * t)
{
    DdNode	*n;
    int		T, E;
    DdNode	*base = DD_ONE(zdd);
    
    if (f == NULL)
	return(0);

    if (Cudd_IsConstant(f)) {
        (void)fprintf(zdd->out, "ID = %d\n", (f == base));
	return(1);
    }
    if (st_is_member(t, (char *)f) == 1)
	return(1);

    if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM)
	return(0);

#if SIZEOF_VOID_P == 8
    (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %d\tr = %d\t",
	(unsigned long)f / (unsigned long) sizeof(DdNode), f->index, f->ref);
#else
    (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t",
	(unsigned)f / (unsigned) sizeof(DdNode), f->index, f->ref);
#endif

    n = cuddT(f);
    if (Cudd_IsConstant(n)) {
        (void) fprintf(zdd->out, "T = %d\t\t", (n == base));
	T = 1;
    } else {
#if SIZEOF_VOID_P == 8
        (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n /
		       (unsigned long) sizeof(DdNode));
#else
        (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode));
#endif
	T = 0;
    }

    n = cuddE(f);
    if (Cudd_IsConstant(n)) {
        (void) fprintf(zdd->out, "E = %d\n", (n == base));
	E = 1;
    } else {
#if SIZEOF_VOID_P == 8
        (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n /
		      (unsigned long) sizeof(DdNode));
#else
        (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode));
#endif
	E = 0;
    }

    if (E == 0)
	if (zp2(zdd, cuddE(f), t) == 0) return(0);
    if (T == 0)
	if (zp2(zdd, cuddT(f), t) == 0) return(0);
    return(1);

} /* end of zp2 */
Exemple #5
0
/**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:
    <ul>
    <li> solid line: THEN arcs;
    <li> dashed line: ELSE arcs.
    </ul>
  The dot options are chosen so that the drawing fits on a letter-size
  sheet.
  ]

  SideEffects [None]

  SeeAlso     [Cudd_DumpDot Cudd_zddPrintDebug]

******************************************************************************/
int
Cudd_zddDumpDot(
  DdManager * dd /* manager */,
  int  n /* number of output nodes to be dumped */,
  DdNode ** f /* array of output nodes to be dumped */,
  char ** inames /* array of input names (or NULL) */,
  char ** onames /* array of output names (or NULL) */,
  FILE * fp /* pointer to the dump file */)
{
    DdNode	*support = NULL;
    DdNode	*scan;
    int		*sorted = NULL;
    int		nvars = dd->sizeZ;
    st_table	*visited = NULL;
    st_generator *gen;
    int		retval;
    int		i, j;
    int		slots;
    DdNodePtr	*nodelist;
    long	refAddr, diff, mask;

    /* Build a bit array with the support of f. */
    sorted = ALLOC(int,nvars);
    if (sorted == NULL) {
	dd->errorCode = CUDD_MEMORY_OUT;
	goto failure;
    }
    for (i = 0; i < nvars; i++) sorted[i] = 0;

    /* Take the union of the supports of each output function. */
    for (i = 0; i < n; i++) {
	support = Cudd_Support(dd,f[i]);
	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; /* so that we do not try to free it in case of failure */

    /* Initialize symbol table for visited nodes. */
    visited = st_init_table(st_ptrcmp, st_ptrhash);
    if (visited == NULL) goto failure;

    /* Collect all the nodes of this DD in the symbol table. */
    for (i = 0; i < n; i++) {
	retval = cuddCollectNodes(f[i],visited);
	if (retval == 0) goto failure;
    }

    /* 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. */
    refAddr = (long) f[0];
    diff = 0;
    gen = st_init_gen(visited);
    while (st_gen(gen, (char **) &scan, NULL)) {
	diff |= refAddr ^ (long) scan;
    }
    st_free_gen(gen);

    /* Choose the mask. */
    for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
	mask = (1 << i) - 1;
	if (diff <= mask) break;
    }

    /* Write the header and the global attributes. */
    retval = fprintf(fp,"digraph \"ZDD\" {\n");
    if (retval == EOF) return(0);
    retval = fprintf(fp,
	"size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n");
    if (retval == EOF) return(0);

    /* Write the input name subgraph by scanning the support array. */
    retval = fprintf(fp,"{ node [shape = plaintext];\n");
    if (retval == EOF) goto failure;
    retval = fprintf(fp,"  edge [style = invis];\n");
    if (retval == EOF) goto failure;
    /* We use a name ("CONST NODES") with an embedded blank, because
    ** it is unlikely to appear as an input name.
    */
    retval = fprintf(fp,"  \"CONST NODES\" [style = invis];\n");
    if (retval == EOF) goto failure;
    for (i = 0; i < nvars; i++) {
        if (sorted[dd->invpermZ[i]]) {
	    if (inames == NULL) {
		retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]);
	    } else {
		retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]);
	    }
            if (retval == EOF) goto failure;
        }
    }
    retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
    if (retval == EOF) goto failure;

    /* Write the output node subgraph. */
    retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n");
    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]);
	}
	if (retval == EOF) goto failure;
	if (i == n - 1) {
	    retval = fprintf(fp,"; }\n");
	} else {
	    retval = fprintf(fp," -> ");
	}
	if (retval == EOF) goto failure;
    }

    /* Write rank info: All nodes with the same index have the same rank. */
    for (i = 0; i < nvars; i++) {
        if (sorted[dd->invpermZ[i]]) {
	    retval = fprintf(fp,"{ rank = same; ");
	    if (retval == EOF) goto failure;
	    if (inames == NULL) {
		retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]);
	    } else {
		retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]);
	    }
            if (retval == EOF) goto failure;
	    nodelist = dd->subtableZ[i].nodelist;
	    slots = dd->subtableZ[i].slots;
	    for (j = 0; j < slots; j++) {
		scan = nodelist[j];
		while (scan != NULL) {
		    if (st_is_member(visited,(char *) scan)) {
			retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
			if (retval == EOF) goto failure;
		    }
		    scan = scan->next;
		}
	    }
	    retval = fprintf(fp,"}\n");
	    if (retval == EOF) goto failure;
	}
    }

    /* All constants have the same rank. */
    retval = fprintf(fp,
	"{ rank = same; \"CONST NODES\";\n{ node [shape = box]; ");
    if (retval == EOF) goto failure;
    nodelist = dd->constants.nodelist;
    slots = dd->constants.slots;
    for (j = 0; j < slots; j++) {
	scan = nodelist[j];
	while (scan != NULL) {
	    if (st_is_member(visited,(char *) scan)) {
		retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode));
		if (retval == EOF) goto failure;
	    }
	    scan = scan->next;
	}
    }
    retval = fprintf(fp,"}\n}\n");
    if (retval == EOF) goto failure;

    /* Write edge info. */
    /* Edges from the output nodes. */
    for (i = 0; i < n; i++) {
	if (onames == NULL) {
	    retval = fprintf(fp,"\"F%d\"", i);
	} else {
	    retval = fprintf(fp,"\"  %s  \"", onames[i]);
	}
	if (retval == EOF) goto failure;
	retval = fprintf(fp," -> \"%lx\" [style = solid];\n",
			 (mask & (long) f[i]) / sizeof(DdNode));
	if (retval == EOF) goto failure;
    }

    /* Edges from internal nodes. */
    for (i = 0; i < nvars; i++) {
        if (sorted[dd->invpermZ[i]]) {
	    nodelist = dd->subtableZ[i].nodelist;
	    slots = dd->subtableZ[i].slots;
	    for (j = 0; j < slots; j++) {
		scan = nodelist[j];
		while (scan != NULL) {
		    if (st_is_member(visited,(char *) scan)) {
			retval = fprintf(fp,
			    "\"%lx\" -> \"%lx\";\n",
			    (mask & (long) scan) / sizeof(DdNode),
			    (mask & (long) cuddT(scan)) / sizeof(DdNode));
			if (retval == EOF) goto failure;
			retval = fprintf(fp,
					 "\"%lx\" -> \"%lx\" [style = dashed];\n",
					 (mask & (long) scan) / sizeof(DdNode),
					 (mask & (long) cuddE(scan)) / sizeof(DdNode));
			if (retval == EOF) goto failure;
		    }
		    scan = scan->next;
		}
	    }
	}
    }

    /* Write constant labels. */
    nodelist = dd->constants.nodelist;
    slots = dd->constants.slots;
    for (j = 0; j < slots; j++) {
	scan = nodelist[j];
	while (scan != NULL) {
	    if (st_is_member(visited,(char *) scan)) {
		retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n",
		    (mask & (long) scan) / sizeof(DdNode), cuddV(scan));
		if (retval == EOF) goto failure;
	    }
	    scan = scan->next;
	}
    }

    /* Write trailer and return. */
    retval = fprintf(fp,"}\n");
    if (retval == EOF) goto failure;

    st_free_table(visited);
    FREE(sorted);
    return(1);

failure:
    if (sorted != NULL) FREE(sorted);
    if (support != NULL) Cudd_RecursiveDeref(dd,support);
    if (visited != NULL) st_free_table(visited);
    return(0);

} /* end of Cudd_zddDumpBlif */
Exemple #6
0
static int
DddmpCuddDdArrayStorePrefixStep (
  DdManager * ddMgr,
  DdNode * f,
  FILE * fp,
  st_table * visited,
  char ** names
  )
{
  DdNode *T, *E;
  int retValue;

#ifdef DDDMP_DEBUG
  assert(!Cudd_IsComplement(f));
#endif

  /* If already visited, nothing to do. */
  if (st_is_member(visited, (char *) f) == 1) {
    return(1);
  }

  /* Check for abnormal condition that should never happen. */
  if (f == NULL) {
    return(0);
  }

  /* Mark node as visited. */
  if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
    return(0);
  }

  /* Check for special case: If constant node, generate constant 1. */
  if (f == DD_ONE (ddMgr)) {
    retValue = fprintf (fp, "(OR node%" PRIxPTR " vss vdd)\n",
      (ptruint) f / sizeof(DdNode));
    if (retValue == EOF) {
       return(0);
    } else {
       return(1);
    }
  }

  /*
   *  Check whether this is an ADD. We deal with 0-1 ADDs, but not
   *  with the general case.
   */

  if (f == DD_ZERO(ddMgr)) {
    retValue = fprintf (fp, "(AND node%" PRIxPTR " vss vdd)\n",
       (ptruint) f / sizeof(DdNode));
   if (retValue == EOF) {
     return(0);
   } else {
     return(1);
   }
  }

  if (cuddIsConstant(f)) {
    return(0);
  }

  /* Recursive calls. */
  T = cuddT(f);
  retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,T,fp,visited,names);
  if (retValue != 1) {
    return(retValue);
  }
  E = Cudd_Regular(cuddE(f));
  retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,E,fp,visited,names);
  if (retValue != 1) {
    return(retValue);
  }

  /* Write multiplexer taking complement arc into account. */
  retValue = fprintf (fp, "(OR node%" PRIxPTR " (AND ",
    (ptruint) f / sizeof(DdNode));
  if (retValue == EOF) {
    return(0);
  }

  if (names != NULL) {
    retValue = fprintf(fp, "%s ", names[f->index]);
  } else {
    retValue = fprintf(fp, "inNode%d ", f->index);
  }
  if (retValue == EOF) {
    return(0);
  }

  retValue = fprintf (fp, "node%" PRIxPTR ") (AND (NOT ",
    (ptruint) T / sizeof(DdNode));
  if (retValue == EOF) {
    return(0);
  }

  if (names != NULL) {
    retValue = fprintf (fp, "%s", names[f->index]);
  } else {
    retValue = fprintf (fp, "inNode%d", f->index);
  }
  if (retValue == EOF) {
    return(0);
  }

  if (Cudd_IsComplement(cuddE(f))) {
    retValue = fprintf (fp, ") (NOT node%" PRIxPTR ")))\n",
      (ptruint) E / sizeof(DdNode));
  } else {
    retValue = fprintf (fp, ") node%" PRIxPTR "))\n",
      (ptruint) E / sizeof(DdNode));
  }

  if (retValue == EOF) {
    return(0);
  } else {
    return(1);
  }
}