diff --git a/prism/src/explicit/DTMCModelChecker.java b/prism/src/explicit/DTMCModelChecker.java index 2223cd0e..b50bb357 100644 --- a/prism/src/explicit/DTMCModelChecker.java +++ b/prism/src/explicit/DTMCModelChecker.java @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.BitSet; import java.util.List; import java.util.Map; +import java.util.Vector; import parser.VarList; import parser.ast.Declaration; @@ -43,7 +44,10 @@ import prism.PrismFileLog; import prism.PrismUtils; import acceptance.AcceptanceReach; import acceptance.AcceptanceType; +import automata.DA; import common.IterableBitSet; +import common.StopWatch; +import explicit.LTLModelChecker.LTLProduct; import explicit.rewards.MCRewards; import explicit.rewards.Rewards; @@ -140,21 +144,25 @@ public class DTMCModelChecker extends ProbModelChecker MCRewards productRewards; StateValues rewardsProduct, rewards; DTMCModelChecker mcProduct; - LTLModelChecker.LTLProduct product; + LTLProduct product; // For LTL model checking routines mcLtl = new LTLModelChecker(this); - // Build product of Markov chain and automaton - AcceptanceType[] allowedAcceptance = { - AcceptanceType.RABIN, - AcceptanceType.REACH - }; - product = mcLtl.constructProductMC(this, (DTMC)model, expr, statesOfInterest, allowedAcceptance); - + // Model check maximal state formulas and construct DFA, with the special + // handling needed for cosafety reward translation + Vector labelBS = new Vector(); + DA da = mcLtl.constructDFAForCosafetyRewardLTL(this, model, expr, labelBS); + + StopWatch timer = new StopWatch(mainLog); + mainLog.println("\nConstructing " + model.getModelType() + "-" + da.getAutomataType() + " product..."); + timer.start(model.getModelType() + "-" + da.getAutomataType() + " product"); + product = mcLtl.constructProductModel(da, (DTMC)model, labelBS, statesOfInterest); + timer.stop("product has " + product.getProductModel().infoString()); + // Adapt reward info to product model productRewards = ((MCRewards) modelRewards).liftFromModel(product); - + // Output product, if required if (getExportProductTrans()) { mainLog.println("\nExporting product transition matrix to file \"" + getExportProductTransFilename() + "\"..."); @@ -172,22 +180,16 @@ public class DTMCModelChecker extends ProbModelChecker product.getProductModel().exportStates(Prism.EXPORT_PLAIN, newVarList, out); out.close(); } - + // Find accepting states + compute reachability rewards - BitSet acc; - if (product.getAcceptance() instanceof AcceptanceReach) { - mainLog.println("\nSkipping BSCC computation since acceptance is defined via goal states..."); - acc = ((AcceptanceReach)product.getAcceptance()).getGoalStates(); - } else { - mainLog.println("\nFinding accepting BSCCs..."); - acc = mcLtl.findAcceptingBSCCs(product.getProductModel(), product.getAcceptance()); - } - mainLog.println("\nComputing reachability probabilities..."); + BitSet acc = ((AcceptanceReach)product.getAcceptance()).getGoalStates(); + + mainLog.println("\nComputing reachability rewards..."); mcProduct = new DTMCModelChecker(this); mcProduct.inheritSettings(this); - ModelCheckerResult res = mcProduct.computeReachRewards(product.getProductModel(), productRewards, acc); + ModelCheckerResult res = mcProduct.computeReachRewards((DTMC)product.getProductModel(), productRewards, acc); rewardsProduct = StateValues.createFromDoubleArray(res.soln, product.getProductModel()); - + // Output vector over product, if required if (getExportProductVector()) { mainLog.println("\nExporting product solution vector matrix to file \"" + getExportProductVectorFilename() + "\"..."); @@ -195,11 +197,11 @@ public class DTMCModelChecker extends ProbModelChecker rewardsProduct.print(out, false, false, false, false); out.close(); } - + // Mapping rewards in the original model rewards = product.projectToOriginalModel(rewardsProduct); rewardsProduct.clear(); - + return rewards; } diff --git a/prism/src/explicit/MDPModelChecker.java b/prism/src/explicit/MDPModelChecker.java index 47b686a2..b8406d23 100644 --- a/prism/src/explicit/MDPModelChecker.java +++ b/prism/src/explicit/MDPModelChecker.java @@ -31,8 +31,10 @@ import java.util.BitSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Vector; import common.IterableStateSet; +import common.StopWatch; import parser.VarList; import parser.ast.Declaration; import parser.ast.DeclarationIntUnbounded; @@ -48,6 +50,8 @@ import prism.PrismUtils; import strat.MDStrategyArray; import acceptance.AcceptanceReach; import acceptance.AcceptanceType; +import automata.DA; +import automata.LTL2WDBA; import common.IterableBitSet; import explicit.rewards.MCRewards; import explicit.rewards.MCRewardsFromMDPRewards; @@ -163,16 +167,20 @@ public class MDPModelChecker extends ProbModelChecker // For LTL model checking routines mcLtl = new LTLModelChecker(this); - // Build product of MDP and automaton - AcceptanceType[] allowedAcceptance = { - AcceptanceType.RABIN, - AcceptanceType.REACH - }; - product = mcLtl.constructProductMDP(this, (MDP)model, expr, statesOfInterest, allowedAcceptance); - + // Model check maximal state formulas and construct DFA, with the special + // handling needed for cosafety reward translation + Vector labelBS = new Vector(); + DA da = mcLtl.constructDFAForCosafetyRewardLTL(this, model, expr, labelBS); + + StopWatch timer = new StopWatch(getLog()); + mainLog.println("\nConstructing " + model.getModelType() + "-" + da.getAutomataType() + " product..."); + timer.start(model.getModelType() + "-" + da.getAutomataType() + " product"); + product = mcLtl.constructProductModel(da, (MDP)model, labelBS, statesOfInterest); + timer.stop("product has " + product.getProductModel().infoString()); + // Adapt reward info to product model productRewards = ((MDPRewards) modelRewards).liftFromModel(product); - + // Output product, if required if (getExportProductTrans()) { mainLog.println("\nExporting product transition matrix to file \"" + getExportProductTransFilename() + "\"..."); @@ -190,24 +198,16 @@ public class MDPModelChecker extends ProbModelChecker product.getProductModel().exportStates(Prism.EXPORT_PLAIN, newVarList, out); out.close(); } - + // Find accepting states + compute reachability rewards - BitSet acc; - if (product.getAcceptance() instanceof AcceptanceReach) { - // For a DFA, just collect the accept states - mainLog.println("\nSkipping end component detection since DRA is a DFA..."); - acc = ((AcceptanceReach)product.getAcceptance()).getGoalStates(); - } else { - // Usually, we have to detect end components in the product - mainLog.println("\nFinding accepting end components..."); - acc = mcLtl.findAcceptingECStates(product.getProductModel(), product.getAcceptance()); - } + BitSet acc = ((AcceptanceReach)product.getAcceptance()).getGoalStates(); + mainLog.println("\nComputing reachability rewards..."); mcProduct = new MDPModelChecker(this); mcProduct.inheritSettings(this); - ModelCheckerResult res = mcProduct.computeReachRewards(product.getProductModel(), productRewards, acc, minMax.isMin()); + ModelCheckerResult res = mcProduct.computeReachRewards((MDP)product.getProductModel(), productRewards, acc, minMax.isMin()); rewardsProduct = StateValues.createFromDoubleArray(res.soln, product.getProductModel()); - + // Output vector over product, if required if (getExportProductVector()) { mainLog.println("\nExporting product solution vector matrix to file \"" + getExportProductVectorFilename() + "\"..."); @@ -215,11 +215,11 @@ public class MDPModelChecker extends ProbModelChecker rewardsProduct.print(out, false, false, false, false); out.close(); } - + // Mapping rewards in the original model rewards = product.projectToOriginalModel(rewardsProduct); rewardsProduct.clear(); - + return rewards; }