Пример #1
0
/**Function********************************************************************

  Synopsis    [Checks if the two variables are symmetric.]

  Description [Returns 0 if vars are not symmetric. Return 1 if vars are symmetric.]

  SideEffects []

  SeeAlso     []

******************************************************************************/
int Extra_bddCheckVarsSymmetricNaive( 
  DdManager * dd,   /* the DD manager */
  DdNode * bF,
  int iVar1,
  int iVar2) 
{
    DdNode * bCube1, * bCube2;
    DdNode * bCof01, * bCof10;
    int Res;

    assert( iVar1 != iVar2 );
    assert( iVar1 < dd->size );
    assert( iVar2 < dd->size );

    bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] );   Cudd_Ref( bCube1 );
    bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] );   Cudd_Ref( bCube2 );

    bCof01 = Cudd_Cofactor( dd, bF, bCube1 );  Cudd_Ref( bCof01 );
    bCof10 = Cudd_Cofactor( dd, bF, bCube2 );  Cudd_Ref( bCof10 );

    Res = (int)( bCof10 == bCof01 );

    Cudd_RecursiveDeref( dd, bCof01 );
    Cudd_RecursiveDeref( dd, bCof10 );
    Cudd_RecursiveDeref( dd, bCube1 );
    Cudd_RecursiveDeref( dd, bCube2 );

    return Res;
} /* end of Extra_bddCheckVarsSymmetricNaive */
/**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;
}
Пример #3
0
/**Function********************************************************************

  Synopsis    [Classifies the variables in the support of two DDs.]

  Description [Classifies the variables in the support of two DDs
  <code>f</code> and <code>g</code>, depending on whther they appear
  in both DDs, only in <code>f</code>, or only in <code>g</code>.
  Returns 1 if successful; 0 otherwise.]

  SideEffects [The cubes of the three classes of variables are
  returned as side effects.]

  SeeAlso     []

******************************************************************************/
int
Cuddaux_ClassifySupport(
			DdManager * dd /* manager */,
			DdNode * f /* first DD */,
			DdNode * g /* second DD */,
			DdNode ** common /* cube of shared variables */,
			DdNode ** onlyF /* cube of variables only in f */,
			DdNode ** onlyG /* cube of variables only in g */)
{
  DdNode *suppF, *suppG;

  suppF = suppG = *common = *onlyF = *onlyG = NULL;

  suppF = Cuddaux_Support(dd,f);
  if (suppF == NULL) goto Cuddaux_ClassifySupport_error;
  cuddRef(suppF);

  suppG = Cuddaux_Support(dd,g);
  if (suppG == NULL) goto Cuddaux_ClassifySupport_error;
  cuddRef(suppG);

  *common = Cudd_bddLiteralSetIntersection(dd,suppF,suppG);
  if (*common == NULL) goto Cuddaux_ClassifySupport_error;
  cuddRef(*common);

  *onlyF = Cudd_Cofactor(dd,suppF,*common);
  if (*onlyF == NULL) goto Cuddaux_ClassifySupport_error;
  cuddRef(*onlyF);

  *onlyG = Cudd_Cofactor(dd,suppG,*common);
  if (*onlyG == NULL) goto Cuddaux_ClassifySupport_error;
  cuddRef(*onlyG);
  Cudd_IterDerefBdd(dd,suppF);
  Cudd_IterDerefBdd(dd,suppG);
  cuddDeref(*common);
  cuddDeref(*onlyF);
  cuddDeref(*onlyG);
  return 1;
 Cuddaux_ClassifySupport_error:
  if (suppF) Cudd_IterDerefBdd(dd,suppF);
  if (suppG) Cudd_IterDerefBdd(dd,suppG);
  if (*common){
    Cudd_IterDerefBdd(dd,*common);
    *common = NULL;
  }
  if (*onlyF){
    Cudd_IterDerefBdd(dd,*onlyF);
    *onlyF = NULL;
  }
  if (*onlyG){
    Cudd_IterDerefBdd(dd,*onlyG);
    *onlyG = NULL;
  }
  dd->errorCode = CUDD_MEMORY_OUT;
  return(0);
} /* end of Cuddaux_ClassifySupport */
Пример #4
0
/**Function*************************************************************

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars )
{
	DdNode * bNegCube;
	DdNode * bResult;
	bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars );  Cudd_Ref( bNegCube );
	bResult  = Cudd_Cofactor( dd, bFunc, bNegCube );            Cudd_Ref( bResult );
	Cudd_RecursiveDeref( dd, bNegCube );
	Cudd_Deref( bResult );
	return bResult;
}
Пример #5
0
static keyvalue_table_ptr cudd_restrict(shadow_mgr mgr, set_ptr roots,
					set_ptr lits) {
    DdNode *cube = cudd_lit_cube(mgr, lits);
    keyvalue_table_ptr rtable = word_keyvalue_new();
    word_t w;
    set_iterstart(roots);
    while (set_iternext(roots, &w)) {
	ref_t r = (ref_t) w;
	DdNode *n = get_ddnode(mgr, r);
	DdNode *nr = Cudd_Cofactor(mgr->bdd_manager, n, cube);
	reference_dd(mgr, nr);
	keyvalue_insert(rtable, w, (word_t) nr);
    }
    unreference_dd(mgr, cube, IS_BDD);
    return rtable;
}
Пример #6
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_MvDecompose( Mv_Man_t * p )
{
    DdNode * bCofs[16], * bVarCube1, * bVarCube2, * bVarCube, * bCube, * bVar0, * bVar1;//, * bRes;
    int k, i1, i2, v1, v2;//, c1, c2, Counter;

    bVar0 = Cudd_bddIthVar(p->dd, 30);
    bVar1 = Cudd_bddIthVar(p->dd, 31);
    bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 );  Cudd_Ref( bCube );

    for ( k = 0; k < p->nFuncs; k++ )
    {
        printf( "FUNCTION %d\n", k );
        for ( i1 = 0; i1 < p->nFuncs; i1++ )
        for ( i2 = i1+1; i2 < p->nFuncs; i2++ )
        {
            Vec_Ptr_t * vCofs;

            for ( v1 = 0; v1 < 4; v1++ )
            {
                bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1  ), ((v1 & 1) == 0) );
                bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1-1), ((v1 & 2) == 0) );
                bVarCube1 = Cudd_bddAnd( p->dd, bVar0, bVar1 );  Cudd_Ref( bVarCube1 );
                for ( v2 = 0; v2 < 4; v2++ )
                {
                    bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2  ), ((v2 & 1) == 0) );
                    bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2-1), ((v2 & 2) == 0) );
                    bVarCube2 = Cudd_bddAnd( p->dd, bVar0, bVar1 );         Cudd_Ref( bVarCube2 );
                    bVarCube = Cudd_bddAnd( p->dd, bVarCube1, bVarCube2 );  Cudd_Ref( bVarCube );
                    bCofs[v1 * 4 + v2] = Cudd_Cofactor( p->dd, p->bFuncs[k], bVarCube );  Cudd_Ref( bCofs[v1 * 4 + v2] );
                    Cudd_RecursiveDeref( p->dd, bVarCube );
                    Cudd_RecursiveDeref( p->dd, bVarCube2 );
                }
                Cudd_RecursiveDeref( p->dd, bVarCube1 );
            }
/*
            // check the compatibility of cofactors
            Counter = 0;
            for ( c1 = 0; c1 < 16; c1++ )
            {
                for ( c2 = 0; c2 <= c1; c2++ )
                    printf( " " );
                for ( c2 = c1+1; c2 < 16; c2++ )
                {
                    bRes = Cudd_bddAndAbstract( p->dd, bCofs[c1], bCofs[c2], bCube );  Cudd_Ref( bRes );
                    if ( bRes == Cudd_ReadOne(p->dd) )
                    {
                        printf( "+" );
                        Counter++;
                    }
                    else
                    {
                        printf( " " );
                    }
                    Cudd_RecursiveDeref( p->dd, bRes );
                }
                printf( "\n" );
            }
*/

            vCofs = Vec_PtrAlloc( 16 );
            for ( v1 = 0; v1 < 4; v1++ )
            for ( v2 = 0; v2 < 4; v2++ )
                Vec_PtrPushUnique( vCofs, bCofs[v1 * 4 + v2] );
            printf( "%d ", Vec_PtrSize(vCofs) );
            Vec_PtrFree( vCofs );

            // free the cofactors
            for ( v1 = 0; v1 < 4; v1++ )
            for ( v2 = 0; v2 < 4; v2++ )
                Cudd_RecursiveDeref( p->dd, bCofs[v1 * 4 + v2] );

            printf( "\n" );
//            printf( "%2d, %2d : %3d\n", i1, i2, Counter );
        }
    }

    Cudd_RecursiveDeref( p->dd, bCube );
}
Пример #7
0
/**Function********************************************************************

  Synopsis    [Floyd-Warshall algorithm for all-pair shortest paths.]

  Description []

  SideEffects []

  SeeAlso     []

******************************************************************************/
static DdNode *
ntrWarshall(
  DdManager *dd,
  DdNode *D,
  DdNode **x,
  DdNode **y,
  int vars,
  int pr)
{
    DdNode *one, *zero;
    DdNode *xminterm,  *w, *V, *V2;
    DdNode *P, *R;
    int i;
    int nodes;
    int k,u;
    long start_time;
    if (vars > 30)
	nodes = 1000000000;
    else
	nodes = 1 << vars;

    one = DD_ONE(dd);
    zero = DD_ZERO(dd);
    Cudd_Ref(R = D);                        /* make copy of original matrix */

    /* Extract pivot row and column from D */
    start_time = util_cpu_time();
    for (k = 0; k < nodes; k++) {
        if (k % 10000 == 0) {
	    (void) printf("Starting iteration  %d  at time %s\n",
			  k,util_print_time(util_cpu_time() - start_time));
        }
        Cudd_Ref(xminterm = one);
        u = k;
	for (i = vars-1; i >= 0; i--) {
	    if (u&1) {
	        Cudd_Ref(w = Cudd_addIte(dd,x[i],xminterm,zero));
	    } else {
	        Cudd_Ref(w = Cudd_addIte(dd,x[i],zero,xminterm));
	    }
	    Cudd_RecursiveDeref(dd,xminterm);
	    xminterm = w;
	    u >>= 1;
	}

	Cudd_Ref(V = Cudd_Cofactor(dd,R,xminterm));
	Cudd_RecursiveDeref(dd,xminterm);
	if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);}


	Cudd_Ref(xminterm = one);
	u = k;
	for (i = vars-1; i >= 0; i--) {
	    if (u&1) {
	        Cudd_Ref(w = Cudd_addIte(dd,y[i],xminterm,zero));
	    } else {
	        Cudd_Ref(w = Cudd_addIte(dd,y[i],zero,xminterm));
	    }
	    Cudd_RecursiveDeref(dd,xminterm);
	    xminterm = w;
	    u >>= 1;
	}

	Cudd_Ref(V2 = Cudd_Cofactor(dd,R,xminterm));
	Cudd_RecursiveDeref(dd,xminterm);
	if (pr>2) {(void) printf("V2"); Cudd_PrintDebug(dd,V2,vars,pr);}

	Cudd_Ref(P = Cudd_addOuterSum(dd,R,V,V2));

	Cudd_RecursiveDeref(dd,V);
	Cudd_RecursiveDeref(dd,V2);
	Cudd_RecursiveDeref(dd,R);
	R = P;
	if (pr>2) {(void) printf("R"); Cudd_PrintDebug(dd,R,vars,pr);}
    }

    Cudd_Deref(R);
    return(R);

} /* end of ntrWarshall */
Пример #8
0
/**Function********************************************************************

  Synopsis    [Bellman-Ford algorithm for single-source shortest paths.]

  Description [Bellman-Ford algorithm for single-source shortest
  paths.  Returns the vector of the distances of all states from the
  initial states.  In case of multiple initial states the distance for
  each state is from the nearest initial state.  Negative-weight
  cycles are detected, though only in the naive way.  (Lack of
  convergence after nodes-1 iterations.)  In such a case, a constant
  ADD with value minus infinity is returned.  Bellman-Ford is based on
  matrix-vector multiplication.  The matrix is the distance matrix
  D(x,y), such that D(a,b) is the length of the arc connecting state a
  to state b.  The vector V(x) stores the distances of all states from
  the initial states.  The actual vector used in the matrix-vector
  multiplication is diff(x), that holds those distances that have
  changed during the last update.]

  SideEffects []

  SeeAlso     [ntrWarshall ntrSquare]

******************************************************************************/
static DdNode *
ntrBellman(
  DdManager *dd,
  DdNode *D,
  DdNode *source,
  DdNode **x,
  DdNode **y,
  int vars,
  int pr)
{
    DdNode *u, *w, *V, *min, *diff;
    DdApaNumber i, nodes, one;
    int digits = vars + 1;

    /* To avoid overflow when there are many variables, use APA. */
    nodes = Cudd_NewApaNumber(digits);
    Cudd_ApaPowerOfTwo(digits,nodes,vars);
    i = Cudd_NewApaNumber(digits);
    one = Cudd_NewApaNumber(digits);
    Cudd_ApaSetToLiteral(digits,one,1);

#if 0
    /* Find the distances from the initial state along paths using one
    ** arc. */
    w = Cudd_Cofactor(dd,D,source); /* works only if source is a cube */
    Cudd_Ref(w);
    V = Cudd_addSwapVariables(dd,w,x,y,vars);
    Cudd_Ref(V);
    Cudd_RecursiveDeref(dd,w);
#endif

    /* The initial states are at distance 0. The other states are
    ** initially at infinite distance. */
    V = Cudd_addIte(dd,source,Cudd_ReadZero(dd),Cudd_ReadPlusInfinity(dd));
    Cudd_Ref(V);

    /* Selective trace algorithm.  For the next update, only consider the
    ** nodes whose distance has changed in the last update. */
    diff = V;
    Cudd_Ref(diff);

    for (Cudd_ApaSetToLiteral(digits,i,1);
	 Cudd_ApaCompare(digits,i,digits,nodes) < 0;
	 Cudd_ApaAdd(digits,i,one,i)) {
	if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);}
	/* Compute the distances via triangulation as a function of x. */
	w = Cudd_addTriangle(dd,diff,D,x,vars);
	Cudd_Ref(w);
	Cudd_RecursiveDeref(dd,diff);
	u = Cudd_addSwapVariables(dd,w,x,y,vars);
	Cudd_Ref(u);
	Cudd_RecursiveDeref(dd,w);
	if (pr>2) {(void) printf("u"); Cudd_PrintDebug(dd,u,vars,pr);}

	/* Take the minimum of the previous distances and those just
	** computed. */
	min = Cudd_addApply(dd,Cudd_addMinimum,V,u);
	Cudd_Ref(min);
	Cudd_RecursiveDeref(dd,u);
	if (pr>2) {(void) printf("min"); Cudd_PrintDebug(dd,min,vars,pr);}

	if (V == min) {		/* convergence */
	    Cudd_RecursiveDeref(dd,min);
	    if (pr>0) {
		(void) printf("Terminating after ");
		Cudd_ApaPrintDecimal(stdout,digits,i);
		(void) printf(" iterations\n");
	    }
	    break;
	}
	/* Find the distances that decreased. */
	diff = Cudd_addApply(dd,Cudd_addDiff,V,min);
	Cudd_Ref(diff);
	if (pr>2) {(void) printf("diff"); Cudd_PrintDebug(dd,diff,vars,pr);}
	Cudd_RecursiveDeref(dd,V);
	V = min;
    }
    /* Negative cycle detection. */
    if (Cudd_ApaCompare(digits,i,digits,nodes) == 0 &&
	diff != Cudd_ReadPlusInfinity(dd)) {
	(void) printf("Negative cycle\n");
	Cudd_RecursiveDeref(dd,diff);
	Cudd_RecursiveDeref(dd,V);
	V = Cudd_ReadMinusInfinity(dd);
	Cudd_Ref(V);
    }

    Cudd_Deref(V);
    FREE(i);
    FREE(nodes);
    FREE(one);
    return(V);

} /* end of ntrBellman */
Пример #9
0
/**Function********************************************************************

  Synopsis [BDD restrict according to Coudert and Madre's algorithm
  (ICCAD90).]

  Description [BDD restrict according to Coudert and Madre's algorithm
  (ICCAD90). Returns the restricted BDD if successful; otherwise NULL.]

  SideEffects [None]

  SeeAlso     [Cudd_bddRestrict]

******************************************************************************/
DdNode*
Cuddaux_bddRestrict(DdManager * dd, DdNode * f, DdNode * c)
{
  DdNode *one,*zero;
  DdNode *suppF, *suppC, *commonSupp, *onlyC;
  DdNode *cplus, *res;
  int retval;
  
  one = DD_ONE(dd);
  zero = Cudd_Not(one);
  /* Check terminal cases here to avoid computing supports in trivial cases.
  ** This also allows us notto check later for the case c == 0, in which
  ** there is no common support. */
  if (c == one) return(f);
  if (c == zero){
    fprintf(stderr,"Cuddaux_bddRestrict: warning: false careset\n");
    return(zero);
  }
  if (Cudd_IsConstant(f)) return(f);
  if (f == c) return(one);
  if (f == Cudd_Not(c)) return(zero);
  
  /* Check if supports intersect. */
  suppF = Cuddaux_Support(dd,f);
  if (suppF==NULL) return(NULL);
  cuddRef(suppF);

  suppC = Cuddaux_Support(dd,c);
  if (suppC==NULL){
    Cudd_IterDerefBdd(dd,suppF);
    return(NULL);
  }
  cuddRef(suppC);

  commonSupp = Cudd_bddLiteralSetIntersection(dd,suppF,suppC);
  if (commonSupp==NULL){
    Cudd_IterDerefBdd(dd,suppF);
    Cudd_IterDerefBdd(dd,suppC); 
    return(NULL);
  }
  if (commonSupp == one) {
    Cudd_IterDerefBdd(dd,suppF);
    Cudd_IterDerefBdd(dd,suppC); 
    return(f);
  }
  cuddRef(commonSupp);

  Cudd_IterDerefBdd(dd,suppF);
  /* Abstract from c the variables that do not appear in f. */
  onlyC = Cudd_Cofactor(dd,suppC,commonSupp);
  if (onlyC == NULL) {
    Cudd_IterDerefBdd(dd,suppC); 
    Cudd_IterDerefBdd(dd,commonSupp); 
    return(NULL);
  }
  cuddRef(onlyC);
  Cudd_IterDerefBdd(dd,suppC); 
  Cudd_IterDerefBdd(dd,commonSupp); 
  cplus = Cudd_bddExistAbstract(dd, c, onlyC);
  if (cplus == NULL) {
    Cudd_IterDerefBdd(dd,onlyC); 
    return(NULL);
  }
  cuddRef(cplus);
  Cudd_IterDerefBdd(dd,onlyC);
  
  do {
    dd->reordered = 0;
    res = cuddBddRestrictRecur(dd, f, cplus);
  } while (dd->reordered == 1);
  if (res == NULL) {
    Cudd_IterDerefBdd(dd,cplus);
    return(NULL);
  }
  cuddRef(res);
  Cudd_IterDerefBdd(dd,cplus);
  cuddDeref(res);
  return(res);
} /* end of Cuddaux_bddRestrict */