Browse Source
reintegrated fau
reintegrated fau
git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@6782 bbc10eb1-c90d-0410-af57-cb519fbb1720master
8 changed files with 2092 additions and 8 deletions
-
264prism/src/explicit/BirthProcess.java
-
1206prism/src/explicit/FastAdaptiveUniformisation.java
-
275prism/src/explicit/FastAdaptiveUniformisationModelChecker.java
-
99prism/src/explicit/ModelExplorer.java
-
19prism/src/prism/Prism.java
-
103prism/src/prism/PrismSettings.java
-
9prism/src/prism/PropertyConstants.java
-
125prism/src/simulator/PrismModelExplorer.java
@ -0,0 +1,264 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2013- |
||||
|
// Authors: |
||||
|
// * Dave Parker <david.parker@comlab.ox.ac.uk> (University of Oxford) |
||||
|
// * Frits Dannenberg <frits.dannenberg@cs.ox.ac.uk> (University of Oxford) |
||||
|
// * Ernst Moritz Hahn <emhahn@cs.ox.ac.uk> (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.ArrayList; |
||||
|
import prism.PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Class to efficiently compute transient probabilities of a birth process. |
||||
|
* |
||||
|
* @author Dave Parker <david.parker@comlab.ox.ac.uk> (University of Oxford) |
||||
|
* @author Frits Dannenberg <frits.dannenberg@cs.ox.ac.uk> (University of Oxford) |
||||
|
* @author Ernst Moritz Hahn <emhahn@cs.ox.ac.uk> (University of Oxford) |
||||
|
*/ |
||||
|
public class BirthProcess |
||||
|
{ |
||||
|
/* uniformisation rate to compute probabilities. |
||||
|
* Must be at least as large as largest rate. */ |
||||
|
double unifRate; |
||||
|
/* precision of computations using Fox-Glynn algorithm */ |
||||
|
double termCritParam; |
||||
|
/* time to compute probabilities for */ |
||||
|
double time; |
||||
|
/* values used to compute probability to be in a given stage */ |
||||
|
double[] probs; |
||||
|
/* same as above */ |
||||
|
double[] newProbs; |
||||
|
/* whether rates added by calculateNextRate will be stored */ |
||||
|
boolean withRateArray; |
||||
|
ArrayList<Double> jumpRates; |
||||
|
boolean initialising; |
||||
|
/* current birth process stage */ |
||||
|
int stageNr; |
||||
|
/* whether to try to avoid birth process computations in |
||||
|
* case all rates are the same |
||||
|
*/ |
||||
|
boolean avoidBirthComputation; |
||||
|
|
||||
|
/** |
||||
|
* Construct birth process. |
||||
|
*/ |
||||
|
public BirthProcess() |
||||
|
{ |
||||
|
stageNr = 0; |
||||
|
termCritParam = 1E-7; |
||||
|
withRateArray = true; |
||||
|
initialising = true; |
||||
|
avoidBirthComputation = true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets whether rates added by calculateNextRate will be stored. |
||||
|
* The default is to do so. Setting it to false allows to save space, |
||||
|
* but will not allow rates larger than @a unifRate to be added. |
||||
|
* |
||||
|
* @param withRateArray whether to store rates in array |
||||
|
*/ |
||||
|
public void setWithRateArray(boolean withRateArray) |
||||
|
{ |
||||
|
if (!initialising) { |
||||
|
throw new IllegalArgumentException("this method might not be called after calculateNextRate"); |
||||
|
} |
||||
|
this.withRateArray = withRateArray; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the time to compute probabilities for. |
||||
|
* |
||||
|
* @param time time to compute probabilities for |
||||
|
*/ |
||||
|
public void setTime(double time) |
||||
|
{ |
||||
|
if (!initialising) { |
||||
|
throw new IllegalArgumentException("this method might not be called after calculateNextRate"); |
||||
|
} |
||||
|
if (time < 0.0) { |
||||
|
throw new IllegalArgumentException("time must be nonnegative"); |
||||
|
} |
||||
|
this.time = time; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets precision to be used to compute probabilities. |
||||
|
* |
||||
|
* @param termCritParam precision to be used to compute probabilities |
||||
|
*/ |
||||
|
public void setTermCritParam(double termCritParam) |
||||
|
{ |
||||
|
if (!initialising) { |
||||
|
throw new IllegalArgumentException("this method might not be called after calculateNextRate"); |
||||
|
} |
||||
|
|
||||
|
this.termCritParam = termCritParam; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Chooses whether to try to avoid birth process construction. |
||||
|
* In case all rates provided to calculateNextProb are the same, it is |
||||
|
* possible to use the Fox-Glynn algorithm to compute probabilities in |
||||
|
* the birth process, which is then a Poisson process. If delayBirthComputation |
||||
|
* is true, the more expensive computations will only be computed in case |
||||
|
* this is necessary. Thus, if calculateNextProb is called with the same |
||||
|
* rate all the time, computations are significantly faster. |
||||
|
* |
||||
|
* @param avoidBirthComputation true iff birth process construction shall be delayed |
||||
|
*/ |
||||
|
public void setAvoidBirthComputation(boolean avoidBirthComputation) |
||||
|
{ |
||||
|
if (!initialising) { |
||||
|
throw new IllegalArgumentException("this method might not be called after calculateNextRate"); |
||||
|
} |
||||
|
this.avoidBirthComputation = avoidBirthComputation; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Computes probability to reside in next process stage at given time. |
||||
|
* If this is the nth call to the process, computes the probability |
||||
|
* to reside in the nth stage of the birth process. The rates of the |
||||
|
* birth process up to the n-1th stage have been set by previous calls |
||||
|
* to the function, the nth rate is set by the current call. The time |
||||
|
* probabilities are computed for must have been set previously by |
||||
|
* setTime. |
||||
|
* |
||||
|
* @param rate leaving rate of current state |
||||
|
* @return probability to reside in current stage at given time |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public double calculateNextProb(double rate) throws PrismException |
||||
|
{ |
||||
|
if (initialising && 0.0 == unifRate && !withRateArray) { |
||||
|
throw new IllegalArgumentException("unifRate must be set if withRateArray is false"); |
||||
|
} |
||||
|
if (withRateArray && initialising) { |
||||
|
jumpRates = new ArrayList<Double>(); |
||||
|
} |
||||
|
initialising = false; |
||||
|
if (!withRateArray && rate > unifRate) { |
||||
|
throw new IllegalArgumentException("cannot use rates larger than initial rate if withRateArray is false"); |
||||
|
} |
||||
|
if (withRateArray) { |
||||
|
jumpRates.add(rate); |
||||
|
} |
||||
|
boolean recompute = false; |
||||
|
if (rate > unifRate) { |
||||
|
if (!avoidBirthComputation) { |
||||
|
recompute = true; |
||||
|
unifRate = rate * 1.25 * 1.02; |
||||
|
} else { |
||||
|
unifRate = rate; |
||||
|
} |
||||
|
} |
||||
|
if ((jumpRates.size() != 1) && (Math.abs(rate - jumpRates.get(jumpRates.size() - 2)) > 1E-100)) { |
||||
|
if (avoidBirthComputation) { |
||||
|
recompute = true; |
||||
|
} |
||||
|
avoidBirthComputation = false; |
||||
|
} |
||||
|
|
||||
|
if (null == probs || recompute) { |
||||
|
initPoisson(); |
||||
|
} |
||||
|
double result = 0.0; |
||||
|
if (recompute) { |
||||
|
for (stageNr = 0; stageNr < jumpRates.size(); stageNr++) { |
||||
|
result = compNextStageProb(jumpRates.get(stageNr)); |
||||
|
} |
||||
|
} else { |
||||
|
if (avoidBirthComputation) { |
||||
|
result = (stageNr < probs.length) ? probs[stageNr] : 0.0; |
||||
|
stageNr++; |
||||
|
} else { |
||||
|
result = compNextStageProb(rate); |
||||
|
stageNr++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private double compNextStageProb(double rate) |
||||
|
{ |
||||
|
assert(rate > 0.0); |
||||
|
double prob = rate / unifRate; // p = r / q |
||||
|
double omprob = 1.0 - prob; // 1-p |
||||
|
double result = 0.0; |
||||
|
|
||||
|
double omprobtti = 1.0; // (1-p)^i |
||||
|
for (int i = 0; i < probs.length; i++) { |
||||
|
result += omprobtti * probs[i]; |
||||
|
omprobtti *= omprob; |
||||
|
} |
||||
|
|
||||
|
newProbs[newProbs.length - 1] = 0.0; |
||||
|
for (int i = probs.length - 1; i >= 1; i--) { |
||||
|
newProbs[i - 1] = newProbs[i] * omprob + probs[i] * prob; |
||||
|
} |
||||
|
double[] temp = probs; |
||||
|
probs = newProbs; |
||||
|
newProbs = temp; |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Initialises probability vectors by Poisson probabilities. |
||||
|
*/ |
||||
|
private void initPoisson() throws PrismException |
||||
|
{ |
||||
|
long left, right; |
||||
|
double qt = unifRate * time; |
||||
|
double acc = termCritParam / 8.0; |
||||
|
double[] weights; |
||||
|
double totalWeight; |
||||
|
if (unifRate * time == 0.0) { |
||||
|
left = 0; |
||||
|
right = 0; |
||||
|
totalWeight = 1.0; |
||||
|
weights = new double[1]; |
||||
|
weights[0] = 1.0; |
||||
|
} else { |
||||
|
FoxGlynn fg = new FoxGlynn(qt, 1e-300, 1e+300, acc); |
||||
|
left = fg.getLeftTruncationPoint(); |
||||
|
right = fg.getRightTruncationPoint(); |
||||
|
if (right < 0) { |
||||
|
throw new PrismException("Overflow in Fox-Glynn computation (time bound too big?)"); |
||||
|
} |
||||
|
weights = fg.getWeights(); |
||||
|
totalWeight = fg.getTotalWeight(); |
||||
|
} |
||||
|
for (long i = left; i <= right; i++) { |
||||
|
weights[(int) (i - left)] /= totalWeight; |
||||
|
} |
||||
|
probs = new double[(int) (right + 1)]; |
||||
|
newProbs = new double[(int) (right + 1)]; |
||||
|
for (long entryNr = left; entryNr <= right; entryNr++) { |
||||
|
probs[(int) entryNr] = weights[(int) (entryNr - left)]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
1206
prism/src/explicit/FastAdaptiveUniformisation.java
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,275 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2013- |
||||
|
// Authors: |
||||
|
// * Dave Parker <david.parker@comlab.ox.ac.uk> (University of Oxford) |
||||
|
// * Ernst Moritz Hahn <emhahn@cs.ox.ac.uk> (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 parser.Values; |
||||
|
import parser.ast.Expression; |
||||
|
import parser.ast.ExpressionProb; |
||||
|
import parser.ast.ExpressionReward; |
||||
|
import parser.ast.ExpressionTemporal; |
||||
|
import parser.ast.ModulesFile; |
||||
|
import parser.ast.PropertiesFile; |
||||
|
import parser.ast.LabelList; |
||||
|
import prism.Prism; |
||||
|
import prism.PrismException; |
||||
|
import prism.PrismLog; |
||||
|
import prism.Result; |
||||
|
import simulator.PrismModelExplorer; |
||||
|
import parser.ast.RewardStruct; |
||||
|
|
||||
|
/** |
||||
|
* CTMC model checker based on fast adaptive uniformisation. |
||||
|
*/ |
||||
|
public class FastAdaptiveUniformisationModelChecker |
||||
|
{ |
||||
|
// Prism object |
||||
|
private Prism prism; |
||||
|
// Log |
||||
|
private PrismLog mainLog; |
||||
|
// Model file |
||||
|
private ModulesFile modulesFile; |
||||
|
// Properties file |
||||
|
private PropertiesFile propertiesFile; |
||||
|
// Constants from model |
||||
|
private Values constantValues; |
||||
|
// Labels from the model |
||||
|
private LabelList labelListModel; |
||||
|
// Labels from the property file |
||||
|
private LabelList labelListProp; |
||||
|
|
||||
|
/** |
||||
|
* Constructor. |
||||
|
*/ |
||||
|
public FastAdaptiveUniformisationModelChecker(Prism prism, ModulesFile modulesFile, PropertiesFile propertiesFile) throws PrismException |
||||
|
{ |
||||
|
this.prism = prism; |
||||
|
mainLog = prism.getMainLog(); |
||||
|
this.modulesFile = modulesFile; |
||||
|
this.propertiesFile = propertiesFile; |
||||
|
|
||||
|
// Get combined constant values from model/properties |
||||
|
constantValues = new Values(); |
||||
|
constantValues.addValues(modulesFile.getConstantValues()); |
||||
|
if (propertiesFile != null) |
||||
|
constantValues.addValues(propertiesFile.getConstantValues()); |
||||
|
this.labelListModel = modulesFile.getLabelList(); |
||||
|
this.labelListProp = propertiesFile.getLabelList(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Model check a property. |
||||
|
*/ |
||||
|
public Result check(Expression expr) throws PrismException |
||||
|
{ |
||||
|
Result res; |
||||
|
String resultString; |
||||
|
long timer; |
||||
|
|
||||
|
// Starting model checking |
||||
|
timer = System.currentTimeMillis(); |
||||
|
|
||||
|
// Do model checking |
||||
|
res = checkExpression(expr); |
||||
|
|
||||
|
// Model checking complete |
||||
|
timer = System.currentTimeMillis() - timer; |
||||
|
mainLog.println("\nModel checking completed in " + (timer / 1000.0) + " secs."); |
||||
|
|
||||
|
// Print result to log |
||||
|
resultString = "Result"; |
||||
|
if (!("Result".equals(expr.getResultName()))) |
||||
|
resultString += " (" + expr.getResultName().toLowerCase() + ")"; |
||||
|
resultString += ": " + res; |
||||
|
mainLog.print("\n" + resultString + "\n"); |
||||
|
|
||||
|
// Return result |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Model check an expression (used recursively). |
||||
|
*/ |
||||
|
private Result checkExpression(Expression expr) throws PrismException |
||||
|
{ |
||||
|
Result res; |
||||
|
|
||||
|
// Current range of supported properties is quite limited... |
||||
|
if (expr instanceof ExpressionProb) |
||||
|
res = checkExpressionProb((ExpressionProb) expr); |
||||
|
else if (expr instanceof ExpressionReward) |
||||
|
res = checkExpressionReward((ExpressionReward) expr); |
||||
|
else |
||||
|
throw new PrismException("Fast adaptive uniformisation not yet supported for this operator"); |
||||
|
|
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Model check a P operator. |
||||
|
*/ |
||||
|
private Result checkExpressionProb(ExpressionProb expr) throws PrismException |
||||
|
{ |
||||
|
// Check whether P=? (only case allowed) |
||||
|
if (expr.getProb() != null) { |
||||
|
throw new PrismException("Fast adaptive uniformisation model checking currently only supports P=? properties"); |
||||
|
} |
||||
|
|
||||
|
if (!(expr.getExpression() instanceof ExpressionTemporal)) { |
||||
|
throw new PrismException("Fast adaptive uniformisation model checking currently only supports simple path operators"); |
||||
|
} |
||||
|
ExpressionTemporal exprTemp = (ExpressionTemporal) expr.getExpression(); |
||||
|
if (!exprTemp.isSimplePathFormula()) { |
||||
|
throw new PrismException("Fast adaptive uniformisation window model checking currently only supports simple until operators"); |
||||
|
} |
||||
|
|
||||
|
double timeLower = 0.0; |
||||
|
if (exprTemp.getLowerBound() != null) { |
||||
|
timeLower = exprTemp.getLowerBound().evaluateDouble(constantValues); |
||||
|
} |
||||
|
if (exprTemp.getUpperBound() == null) { |
||||
|
throw new PrismException("Fast adaptive uniformisation window model checking currently requires an upper time bound"); |
||||
|
} |
||||
|
double timeUpper = exprTemp.getUpperBound().evaluateDouble(constantValues); |
||||
|
|
||||
|
if (!exprTemp.hasBounds()) { |
||||
|
throw new PrismException("Fast adaptive uniformisation window model checking currently only supports timed properties"); |
||||
|
} |
||||
|
|
||||
|
mainLog.println("Starting transient probability computation using fast adaptive uniformisation..."); |
||||
|
PrismModelExplorer modelExplorer = new PrismModelExplorer(prism.getSimulator(), modulesFile); |
||||
|
FastAdaptiveUniformisation fau = new FastAdaptiveUniformisation(prism.getSettings(), modelExplorer); |
||||
|
fau.setConstantValues(constantValues); |
||||
|
|
||||
|
Expression op1 = exprTemp.getOperand1(); |
||||
|
if (op1 == null) { |
||||
|
op1 = Expression.True(); |
||||
|
} |
||||
|
Expression op2 = exprTemp.getOperand2(); |
||||
|
op1 = (Expression) op1.expandPropRefsAndLabels(propertiesFile, labelListModel); |
||||
|
op1 = (Expression) op1.expandPropRefsAndLabels(propertiesFile, labelListProp); |
||||
|
op2 = (Expression) op2.expandPropRefsAndLabels(propertiesFile, labelListModel); |
||||
|
op2 = (Expression) op2.expandPropRefsAndLabels(propertiesFile, labelListProp); |
||||
|
int operator = exprTemp.getOperator(); |
||||
|
|
||||
|
Expression sink = null; |
||||
|
Expression target = null; |
||||
|
switch (operator) { |
||||
|
case ExpressionTemporal.P_U: |
||||
|
case ExpressionTemporal.P_F: |
||||
|
sink = Expression.Not(op1); |
||||
|
break; |
||||
|
case ExpressionTemporal.P_G: |
||||
|
sink = Expression.False(); |
||||
|
break; |
||||
|
case ExpressionTemporal.P_W: |
||||
|
case ExpressionTemporal.P_R: |
||||
|
default: |
||||
|
throw new PrismException("operator currently not supported for fast adaptive uniformisation"); |
||||
|
} |
||||
|
|
||||
|
fau.setSink(sink); |
||||
|
fau.computeTransientProbsAdaptive(timeLower); |
||||
|
switch (operator) { |
||||
|
case ExpressionTemporal.P_U: |
||||
|
case ExpressionTemporal.P_F: |
||||
|
sink = Expression.Or(Expression.Not(op1), op2); |
||||
|
target = op2; |
||||
|
break; |
||||
|
case ExpressionTemporal.P_G: |
||||
|
sink = Expression.Not(op2); |
||||
|
target = op2; |
||||
|
break; |
||||
|
case ExpressionTemporal.P_W: |
||||
|
case ExpressionTemporal.P_R: |
||||
|
default: |
||||
|
throw new PrismException("operator currently not supported for fast adaptive uniformisation"); |
||||
|
} |
||||
|
Values varValues = new Values(); |
||||
|
varValues.addValue("deadlock", "true"); |
||||
|
sink.replaceVars(varValues); |
||||
|
fau.setAnalysisType(FastAdaptiveUniformisation.AnalysisType.REACH); |
||||
|
fau.setSink(sink); |
||||
|
fau.setTarget(target); |
||||
|
fau.computeTransientProbsAdaptive(timeUpper - timeLower); |
||||
|
mainLog.println("\nTotal probability lost is : " + fau.getTotalDiscreteLoss()); |
||||
|
mainLog.println("Maximal number of states stored during analysis : " + fau.getMaxNumStates()); |
||||
|
|
||||
|
return new Result(new Double(fau.getValue())); |
||||
|
} |
||||
|
|
||||
|
private RewardStruct findRewardStruct(ExpressionReward expr) throws PrismException |
||||
|
{ |
||||
|
RewardStruct rewStruct = null; |
||||
|
Object rs = expr.getRewardStructIndex(); |
||||
|
if (modulesFile == null) |
||||
|
throw new PrismException("No model file to obtain reward structures"); |
||||
|
if (modulesFile.getNumRewardStructs() == 0) |
||||
|
throw new PrismException("Model has no rewards specified"); |
||||
|
if (rs == null) { |
||||
|
rewStruct = modulesFile.getRewardStruct(0); |
||||
|
} else if (rs instanceof Expression) { |
||||
|
int i = ((Expression) rs).evaluateInt(constantValues); |
||||
|
rs = new Integer(i); // for better error reporting below |
||||
|
rewStruct = modulesFile.getRewardStruct(i - 1); |
||||
|
} else if (rs instanceof String) { |
||||
|
rewStruct = modulesFile.getRewardStructByName((String) rs); |
||||
|
} |
||||
|
if (rewStruct == null) |
||||
|
throw new PrismException("Invalid reward structure index \"" + rs + "\""); |
||||
|
return rewStruct; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Model check an R operator. |
||||
|
*/ |
||||
|
private Result checkExpressionReward(ExpressionReward expr) throws PrismException |
||||
|
{ |
||||
|
mainLog.println("Starting transient probability computation using fast adaptive uniformisation..."); |
||||
|
PrismModelExplorer modelExplorer = new PrismModelExplorer(prism.getSimulator(), modulesFile); |
||||
|
FastAdaptiveUniformisation fau = new FastAdaptiveUniformisation(prism.getSettings(), modelExplorer); |
||||
|
ExpressionTemporal temporal = (ExpressionTemporal) expr.getExpression(); |
||||
|
switch (temporal.getOperator()) { |
||||
|
case ExpressionTemporal.R_I: |
||||
|
fau.setAnalysisType(FastAdaptiveUniformisation.AnalysisType.REW_INST); |
||||
|
break; |
||||
|
case ExpressionTemporal.R_C: |
||||
|
fau.setAnalysisType(FastAdaptiveUniformisation.AnalysisType.REW_CUMUL); |
||||
|
break; |
||||
|
default: |
||||
|
throw new PrismException("Currently only instantaneous or cumulative rewards are allowed."); |
||||
|
} |
||||
|
double time = temporal.getUpperBound().evaluateDouble(constantValues); |
||||
|
RewardStruct rewStruct = findRewardStruct(expr); |
||||
|
fau.setRewardStruct(rewStruct); |
||||
|
fau.setConstantValues(constantValues); |
||||
|
fau.computeTransientProbsAdaptive(time); |
||||
|
mainLog.println("\nTotal probability lost is : " + fau.getTotalDiscreteLoss()); |
||||
|
mainLog.println("Maximal number of states stored during analysis : " + fau.getMaxNumStates()); |
||||
|
return new Result(new Double(fau.getValue())); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,99 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Authors: |
||||
|
// * Dave Parker <david.parker@comlab.ox.ac.uk> (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 parser.State; |
||||
|
import prism.PrismException; |
||||
|
|
||||
|
public interface ModelExplorer |
||||
|
{ |
||||
|
public State getDefaultInitialState() throws PrismException; |
||||
|
|
||||
|
public void queryState(State state) throws PrismException; |
||||
|
|
||||
|
public void queryState(State state, double time) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Returns the current number of available choices. |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public int getNumChoices() throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Returns the current (total) number of available transitions. |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public int getNumTransitions() throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Returns the current number of available transitions in choice i. |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public int getNumTransitions(int i) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the probability/rate of a transition within a choice, specified by its index/offset. |
||||
|
*/ |
||||
|
public double getTransitionProbability(int i, int offset) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the action label of a transition as a string, specified by its index/offset. |
||||
|
* (null for asynchronous/independent transitions) |
||||
|
* (see also {@link #getTransitionModuleOrAction(int, int)} and {@link #getTransitionModuleOrActionIndex(int, int)}) |
||||
|
* TODO: change return type to Object? |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public String getTransitionAction(int i, int offset) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the action label of a transition as a string, specified by its index. |
||||
|
* (null for asynchronous/independent transitions) |
||||
|
* (see also {@link #getTransitionModuleOrAction(int)} and {@link #getTransitionModuleOrActionIndex(int)}) |
||||
|
* TODO: change return type to Object? |
||||
|
* @throws PrismException |
||||
|
*/ |
||||
|
public String getTransitionAction(int index) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the probability/rate of a transition, specified by its index. |
||||
|
*/ |
||||
|
public double getTransitionProbability(int i) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the sum of probabilities/rates for transitions. |
||||
|
*/ |
||||
|
// public double getTransitionProbabilitySum() throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the target (as a new State object) of a transition within a choice, specified by its index/offset. |
||||
|
*/ |
||||
|
public State computeTransitionTarget(int i, int offset) throws PrismException; |
||||
|
|
||||
|
/** |
||||
|
* Get the target of a transition (as a new State object), specified by its index. |
||||
|
*/ |
||||
|
public State computeTransitionTarget(int i) throws PrismException; |
||||
|
} |
||||
@ -0,0 +1,125 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Authors: |
||||
|
// * Dave Parker <david.parker@comlab.ox.ac.uk> (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 simulator; |
||||
|
|
||||
|
import parser.State; |
||||
|
import parser.ast.ModulesFile; |
||||
|
import prism.PrismException; |
||||
|
import explicit.ModelExplorer; |
||||
|
|
||||
|
public class PrismModelExplorer implements ModelExplorer |
||||
|
{ |
||||
|
private SimulatorEngine simEngine; |
||||
|
private ModulesFile modulesFile; |
||||
|
|
||||
|
public PrismModelExplorer(SimulatorEngine simEngine, ModulesFile modulesFile) throws PrismException |
||||
|
{ |
||||
|
this.simEngine = simEngine; |
||||
|
this.modulesFile = modulesFile; |
||||
|
simEngine.createNewOnTheFlyPath(modulesFile); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public State getDefaultInitialState() throws PrismException |
||||
|
{ |
||||
|
return modulesFile.getDefaultInitialState(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void queryState(State state) throws PrismException |
||||
|
{ |
||||
|
simEngine.initialisePath(state); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void queryState(State state, double time) throws PrismException |
||||
|
{ |
||||
|
queryState(state); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getNumChoices() throws PrismException |
||||
|
{ |
||||
|
return simEngine.getNumChoices(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getNumTransitions() throws PrismException |
||||
|
{ |
||||
|
return simEngine.getNumTransitions(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getNumTransitions(int i) throws PrismException |
||||
|
{ |
||||
|
return simEngine.getNumTransitions(i); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getTransitionAction(int i, int offset) throws PrismException |
||||
|
{ |
||||
|
return simEngine.getTransitionAction(i, offset); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getTransitionAction(int i) throws PrismException |
||||
|
{ |
||||
|
return simEngine.getTransitionAction(i); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public double getTransitionProbability(int i, int offset) throws PrismException |
||||
|
{ |
||||
|
return simEngine.getTransitionProbability(i, offset); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public double getTransitionProbability(int i) throws PrismException |
||||
|
{ |
||||
|
return simEngine.getTransitionProbability(i); |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
@Override |
||||
|
public double getTransitionProbabilitySum() throws PrismException |
||||
|
{ |
||||
|
return simEngine.getTransitionProbabilitySum(); |
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
@Override |
||||
|
public State computeTransitionTarget(int i, int offset) throws PrismException |
||||
|
{ |
||||
|
return simEngine.computeTransitionTarget(i, offset); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public State computeTransitionTarget(int i) throws PrismException |
||||
|
{ |
||||
|
return simEngine.computeTransitionTarget(i); |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue