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

  Synopsis    [Substitutes g for x_v in the BDD for f.]

  Description [Substitutes g for x_v in the BDD for f. v is the index of the
  variable to be substituted. Cudd_bddCompose passes the corresponding
  projection function to the recursive procedure, so that the cache may
  be used.  Returns the composed BDD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addCompose]

******************************************************************************/
DdNode *
Cudd_bddCompose(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  int  v)
{
    DdNode *proj, *res;

    /* Sanity check. */
    if (v < 0 || v > dd->size) return(NULL);

    proj =  dd->vars[v];
    do {
	dd->reordered = 0;
	res = cuddBddComposeRecur(dd,f,g,proj);
    } while (dd->reordered == 1);
    return(res);

} /* end of Cudd_bddCompose */
Пример #2
0
/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_SolveEqn.]

  Description [Implements the recursive step of Cudd_SolveEqn. 
  Returns NULL if the intermediate solution blows up
  or reordering occurs. The parametric solutions are
  stored in the array G.]

  SideEffects [none]

  SeeAlso     [Cudd_SolveEqn, Cudd_VerifySol]

******************************************************************************/
DdNode *
cuddSolveEqnRecur(
  DdManager * bdd,
  DdNode * F /* the left-hand side of the equation */,
  DdNode * Y /* the cube of remaining y variables */,
  DdNode ** G /* the array of solutions */,
  int  n /* number of unknowns */,
  int * yIndex /* array holding the y variable indices */,
  int  i /* level of recursion */)
{
    DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
    DdNodePtr *variables;

    int j;

    statLine(bdd);
    variables = bdd->vars;
    one = DD_ONE(bdd);

    /* Base condition. */
    if (Y == one) {
	return F;
    }

    /* Cofactor of Y. */
    yIndex[i] = Y->index;
    nextY = Cudd_T(Y);

    /* Universal abstraction of F with respect to the top variable index. */
    Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
    if (Fm1) {
	Fm1 = Cudd_Not(Fm1);
	cuddRef(Fm1);
    } else {
	return(NULL);
    }

    Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
    if (Fn) {
	cuddRef(Fn);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	return(NULL);
    }

    Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
    if (Fv) {
	cuddRef(Fv);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	return(NULL);
    }

    Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
    if (Fvbar) {
	cuddRef(Fvbar);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	return(NULL);
    }

    /* Build i-th component of the solution. */
    w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
    if (w) {
	cuddRef(w);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	Cudd_RecursiveDeref(bdd, Fvbar);
	return(NULL);
    }

    T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
    if(T) {
	cuddRef(T);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	Cudd_RecursiveDeref(bdd, Fvbar);
	Cudd_RecursiveDeref(bdd, w);
	return(NULL);
    }

    Cudd_RecursiveDeref(bdd,Fm1);
    Cudd_RecursiveDeref(bdd,w);
    Cudd_RecursiveDeref(bdd,Fv);
    Cudd_RecursiveDeref(bdd,Fvbar);

    /* Substitute components of solution already found into solution. */
    for (j = n-1; j > i; j--) {
	w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
	if(w) {
	    cuddRef(w);
	} else {
	    Cudd_RecursiveDeref(bdd, Fn);
	    Cudd_RecursiveDeref(bdd, T);
	    return(NULL);
	}
	Cudd_RecursiveDeref(bdd,T);
	T = w;
    }
    G[i] = T;

    Cudd_Deref(Fn);

    return(Fn);

} /* end of cuddSolveEqnRecur */
Пример #3
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_bddCompose.]

  Description [Performs the recursive step of Cudd_bddCompose.
  Exploits the fact that the composition of f' with g
  produces the complement of the composition of f with g to better
  utilize the cache.  Returns the composed BDD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddCompose]

******************************************************************************/
DdNode *
cuddBddComposeRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * proj)
{
    DdNode	*F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
    unsigned int v, topf, topg, topindex;
    int		comple;

    statLine(dd);
    v = dd->perm[proj->index];
    F = Cudd_Regular(f);
    topf = cuddI(dd,F->index);

    /* Terminal case. Subsumes the test for constant f. */
    if (topf > v) return(f);

    /* We solve the problem for a regular pointer, and then complement
    ** the result if the pointer was originally complemented.
    */
    comple = Cudd_IsComplement(f);

    /* Check cache. */
    r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
    if (r != NULL) {
	return(Cudd_NotCond(r,comple));
    }

    if (topf == v) {
	/* Compose. */
	f1 = cuddT(F);
	f0 = cuddE(F);
	r = cuddBddIteRecur(dd, g, f1, f0);
	if (r == NULL) return(NULL);
    } else {
	/* Compute cofactors of f and g. Remember the index of the top
	** variable.
	*/
	G = Cudd_Regular(g);
	topg = cuddI(dd,G->index);
	if (topf > topg) {
	    topindex = G->index;
	    f1 = f0 = F;
	} else {
	    topindex = F->index;
	    f1 = cuddT(F);
	    f0 = cuddE(F);
	}
	if (topg > topf) {
	    g1 = g0 = g;
	} else {
	    g1 = cuddT(G);
	    g0 = cuddE(G);
	    if (g != G) {
		g1 = Cudd_Not(g1);
		g0 = Cudd_Not(g0);
	    }
	}
	/* Recursive step. */
	t = cuddBddComposeRecur(dd, f1, g1, proj);
	if (t == NULL) return(NULL);
	cuddRef(t);
	e = cuddBddComposeRecur(dd, f0, g0, proj);
	if (e == NULL) {
	    Cudd_IterDerefBdd(dd, t);
	    return(NULL);
	}
	cuddRef(e);

	r = cuddBddIteRecur(dd, dd->vars[topindex], t, e);
	if (r == NULL) {
	    Cudd_IterDerefBdd(dd, t);
	    Cudd_IterDerefBdd(dd, e);
	    return(NULL);
	}
	cuddRef(r);
	Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */
	Cudd_IterDerefBdd(dd, e);
	cuddDeref(r);
    }

    cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r);

    return(Cudd_NotCond(r,comple));

} /* end of cuddBddComposeRecur */