Browse Source

Adapt (explicit) LTLModelChecker to support generic acceptance types. [Joachim Klein]

Adapt product constructions (rename dra to da, generic lifting of acceptance)
Generic findAcceptingBSCCs() and findAcceptingECStates()



git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@9604 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Dave Parker 11 years ago
parent
commit
b6f3b2dce3
  1. 6
      prism/src/explicit/DTMCModelChecker.java
  2. 216
      prism/src/explicit/LTLModelChecker.java
  3. 6
      prism/src/explicit/MDPModelChecker.java

6
prism/src/explicit/DTMCModelChecker.java

@ -31,6 +31,7 @@ import java.util.BitSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import acceptance.AcceptanceType;
import parser.ast.Expression; import parser.ast.Expression;
import parser.type.TypeDouble; import parser.type.TypeDouble;
import prism.PrismComponent; import prism.PrismComponent;
@ -65,11 +66,12 @@ public class DTMCModelChecker extends ProbModelChecker
mcLtl = new LTLModelChecker(this); mcLtl = new LTLModelChecker(this);
// Build product of Markov chain and automaton // Build product of Markov chain and automaton
product = mcLtl.constructProductMC(this, (DTMC)model, expr, statesOfInterest);
AcceptanceType[] allowedAcceptance = {AcceptanceType.RABIN};
product = mcLtl.constructProductMC(this, (DTMC)model, expr, statesOfInterest, allowedAcceptance);
// Find accepting BSCCs + compute reachability probabilities // Find accepting BSCCs + compute reachability probabilities
mainLog.println("\nFinding accepting BSCCs..."); mainLog.println("\nFinding accepting BSCCs...");
BitSet acceptingBSCCs = mcLtl.findAcceptingBSCCsForRabin(product.getProductModel(), product.getAcceptance());
BitSet acceptingBSCCs = mcLtl.findAcceptingBSCCs(product.getProductModel(), product.getAcceptance());
mainLog.println("\nComputing reachability probabilities..."); mainLog.println("\nComputing reachability probabilities...");
mcProduct = new DTMCModelChecker(this); mcProduct = new DTMCModelChecker(this);
mcProduct.inheritSettings(this); mcProduct.inheritSettings(this);

216
prism/src/explicit/LTLModelChecker.java

@ -38,7 +38,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Vector; import java.util.Vector;
import acceptance.AcceptanceOmega;
import acceptance.AcceptanceRabin; import acceptance.AcceptanceRabin;
import acceptance.AcceptanceType;
import common.IterableStateSet; import common.IterableStateSet;
import parser.State; import parser.State;
import parser.ast.Expression; import parser.ast.Expression;
@ -64,14 +66,14 @@ public class LTLModelChecker extends PrismComponent
{ {
/** Make LTL product accessible as a Product */ /** Make LTL product accessible as a Product */
public class LTLProduct<M extends Model> extends Product<M> { public class LTLProduct<M extends Model> extends Product<M> {
private int draSize;
private int daSize;
private int invMap[]; private int invMap[];
private AcceptanceRabin acceptance;
private AcceptanceOmega acceptance;
public LTLProduct(M productModel, M originalModel, AcceptanceRabin acceptance, int draSize, int[] invMap)
public LTLProduct(M productModel, M originalModel, AcceptanceOmega acceptance, int daSize, int[] invMap)
{ {
super(productModel, originalModel); super(productModel, originalModel);
this.draSize = draSize;
this.daSize = daSize;
this.invMap = invMap; this.invMap = invMap;
this.acceptance = acceptance; this.acceptance = acceptance;
} }
@ -79,18 +81,22 @@ public class LTLModelChecker extends PrismComponent
@Override @Override
public int getModelState(int productState) public int getModelState(int productState)
{ {
return invMap[productState] / draSize;
return invMap[productState] / daSize;
} }
@Override @Override
public int getAutomatonState(int productState) public int getAutomatonState(int productState)
{ {
return invMap[productState] % draSize;
return invMap[productState] % daSize;
} }
public AcceptanceRabin getAcceptance() {
public AcceptanceOmega getAcceptance() {
return acceptance; return acceptance;
} }
public void setAcceptance(AcceptanceOmega acceptance) {
this.acceptance = acceptance;
}
} }
@ -180,18 +186,19 @@ public class LTLModelChecker extends PrismComponent
} }
/** /**
* Generate the DRA for the given LTL expression and construct the product.
* Generate a deterministic automaton for the given LTL expression and construct the product.
* *
* @param mc a ProbModelChecker, used for checking maximal state formulas * @param mc a ProbModelChecker, used for checking maximal state formulas
* @param dtmc the model * @param dtmc the model
* @param expr a path expression * @param expr a path expression
* @param statesOfInterest the set of states for which values should be calculated (null = all states) * @param statesOfInterest the set of states for which values should be calculated (null = all states)
* @return the product with the DRA
* @param allowedAcceptance the allowed acceptance types
* @return the product with the DA
*/ */
public LTLProduct<DTMC> constructProductMC(ProbModelChecker mc, DTMC dtmc, Expression expr, BitSet statesOfInterest) throws PrismException
public LTLProduct<DTMC> constructProductMC(ProbModelChecker mc, DTMC dtmc, Expression expr, BitSet statesOfInterest, AcceptanceType... allowedAcceptance) throws PrismException
{ {
Expression ltl; Expression ltl;
DA<BitSet,AcceptanceRabin> dra;
DA<BitSet,? extends AcceptanceOmega> da;
LTLProduct<DTMC> product; LTLProduct<DTMC> product;
long time; long time;
@ -218,26 +225,27 @@ public class LTLModelChecker extends PrismComponent
Vector<BitSet> labelBS = new Vector<BitSet>(); Vector<BitSet> labelBS = new Vector<BitSet>();
ltl = checkMaximalStateFormulas(mc, dtmc, expr.deepCopy(), labelBS); ltl = checkMaximalStateFormulas(mc, dtmc, expr.deepCopy(), labelBS);
// Convert LTL formula to deterministic Rabin automaton (DRA)
mainLog.println("\nBuilding deterministic Rabin automaton (for " + ltl + ")...");
// Convert LTL formula to deterministic automaton
mainLog.println("\nBuilding deterministic automaton (for " + ltl + ")...");
time = System.currentTimeMillis(); time = System.currentTimeMillis();
LTL2DA ltl2da = new LTL2DA(this); LTL2DA ltl2da = new LTL2DA(this);
dra = ltl2da.convertLTLFormulaToDRA(ltl, mc.getConstantValues());
mainLog.println("DRA has " + dra.size() + " states, " + dra.getAcceptance().getSizeStatistics() + ".");
da = ltl2da.convertLTLFormulaToDA(ltl, mc.getConstantValues(), allowedAcceptance);
mainLog.println(da.getAutomataType()+" has " + da.size() + " states, " + da.getAcceptance().getSizeStatistics() + ".");
time = System.currentTimeMillis() - time; time = System.currentTimeMillis() - time;
mainLog.println("Time for Rabin translation: " + time / 1000.0 + " seconds.");
mainLog.println("Time for "+da.getAutomataType()+" translation: " + time / 1000.0 + " seconds.");
// If required, export DRA // If required, export DRA
if (settings.getExportPropAut()) { if (settings.getExportPropAut()) {
mainLog.println("Exporting DRA to file \"" + settings.getExportPropAutFilename() + "\"..."); mainLog.println("Exporting DRA to file \"" + settings.getExportPropAutFilename() + "\"...");
PrismLog out = new PrismFileLog(settings.getExportPropAutFilename()); PrismLog out = new PrismFileLog(settings.getExportPropAutFilename());
out.println(dra);
out.println(da);
out.close(); out.close();
//dra.printDot(new java.io.PrintStream("dra.dot")); //dra.printDot(new java.io.PrintStream("dra.dot"));
} }
// Build product of Markov chain and automaton // Build product of Markov chain and automaton
mainLog.println("\nConstructing MC-DRA product...");
product = constructProductMC(dra, dtmc, labelBS, statesOfInterest);
mainLog.println("\nConstructing MC-"+da.getAutomataType()+" product...");
product = constructProductMC(da, dtmc, labelBS, statesOfInterest);
mainLog.print("\n" + product.getProductModel().infoStringTable()); mainLog.print("\n" + product.getProductModel().infoStringTable());
@ -245,30 +253,29 @@ public class LTLModelChecker extends PrismComponent
} }
/** /**
* Construct the product of a DRA and a DTMC.
* @param dra The DRA
* Construct the product of a DA and a DTMC.
* @param dra The DA
* @param dtmc The DTMC * @param dtmc The DTMC
* @param labelBS BitSets giving the set of states for each AP in the DRA
* @param labelBS BitSets giving the set of states for each AP in the DA
* @param statesOfInterest the set of states for which values should be calculated (null = all states) * @param statesOfInterest the set of states for which values should be calculated (null = all states)
* @return The product DTMC * @return The product DTMC
*/ */
public LTLProduct<DTMC> constructProductMC(DA<BitSet,AcceptanceRabin> dra, DTMC dtmc, Vector<BitSet> labelBS, BitSet statesOfInterest) throws PrismException
public LTLProduct<DTMC> constructProductMC(DA<BitSet,? extends AcceptanceOmega> da, DTMC dtmc, Vector<BitSet> labelBS, BitSet statesOfInterest) throws PrismException
{ {
DTMCSimple prodModel = new DTMCSimple(); DTMCSimple prodModel = new DTMCSimple();
int draSize = dra.size();
int numAPs = dra.getAPList().size();
int daSize = da.size();
int numAPs = da.getAPList().size();
int modelNumStates = dtmc.getNumStates(); int modelNumStates = dtmc.getNumStates();
int prodNumStates = modelNumStates * draSize;
int prodNumStates = modelNumStates * daSize;
int s_1, s_2, q_1, q_2; int s_1, s_2, q_1, q_2;
BitSet s_labels = new BitSet(numAPs); BitSet s_labels = new BitSet(numAPs);
AcceptanceRabin prodAcceptance;
List<State> prodStatesList = null; List<State> prodStatesList = null;
// Encoding: // Encoding:
// each state s' = <s, q> = s * draSize + q
// s(s') = s' / draSize
// q(s') = s' % draSize
// each state s' = <s, q> = s * daSize + q
// s(s') = s' / daSize
// q(s') = s' % daSize
LinkedList<Point> queue = new LinkedList<Point>(); LinkedList<Point> queue = new LinkedList<Point>();
int map[] = new int[prodNumStates]; int map[] = new int[prodNumStates];
@ -287,15 +294,15 @@ public class LTLModelChecker extends PrismComponent
for (int s_0 : new IterableStateSet(statesOfInterest, dtmc.getNumStates())) { for (int s_0 : new IterableStateSet(statesOfInterest, dtmc.getNumStates())) {
// Get BitSet representing APs (labels) satisfied by state s_0 // Get BitSet representing APs (labels) satisfied by state s_0
for (int k = 0; k < numAPs; k++) { for (int k = 0; k < numAPs; k++) {
s_labels.set(k, labelBS.get(Integer.parseInt(dra.getAPList().get(k).substring(1))).get(s_0));
s_labels.set(k, labelBS.get(Integer.parseInt(da.getAPList().get(k).substring(1))).get(s_0));
} }
// Find corresponding initial state in DRA
int q_0 = dra.getEdgeDestByLabel(dra.getStartState(), s_labels);
// Find corresponding initial state in DA
int q_0 = da.getEdgeDestByLabel(da.getStartState(), s_labels);
// Add (initial) state to product // Add (initial) state to product
queue.add(new Point(s_0, q_0)); queue.add(new Point(s_0, q_0));
prodModel.addState(); prodModel.addState();
prodModel.addInitialState(prodModel.getNumStates() - 1); prodModel.addInitialState(prodModel.getNumStates() - 1);
map[s_0 * draSize + q_0] = prodModel.getNumStates() - 1;
map[s_0 * daSize + q_0] = prodModel.getNumStates() - 1;
if (prodStatesList != null) { if (prodStatesList != null) {
// store DTMC state information for the product state // store DTMC state information for the product state
prodStatesList.add(dtmc.getStatesList().get(s_0)); prodStatesList.add(dtmc.getStatesList().get(s_0));
@ -308,7 +315,7 @@ public class LTLModelChecker extends PrismComponent
Point p = queue.pop(); Point p = queue.pop();
s_1 = p.x; s_1 = p.x;
q_1 = p.y; q_1 = p.y;
visited.set(s_1 * draSize + q_1);
visited.set(s_1 * daSize + q_1);
// Go through transitions from state s_1 in original DTMC // Go through transitions from state s_1 in original DTMC
Iterator<Map.Entry<Integer, Double>> iter = dtmc.getTransitionsIterator(s_1); Iterator<Map.Entry<Integer, Double>> iter = dtmc.getTransitionsIterator(s_1);
@ -318,21 +325,21 @@ public class LTLModelChecker extends PrismComponent
double prob = e.getValue(); double prob = e.getValue();
// Get BitSet representing APs (labels) satisfied by successor state s_2 // Get BitSet representing APs (labels) satisfied by successor state s_2
for (int k = 0; k < numAPs; k++) { for (int k = 0; k < numAPs; k++) {
s_labels.set(k, labelBS.get(Integer.parseInt(dra.getAPList().get(k).substring(1))).get(s_2));
s_labels.set(k, labelBS.get(Integer.parseInt(da.getAPList().get(k).substring(1))).get(s_2));
} }
// Find corresponding successor in DRA // Find corresponding successor in DRA
q_2 = dra.getEdgeDestByLabel(q_1, s_labels);
q_2 = da.getEdgeDestByLabel(q_1, s_labels);
// Add state/transition to model // Add state/transition to model
if (!visited.get(s_2 * draSize + q_2) && map[s_2 * draSize + q_2] == -1) {
if (!visited.get(s_2 * daSize + q_2) && map[s_2 * daSize + q_2] == -1) {
queue.add(new Point(s_2, q_2)); queue.add(new Point(s_2, q_2));
prodModel.addState(); prodModel.addState();
map[s_2 * draSize + q_2] = prodModel.getNumStates() - 1;
map[s_2 * daSize + q_2] = prodModel.getNumStates() - 1;
if (prodStatesList != null) { if (prodStatesList != null) {
// store DTMC state information for the product state // store DTMC state information for the product state
prodStatesList.add(dtmc.getStatesList().get(s_2)); prodStatesList.add(dtmc.getStatesList().get(s_2));
} }
} }
prodModel.setProbability(map[s_1 * draSize + q_1], map[s_2 * draSize + q_2], prob);
prodModel.setProbability(map[s_1 * daSize + q_1], map[s_2 * daSize + q_2], prob);
} }
} }
@ -350,15 +357,10 @@ public class LTLModelChecker extends PrismComponent
prodModel.setStatesList(prodStatesList); prodModel.setStatesList(prodStatesList);
} }
prodAcceptance = new AcceptanceRabin();
LTLProduct<DTMC> product = new LTLProduct<DTMC>(prodModel, dtmc, prodAcceptance, draSize, invMap);
LTLProduct<DTMC> product = new LTLProduct<DTMC>(prodModel, dtmc, null, daSize, invMap);
// generate acceptance for the product model by lifting // generate acceptance for the product model by lifting
for (AcceptanceRabin.RabinPair pair : dra.getAcceptance()) {
BitSet Lprod = product.liftFromAutomaton(pair.getL());
BitSet Kprod = product.liftFromAutomaton(pair.getK());
prodAcceptance.add(new AcceptanceRabin.RabinPair(Lprod, Kprod));
}
product.setAcceptance(liftAcceptance(product, da.getAcceptance()));
// lift the labels // lift the labels
for (String label : dtmc.getLabels()) { for (String label : dtmc.getLabels()) {
@ -369,18 +371,20 @@ public class LTLModelChecker extends PrismComponent
return product; return product;
} }
/** /**
* Generate the DRA for the given LTL expression and construct the product.
* Generate the DA for the given LTL expression and construct the product.
* *
* @param mc a ProbModelChecker, used for checking maximal state formulas * @param mc a ProbModelChecker, used for checking maximal state formulas
* @param model the model * @param model the model
* @param expr a path expression * @param expr a path expression
* @param statesOfInterest the set of states for which values should be calculated (null = all states)
* @return the product with the DRA
* @param statesOfInterest the set of states for which values should be calculated (null = all states)
* @param allowedAcceptance the allowed acceptance conditions
* @return the product with the DA
* @throws PrismException
*/ */
public LTLProduct<MDP> constructProductMDP(ProbModelChecker mc, MDP model, Expression expr, BitSet statesOfInterest) throws PrismException
public LTLProduct<MDP> constructProductMDP(ProbModelChecker mc, MDP model, Expression expr, BitSet statesOfInterest, AcceptanceType... allowedAcceptance) throws PrismException
{ {
Expression ltl; Expression ltl;
DA<BitSet,AcceptanceRabin> dra;
DA<BitSet, ? extends AcceptanceOmega> da;
LTLProduct<MDP> product; LTLProduct<MDP> product;
long time; long time;
@ -407,26 +411,26 @@ public class LTLModelChecker extends PrismComponent
Vector<BitSet> labelBS = new Vector<BitSet>(); Vector<BitSet> labelBS = new Vector<BitSet>();
ltl = checkMaximalStateFormulas(mc, model, expr.deepCopy(), labelBS); ltl = checkMaximalStateFormulas(mc, model, expr.deepCopy(), labelBS);
// Convert LTL formula to deterministic Rabin automaton (DRA)
mainLog.println("\nBuilding deterministic Rabin automaton (for " + ltl + ")...");
// Convert LTL formula to deterministic automaton
mainLog.println("\nBuilding deterministic automaton (for " + ltl + ")...");
time = System.currentTimeMillis(); time = System.currentTimeMillis();
LTL2DA ltl2da = new LTL2DA(this); LTL2DA ltl2da = new LTL2DA(this);
dra = ltl2da.convertLTLFormulaToDRA(ltl, mc.getConstantValues());
mainLog.println("DRA has " + dra.size() + " states, " + dra.getAcceptance().getSizeStatistics() + ".");
da = ltl2da.convertLTLFormulaToDA(ltl, mc.getConstantValues(), allowedAcceptance);
mainLog.println(da.getAutomataType()+" has " + da.size() + " states, " + da.getAcceptance().getSizeStatistics() + ".");
time = System.currentTimeMillis() - time; time = System.currentTimeMillis() - time;
mainLog.println("Time for Rabin translation: " + time / 1000.0 + " seconds.");
// If required, export DRA
mainLog.println("Time for "+da.getAutomataType()+" translation: " + time / 1000.0 + " seconds.");
// If required, export DA
if (settings.getExportPropAut()) { if (settings.getExportPropAut()) {
mainLog.println("Exporting DRA to file \"" + settings.getExportPropAutFilename() + "\"...");
mainLog.println("Exporting "+da.getAutomataType()+" to file \"" + settings.getExportPropAutFilename() + "\"...");
PrismLog out = new PrismFileLog(settings.getExportPropAutFilename()); PrismLog out = new PrismFileLog(settings.getExportPropAutFilename());
out.println(dra);
out.println(da);
out.close(); out.close();
//dra.printDot(new java.io.PrintStream("dra.dot"));
//da.printDot(new java.io.PrintStream("da.dot"));
} }
// Build product of MDP and automaton // Build product of MDP and automaton
mainLog.println("\nConstructing MDP-DRA product...");
product = constructProductMDP(dra, (MDP) model, labelBS, statesOfInterest);
mainLog.println("\nConstructing MDP-"+da.getAutomataType()+" product...");
product = constructProductMDP(da, model, labelBS, statesOfInterest);
mainLog.print("\n" + product.getProductModel().infoStringTable()); mainLog.print("\n" + product.getProductModel().infoStringTable());
@ -434,24 +438,23 @@ public class LTLModelChecker extends PrismComponent
} }
/** /**
* Construct the product of a DRA and an MDP.
* @param dra The DRA
* Construct the product of a DA and an MDP.
* @param da The DA
* @param mdp The MDP * @param mdp The MDP
* @param labelBS BitSets giving the set of states for each AP in the DRA
* @param labelBS BitSets giving the set of states for each AP in the DA
* @param statesOfInterest the set of states for which values should be calculated (null = all states) * @param statesOfInterest the set of states for which values should be calculated (null = all states)
* @return The product MDP * @return The product MDP
*/ */
public LTLProduct<MDP> constructProductMDP(DA<BitSet,AcceptanceRabin> dra, MDP mdp, Vector<BitSet> labelBS, BitSet statesOfInterest) throws PrismException
public LTLProduct<MDP> constructProductMDP(DA<BitSet,? extends AcceptanceOmega> da, MDP mdp, Vector<BitSet> labelBS, BitSet statesOfInterest) throws PrismException
{ {
MDPSimple prodModel = new MDPSimple(); MDPSimple prodModel = new MDPSimple();
int draSize = dra.size();
int numAPs = dra.getAPList().size();
int daSize = da.size();
int numAPs = da.getAPList().size();
int modelNumStates = mdp.getNumStates(); int modelNumStates = mdp.getNumStates();
int prodNumStates = modelNumStates * draSize;
int prodNumStates = modelNumStates * daSize;
int s_1, s_2, q_1, q_2; int s_1, s_2, q_1, q_2;
BitSet s_labels = new BitSet(numAPs); BitSet s_labels = new BitSet(numAPs);
AcceptanceRabin prodAcceptance;
List<State> prodStatesList = null; List<State> prodStatesList = null;
@ -477,15 +480,15 @@ public class LTLModelChecker extends PrismComponent
for (int s_0 : new IterableStateSet(statesOfInterest, mdp.getNumStates())) { for (int s_0 : new IterableStateSet(statesOfInterest, mdp.getNumStates())) {
// Get BitSet representing APs (labels) satisfied by state s_0 // Get BitSet representing APs (labels) satisfied by state s_0
for (int k = 0; k < numAPs; k++) { for (int k = 0; k < numAPs; k++) {
s_labels.set(k, labelBS.get(Integer.parseInt(dra.getAPList().get(k).substring(1))).get(s_0));
s_labels.set(k, labelBS.get(Integer.parseInt(da.getAPList().get(k).substring(1))).get(s_0));
} }
// Find corresponding initial state in DRA // Find corresponding initial state in DRA
int q_0 = dra.getEdgeDestByLabel(dra.getStartState(), s_labels);
int q_0 = da.getEdgeDestByLabel(da.getStartState(), s_labels);
// Add (initial) state to product // Add (initial) state to product
queue.add(new Point(s_0, q_0)); queue.add(new Point(s_0, q_0));
prodModel.addState(); prodModel.addState();
prodModel.addInitialState(prodModel.getNumStates() - 1); prodModel.addInitialState(prodModel.getNumStates() - 1);
map[s_0 * draSize + q_0] = prodModel.getNumStates() - 1;
map[s_0 * daSize + q_0] = prodModel.getNumStates() - 1;
if (prodStatesList != null) { if (prodStatesList != null) {
// store MDP state information for the product state // store MDP state information for the product state
prodStatesList.add(mdp.getStatesList().get(s_0)); prodStatesList.add(mdp.getStatesList().get(s_0));
@ -498,7 +501,7 @@ public class LTLModelChecker extends PrismComponent
Point p = queue.pop(); Point p = queue.pop();
s_1 = p.x; s_1 = p.x;
q_1 = p.y; q_1 = p.y;
visited.set(s_1 * draSize + q_1);
visited.set(s_1 * daSize + q_1);
// Go through transitions from state s_1 in original DTMC // Go through transitions from state s_1 in original DTMC
int numChoices = mdp.getNumChoices(s_1); int numChoices = mdp.getNumChoices(s_1);
@ -511,23 +514,23 @@ public class LTLModelChecker extends PrismComponent
double prob = e.getValue(); double prob = e.getValue();
// Get BitSet representing APs (labels) satisfied by successor state s_2 // Get BitSet representing APs (labels) satisfied by successor state s_2
for (int k = 0; k < numAPs; k++) { for (int k = 0; k < numAPs; k++) {
s_labels.set(k, labelBS.get(Integer.parseInt(dra.getAPList().get(k).substring(1))).get(s_2));
s_labels.set(k, labelBS.get(Integer.parseInt(da.getAPList().get(k).substring(1))).get(s_2));
} }
// Find corresponding successor in DRA // Find corresponding successor in DRA
q_2 = dra.getEdgeDestByLabel(q_1, s_labels);
q_2 = da.getEdgeDestByLabel(q_1, s_labels);
// Add state/transition to model // Add state/transition to model
if (!visited.get(s_2 * draSize + q_2) && map[s_2 * draSize + q_2] == -1) {
if (!visited.get(s_2 * daSize + q_2) && map[s_2 * daSize + q_2] == -1) {
queue.add(new Point(s_2, q_2)); queue.add(new Point(s_2, q_2));
prodModel.addState(); prodModel.addState();
map[s_2 * draSize + q_2] = prodModel.getNumStates() - 1;
map[s_2 * daSize + q_2] = prodModel.getNumStates() - 1;
if (prodStatesList != null) { if (prodStatesList != null) {
// store MDP state information for the product state // store MDP state information for the product state
prodStatesList.add(mdp.getStatesList().get(s_2)); prodStatesList.add(mdp.getStatesList().get(s_2));
} }
} }
prodDistr.set(map[s_2 * draSize + q_2], prob);
prodDistr.set(map[s_2 * daSize + q_2], prob);
} }
prodModel.addActionLabelledChoice(map[s_1 * draSize + q_1], prodDistr, mdp.getAction(s_1, j));
prodModel.addActionLabelledChoice(map[s_1 * daSize + q_1], prodDistr, mdp.getAction(s_1, j));
} }
} }
@ -545,15 +548,10 @@ public class LTLModelChecker extends PrismComponent
prodModel.setStatesList(prodStatesList); prodModel.setStatesList(prodStatesList);
} }
prodAcceptance = new AcceptanceRabin();
LTLProduct<MDP> product = new LTLProduct<MDP>(prodModel, mdp, prodAcceptance, draSize, invMap);
LTLProduct<MDP> product = new LTLProduct<MDP>(prodModel, mdp, null, daSize, invMap);
// generate acceptance for the product model by lifting // generate acceptance for the product model by lifting
for (AcceptanceRabin.RabinPair pair : dra.getAcceptance()) {
BitSet Lprod = product.liftFromAutomaton(pair.getL());
BitSet Kprod = product.liftFromAutomaton(pair.getK());
prodAcceptance.add(new AcceptanceRabin.RabinPair(Lprod, Kprod));
}
product.setAcceptance(liftAcceptance(product, da.getAcceptance()));
// lift the labels // lift the labels
for (String label : mdp.getLabels()) { for (String label : mdp.getLabels()) {
@ -565,11 +563,11 @@ public class LTLModelChecker extends PrismComponent
} }
/** /**
* Find the set of states belong to accepting BSCCs in a model wrt a Rabin acceptance condition.
* Find the set of states that belong to accepting BSCCs in a model wrt an acceptance condition.
* @param model The model * @param model The model
* @param acceptance The Rabin acceptance condition
* @param acceptance The acceptance condition
*/ */
public BitSet findAcceptingBSCCsForRabin(Model model, AcceptanceRabin acceptance) throws PrismException
public BitSet findAcceptingBSCCs(Model model, AcceptanceOmega acceptance) throws PrismException
{ {
// Compute bottom strongly connected components (BSCCs) // Compute bottom strongly connected components (BSCCs)
SCCComputer sccComputer = SCCComputer.createSCCComputer(this, model); SCCComputer sccComputer = SCCComputer.createSCCComputer(this, model);
@ -588,10 +586,25 @@ public class LTLModelChecker extends PrismComponent
return result; return result;
} }
/**
* Compute the set of states in end components of the model that are accepting
* with regard to the acceptance condition.
* @param model the model
* @param acceptance the acceptance condition
* @return BitSet with the set of states that are accepting
*/
public BitSet findAcceptingECStates(NondetModel model, AcceptanceOmega acceptance) throws PrismException
{
if (acceptance instanceof AcceptanceRabin) {
return findAcceptingECStatesForRabin(model, (AcceptanceRabin) acceptance);
}
throw new PrismException("Computing end components for acceptance type '"+acceptance.getTypeName()+"' currently not supported (explicit engine).");
}
/** /**
* Find the set of states in accepting end components (ECs) in a nondeterministic model wrt a Rabin acceptance condition. * Find the set of states in accepting end components (ECs) in a nondeterministic model wrt a Rabin acceptance condition.
* @param model The model * @param model The model
* @param acceptance the acceptance condition
* @param acceptance The acceptance condition
*/ */
public BitSet findAcceptingECStatesForRabin(NondetModel model, AcceptanceRabin acceptance) throws PrismException public BitSet findAcceptingECStatesForRabin(NondetModel model, AcceptanceRabin acceptance) throws PrismException
{ {
@ -626,4 +639,23 @@ public class LTLModelChecker extends PrismComponent
return allAcceptingStates; return allAcceptingStates;
} }
/** Lift the acceptance condition from the automaton to the product states. */
private AcceptanceOmega liftAcceptance(final LTLProduct<?> product, AcceptanceOmega acceptance)
{
// make a copy of the acceptance condition
AcceptanceOmega lifted = acceptance.clone();
// lift state sets
lifted.lift(new AcceptanceOmega.LiftBitSet() {
@Override
public BitSet lift(BitSet states)
{
return product.liftFromAutomaton(states);
}
});
return lifted;
}
} }

6
prism/src/explicit/MDPModelChecker.java

@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import acceptance.AcceptanceType;
import parser.ast.Expression; import parser.ast.Expression;
import prism.PrismComponent; import prism.PrismComponent;
import prism.PrismDevNullLog; import prism.PrismDevNullLog;
@ -75,11 +76,12 @@ public class MDPModelChecker extends ProbModelChecker
// For LTL model checking routines // For LTL model checking routines
mcLtl = new LTLModelChecker(this); mcLtl = new LTLModelChecker(this);
product = mcLtl.constructProductMDP(this, (MDP)model, expr, statesOfInterest);
AcceptanceType[] allowedAcceptance = {AcceptanceType.RABIN};
product = mcLtl.constructProductMDP(this, (MDP)model, expr, statesOfInterest, allowedAcceptance);
// Find accepting MECs + compute reachability probabilities // Find accepting MECs + compute reachability probabilities
mainLog.println("\nFinding accepting MECs..."); mainLog.println("\nFinding accepting MECs...");
BitSet acceptingMECs = mcLtl.findAcceptingECStatesForRabin(product.getProductModel(), product.getAcceptance());
BitSet acceptingMECs = mcLtl.findAcceptingECStates(product.getProductModel(), product.getAcceptance());
mainLog.println("\nComputing reachability probabilities..."); mainLog.println("\nComputing reachability probabilities...");
mcProduct = new MDPModelChecker(this); mcProduct = new MDPModelChecker(this);
mcProduct.inheritSettings(this); mcProduct.inheritSettings(this);

Loading…
Cancel
Save