diff --git a/prism/src/explicit/ECComputer.java b/prism/src/explicit/ECComputer.java index acf3581d..da590e3c 100644 --- a/prism/src/explicit/ECComputer.java +++ b/prism/src/explicit/ECComputer.java @@ -61,6 +61,13 @@ public abstract class ECComputer extends PrismComponent */ public abstract void computeMECStates() throws PrismException; + /** + * Compute states of all maximal end components (MECs) contained within {@code states}, and store them. + * They can be retrieved using {@link #getMECStates()}. + * @param states BitSet for the set of containing states + */ + public abstract void computeMECStates(BitSet states) throws PrismException; + /** * Get the list of states for computed MECs. */ diff --git a/prism/src/explicit/ECComputerDefault.java b/prism/src/explicit/ECComputerDefault.java index 4614e793..c9de1781 100644 --- a/prism/src/explicit/ECComputerDefault.java +++ b/prism/src/explicit/ECComputerDefault.java @@ -39,8 +39,8 @@ import prism.PrismComponent; import prism.PrismException; /** - * EXplicit maximal end component computer for a nondeterministic model such as MDP. - * Implements the algorithm from: + * Explicit maximal end component computer for a nondeterministic model such as an MDP. + * Implements the algorithm from p.48 of: * Luca de Alfaro. Formal Verification of Probabilistic Systems. Ph.D. thesis, Stanford University (1997) */ public class ECComputerDefault extends ECComputer @@ -65,33 +65,53 @@ public class ECComputerDefault extends ECComputer @Override public void computeMECStates() throws PrismException { - SubNondetModel submodel = null; - List L = new ArrayList(); + // Look within set of all reachable states + BitSet reach = new BitSet(); + reach.set(0, model.getNumStates()); + computeMECStates(reach); + } + + @Override + public void computeMECStates(BitSet states) throws PrismException + { + mecs = findEndComponents(states, null); //TODO + } + + @Override + public List getMECStates() + { + return mecs; + } + + // Computation - BitSet initialModel = new BitSet(); - initialModel.set(0, model.getNumStates()); - L.add(initialModel); + /** + * Find all accepting maximal end components (MECs) contained within {@code states}, + * where acceptance is defined as those which intersect with {@code filter}. + * (If {@code filter} is null, the acceptance condition is trivially satisfied.) + * @param states BitSet for the set of containing states + * @param filter BitSet for the set of accepting states + * @return a list of BitSets representing the MECs + */ + private List findEndComponents(BitSet states, BitSet filter) throws PrismException + { + // Initialise L with set of all states to look in + List L = new ArrayList(); + L.add(states); boolean changed = true; while (changed) { changed = false; BitSet E = L.remove(0); - submodel = restrict(model, E); + SubNondetModel submodel = restrict(model, E); List sccs = translateStates(submodel, computeSCCs(submodel)); L = replaceEWithSCCs(L, E, sccs); changed = canLBeChanged(L, E); } - mecs = L; - } - @Override - public List getMECStates() - { - return mecs; + return L; } - // Computation - private Set processedSCCs = new HashSet(); private boolean canLBeChanged(List L, BitSet E) diff --git a/prism/src/explicit/LTLModelChecker.java b/prism/src/explicit/LTLModelChecker.java index 9f3c8887..a98d37f8 100644 --- a/prism/src/explicit/LTLModelChecker.java +++ b/prism/src/explicit/LTLModelChecker.java @@ -357,17 +357,17 @@ public class LTLModelChecker extends PrismComponent for (BitSet mec : mecs) { boolean isLEmpty = true; - boolean isKEmpty = true; - for (int acceptancePair = 0; acceptancePair < numAcceptancePairs && isLEmpty && isKEmpty; acceptancePair++) { + boolean isKNonEmpty = false; + for (int acceptancePair = 0; acceptancePair < numAcceptancePairs; acceptancePair++) { BitSet L = dra.getAcceptanceL(acceptancePair); BitSet K = dra.getAcceptanceK(acceptancePair); for (int state = mec.nextSetBit(0); state != -1; state = mec.nextSetBit(state + 1)) { int draState = invMap[state] % draSize; isLEmpty &= !L.get(draState); - isKEmpty &= !K.get(draState); + isKNonEmpty |= K.get(draState); } // Stop as soon as we find the first acceptance pair that is satisfied - if (isLEmpty && !isKEmpty) { + if (isLEmpty && isKNonEmpty) { result.or(mec); break; }