/** * Constructor: build an STPG from an MDP. Data is copied directly from the MDP so take a copy * first if you plan to keep/modify the MDP. */ public STPGAbstrSimple(MDPSimple m) { DistributionSet set; int i; // TODO: actions? initialise(m.getNumStates()); copyFrom(m); for (i = 0; i < numStates; i++) { set = newDistributionSet(null); set.addAll(m.getChoices(i)); addDistributionSet(i, set); } }
@Override public Iterator<Entry<Integer, Double>> getNestedTransitionsIterator(int s, int i, int j) { DistributionSet ds = trans.get(s).get(i); Iterator<Distribution> iter = ds.iterator(); Distribution distr = null; int k = 0; while (iter.hasNext() && k <= j) { distr = iter.next(); k++; } if (k <= j) return null; else return distr.iterator(); }
@Override public int getNumNestedTransitions(int s, int i, int j) { DistributionSet ds = trans.get(s).get(i); Iterator<Distribution> iter = ds.iterator(); Distribution distr = null; int k = 0; while (iter.hasNext() && k <= j) { distr = iter.next(); k++; } if (k <= j) return 0; else return distr.size(); }
@Override public void findDeadlocks(boolean fix) throws PrismException { for (int i = 0; i < numStates; i++) { // Note that no distributions is a deadlock, not an empty distribution if (trans.get(i).isEmpty()) { addDeadlockState(i); if (fix) { DistributionSet distrs = newDistributionSet(null); Distribution distr = new Distribution(); distr.add(i, 1.0); distrs.add(distr); addDistributionSet(i, distrs); } } } }
@Override public void clearState(int i) { // Do nothing if state does not exist if (i >= numStates || i < 0) return; // Clear data structures and update stats List<DistributionSet> list = trans.get(i); numDistrSets -= list.size(); for (DistributionSet set : list) { numDistrs -= set.size(); for (Distribution distr : set) numTransitions -= distr.size(); } // TODO: recompute maxNumDistrSets // TODO: recompute maxNumDistrs // Remove all distribution sets trans.set(i, new ArrayList<DistributionSet>(0)); }
/** * Add distribution set 'newSet' to state s (which must exist). Distribution set is only actually * added if it does not already exists for state s. (Assuming 'allowDupes' flag is not enabled.) * Returns the index of the (existing or newly added) set. Returns -1 in case of error. */ public int addDistributionSet(int s, DistributionSet newSet) { ArrayList<DistributionSet> set; // Check state exists if (s >= numStates || s < 0) return -1; // Add distribution set (if new) set = trans.get(s); if (!allowDupes) { int i = set.indexOf(newSet); if (i != -1) return i; } set.add(newSet); // Update stats numDistrSets++; maxNumDistrSets = Math.max(maxNumDistrSets, set.size()); numDistrs += newSet.size(); maxNumDistrs = Math.max(maxNumDistrs, newSet.size()); for (Distribution distr : newSet) numTransitions += distr.size(); return set.size() - 1; }
/** Simple test program */ public static void main(String args[]) { STPGModelChecker mc; STPGAbstrSimple stpg; DistributionSet set; Distribution distr; // ModelCheckerResult res; BitSet target; // Simple example: Create and solve the stochastic game from: // Mark Kattenbelt, Marta Kwiatkowska, Gethin Norman, David Parker // A Game-based Abstraction-Refinement Framework for Markov Decision Processes // Formal Methods in System Design 36(3): 246-280, 2010 try { // Build game stpg = new STPGAbstrSimple(); stpg.addStates(4); // State 0 (s_0) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(1, 1.0); set.add(distr); stpg.addDistributionSet(0, set); // State 1 (s_1,s_2,s_3) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 1.0); set.add(distr); distr = new Distribution(); distr.set(1, 1.0); set.add(distr); stpg.addDistributionSet(1, set); set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 0.5); distr.set(3, 0.5); set.add(distr); distr = new Distribution(); distr.set(3, 1.0); set.add(distr); stpg.addDistributionSet(1, set); // State 2 (s_4,s_5) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 1.0); set.add(distr); stpg.addDistributionSet(2, set); // State 3 (s_6) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(3, 1.0); set.add(distr); stpg.addDistributionSet(3, set); // Print game System.out.println(stpg); // Model check mc = new STPGModelChecker(null); // mc.setVerbosity(2); target = new BitSet(); target.set(3); stpg.exportToDotFile("stpg.dot", target); System.out.println("min min: " + mc.computeReachProbs(stpg, target, true, true).soln[0]); System.out.println("max min: " + mc.computeReachProbs(stpg, target, false, true).soln[0]); System.out.println("min max: " + mc.computeReachProbs(stpg, target, true, false).soln[0]); System.out.println("max max: " + mc.computeReachProbs(stpg, target, false, false).soln[0]); } catch (PrismException e) { System.out.println(e); } }
@Override public void buildFromPrismExplicit(String filename) throws PrismException { BufferedReader in; Distribution distr; DistributionSet distrs; String s, ss[]; int i, j, k1, k2, iLast, k1Last, k2Last, n, lineNum = 0; double prob; try { // Open file in = new BufferedReader(new FileReader(new File(filename))); // Parse first line to get num states s = in.readLine(); lineNum = 1; if (s == null) { in.close(); throw new PrismException("Missing first line of .tra file"); } ss = s.split(" "); n = Integer.parseInt(ss[0]); // Initialise initialise(n); // Go though list of transitions in file iLast = -1; k1Last = -1; k2Last = -1; distrs = null; distr = null; s = in.readLine(); lineNum++; while (s != null) { s = s.trim(); if (s.length() > 0) { ss = s.split(" "); i = Integer.parseInt(ss[0]); k1 = Integer.parseInt(ss[1]); k2 = Integer.parseInt(ss[2]); j = Integer.parseInt(ss[3]); prob = Double.parseDouble(ss[4]); // For a new state or distribution set or distribution if (i != iLast || k1 != k1Last || k2 != k2Last) { // Add any previous distribution to the last set, create new one if (distrs != null) { distrs.add(distr); } distr = new Distribution(); // Only for a new state or distribution set... if (i != iLast || k1 != k1Last) { // Add any previous distribution set to the last state, create new one if (distrs != null) { addDistributionSet(iLast, distrs); } distrs = newDistributionSet(null); } } // Add transition to the current distribution distr.add(j, prob); // Prepare for next iter iLast = i; k1Last = k1; k2Last = k2; } s = in.readLine(); lineNum++; } // Add previous distribution to the last set distrs.add(distr); // Add previous distribution set to the last state addDistributionSet(iLast, distrs); // Close file in.close(); } catch (IOException e) { System.out.println(e); System.exit(1); } catch (NumberFormatException e) { throw new PrismException("Problem in .tra file (line " + lineNum + ") for " + getModelType()); } // Set initial state (assume 0) initialStates.add(0); }