Esempio n. 1
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;
    }
  }
}
Esempio n. 2
0
/**Function*************************************************************

  Synopsis    [Symmetry computation using BDDs (both naive and smart).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
{
    Extra_SymmInfo_t * pSymms;
    Abc_Obj_t * pNode;
    DdNode * bFunc;
    int nSymms = 0;
    int nSupps = 0;
    int i;

    // compute symmetry info for each PO
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
//      bFunc = pNtk->vFuncsGlob->pArray[i];
        bFunc = Abc_ObjGlobalBdd( pNode );
        nSupps += Cudd_SupportSize( dd, bFunc );
        if ( Cudd_IsConstant(bFunc) )
            continue;
        if ( fNaive )
            pSymms = Extra_SymmPairsComputeNaive( dd, bFunc );
        else
            pSymms = Extra_SymmPairsCompute( dd, bFunc );
        nSymms += pSymms->nSymms;
        if ( fVerbose )
        {
            printf( "Output %6s (%d): ", Abc_ObjName(pNode), pSymms->nSymms );
            Ntk_NetworkSymmsPrint( pNtk, pSymms );
        }
//Extra_SymmPairsPrint( pSymms );
        Extra_SymmPairsDissolve( pSymms );
    }
Esempio n. 3
0
static double Expectation(DdNode **nodes_ex, int lenNodes) {
  int i;
  double rootProb, CLL = 0;

  for (i = 0; i < lenNodes; i++) {
    if (!Cudd_IsConstant(nodes_ex[i])) {
      nodesB = init_table(boolVars_ex[i]);
      nodesF = init_table(boolVars_ex[i]);

      Forward(nodes_ex[i], i);
      rootProb = GetOutsideExpe(nodes_ex[i], example_prob[i], i);

      if (rootProb <= 0.0)
        CLL = CLL + LOGZERO * example_prob[i];
      else
        CLL = CLL + log(rootProb) * example_prob[i];

      nodes_probs_ex[i] = rootProb;
      destroy_table(nodesB, boolVars_ex[i]);
      destroy_table(nodesF, boolVars_ex[i]);
    } else if (nodes_ex[i] == Cudd_ReadLogicZero(mgr_ex[i])) {
      CLL = CLL + LOGZERO * example_prob[i];
      nodes_probs_ex[i] = 0.0;
    } else
      nodes_probs_ex[i] = 1.0;
  }
  return CLL;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_zddPrintCover.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static void
zddPrintCoverAux(
  DdManager * zdd /* manager */,
  DdNode * node /* current node */,
  int  level /* depth in the recursion */,
  int * list /* current recursion path */)
{
    DdNode	*Nv, *Nnv;
    int		i, v;
    DdNode	*base = DD_ONE(zdd);

    if (Cudd_IsConstant(node)) {
	if (node == base) {
	    /* Check for missing variable. */
	    if (level != zdd->sizeZ) {
		list[zdd->invpermZ[level]] = 0;
		zddPrintCoverAux(zdd, node, level + 1, list);
		return;
	    }
	    /* Terminal case: Print one cube based on the current recursion
	    ** path.
	    */
	    for (i = 0; i < zdd->sizeZ; i += 2) {
		v = list[i] * 4 + list[i+1];
		if (v == 0)
		    (void) fprintf(zdd->out,"-");
		else if (v == 4)
		    (void) fprintf(zdd->out,"1");
		else if (v == 1)
		    (void) fprintf(zdd->out,"0");
		else
		    (void) fprintf(zdd->out,"@"); /* should never happen */
	    }
	    (void) fprintf(zdd->out," 1\n");
	}
    } else {
	/* Check for missing variable. */
	if (level != cuddIZ(zdd,node->index)) {
	    list[zdd->invpermZ[level]] = 0;
	    zddPrintCoverAux(zdd, node, level + 1, list);
	    return;
	}

	Nnv = cuddE(node);
	Nv = cuddT(node);
	if (Nv == Nnv) {
	    list[node->index] = 2;
	    zddPrintCoverAux(zdd, Nnv, level + 1, list);
	    return;
	}

	list[node->index] = 1;
	zddPrintCoverAux(zdd, Nv, level + 1, list);
	list[node->index] = 0;
	zddPrintCoverAux(zdd, Nnv, level + 1, list);
    }
    return;

} /* end of zddPrintCoverAux */
Esempio n. 6
0
/**
 * Internal function
 */
double recurse_getNofSatisfyingAssignments(DdManager *dd, DdNode *orig, DdNode *cube, std::map<DdNode*,double> &buffer) {

	// Normalize the cube
	DdNode *cubeNext;
	if (Cudd_Regular(cube)==cube) {
		cubeNext = cuddT(cube);
	} else {
		if (!Cudd_IsConstant(cube)) {
			cube = Cudd_Regular(cube);
			cubeNext = (DdNode*)(((size_t)(cuddE(cube)) ^ 0x1));
		} else {
			// Constant
			return (orig==dd->one)?1:0;
		}
	}

	if (buffer.count(orig)>0) return buffer[orig];
	if (Cudd_IsConstant(orig)) {
		if (Cudd_IsConstant(cube)) {
			return (orig==dd->one)?1:0;
		} else {
			return 2*recurse_getNofSatisfyingAssignments(dd,orig,cubeNext,buffer);
		}
	}

	size_t xoring = (Cudd_Regular(orig)==orig?0:1);
	DdNode *reference = Cudd_Regular(orig);

	if (Cudd_IsConstant(cube)) return std::numeric_limits<double>::quiet_NaN(); // Missing variable!
	int i1 = cuddI(dd,cube->index);
	int i2 = cuddI(dd,reference->index);

	if (i1<i2) {
		double value = 2*recurse_getNofSatisfyingAssignments(dd,(DdNode*)((size_t)reference ^ xoring),cubeNext,buffer);
		buffer[orig] = value;
		return value;
	} else if (i1>i2) {
		return std::numeric_limits<double>::quiet_NaN();
	} else {
		double value = recurse_getNofSatisfyingAssignments(dd,(DdNode*)((size_t)(cuddT(reference)) ^ xoring),cubeNext,buffer)
			+ recurse_getNofSatisfyingAssignments(dd,(DdNode*)((size_t)(cuddE(reference)) ^ xoring),cubeNext,buffer);

		buffer[orig] = value;
		return value;
	}
}
int
DddmpReadNodeIndexCnf (
  DdNode *f     /* IN: BDD node */
  )
{
  if (!Cudd_IsConstant (f)) {
    return ((int)(((uintptr_t)(f->next))>>1));
  } else {
    return (1);
Esempio n. 8
0
int
DddmpReadNodeIndexAdd (
  DdNode *f    /* IN: BDD node */
  )
{
  if (1 || !Cudd_IsConstant (f)) {
    return ((int)(((ptruint)(f->next))>>1));
  } else {
    return (1);
Esempio n. 9
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;
        }
    }
}
Esempio n. 10
0
File: Synth.cpp Progetto: 5nizza/sdf
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;
}
Esempio n. 11
0
void 
DddmpWriteNodeIndexAdd (
  DdNode *f   /* IN: BDD node */,
  int id      /* IN: index to be written */
  )
{
  if (1 || !Cudd_IsConstant (f)) {
    f->next = (struct DdNode *)((ptruint)((id)<<1));
  }

  return;
}
int
DddmpWriteNodeIndexCnf (
  DdNode *f   /* IN: BDD node */,
  int id      /* IN: index to be written */
  )
{
  if (!Cudd_IsConstant (f)) {
    f->next = (struct DdNode *)((uintptr_t)((id)<<1));
  }

  return (DDDMP_SUCCESS);
}
Esempio n. 13
0
/**Function********************************************************************

  Synopsis    [Checks whether a variable is dependent on others in a
  function.]

  Description [Checks whether a variable is dependent on others in a
  function.  Returns 1 if the variable is dependent; 0 otherwise. No
  new nodes are created.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
Cudd_bddVarIsDependent(
  DdManager *dd,		/* manager */
  DdNode *f,			/* function */
  DdNode *var			/* variable */)
{
    DdNode *F, *res, *zero, *ft, *fe;
    unsigned topf, level;
    DD_CTFP cacheOp;
    int retval;

    /* NuSMV: begin add */
    abort(); /* NOT USED BY NUSMV */
    /* NuSMV: begin end */

    zero = Cudd_Not(DD_TRUE(dd));
    if (Cudd_IsConstant(f)) return(f == zero);

    /* From now on f is not constant. */
    F = Cudd_Regular(f);
    topf = (unsigned) dd->perm[F->index];
    level = (unsigned) dd->perm[var->index];

    /* Check terminal case. If topf > index of var, f does not depend on var.
    ** Therefore, var is not dependent in f. */
    if (topf > level) {
	return(0);
    }

    cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
    res = cuddCacheLookup2(dd,cacheOp,f,var);
    if (res != NULL) {
	return(res != zero);
    }

    /* Compute cofactors. */
    ft = Cudd_NotCond(cuddT(F), f != F);
    fe = Cudd_NotCond(cuddE(F), f != F);

    if (topf == level) {
	retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
    } else {
	retval = Cudd_bddVarIsDependent(dd,ft,var) &&
	    Cudd_bddVarIsDependent(dd,fe,var);
    }

    cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));

    return(retval);

} /* Cudd_bddVarIsDependent */
Esempio n. 14
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;
    }
  }
}
Esempio n. 15
0
/**Function********************************************************************

  Synopsis [Computes the fraction of minterms in the on-set of all the
  positive cofactors of a BDD or ADD.]

  Description [Computes the fraction of minterms in the on-set of all
  the positive cofactors of DD. Returns the pointer to an array of
  doubles if successful; NULL otherwise. The array hs as many
  positions as there are BDD variables in the manager plus one. The
  last position of the array contains the fraction of the minterms in
  the ON-set of the function represented by the BDD or ADD. The other
  positions of the array hold the variable signatures.]

  SideEffects [None]

******************************************************************************/
double *
Cudd_CofMinterm(
  DdManager * dd,
  DdNode * node)
{
    st_table	*table;
    double	*values;
    double	*result = NULL;
    int		i, firstLevel;

#ifdef DD_STATS
    long startTime;
    startTime = util_cpu_time();
    num_calls = 0;
    table_mem = sizeof(st_table);
#endif

    table = st_init_table(st_ptrcmp, st_ptrhash);
    if (table == NULL) {
	(void) fprintf(stdout,"out-of-memory, couldn't measure DD cofactors.\n");
	return(NULL);
    }
    size = dd->size;
    values = ddCofMintermAux(dd, node, table);
    if (values != NULL) {
	result = ALLOC(double,size + 1);
	if (result != NULL) {
#ifdef DD_STATS
	    table_mem += (size + 1) * sizeof(double);
#endif
	    if (Cudd_IsConstant(node))
		firstLevel = 1;
	    else
		firstLevel = cuddI(dd,Cudd_Regular(node)->index);
	    for (i = 0; i < size; i++) {
		if (i >= cuddI(dd,Cudd_Regular(node)->index)) {
		    result[dd->invperm[i]] = values[i - firstLevel];
		} else {
		    result[dd->invperm[i]] = values[size - firstLevel];
		}
	    }
	    result[size] = values[size - firstLevel];
	} else {
	    dd->errorCode = CUDD_MEMORY_OUT;
	}
    }
Esempio n. 16
0
double Prob(extmanager MyManager, DdNode *node,  int comp)
/* 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 mVarIndex,nBit,index;
  variable v;
  hisnode *Found;
  double res;
  double value;


  if (Cudd_IsConstant(node))
  {
    value=Cudd_V(node);
    if (comp)
	{
	return 0.0;
	}
	else
	{
	return 1.0;
	}
  }
  else
{
	Found = GetNode1(MyManager.varmap.bVar2mVar,MyManager.his, MyManager.varmap.varstart, node);
	
	if (Found!=NULL)
	{
		return Found->dvalue;
	}
	else
  	{
		index=Cudd_NodeReadIndex(node);
		mVarIndex=MyManager.varmap.bVar2mVar[index];
		v=MyManager.varmap.mvars[mVarIndex];
    		nBit=v.nBit;
    		res=ProbBool(MyManager,node,0,nBit,0,v,comp);
		AddNode1(MyManager.varmap.bVar2mVar,MyManager.his, MyManager.varmap.varstart, node, res, 0, NULL);
    		return res;
  	}
}
}
Esempio n. 17
0
static YAP_Bool ret_prob(void) {
  YAP_Term arg1, arg2, out;
  DdNode *node;

  arg1 = YAP_ARG1;
  arg2 = YAP_ARG2;
  node = (DdNode *)YAP_IntOfTerm(arg1);

  if (!Cudd_IsConstant(node)) {
    table = init_table(boolVars_ex[ex]);
    out = YAP_MkFloatTerm(Prob(node, 0));
    destroy_table(table, boolVars_ex[ex]);
  } else {
    if (node == Cudd_ReadOne(mgr_ex[ex]))
      out = YAP_MkFloatTerm(1.0);
    else
      out = YAP_MkFloatTerm(0.0);
  }

  return (YAP_Unify(out, arg2));
}
Esempio n. 18
0
/**Function********************************************************************

  Synopsis    [Checks whether g is the BDD of a cube.]

  Description [Checks whether g is the BDD of a cube. Returns 1 in case
  of success; 0 otherwise. The constant 1 is a valid cube, but all other
  constant functions cause cuddCheckCube to return 0.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
cuddCheckCube(
  DdManager * dd,
  DdNode * g)
{
    DdNode *g1,*g0,*one,*zero;
    
    one = DD_ONE(dd);
    if (g == one) return(1);
    if (Cudd_IsConstant(g)) return(0);

    zero = Cudd_Not(one);
    cuddGetBranches(g,&g1,&g0);

    if (g0 == zero) {
        return(cuddCheckCube(dd, g1));
    }
    if (g1 == zero) {
        return(cuddCheckCube(dd, g0));
    }
    return(0);

} /* end of cuddCheckCube */
Esempio n. 19
0
/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_SplitSet.]

  Description [Implements the recursive step of Cudd_SplitSet. The
  procedure recursively traverses the BDD and checks to see if any
  node satisfies the minterm requirements as specified by 'n'. At any
  node X, n is compared to the number of minterms in the onset of X's
  children. If either of the child nodes have exactly n minterms, then
  that node is returned; else, if n is greater than the onset of one
  of the child nodes, that node is retained and the difference in the
  number of minterms is extracted from the other child. In case n
  minterms can be extracted from constant 1, the algorithm returns the
  result with at most log(n) nodes.]

  SideEffects [The array 'varSeen' is updated at every recursive call
  to set the variables traversed by the procedure.]

  SeeAlso     []

******************************************************************************/
DdNode*
cuddSplitSetRecur(
  DdManager * manager,
  st_table * mtable,
  int * varSeen,
  DdNode * p,
  double  n,
  double  max,
  int  index)
{
    DdNode *one, *zero, *N, *Nv;
    DdNode *Nnv, *q, *r, *v;
    DdNode *result;
    double *dummy, numT, numE;
    int variable, positive;
  
    statLine(manager);
    one = DD_ONE(manager);
    zero = Cudd_Not(one);

    /* If p is constant, extract n minterms from constant 1.  The procedure by
    ** construction guarantees that minterms will not be extracted from
    ** constant 0.
    */
    if (Cudd_IsConstant(p)) {
	q = selectMintermsFromUniverse(manager,varSeen,n);
	return(q);
    }

    N = Cudd_Regular(p);

    /* Set variable as seen. */
    variable = N->index;
    varSeen[manager->invperm[variable]] = -1;

    Nv = cuddT(N);
    Nnv = cuddE(N);
    if (Cudd_IsComplement(p)) {
	Nv = Cudd_Not(Nv);
	Nnv = Cudd_Not(Nnv);
    }

    /* If both the children of 'p' are constants, extract n minterms from a
    ** constant node.
    */
    if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) {
	q = selectMintermsFromUniverse(manager,varSeen,n);
	if (q == NULL) {
	    return(NULL);
	}
	cuddRef(q);
	r = cuddBddAndRecur(manager,p,q);
	if (r == NULL) {
	    Cudd_RecursiveDeref(manager,q);
	    return(NULL);
	}
	cuddRef(r);
	Cudd_RecursiveDeref(manager,q);
	cuddDeref(r);
	return(r);
    }
  
    /* Lookup the # of minterms in the onset of the node from the table. */
    if (!Cudd_IsConstant(Nv)) {
	if (!st_lookup(mtable, Nv, &dummy)) return(NULL);
	numT = *dummy/(2*(1<<index));
    } else if (Nv == one) {
	numT = max/(2*(1<<index));
    } else {
	numT = 0;
    }
  
    if (!Cudd_IsConstant(Nnv)) {
	if (!st_lookup(mtable, Nnv, &dummy)) return(NULL);
	numE = *dummy/(2*(1<<index));
    } else if (Nnv == one) {
	numE = max/(2*(1<<index));
    } else {
	numE = 0;
    }

    v = cuddUniqueInter(manager,variable,one,zero);
    cuddRef(v);

    /* If perfect match. */
    if (numT == n) {
	q = cuddBddAndRecur(manager,v,Nv);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(q);
	return(q);
    }
    if (numE == n) {
	q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(q);
	return(q);
    }
    /* If n is greater than numT, extract the difference from the ELSE child
    ** and retain the function represented by the THEN branch.
    */
    if (numT < n) {
	q = cuddSplitSetRecur(manager,mtable,varSeen,
			      Nnv,(n-numT),max,index+1);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	r = cuddBddIteRecur(manager,v,Nv,q);
	if (r == NULL) {
	    Cudd_RecursiveDeref(manager,q);
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(r);
	Cudd_RecursiveDeref(manager,q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(r);
	return(r);
    }
    /* If n is greater than numE, extract the difference from the THEN child
    ** and retain the function represented by the ELSE branch.
    */
    if (numE < n) {
	q = cuddSplitSetRecur(manager,mtable,varSeen,
			      Nv, (n-numE),max,index+1);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	r = cuddBddIteRecur(manager,v,q,Nnv);
	if (r == NULL) {
	    Cudd_RecursiveDeref(manager,q);
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(r);
	Cudd_RecursiveDeref(manager,q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(r);    
	return(r);
    }

    /* None of the above cases; (n < numT and n < numE) and either of
    ** the Nv, Nnv or both are not constants. If possible extract the
    ** required minterms the constant branch.
    */
    if (Cudd_IsConstant(Nv) && !Cudd_IsConstant(Nnv)) {
	q = selectMintermsFromUniverse(manager,varSeen,n);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	result = cuddBddAndRecur(manager,v,q);
	if (result == NULL) {
	    Cudd_RecursiveDeref(manager,q);
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(result);
	Cudd_RecursiveDeref(manager,q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(result);
	return(result);
    } else if (!Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) {
	q = selectMintermsFromUniverse(manager,varSeen,n);
	if (q == NULL) {
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(q);
	result = cuddBddAndRecur(manager,Cudd_Not(v),q);
	if (result == NULL) {
	    Cudd_RecursiveDeref(manager,q);
	    Cudd_RecursiveDeref(manager,v);
	    return(NULL);
	}
	cuddRef(result);
	Cudd_RecursiveDeref(manager,q);
	Cudd_RecursiveDeref(manager,v);
	cuddDeref(result);
	return(result);
    }

    /* Both Nv and Nnv are not constants. So choose the one which
    ** has fewer minterms in its onset.
    */
    positive = 0;
    if (numT < numE) {
	q = cuddSplitSetRecur(manager,mtable,varSeen,
			      Nv,n,max,index+1);
	positive = 1;
    } else {
	q = cuddSplitSetRecur(manager,mtable,varSeen,
			      Nnv,n,max,index+1);
    }

    if (q == NULL) {
	Cudd_RecursiveDeref(manager,v);
	return(NULL);
    }
    cuddRef(q);

    if (positive) {
	result = cuddBddAndRecur(manager,v,q);
    } else {
	result = cuddBddAndRecur(manager,Cudd_Not(v),q);
    }
    if (result == NULL) {
	Cudd_RecursiveDeref(manager,q);
	Cudd_RecursiveDeref(manager,v);
	return(NULL);
    }
    cuddRef(result);
    Cudd_RecursiveDeref(manager,q);
    Cudd_RecursiveDeref(manager,v);
    cuddDeref(result);

    return(result);

} /* end of cuddSplitSetRecur */
Esempio n. 20
0
char* DumpDoth(DdManager *dd, DdNode *add, onum *orig_vars, int rovar, char ** lnames, FILE *fp, FILE *nfp, int *hmn) {
  // descend the add through the root_ovar's binary variables and recursively
  // write out the nodes for all sub-adds
  DdNode *temp, *branch, *newadd;
  char *nodename, *newnodename;
  char namestr[1024];
  // make up a new name for this node
  // and write it to fp
  nodename = new char[256];
  newnodename = new char[256];
  sprintf(newnodename,"a%d",*hmn);
  (*hmn)++;


  // we're at a leaf
  if (Cudd_IsConstant(add)) {
    //write the node to nfp
    fprintf(fp,"{ rank = same; node [shape=box, style=filled, color=goldenrod];\"%s\" ",newnodename);

    if (lnames == NULL) {
      fprintf(fp," [label = \"%s \"];}\n",(*Cudd_V(add)).toString());
    } else {
      strcpy(namestr,"");
      aconvert(namestr,lnames,(*Cudd_V(add)).get_min());
      fprintf(fp,"[label = \"%s \"];}\n",namestr);
    }
    return newnodename;
  } else {
    // move down to the rovar which is at the root of this ADD
    while (Cudd_NodeReadIndex(vars[orig_vars[rovar].var1index].add_var) < Cudd_NodeReadIndex(add) &&
	   Cudd_NodeReadIndex(vars[orig_vars[rovar].var1index+orig_vars[rovar].nbvars-1].add_var) < Cudd_NodeReadIndex(add))
      rovar++;
    
    //

    fprintf(fp,"{ rank = same; node [shape=ellipse, style=filled, color=cornflowerblue];\"%s\" [label=\"%s\"];}\n",
	    newnodename,orig_vars[rovar].name);
  }
  
  onum root_ovar = orig_vars[rovar];
  int next_rovar_index;
  onum next_rovar;
  if (rovar+1 < numorigvars) {
    next_rovar_index = orig_vars[rovar+1].var1index;
  } else {
    next_rovar_index = -1;
  }
  next_rovar_index *= 2;
  int nbv(root_ovar.nbvars),tmp;
  int nbvals = int(pow(2.0,nbv));
  int *phase = new int[nbv];

  DdNode **arrayofvars = new DdNode*[nbv];

  DdNode *subadds[MAXVALS];
  temp = add;
  Cudd_Ref(temp);
  
  int coval =0,i;
  // go over all the branches at this node. 
  // we want to figure out the add rooted at each branch of the original
  // variable and then write the parent pointing to that branch. 
  while (coval<root_ovar.nvals) {
    
    for (i=0; i<nbv; i++)
      phase[i] = 0;
    tmp = nbvals-coval-1;
    i=nbv-1;
    // get the branch in binary
    while (tmp > 0 && i >=0) {
      phase[i--] = tmp%2;
      tmp = tmp/2;
    }
    i=0;
    int shit;
    // descend the add to find that branch. However ,not all the variables will be present in the add in general.
    // therefore, we have to skip all the ones which are not there until we find one, and then skip
    // all the ones missing at the end. Do this by checking to see if the either
    // (a) the add is a constant node (then we've gone far enough)
    // (b) the index of the node is in the next original variable's domain (gone far enough)
    while (i < nbv && ( !Cudd_IsConstant(temp) && (next_rovar_index < 0 || Cudd_NodeReadIndex(temp) < next_rovar_index))) {
      if (Cudd_NodeReadIndex(temp) == 2*(orig_vars[rovar].var1index+i)+1) {
	if (phase[i]) 
	  branch = Cudd_Then(temp);
	else
	  branch = Cudd_Else(temp);
	Cudd_Ref(branch);
	Cudd_RecursiveDeref(gbm,temp);
	temp = branch;
      }
      i++;
    }
    // now check if its the same as one we've done so far
    bool different(true);
    for (i=0; i<numbranches && different; i++) 
      different = (temp != branches[i]);
    if (different) {
      // recursive call - writes this branch to nfp
      nodename = DumpDoth(dd,temp,orig_vars,rovar+1,lnames,fp,nfp,hmn);
      branches[numbranches] = temp;
      Cudd_Ref(branches[numbranches]);
      branchnodenames[numbranches] = nodename;
      numbranches++;
      // may need more space than expected so check for that
      // this would work better with a list
      if (numbranches >= numexpbranches) {
	// need more space
	// save old branches
	DdNode ** newbranches = new DdNode *[numbranches*2];
	for (i=0; i<numbranches; i++) 
	  newbranches[i] = branches[i];

	// delete old
	delete [] branches;
	// re-allocoate
	numexpbranches = 2*numbranches;
	branches = new DdNode *[numexpbranches];
	for (i=0; i<numbranches; i++)
	  branches[i] = newbranches[i];
	delete [] newbranches;
      }
    } else {
      nodename = branchnodenames[i-1];
    }

    //now write our current node pointing to this one
    fprintf(nfp,"\"%s\" -> \"%s\" [label = \"%s\"];\n",newnodename,nodename,root_ovar.valname[coval]);
    coval++;
    // start back at top
    Cudd_RecursiveDeref(gbm,temp);
    temp = add;
    Cudd_Ref(temp);
  }
  return newnodename;
  delete [] phase;
}
Esempio n. 21
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;
    }
  }
}
Esempio n. 22
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Extra_TransferPermute.]

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

  SideEffects [None]

  SeeAlso     [extraTransferPermuteTime]

******************************************************************************/
static DdNode * 
extraTransferPermuteRecurTime( 
  DdManager * ddS, 
  DdManager * ddD, 
  DdNode * f, 
  st_table * table, 
  int * Permute,
  int TimeOut )
{
    DdNode *ft, *fe, *t, *e, *var, *res;
    DdNode *one, *zero;
    int index;
    int comple = 0;

    statLine( ddD );
    one = DD_ONE( ddD );
    comple = Cudd_IsComplement( f );

    /* Trivial cases. */
    if ( Cudd_IsConstant( f ) )
        return ( Cudd_NotCond( one, comple ) );


    /* Make canonical to increase the utilization of the cache. */
    f = Cudd_NotCond( f, comple );
    /* Now f is a regular pointer to a non-constant node. */

    /* Check the cache. */
    if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) )
        return ( Cudd_NotCond( res, comple ) );

    if ( TimeOut && TimeOut < clock() )
        return NULL;

    /* Recursive step. */
    if ( Permute )
        index = Permute[f->index];
    else
        index = f->index;

    ft = cuddT( f );
    fe = cuddE( f );

    t = extraTransferPermuteRecurTime( ddS, ddD, ft, table, Permute, TimeOut );
    if ( t == NULL )
    {
        return ( NULL );
    }
    cuddRef( t );

    e = extraTransferPermuteRecurTime( ddS, ddD, fe, table, Permute, TimeOut );
    if ( e == NULL )
    {
        Cudd_RecursiveDeref( ddD, t );
        return ( NULL );
    }
    cuddRef( e );

    zero = Cudd_Not(ddD->one);
    var = cuddUniqueInter( ddD, index, one, zero );
    if ( var == NULL )
    {
        Cudd_RecursiveDeref( ddD, t );
        Cudd_RecursiveDeref( ddD, e );
        return ( NULL );
    }
    res = cuddBddIteRecur( ddD, var, t, e );

    if ( res == NULL )
    {
        Cudd_RecursiveDeref( ddD, t );
        Cudd_RecursiveDeref( ddD, e );
        return ( NULL );
    }
    cuddRef( res );
    Cudd_RecursiveDeref( ddD, t );
    Cudd_RecursiveDeref( ddD, e );

    if ( st_add_direct( table, ( char * ) f, ( char * ) res ) ==
         ST_OUT_OF_MEM )
    {
        Cudd_RecursiveDeref( ddD, res );
        return ( NULL );
    }
    return ( Cudd_NotCond( res, comple ) );

}  /* end of extraTransferPermuteRecurTime */
Esempio n. 23
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 */
Esempio n. 24
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 */
Esempio n. 25
0
/**Function********************************************************************

  Synopsis [Performs the recursive step of cuddZddP.]

  Description [Performs the recursive step of cuddZddP. Returns 1 in
  case of success; 0 otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static int
zp2(
  DdManager * zdd,
  DdNode * f,
  st_table * t)
{
    DdNode	*n;
    int		T, E;
    DdNode	*base = DD_ONE(zdd);
    
    if (f == NULL)
	return(0);

    if (Cudd_IsConstant(f)) {
        (void)fprintf(zdd->out, "ID = %d\n", (f == base));
	return(1);
    }
    if (st_is_member(t, (char *)f) == 1)
	return(1);

    if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM)
	return(0);

#if SIZEOF_VOID_P == 8
    (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %d\tr = %d\t",
	(unsigned long)f / (unsigned long) sizeof(DdNode), f->index, f->ref);
#else
    (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t",
	(unsigned)f / (unsigned) sizeof(DdNode), f->index, f->ref);
#endif

    n = cuddT(f);
    if (Cudd_IsConstant(n)) {
        (void) fprintf(zdd->out, "T = %d\t\t", (n == base));
	T = 1;
    } else {
#if SIZEOF_VOID_P == 8
        (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n /
		       (unsigned long) sizeof(DdNode));
#else
        (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode));
#endif
	T = 0;
    }

    n = cuddE(f);
    if (Cudd_IsConstant(n)) {
        (void) fprintf(zdd->out, "E = %d\n", (n == base));
	E = 1;
    } else {
#if SIZEOF_VOID_P == 8
        (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n /
		      (unsigned long) sizeof(DdNode));
#else
        (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode));
#endif
	E = 0;
    }

    if (E == 0)
	if (zp2(zdd, cuddE(f), t) == 0) return(0);
    if (T == 0)
	if (zp2(zdd, cuddT(f), t) == 0) return(0);
    return(1);

} /* end of zp2 */
Esempio n. 26
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 */
Esempio n. 27
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step for Cudd_BddToAdd.]

  Description [Performs the recursive step for Cudd_BddToAdd. Returns a
  pointer to the resulting ADD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
ddBddToAddRecur(
  DdManager * dd,
  DdNode * B)
{
    DdNode *_true;
    DdNode *res, *res1, *T, *E, *Bt, *Be;
    int complement = 0;

    statLine(dd);
    _true = DD_TRUE(dd);

    if (Cudd_IsConstant(B)) {
	if (B == _true) {
	    res = _true;
	} else {
	    res = DD_FALSE(dd);
	}
	return(res);
    }
    /* Check visited table */
    res = cuddCacheLookup1(dd,ddBddToAddRecur,B);
    if (res != NULL) return(res);

    if (Cudd_IsComplement(B)) {
	complement = 1;
	Bt = cuddT(Cudd_Regular(B));
	Be = cuddE(Cudd_Regular(B));
    } else {
	Bt = cuddT(B);
	Be = cuddE(B);
    }

    T = ddBddToAddRecur(dd, Bt);
    if (T == NULL) return(NULL);
    cuddRef(T);

    E = ddBddToAddRecur(dd, Be);
    if (E == NULL) {
	Cudd_RecursiveDeref(dd, T);
	return(NULL);
    }
    cuddRef(E);

    /* No need to check for T == E, because it is guaranteed not to happen. */
    res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E);
    if (res == NULL) {
	Cudd_RecursiveDeref(dd ,T);
	Cudd_RecursiveDeref(dd ,E);
	return(NULL);
    }
    cuddDeref(T);
    cuddDeref(E);

    if (complement) {
	cuddRef(res);
	res1 = cuddAddCmplRecur(dd, res);
	if (res1 == NULL) {
	    Cudd_RecursiveDeref(dd, res);
	    return(NULL);
	}
	cuddRef(res1);
	Cudd_RecursiveDeref(dd, res);
	res = res1;
	cuddDeref(res);
    }

    /* Store result. */
    cuddCacheInsert1(dd,ddBddToAddRecur,B,res);

    return(res);

} /* end of ddBddToAddRecur */
Esempio n. 28
0
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                    FUNCTION DEFINITIONS                          ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [This procedure is similar to Cudd_ShuffleHeap() and Cudd_bddPermute().]

  Description [The first argument is the REO manager. The 2nd/3d
  arguments are the function and its CUDD manager. The last argument
  is the permutation to be implemented. The i-th entry of the permutation 
  array contains the index of the variable that should be brought to the 
  i-th level.  The size of the array should be equal or greater to 
  the number of variables currently in use (that is, the size of CUDD
  manager and the size of REO manager).]

  SideEffects [Note that the resulting BDD is not referenced.]

  SeeAlso     []

***********************************************************************/
DdNode * reoShuffle( reo_man * p, DdManager * dd, DdNode * bFunc, int * pPerm, int * pPermInv )
{
    DdNode * bFuncRes = NULL;
    int i, k, v;

    if ( Cudd_IsConstant(bFunc) )
        return bFunc;

	// set the initial parameters
	p->dd    = dd;
    p->nSupp = Cudd_SupportSize( dd, bFunc );
	p->nTops = 1;
//    p->nNodesBeg = Cudd_DagSize( bFunc );

    // set the starting permutation
	for ( i = 0; i < p->nSupp; i++ )
    {
        p->pOrderInt[i] = i;
		p->pMapToPlanes[ dd->invperm[i] ] = i;
		p->pMapToDdVarsFinal[i] = dd->invperm[i];
    }

	// set the initial parameters
	p->nUnitsUsed = 0;
	p->nNodesCur  = 0;
	p->fThisIsAdd = 0;
	p->Signature++;

	// transfer the function from the CUDD package into REO's internal data structure
    p->pTops[0] = reoTransferNodesToUnits_rec( p, bFunc );
//	assert( p->nNodesBeg == p->nNodesCur );

    // reorder one variable at a time
    for ( i = 0; i < p->nSupp; i++ )
    {
        if ( p->pOrderInt[i] == pPerm[i] )
            continue;
        // find where is variable number pPerm[i]
        for ( k = i + 1; k < p->nSupp; k++ )
            if ( pPerm[i] == p->pOrderInt[k] )
                break;
        if ( k == p->nSupp )
        {
            printf( "reoShuffle() Error: Cannot find a variable.\n" );
            goto finish;
        }
        // move the variable up
        for ( v = k - 1; v >= i; v-- )
        {
            reoReorderSwapAdjacentVars( p, v, 1 );
            // check if the number of nodes is not too large
            if ( p->nNodesCur > 10000 )
            {
                printf( "reoShuffle() Error: BDD size is too large.\n" );
                goto finish;
            }
        }
        assert( p->pOrderInt[i] == pPerm[i] );
    }

	// set the initial parameters
	p->nRefNodes  = 0;
	p->nNodesCur  = 0;
	p->Signature++;
	// transfer the BDDs from REO's internal data structure to CUDD
    bFuncRes = reoTransferUnitsToNodes_rec( p, p->pTops[0] ); Cudd_Ref( bFuncRes );
	// undo the DDs referenced for storing in the cache
	for ( i = 0; i < p->nRefNodes; i++ )
		Cudd_RecursiveDeref( dd, p->pRefNodes[i] );

	// verify zero refs of the terminal nodes
//    assert( reoRecursiveDeref( p->pTops[0] ) );
//    assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );

    // perform verification
	if ( p->fVerify )
	{
		DdNode * bFuncPerm;
		bFuncPerm = Cudd_bddPermute( dd, bFunc, pPermInv );  Cudd_Ref( bFuncPerm );
		if ( bFuncPerm != bFuncRes )
		{
			printf( "REO: Internal verification has failed!\n" );
			fflush( stdout );
		}
		Cudd_RecursiveDeref( dd, bFuncPerm );
	}

	// recycle the data structure
	for ( i = 0; i <= p->nSupp; i++ )
		reoUnitsRecycleUnitList( p, p->pPlanes + i );

finish :
    if ( bFuncRes )
        Cudd_Deref( bFuncRes );
    return bFuncRes;
}
Esempio n. 29
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_CProjection.]

  Description [Performs the recursive step of Cudd_CProjection. Returns
  the projection if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_CProjection]

******************************************************************************/
DdNode *
cuddCProjectionRecur(
  DdManager * dd,
  DdNode * R,
  DdNode * Y,
  DdNode * Ysupp)
{
    DdNode *res, *res1, *res2, *resA;
    DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha;
    unsigned int topR, topY, top, index;
    DdNode *one = DD_ONE(dd);

    statLine(dd);
    if (Y == one) return(R);

#ifdef DD_DEBUG
    assert(!Cudd_IsConstant(Y));
#endif

    if (R == Cudd_Not(one)) return(R);

    res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y);
    if (res != NULL) return(res);

    r = Cudd_Regular(R);
    topR = cuddI(dd,r->index);
    y = Cudd_Regular(Y);
    topY = cuddI(dd,y->index);

    top = ddMin(topR, topY);

    /* Compute the cofactors of R */
    if (topR == top) {
	index = r->index;
	RT = cuddT(r);
	RE = cuddE(r);
	if (r != R) {
	    RT = Cudd_Not(RT); RE = Cudd_Not(RE);
	}
    } else {
	RT = RE = R;
    }

    if (topY > top) {
	/* Y does not depend on the current top variable.
	** We just need to compute the results on the two cofactors of R
	** and make them the children of a node labeled r->index.
	*/
	res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp);
	if (res1 == NULL) return(NULL);
	cuddRef(res1);
	res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp);
	if (res2 == NULL) {
	    Cudd_RecursiveDeref(dd,res1);
	    return(NULL);
	}
	cuddRef(res2);
	res = cuddBddIteRecur(dd, dd->vars[index], res1, res2);
	if (res == NULL) {
	    Cudd_RecursiveDeref(dd,res1);
	    Cudd_RecursiveDeref(dd,res2);
	    return(NULL);
	}
	/* If we have reached this point, res1 and res2 are now
	** incorporated in res. cuddDeref is therefore sufficient.
	*/
	cuddDeref(res1);
	cuddDeref(res2);
    } else {
	/* Compute the cofactors of Y */
	index = y->index;
	YT = cuddT(y);
	YE = cuddE(y);
	if (y != Y) {
	    YT = Cudd_Not(YT); YE = Cudd_Not(YE);
	}
	if (YT == Cudd_Not(one)) {
	    Alpha  = Cudd_Not(dd->vars[index]);
	    Yrest = YE;
	    Ra = RE;
	    Ran = RT;
	} else {
	    Alpha = dd->vars[index];
	    Yrest = YT;
	    Ra = RT;
	    Ran = RE;
	}
	Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp));
	if (Gamma == NULL) return(NULL);
	if (Gamma == one) {
	    res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
	    if (res1 == NULL) return(NULL);
	    cuddRef(res1);
	    res = cuddBddAndRecur(dd, Alpha, res1);
	    if (res == NULL) {
		Cudd_RecursiveDeref(dd,res1);
		return(NULL);
	    }
	    cuddDeref(res1);
	} else if (Gamma == Cudd_Not(one)) {
	    res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
	    if (res1 == NULL) return(NULL);
	    cuddRef(res1);
	    res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1);
	    if (res == NULL) {
		Cudd_RecursiveDeref(dd,res1);
		return(NULL);
	    }
	    cuddDeref(res1);
	} else {
	    cuddRef(Gamma);
	    resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
	    if (resA == NULL) {
		Cudd_RecursiveDeref(dd,Gamma);
		return(NULL);
	    }
	    cuddRef(resA);
	    res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA);
	    if (res2 == NULL) {
		Cudd_RecursiveDeref(dd,Gamma);
		Cudd_RecursiveDeref(dd,resA);
		return(NULL);
	    }
	    cuddRef(res2);
	    Cudd_RecursiveDeref(dd,Gamma);
	    Cudd_RecursiveDeref(dd,resA);
	    res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
	    if (res1 == NULL) {
		Cudd_RecursiveDeref(dd,res2);
		return(NULL);
	    }
	    cuddRef(res1);
	    res = cuddBddIteRecur(dd, Alpha, res1, res2);
	    if (res == NULL) {
		Cudd_RecursiveDeref(dd,res1);
		Cudd_RecursiveDeref(dd,res2);
		return(NULL);
	    }
	    cuddDeref(res1);
	    cuddDeref(res2);
	}
    }

    cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res);

    return(res);

} /* end of cuddCProjectionRecur */
Esempio n. 30
0
/**Function********************************************************************

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

  Description [Implements ITEconstant(f,g,h). Returns a pointer to the
  resulting BDD (which may or may not be constant) or DD_NON_CONSTANT.
  No new nodes are created.]

  SideEffects [None]

  SeeAlso     [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]

******************************************************************************/
DdNode *
Cudd_bddIteConstant(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * h)
{
    DdNode       *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
    DdNode       *one = DD_ONE(dd);
    DdNode       *zero = Cudd_Not(one);
    int          comple;
    unsigned int topf, topg, toph, v;

    statLine(dd);
    /* Trivial cases. */
    if (f == one)                       /* ITE(1,G,H) => G */
        return(g);
    
    if (f == zero)                      /* ITE(0,G,H) => H */
        return(h);
    
    /* f now not a constant. */
    bddVarToConst(f, &g, &h, one);      /* possibly convert g or h */
                                        /* to constants */

    if (g == h)                         /* ITE(F,G,G) => G */
        return(g);

    if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) 
        return(DD_NON_CONSTANT);        /* ITE(F,1,0) or ITE(F,0,1) */
                                        /* => DD_NON_CONSTANT */
    
    if (g == Cudd_Not(h))
        return(DD_NON_CONSTANT);        /* ITE(F,G,G') => DD_NON_CONSTANT */
                                        /* if F != G and F != G' */
    
    comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);

    /* Cache lookup. */
    r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h);
    if (r != NULL) {
        return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
    }

    v = ddMin(topg, toph);

    /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
    if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
        return(DD_NON_CONSTANT);
    }

    /* Compute cofactors. */
    if (topf <= v) {
        v = ddMin(topf, v);             /* v = top_var(F,G,H) */
        Fv = cuddT(f); Fnv = cuddE(f);
    } else {
        Fv = Fnv = f;
    }

    if (topg == v) {
        Gv = cuddT(g); Gnv = cuddE(g);
    } else {
        Gv = Gnv = g;
    }

    if (toph == v) {
        H = Cudd_Regular(h);
        Hv = cuddT(H); Hnv = cuddE(H);
        if (Cudd_IsComplement(h)) {
            Hv = Cudd_Not(Hv);
            Hnv = Cudd_Not(Hnv);
        }
    } else {
        Hv = Hnv = h;
    }

    /* Recursion. */
    t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
    if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
        cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
        return(DD_NON_CONSTANT);
    }
    e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
    if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
        cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
        return(DD_NON_CONSTANT);
    }
    cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
    return(Cudd_NotCond(t,comple));

} /* end of Cudd_bddIteConstant */