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