public IModel Encode() { //get variable info from ModulesFile varList = new VariableList(modules); //Collect all sync label of all modules synchs = modules.GetAllSynchs().ToList(); AddVars(); //Create Expression Encoder, use the same copy of varList, variableEncoding expressionEncoder = new ExpressionToBDD(varList, variableEncoding); EncodeSystemDef(modules.systemDef); // get rid of any nondet dd variables not needed if (modules.modelType == ModelType.MDP) { CUDDNode tmp = CUDD.GetSupport(trans); tmp = CUDD.Abstract.ThereExists(tmp, allRowVars); tmp = CUDD.Abstract.ThereExists(tmp, allColVars); CUDDVars ddv = new CUDDVars(); while (!tmp.Equals(CUDD.ONE)) { ddv.AddVar(CUDD.Var(tmp.GetIndex())); tmp = tmp.GetThen(); } CUDD.Deref(tmp); allNondetVars.Deref(); allNondetVars = ddv; } init = GetInitState(); // CUDD.Deref(moduleRangeDDs, moduleIdentities, colVarRanges, syncVars, choiceVars); CUDD.Deref(moduleRowVars, moduleColVars, rowVars, colVars, new List <CUDDVars>() { globalRowVars, globalColVars, allSynchVars, allChoiceVars }); IModel result; if (modules.modelType == ModelType.DTMC) { // allNondetVars.Deref(); result = new ProbModel(trans, init, stateRewards, transRewards, allRowVars, allColVars, varList, allRowVarRanges, varIdentities, variableEncoding); } else { result = new NonDetModel(trans, init, stateRewards, transRewards, allRowVars, allColVars, allNondetVars, varList, allRowVarRanges, varIdentities, variableEncoding); } return(result); }
/// <summary> /// Add new not-global variable where row- and column- boolean variable are the same. /// This function is used to add BDD variables to encode event names /// </summary> /// <param name="name"></param> /// <param name="lower"></param> /// <param name="upper"></param> public void AddSingleCopyVar(string name, int lower, int upper) { varList.AddNewVariable(name, lower, upper); int numBits = varList.GetNumberOfBits(name); CUDDNode vr; CUDDVars rowVar = new CUDDVars(); for (int j = 0; j < numBits; j++) { vr = CUDD.Var(numverOfBoolVars++); rowVar.AddVar(vr); } this.rowVars.Add(rowVar); this.colVars.Add(rowVar); this.AllRowVars.AddVars(rowVar); this.AllColVars.AddVars(rowVar); this.AllEventVars.AddVars(rowVar); // used for unchanged variable in transition. CUDDNode identity = (numBits == 0) ? CUDD.Constant(1) : CUDD.Matrix.Identity(rowVar, rowVar); this.varIdentities.Add(identity); // CUDDNode expressionDD = CUDD.MINUS_INFINITY; CUDD.Ref(expressionDD); for (int i = lower; i <= upper; i++) { expressionDD = CUDD.Matrix.SetVectorElement(expressionDD, rowVar, i - lower, i); } this.variableEncoding.Add(expressionDD); }
private void GenerateGroundEffect(Dictionary <string, Ground <Predicate> > preGndPredDict) { CUDDVars oldVars = new CUDDVars(); CUDDVars newVars = new CUDDVars(); Dictionary <string, string> abstractParmMap = new Dictionary <string, string>(); //Console.WriteLine(" Ground action constant list count:{0}", gndAction.ConstantList.Count); for (int i = 0; i < ConstantList.Count; i++) { string abstractParm = Container.VariableList[i].Item1; string gndParm = ConstantList[i]; abstractParmMap.Add(abstractParm, gndParm); //Console.WriteLine(" Parameter:{0}, constant:{1}", abstractParm, gndParm); } foreach (var pair in Container.AbstractPredicateDict) { oldVars.AddVar(CUDD.Var(pair.Value.CuddIndex)); List <string> collection = new List <string>(); foreach (var parm in pair.Value.ParameterList) { collection.Add(abstractParmMap[parm]); } string gndPredFullName = VariableContainer.GetFullName(pair.Value.Predicate.Name, collection); Ground <Predicate> gndPred = preGndPredDict[gndPredFullName]; newVars.AddVar(CUDD.Var(gndPred.CuddIndex)); //Console.WriteLine(" old cuddIndex:{0}, new cuddIndex:{1}", pair.Value.CuddIndex, gndPred.CuddIndex); } foreach (var cEffect in Container.Effect) { CUDDNode abstractCondition = cEffect.Item1; CUDDNode gndCondition = CUDD.Variable.SwapVariables(abstractCondition, oldVars, newVars); CUDD.Ref(gndCondition); var gndLiteralList = new List <Tuple <Ground <Predicate>, bool> >(); var abstractLiteralList = cEffect.Item2; foreach (var abstractLiteral in abstractLiteralList) { List <string> collection = new List <string>(); foreach (var parm in abstractLiteral.Item1.ParameterList) { collection.Add(abstractParmMap[parm]); } string gndPredFullName = VariableContainer.GetFullName(abstractLiteral.Item1.Predicate.Name, collection); Ground <Predicate> gndPred = preGndPredDict[gndPredFullName]; var gndLiteral = new Tuple <Ground <Predicate>, bool>(gndPred, abstractLiteral.Item2); gndLiteralList.Add(gndLiteral); } var gndCEffect = new Tuple <CUDDNode, List <Tuple <Ground <Predicate>, bool> > >(gndCondition, gndLiteralList); _effect.Add(gndCEffect); } }
/// <summary> /// Add new local variable /// </summary> /// <param name="name"></param> /// <param name="lower"></param> /// <param name="upper"></param> public void AddLocalVar(string name, int lower, int upper) { varList.AddNewVariable(name, lower, upper); int numBits = varList.GetNumberOfBits(name); CUDDNode vr, vc; CUDDVars rowVar = new CUDDVars(); CUDDVars colVar = new CUDDVars(); for (int j = 0; j < numBits; j++) { vr = CUDD.Var(numverOfBoolVars++); vc = CUDD.Var(numverOfBoolVars++); rowVar.AddVar(vr); colVar.AddVar(vc); } this.rowVars.Add(rowVar); this.colVars.Add(colVar); this.AllRowVars.AddVars(rowVar); this.AllRowVarsExceptSingleCopy.AddVars(rowVar); this.AllColVars.AddVars(colVar); // used for unchanged variable in transition. CUDDNode identity = CUDD.Constant(0); for (int i = lower; i <= upper; i++) { identity = CUDD.Matrix.SetMatrixElement(identity, rowVar, colVar, i - lower, i - lower, 1); } this.varIdentities.Add(identity); // CUDDNode expressionDD = CUDD.MINUS_INFINITY; CUDD.Ref(expressionDD); for (int i = lower; i <= upper; i++) { expressionDD = CUDD.Matrix.SetVectorElement(expressionDD, rowVar, i - lower, i); } this.variableEncoding.Add(expressionDD); // CUDD.Ref(identity); allRowVarRanges = CUDD.Function.And(allRowVarRanges, CUDD.Abstract.ThereExists(identity, colVar)); CUDD.Ref(identity); colVarRanges.Add(CUDD.Abstract.ThereExists(identity, rowVar)); }
private void UpdateKnowledge(EventModel eventModel) { //Console.WriteLine("Enter update knowledge"); //CUDD.Ref(eventModel.KnowPrecondition); //Console.WriteLine("After ref know precondition"); //CUDDNode knowledgeWithPre = CUDD.Function.And(Knowledge, eventModel.KnowPrecondition); CUDD.Ref(eventModel.KnowPartialSsa); //Console.WriteLine("After ref know partial ssa"); CUDDNode knowledgeWithPssa = CUDD.Function.And(Knowledge, eventModel.KnowPartialSsa); //Console.WriteLine("After get knowledge with pre and partial ssa"); if (eventModel.KnowAffectedPredSet.Count != 0) { CUDDVars oldVars = new CUDDVars(); CUDDVars newVars = new CUDDVars(); foreach (var predicate in eventModel.KnowAffectedPredSet) { CUDDNode trueRestrictBy = CUDD.Var(predicate.PreviousCuddIndex); CUDD.Ref(trueRestrictBy); CUDD.Ref(knowledgeWithPssa); CUDDNode trueNode = CUDD.Function.Restrict(knowledgeWithPssa, trueRestrictBy); CUDDNode falseRestrictBy = CUDD.Function.Not(trueRestrictBy); CUDDNode falseNode = CUDD.Function.Restrict(knowledgeWithPssa, falseRestrictBy); knowledgeWithPssa = CUDD.Function.Or(trueNode, falseNode); oldVars.AddVar(CUDD.Var(predicate.SuccessiveCuddIndex)); newVars.AddVar(CUDD.Var(predicate.PreviousCuddIndex)); } Knowledge = CUDD.Variable.SwapVariables(knowledgeWithPssa, oldVars, newVars); oldVars.Deref(); newVars.Deref(); } else { Knowledge = knowledgeWithPssa; } //Console.WriteLine("Whether knowledge is equal to false: {0}", Knowledge.Equals(CUDD.ZERO)); //Console.WriteLine("Finish!"); }
private void GenerateGroundPrecondition(Dictionary <string, Ground <Predicate> > preGndPredDict) { CUDDVars oldVars = new CUDDVars(); CUDDVars newVars = new CUDDVars(); Dictionary <string, string> abstractParmMap = new Dictionary <string, string>(); //Console.WriteLine(" Ground action constant list count:{0}", gndAction.ConstantList.Count); for (int i = 0; i < ConstantList.Count; i++) { string abstractParm = Container.VariableList[i].Item1; string gndParm = ConstantList[i]; abstractParmMap.Add(abstractParm, gndParm); //Console.WriteLine(" Parameter:{0}, constant:{1}", abstractParm, gndParm); } foreach (var pair in Container.AbstractPredicateDict) { oldVars.AddVar(CUDD.Var(pair.Value.CuddIndex)); List <string> collection = new List <string>(); foreach (var parm in pair.Value.ParameterList) { collection.Add(abstractParmMap[parm]); } Ground <Predicate> gndPred = new Ground <Predicate>(pair.Value.Predicate, collection); gndPred = preGndPredDict[gndPred.ToString()]; newVars.AddVar(CUDD.Var(gndPred.CuddIndex)); } CUDDNode abstractPre = Container.Precondition; Precondition = CUDD.Variable.SwapVariables(abstractPre, oldVars, newVars); //Console.WriteLine(" Ground precondition:"); //CUDD.Print.PrintMinterm(gndAction.Precondition); //CUDDNode abstractEff = gndAction.VariableContainer.Effect; //gndAction.VariableContainer.Effect = CUDD.Variable.SwapVariables(abstractEff, oldVars, newVars); }
private void UpdateBelief(CUDDNode partialSsa, HashSet <Predicate> affectedPredSet) { //CUDD.Ref(precondition); //CUDDNode beliefWithPre = CUDD.Function.And(Belief, precondition); CUDD.Ref(partialSsa); CUDDNode beliefWithPssa = CUDD.Function.And(Belief, partialSsa); if (affectedPredSet.Count != 0) { CUDDVars oldVars = new CUDDVars(); CUDDVars newVars = new CUDDVars(); foreach (var predicate in affectedPredSet) { CUDDNode trueRestrictBy = CUDD.Var(predicate.PreviousCuddIndex); CUDD.Ref(trueRestrictBy); CUDD.Ref(beliefWithPssa); CUDDNode trueNode = CUDD.Function.Restrict(beliefWithPssa, trueRestrictBy); CUDDNode falseRestrictBy = CUDD.Function.Not(trueRestrictBy); CUDDNode falseNode = CUDD.Function.Restrict(beliefWithPssa, falseRestrictBy); beliefWithPssa = CUDD.Function.Or(trueNode, falseNode); oldVars.AddVar(CUDD.Var(predicate.SuccessiveCuddIndex)); newVars.AddVar(CUDD.Var(predicate.PreviousCuddIndex)); } Belief = CUDD.Variable.SwapVariables(beliefWithPssa, oldVars, newVars); oldVars.Deref(); newVars.Deref(); } else { Belief = beliefWithPssa; } //Console.WriteLine("Whether belief is equal to false: {0}", Belief.Equals(CUDD.ZERO)); //Console.WriteLine("Finish!"); }
/// <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); }
public static double[] Jacobi(double[][] A, double[] b, double[] init) { CUDD.InitialiseCUDD(2048 * 1024, Math.Pow(10, -15)); if (!(A.Length == b.Length && b.Length == init.Length & A.Length > 0)) { throw new Exception("Wrong format"); } int rowSize = A.Length; int colSize = A[0].Length; CUDDVars rowVars = new CUDDVars(); CUDDVars colVars = new CUDDVars(); int numverOfBoolVars = 0; //Create bits for row index int numberOfBitForRow = (int)Math.Ceiling(Math.Log(rowSize, 2)); for (int i = 0; i < numberOfBitForRow; i++) { CUDDNode v = CUDD.Var(numverOfBoolVars++); rowVars.AddVar(v); } //Create bits for col index int numberOfBitForCol = (int)Math.Ceiling(Math.Log(colSize, 2)); for (int i = 0; i < numberOfBitForCol; i++) { CUDDNode v = CUDD.Var(numverOfBoolVars++); colVars.AddVar(v); } //Convert matrix to BDD CUDDNode matrixA = CUDD.Constant(0); for (int i = 0; i < A.Length; i++) { for (int j = 0; j < A[i].Length; j++) { if (A[i][j] != 0) { CUDD.Matrix.SetMatrixElement(matrixA, rowVars, colVars, i, j, A[i][j]); } } } //Convert vector to BDD CUDDNode vectorB = CUDD.Constant(0); for (int i = 0; i < b.Length; i++) { if (b[i] != 0) { CUDD.Matrix.SetVectorElement(vectorB, rowVars, i, b[i]); } } //Set reach state CUDDNode reach = CUDD.Constant(0); for (int i = 0; i < rowSize; i++) { CUDD.Matrix.SetVectorElement(reach, rowVars, i, 1); } CUDDNode vectorInit = CUDD.Constant(0); for (int i = 0; i < init.Length; i++) { if (init[i] != 0) { CUDD.Matrix.SetVectorElement(vectorInit, rowVars, i, init[i]); } } CUDDNode result = Jacobi(matrixA, vectorB, vectorInit, reach, rowVars, colVars, 1); double[] solution = new double[colSize]; for (int i = 0; i < colSize; i++) { solution[i] = CUDD.Matrix.GetVectorElement(result, rowVars, i); } return(solution); }