//============================================================================== // //Copyright (c) 2002- //Authors: //* Dave Parker (University of Oxford) // //------------------------------------------------------------------------------ // //This file is part of PRISM. // //PRISM is free software; you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation; either version 2 of the License, or //(at your option) any later version. // //PRISM is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with PRISM; if not, write to the Free Software Foundation, //Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //============================================================================== package explicit; import java.util.*; import prism.ModelType; import prism.PrismException; /** * Simple explicit-state representation of a DTMC, constructed (implicitly) as the uniformised DTMC of a CTMC. * This class is read-only: most of data is pointers to other model info. */ public class DTMCUniformisedSimple implements DTMC { // Parent CTMC protected CTMCSimple ctmc; // Uniformisation rate protected double q; // Number of extra transitions added (just for stats) protected int numExtraTransitions; /** * Constructor: create from CTMC and uniformisation rate q. */ public DTMCUniformisedSimple(CTMCSimple ctmc, double q) { this.ctmc = ctmc; this.q = q; int numStates = ctmc.getNumStates(); numExtraTransitions = 0; for (int i = 0; i < numStates; i++) { if (ctmc.getTransitions(i).get(i) == 0 && ctmc.getTransitions(i).sumAllBut(i) < q) { numExtraTransitions++; } } } /** * Constructor: create from CTMC and its default uniformisation rate. */ public DTMCUniformisedSimple(CTMCSimple ctmc) { this(ctmc, ctmc.getDefaultUniformisationRate()); } // Accessors (for Model) public ModelType getModelType() { return ModelType.DTMC; } public int getNumStates() { return ctmc.getNumStates(); } public int getNumInitialStates() { return ctmc.getNumInitialStates(); } public Iterable getInitialStates() { return ctmc.getInitialStates(); } public int getFirstInitialState() { return ctmc.getFirstInitialState(); } public boolean isInitialState(int i) { return ctmc.isInitialState(i); } public int getNumTransitions() { return ctmc.getNumTransitions() + numExtraTransitions; } public boolean isSuccessor(int s1, int s2) { // TODO throw new Error("Not yet supported"); } public boolean allSuccessorsInSet(int s, BitSet set) { // TODO throw new Error("Not yet supported"); } public boolean someSuccessorsInSet(int s, BitSet set) { // TODO throw new Error("Not yet supported"); } public int getNumChoices(int s) { // Always 1 for a DTMC return 1; } public void checkForDeadlocks() throws PrismException { // No deadlocks by definition } public void checkForDeadlocks(BitSet except) throws PrismException { // No deadlocks by definition } public BitSet findDeadlocks(boolean fix) throws PrismException { // No deadlocks by definition return new BitSet(); } public void exportToPrismExplicit(String baseFilename) throws PrismException { throw new PrismException("Export not yet supported"); } public void exportToPrismExplicitTra(String filename) throws PrismException { throw new PrismException("Export not yet supported"); } public void exportToDotFile(String filename) throws PrismException { throw new PrismException("Export not yet supported"); } public void exportToDotFile(String filename, BitSet mark) throws PrismException { throw new PrismException("Export not yet supported"); } public String infoString() { return ctmc.infoString() + " + " + numExtraTransitions + " self-loops"; } // Accessors (for DTMC) public double getTransitionReward(int s) { // TODO throw new Error("Not yet supported"); } public void mvMult(double vect[], double result[], BitSet subset, boolean complement) { int s, numStates; numStates = ctmc.getNumStates(); // Loop depends on subset/complement arguments if (subset == null) { for (s = 0; s < numStates; s++) result[s] = mvMultSingle(s, vect); } else if (complement) { for (s = subset.nextClearBit(0); s < numStates; s = subset.nextClearBit(s + 1)) result[s] = mvMultSingle(s, vect); } else { for (s = subset.nextSetBit(0); s >= 0; s = subset.nextSetBit(s + 1)) result[s] = mvMultSingle(s, vect); } } public double mvMultSingle(int s, double vect[]) { int k; double sum, d, prob; Distribution distr; distr = ctmc.getTransitions(s); sum = d = 0.0; for (Map.Entry e : distr) { k = (Integer) e.getKey(); prob = (Double) e.getValue(); // Non-diagonal entries if (k != s) { sum += prob; d += (prob / q) * vect[k]; } } // Diagonal entry if (sum < q) { d += (1 - sum/q) * vect[s]; } return d; } public void mvMultRew(double vect[], double result[], BitSet subset, boolean complement) { int s, numStates; numStates = ctmc.getNumStates(); // Loop depends on subset/complement arguments if (subset == null) { for (s = 0; s < numStates; s++) result[s] = mvMultRewSingle(s, vect); } else if (complement) { for (s = subset.nextClearBit(0); s < numStates; s = subset.nextClearBit(s + 1)) result[s] = mvMultRewSingle(s, vect); } else { for (s = subset.nextSetBit(0); s >= 0; s = subset.nextSetBit(s + 1)) result[s] = mvMultRewSingle(s, vect); } } public double mvMultRewSingle(int s, double vect[]) { // TODO throw new Error("Not yet supported"); } @Override public String toString() { String s = ""; s += "ctmc: " + ctmc; s = ", q: " + q; return s; } @Override public boolean equals(Object o) { if (o == null || !(o instanceof DTMCUniformisedSimple)) return false; DTMCUniformisedSimple dtmc = (DTMCUniformisedSimple) o; if (!ctmc.equals(dtmc.ctmc)) return false; if (q != dtmc.q) return false; if (numExtraTransitions != dtmc.numExtraTransitions) return false; return true; } }