Пример #1
0
double CountMintermFractionRecurr(DdNode* node, NodeTable& table) {
    double frac = std::numeric_limits<double>::quiet_NaN();

    auto iter = table.find(node);

    if(iter != table.end()) {
        //Use sub-problem from table
        frac = iter->second;

    } else {
        if(Cudd_IsConstant(node)) {
            assert(Cudd_V(node) == 1);

            //Base case (leaf node)
            if(Cudd_IsComplement(node)) {
                //At the false node
                frac = 0.;
            } else {
                assert(!Cudd_IsComplement(node));
                //At the true node
                frac = 1.;
            }
        } else {
            //Recursive case (internal node)
            assert(!Cudd_IsConstant(node));

            DdNode* then_node = (Cudd_IsComplement(node)) ? Cudd_Not(Cudd_T(node)) : Cudd_T(node);
            double frac_then = CountMintermFractionRecurr(then_node, table);

            DdNode* else_node = (Cudd_IsComplement(node)) ? Cudd_Not(Cudd_E(node)) : Cudd_E(node);
            double frac_else = CountMintermFractionRecurr(else_node, table);

            // Using identity:
            //   |f| = (|f0| + |f1|) / 2
            //
            // where |f| is the number of minterms
            // and f0 and f1 are the co-factors of f
            frac = (frac_then + frac_else) / 2.;

        }

        //Store sub-problem answer in table
        auto result = table.insert(std::make_pair(node, frac)); 
        assert(result.second); //Was inserted
    }
    return frac;
}
Пример #2
0
void UpdateForward(DdNode *node, int nex) {
  int index, position, mVarIndex;
  DdNode *T, *E, *nodereg;
  variable v;
  double *value_p, *value_p_T, *value_p_F, p;

  if (Cudd_IsConstant(node)) {
    return;
  } else {
    index = Cudd_NodeReadIndex(node);
    mVarIndex = bVar2mVar_ex[nex][index];
    v = vars_ex[nex][mVarIndex];
    p = probs_ex[nex][index];
    nodereg = Cudd_Regular(node);
    value_p = get_value(nodesF, nodereg);
    if (value_p == NULL) {
      printf("Error\n");
      return;
    } else {
      T = Cudd_T(node);
      E = Cudd_E(node);
      if (!Cudd_IsConstant(T)) {
        value_p_T = get_value(nodesF, T);
        if (value_p_T != NULL) {
          *value_p_T = *value_p_T + *value_p * p;
        } else {
          add_or_replace_node(nodesF, Cudd_Regular(T), *value_p * p);
          index = Cudd_NodeReadIndex(T);
          position = Cudd_ReadPerm(mgr_ex[nex], index);
          nodesToVisit[position] = (DdNode **)realloc(
              nodesToVisit[position],
              (NnodesToVisit[position] + 1) * sizeof(DdNode *));
          nodesToVisit[position][NnodesToVisit[position]] = T;
          NnodesToVisit[position] = NnodesToVisit[position] + 1;
        }
      }
      if (!Cudd_IsConstant(E)) {
        value_p_F = get_value(nodesF, Cudd_Regular(E));

        if (value_p_F != NULL) {
          *value_p_F = *value_p_F + *value_p * (1 - p);
        } else {
          add_or_replace_node(nodesF, Cudd_Regular(E), *value_p * (1 - p));
          index = Cudd_NodeReadIndex(E);
          position = Cudd_ReadPerm(mgr_ex[nex], index);
          nodesToVisit[position] = (DdNode **)realloc(
              nodesToVisit[position],
              (NnodesToVisit[position] + 1) * sizeof(DdNode *));
          nodesToVisit[position][NnodesToVisit[position]] = E;
          NnodesToVisit[position] = NnodesToVisit[position] + 1;
        }
      }
      return;
    }
  }
}
Пример #3
0
double Prob(DdNode *node )
/* compute the probability of the expression rooted at node
nodes is used to store nodes for which the probability has alread been computed
so that it is not recomputed
 */
{
    int comp;
    int index;
    double res,resT,resF;
    double p;
    double * value_p;
    DdNode **key,*T,*F,*nodereg;
    double *rp;

    comp=Cudd_IsComplement(node);
    if (Cudd_IsConstant(node))
    {
        if (comp)
            return 0.0;
        else
            return 1.0;
    }
    else
    {
        nodereg=Cudd_Regular(node);
        value_p=g_hash_table_lookup(nodes,&node);
        if (value_p!=NULL)
        {
            if (comp)
                return 1-*value_p;
            else
                return *value_p;
        }
        else
        {
            index=Cudd_NodeReadIndex(node);
            p=probs[index];
            T = Cudd_T(node);
            F = Cudd_E(node);
            resT=Prob(T);
            resF=Prob(F);
            res=p*resT+(1-p)*resF;
            key=(DdNode **)malloc(sizeof(DdNode *));
            *key=nodereg;
            rp=(double *)malloc(sizeof(double));
            *rp=res;
            g_hash_table_insert(nodes, key, rp);
            if (comp)
                return 1-res;
            else
                return res;
        }
    }
}
Пример #4
0
uint Synth::walk(DdNode *a_dd) {
    /**
    Walk given DdNode node (recursively).
    If a given node requires intermediate AND gates for its representation, the function adds them.
        Literal representing given input node is `not` added to the spec.

    :returns: literal representing input node
    **/

    // caching
    static hmap<DdNode*, uint> cache;
    {
        auto cached_lit = cache.find(Cudd_Regular(a_dd));
        if (cached_lit != cache.end())
            return Cudd_IsComplement(a_dd) ? NEGATED(cached_lit->second) : cached_lit->second;
    }
    // end of caching

    if (Cudd_IsConstant(a_dd))
        return (uint) (a_dd == cudd.bddOne().getNode());  // in aiger: 0 is False and 1 is True

    // get an index of the variable
    uint a_lit = aiger_by_cudd[Cudd_NodeReadIndex(a_dd)];

    DdNode *t_bdd = Cudd_T(a_dd);
    DdNode *e_bdd = Cudd_E(a_dd);

    uint t_lit = walk(t_bdd);
    uint e_lit = walk(e_bdd);

    // ite(a_bdd, then_bdd, else_bdd)
    // = a*then + !a*else
    // = !(!(a*then) * !(!a*else))
    // -> in general case we need 3 more ANDs

    uint a_t_lit = get_optimized_and_lit(a_lit, t_lit);

    uint na_e_lit = get_optimized_and_lit(NEGATED(a_lit), e_lit);

    uint n_a_t_lit = NEGATED(a_t_lit);
    uint n_na_e_lit = NEGATED(na_e_lit);

    uint and_lit = get_optimized_and_lit(n_a_t_lit, n_na_e_lit);

    uint res = NEGATED(and_lit);

    cache[Cudd_Regular(a_dd)] = res;

    if (Cudd_IsComplement(a_dd))
        res = NEGATED(res);

    return res;
}
Пример #5
0
double Prob(DdNode *node, int comp_par)
/* compute the probability of the expression rooted at node.
table is used to store nodeB for which the probability has alread been computed
so that it is not recomputed
 */
{
  int index, mVarIndex, comp, pos;
  variable v;
  double res;
  double p, pt, pf, BChild0, BChild1;
  double *value_p;
  DdNode *nodekey, *T, *F;

  comp = Cudd_IsComplement(node);
  comp = (comp && !comp_par) || (!comp && comp_par);
  if (Cudd_IsConstant(node)) {
    if (comp)
      return 0.0;
    else
      return 1.0;
  } else {
    nodekey = Cudd_Regular(node);
    value_p = get_value(table, nodekey);
    if (value_p != NULL)
      return *value_p;
    else {
      index = Cudd_NodeReadIndex(node); // Returns the index of the node. The
                                        // node pointer can be either regular or
                                        // complemented.
      // The index field holds the name of the variable that labels the node.
      // The index of a variable is a permanent attribute that reflects the
      // order of creation.
      p = probs_ex[ex][index];
      T = Cudd_T(node);
      F = Cudd_E(node);
      pf = Prob(F, comp);
      pt = Prob(T, comp);
      BChild0 = pf * (1 - p);
      BChild1 = pt * p;
      mVarIndex = bVar2mVar_ex[ex][index];
      v = vars_ex[ex][mVarIndex];
      pos = index - v.firstBoolVar;
      res = BChild0 + BChild1;
      add_node(table, nodekey, res);
      return res;
    }
  }
}
Пример #6
0
double ProbBool(extmanager MyManager, DdNode *node, int bits, int nBit,int posBVar,variable v, int comp)
/* explores a group of binary variables making up the multivalued variable v */
{
  DdNode *T,*F;
  double p,res;
  double * probs;
  int index;
  probs=v.probabilities;
  if (nBit==0)
  {
    if (bits>=v.nVal)
	{
	return 0.0;
	}
    else
    {
      p=probs[bits];
      res=p*Prob(MyManager,node,comp);
      return res;
    }
  }
  else
  {
    index=Cudd_NodeReadIndex(node);
     if (correctPosition(index,v,posBVar))
    {
      T = Cudd_T(node);
      F = Cudd_E(node);
      bits=bits<<1;
      res=ProbBool(MyManager,T,bits+1,nBit-1,posBVar+1,v,comp);
      comp=(!comp && Cudd_IsComplement(F)) || (comp && !Cudd_IsComplement(F));
res=res+ 
        ProbBool(MyManager,F,bits,nBit-1,posBVar+1,v,comp);
      return res;
    }
    else
    {
      bits=bits<<1;
      res=ProbBool(MyManager,node,bits+1,nBit-1,posBVar+1,v,comp);
      res=res+ 
        ProbBool(MyManager,node,bits,nBit-1,posBVar+1,v,comp);
return res;
    }
  }
}
Пример #7
0
/**Function********************************************************************

  Synopsis [Performs the recursive step of Cudd_bddIsop.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_bddIsop]

******************************************************************************/
DdNode	*
cuddBddIsop(
  DdManager * dd,
  DdNode * L,
  DdNode * U)
{
    DdNode	*one = DD_ONE(dd);
    DdNode	*zero = Cudd_Not(one);
    int		v, top_l, top_u;
    DdNode	*Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
    DdNode	*Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
    DdNode	*Isub0, *Isub1, *Id;
    DdNode	*x;
    DdNode	*term0, *term1, *sum;
    DdNode	*Lv, *Uv, *Lnv, *Unv;
    DdNode	*r;
    int		index;

    statLine(dd);
    if (L == zero)
    	return(zero);
    if (U == one)
    	return(one);

    /* Check cache */
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
    if (r)
    	return(r);

    top_l = dd->perm[Cudd_Regular(L)->index];
    top_u = dd->perm[Cudd_Regular(U)->index];
    v = ddMin(top_l, top_u);

    /* Compute cofactors */
    if (top_l == v) {
	index = Cudd_Regular(L)->index;
    	Lv = Cudd_T(L);
    	Lnv = Cudd_E(L);
    	if (Cudd_IsComplement(L)) {
    	    Lv = Cudd_Not(Lv);
    	    Lnv = Cudd_Not(Lnv);
    	}
    }
    else {
	index = Cudd_Regular(U)->index;
        Lv = Lnv = L;
    }

    if (top_u == v) {
    	Uv = Cudd_T(U);
    	Unv = Cudd_E(U);
    	if (Cudd_IsComplement(U)) {
    	    Uv = Cudd_Not(Uv);
    	    Unv = Cudd_Not(Unv);
    	}
    }
    else {
        Uv = Unv = U;
    }

    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
    if (Lsub0 == NULL)
	return(NULL);
    Cudd_Ref(Lsub0);
    Usub0 = Unv;
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
    if (Lsub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	return(NULL);
    }
    Cudd_Ref(Lsub1);
    Usub1 = Uv;

    Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
    if (Isub0 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	return(NULL);
    }
    Cudd_Ref(Isub0);
    Isub1 = cuddBddIsop(dd, Lsub1, Usub1);
    if (Isub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	Cudd_RecursiveDeref(dd, Isub0);
	return(NULL);
    }
    Cudd_Ref(Isub1);
    Cudd_RecursiveDeref(dd, Lsub0);
    Cudd_RecursiveDeref(dd, Lsub1);

    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
    if (Lsuper0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	return(NULL);
    }
    Cudd_Ref(Lsuper0);
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
    if (Lsuper1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	return(NULL);
    }
    Cudd_Ref(Lsuper1);
    Usuper0 = Unv;
    Usuper1 = Uv;

    /* Ld = Lsuper0 + Lsuper1 */
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
    Ld = Cudd_NotCond(Ld, Ld != NULL);
    if (Ld == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	return(NULL);
    }
    Cudd_Ref(Ld);
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
    if (Ud == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	Cudd_RecursiveDeref(dd, Ld);
	return(NULL);
    }
    Cudd_Ref(Ud);
    Cudd_RecursiveDeref(dd, Lsuper0);
    Cudd_RecursiveDeref(dd, Lsuper1);

    Id = cuddBddIsop(dd, Ld, Ud);
    if (Id == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Ld);
	Cudd_RecursiveDeref(dd, Ud);
	return(NULL);
    }
    Cudd_Ref(Id);
    Cudd_RecursiveDeref(dd, Ld);
    Cudd_RecursiveDeref(dd, Ud);

    x = cuddUniqueInter(dd, index, one, zero);
    if (x == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	return(NULL);
    }
    Cudd_Ref(x);
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
    if (term0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, x);
	return(NULL);
    }
    Cudd_Ref(term0);
    Cudd_RecursiveDeref(dd, Isub0);
    term1 = cuddBddAndRecur(dd, x, Isub1);
    if (term1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, x);
	Cudd_RecursiveDeref(dd, term0);
	return(NULL);
    }
    Cudd_Ref(term1);
    Cudd_RecursiveDeref(dd, x);
    Cudd_RecursiveDeref(dd, Isub1);
    /* sum = term0 + term1 */
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
    sum = Cudd_NotCond(sum, sum != NULL);
    if (sum == NULL) {
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, term0);
	Cudd_RecursiveDeref(dd, term1);
	return(NULL);
    }
    Cudd_Ref(sum);
    Cudd_RecursiveDeref(dd, term0);
    Cudd_RecursiveDeref(dd, term1);
    /* r = sum + Id */
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
    r = Cudd_NotCond(r, r != NULL);
    if (r == NULL) {
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, sum);
	return(NULL);
    }
    Cudd_Ref(r);
    Cudd_RecursiveDeref(dd, sum);
    Cudd_RecursiveDeref(dd, Id);

    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);

    Cudd_Deref(r);
    return(r);

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

  Synopsis [Performs the recursive step of Cudd_zddIsop.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddIsop]

******************************************************************************/
DdNode	*
cuddZddIsop(
  DdManager * dd,
  DdNode * L,
  DdNode * U,
  DdNode ** zdd_I)
{
    DdNode	*one = DD_ONE(dd);
    DdNode	*zero = Cudd_Not(one);
    DdNode	*zdd_one = DD_ONE(dd);
    DdNode	*zdd_zero = DD_ZERO(dd);
    int		v, top_l, top_u;
    DdNode	*Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
    DdNode	*Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
    DdNode	*Isub0, *Isub1, *Id;
    DdNode	*zdd_Isub0, *zdd_Isub1, *zdd_Id;
    DdNode	*x;
    DdNode	*term0, *term1, *sum;
    DdNode	*Lv, *Uv, *Lnv, *Unv;
    DdNode	*r, *y, *z;
    int		index;
    DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);

    statLine(dd);
    if (L == zero) {
	*zdd_I = zdd_zero;
    	return(zero);
    }
    if (U == one) {
	*zdd_I = zdd_one;
    	return(one);
    }

    if (U == zero || L == one) {
	printf("*** ERROR : illegal condition for ISOP (U < L).\n");
	exit(1);
    }

    /* Check the cache. We store two results for each recursive call.
    ** One is the BDD, and the other is the ZDD. Both are needed.
    ** Hence we need a double hit in the cache to terminate the
    ** recursion. Clearly, collisions may evict only one of the two
    ** results. */
    cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) cuddZddIsop;
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
    if (r) {
	*zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
	if (*zdd_I)
	    return(r);
	else {
	    /* The BDD result may have been dead. In that case
	    ** cuddCacheLookup2 would have called cuddReclaim,
	    ** whose effects we now have to undo. */
	    cuddRef(r);
	    Cudd_RecursiveDeref(dd, r);
	}
    }

    top_l = dd->perm[Cudd_Regular(L)->index];
    top_u = dd->perm[Cudd_Regular(U)->index];
    v = ddMin(top_l, top_u);

    /* Compute cofactors. */
    if (top_l == v) {
	index = Cudd_Regular(L)->index;
    	Lv = Cudd_T(L);
    	Lnv = Cudd_E(L);
    	if (Cudd_IsComplement(L)) {
    	    Lv = Cudd_Not(Lv);
    	    Lnv = Cudd_Not(Lnv);
    	}
    }
    else {
	index = Cudd_Regular(U)->index;
        Lv = Lnv = L;
    }

    if (top_u == v) {
    	Uv = Cudd_T(U);
    	Unv = Cudd_E(U);
    	if (Cudd_IsComplement(U)) {
    	    Uv = Cudd_Not(Uv);
    	    Unv = Cudd_Not(Unv);
    	}
    }
    else {
        Uv = Unv = U;
    }

    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
    if (Lsub0 == NULL)
	return(NULL);
    Cudd_Ref(Lsub0);
    Usub0 = Unv;
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
    if (Lsub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	return(NULL);
    }
    Cudd_Ref(Lsub1);
    Usub1 = Uv;

    Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
    if (Isub0 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
	(Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Isub0);
    Cudd_Ref(zdd_Isub0);
    Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1);
    if (Isub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
	(Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Isub1);
    Cudd_Ref(zdd_Isub1);
    Cudd_RecursiveDeref(dd, Lsub0);
    Cudd_RecursiveDeref(dd, Lsub1);

    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
    if (Lsuper0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	return(NULL);
    }
    Cudd_Ref(Lsuper0);
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
    if (Lsuper1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	return(NULL);
    }
    Cudd_Ref(Lsuper1);
    Usuper0 = Unv;
    Usuper1 = Uv;

    /* Ld = Lsuper0 + Lsuper1 */
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
    if (Ld == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	return(NULL);
    }
    Ld = Cudd_Not(Ld);
    Cudd_Ref(Ld);
    /* Ud = Usuper0 * Usuper1 */
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
    if (Ud == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	Cudd_RecursiveDeref(dd, Ld);
	return(NULL);
    }
    Cudd_Ref(Ud);
    Cudd_RecursiveDeref(dd, Lsuper0);
    Cudd_RecursiveDeref(dd, Lsuper1);

    Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id);
    if (Id == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Ld);
	Cudd_RecursiveDeref(dd, Ud);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Id))) &&
	(Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Id);
    Cudd_Ref(zdd_Id);
    Cudd_RecursiveDeref(dd, Ld);
    Cudd_RecursiveDeref(dd, Ud);

    x = cuddUniqueInter(dd, index, one, zero);
    if (x == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	return(NULL);
    }
    Cudd_Ref(x);
    /* term0 = x * Isub0 */
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
    if (term0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, x);
	return(NULL);
    }
    Cudd_Ref(term0);
    Cudd_RecursiveDeref(dd, Isub0);
    /* term1 = x * Isub1 */
    term1 = cuddBddAndRecur(dd, x, Isub1);
    if (term1 == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, x);
	Cudd_RecursiveDeref(dd, term0);
	return(NULL);
    }
    Cudd_Ref(term1);
    Cudd_RecursiveDeref(dd, x);
    Cudd_RecursiveDeref(dd, Isub1);
    /* sum = term0 + term1 */
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
    if (sum == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, term0);
	Cudd_RecursiveDeref(dd, term1);
	return(NULL);
    }
    sum = Cudd_Not(sum);
    Cudd_Ref(sum);
    Cudd_RecursiveDeref(dd, term0);
    Cudd_RecursiveDeref(dd, term1);
    /* r = sum + Id */
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
    r = Cudd_NotCond(r, r != NULL);
    if (r == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, sum);
	return(NULL);
    }
    Cudd_Ref(r);
    Cudd_RecursiveDeref(dd, sum);
    Cudd_RecursiveDeref(dd, Id);

    if (zdd_Isub0 != zdd_zero) {
	z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id);
	if (z == NULL) {
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	    Cudd_RecursiveDerefZdd(dd, zdd_Id);
	    Cudd_RecursiveDeref(dd, r);
	    return(NULL);
	}
    }
    else {
	z = zdd_Id;
    }
    Cudd_Ref(z);
    if (zdd_Isub1 != zdd_zero) {
	y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z);
	if (y == NULL) {
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	    Cudd_RecursiveDerefZdd(dd, zdd_Id);
	    Cudd_RecursiveDeref(dd, r);
	    Cudd_RecursiveDerefZdd(dd, z);
	    return(NULL);
	}
    }
    else
	y = z;
    Cudd_Ref(y);

    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
    Cudd_RecursiveDerefZdd(dd, zdd_Id);
    Cudd_RecursiveDerefZdd(dd, z);

    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
    cuddCacheInsert2(dd, cacheOp, L, U, y);

    Cudd_Deref(r);
    Cudd_Deref(y);
    *zdd_I = y;
    /*
    if (Cudd_Regular(r)->index != y->index / 2) {
	printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
    }
    */
    return(r);

} /* end of cuddZddIsop */
Пример #9
0
double ProbPath(DdNode *node, int comp_par, int nex) {
  int index, mVarIndex, comp, pos, position, boolVarIndex;
  variable v;
  double res;
  double value, p, pt, pf, BChild0, BChild1, e0, e1;
  double *value_p, **eta_rule;
  DdNode *nodekey, *T, *F;

  comp = Cudd_IsComplement(node);
  comp = (comp && !comp_par) || (!comp && comp_par);
  if (Cudd_IsConstant(node)) {
    value = Cudd_V(node);
    if (comp) {
      return 0.0;
    } else {
      return 1.0;
    }
  } else {
    nodekey = Cudd_Regular(node);
    value_p = get_value(nodesB, nodekey);
    if (value_p != NULL) {
      return *value_p;
    } else {
      index = Cudd_NodeReadIndex(node);
      p = probs_ex[nex][index];
      T = Cudd_T(node);
      F = Cudd_E(node);
      pf = ProbPath(F, comp, nex);
      pt = ProbPath(T, comp, nex);
      BChild0 = pf * (1 - p);
      BChild1 = pt * p;
      value_p = get_value(nodesF, nodekey);
      e0 = (*value_p) * BChild0;
      e1 = (*value_p) * BChild1;
      mVarIndex = bVar2mVar_ex[nex][index];
      v = vars_ex[nex][mVarIndex];
      pos = index - v.firstBoolVar;
      eta_rule = eta_temp[v.nRule];
      eta_rule[pos][0] = eta_rule[pos][0] + e0;
      eta_rule[pos][1] = eta_rule[pos][1] + e1;
      res = BChild0 + BChild1;
      add_node(nodesB, nodekey, res);
      position = Cudd_ReadPerm(mgr_ex[nex], index);
      position = position + 1;
      boolVarIndex = Cudd_ReadInvPerm(
          mgr_ex[nex], position); // Returns the index of the variable currently
                                  // in the i-th position of the order.
      if (position < boolVars_ex[nex]) {
        sigma[position] = sigma[position] + e0 + e1;
      }
      if (!Cudd_IsConstant(T)) {
        index = Cudd_NodeReadIndex(T);
        position = Cudd_ReadPerm(mgr_ex[nex], index);
        sigma[position] = sigma[position] - e1;
      }

      if (!Cudd_IsConstant(F)) {
        index = Cudd_NodeReadIndex(F);
        position = Cudd_ReadPerm(mgr_ex[nex], index);
        sigma[position] = sigma[position] - e0;
      }

      return res;
    }
  }
}
Пример #10
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cuddaux_addConstrain.]

  Description [Performs the recursive step of Cuddaux_addConstrain.
  Returns a pointer to the result if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cuddaux_addConstrain]

******************************************************************************/
DdNode *
cuddauxAddConstrainRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * c)
{
  DdNode       *Fv, *Fnv, *Cv, *Cnv, *t, *e, *res;
  DdNode	 *one, *zero;
  unsigned int topf, topc;
  int		 index;
  
  one = DD_ONE(dd);
  zero = Cudd_Not(one);
  
  /* Trivial cases. */
  if (c == one)		return(f);
  if (c == zero){
    fprintf(stderr,"CuddauxAddConstrainRecur: warning: false careset\n");
    return(DD_BACKGROUND(dd));
  }
  if (Cudd_IsConstant(f))	return(f);
  
  /* Now f and c are non-constant. */
  
  /* Check the cache. */
  res = cuddCacheLookup2(dd, Cuddaux_addConstrain, f, c);
  if (res != NULL) {
    return(res);
  }
  
  /* Recursive step. */
  topf = dd->perm[f->index];
  topc = dd->perm[Cudd_Regular(c)->index];
  if (topf <= topc) {
    index = f->index;
    Fv = cuddT(f); Fnv = cuddE(f);
  } else {
    index = Cudd_Regular(c)->index;
    Fv = Fnv = f;
  }
  if (topc <= topf) {
    Cv = Cudd_T(c); Cnv = Cudd_E(c);
    if (Cudd_IsComplement(c)) {
      Cv = Cudd_Not(Cv); Cnv = Cudd_Not(Cnv);
    }
  } else {
    Cv = Cnv = c;
  }
  
  if (!Cudd_IsConstant(Cv)) {
    t = cuddauxAddConstrainRecur(dd, Fv, Cv);
    if (t == NULL)
      return(NULL);
  } 
  else if (Cv == one) {
    t = Fv;
  } 
  else {		/* Cv == zero: return Fnv @ Cnv */
    if (Cnv == one) {
      res = Fnv;
    } 
    else {
      res = cuddauxAddConstrainRecur(dd, Fnv, Cnv);
      if (res == NULL)
	return(NULL);
    }
    return(res);
  }
  cuddRef(t);
  
  if (!Cudd_IsConstant(Cnv)) {
    e = cuddauxAddConstrainRecur(dd, Fnv, Cnv);
    if (e == NULL) {
      Cudd_RecursiveDeref(dd, t);
      return(NULL);
    }
  } 
  else if (Cnv == one) {
    e = Fnv;
  } 
  else {		/* Cnv == zero: return Fv @ Cv previously computed */
    cuddDeref(t);
    return(t);
  }
  cuddRef(e);
  
  res = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
  if (res == NULL) {
    Cudd_RecursiveDeref(dd, e);
    Cudd_RecursiveDeref(dd, t);
    return(NULL);
  }
  cuddDeref(t);
  cuddDeref(e);
  
  cuddCacheInsert2(dd, Cuddaux_addConstrain, f, c, res);
  return(res);
  
} /* end of cuddauxAddConstrainRecur */
Пример #11
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cuddaux_addRestrict.]

  Description [Performs the recursive step of Cuddaux_addRestrict.
  Returns the restricted ADD if successful; otherwise NULL.]

  SideEffects [None]

  SeeAlso     [Cudd_addRestrict]

******************************************************************************/
DdNode *
cuddauxAddRestrictRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * c)
{
  DdNode	 *Fv, *Fnv, *Cv, *Cnv, *t, *e, *res, *one, *zero;
  unsigned int topf, topc;
  int		 index;

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

  /* Trivial cases */
  if (c == one)		return(f);
  if (c == zero){
    fprintf(stderr,"CuddauxAddRestrictRecur: warning: false careset\n");
    return(DD_BACKGROUND(dd));
  }
  if (Cudd_IsConstant(f)) return(f);

  /* Now f and c are non-constant. */

  /* Check the cache. */
  res = cuddCacheLookup2(dd, Cuddaux_addRestrict, f, c);
  if (res != NULL) {
    return(res);
  }

  topf = dd->perm[f->index];
  topc = dd->perm[Cudd_Regular(c)->index];

  if (topc < topf) {	/* abstract top variable from c */
    DdNode *d, *s1, *s2;

    /* Take the OR by applying DeMorgan. */
    /* Find complements of cofactors of c. */
    if (Cudd_IsComplement(c)) {
      s1 = cuddT(Cudd_Regular(c));
      s2 = cuddE(Cudd_Regular(c));
    } else {
      s1 = Cudd_Not(cuddT(c));
      s2 = Cudd_Not(cuddE(c));
    }
    /* Take the AND and negate */
    d = cuddBddAndRecur(dd, s1, s2);
    if (d == NULL) return(NULL);
    d = Cudd_Not(d);
    cuddRef(d);

    res = cuddauxAddRestrictRecur(dd, f, d);
    if (res == NULL) {
      Cudd_IterDerefBdd(dd, d);
      return(NULL);
    }
    cuddRef(res);
    Cudd_IterDerefBdd(dd, d);
    cuddDeref(res);
    cuddCacheInsert2(dd, Cuddaux_addRestrict, f, c, res);
    return(res);
  }

  /* Recursive step. Here topf <= topc. */
  index = f->index;
  Fv = cuddT(f); Fnv = cuddE(f);
  if (topc == topf) {
    Cv = Cudd_T(c); Cnv = Cudd_E(c);
    if (Cudd_IsComplement(c)) {
      Cv = Cudd_Not(Cv); Cnv = Cudd_Not(Cnv);
    }
  } else {
    Cv = Cnv = c;
  }

  if (!Cudd_IsConstant(Cv)) {
    t = cuddauxAddRestrictRecur(dd, Fv, Cv);
    if (t == NULL) return(NULL);
  } 
  else if (Cv == one) {
    t = Fv;
  } 
  else {		/* Cv == zero: return(Fnv @ Cnv) */
    if (Cnv == one) {
      res = Fnv;
    } 
    else {
      res = cuddauxAddRestrictRecur(dd, Fnv, Cnv);
      if (res == NULL) return(NULL);
    }
    return(res);
  }
  cuddRef(t);

  if (!Cudd_IsConstant(Cnv)) {
    e = cuddauxAddRestrictRecur(dd, Fnv, Cnv);
    if (e == NULL) {
      Cudd_RecursiveDeref(dd, t);
      return(NULL);
    }
  } else if (Cnv == one) {
    e = Fnv;
  } else {		/* Cnv == zero: return (Fv @ Cv) previously computed */
    cuddDeref(t);
    return(t);
  }
  cuddRef(e);

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

  cuddCacheInsert2(dd, Cuddaux_addRestrict, f, c, res);
  return(res);

} /* end of cuddauxAddRestrictRecur */