Browse Source
Further work on simulator, including sampling.
Further work on simulator, including sampling.
git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@1874 bbc10eb1-c90d-0410-af57-cb519fbb1720master
17 changed files with 1554 additions and 222 deletions
-
2prism/src/simulator/Makefile
-
176prism/src/simulator/PathFull.java
-
198prism/src/simulator/PathOnTheFly.java
-
326prism/src/simulator/SimulatorEngine.java
-
10prism/src/simulator/Updater.java
-
205prism/src/simulator/sampler/Sampler.java
-
99prism/src/simulator/sampler/SamplerBoolean.java
-
114prism/src/simulator/sampler/SamplerBoundedUntilCont.java
-
84prism/src/simulator/sampler/SamplerBoundedUntilDisc.java
-
78prism/src/simulator/sampler/SamplerDouble.java
-
66prism/src/simulator/sampler/SamplerNext.java
-
75prism/src/simulator/sampler/SamplerRewardCumulCont.java
-
66prism/src/simulator/sampler/SamplerRewardCumulDisc.java
-
72prism/src/simulator/sampler/SamplerRewardInstCont.java
-
66prism/src/simulator/sampler/SamplerRewardInstDisc.java
-
65prism/src/simulator/sampler/SamplerRewardReach.java
-
74prism/src/simulator/sampler/SamplerUntil.java
@ -0,0 +1,198 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.*; |
|||
import parser.ast.*; |
|||
|
|||
/** |
|||
* Stores and manipulates a path though a model. |
|||
* Minimal info is stored - just enough to allow checking of properties. |
|||
* State objects and arrays are just stored as references to existing objects, but never modified. |
|||
* TODO: decide whether to copy states (we already copy rewards actually) |
|||
*/ |
|||
public class PathOnTheFly extends Path |
|||
{ |
|||
// Parent simulator engine |
|||
protected SimulatorEngine engine; |
|||
// Model to which the path corresponds |
|||
protected ModulesFile modulesFile; |
|||
// Does model use continuous time? |
|||
protected boolean continuousTime; |
|||
// Model info/stats |
|||
protected int numRewardStructs; |
|||
|
|||
// Path info required to implement Path abstract class: |
|||
protected int size; |
|||
protected State previousState; |
|||
protected State currentState; |
|||
protected double totalTime; |
|||
double timeInPreviousState; |
|||
protected double totalRewards[]; |
|||
protected double previousStateRewards[]; |
|||
protected double previousTransitionRewards[]; |
|||
protected double currentStateRewards[]; |
|||
|
|||
/** |
|||
* Constructor: creates a new (empty) PathOnTheFly object for a specific model. |
|||
*/ |
|||
public PathOnTheFly(SimulatorEngine engine, ModulesFile modulesFile) |
|||
{ |
|||
// Store ptr to engine |
|||
this.engine = engine; |
|||
// Store model and info |
|||
this.modulesFile = modulesFile; |
|||
continuousTime = modulesFile.getModelType().continuousTime(); |
|||
numRewardStructs = modulesFile.getNumRewardStructs(); |
|||
// Create arrays to store totals |
|||
totalRewards = new double[numRewardStructs]; |
|||
previousStateRewards = new double[numRewardStructs]; |
|||
previousTransitionRewards = new double[numRewardStructs]; |
|||
currentStateRewards = new double[numRewardStructs]; |
|||
// Initialise path info |
|||
clear(); |
|||
} |
|||
|
|||
/** |
|||
* Clear the path. |
|||
*/ |
|||
protected void clear() |
|||
{ |
|||
// Initialise all path info |
|||
size = 0; |
|||
previousState = null; |
|||
currentState = null; |
|||
totalTime = 0.0; |
|||
timeInPreviousState = 0.0; |
|||
for (int i = 0; i < numRewardStructs; i++) { |
|||
totalRewards[i] = 0.0; |
|||
previousStateRewards[i] = 0.0; |
|||
previousTransitionRewards[i] = 0.0; |
|||
currentStateRewards[i] = 0.0; |
|||
} |
|||
} |
|||
|
|||
// MUTATORS (for Path) |
|||
|
|||
@Override |
|||
public void initialise(State initialState, double[] initialStateRewards) |
|||
{ |
|||
clear(); |
|||
currentState = initialState; |
|||
currentStateRewards = initialStateRewards; |
|||
} |
|||
|
|||
/** |
|||
* Add a step to the path. |
|||
* The passed in State object and arrays (of rewards) will be stored as references, but never modified. |
|||
*/ |
|||
@Override |
|||
public void addStep(int choice, String action, double[] transRewards, State newState, double[] newStateRewards) |
|||
{ |
|||
addStep(0, choice, action, transRewards, newState, newStateRewards); |
|||
} |
|||
|
|||
/** |
|||
* Add a timed step to the path. |
|||
* The passed in State object and arrays (of rewards) will be stored as references, but never modified. |
|||
*/ |
|||
@Override |
|||
public void addStep(double time, int choice, String action, double[] transRewards, State newState, double[] newStateRewards) |
|||
{ |
|||
size = 0; |
|||
previousState = currentState; |
|||
currentState = newState; |
|||
totalTime += time; |
|||
timeInPreviousState = time; |
|||
for (int i = 0; i < numRewardStructs; i++) { |
|||
if (continuousTime) { |
|||
totalRewards[i] += currentStateRewards[i] * time + transRewards[i]; |
|||
} else { |
|||
totalRewards[i] += currentStateRewards[i] + transRewards[i]; |
|||
} |
|||
previousStateRewards[i] = currentStateRewards[i]; |
|||
previousTransitionRewards[i] = transRewards[i]; |
|||
currentStateRewards[i] = newStateRewards[i]; |
|||
} |
|||
} |
|||
|
|||
// ACCESSORS (for Path) |
|||
|
|||
@Override |
|||
public int size() |
|||
{ |
|||
return size; |
|||
} |
|||
|
|||
@Override |
|||
public State getPreviousState() |
|||
{ |
|||
return previousState; |
|||
} |
|||
|
|||
@Override |
|||
public State getCurrentState() |
|||
{ |
|||
return currentState; |
|||
} |
|||
|
|||
@Override |
|||
public double getTimeSoFar() |
|||
{ |
|||
return totalTime; |
|||
} |
|||
|
|||
@Override |
|||
public double getTimeInPreviousState() |
|||
{ |
|||
return timeInPreviousState; |
|||
} |
|||
|
|||
@Override |
|||
public double getRewardCumulatedSoFar(int index) |
|||
{ |
|||
return totalRewards[index]; |
|||
} |
|||
|
|||
@Override |
|||
public double getPreviousStateReward(int index) |
|||
{ |
|||
return previousStateRewards[index]; |
|||
} |
|||
|
|||
@Override |
|||
public double getPreviousTransitionReward(int index) |
|||
{ |
|||
return previousTransitionRewards[index]; |
|||
} |
|||
|
|||
@Override |
|||
public double getCurrentStateReward(int index) |
|||
{ |
|||
return currentStateRewards[index]; |
|||
} |
|||
} |
|||
@ -0,0 +1,205 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import parser.ast.*; |
|||
import prism.PrismException; |
|||
import prism.PrismLangException; |
|||
|
|||
/** |
|||
* Samplers: determine values based on a sequence of simulation paths. |
|||
*/ |
|||
public abstract class Sampler |
|||
{ |
|||
protected boolean valueKnown; |
|||
|
|||
/** |
|||
* Is the current value of the sampler known, based on the path seen so far? |
|||
*/ |
|||
public boolean isCurrentValueKnown() |
|||
{ |
|||
return valueKnown; |
|||
} |
|||
|
|||
/** |
|||
* Reset the current value of the sampler and whether it is known or not. |
|||
*/ |
|||
public abstract void reset(); |
|||
|
|||
/** |
|||
* Reset all statistics for the sampler. |
|||
*/ |
|||
public abstract void resetStats(); |
|||
|
|||
/** |
|||
* Update the current value of the sampler based on the current simulation path. |
|||
* It is assumed that this is called at every step of the path. |
|||
* It is also assumed that this is not called after the value becomes known. |
|||
*/ |
|||
public abstract void update(Path path) throws PrismLangException; |
|||
|
|||
/** |
|||
* Update the statistics for the sampler, assuming that the current path is finished. |
|||
*/ |
|||
public abstract void updateStats(); |
|||
|
|||
/** |
|||
* Get the current value of the sampler. |
|||
*/ |
|||
public abstract Object getCurrentValue(); |
|||
|
|||
/** |
|||
* Get the mean value of the sampler, over all paths seen. |
|||
*/ |
|||
public abstract Object getMeanValue(); |
|||
|
|||
// Static methods for sampler creation |
|||
|
|||
/** |
|||
* Create a sampler for an expression (P=? or R=?). |
|||
* Expression should contain no constants/formula/etc. |
|||
* The model to which the property applies should also be specified. |
|||
*/ |
|||
public static Sampler createSampler(Expression expr, ModulesFile mf) throws PrismException |
|||
{ |
|||
Sampler sampler = null; |
|||
// P=? |
|||
if (expr instanceof ExpressionProb) { |
|||
ExpressionProb propProb = (ExpressionProb) expr; |
|||
// Test whether this is a simple path formula (i.e. non-LTL) |
|||
if (propProb.getExpression().isSimplePathFormula()) { |
|||
sampler = createSamplerForProbPathPropertySimple(propProb.getExpression(), mf); |
|||
} else { |
|||
throw new PrismException("LTL-style path formulas are not supported by the simulator"); |
|||
} |
|||
} |
|||
// R=? |
|||
else if (expr instanceof ExpressionReward) { |
|||
sampler = createSamplerForRewardProperty((ExpressionReward) expr, mf); |
|||
} |
|||
// Neither |
|||
else { |
|||
throw new PrismException("Can't create sampler for property \"" + expr + "\""); |
|||
} |
|||
return sampler; |
|||
} |
|||
|
|||
private static SamplerBoolean createSamplerForProbPathPropertySimple(Expression expr, ModulesFile mf) throws PrismException |
|||
{ |
|||
// Negation/parentheses |
|||
if (expr instanceof ExpressionUnaryOp) { |
|||
ExpressionUnaryOp exprUnary = (ExpressionUnaryOp) expr; |
|||
// Parentheses |
|||
if (exprUnary.getOperator() == ExpressionUnaryOp.PARENTH) { |
|||
// Recurse |
|||
return createSamplerForProbPathPropertySimple(exprUnary.getOperand(), mf); |
|||
} |
|||
// Negation |
|||
else if (exprUnary.getOperator() == ExpressionUnaryOp.NOT) { |
|||
// Recurse, then negate meaning |
|||
SamplerBoolean sampler = createSamplerForProbPathPropertySimple(exprUnary.getOperand(), mf); |
|||
sampler.negate(); |
|||
return sampler; |
|||
} |
|||
} |
|||
// Temporal operators |
|||
else if (expr instanceof ExpressionTemporal) { |
|||
ExpressionTemporal exprTemp = (ExpressionTemporal) expr; |
|||
// Next |
|||
if (exprTemp.getOperator() == ExpressionTemporal.P_X) { |
|||
return new SamplerNext(exprTemp); |
|||
} |
|||
// Until |
|||
else if (exprTemp.getOperator() == ExpressionTemporal.P_U) { |
|||
if (exprTemp.hasBounds()) { |
|||
if (mf.getModelType().continuousTime()) { |
|||
// Continuous-time bounded until |
|||
return new SamplerBoundedUntilCont(exprTemp); |
|||
} else { |
|||
// Discrete-time bounded until |
|||
return new SamplerBoundedUntilDisc(exprTemp); |
|||
} |
|||
} else { |
|||
// Unbounded until |
|||
return new SamplerUntil(exprTemp); |
|||
} |
|||
} |
|||
// Anything else - convert to until and recurse |
|||
else { |
|||
return createSamplerForProbPathPropertySimple(exprTemp.convertToUntilForm(), mf); |
|||
} |
|||
} |
|||
|
|||
throw new PrismException("Can't create sampler for property \"" + expr + "\""); |
|||
} |
|||
|
|||
private static SamplerDouble createSamplerForRewardProperty(ExpressionReward expr, ModulesFile mf) throws PrismException |
|||
{ |
|||
// Extract reward structure index |
|||
Object rs = expr.getRewardStructIndex(); |
|||
int rsi = -1; |
|||
if (mf.getNumRewardStructs() == 0) |
|||
throw new PrismException("Model has no rewards specified"); |
|||
if (rs == null) { |
|||
rsi = 0; |
|||
} else if (rs instanceof Expression) { |
|||
rsi = ((Expression) rs).evaluateInt() - 1; |
|||
rs = new Integer(rsi + 1); // for better error reporting below |
|||
} else if (rs instanceof String) { |
|||
rsi = mf.getRewardStructIndex((String) rs); |
|||
} |
|||
if (rsi == -1) |
|||
throw new PrismException("Invalid reward structure index \"" + rs + "\""); |
|||
|
|||
// Construct sampler based on type |
|||
ExpressionTemporal exprTemp = (ExpressionTemporal) expr.getExpression(); |
|||
switch (exprTemp.getOperator()) { |
|||
case ExpressionTemporal.R_C: |
|||
if (mf.getModelType().continuousTime()) { |
|||
// Continuous-time cumulative reward |
|||
return new SamplerRewardCumulCont(exprTemp, rsi); |
|||
} else { |
|||
// Discrete-time cumulative reward |
|||
return new SamplerRewardCumulDisc(exprTemp, rsi); |
|||
} |
|||
case ExpressionTemporal.R_I: |
|||
if (mf.getModelType().continuousTime()) { |
|||
// Continuous-time instantaneous reward |
|||
return new SamplerRewardInstCont(exprTemp, rsi); |
|||
} else { |
|||
// Discrete-time instantaneous reward |
|||
return new SamplerRewardInstDisc(exprTemp, rsi); |
|||
} |
|||
case ExpressionTemporal.R_F: |
|||
// reachability reward |
|||
return new SamplerRewardReach(exprTemp, rsi); |
|||
} |
|||
|
|||
throw new PrismException("Can't create sampler for property \"" + expr + "\""); |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.PrismLangException; |
|||
|
|||
/** |
|||
* Samplers for properties that associate a simulation path with a Boolean value. |
|||
*/ |
|||
public abstract class SamplerBoolean extends Sampler |
|||
{ |
|||
// Value of current path |
|||
protected boolean value; |
|||
// Whether the actual value should be the negation of 'value' |
|||
protected boolean negated = false; |
|||
// Stats over all paths |
|||
protected int numSamples; |
|||
protected int numTrue; |
|||
|
|||
@Override |
|||
public void reset() |
|||
{ |
|||
valueKnown = false; |
|||
value = false; |
|||
} |
|||
|
|||
@Override |
|||
public void resetStats() |
|||
{ |
|||
numSamples = 0; |
|||
numTrue = 0; |
|||
} |
|||
|
|||
@Override |
|||
public abstract void update(Path path) throws PrismLangException; |
|||
|
|||
@Override |
|||
public void updateStats() |
|||
{ |
|||
numSamples++; |
|||
// XOR: value && !negated || !value && negated |
|||
if (value != negated) |
|||
numTrue++; |
|||
} |
|||
|
|||
@Override |
|||
public Object getCurrentValue() |
|||
{ |
|||
// XOR: value && !negated || !value && negated |
|||
return new Boolean(value != negated); |
|||
} |
|||
|
|||
@Override |
|||
public Object getMeanValue() |
|||
{ |
|||
return new Double(numTrue / (double) numSamples); |
|||
} |
|||
|
|||
/** |
|||
* Negate the meaning of this sampler. |
|||
*/ |
|||
public boolean negate() |
|||
{ |
|||
return negated = !negated; |
|||
} |
|||
|
|||
/** |
|||
* Is this sampler negated? |
|||
*/ |
|||
public boolean getNegated() |
|||
{ |
|||
return negated; |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
/** |
|||
* Construct a sampler for a (continuous-time) bounded until property. |
|||
* Passed in ExpressionTemporal should be a formula of this type. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public class SamplerBoundedUntilCont extends SamplerBoolean |
|||
{ |
|||
private Expression left; |
|||
private Expression right; |
|||
private double lb; |
|||
private double ub; |
|||
|
|||
/** |
|||
* Construct a sampler for a (continuous) time-bounded until formula. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerBoundedUntilCont(ExpressionTemporal expr) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.P_U) |
|||
throw new PrismException("Error creating Sampler"); |
|||
left = expr.getOperand1(); |
|||
right = expr.getOperand2(); |
|||
lb = expr.getLowerBound() == null ? 0.0 : expr.getLowerBound().evaluateDouble(); |
|||
ub = expr.getUpperBound() == null ? Double.POSITIVE_INFINITY: expr.getUpperBound().evaluateDouble(); |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
if (path.size() > 0) { |
|||
double time_so_far = path.getTimeSoFar(); |
|||
if (time_so_far > ub) { |
|||
// must take into account the possibility of missing lower bound |
|||
|
|||
// could have missed out evaluation of right |
|||
if (time_so_far - path.getTimeInPreviousState() <= lb) { |
|||
if (right.evaluateBoolean(path.getPreviousState())) { |
|||
valueKnown = true; |
|||
value = true; |
|||
} else { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} else { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} else if (time_so_far <= lb) { |
|||
if (!left.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} else { |
|||
if (right.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = true; |
|||
} else if (!left.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} |
|||
} else { |
|||
if (lb == 0.0) { |
|||
if (right.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = true; |
|||
} |
|||
} else { |
|||
if (!left.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerBoundedUntilDisc extends SamplerBoolean |
|||
{ |
|||
private Expression left; |
|||
private Expression right; |
|||
private int lb; |
|||
private int ub; |
|||
|
|||
/** |
|||
* Construct a sampler for a (discrete-time) bounded until property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerBoundedUntilDisc(ExpressionTemporal expr) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.P_U) |
|||
throw new PrismException("Error creating Sampler"); |
|||
left = expr.getOperand1(); |
|||
right = expr.getOperand2(); |
|||
lb = expr.getLowerBound() == null ? 0 : expr.getLowerBound().evaluateInt(); |
|||
ub = expr.getUpperBound() == null ? Integer.MAX_VALUE : expr.getUpperBound().evaluateInt(); |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
int pathSize = path.size(); |
|||
if (pathSize > ub) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} else if (pathSize < lb) { |
|||
if (!left.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} else { |
|||
State currentState = path.getCurrentState(); |
|||
if (right.evaluateBoolean(currentState)) { |
|||
valueKnown = true; |
|||
value = true; |
|||
} else if (!left.evaluateBoolean(currentState)) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.PrismLangException; |
|||
|
|||
/** |
|||
* Samplers for properties that associate a simulation path with a real (double) value. |
|||
*/ |
|||
public abstract class SamplerDouble extends Sampler |
|||
{ |
|||
// Value of current path |
|||
protected double value; |
|||
// Stats over all paths |
|||
protected double valueSum; |
|||
protected int numSamples; |
|||
|
|||
@Override |
|||
public void reset() |
|||
{ |
|||
valueKnown = false; |
|||
value = 0.0; |
|||
} |
|||
|
|||
@Override |
|||
public void resetStats() |
|||
{ |
|||
valueSum = 0.0; |
|||
numSamples = 0; |
|||
} |
|||
|
|||
@Override |
|||
public abstract void update(Path path) throws PrismLangException; |
|||
|
|||
@Override |
|||
public void updateStats() |
|||
{ |
|||
valueSum += value; |
|||
numSamples++; |
|||
} |
|||
|
|||
@Override |
|||
public Object getCurrentValue() |
|||
{ |
|||
return new Double(value); |
|||
} |
|||
|
|||
@Override |
|||
public Object getMeanValue() |
|||
{ |
|||
return new Double(valueSum / numSamples); |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerNext extends SamplerBoolean |
|||
{ |
|||
private Expression target; |
|||
|
|||
/** |
|||
* Construct a sampler for a "next" property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerNext(ExpressionTemporal expr) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.P_X) |
|||
throw new PrismException("Error creating Sampler"); |
|||
target = expr.getOperand2(); |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
// X "target" is true iff state 1 satisfies "target" |
|||
if (path.size() == 1) { |
|||
valueKnown = true; |
|||
value = target.evaluateBoolean(path.getCurrentState()); |
|||
} |
|||
// Nothing else to do: if path size is 0, can't decide; |
|||
// if path size > 1 (should never happen), nothing changes |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerRewardCumulCont extends SamplerDouble |
|||
{ |
|||
private double timeBound; |
|||
private int rewardStructIndex; |
|||
|
|||
/** |
|||
* Construct a sampler for a (continuous-time) cumulative reward property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* Reward structure index should also be specified. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerRewardCumulCont(ExpressionTemporal expr, int rewardStructIndex) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.R_C) |
|||
throw new PrismException("Error creating Sampler"); |
|||
timeBound = expr.getUpperBound().evaluateDouble(); |
|||
this.rewardStructIndex = rewardStructIndex; |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
// As soon as time bound exceeded, compute reward total |
|||
if (path.getTimeSoFar() >= timeBound) { |
|||
valueKnown = true; |
|||
value = path.getRewardCumulatedSoFar(rewardStructIndex); |
|||
// Compute excess time, i.e. how long ago time bound was reached |
|||
double excessTime = timeBound - path.getTimeSoFar(); |
|||
// If this is > 0 (very likely, unless time bound = 0), |
|||
// need to subtract reward accumulated in excess time |
|||
// (i.e. fraction of previous state reward, and transition reward) |
|||
if (excessTime > 0) { |
|||
value -= path.getPreviousStateReward(rewardStructIndex) * (excessTime / path.getTimeInPreviousState()); |
|||
value -= path.getPreviousTransitionReward(rewardStructIndex); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerRewardCumulDisc extends SamplerDouble |
|||
{ |
|||
private int timeBound; |
|||
private int rewardStructIndex; |
|||
|
|||
/** |
|||
* Construct a sampler for a (discrete-time) cumulative reward property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* Reward structure index should also be specified. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerRewardCumulDisc(ExpressionTemporal expr, int rewardStructIndex) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.R_C) |
|||
throw new PrismException("Error creating Sampler"); |
|||
timeBound = expr.getUpperBound().evaluateInt(); |
|||
this.rewardStructIndex = rewardStructIndex; |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
// As soon as time bound reached, store current reward total |
|||
if (path.size() == timeBound) { |
|||
valueKnown = true; |
|||
value = path.getRewardCumulatedSoFar(rewardStructIndex); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerRewardInstCont extends SamplerDouble |
|||
{ |
|||
private double time; |
|||
private int rewardStructIndex; |
|||
|
|||
/** |
|||
* Construct a sampler for a (continuous-time) instantaneous reward property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* Reward structure index should also be specified. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerRewardInstCont(ExpressionTemporal expr, int rewardStructIndex) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.R_C) |
|||
throw new PrismException("Error creating Sampler"); |
|||
time = expr.getUpperBound().evaluateDouble(); |
|||
this.rewardStructIndex = rewardStructIndex; |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
// As soon as time bound exceeded, compute reward |
|||
if (path.getTimeSoFar() >= time) { |
|||
valueKnown = true; |
|||
// Time bound was exceeded in either previous or current state |
|||
// (unless the time bound is 0, the latter is very unlikely) |
|||
if (path.getTimeSoFar() > time) { |
|||
value = path.getPreviousStateReward(rewardStructIndex); |
|||
} else { |
|||
value = path.getCurrentStateReward(rewardStructIndex); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerRewardInstDisc extends SamplerDouble |
|||
{ |
|||
private int time; |
|||
private int rewardStructIndex; |
|||
|
|||
/** |
|||
* Construct a sampler for a (discrete-time) instantaneous reward property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* Reward structure index should also be specified. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerRewardInstDisc(ExpressionTemporal expr, int rewardStructIndex) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.R_C) |
|||
throw new PrismException("Error creating Sampler"); |
|||
time = expr.getUpperBound().evaluateInt(); |
|||
this.rewardStructIndex = rewardStructIndex; |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
// As soon as time bound reached, store current state reward |
|||
if (path.size() == time) { |
|||
valueKnown = true; |
|||
value = path.getCurrentStateReward(rewardStructIndex); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import prism.*; |
|||
import parser.ast.*; |
|||
|
|||
public class SamplerRewardReach extends SamplerDouble |
|||
{ |
|||
private Expression target; |
|||
private int rewardStructIndex; |
|||
|
|||
/** |
|||
* Construct a sampler for a reachability reward property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* Reward structure index should also be specified. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerRewardReach(ExpressionTemporal expr, int rewardStructIndex) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.R_F) |
|||
throw new PrismException("Error creating Sampler"); |
|||
target = expr.getOperand2(); |
|||
this.rewardStructIndex = rewardStructIndex; |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
if (target.evaluateBoolean(path.getCurrentState())) { |
|||
valueKnown = true; |
|||
value = path.getRewardCumulatedSoFar(rewardStructIndex); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2002- |
|||
// 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.sampler; |
|||
|
|||
import simulator.*; |
|||
import parser.State; |
|||
import parser.ast.Expression; |
|||
import parser.ast.ExpressionTemporal; |
|||
import prism.PrismException; |
|||
import prism.PrismLangException; |
|||
|
|||
public class SamplerUntil extends SamplerBoolean |
|||
{ |
|||
private Expression left; |
|||
private Expression right; |
|||
|
|||
/** |
|||
* Construct a sampler for a (unbounded) until property. |
|||
* Passed in ExpressionTemporal should be a property of this type. |
|||
* All constants should have already been evaluated/replaced. |
|||
*/ |
|||
public SamplerUntil(ExpressionTemporal expr) throws PrismException |
|||
{ |
|||
// Make sure expression is of the correct type |
|||
// Then extract other required info |
|||
if (expr.getOperator() != ExpressionTemporal.P_U) |
|||
throw new PrismException("Error creating Sampler"); |
|||
left = expr.getOperand1(); |
|||
right = expr.getOperand2(); |
|||
// Initialise sampler info |
|||
reset(); |
|||
resetStats(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Path path) throws PrismLangException |
|||
{ |
|||
State currentState = path.getCurrentState(); |
|||
// Have we reached the target (i.e. RHS of until)? |
|||
if (right.evaluateBoolean(currentState)) { |
|||
valueKnown = true; |
|||
value = true; |
|||
} |
|||
// Or, if not, have we violated the LJS of the until? |
|||
else if (!left.evaluateBoolean(currentState)) { |
|||
valueKnown = true; |
|||
value = false; |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue