diff --git a/prism/src/explicit/DTMCEmbeddedSimple.java b/prism/src/explicit/DTMCEmbeddedSimple.java index 66f0626b..648ccc44 100644 --- a/prism/src/explicit/DTMCEmbeddedSimple.java +++ b/prism/src/explicit/DTMCEmbeddedSimple.java @@ -128,6 +128,12 @@ public class DTMCEmbeddedSimple implements DTMC // 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"); diff --git a/prism/src/explicit/DTMCSimple.java b/prism/src/explicit/DTMCSimple.java index 1d3f90e1..3e04fc20 100644 --- a/prism/src/explicit/DTMCSimple.java +++ b/prism/src/explicit/DTMCSimple.java @@ -301,6 +301,23 @@ public class DTMCSimple extends ModelSimple implements DTMC } } + @Override + public BitSet findDeadlocks(boolean fix) throws PrismException + { + int i; + BitSet deadlocks = new BitSet(); + for (i = 0; i < numStates; i++) { + if (trans.get(i).isEmpty()) + deadlocks.set(i); + } + if (fix) { + for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) { + setProbability(i, i, 1.0); + } + } + return deadlocks; + } + @Override public void exportToPrismExplicit(String baseFilename) throws PrismException { diff --git a/prism/src/explicit/DTMCUniformisedSimple.java b/prism/src/explicit/DTMCUniformisedSimple.java index 3e5afefa..4f61a83c 100644 --- a/prism/src/explicit/DTMCUniformisedSimple.java +++ b/prism/src/explicit/DTMCUniformisedSimple.java @@ -139,6 +139,12 @@ public class DTMCUniformisedSimple implements DTMC // 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"); diff --git a/prism/src/explicit/MDPSimple.java b/prism/src/explicit/MDPSimple.java index 49cdd720..1d118c8f 100644 --- a/prism/src/explicit/MDPSimple.java +++ b/prism/src/explicit/MDPSimple.java @@ -110,6 +110,26 @@ public class MDPSimple extends ModelSimple implements MDP // TODO: copy rewards, etc. } + /** + * Construct an MDP from an existing one and a state index permutation, + * i.e. in which state index i becomes index permut[i]. + * Note: have to build new Distributions from scratch anyway to do this, + * so may as well provide this functionality as a constructor. + */ + public MDPSimple(MDPSimple mdp, int permut[]) + { + this(mdp.numStates); + for (int in : mdp.getInitialStates()) { + addInitialState(permut[in]); + } + for (int i = 0; i < numStates; i++) { + for (Distribution distr : mdp.trans.get(i)) { + addChoice(permut[i], new Distribution(distr, permut)); + } + } + // TODO: permute rewards + } + // Mutators (for ModelSimple) @Override @@ -398,6 +418,26 @@ public class MDPSimple extends ModelSimple implements MDP // TODO: Check for empty distributions too? } + @Override + public BitSet findDeadlocks(boolean fix) throws PrismException + { + int i; + BitSet deadlocks = new BitSet(); + for (i = 0; i < numStates; i++) { + // Note that no distributions is a deadlock, not an empty distribution + if (trans.get(i).isEmpty()) + deadlocks.set(i); + } + if (fix) { + for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) { + Distribution distr = new Distribution(); + distr.add(i, 1.0); + addChoice(i, distr); + } + } + return deadlocks; + } + @Override public void exportToPrismExplicitTra(String filename) throws PrismException { diff --git a/prism/src/explicit/Model.java b/prism/src/explicit/Model.java index beaf5a11..ca5ceb30 100644 --- a/prism/src/explicit/Model.java +++ b/prism/src/explicit/Model.java @@ -104,6 +104,12 @@ public interface Model */ public void checkForDeadlocks() throws PrismException; + /** + * Find all deadlocks and return a BitSet of these states. + * If requested (if fix=true, then add self-loops in these states). + */ + public BitSet findDeadlocks(boolean fix) throws PrismException; + /** * Checks for deadlocks and throws an exception if any exist. * States in 'except' (If non-null) are excluded from the check. diff --git a/prism/src/explicit/STPG.java b/prism/src/explicit/STPG.java index 365dcd18..14f5858d 100644 --- a/prism/src/explicit/STPG.java +++ b/prism/src/explicit/STPG.java @@ -366,6 +366,28 @@ public class STPG extends ModelSimple // TODO: Check for empty distributions sets too? } + @Override + public BitSet findDeadlocks(boolean fix) throws PrismException + { + int i; + BitSet deadlocks = new BitSet(); + for (i = 0; i < numStates; i++) { + // Note that no distributions is a deadlock, not an empty distribution + if (trans.get(i).isEmpty()) + deadlocks.set(i); + } + if (fix) { + for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) { + DistributionSet distrs = newDistributionSet(null); + Distribution distr = new Distribution(); + distr.add(i, 1.0); + distrs.add(distr); + addDistributionSet(i, distrs); + } + } + return deadlocks; + } + /** * Build (anew) from a list of transitions exported explicitly by PRISM (i.e. a .tra file). */