/**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 */
Beispiel #2
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 */