Esempio n. 1
0
void getActionAndValue(Pair & dval, Pair & aval, int whichPolicy) {
  // query the whichPolicy policy action and value with the current values of varvals
  // fprintf(stderr,"querying policy and action diagrams %d\n",whichPolicy);
  // build an array varass of 1s and 0s over the variables v
  // with assignments corresponding to the varvals (values for the original variables  ov)
  // then call *(Cudd_V(Cudd_Eval(dd,act, varass)))
  int *varass = new int[2*nvars];
  int i,j,nbv,tmp,nbvals;
  for (i=0; i<nvars*2; i++)
    varass[i] = 0;

  for (i=0; i<novars; i++) {
    nbv = ov[i].nbvars;
    nbvals = int(pow(2.0,nbv));
    tmp = nbvals-varvals[i]-1;
    for (j=nbv-1; j>=0; j--) {
      varass[Cudd_NodeReadIndex(v[ov[i].var1index+j].add_var)] = tmp%2;
      tmp = tmp/2;
    }
  }

  dval = *(Cudd_V(Cudd_Eval(dd,val[whichPolicy],varass)));
  aval = *(Cudd_V(Cudd_Eval(dd,act[whichPolicy],varass)));
  
  delete [] varass;
}
Esempio n. 2
0
/**
 * @brief Basic ADD test.
 * @return 0 if successful; -1 otherwise.
 */
static int
testAdd(int verbosity)
{
    DdManager *manager;
    DdNode *f, *var, *tmp, *bg;
    int i, ret;
    CUDD_VALUE_TYPE pinf;

    manager = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!manager) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }
    pinf = Cudd_V(Cudd_ReadPlusInfinity(manager));
    if (verbosity) {
        printf("Plus infinity is %g\n", pinf);
    }
    f = Cudd_addConst(manager,5);
    Cudd_Ref(f);
    for (i = 3; i >= 0; i--) {
        var = Cudd_addIthVar(manager,i);
        Cudd_Ref(var);
        tmp = Cudd_addApply(manager,Cudd_addTimes,var,f);
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(manager,f);
        Cudd_RecursiveDeref(manager,var);
        f = tmp;
    }
    if (verbosity) {
        Cudd_PrintMinterm(manager, f);
        printf("\n");
    }
    Cudd_RecursiveDeref(manager, f);
    bg = Cudd_ReadBackground(manager);
    if (verbosity) {
        printf("background (%g) minterms : ", Cudd_V(bg));
        Cudd_ApaPrintMinterm(Cudd_ReadStdout(manager), manager, bg, 0);
    }
    ret = Cudd_CheckZeroRef(manager);
    if (ret != 0 && verbosity) {
        printf("%d non-zero ADD reference counts after dereferencing\n", ret);
    }
    Cudd_Quit(manager);
    return ret != 0;
}
Esempio n. 3
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. 4
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. 5
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. 6
0
/**Function********************************************************************

  Synopsis    [Repeated squaring algorithm for all-pairs shortest paths.]

  Description []

  SideEffects []

  SeeAlso     []

******************************************************************************/
static DdNode *
ntrSquare(
  DdManager *dd /* manager */,
  DdNode *D /* D(z,y): distance matrix */,
  DdNode **x /* array of x variables */,
  DdNode **y /* array of y variables */,
  DdNode **z /* array of z variables */,
  int vars /* number of variables in each of the three arrays */,
  int pr /* verbosity level */,
  int st /* use the selective trace algorithm */)
{
    DdNode *zero;
    DdNode *I;              /* identity matirix */
    DdNode *w, *V, *P, *M, *R, *RT;
    DdNode *diff, *min, *minDiag;
    int n;
    int neg;
    long start_time;

    zero = Cudd_ReadZero(dd);
    /* Make a working copy of the original matrix. */
    R = D;
    Cudd_Ref(R);
    I = Cudd_addXeqy(dd,vars,z,y);    /* identity matrix */
    Cudd_Ref(I);

    /* Make a copy of the matrix for the selective trace algorithm. */
    diff = R;
    Cudd_Ref(diff);

    start_time = util_cpu_time();
    for (n = vars; n >= 0; n--) {
	printf("Starting iteration %d at time %s\n",vars-n,
	       util_print_time(util_cpu_time() - start_time));

	/* Check for negative cycles: They are identified by negative
	** elements on the diagonal.
	*/

	/* Extract values from the diagonal. */
        Cudd_Ref(w = Cudd_addIte(dd,I,R,zero));
	minDiag = Cudd_addFindMin(dd,w);	/* no need to ref */
	neg = Cudd_V(minDiag) < 0;
	Cudd_RecursiveDeref(dd,w);
	if (neg) {
	    Cudd_RecursiveDeref(dd,diff);
            (void) printf("Negative cycle after %d iterations!\n",vars-n);
            break;
        }

	/* Prepare the first operand of matrix multiplication:
	**   diff(z,y) -> RT(x,y) -> V(x,z)
	*/

	/* RT(x,y) */
	Cudd_Ref(RT = Cudd_addSwapVariables(dd,diff,x,z,vars));
	Cudd_RecursiveDeref(dd,diff);
	/* V(x,z) */
	Cudd_Ref(V = Cudd_addSwapVariables(dd,RT,y,z,vars));
	Cudd_RecursiveDeref(dd,RT);
	if (pr > 0) {
	    double pathcount;
	    (void) printf("V"); Cudd_PrintDebug(dd,V,2*vars,pr);
	    pathcount = Cudd_CountPath(V);
	    (void) printf("Path count = %g\n", pathcount);
	}

	/* V(x,z) * R(z,y) -> P(x,y) */
	Cudd_Ref(P = Cudd_addTriangle(dd,V,R,z,vars));
	Cudd_RecursiveDeref(dd,V);
	/* P(x,y) => M(z,y) */
	Cudd_Ref(M = Cudd_addSwapVariables(dd,P,x,z,vars));
	Cudd_RecursiveDeref(dd,P);
	if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,2*vars,pr);}

	/* min(z,y) */
	Cudd_Ref(min = Cudd_addApply(dd,Cudd_addMinimum,R,M));
	Cudd_RecursiveDeref(dd,M);

	if (R == min) {
	    Cudd_RecursiveDeref(dd,min);
	    if (pr>0) {printf("Done after %d iterations\n",vars-n+1); }
	    break;
	}
	/* diff(z,y) */
	if (st) {
	    Cudd_Ref(diff = Cudd_addApply(dd,Cudd_addDiff,min,R));
	} else {
	    Cudd_Ref(diff = min);
	}
	Cudd_RecursiveDeref(dd,R);
	R = min;                  /* keep a copy of matrix at current iter. */
	if (pr > 0) {
	    double pathcount;
	    (void) printf("R"); Cudd_PrintDebug(dd,R,2*vars,pr);
	    pathcount = Cudd_CountPath(R);
	    (void) printf("Path count = %g\n", pathcount);
	}

	if (n == 0) {
	    (void) printf("Negative cycle!\n");
	    break;
	}

    }
    Cudd_RecursiveDeref(dd,I);
    Cudd_Deref(R);
    return(R);

} /* end of ntrSquare */
Esempio n. 7
0
double maximum(ADD a) {
	return Cudd_V(a.FindMax().getNode());
}
Esempio n. 8
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addOuterSum.]

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

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddOuterSumRecur(
  DdManager *dd,
  DdNode *M,
  DdNode *r,
  DdNode *c)
{
    DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re;
    int topM, topc, topr;
    int v, index;

    statLine(dd);
    /* Check special cases. */
    if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); 

    if (cuddIsConstant(c) && cuddIsConstant(r)) {
	R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r));
	cuddRef(R);
	if (cuddIsConstant(M)) {
	    if (cuddV(R) <= cuddV(M)) {
		cuddDeref(R);
	        return(R);
	    } else {
	        Cudd_RecursiveDeref(dd,R);       
		return(M);
	    }
	} else {
	    P = Cudd_addApply(dd,Cudd_addMinimum,R,M);
	    cuddRef(P);
	    Cudd_RecursiveDeref(dd,R);
	    cuddDeref(P);
	    return(P);
	}
    }

    /* Check the cache. */
    R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c);
    if (R != NULL) return(R);

    topM = cuddI(dd,M->index); topr = cuddI(dd,r->index);
    topc = cuddI(dd,c->index);
    v = ddMin(topM,ddMin(topr,topc));

    /* Compute cofactors. */
    if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; }
    if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; }
    if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; }

    /* Recursively solve. */
    Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct);
    if (Rt == NULL) return(NULL);
    cuddRef(Rt);
    Re = cuddAddOuterSumRecur(dd,Me,re,ce);
    if (Re == NULL) {
	Cudd_RecursiveDeref(dd, Rt);
	return(NULL);
    }
    cuddRef(Re);
    index = dd->invperm[v];
    R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re);
    if (R == NULL) {
	Cudd_RecursiveDeref(dd, Rt);
	Cudd_RecursiveDeref(dd, Re);
	return(NULL);
    }
    cuddDeref(Rt);
    cuddDeref(Re);

    /* Store the result in the cache. */
    cuddCacheInsert(dd,DD_ADD_OUT_SUM_TAG,M,r,c,R);

    return(R);

} /* end of cuddAddOuterSumRecur */
Esempio n. 9
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;
}