Exemplo n.º 1
0
/**Function********************************************************************

  Synopsis    [Generates a BDD for the function x==y.]

  Description [This function generates a BDD for the function x==y.
  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
  y\[0\] y\[1\] ...  y\[N-1\], with 0 the most significant bit.
  The BDD is built bottom-up.
  It has 3*N-1 internal nodes, if the variables are ordered as follows: 
  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]

  SideEffects [None]

  SeeAlso     [Cudd_addXeqy]

******************************************************************************/
DdNode *
Cudd_Xeqy(
  DdManager * dd /* DD manager */,
  int  N /* number of x and y variables */,
  DdNode ** x /* array of x variables */,
  DdNode ** y /* array of y variables */)
{
    DdNode *u, *v, *w;
    int     i;

    /* Build bottom part of BDD outside loop. */
    u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1]));
    if (u == NULL) return(NULL);
    cuddRef(u);

    /* Loop to build the rest of the BDD. */
    for (i = N-2; i >= 0; i--) {
	v = Cudd_bddAnd(dd, y[i], u);
	if (v == NULL) {
	    Cudd_RecursiveDeref(dd, u);
	    return(NULL);
	}
	cuddRef(v);
	w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u);
	if (w == NULL) {
	    Cudd_RecursiveDeref(dd, u);
	    Cudd_RecursiveDeref(dd, v);
	    return(NULL);
	}
	cuddRef(w);
	Cudd_RecursiveDeref(dd, u);
	u = Cudd_bddIte(dd, x[i], v, w);
	if (u == NULL) {
	    Cudd_RecursiveDeref(dd, v);
	    Cudd_RecursiveDeref(dd, w);
	    return(NULL);
	}
	cuddRef(u);
	Cudd_RecursiveDeref(dd, v);
	Cudd_RecursiveDeref(dd, w);
    }
    cuddDeref(u);
    return(u);

} /* end of Cudd_Xeqy */
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * dsdTreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode, int fRemap ) 
{
	DdNode * bCof0,  * bCof1, * bCube0, * bCube1, * bNewFunc, * bTemp;
	int i;
	int fAllBuffs = 1;
	static int Permute[MAXINPUTS];

	assert( pNode );
	assert( !Dsd_IsComplement( pNode ) );
	assert( pNode->Type == DT_PRIME );

	// transform the function of this block to depend on inputs
	// corresponding to the formal inputs

	// first, substitute those inputs that have some blocks associated with them
	// second, remap the inputs to the top of the manager (then, it is easy to output them)

	// start the function
	bNewFunc = pNode->G;  Cudd_Ref( bNewFunc );
	// go over all primary inputs
	for ( i = 0; i < pNode->nDecs; i++ )
	if ( pNode->pDecs[i]->Type != DT_BUF ) // remap only if it is not the buffer
	{
		bCube0 = Extra_bddFindOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) );  Cudd_Ref( bCube0 );
		bCof0 = Cudd_Cofactor( dd, bNewFunc, bCube0 );                     Cudd_Ref( bCof0 );
		Cudd_RecursiveDeref( dd, bCube0 );

		bCube1 = Extra_bddFindOneCube( dd,          pNode->pDecs[i]->G  );  Cudd_Ref( bCube1 );
		bCof1 = Cudd_Cofactor( dd, bNewFunc, bCube1 );                     Cudd_Ref( bCof1 );
		Cudd_RecursiveDeref( dd, bCube1 );

		Cudd_RecursiveDeref( dd, bNewFunc );

		// use the variable in the i-th level of the manager
//		bNewFunc = Cudd_bddIte( dd, dd->vars[dd->invperm[i]],bCof1,bCof0 );     Cudd_Ref( bNewFunc );
		// use the first variale in the support of the component
		bNewFunc = Cudd_bddIte( dd, dd->vars[pNode->pDecs[i]->S->index],bCof1,bCof0 );     Cudd_Ref( bNewFunc );
		Cudd_RecursiveDeref( dd, bCof0 );
		Cudd_RecursiveDeref( dd, bCof1 );
	}

	if ( fRemap )
	{
		// remap the function to the top of the manager
		// remap the function to the first variables of the manager
		for ( i = 0; i < pNode->nDecs; i++ )
	//		Permute[ pNode->pDecs[i]->S->index ] = dd->invperm[i];
			Permute[ pNode->pDecs[i]->S->index ] = i;

		bNewFunc = Cudd_bddPermute( dd, bTemp = bNewFunc, Permute );   Cudd_Ref( bNewFunc );
		Cudd_RecursiveDeref( dd, bTemp );
	}

	Cudd_Deref( bNewFunc );
	return bNewFunc;
}
Exemplo n.º 3
0
/**Function********************************************************************

  Synopsis    [Computes the Hamming distance ADD.]

  Description [Computes the Hamming distance ADD. Returns an ADD that
  gives the Hamming distance between its two arguments if successful;
  NULL otherwise. The two vectors xVars and yVars identify the variables
  that form the two arguments.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
DdNode *
Cudd_addHamming(
  DdManager * dd,
  DdNode ** xVars,
  DdNode ** yVars,
  int  nVars)
{
    DdNode  *result,*tempBdd;
    DdNode  *tempAdd,*temp;
    int     i;

    result = DD_ZERO(dd);
    cuddRef(result);

    for (i = 0; i < nVars; i++) {
	tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]);
	if (tempBdd == NULL) {
	    Cudd_RecursiveDeref(dd,result);
	    return(NULL);
	}
	cuddRef(tempBdd);
	tempAdd = Cudd_BddToAdd(dd,tempBdd);
	if (tempAdd == NULL) {
	    Cudd_RecursiveDeref(dd,tempBdd);
	    Cudd_RecursiveDeref(dd,result);
	    return(NULL);
	}
	cuddRef(tempAdd);
	Cudd_RecursiveDeref(dd,tempBdd);
	temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result);
	if (temp == NULL) {
	    Cudd_RecursiveDeref(dd,tempAdd);
	    Cudd_RecursiveDeref(dd,result);
	    return(NULL);
	}
	cuddRef(temp);
	Cudd_RecursiveDeref(dd,tempAdd);
	Cudd_RecursiveDeref(dd,result);
	result = temp;
    }

    cuddDeref(result);
    return(result);

} /* end of Cudd_addHamming */
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_dsdRemap( DdManager * dd, DdNode * bF, st_table * pCache,
    int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] )
{
	DdNode * bFR, * bF0, * bF1;
    DdNode * bRes0, * bRes1, * bRes;
	int iForm;
	
	bFR = Cudd_Regular(bF);
	if ( cuddIsConstant(bFR) )
		return bF;

	// check the hash-table
	if ( bFR->ref != 1 )
	{
        if ( st_lookup( pCache, (char *)bF, (char **)&bRes ) )
            return bRes;
	}

    // get the formal input
    iForm = pVar2Form[bFR->index];

    // get the nodes pointed to by the cube
    bF0 = Extra_bddNodePointedByCube( dd, bF, pbCube0[iForm] );
    bF1 = Extra_bddNodePointedByCube( dd, bF, pbCube1[iForm] );

    // call recursively for these nodes
    bRes0 = Extra_dsdRemap( dd, bF0, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes0 );
    bRes1 = Extra_dsdRemap( dd, bF1, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes1 );

	// derive the result using ITE
	bRes = Cudd_bddIte( dd, dd->vars[ pForm2Var[iForm] ], bRes1, bRes0 ); Cudd_Ref( bRes );
    Cudd_RecursiveDeref( dd, bRes0 );
    Cudd_RecursiveDeref( dd, bRes1 );

	// add to the hash table
	if ( bFR->ref != 1 )
        st_insert( pCache, (char *)bF, (char *)bRes );
    Cudd_Deref( bRes );
    return bRes;
}
Exemplo n.º 5
0
/**Function********************************************************************

  Synopsis    [Generates a BDD for the function d(x,y) &gt; d(y,z).]

  Description [This function generates a BDD for the function d(x,y)
  &gt; d(y,z);
  x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
  y\[0\] y\[1\] ...  y\[N-1\], and z\[0\] z\[1\] ...  z\[N-1\],
  with 0 the most significant bit.
  The distance d(x,y) is defined as:
	\sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}).
  The BDD is built bottom-up.
  It has 7*N-3 internal nodes, if the variables are ordered as follows: 
  x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]

  SideEffects [None]

  SeeAlso     [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX]

******************************************************************************/
DdNode *
Cudd_Dxygtdyz(
  DdManager * dd /* DD manager */,
  int  N /* number of x, y, and z variables */,
  DdNode ** x /* array of x variables */,
  DdNode ** y /* array of y variables */,
  DdNode ** z /* array of z variables */)
{
    DdNode *one, *zero;
    DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
    int     i;

    one = DD_ONE(dd);
    zero = Cudd_Not(one);

    /* Build bottom part of BDD outside loop. */
    y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]);
    if (y1_ == NULL) return(NULL);
    cuddRef(y1_);
    y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero);
    if (y2 == NULL) {
	Cudd_RecursiveDeref(dd, y1_);
	return(NULL);
    }
    cuddRef(y2);
    x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2));
    if (x1 == NULL) {
	Cudd_RecursiveDeref(dd, y1_);
	Cudd_RecursiveDeref(dd, y2);
	return(NULL);
    }
    cuddRef(x1);
    Cudd_RecursiveDeref(dd, y1_);
    Cudd_RecursiveDeref(dd, y2);

    /* Loop to build the rest of the BDD. */
    for (i = N-2; i >= 0; i--) {
	z1 = Cudd_bddIte(dd, z[i], x1, zero);
	if (z1 == NULL) {
	    Cudd_RecursiveDeref(dd, x1);
	    return(NULL);
	}
	cuddRef(z1);
	z2 = Cudd_bddIte(dd, z[i], x1, one);
	if (z2 == NULL) {
	    Cudd_RecursiveDeref(dd, x1);
	    Cudd_RecursiveDeref(dd, z1);
	    return(NULL);
	}
	cuddRef(z2);
	z3 = Cudd_bddIte(dd, z[i], one, x1);
	if (z3 == NULL) {
	    Cudd_RecursiveDeref(dd, x1);
	    Cudd_RecursiveDeref(dd, z1);
	    Cudd_RecursiveDeref(dd, z2);
	    return(NULL);
	}
	cuddRef(z3);
	z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1));
	if (z4 == NULL) {
	    Cudd_RecursiveDeref(dd, x1);
	    Cudd_RecursiveDeref(dd, z1);
	    Cudd_RecursiveDeref(dd, z2);
	    Cudd_RecursiveDeref(dd, z3);
	    return(NULL);
	}
	cuddRef(z4);
	Cudd_RecursiveDeref(dd, x1);
	y1_ = Cudd_bddIte(dd, y[i], z2, z1);
	if (y1_ == NULL) {
	    Cudd_RecursiveDeref(dd, z1);
	    Cudd_RecursiveDeref(dd, z2);
	    Cudd_RecursiveDeref(dd, z3);
	    Cudd_RecursiveDeref(dd, z4);
	    return(NULL);
	}
	cuddRef(y1_);
	y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3));
	if (y2 == NULL) {
	    Cudd_RecursiveDeref(dd, z1);
	    Cudd_RecursiveDeref(dd, z2);
	    Cudd_RecursiveDeref(dd, z3);
	    Cudd_RecursiveDeref(dd, z4);
	    Cudd_RecursiveDeref(dd, y1_);
	    return(NULL);
	}
	cuddRef(y2);
	Cudd_RecursiveDeref(dd, z1);
	Cudd_RecursiveDeref(dd, z2);
	Cudd_RecursiveDeref(dd, z3);
	Cudd_RecursiveDeref(dd, z4);
	x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2));
	if (x1 == NULL) {
	    Cudd_RecursiveDeref(dd, y1_);
	    Cudd_RecursiveDeref(dd, y2);
	    return(NULL);
	}
	cuddRef(x1);
	Cudd_RecursiveDeref(dd, y1_);
	Cudd_RecursiveDeref(dd, y2);
    }
    cuddDeref(x1);
    return(Cudd_Not(x1));

} /* end of Cudd_Dxygtdyz */
Exemplo n.º 6
0
void
I_BDD_new_mutex_domain (DdManager *dd, DdNode *node[], unsigned int size)
{
  unsigned int shbuf, vars, ctr;
  DdNode **ddVar, *one, *newnode, *oldnode, *bitnode;
  int i,j, extra;

  /* base cases */

  if (size == 0)
    {
      return;
    }

  one = Cudd_ReadOne(dd);

  if (size == 1)
    {
      node[0] = one;
      Cudd_Ref (node[0]);
      return;
    }

  for(shbuf = size - 1, vars = 0; shbuf != 0; shbuf >>= 1, vars++);

  extra = (1 << vars) - size;

  ddVar = malloc(vars * sizeof(DdNode *));

  for (j = 0; j < vars; j++)
    {
      ddVar[j] = bitnode = Cudd_bddNewVar (dd);
      Cudd_Ref (bitnode);
    }

  ctr = 0;

  for (i = 0; i < size; i++, ctr++)
    {
      newnode = one;
      Cudd_Ref (newnode);

#ifdef I_BDD_MUTEX_DEBUG
      printf("i%d:", i);
#endif

      for (j = (extra > 0); j < vars; j++)
	{
	  bitnode = (ctr & (1 << j)) ? ddVar[j] : Cudd_Not(ddVar[j]);

	  newnode = Cudd_bddAnd (dd, bitnode, oldnode = newnode);
	  Cudd_Ref (newnode);
	  Cudd_RecursiveDeref (dd, oldnode);

#ifdef I_BDD_MUTEX_DEBUG
	  if (ctr & (1 << j))
	    printf("+ v%d ", j);
	  else
	    printf("+ !v%d ", j);
#endif
	}

#ifdef I_BDD_MUTEX_DEBUG
      printf ("\n");
#endif

      node[i] = newnode;

      if (extra > 0)
	{
	  extra--;
	  ctr++;
	}
    }

#ifdef I_BDD_MUTEX_TEST
  {
    DdNode *test, *old_test;
    int i;
    test = Cudd_ReadLogicZero(dd);
    Cudd_Ref (test);
    for (i = 0; i < size; i++)
      {
	if (Cudd_bddIte (dd, test, node[i], zero) != zero)
	  I_punt("I_BDD_new_mutex_complex: not mutex!");

	test = Cudd_bddIte(dd, node[i], one, old_test = test);
	Cudd_Ref (test);
	Cudd_RecursiveDeref (dd, old_test);
      }
    if (test != one)
      I_punt("I_BDD_new_mutex_complex: not exhaustive!");

    Cudd_RecursiveDeref (dd, test);
    }
#endif

  for (j = 0; j < vars; j++)
    Cudd_RecursiveDeref (dd, ddVar[j]);

  free (ddVar);
  return;
}
Exemplo n.º 7
0
ref_t shadow_ite(shadow_mgr mgr, ref_t iref, ref_t tref, ref_t eref) {
    DdNode *in = get_ddnode(mgr, iref);
    DdNode *tn = get_ddnode(mgr, tref);
    DdNode *en = get_ddnode(mgr, eref);
    DdNode *n = NULL;
    ref_t r = REF_INVALID;
    dd_type_t dtype = IS_BDD;

    if (mgr->do_local) {
	r = ref_ite(mgr->ref_mgr, iref, tref, eref);
    }
    if (mgr->do_dist) {
	ref_t rdist = dist_ite(mgr->ref_mgr, iref, tref, eref);
	if (mgr->do_local) {
	    if (!check_refs(mgr, r, rdist)) {
		return REF_INVALID;
	    }
	} else {
	    r = rdist;
	}
    }

    if (mgr->do_cudd) {

	if (mgr->nzvars > 0) {
	    bool zi = is_zdd(mgr, iref);
	    bool zt = is_zdd(mgr, tref);
	    bool ze = is_zdd(mgr, eref);
	    if (zi || zt || ze) {
		dtype = IS_ZDD;
		if (is_add(mgr, iref) || is_add(mgr, tref) || is_add(mgr, eref)) {
		    err(false, "Can't mix ADDs with ZDDs");
		}
		if (!zi) {
		    in = zconvert(mgr, in);
		}
		if (!zt) {
		    tn = zconvert(mgr, tn);
		}
		if (!ze) {
		    en = zconvert(mgr, en);
		}
		n = Cudd_zddIte(mgr->bdd_manager, in, tn, en);
		reference_dd(mgr, n);
		if (!zi)
		    unreference_dd(mgr, in, IS_ZDD);
		if (!zt)
		    unreference_dd(mgr, tn, IS_ZDD);
		if (!ze)
		    unreference_dd(mgr, en, IS_ZDD);
	    }
	}
	{
	    bool ai = is_add(mgr, iref);
	    bool at = is_add(mgr, tref);
	    bool ae = is_add(mgr, eref);

	    if (ai || at || ae) {
		dtype = IS_ADD;
		if (!ai) {
		    in = aconvert(mgr, in);
		}
		if (!at) {
		    tn = aconvert(mgr, tn);
		}
		if (!ae) {
		    en = aconvert(mgr, en);
		}
		n = Cudd_addIte(mgr->bdd_manager, in, tn, en);
		reference_dd(mgr, n);
		if (!ai)
		    unreference_dd(mgr, in, IS_ADD);
		if (!at)
		    unreference_dd(mgr, tn, IS_ADD);
		if (!ae)
		    unreference_dd(mgr, en, IS_ADD);
	    }
	}
	if (dtype == IS_BDD) {
	    n = Cudd_bddIte(mgr->bdd_manager, in, tn, en);
	    reference_dd(mgr, n);
	}
    } else {
	n = ref2dd(mgr, r);
    }
    if (!do_ref(mgr))
	r = dd2ref(n, dtype);
    add_ref(mgr, r, n);
    return r;
}