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

  Synopsis    [Implements ITE(f,g,h).]

  Description [Implements ITE(f,g,h). This procedure assumes that f is
  a 0-1 ADD.  Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddIte Cudd_addIteConstant Cudd_addApply]

******************************************************************************/
DdNode *
Cudd_addIte(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * h)
{
    DdNode *res;

    do {
	dd->reordered = 0;
	res = cuddAddIteRecur(dd,f,g,h);
    } while (dd->reordered == 1);
    return(res);

} /* end of Cudd_addIte */
Exemplo n.º 2
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addCompose.]

  Description [Performs the recursive step of Cudd_addCompose.
  Returns the composed BDD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addCompose]

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

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

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

    /* Check cache. */
    r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
    if (r != NULL) {
	return(r);
    }

    if (topf == v) {
	/* Compose. */
	f1 = cuddT(f);
	f0 = cuddE(f);
	r = cuddAddIteRecur(dd, g, f1, f0);
	if (r == NULL) return(NULL);
    } else {
	/* Compute cofactors of f and g. Remember the index of the top
	** variable.
	*/
	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);
	}
	/* Recursive step. */
	t = cuddAddComposeRecur(dd, f1, g1, proj);
	if (t == NULL) return(NULL);
	cuddRef(t);
	e = cuddAddComposeRecur(dd, f0, g0, proj);
	if (e == NULL) {
	    Cudd_RecursiveDeref(dd, t);
	    return(NULL);
	}
	cuddRef(e);

	if (t == e) {
	    r = t;
	} else {
	    r = cuddUniqueInter(dd, (int) topindex, t, e);
	    if (r == NULL) {
		Cudd_RecursiveDeref(dd, t);
		Cudd_RecursiveDeref(dd, e);
		return(NULL);
	    }
	}
	cuddDeref(t);
	cuddDeref(e);
    }

    cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r);

    return(r);

} /* end of cuddAddComposeRecur */
Exemplo n.º 3
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addNonSimCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddNonSimComposeRecur(
  DdManager * dd,
  DdNode * f,
  DdNode ** vector,
  DdNode * key,
  DdNode * cube,
  int  lastsub)
{
    DdNode *f1, *f0, *key1, *key0, *cube1, *var;
    DdNode *T,*E;
    DdNode *r;
    unsigned int top, topf, topk, topc;
    unsigned int index;
    int i;
    DdNode **vect1;
    DdNode **vect0;

    statLine(dd);
    /* If we are past the deepest substitution, return f. */
    if (cube == DD_ONE(dd) || cuddIsConstant(f)) {
	return(f);
    }

    /* If problem already solved, look up answer and return. */
    r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube);
    if (r != NULL) {
	return(r);
    }

    /* Find top variable. we just need to look at f, key, and cube,
    ** because all the varibles in the gi are in key.
    */
    topf = cuddI(dd,f->index);
    topk = cuddI(dd,key->index);
    top = ddMin(topf,topk);
    topc = cuddI(dd,cube->index);
    top = ddMin(top,topc);
    index = dd->invperm[top];

    /* Compute the cofactors. */
    if (topf == top) {
	f1 = cuddT(f);
	f0 = cuddE(f);
    } else {
	f1 = f0 = f;
    }
    if (topc == top) {
	cube1 = cuddT(cube);
	/* We want to eliminate vector[index] from key. Otherwise
	** cache performance is severely affected. Hence we
	** existentially quantify the variable with index "index" from key.
	*/
	var = Cudd_addIthVar(dd, (int) index);
	if (var == NULL) {
	    return(NULL);
	}
	cuddRef(var);
	key1 = cuddAddExistAbstractRecur(dd, key, var);
	if (key1 == NULL) {
	    Cudd_RecursiveDeref(dd,var);
	    return(NULL);
	}
	cuddRef(key1);
	Cudd_RecursiveDeref(dd,var);
	key0 = key1;
    } else {
	cube1 = cube;
	if (topk == top) {
	    key1 = cuddT(key);
	    key0 = cuddE(key);
	} else {
	    key1 = key0 = key;
	}
	cuddRef(key1);
    }

    /* Allocate two new vectors for the cofactors of vector. */
    vect1 = ALLOC(DdNode *,lastsub);
    if (vect1 == NULL) {
	dd->errorCode = CUDD_MEMORY_OUT;
	Cudd_RecursiveDeref(dd,key1);
	return(NULL);
    }
    vect0 = ALLOC(DdNode *,lastsub);
    if (vect0 == NULL) {
	dd->errorCode = CUDD_MEMORY_OUT;
	Cudd_RecursiveDeref(dd,key1);
	FREE(vect1);
	return(NULL);
    }

    /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because
    ** we do not need them.
    */
    for (i = 0; i < lastsub; i++) {
	DdNode *gi = vector[i];
	if (gi == NULL) {
	    vect1[i] = vect0[i] = NULL;
	} else if (gi->index == index) {
	    vect1[i] = cuddT(gi);
	    vect0[i] = cuddE(gi);
	} else {
	    vect1[i] = vect0[i] = gi;
	}
    }
    vect1[index] = vect0[index] = NULL;

    /* Recur on children. */
    T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub);
    FREE(vect1);
    if (T == NULL) {
	Cudd_RecursiveDeref(dd,key1);
	FREE(vect0);
	return(NULL);
    }
    cuddRef(T);
    E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
    FREE(vect0);
    if (E == NULL) {
	Cudd_RecursiveDeref(dd,key1);
	Cudd_RecursiveDeref(dd,T);
	return(NULL);
    }
    cuddRef(E);
    Cudd_RecursiveDeref(dd,key1);

    /* Retrieve the 0-1 ADD for the current top variable from vector,
    ** and call cuddAddIteRecur with the T and E we just created.
    */
    r = cuddAddIteRecur(dd,vector[index],T,E);
    if (r == NULL) {
	Cudd_RecursiveDeref(dd,T);
	Cudd_RecursiveDeref(dd,E);
	return(NULL);
    }
    cuddRef(r);
    Cudd_RecursiveDeref(dd,T);
    Cudd_RecursiveDeref(dd,E);
    cuddDeref(r);

    /* Store answer to trim recursion. */
    cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r);

    return(r);

} /* end of cuddAddNonSimComposeRecur */
Exemplo n.º 4
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addVectorCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddVectorComposeRecur(
  DdManager * dd /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * f /* ADD in which to compose */,
  DdNode ** vector /* functions to substitute */,
  int  deepest /* depth of deepest substitution */)
{
    DdNode	*T,*E;
    DdNode	*res;

    statLine(dd);
    /* If we are past the deepest substitution, return f. */
    if (cuddI(dd,f->index) > deepest) {
	return(f);
    }

    if ((res = cuddHashTableLookup1(table,f)) != NULL) {
#ifdef DD_DEBUG
	addVectorComposeHits++;
#endif
	return(res);
    }

    /* Split and recur on children of this node. */
    T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest);
    if (T == NULL)  return(NULL);
    cuddRef(T);
    E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest);
    if (E == NULL) {
	Cudd_RecursiveDeref(dd, T);
	return(NULL);
    }
    cuddRef(E);

    /* Retrieve the 0-1 ADD for the current top variable and call
    ** cuddAddIteRecur with the T and E we just created.
    */
    res = cuddAddIteRecur(dd,vector[f->index],T,E);
    if (res == NULL) {
	Cudd_RecursiveDeref(dd, T);
	Cudd_RecursiveDeref(dd, E);
	return(NULL);
    }
    cuddRef(res);
    Cudd_RecursiveDeref(dd, T);
    Cudd_RecursiveDeref(dd, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again
    */
    if (f->ref != 1) {
	ptrint fanout = (ptrint) f->ref;
	cuddSatDec(fanout);
	if (!cuddHashTableInsert1(table,f,res,fanout)) {
	    Cudd_RecursiveDeref(dd, res);
	    return(NULL);
	}
    }
    cuddDeref(res);
    return(res);

} /* end of cuddAddVectorComposeRecur */
Exemplo n.º 5
0
/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_addPermute.]

  Description [ Recursively puts the ADD in the order given in the
  array permut. Checks for trivial cases to terminate recursion, then
  splits on the children of this node.  Once the solutions for the
  children are obtained, it puts into the current position the node
  from the rest of the ADD that should be here. Then returns this ADD.
  The key here is that the node being visited is NOT put in its proper
  place by this instance, but rather is switched when its proper
  position is reached in the recursion tree.<p>
  The DdNode * that is returned is the same ADD as passed in as node,
  but in the new order.]

  SideEffects [None]

  SeeAlso     [Cudd_addPermute cuddBddPermuteRecur]

******************************************************************************/
static DdNode *
cuddAddPermuteRecur(
  DdManager * manager /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * node /* ADD to be reordered */,
  int * permut /* permutation array */)
{
    DdNode	*T,*E;
    DdNode	*res,*var;
    int		index;
    
    statLine(manager);
    /* Check for terminal case of constant node. */
    if (cuddIsConstant(node)) {
	return(node);
    }

    /* If problem already solved, look up answer and return. */
    if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
#ifdef DD_DEBUG
	addPermuteRecurHits++;
#endif
	return(res);
    }

    /* Split and recur on children of this node. */
    T = cuddAddPermuteRecur(manager,table,cuddT(node),permut);
    if (T == NULL) return(NULL);
    cuddRef(T);
    E = cuddAddPermuteRecur(manager,table,cuddE(node),permut);
    if (E == NULL) {
	Cudd_RecursiveDeref(manager, T);
	return(NULL);
    }
    cuddRef(E);

    /* Move variable that should be in this position to this position
    ** by creating a single var ADD for that variable, and calling
    ** cuddAddIteRecur with the T and E we just created.
    */
    index = permut[node->index];
    var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager));
    if (var == NULL) return(NULL);
    cuddRef(var);
    res = cuddAddIteRecur(manager,var,T,E);
    if (res == NULL) {
	Cudd_RecursiveDeref(manager,var);
	Cudd_RecursiveDeref(manager, T);
	Cudd_RecursiveDeref(manager, E);
	return(NULL);
    }
    cuddRef(res);
    Cudd_RecursiveDeref(manager,var);
    Cudd_RecursiveDeref(manager, T);
    Cudd_RecursiveDeref(manager, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again.
    */
    if (node->ref != 1) {
	ptrint fanout = (ptrint) node->ref;
	cuddSatDec(fanout);
	if (!cuddHashTableInsert1(table,node,res,fanout)) {
	    Cudd_RecursiveDeref(manager, res);
	    return(NULL);
	}
    }
    cuddDeref(res);
    return(res);

} /* end of cuddAddPermuteRecur */
Exemplo n.º 6
0
/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_addIte(f,g,h).]

  Description [Implements the recursive step of Cudd_addIte(f,g,h).
  Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addIte]

******************************************************************************/
DdNode *
cuddAddIteRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * h)
{
    DdNode *one,*zero;
    DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
    unsigned int topf,topg,toph,v;
    int index;

    statLine(dd);
    /* Trivial cases. */

    /* One variable cases. */
    if (f == (one = DD_ONE(dd))) {	/* ITE(1,G,H) = G */
        return(g);
    }
    if (f == (zero = DD_ZERO(dd))) {	/* ITE(0,G,H) = H */
        return(h);
    }

    /* From now on, f is known to not be a constant. */
    addVarToConst(f,&g,&h,one,zero);

    /* Check remaining one variable cases. */
    if (g == h) {			/* ITE(F,G,G) = G */
        return(g);
    }

    if (g == one) {			/* ITE(F,1,0) = F */
        if (h == zero) return(f);
    }

    topf = cuddI(dd,f->index);
    topg = cuddI(dd,g->index);
    toph = cuddI(dd,h->index);
    v = ddMin(topg,toph);

    /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */
    if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
	r = cuddUniqueInter(dd,(int)f->index,g,h);
	return(r);
    }
    if (topf < v && cuddT(f) == zero && cuddE(f) == one) {
	r = cuddUniqueInter(dd,(int)f->index,h,g);
	return(r);
    }

    /* Check cache. */
    r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h);
    if (r != NULL) {
        return(r);
    }

    /* Compute cofactors. */
    if (topf <= v) {
	v = ddMin(topf,v);	/* v = top_var(F,G,H) */
	index = f->index;
        Fv = cuddT(f); Fnv = cuddE(f);
    } else {
        Fv = Fnv = f;
    }
    if (topg == v) {
	index = g->index;
        Gv = cuddT(g); Gnv = cuddE(g);
    } else {
        Gv = Gnv = g;
    }
    if (toph == v) {
	index = h->index;
        Hv = cuddT(h); Hnv = cuddE(h);
    } else {
        Hv = Hnv = h;
    }
    
    /* Recursive step. */
    t = cuddAddIteRecur(dd,Fv,Gv,Hv);
    if (t == NULL) return(NULL);
    cuddRef(t);

    e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
    if (e == NULL) {
	Cudd_RecursiveDeref(dd,t);
	return(NULL);
    }
    cuddRef(e);

    r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
    if (r == NULL) {
	Cudd_RecursiveDeref(dd,t);
	Cudd_RecursiveDeref(dd,e);
	return(NULL);
    }
    cuddDeref(t);
    cuddDeref(e);

    cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r);

    return(r);

} /* end of cuddAddIteRecur */