/// <summary> /// [ REFS: '', DEREFS:] /// </summary> /// <param name="allProb"></param> /// <param name="state"></param> public double GetMaxProb(CUDDNode allProb, CUDDNode filter) { double result = 0; CUDD.Ref(filter, reach); CUDDNode newFilter = CUDD.Function.And(filter, reach); if (newFilter.Equals(CUDD.ZERO)) { result = double.MinValue; } else { CUDD.Ref(newFilter, allProb); CUDDNode tmp = CUDD.Function.ITE(newFilter, allProb, CUDD.MinusInfinity()); result = CUDD.FindMax(tmp); CUDD.Deref(tmp); } CUDD.Deref(newFilter); return(result); }
/// <summary> /// [ REFS: 'result', DEREFS: 'guardDDs, commandDDs' ] /// </summary> /// <param name="guardDDs"></param> /// <param name="commandDDs"></param> /// <param name="currentAvailStartBit"></param> /// <returns></returns> private ComponentDDs CombineNondetCommands(List <CUDDNode> guardDDs, List <CUDDNode> commandDDs, int currentAvailStartBit) { ComponentDDs compDDs; int i, j, maxChoices, numDDChoiceVarsUsed; CUDDNode covered, transDD, overlaps, guardHasIChoices, tmp; // create object to return result compDDs = new ComponentDDs(); // use 'transDD' to build up MTBDD for transitions transDD = CUDD.Constant(0); // use 'covered' to track states covered by guards covered = CUDD.Constant(0); // find overlaps in guards by adding them all up overlaps = CUDD.Constant(0); for (i = 0; i < guardDDs.Count; i++) { CUDD.Ref(guardDDs[i]); overlaps = CUDD.Function.Plus(overlaps, guardDDs[i]); // compute bdd of all guards at same time CUDD.Ref(guardDDs[i]); covered = CUDD.Function.Or(covered, guardDDs[i]); } // find the max number of overlaps // (i.e. max number of nondet. choices) maxChoices = (int)Math.Round(CUDD.FindMax(overlaps)); // if all the guards were false, we're done already if (maxChoices == 0) { compDDs.guards = covered; compDDs.trans = transDD; compDDs.min = currentAvailStartBit; compDDs.max = currentAvailStartBit; CUDD.Deref(overlaps); CUDD.Deref(guardDDs, commandDDs); return(compDDs); } // likewise, if there are no overlaps, it's also pretty easy if (maxChoices == 1) { // add up dds for all commands for (i = 0; i < guardDDs.Count; i++) { // add up transitions CUDD.Ref(commandDDs[i]); transDD = CUDD.Function.Plus(transDD, commandDDs[i]); } compDDs.guards = covered; compDDs.trans = transDD; compDDs.min = currentAvailStartBit; compDDs.max = currentAvailStartBit; CUDD.Deref(overlaps); CUDD.Deref(guardDDs, commandDDs); return(compDDs); } // otherwise, it's a bit more complicated... // first, calculate how many dd vars will be needed //the indexes of these bits are: (currentLastBitForChoice + 1), (currentLastBitForChoice + 2), ... numDDChoiceVarsUsed = (int)Math.Ceiling(Math.Log(maxChoices, 2)); // select the variables we will use and put them in a JDDVars if (currentAvailStartBit + numDDChoiceVarsUsed - 1 >= choiceVars.Count) { throw new Exception("Insufficient BDD variables allocated for nondeterminism - please report this as a bug. Thank you."); } CUDDVars varForThisChoice = new CUDDVars(); for (i = 0; i < numDDChoiceVarsUsed; i++) { varForThisChoice.AddVar(choiceVars[currentAvailStartBit + i]); } // for each i (i = 1 ... max number of nondet. choices) for (i = 1; i <= maxChoices; i++) { // find sections of state space // which have exactly i nondet. choices in this module CUDD.Ref(overlaps); guardHasIChoices = CUDD.Convert.Equals(overlaps, i); // if there aren't any for this i, skip the iteration if (guardHasIChoices.Equals(CUDD.ZERO)) { CUDD.Deref(guardHasIChoices); continue; } //store guards satisfying the guardHasIChoices, and classify them List <CUDDNode> satisfiedGuards = new List <CUDDNode>(); //store the current number of commands satisfying the guard of the corresponding guard List <int> numberOfChoicesAdded = new List <int>(); // go thru each command of the module... for (j = 0; j < guardDDs.Count; j++) { // see if this command's guard overlaps with 'guardHasIChoices' CUDD.Ref(guardDDs[j], guardHasIChoices); tmp = CUDD.Function.And(guardDDs[j], guardHasIChoices); // if it does... if (!tmp.Equals(CUDD.ZERO)) { //find guard Index int guardIndex = -1; int choiceIndexForThisCommand = 0; for (int k = 0; k < satisfiedGuards.Count; k++) { if (satisfiedGuards[k].Equals(tmp)) { guardIndex = k; break; } } //if guard exists, then use the index from numberOfChoicesAdded, and increase it if (guardIndex >= 0) { choiceIndexForThisCommand = numberOfChoicesAdded[guardIndex]; numberOfChoicesAdded[guardIndex]++; } else { //if not exists, satisfiedGuards, numberOfChoicesAdded satisfiedGuards.Add(tmp); numberOfChoicesAdded.Add(1); } CUDD.Ref(commandDDs[j]); tmp = CUDD.Function.Times(tmp, commandDDs[j]); CUDDNode choiceIndexDD = CUDD.Matrix.SetVectorElement(CUDD.Constant(0), varForThisChoice, choiceIndexForThisCommand, 1); CUDD.Ref(tmp); transDD = CUDD.Function.Plus(transDD, CUDD.Function.Times(tmp, choiceIndexDD)); } CUDD.Deref(tmp); } // take the i bits out of 'overlaps' overlaps = CUDD.Function.Times(overlaps, CUDD.Function.Not(guardHasIChoices)); } // store result compDDs.guards = covered; compDDs.trans = transDD; compDDs.min = currentAvailStartBit; compDDs.max = currentAvailStartBit + numDDChoiceVarsUsed; CUDD.Deref(overlaps); CUDD.Deref(guardDDs, commandDDs); return(compDDs); }