/// <summary> /// (dd && list[0]) || (dd && list[1]) ... /// [ REFS: 'result', DEREFS: dd, list ] /// </summary> /// <param name="dd"></param> /// <param name="list"></param> /// <returns></returns> public static CUDDNode And(CUDDNode dd, List<CUDDNode> list) { CUDDNode result = CUDD.Constant(0); foreach (CUDDNode dd1 in list) { CUDD.Ref(dd); CUDDNode temp = CUDD.Function.And(dd, dd1); result = CUDD.Function.Or(result, temp); } CUDD.Deref(dd); return result; }
public static CUDDNode NondetBoundedUntil(CUDDNode trans, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, CUDDNode yes, CUDDNode maybe, int bound, bool min) { DateTime startTime = DateTime.Now; CUDDNode a, sol, tmp; CUDD.Ref(trans, maybe); a = CUDD.Function.Times(trans, maybe); CUDD.Ref(yes); sol = yes; for (int i = 0; i < bound; i++) { tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); if (min) { CUDD.Ref(nondetMask); tmp = CUDD.Function.Maximum(tmp, nondetMask); tmp = CUDD.Abstract.MinAbstract(tmp, nondetVars); } else { tmp = CUDD.Abstract.MaxAbstract(tmp, nondetVars); } CUDD.Ref(yes); tmp = CUDD.Function.Maximum(tmp, yes); CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("NondetBoundedUntil: " + bound + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a); return sol; }
public static CUDDNode NondetInstReward(CUDDNode trans, CUDDNode stateReward, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, int bound, bool min, CUDDNode init) { DateTime startTime = DateTime.Now; CUDDNode newNondetMask, sol, tmp; CUDD.Ref(nondetMask); newNondetMask = CUDD.Function.ITE(nondetMask, CUDD.PlusInfinity(), CUDD.Constant(0)); CUDD.Ref(stateReward); sol = stateReward; for(int i = 0; i < bound; i++) { tmp = CUDD.Matrix.MatrixMultiplyVector(trans, sol, allRowVars, allColVars); if(min) { CUDD.Ref(newNondetMask); tmp = CUDD.Function.Maximum(tmp, newNondetMask); tmp = CUDD.Abstract.MinAbstract(tmp, nondetVars); } else { tmp = CUDD.Abstract.MaxAbstract(tmp, nondetVars); } // CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("NondetInstReward: " + bound + " iterations in " + runningTime + " seconds"); // CUDD.Deref(newNondetMask); return sol; }
/// <summary> /// Print vector dd, suppos that all variables supporting dd belong to vars /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintVector(CUDDNode dd, CUDDVars vars) { PlatformInvoke.DD_PrintVector(manager, dd.Ptr, vars.GetArrayPointer(), vars.GetNumVars(), LOW); }
/// <summary> /// At each terminal, return dd1 if dd1 >= dd2; 0 if dd1 < dd2 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode Threshold(CUDDNode dd1, CUDDNode dd2) { return new CUDDNode(PlatformInvoke.DD_Thresholds(manager, dd1.Ptr, dd2.Ptr)); }
/// <summary> /// Restrict a node according to the cube of variables. /// [ REFS: 'result', DEREFS: dd, cube ] /// </summary> public static CUDDNode Restrict(CUDDNode dd, CUDDNode cube) { return new CUDDNode(PlatformInvoke.DD_Restrict(manager, dd.Ptr, cube.Ptr)); }
public static CUDDNode NondetUntil(CUDDNode trans, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, CUDDNode yes, CUDDNode maybe, bool min) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDDNode a, sol, tmp; CUDD.Ref(trans, maybe); a = CUDD.Function.Times(trans, maybe); CUDD.Ref(yes); sol = yes; while (true) { numberOfIterations++; tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); if (min) { CUDD.Ref(nondetMask); tmp = CUDD.Function.Maximum(tmp, nondetMask); tmp = CUDD.Abstract.MinAbstract(tmp, nondetVars); } else { tmp = CUDD.Abstract.MaxAbstract(tmp, nondetVars); } CUDD.Ref(yes); tmp = CUDD.Function.Maximum(tmp, yes); //check convergence if(CUDD.IsEqual(tmp, sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("NondetUntil: " + numberOfIterations + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a); return sol; }
/// <summary> /// Forward search, check destination is reachable from source /// Store all reachable states and check fix point /// At step t, find all reachable states after t time units /// Fix point: rechable(0, t) == rechable(0, t + 1) /// (S x Tick x Trans*)* /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="discreteTransitions"></param> /// <returns></returns> public bool PathForward1(CUDDNode source, CUDDNode destination, List<CUDDNode> discreteTransitions, List<CUDDNode> tickTransitions, bool simulationUsed, CUDDNode simulationRel) { numLoopDiscrete = 0; // bool reachable = false; CUDD.Ref(source); CUDDNode allReachableFromInit = (simulationUsed) ? SuccessorsStartWithSimulation(source, discreteTransitions, simulationRel) : SuccessorsStart(source, discreteTransitions); CUDD.Ref(allReachableFromInit); CUDDNode currentReachableFromInit = allReachableFromInit; CUDDNode commonNode = CUDD.Constant(0); int numberOfLoop = 0; do { numberOfLoop++; Debug.Write(numberOfLoop + " "); currentReachableFromInit = Successors(currentReachableFromInit, tickTransitions); currentReachableFromInit = (simulationUsed)? SuccessorsStartWithSimulation(currentReachableFromInit, discreteTransitions, simulationRel): SuccessorsStart(currentReachableFromInit, discreteTransitions); //Check 2 directions have intersection CUDD.Ref(destination, currentReachableFromInit); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(destination, currentReachableFromInit); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } //find fixpoint CUDD.Ref(currentReachableFromInit, allReachableFromInit); CUDDNode allReachabeFromInitTemp = CUDD.Function.Or(currentReachableFromInit, allReachableFromInit); if (allReachabeFromInitTemp.Equals(allReachableFromInit)) { //reachable = false; CUDD.Deref(allReachabeFromInitTemp); break; } else { currentReachableFromInit = CUDD.Function.Different(currentReachableFromInit, allReachableFromInit); allReachableFromInit = allReachabeFromInitTemp; } } while (true); Debug.WriteLine("\nTA Path Forward 1: " + (numberOfLoop + 1) + " loops."); Debug.WriteLine("Discrete loops: " + numLoopDiscrete); Debug.WriteLine("Avarage Discrete loops: " + ((double) numLoopDiscrete/(numberOfLoop + 1))); CUDD.Deref(allReachableFromInit, currentReachableFromInit, commonNode); if(simulationUsed) { CUDD.Deref(simulationRel); } // return reachable; }
/// <summary> /// Return (f and g) abstract vars /// [ REFS: 'result', DEREFS: f ] /// </summary> public static CUDDNode MinAbstract(CUDDNode f, CUDDVars vars) { return new CUDDNode(PlatformInvoke.DD_MinAbstract(manager, f.Ptr, vars.GetArrayPointer(), vars.GetNumVars())); }
/// <summary> /// Solve the linear equation system Ax = b with Jacobi /// Sometimes we can use Jacobi to solve the recursive definition /// x = Ax + b. We will convert this to (I - A)x = b and use Jacobi to solve. /// Experiments show that Jacobi converges faster /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="init">initial solution</param> /// <param name="reach"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="omega">jor parameter</param> /// <returns></returns> public static CUDDNode Jacobi(CUDDNode a, CUDDNode b, CUDDNode init, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, double omega) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDDNode id = CUDD.Matrix.Identity(allRowVars, allColVars); CUDD.Ref(reach); id = CUDD.Function.And(id, reach); CUDD.Ref(id, a); CUDDNode diags = CUDD.Function.Times(id, a); diags = CUDD.Abstract.SumAbstract(diags, allColVars); // CUDD.Ref(id, a); CUDDNode newA = CUDD.Function.ITE(id, CUDD.Constant(0), a); newA = CUDD.Function.Times(CUDD.Constant(-1), newA); // divide a,b by diagonal CUDD.Ref(diags); newA = CUDD.Function.Divide(newA, diags); CUDD.Ref(b, diags); CUDDNode newB = CUDD.Function.Divide(b, diags); // print out some memory usage Debug.WriteLine("Iteration matrix MTBDD... [nodes = " + CUDD.GetNumNodes(newA) + "]"); Debug.WriteLine("Diagonals MTBDD... [nodes = " + CUDD.GetNumNodes(diags) + "]"); CUDD.Ref(init); CUDDNode sol = init; while(true) { numberOfIterations++; CUDDNode tmp = CUDD.Matrix.MatrixMultiplyVector(newA, sol, allRowVars, allColVars); CUDD.Ref(newB); tmp = CUDD.Function.Plus(tmp, newB); if(omega != 1) { tmp = CUDD.Function.Times(tmp, CUDD.Constant(omega)); CUDD.Ref(sol); tmp = CUDD.Function.Plus(tmp, CUDD.Function.Times(sol, CUDD.Constant(1 - omega))); } if(CUDD.IsEqual(tmp, sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } CUDD.Deref(id, diags, newA, newB); DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("Jacobi: " + numberOfIterations + " iterations in " + runningTime + " seconds"); return sol; }
/// <summary> /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="trans"></param> /// <param name="stateReward"></param> /// <param name="transReward"></param> /// <param name="reach"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="maybe"></param> /// <param name="inf"></param> /// <returns></returns> public static CUDDNode ProbReachReward(CUDDNode trans, CUDDNode stateReward, CUDDNode transReward, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, CUDDNode maybe, CUDDNode inf) { CUDD.Ref(trans, maybe); CUDDNode a = CUDD.Function.Times(trans, maybe); CUDD.Ref(stateReward, maybe); CUDDNode newStateReward = CUDD.Function.Times(stateReward, maybe); CUDD.Ref(transReward, a); CUDDNode newTransRewards = CUDD.Function.Times(transReward, a); newTransRewards = CUDD.Abstract.SumAbstract(newTransRewards, allColVars); CUDDNode allReward = CUDD.Function.Plus(newStateReward, newTransRewards); // CUDDNode tmp = CUDD.Matrix.Identity(allRowVars, allColVars); CUDD.Ref(reach); tmp = CUDD.Function.And(tmp, reach); a = CUDD.Function.Minus(tmp, a); CUDDNode sol = Jacobi(a, allReward, allReward, reach, allRowVars, allColVars, 1); // set reward for infinity states to infinity CUDD.Ref(inf); sol = CUDD.Function.ITE(inf, CUDD.PlusInfinity(), sol); // CUDD.Deref(a, allReward); return sol; }
/// <summary> /// Return string of number of nodes, terminals, minterms /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static string GetInfoBriefString(CUDDNode dd, int numVars) { return("[" + GetNumNodes(dd) + "," + GetNumTerminals(dd) + "," + GetNumMinterms(dd, numVars) + "]"); }
/// <summary> /// Print the variables on which a DD depends. /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintSupport(CUDDNode dd) { PlatformInvoke.DD_PrintSupport(manager, dd.Ptr); }
/// <summary> /// Return string of number of nodes, terminals, minterms /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static string GetInfoString(CUDDNode dd, int numVars) { return(GetNumNodes(dd) + " nodes (" + GetNumTerminals(dd) + " terminal), " + GetNumMinterms(dd, numVars) + " minterms"); }
/// <summary> /// Print about number of nodes, terminals, minterms /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintInfoBrief(CUDDNode dd, int numVars) { PlatformInvoke.DD_PrintInfoBrief(manager, dd.Ptr, numVars); }
public static int PrintBDDTree(CUDDNode node, string filename = "BDDTree.dot") { return(PlatformInvoke.Cudd_PrintBDDTree(manager, node.Ptr, filename)); }
/// <summary> /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintTerminalsAndNumbers(CUDDNode dd, int numVars) { PlatformInvoke.DD_PrintTerminalsAndNumbers(manager, dd.Ptr, numVars); }
/// <summary> /// Print terminals of DD /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintTerminals(CUDDNode dd) { PlatformInvoke.DD_PrintTerminals(manager, dd.Ptr); }
/// <summary> /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="trans"></param> /// <param name="stateReward"></param> /// <param name="transReward"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="bound"></param> /// <returns></returns> public static CUDDNode ProbCumulReward(CUDDNode trans, CUDDNode stateReward, CUDDNode transReward, CUDDVars allRowVars, CUDDVars allColVars, int bound) { DateTime startTime = DateTime.Now; // multiply transition rewards by transition probs and sum rows // then combine state and transition rewards and put in a vector CUDD.Ref(transReward, trans); CUDDNode allReward = CUDD.Function.Times(transReward, trans); allReward = CUDD.Abstract.SumAbstract(allReward, allColVars); CUDD.Ref(stateReward); allReward = CUDD.Function.Plus(stateReward, allReward); // initial solution is zero CUDDNode sol = CUDD.Constant(0); for (int i = 0; i < bound; i++) { CUDDNode tmp = CUDD.Matrix.MatrixMultiplyVector(trans, sol, allRowVars, allColVars); // add in (combined state and transition) rewards CUDD.Ref(allReward); tmp = CUDD.Function.Plus(tmp, allReward); CUDD.Deref(sol); sol = tmp; } // CUDD.Deref(allReward); DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("ProbCumulReward: " + bound + " iterations in " + runningTime + " seconds"); // return sol; }
/// <summary> /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintMatrix(CUDDNode dd, CUDDVars rVars, int numRowVars, CUDDVars cVars, int numColVars, int accuracy) { PlatformInvoke.DD_PrintMatrix(manager, dd.Ptr, rVars.GetArrayPointer(), numRowVars, cVars.GetArrayPointer(), numColVars, accuracy); }
/// <summary> /// Forward search, check destination is reachable from source /// NOT store all reachable states, use some special condition to terminate /// At step t, find all reachable states after t time units /// Fix point when rechable(t1 + a, t1 + a) is a subset of rechable(t1, t1) /// Rabbit algorithm (S x Tick x Trans*)* /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="discreteTransitions"></param> /// <returns></returns> public bool PathForward2(CUDDNode source, CUDDNode destination, List<CUDDNode> discreteTransitions, List<CUDDNode> tickTransitions) { // bool reachable = false; CUDD.Ref(source); CUDDNode currentReachableFromInit = SuccessorsStart(source, discreteTransitions); CUDDNode previousReachableFromInit = CUDD.Constant(0); int s, p; s = p = 0; CUDDNode commonNode = CUDD.Constant(0); int numberOfLoop = 0; while (!CUDD.IsSubSet(previousReachableFromInit, currentReachableFromInit)) { numberOfLoop++; Debug.Write(numberOfLoop + " "); if(p <= s/2) { p = s; CUDD.Deref(previousReachableFromInit); CUDD.Ref(currentReachableFromInit); previousReachableFromInit = currentReachableFromInit; } currentReachableFromInit = Successors(currentReachableFromInit, tickTransitions); currentReachableFromInit = SuccessorsStart(currentReachableFromInit, discreteTransitions); s++; //Check 2 directions have intersection CUDD.Ref(destination, currentReachableFromInit); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(destination, currentReachableFromInit); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } } Debug.WriteLine("\nTA Path Forward 2: " + numberOfLoop + " loops."); CUDD.Deref(currentReachableFromInit, previousReachableFromInit, commonNode); // return reachable; }
/// <summary> /// return 1 if node1 is 1 and node2 is 0, others return 0. /// belong dd1 but not belong dd2 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode Different(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_Different(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// [ REFS: 'result', DEREFS: states] /// </summary> /// <param name="states"></param> /// <param name="simulationRel"></param> /// <returns></returns> private CUDDNode GetSimulatedStates(CUDDNode states, CUDDNode simulationRel) { CUDD.Ref(simulationRel); return CUDD.Abstract.ThereExists(CUDD.Function.And(SwapRowColVars(states), simulationRel), AllColVars); }
/// <summary> /// Return the ratio ADD of dd1, dd2 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode BitwiseOr(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_BitwiseOr(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// Or Abstract variables in vars, dd must be 0-1 ADD. /// result will not contain boolean variables in vars /// [ REFS: 'result', DEREFS: dd ] /// </summary> public static CUDDNode ThereExists(CUDDNode dd, CUDDVars vars) { return new CUDDNode(PlatformInvoke.DD_ThereExists(manager, dd.Ptr, vars.GetArrayPointer(), vars.GetNumVars())); }
/// <summary> /// At each terminal, return 1 if dd1 > dd2; 0 otherwise /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode Greater(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_ApplyGreater(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// Return Pmin(phi1 U phi2) = 1 /// </summary> /// <param name="trans01"></param> /// <param name="reach"></param> /// <param name="nondetMask"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="nondetVar"></param> /// <param name="no"></param> /// <param name="b2"></param> /// <returns></returns> public static CUDDNode Prob1A(CUDDNode trans01, CUDDNode reach, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVar, CUDDNode no, CUDDNode b2) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDD.Ref(reach, no); CUDDNode notNo = CUDD.Function.And(reach, CUDD.Function.Not(no)); CUDD.Ref(b2, notNo); CUDDNode sol = CUDD.Function.Or(b2, notNo); while (true) { numberOfIterations++; CUDD.Ref(sol); CUDDNode tmp = CUDD.Variable.SwapVariables(sol, allRowVars, allColVars); CUDD.Ref(trans01); tmp = CUDD.Abstract.ForAll(CUDD.Function.Implies(trans01, tmp), allColVars); CUDD.Ref(nondetMask); tmp = CUDD.Function.Or(tmp, nondetMask); tmp = CUDD.Abstract.ForAll(tmp, nondetVar); CUDD.Ref(notNo); tmp = CUDD.Function.And(notNo, tmp); CUDD.Ref(b2); tmp = CUDD.Function.Or(b2, tmp); if (tmp.Equals(sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("Prob1A: " + numberOfIterations + " iterations in " + runningTime + " seconds"); // CUDD.Deref(notNo); return sol; }
/// <summary> /// At each terminal, return 1 if dd1 <= dd2; 0 otherwise /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode LessEqual(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_ApplyLessEqual(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintMinterm(CUDDNode dd) { Console.WriteLine("--------------------------Start"); PlatformInvoke.Cudd_PrintMinterm(manager, dd.Ptr); Console.WriteLine("--------------------------End"); }
/// <summary> /// At each terminal, return dd1 if dd1 >= dd2; 0 if dd1 < dd2 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode Threshold(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_Thresholds(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// Rounds off the discriminants of an ADD. The discriminants are rounded off to N digits after the decimal. /// [ REFS: 'result', DEREFS: dd ] /// </summary> public static CUDDNode RoundOff(CUDDNode dd, int numberOfDigits) { return new CUDDNode(PlatformInvoke.DD_RoundOff(manager, dd.Ptr, numberOfDigits)); }
/// <summary> /// Natural logarithm of an ADD /// [ REFS: 'result', DEREFS: dd] /// </summary> public static CUDDNode Log(CUDDNode dd) { return(new CUDDNode(PlatformInvoke.DD_Log(manager, dd.Ptr))); }
/// <summary> /// Xor 0-1 ADDs, difficult to know the result if not 0-1 ADDs, refer the C++ code /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode Xor(CUDDNode dd1, CUDDNode dd2) { return new CUDDNode(PlatformInvoke.DD_Xor(manager, dd1.Ptr, dd2.Ptr)); }
/// <summary> /// Restrict a node according to the cube of variables. /// [ REFS: 'result', DEREFS: dd, cube ] /// </summary> public static CUDDNode Restrict(CUDDNode dd, CUDDNode cube) { return(new CUDDNode(PlatformInvoke.DD_Restrict(manager, dd.Ptr, cube.Ptr))); }
/// <summary> /// (dd && list[0]) || (dd && list[1]) ... /// [ REFS: 'result', DEREFS: dd, list ] /// </summary> /// <param name="dd"></param> /// <param name="list"></param> /// <returns></returns> public static List<CUDDNode> And(List<CUDDNode> list, CUDDNode dd) { List<CUDDNode> result = new List<CUDDNode>(); foreach (CUDDNode dd1 in list) { CUDD.Ref(dd); CUDDNode temp = CUDD.Function.And(dd, dd1); if (temp.Equals(CUDD.ZERO)) { CUDD.Deref(temp); } else { result.Add(temp); } } CUDD.Deref(dd); return result; }
/// <summary> /// Create node with root node dd1, its then node is dd2 and its else node is dd3. /// This procedure assumes that dd1 is a 0-1 ADD. /// [ REFS: 'result', DEREFS: dd1, dd2, dd3 ]. /// </summary> public static CUDDNode ITE(CUDDNode dd1, CUDDNode dd2, CUDDNode dd3) { return(new CUDDNode(PlatformInvoke.DD_ITE(manager, dd1.Ptr, dd2.Ptr, dd3.Ptr))); }
/// <summary> /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="trans"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="yes"></param> /// <param name="maybe"></param> /// <param name="bound"></param> /// <returns></returns> public static CUDDNode ProbBoundedUntil(CUDDNode trans, CUDDVars allRowVars, CUDDVars allColVars, CUDDNode yes, CUDDNode maybe, int bound) { DateTime startTime = DateTime.Now; CUDDNode a, sol, tmp; CUDD.Ref(trans, maybe); a = CUDD.Function.Times(trans, maybe); CUDD.Ref(yes); sol = yes; for (int i = 1; i <= bound; i++) { tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); CUDD.Ref(yes); tmp = CUDD.Function.Maximum(tmp, yes); CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("ProbBoundedUntil: " + bound + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a); return sol; }
/// <summary> /// At each terminal, return dd1 % dd2, non-negative when dd2 > 0 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode ModuloNonNegative(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_ModuloNonNegative(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="trans"></param> /// <param name="stateReward"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="bound"></param> /// <returns></returns> public static CUDDNode ProbInstReward(CUDDNode trans, CUDDNode stateReward, CUDDVars allRowVars, CUDDVars allColVars, int bound) { DateTime startTime = DateTime.Now; // initial solution is the state rewards CUDD.Ref(stateReward); CUDDNode sol = stateReward; for (int iters = 0; iters < bound; iters++) { CUDDNode tmp = CUDD.Matrix.MatrixMultiplyVector(trans, sol, allRowVars, allColVars); CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("ProbInstReward: " + bound + " iterations in " + runningTime + " seconds"); return sol; }
/// <summary> /// Rounds off the discriminants of an ADD. The discriminants are rounded off to N digits after the decimal. /// [ REFS: 'result', DEREFS: dd ] /// </summary> public static CUDDNode RoundOff(CUDDNode dd, int numberOfDigits) { return(new CUDDNode(PlatformInvoke.DD_RoundOff(manager, dd.Ptr, numberOfDigits))); }
/// <summary> /// [ REFS: 'result', DEREFS: ] /// </summary> /// <param name="trans"></param> /// <param name="reach"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="yes"></param> /// <param name="maybe"></param> /// <returns></returns> public static CUDDNode ProbUntil(CUDDNode trans, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, CUDDNode yes, CUDDNode maybe) { CUDD.Ref(trans, maybe); CUDDNode a = CUDD.Function.Times(trans, maybe); CUDDNode tmp = CUDD.Matrix.Identity(allRowVars, allColVars); CUDD.Ref(reach); tmp = CUDD.Function.And(tmp, reach); a = CUDD.Function.Minus(tmp, a); CUDD.Ref(yes); CUDDNode b = yes; CUDDNode sol = Jacobi(a, b, b, reach, allRowVars, allColVars, 1); CUDD.Deref(a, b); return sol; }
/// <summary> /// And 0-1 ADDs, difficult to know the result if not 0-1 ADDs, refer the C++ code /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode And(CUDDNode dd1, CUDDNode dd2) { return(new CUDDNode(PlatformInvoke.DD_And(manager, dd1.Ptr, dd2.Ptr))); }
/// <summary> /// Forward search, check destination is reachable from source /// (S x (Tick + Trans)*) /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="transitions"></param> /// <returns></returns> public bool PathForward3(CUDDNode source, CUDDNode destination, List<CUDDNode> transitions) { // bool reachable = false; CUDDNode allReachableFromInit, currentReachableFromInit; CUDD.Ref(source, source); allReachableFromInit = currentReachableFromInit = source; CUDDNode commonNode = CUDD.Constant(0); int numberOfLoop = 0; do { numberOfLoop++; Debug.Write(numberOfLoop + " "); currentReachableFromInit = Successors(currentReachableFromInit, transitions); //Check 2 directions have intersection CUDD.Ref(destination, currentReachableFromInit); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(destination, currentReachableFromInit); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } //find fixpoint CUDD.Ref(currentReachableFromInit, allReachableFromInit); CUDDNode allReachabeFromInitTemp = CUDD.Function.Or(currentReachableFromInit, allReachableFromInit); if (allReachabeFromInitTemp.Equals(allReachableFromInit)) { //reachable = false; CUDD.Deref(allReachabeFromInitTemp); break; } else { currentReachableFromInit = CUDD.Function.Different(currentReachableFromInit, allReachableFromInit); allReachableFromInit = allReachabeFromInitTemp; } } while (true); Debug.WriteLine("\nTA Path Forward 3: " + numberOfLoop + " loops."); CUDD.Deref(allReachableFromInit, currentReachableFromInit, commonNode); // return reachable; }
/// <summary> /// Increases the reference count of a node, if it is not saturated /// [ REFS: dd, DEREFS: 'none' ] /// </summary> public static void Ref(CUDDNode dd) { PlatformInvoke.Cudd_Ref(dd.Ptr); }
/// <summary> /// return all states reachable from start and Start /// P ◦ R* /// [ REFS: 'result', DEREFS:start] /// </summary> /// <param name="start"></param> /// <param name="transition"></param> /// <returns></returns> public CUDDNode SuccessorsStartWithSimulation(CUDDNode start, List<CUDDNode> transition, CUDDNode simulationRel) { CUDDNode allReachableStates = GetSimulatedStates(start, simulationRel); CUDD.Ref(allReachableStates); CUDDNode currentStep = allReachableStates; int numberOfLoop = 0; while (true) { numberOfLoop++; Debug.Write(numberOfLoop + " "); currentStep = Successors(currentStep, transition); currentStep = GetSimulatedStates(currentStep, simulationRel); CUDD.Ref(allReachableStates, currentStep); CUDDNode allReachableTemp = CUDD.Function.Or(allReachableStates, currentStep); if (allReachableTemp.Equals(allReachableStates)) { CUDD.Deref(currentStep, allReachableTemp); numLoopDiscrete += numberOfLoop; Debug.WriteLine("\nSuccessor*: " + numberOfLoop + " loops."); return allReachableStates; } else { currentStep = CUDD.Function.Different(currentStep, allReachableStates); allReachableStates = allReachableTemp; } } }
/// <summary> /// Decreases the reference count of node /// [ REFS: 'none', DEREFS: dd ] /// </summary> public static void Deref(CUDDNode dd) { PlatformInvoke.Cudd_RecursiveDeref(manager, dd.Ptr); }
public CUDDNode(CUDDNode dd) { this.Ptr = dd.Ptr; }
/// <summary> /// Return max of ADD /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static double FindMax(CUDDNode dd) { return(PlatformInvoke.DD_FindMax(manager, dd.Ptr)); }
/// <summary> /// Sum (ie. +) Abstract variables in vars /// [ REFS: 'result', DEREFS: dd ] /// </summary> public static CUDDNode SumAbstract(CUDDNode dd, CUDDVars vars) { return new CUDDNode(PlatformInvoke.DD_SumAbstract(manager, dd.Ptr, vars.GetArrayPointer(), vars.GetNumVars())); }
/// <summary> /// Return the first cube making the ADD not 0 /// [ REFS: 'result', DEREFS: 'dd' ] /// </summary> public static CUDDNode RestrictToFirst(CUDDNode dd, CUDDVars vars) { return(new CUDDNode(PlatformInvoke.DD_RestrictToFirst(manager, dd.Ptr, vars.GetArrayPointer(), vars.GetNumVars()))); }
/// <summary> /// Return number of terminals /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static int GetNumTerminals(CUDDNode dd) { return(PlatformInvoke.DD_GetNumTerminals(manager, dd.Ptr)); }
/// <summary> /// Return number of minterm which made the ADD != 0 /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static double GetNumMinterms(CUDDNode dd, int numVars) { return(PlatformInvoke.DD_GetNumMinterms(manager, dd.Ptr, numVars)); }
/// <summary> /// Return Pmax(b1 U b2) = 0 /// </summary> /// <param name="trans01"></param> /// <param name="reach"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="nondetvars"></param> /// <param name="b1"></param> /// <param name="b2"></param> /// <returns></returns> public static CUDDNode Prob0A(CUDDNode trans01, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetvars, CUDDNode b1, CUDDNode b2) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDD.Ref(b2); CUDDNode sol = b2; while (true) { numberOfIterations++; CUDD.Ref(sol, trans01); CUDDNode tmp = CUDD.Function.And(CUDD.Variable.SwapVariables(sol, allRowVars, allColVars), trans01); tmp = CUDD.Abstract.ThereExists(tmp, allColVars); tmp = CUDD.Abstract.ThereExists(tmp, nondetvars); CUDD.Ref(b1); tmp = CUDD.Function.And(b1, tmp); CUDD.Ref(b2); tmp = CUDD.Function.Or(b2, tmp); if (tmp.Equals(sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } CUDD.Ref(reach); sol = CUDD.Function.And(reach, CUDD.Function.Not(sol)); DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("Prob0A: " + numberOfIterations + " iterations in " + runningTime + " seconds"); return sol; }
/// <summary> /// Return the complement of node /// [ REFS: 'result', DEREFS: 'dd' ] /// </summary> public static CUDDNode Not(CUDDNode dd) { return new CUDDNode(PlatformInvoke.DD_Not(manager, dd.Ptr)); }
/// <summary> /// return Pmax(b1 U b2) = 1 /// </summary> /// <param name="trans01"></param> /// <param name="reach"></param> /// <param name="allRowVars"></param> /// <param name="allColVars"></param> /// <param name="nondetVars"></param> /// <param name="b1"></param> /// <param name="b2"></param> /// <param name="no"></param> /// <returns></returns> public static CUDDNode Prob1E(CUDDNode trans01, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, CUDDNode b1, CUDDNode b2, CUDDNode no) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDD.Ref(reach, no); CUDDNode u = CUDD.Function.And(reach, CUDD.Function.Not(no)); bool uDone = false; while (!uDone) { CUDDNode v = CUDD.Constant(0); bool vDone = false; while (!vDone) { numberOfIterations++; CUDD.Ref(u); CUDDNode tmp = CUDD.Variable.SwapVariables(u, allRowVars, allColVars); CUDD.Ref(trans01); tmp = CUDD.Abstract.ForAll(CUDD.Function.Implies(trans01, tmp), allColVars); CUDD.Ref(v); CUDDNode tmp2 = CUDD.Variable.SwapVariables(v, allRowVars, allColVars); CUDD.Ref(trans01); tmp2 = CUDD.Abstract.ThereExists(CUDD.Function.And(tmp2, trans01), allColVars); tmp = CUDD.Function.And(tmp, tmp2); tmp = CUDD.Abstract.ThereExists(tmp, nondetVars); CUDD.Ref(b1); tmp = CUDD.Function.And(b1, tmp); CUDD.Ref(b2); tmp = CUDD.Function.Or(b2, tmp); if (tmp.Equals(v)) { vDone = true; } CUDD.Deref(v); v = tmp; } if (v == u) { uDone = true; } CUDD.Deref(u); u = v; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("Prob1E: " + numberOfIterations + " iterations in " + runningTime + " seconds"); return u; }
/// <summary> /// At each terminal, return 1 if dd1 != dd2; 0 if dd1 == dd2 /// [ REFS: 'result', DEREFS: dd1, dd2 ] /// </summary> public static CUDDNode NotEqual(CUDDNode dd1, CUDDNode dd2) { return new CUDDNode(PlatformInvoke.DD_ApplyNotEqual(manager, dd1.Ptr, dd2.Ptr)); }
public static CUDDNode NondetReachReward(CUDDNode trans, CUDDNode reach, CUDDNode stateReward, CUDDNode transReward, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, CUDDNode infReward, CUDDNode maybeReward, bool min) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDDNode a, allReward, newNondetMask, sol, tmp; // filter out rows (goal states and infinity states) from matrix CUDD.Ref(trans, maybeReward); a = CUDD.Function.Times(trans, maybeReward); // also remove goal and infinity states from state rewards vector CUDD.Ref(stateReward, maybeReward); CUDDNode tempStateReward = CUDD.Function.Times(stateReward, maybeReward); // multiply transition rewards by transition probs and sum rows // (note also filters out unwanted states at the same time) CUDD.Ref(transReward, a); CUDDNode tempTransReward = CUDD.Function.Times(transReward, a); tempTransReward = CUDD.Abstract.SumAbstract(tempTransReward, allColVars); // combine state and transition rewards allReward = CUDD.Function.Plus(tempStateReward, tempTransReward); // need to change mask because rewards are not necessarily in the range 0..1 CUDD.Ref(nondetMask); newNondetMask = CUDD.Function.ITE(nondetMask, CUDD.PlusInfinity(), CUDD.Constant(0)); // initial solution is infinity in 'inf' states, zero elsewhere // note: ok to do this because cudd matrix-multiply (and other ops) // treat 0 * inf as 0, unlike in IEEE 754 rules CUDD.Ref(infReward); sol = CUDD.Function.ITE(infReward, CUDD.PlusInfinity(), CUDD.Constant(0)); while(true) { numberOfIterations++; tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); // add rewards CUDD.Ref(allReward); tmp = CUDD.Function.Plus(tmp, allReward); if(min) { CUDD.Ref(newNondetMask); tmp = CUDD.Function.Maximum(tmp, newNondetMask); tmp = CUDD.Abstract.MinAbstract(tmp, nondetVars); } else { tmp = CUDD.Abstract.MaxAbstract(tmp, nondetVars); } CUDD.Ref(infReward); tmp = CUDD.Function.ITE(infReward, CUDD.PlusInfinity(), tmp); if (CUDD.IsEqual(tmp, sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("NondetReachReward: " + numberOfIterations + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a, allReward, newNondetMask); return sol; }
/// <summary> /// [ REFS: 'none', DEREFS: 'none' ] /// </summary> public static void PrintVectorFiltered(CUDDNode dd, CUDDNode filter, CUDDVars vars, int numVars, int accuracy) { PlatformInvoke.DD_PrintVectorFiltered(manager, dd.Ptr, filter.Ptr, vars.GetArrayPointer(), numVars); }