Browse Source

* Continued major changes to PRISM API

- keeps track of model, builds when needed
  - takes care of explicit engine stuff too
* Changes to deadlock handling:
  - new option for "fix deadlocks" (defaults to *true*) (and new switch -fixdl) 
  - consistent deadlock handling everywhere, incl. GUI and experiments
  - changes to model-level deadlock storage (symbolic and explicit)
* Explicit engine added as true engine, also available from GUI



git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@4562 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Dave Parker 14 years ago
parent
commit
a218d09b2b
  1. 21
      prism/src/explicit/ConstructModel.java
  2. 11
      prism/src/explicit/DTMCEmbeddedSimple.java
  3. 11
      prism/src/explicit/DTMCFromMDPMemorylessAdversary.java
  4. 26
      prism/src/explicit/DTMCSimple.java
  5. 11
      prism/src/explicit/DTMCUniformisedSimple.java
  6. 33
      prism/src/explicit/MDPSimple.java
  7. 27
      prism/src/explicit/MDPSparse.java
  8. 26
      prism/src/explicit/Model.java
  9. 25
      prism/src/explicit/ModelExplicit.java
  10. 7
      prism/src/explicit/PrismExplicit.java
  11. 39
      prism/src/explicit/STPGAbstrSimple.java
  12. 2
      prism/src/explicit/StateModelChecker.java
  13. 2
      prism/src/prism/ExplicitFiles2MTBDD.java
  14. 2
      prism/src/prism/ExplicitModel2MTBDD.java
  15. 6
      prism/src/prism/LTLModelChecker.java
  16. 24
      prism/src/prism/Model.java
  17. 4
      prism/src/prism/Modules2MTBDD.java
  18. 24
      prism/src/prism/NondetModel.java
  19. 2
      prism/src/prism/NondetModelChecker.java
  20. 952
      prism/src/prism/Prism.java
  21. 342
      prism/src/prism/PrismCL.java
  22. 33
      prism/src/prism/PrismModelListener.java
  23. 20
      prism/src/prism/PrismSettings.java
  24. 34
      prism/src/prism/ProbModel.java
  25. 2
      prism/src/prism/StateModelChecker.java
  26. 112
      prism/src/userinterface/model/GUIModelEvent.java
  27. 699
      prism/src/userinterface/model/GUIMultiModel.java
  28. 2888
      prism/src/userinterface/model/GUIMultiModelHandler.java
  29. 231
      prism/src/userinterface/model/computation/BuildModelThread.java
  30. 31
      prism/src/userinterface/model/computation/ComputeSteadyStateThread.java
  31. 27
      prism/src/userinterface/model/computation/ComputeTransientThread.java
  32. 106
      prism/src/userinterface/model/computation/ExportBuiltModelThread.java
  33. 81
      prism/src/userinterface/model/computation/ParseModelThread.java
  34. 155
      prism/src/userinterface/properties/GUIExperiment.java
  35. 4
      prism/src/userinterface/properties/GUIExperimentTable.java
  36. 93
      prism/src/userinterface/properties/GUIMultiProperties.java
  37. 77
      prism/src/userinterface/properties/computation/ModelCheckThread.java
  38. 58
      prism/src/userinterface/properties/computation/SimulateModelCheckThread.java

21
prism/src/explicit/ConstructModel.java

@ -41,6 +41,12 @@ public class ConstructModel
private SimulatorEngine engine;
private PrismLog mainLog;
// Options:
// Find deadlocks during model construction?
private boolean findDeadlocks = true;
// Automatically fix deadlocks?
private boolean fixDeadlocks = true;
// Basic info needed about model
// private ModelType modelType;
@ -58,6 +64,11 @@ public class ConstructModel
return statesList;
}
public void setFixDeadlocks(boolean b)
{
fixDeadlocks = b;
}
/**
* Build the set of reachable states for a PRISM model language description and return.
* @param modulesFile The PRISM model
@ -118,7 +129,6 @@ public class ConstructModel
// Misc
int i, j, nc, nt, src, dest;
long timer, timerProgress;
boolean fixdl = false;
// Don't support multiple initial states
if (modulesFile.getInitialStates() != null) {
@ -249,12 +259,9 @@ public class ConstructModel
mainLog.println(" done in " + ((System.currentTimeMillis() - timer) / 1000.0) + " secs.");
//mainLog.println(states);
// Fix deadlocks (if required)
if (!justReach && fixdl) {
BitSet deadlocks = modelSimple.findDeadlocks(true);
if (deadlocks.cardinality() > 0) {
mainLog.println("Added self-loops in " + deadlocks.cardinality() + " states...");
}
// Find/fix deadlocks (if required)
if (!justReach && findDeadlocks) {
modelSimple.findDeadlocks(fixDeadlocks);
}
boolean sort = true;

11
prism/src/explicit/DTMCEmbeddedSimple.java

@ -105,9 +105,9 @@ public class DTMCEmbeddedSimple extends DTMCExplicit
return ctmc.isInitialState(i);
}
public boolean isFixedDeadlockState(int i)
public boolean isDeadlockState(int i)
{
return ctmc.isFixedDeadlockState(i);
return ctmc.isDeadlockState(i);
}
public List<State> getStatesList()
@ -146,20 +146,19 @@ public class DTMCEmbeddedSimple extends DTMCExplicit
return 1;
}
public void checkForDeadlocks() throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
// No deadlocks by definition
}
public void checkForDeadlocks(BitSet except) throws PrismException
public void checkForDeadlocks() throws PrismException
{
// No deadlocks by definition
}
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
// No deadlocks by definition
return new BitSet();
}
@Override

11
prism/src/explicit/DTMCFromMDPMemorylessAdversary.java

@ -97,9 +97,9 @@ public class DTMCFromMDPMemorylessAdversary extends DTMCExplicit
return mdp.isInitialState(i);
}
public boolean isFixedDeadlockState(int i)
public boolean isDeadlockState(int i)
{
return mdp.isFixedDeadlockState(i);
return mdp.isDeadlockState(i);
}
public List<State> getStatesList()
@ -138,20 +138,19 @@ public class DTMCFromMDPMemorylessAdversary extends DTMCExplicit
return 1;
}
public void checkForDeadlocks() throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
// No deadlocks by definition
}
public void checkForDeadlocks(BitSet except) throws PrismException
public void checkForDeadlocks() throws PrismException
{
// No deadlocks by definition
}
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
// No deadlocks by definition
return new BitSet();
}
@Override

26
prism/src/explicit/DTMCSimple.java

@ -238,30 +238,24 @@ public class DTMCSimple extends DTMCExplicit implements ModelSimple
}
@Override
public void checkForDeadlocks(BitSet except) throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("DTMC has a deadlock in state " + i);
if (trans.get(i).isEmpty()) {
addDeadlockState(i);
if (fix)
setProbability(i, i, 1.0);
}
}
}
@Override
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
int i;
BitSet deadlocks = new BitSet();
for (i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty())
deadlocks.set(i);
}
if (fix) {
for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) {
setProbability(i, i, 1.0);
addFixedDeadlockState(i);
}
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("DTMC has a deadlock in state " + i);
}
return deadlocks;
}
// Accessors (for DTMC)

11
prism/src/explicit/DTMCUniformisedSimple.java

@ -114,9 +114,9 @@ public class DTMCUniformisedSimple extends DTMCExplicit
return ctmc.isInitialState(i);
}
public boolean isFixedDeadlockState(int i)
public boolean isDeadlockState(int i)
{
return ctmc.isFixedDeadlockState(i);
return ctmc.isDeadlockState(i);
}
public List<State> getStatesList()
@ -158,20 +158,19 @@ public class DTMCUniformisedSimple extends DTMCExplicit
return 1;
}
public void checkForDeadlocks() throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
// No deadlocks by definition
}
public void checkForDeadlocks(BitSet except) throws PrismException
public void checkForDeadlocks() throws PrismException
{
// No deadlocks by definition
}
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
// No deadlocks by definition
return new BitSet();
}
@Override

33
prism/src/explicit/MDPSimple.java

@ -426,33 +426,28 @@ public class MDPSimple extends MDPExplicit implements ModelSimple
}
@Override
public void checkForDeadlocks(BitSet except) throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("MDP has a deadlock in state " + i);
// Note that no distributions is a deadlock, not an empty distribution
if (trans.get(i).isEmpty()) {
addDeadlockState(i);
if (fix) {
Distribution distr = new Distribution();
distr.add(i, 1.0);
addChoice(i, distr);
}
}
}
}
@Override
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
int i;
BitSet deadlocks = new BitSet();
for (i = 0; i < numStates; i++) {
// Note that no distributions is a deadlock, not an empty distribution
if (trans.get(i).isEmpty())
deadlocks.set(i);
}
if (fix) {
for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) {
Distribution distr = new Distribution();
distr.add(i, 1.0);
addChoice(i, distr);
addFixedDeadlockState(i);
}
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("MDP has a deadlock in state " + i);
}
return deadlocks;
}
// Accessors (for MDP)

27
prism/src/explicit/MDPSparse.java

@ -439,29 +439,26 @@ public class MDPSparse extends MDPExplicit
}
@Override
public void checkForDeadlocks(BitSet except) throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
for (int i = 0; i < numStates; i++) {
if (getNumChoices(i) == 0 && (except == null || !except.get(i)))
throw new PrismException("MDP has a deadlock in state " + i);
// Note that no distributions is a deadlock, not an empty distribution
if (getNumChoices(i) == 0) {
addDeadlockState(i);
if (fix) {
throw new PrismException("Can't fix deadlocks in an MDPSparse since it cannot be modified after construction");
}
}
}
}
@Override
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
int i;
BitSet deadlocks = new BitSet();
for (i = 0; i < numStates; i++) {
// Note that no distributions is a deadlock, not an empty distribution
if (getNumChoices(i) == 0)
deadlocks.set(i);
}
if (fix) {
// TODO disallow this call?
throw new RuntimeException("Can't modify this model");
for (int i = 0; i < numStates; i++) {
if (getNumChoices(i) == 0 && (except == null || !except.get(i)))
throw new PrismException("MDP has a deadlock in state " + i);
}
return deadlocks;
}
// Accessors (for MDP)

26
prism/src/explicit/Model.java

@ -75,11 +75,16 @@ public interface Model
public boolean isInitialState(int i);
/**
* Check whether a state is a "fixed" deadlock, i.e. a state that was
* originally a deadlock but has been fixed through the addition of a self-loop,
* or a state that is still a deadlock but in a model where this acceptable, e.g. a CTMC.
* Get the number of states that are/were deadlocks.
* (Such states may have been fixed at build-time by adding self-loops)
*/
public boolean isFixedDeadlockState(int i);
public int getNumDeadlockStates();
/**
* Check whether a state is/was deadlock.
* (Such states may have been fixed at build-time by adding self-loops)
*/
public boolean isDeadlockState(int i);
/**
* Get access to an (optional) list of states.
@ -121,16 +126,17 @@ public interface Model
public int getNumChoices(int s);
/**
* Checks for deadlocks and throws an exception if any exist.
* Find all deadlock states and store this information in the model.
* If requested (if fix=true) and if needed (i.e. for DTMCs/CTMCs),
* fix deadlocks by adding self-loops in these states.
* The set of deadlocks (before any possible fixing) can be obtained from {@link #getDeadlocks()}.
*/
public void checkForDeadlocks() throws PrismException;
public void findDeadlocks(boolean fix) throws PrismException;
/**
* Find all deadlocks and return a BitSet of these states.
* If requested (if fix=true), then add self-loops in these states
* (and update the "fixed" deadlock information).
* Checks for deadlocks and throws an exception if any exist.
*/
public BitSet findDeadlocks(boolean fix) throws PrismException;
public void checkForDeadlocks() throws PrismException;
/**
* Checks for deadlocks and throws an exception if any exist.

25
prism/src/explicit/ModelExplicit.java

@ -46,11 +46,10 @@ public abstract class ModelExplicit implements Model
// Initial states
protected List<Integer> initialStates; // TODO: should be a (linkedhash?) set really
/**
* States with deadlocks that have been "fixed", i.e. a state that was
* originally a deadlock but has been fixed through the addition of a self-loop,
* or a state that is still a deadlock but in a model where this acceptable, e.g. a CTMC.
* States that are/were deadlocks. Where requested and where appropriate (DTMCs/MDPs),
* these states may have been fixed at build time by adding self-loops.
*/
protected TreeSet<Integer> deadlocksFixed;
protected TreeSet<Integer> deadlocks;
// State info (read only, just a pointer)
protected List<State> statesList;
// Constant info (read only, just a pointer)
@ -99,7 +98,7 @@ public abstract class ModelExplicit implements Model
{
this.numStates = numStates;
initialStates = new ArrayList<Integer>();
deadlocksFixed = new TreeSet<Integer>();
deadlocks = new TreeSet<Integer>();
statesList = null;
}
@ -112,11 +111,11 @@ public abstract class ModelExplicit implements Model
}
/**
* Add a state to the list of "fixed" deadlock states.
* Add a state to the list of deadlock states.
*/
public void addFixedDeadlockState(int i)
public void addDeadlockState(int i)
{
deadlocksFixed.add(i);
deadlocks.add(i);
}
/**
@ -176,9 +175,15 @@ public abstract class ModelExplicit implements Model
}
@Override
public boolean isFixedDeadlockState(int i)
public int getNumDeadlockStates()
{
return deadlocksFixed.contains(i);
return deadlocks.size();
}
@Override
public boolean isDeadlockState(int i)
{
return deadlocks.contains(i);
}
@Override

7
prism/src/explicit/PrismExplicit.java

@ -53,7 +53,7 @@ public class PrismExplicit
}
/**
* Build a model from a PRISM modelling language description, storing it explicitly.,
* Build a model from a PRISM modelling language description, storing it explicitly.
* It is assumed that all constants in the model file have been defined by now.
* @param modulesFile Model to build
* @param simEngine PRISM simulator engine (for model exploration)
@ -174,7 +174,7 @@ public class PrismExplicit
try {
statesList = new StateValues(TypeBool.getInstance(), new Boolean(true), model);
} catch (PrismLangException e) {
// Can't go wrong - type always
// Can't go wrong - type always fine
}
if (exportType != Prism.EXPORT_MATLAB)
statesList.print(tmpLog);
@ -253,6 +253,9 @@ public class PrismExplicit
StateValues probs = null;
PrismLog tmpLog;
if (!(model.getModelType() == ModelType.CTMC || model.getModelType() == ModelType.DTMC))
throw new PrismException("Steady-state probabilities only computed for DTMCs/CTMCs");
// no specific states format for MRMC
if (exportType == Prism.EXPORT_MRMC) exportType = Prism.EXPORT_PLAIN;
// rows format does not apply to states output

39
prism/src/explicit/STPGAbstrSimple.java

@ -323,36 +323,31 @@ public class STPGAbstrSimple extends ModelExplicit implements STPG, ModelSimple
}
@Override
public void checkForDeadlocks(BitSet except) throws PrismException
public void findDeadlocks(boolean fix) throws PrismException
{
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("STPG has a deadlock in state " + i);
// Note that no distributions is a deadlock, not an empty distribution
if (trans.get(i).isEmpty()) {
addDeadlockState(i);
if (fix) {
DistributionSet distrs = newDistributionSet(null);
Distribution distr = new Distribution();
distr.add(i, 1.0);
distrs.add(distr);
addDistributionSet(i, distrs);
}
}
}
// TODO: Check for empty distributions sets too?
}
@Override
public BitSet findDeadlocks(boolean fix) throws PrismException
public void checkForDeadlocks(BitSet except) throws PrismException
{
int i;
BitSet deadlocks = new BitSet();
for (i = 0; i < numStates; i++) {
// Note that no distributions is a deadlock, not an empty distribution
if (trans.get(i).isEmpty())
deadlocks.set(i);
}
if (fix) {
for (i = deadlocks.nextSetBit(0); i >= 0; i = deadlocks.nextSetBit(i + 1)) {
DistributionSet distrs = newDistributionSet(null);
Distribution distr = new Distribution();
distr.add(i, 1.0);
distrs.add(distr);
addDistributionSet(i, distrs);
addFixedDeadlockState(i);
}
for (int i = 0; i < numStates; i++) {
if (trans.get(i).isEmpty() && (except == null || !except.get(i)))
throw new PrismException("STPG has a deadlock in state " + i);
}
return deadlocks;
// TODO: Check for empty distributions sets too?
}
@Override

2
prism/src/explicit/StateModelChecker.java

@ -343,7 +343,7 @@ public class StateModelChecker
int numStates = model.getNumStates();
BitSet bs = new BitSet(numStates);
for (i = 0; i < numStates; i++) {
bs.set(i, model.isFixedDeadlockState(i));
bs.set(i, model.isDeadlockState(i));
}
return StateValues.createFromBitSet(bs, model);
} else if (expr.getName().equals("init")) {

2
prism/src/prism/ExplicitFiles2MTBDD.java

@ -466,7 +466,7 @@ public class ExplicitFiles2MTBDD
}
// find any deadlocks
model.findDeadlocks();
model.findDeadlocks(prism.getFixDeadlocks());
// deref spare dds
JDD.Deref(moduleIdentities[0]);

2
prism/src/prism/ExplicitModel2MTBDD.java

@ -235,7 +235,7 @@ public class ExplicitModel2MTBDD
}
// Find any deadlocks
model.findDeadlocks();
model.findDeadlocks(prism.getFixDeadlocks());
// Deref spare dds
if (modelType == ModelType.MDP) {

6
prism/src/prism/LTLModelChecker.java

@ -293,8 +293,9 @@ public class LTLModelChecker
// Do reachability/etc. for the new model
modelProd.doReachability(prism.getExtraReachInfo());
modelProd.filterReachableStates();
modelProd.findDeadlocks();
modelProd.findDeadlocks(false);
if (modelProd.getDeadlockStates().size() > 0) {
// Assuming original model has no deadlocks, neither should product
throw new PrismException("Model-DRA product has deadlock states");
}
@ -508,8 +509,9 @@ public class LTLModelChecker
// Do reachability/etc. for the new model
modelProd.doReachability(prism.getExtraReachInfo());
modelProd.filterReachableStates();
modelProd.findDeadlocks();
modelProd.findDeadlocks(false);
if (modelProd.getDeadlockStates().size() > 0) {
// Assuming original model has no deadlocks, neither should product
throw new PrismException("Model-DRA product has deadlock states");
}

24
prism/src/prism/Model.java

@ -57,7 +57,13 @@ public interface Model
int convertBddToIndex(JDDNode dd);
StateList getReachableStates();
/**
* Get a StateList storing the set of states that are/were deadlocks.
* (Such states may have been fixed at build-time by adding self-loops)
*/
StateList getDeadlockStates();
StateList getStartStates();
int getNumRewardStructs();
long getNumStates();
@ -71,8 +77,13 @@ public interface Model
JDDNode getTrans01();
JDDNode getStart();
JDDNode getReach();
/**
* Get a BDD storing the set of states that are/were deadlocks.
* (Such states may have been fixed at build-time by adding self-loops)
*/
JDDNode getDeadlocks();
JDDNode getFixedDeadlocks();
JDDNode getStateRewards();
JDDNode getStateRewards(int i);
JDDNode getStateRewards(String s);
@ -108,8 +119,15 @@ public interface Model
void setTransActions(JDDNode transActions); // MDPs only
void setTransPerAction(JDDNode[] transPerAction); // D/CTMCs only
void filterReachableStates();
void findDeadlocks();
void fixDeadlocks();
/**
* Find all deadlock states and store this information in the model.
* If requested (if fix=true) and if needed (i.e. for DTMCs/CTMCs),
* fix deadlocks by adding self-loops in these states.
* The set of deadlocks (before any possible fixing) can be obtained from {@link #getDeadlocks()}.
*/
void findDeadlocks(boolean fix);
void printTrans();
void printTrans01();
public void printTransInfo(PrismLog log);

4
prism/src/prism/Modules2MTBDD.java

@ -304,8 +304,8 @@ public class Modules2MTBDD
// symmetrification
if (doSymmetry) doSymmetry(model);
// find any deadlocks
model.findDeadlocks();
// find/fix any deadlocks
model.findDeadlocks(prism.getFixDeadlocks());
// deref spare dds
globalDDRowVars.derefAll();

24
prism/src/prism/NondetModel.java

@ -206,9 +206,8 @@ public class NondetModel extends ProbModel
numChoices = ((Math.pow(2, getNumDDNondetVars())) * numStates) - d;
}
// identify any deadlock states
public void findDeadlocks()
@Override
public void findDeadlocks(boolean fix)
{
// find states with at least one transition
JDD.Ref(trans01);
@ -218,22 +217,15 @@ public class NondetModel extends ProbModel
// find reachable states with no transitions
JDD.Ref(reach);
deadlocks = JDD.And(reach, JDD.Not(deadlocks));
}
// remove deadlocks by adding self-loops
public void fixDeadlocks()
{
JDDNode tmp;
double d;
if (!deadlocks.equals(JDD.ZERO)) {
if (fix && !deadlocks.equals(JDD.ZERO)) {
// remove deadlocks by adding self-loops to trans
// (also update transInd (if necessary) at same time)
// (note: we don't need to update transActions since
// action-less transitions are encoded as 0 anyway)
// (note: would need to update transPerAction[0]
// but this is not stored for MDPs)
JDDNode tmp;
JDD.Ref(deadlocks);
tmp = JDD.SetVectorElement(JDD.Constant(0), allDDNondetVars, 0, 1);
tmp = JDD.And(tmp, JDD.Identity(allDDRowVars, allDDColVars));
@ -247,10 +239,6 @@ public class NondetModel extends ProbModel
transInd = JDD.Or(transInd, JDD.ThereExists(tmp, allDDColVars));
}
JDD.Deref(tmp);
// update lists of deadlocks
JDD.Deref(fixdl);
fixdl = deadlocks;
deadlocks = JDD.Constant(0);
// update mask
JDD.Deref(nondetMask);
JDD.Ref(trans01);
@ -258,7 +246,7 @@ public class NondetModel extends ProbModel
nondetMask = JDD.And(JDD.Not(JDD.ThereExists(trans01, allDDColVars)), reach);
// update model stats
numTransitions = JDD.GetNumMinterms(trans01, getNumDDVarsInTrans());
d = JDD.GetNumMinterms(nondetMask, getNumDDRowVars() + getNumDDNondetVars());
double d = JDD.GetNumMinterms(nondetMask, getNumDDRowVars() + getNumDDNondetVars());
numChoices = ((Math.pow(2, getNumDDNondetVars())) * numStates) - d;
}
}

2
prism/src/prism/NondetModelChecker.java

@ -440,7 +440,7 @@ public class NondetModelChecker extends NonProbModelChecker
if (prism.getExportProductTrans()) {
try {
mainLog.println("\nExporting product transition matrix to file \"" + prism.getExportProductTransFilename() + "\"...");
prism.exportTransToFile(modelProduct, true, Prism.EXPORT_PLAIN, new File(prism.getExportProductTransFilename()));
modelProduct.exportToFile(Prism.EXPORT_PLAIN, true, new File(prism.getExportProductTransFilename()));
} catch (FileNotFoundException e) {
mainLog.printWarning("Could not export product transition matrix to file \"" + prism.getExportProductTransFilename() + "\"");
}

952
prism/src/prism/Prism.java
File diff suppressed because it is too large
View File

342
prism/src/prism/PrismCL.java

@ -31,17 +31,13 @@ import java.util.*;
import parser.*;
import parser.ast.*;
import pta.*;
import simulator.method.*;
import explicit.PrismExplicit;
// prism - command line version
public class PrismCL
{
// flags
private boolean verbose;
private boolean fixdl = false;
private boolean importpepa = false;
private boolean importprismpp = false;
private boolean importtrans = false;
@ -72,7 +68,6 @@ public class PrismCL
private boolean simpath = false;
private ModelType typeOverride = null;
private boolean orderingOverride = false;
private boolean explicit = false;
private boolean explicitbuild = false;
private boolean explicitbuildtest = false;
private boolean nobuild = false;
@ -138,13 +133,6 @@ public class PrismCL
private Values definedMFConstants;
private Values definedPFConstants;
// built (symbolic) model storage
private Model model = null;
// built (explicit) model storage
private PrismExplicit prismExpl = null;
private explicit.Model modelExpl;
// results
private ResultsCollection results[] = null;
@ -175,18 +163,14 @@ public class PrismCL
public void run(String[] args)
{
int i, j, k;
ModulesFile modulesFileToCheck;
Result res;
// Initialise
initialise(args);
// Parse model/properties
// Parse/load model/properties
doParsing();
// Load model into PRISM
prism.loadPRISMModel(modulesFile);
// Sort out properties to check
sortProperties();
@ -240,7 +224,7 @@ public class PrismCL
continue;
}
// if requested, generate a random path with simulator (and then skip anything else)
// if requested, generate a random path with the simulator
if (simpath) {
try {
if (!simMaxPathGiven)
@ -255,65 +239,23 @@ public class PrismCL
for (j = 0; j < numPropertiesToCheck; j++) {
undefinedConstants[j].iterateModel();
}
continue;
}
// Do any requested exports of PRISM code
// (except for PTA digital clocks case - postpone this)
if (!(modulesFile.getModelType() == ModelType.PTA && prism.getSettings().getString(PrismSettings.PRISM_PTA_METHOD).equals("Digital clocks"))) {
doPrismLangExports(modulesFile);
}
// Do any exports of code/model
doPrismLangExports();
doExports();
// Decide if model construction is necessary
boolean doBuild = true;
// If explicitly disabled...
if (nobuild)
doBuild = false;
// No need if using approximate (simulation-based) model checking...
if (simulate)
doBuild = false;
// No need if doing PTA model checking...
// (even if needed for digital clocks, will be done later)
if (modulesFile.getModelType() == ModelType.PTA)
doBuild = false;
// do model construction (if necessary)
if (doBuild) {
// build model
try {
buildModel(modulesFile, false);
} catch (PrismException e) {
// in case of error, report it, store as result for any properties, and go on to the next model
error(e.getMessage());
try {
for (j = 0; j < numPropertiesToCheck; j++) {
results[j].setMultipleErrors(definedMFConstants, null, e);
}
} catch (PrismException e2) {
error("Problem storing results");
}
// iterate to next model
undefinedMFConstants.iterateModel();
for (j = 0; j < numPropertiesToCheck; j++) {
undefinedConstants[j].iterateModel();
}
continue;
}
// Do any exports
doExports();
// Do steady-state/transient probability computation, if required
doSteadyState();
doTransient();
// Do steady-state/transient probability computation, if required
doSteadyState();
doTransient();
}
// work through list of properties to be checked
// Work through list of properties to be checked
for (j = 0; j < numPropertiesToCheck; j++) {
// for simulation we can do multiple values of property constants simultaneously
if (simulate && undefinedConstants[j].getNumPropertyIterations() > 1) {
try {
// TODO: remove output
mainLog.printSeparator();
mainLog.println("\nSimulating: " + propertiesToCheck.get(j));
if (definedMFConstants != null)
@ -321,7 +263,7 @@ public class PrismCL
mainLog.println("Model constants: " + definedMFConstants);
mainLog.println("Property constants: " + undefinedConstants[j].getPFDefinedConstantsString());
simMethod = processSimulationOptions(propertiesToCheck.get(j).getExpression());
prism.modelCheckSimulatorExperiment(modulesFile, propertiesFile, undefinedConstants[j], results[j], propertiesToCheck.get(j).getExpression(), null,
prism.modelCheckSimulatorExperiment(propertiesFile, undefinedConstants[j], results[j], propertiesToCheck.get(j).getExpression(), null,
simMaxPath, simMethod);
} catch (PrismException e) {
// in case of (overall) error, report it, store as result for property, and proceed
@ -341,54 +283,19 @@ public class PrismCL
for (k = 0; k < undefinedConstants[j].getNumPropertyIterations(); k++) {
try {
// set values for PropertiesFile constants
// Set values for PropertiesFile constants
if (propertiesFile != null) {
definedPFConstants = undefinedConstants[j].getPFConstantValues();
propertiesFile.setSomeUndefinedConstants(definedPFConstants);
}
// log output
mainLog.printSeparator();
mainLog.println("\n" + (simulate ? "Simulating" : "Model checking") + ": " + propertiesToCheck.get(j));
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
mainLog.println("Model constants: " + definedMFConstants);
if (definedPFConstants != null)
if (definedPFConstants.getNumValues() > 0)
mainLog.println("Property constants: " + definedPFConstants);
// for PTAs via digital clocks, do model translation and build
if (modulesFile.getModelType() == ModelType.PTA
&& prism.getSettings().getString(PrismSettings.PRISM_PTA_METHOD).equals("Digital clocks")) {
DigitalClocks dc = new DigitalClocks(prism);
dc.translate(modulesFile, propertiesFile, propertiesToCheck.get(j).getExpression());
modulesFileToCheck = dc.getNewModulesFile();
modulesFileToCheck.setUndefinedConstants(modulesFile.getConstantValues());
doPrismLangExports(modulesFileToCheck);
buildModel(modulesFileToCheck, true);
} else {
modulesFileToCheck = modulesFile;
}
// exact (non-approximate) model checking
// Normal model checking
if (!simulate) {
// PTA model checking
if (modulesFileToCheck.getModelType() == ModelType.PTA) {
res = prism.modelCheckPTA(modulesFileToCheck, propertiesFile, propertiesToCheck.get(j).getExpression());
}
// Non-PTA model checking
else {
if (!explicit) {
res = prism.modelCheck(propertiesFile, propertiesToCheck.get(j).getExpression());
} else {
res = prismExpl.modelCheck(modelExpl, modulesFileToCheck, propertiesFile, propertiesToCheck.get(j).getExpression());
}
}
res = prism.modelCheck(propertiesFile, propertiesToCheck.get(j).getExpression(), definedPFConstants);
}
// approximate (simulation-based) model checking
// Approximate (simulation-based) model checking
else {
simMethod = processSimulationOptions(propertiesToCheck.get(j).getExpression());
res = prism.modelCheckSimulator(modulesFileToCheck, propertiesFile, propertiesToCheck.get(j).getExpression(), null, simMaxPath, simMethod);
res = prism.modelCheckSimulator(propertiesFile, propertiesToCheck.get(j).getExpression(), definedPFConstants, null, simMaxPath, simMethod);
simMethod.reset();
}
} catch (PrismException e) {
@ -434,6 +341,15 @@ public class PrismCL
}
}
// Explicitly request a build if necessary
if (propertiesToCheck.size() == 0 && !simpath && !nobuild && prism.modelCanBeBuilt() && !prism.modelIsBuilt()) {
try {
prism.buildModel();
} catch (PrismException e) {
error(e.getMessage());
}
}
// clear model
prism.clearBuiltModel();
@ -496,7 +412,6 @@ public class PrismCL
// create prism object(s)
prism = new Prism(mainLog, techLog);
prismExpl = new PrismExplicit(mainLog, prism.getSettings());
// parse command line arguments
parseArguments(args);
@ -509,16 +424,13 @@ public class PrismCL
// do some processing of the options
processOptions();
// store verbosity option locally
verbose = prism.getVerbose();
} catch (PrismException e) {
errorAndExit(e.getMessage());
}
}
/**
* Parse model and properties.
* Parse model and properties, load model into PRISM.
*/
private void doParsing()
{
@ -548,7 +460,7 @@ public class PrismCL
lf = new File(importLabelsFilename);
}
mainLog.println("...");
modulesFile = prism.parseModelFromExplicitFiles(sf, new File(modelFilename), lf, typeOverride);
modulesFile = prism.loadModelFromExplicitFiles(sf, new File(modelFilename), lf, typeOverride);
} else {
mainLog.print("\nParsing model file \"" + modelFilename + "\"...\n");
modulesFile = prism.parseModelFile(new File(modelFilename), typeOverride);
@ -581,12 +493,17 @@ public class PrismCL
// print out properties (if any)
if (propertiesFile == null)
return;
mainLog.print("\n" + propertiesFile.getNumProperties());
mainLog.print(" propert" + ((propertiesFile.getNumProperties() == 1) ? "y" : "ies") + ":\n");
for (i = 0; i < propertiesFile.getNumProperties(); i++) {
mainLog.println("(" + (i + 1) + ") " + propertiesFile.getPropertyObject(i));
if (propertiesFile != null) {
mainLog.print("\n" + propertiesFile.getNumProperties());
mainLog.print(" propert" + ((propertiesFile.getNumProperties() == 1) ? "y" : "ies") + ":\n");
for (i = 0; i < propertiesFile.getNumProperties(); i++) {
mainLog.println("(" + (i + 1) + ") " + propertiesFile.getPropertyObject(i));
}
}
// Load model into PRISM (if not done already)
if (!importtrans) {
prism.loadPRISMModel(modulesFile);
}
}
@ -633,41 +550,34 @@ public class PrismCL
/**
* Do any exports of PRISM code that have been requested.
*/
private void doPrismLangExports(ModulesFile modulesFileToExport)
private void doPrismLangExports()
{
// output final prism model here if required
// output parsed prism model here if required
if (exportprism) {
mainLog.print("\nExporting parsed PRISM file ");
if (!exportPrismFilename.equals("stdout"))
mainLog.println("to file \"" + exportPrismFilename + "\"...");
else
mainLog.println("below:");
PrismFileLog tmpLog = new PrismFileLog(exportPrismFilename);
if (!tmpLog.ready()) {
errorAndExit("Couldn't open file \"" + exportPrismFilename + "\" for output");
try {
File f = (exportPrismFilename.equals("stdout")) ? null : new File(exportPrismFilename);
prism.exportPRISMModel(f);
}
// in case of error, report it and proceed
catch (FileNotFoundException e) {
error("Couldn't open file \"" + exportPrismFilename + "\" for output");
} catch (PrismException e) {
error(e.getMessage());
}
tmpLog.print(modulesFileToExport.toString());
}
// output parsed prism model, with constants, here if required
if (exportprismconst) {
mainLog.print("\nExporting parsed PRISM file (with constant expansion) ");
if (!exportPrismConstFilename.equals("stdout"))
mainLog.println("to file \"" + exportPrismConstFilename + "\"...");
else
mainLog.println("below:");
PrismFileLog tmpLog = new PrismFileLog(exportPrismConstFilename);
if (!tmpLog.ready()) {
errorAndExit("Couldn't open file \"" + exportPrismConstFilename + "\" for output");
}
ModulesFile mfTmp = (ModulesFile) modulesFileToExport.deepCopy();
try {
mfTmp = (ModulesFile) mfTmp.replaceConstants(modulesFileToExport.getConstantValues());
mfTmp = (ModulesFile) mfTmp.replaceConstants(definedMFConstants);
// NB: Don't use simplify() here because doesn't work for the purposes of printing out
// (e.g. loss of parethenses causes precedence problems)
} catch (PrismLangException e) {
File f = (exportPrismConstFilename.equals("stdout")) ? null : new File(exportPrismConstFilename);
prism.exportPRISMModelWithExpandedConstants(f);
}
// in case of error, report it and proceed
catch (FileNotFoundException e) {
error("Couldn't open file \"" + exportPrismConstFilename + "\" for output");
} catch (PrismException e) {
error(e.getMessage());
}
tmpLog.print(mfTmp.toString());
}
}
@ -680,92 +590,9 @@ public class PrismCL
*/
private void buildModel(ModulesFile modulesFileToBuild, boolean digital) throws PrismException
{
// TODO
/*
StateList states;
int i;
mainLog.printSeparator();
// build model
if (!explicit) {
if (importtrans) {
model = prism.buildModelFromExplicitFiles();
} else if (explicitbuild) {
model = prism.buildModelExplicit(modulesFileToBuild);
} else {
model = prism.buildModel(modulesFileToBuild);
}
modelExpl = null;
} else {
if (importtrans) {
// TODO: add -importtrans case using model.buildFromPrismExplicit(...);
throw new PrismException("Explicit import not yet supported for explicit engine");
} else {
modelExpl = prismExpl.buildModel(modulesFileToBuild, prism.getSimulator());
}
model = null;
}
// Print model info
mainLog.println();
if (!explicit) {
prism.printBuiltModelInfo();
} else {
mainLog.println("\nType: " + modelExpl.getModelType());
}
// check for deadlocks
if (!explicit) {
states = model.getDeadlockStates();
if (states != null && states.size() > 0) {
// for pta models (via digital clocks)
if (digital) {
// by construction, these can only occur from timelocks
throw new PrismException("Timelock in PTA, e.g. in state (" + states.getFirstAsValues() + ")");
}
// if requested, remove them
else if (fixdl) {
mainLog.printWarning(states.size() + " deadlock states detected; adding self-loops in these states...");
model.fixDeadlocks();
}
// otherwise print error and bail out
else {
mainLog.println();
model.printTransInfo(mainLog, prism.getExtraDDInfo());
mainLog.print("\nError: Model contains " + states.size() + " deadlock states");
if (!verbose && states.size() > 10) {
mainLog.print(".\nThe first 10 deadlock states are displayed below. To view them all use the -v switch.\n");
states.print(mainLog, 10);
} else {
mainLog.print(":\n");
states.print(mainLog);
}
mainLog.print("\nTip: Use the -fixdl switch to automatically add self-loops in deadlock states.\n");
model.clear();
exit(1);
}
}
} else {
BitSet deadlocks = modelExpl.findDeadlocks(fixdl);
if (deadlocks.cardinality() > 0) {
if (fixdl) {
mainLog.println("Added self-loops in " + deadlocks.cardinality() + " states...");
} else {
mainLog.println();
mainLog.print("\nError: Model contains " + deadlocks.size() + " deadlock states");
mainLog.print("\nTip: Use the -fixdl switch to automatically add self-loops in deadlock states.\n");
exit(1);
}
}
}
// Print model stats
mainLog.println();
if (!explicit) {
prism.printBuiltModelStats();
} else {
mainLog.print(modelExpl.infoStringTable());
}
// If enabled, also construct model explicitly and compare (for testing purposes)
if (explicitbuildtest) {
String tmpFile = "'";
@ -798,7 +625,7 @@ public class PrismCL
} catch (IOException e) {
throw new PrismException("Could not create temporary file \"" + tmpFile + "\"");
}
}
}*/
}
// do any exporting requested
@ -809,11 +636,7 @@ public class PrismCL
if (exporttrans) {
try {
File f = (exportTransFilename.equals("stdout")) ? null : new File(exportTransFilename);
if (explicit) {
prismExpl.exportTransToFile(modelExpl, exportordered, exportType, f);
} else {
prism.exportTransToFile(exportordered, exportType, f);
}
prism.exportTransToFile(exportordered, exportType, f);
}
// in case of error, report it and proceed
catch (FileNotFoundException e) {
@ -858,11 +681,7 @@ public class PrismCL
if (exportstates) {
try {
File f = (exportStatesFilename.equals("stdout")) ? null : new File(exportStatesFilename);
if (explicit) {
prismExpl.exportStatesToFile(modulesFile, modelExpl, exportType, f);
} else {
prism.exportStatesToFile(exportType, f);
}
prism.exportStatesToFile(exportType, f);
}
// in case of error, report it and proceed
catch (FileNotFoundException e) {
@ -973,13 +792,8 @@ public class PrismCL
exportSteadyStateFile = null;
else
exportSteadyStateFile = new File(exportSteadyStateFilename);
// Compute steady-state probabilities
if (explicit) {
prismExpl.doSteadyState(modelExpl, exportType, exportSteadyStateFile);
} else {
prism.doSteadyState(exportType, exportSteadyStateFile);
}
prism.doSteadyState(exportType, exportSteadyStateFile);
} catch (PrismException e) {
// In case of error, report it and proceed
error(e.getMessage());
@ -1006,11 +820,7 @@ public class PrismCL
exportTransientFile = new File(exportTransientFilename);
// Determine model type
if (explicit) {
modelType = modelExpl.getModelType();
} else {
modelType = prism.getBuiltModel().getModelType();
}
modelType = prism.getModelType();
// Compute transient probabilities
if (modelType == ModelType.CTMC) {
@ -1019,22 +829,14 @@ public class PrismCL
} catch (NumberFormatException e) {
throw new PrismException("Invalid value \"" + transientTime + "\" for transient probability computation");
}
if (explicit) {
prismExpl.doTransient(modelExpl, d, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
} else {
prism.doTransient(d, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
}
prism.doTransient(d, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
} else if (modelType == ModelType.DTMC) {
try {
i = Integer.parseInt(transientTime);
} catch (NumberFormatException e) {
throw new PrismException("Invalid value \"" + transientTime + "\" for transient probability computation");
}
if (explicit) {
prismExpl.doTransient(modelExpl, i, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
} else {
prism.doTransient(i, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
}
prism.doTransient(i, exportType, exportTransientFile, importinitdist ? new File(importInitDistFilename) : null);
} else {
mainLog.printWarning("Transient probabilities only computed for DTMCs/CTMCs.");
}
@ -1606,14 +1408,6 @@ public class PrismCL
else if (sw.equals("modpoliter")) {
prism.setMDPSolnMethod(Prism.MDP_MODPOLITER);
}
// fix deadlocks
else if (sw.equals("fixdl")) {
fixdl = true;
}
// enable explicit-state engine
else if (sw.equals("explicit") || sw.equals("ex")) {
explicit = true;
}
// explicit-state model construction
else if (sw.equals("explicitbuild")) {
explicitbuild = true;
@ -1743,7 +1537,7 @@ public class PrismCL
}
// explicit overrides explicit build
if (explicit) {
if (prism.getExplicit()) {
explicitbuild = false;
}

33
prism/src/prism/PrismModelListener.java

@ -0,0 +1,33 @@
//==============================================================================
//
// 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 prism;
public interface PrismModelListener
{
public void notifyModelBuildSuccessful();
public void notifyModelBuildFailed(PrismException e);
}

20
prism/src/prism/PrismSettings.java

@ -74,6 +74,7 @@ public class PrismSettings implements Observer
public static final String PRISM_PRECOMPUTATION = "prism.precomputation";
public static final String PRISM_PROB0 = "prism.prob0";
public static final String PRISM_PROB1 = "prism.prob1";
public static final String PRISM_FIX_DEADLOCKS = "prism.fixDeadlocks";
public static final String PRISM_DO_PROB_CHECKS = "prism.doProbChecks";
public static final String PRISM_COMPACT = "prism.compact";
public static final String PRISM_LIN_EQ_METHOD = "prism.linEqMethod";//"prism.iterativeMethod";
@ -187,8 +188,8 @@ public class PrismSettings implements Observer
//====================================================================================================================================================================================================================================================================================================================================
// ENGINES/METHODS:
{ CHOICE_TYPE, PRISM_ENGINE, "Engine", "2.1", "Hybrid", "MTBDD,Sparse,Hybrid",
"Which engine (hybrid, sparse or MTBDD) should be used for model checking." },
{ CHOICE_TYPE, PRISM_ENGINE, "Engine", "2.1", "Hybrid", "MTBDD,Sparse,Hybrid,Explicit",
"Which engine (hybrid, sparse, MTBDD, explicit) should be used for model checking." },
{ CHOICE_TYPE, PRISM_PTA_METHOD, "PTA model checking method", "3.3", "Stochastic games", "Digital clocks,Stochastic games",
"Which method to use for model checking of PTAs." },
// NUMERICAL SOLUTION OPTIONS:
@ -213,6 +214,8 @@ public class PrismSettings implements Observer
"Whether to use model checking precomputation algorithm Prob1 (if precomputation enabled)." },
{ BOOLEAN_TYPE, PRISM_FAIRNESS, "Use fairness", "2.1", new Boolean(false), "",
"Constrain to fair adversaries when model checking MDPs." },
{ BOOLEAN_TYPE, PRISM_FIX_DEADLOCKS, "Automatically fix deadlocks", "4.0.3", new Boolean(true), "",
"Automatically fix deadlocks, where necessary, when constructing probabilistic models." },
{ BOOLEAN_TYPE, PRISM_DO_PROB_CHECKS, "Do probability/rate checks", "2.1", new Boolean(true), "",
"Perform sanity checks on model probabilities/rates when constructing probabilistic models." },
{ BOOLEAN_TYPE, PRISM_DO_SS_DETECTION, "Use steady-state detection", "2.1", new Boolean(true), "0,",
@ -738,6 +741,9 @@ public class PrismSettings implements Observer
else if (sw.equals("hybrid") || sw.equals("h")) {
set(PRISM_ENGINE, "Hybrid");
}
else if (sw.equals("explicit") || sw.equals("ex")) {
set(PRISM_ENGINE, "Explicit");
}
// PTA model checking methods
else if (sw.equals("ptamethod")) {
if (i < args.length - 1) {
@ -845,6 +851,13 @@ public class PrismSettings implements Observer
else if (sw.equals("noprob1")) {
set(PRISM_PROB1, false);
}
// Fix deadlocks on/off
else if (sw.equals("fixdl")) {
set(PRISM_FIX_DEADLOCKS, true);
}
else if (sw.equals("nofixdl")) {
set(PRISM_FIX_DEADLOCKS, false);
}
// Fairness on/off
else if (sw.equals("fair")) {
set(PRISM_FAIRNESS, true);
@ -1073,7 +1086,8 @@ public class PrismSettings implements Observer
mainLog.println("-noprob1 ....................... Skip precomputation algorithm Prob1 (where optional)");
mainLog.println("-fair .......................... Use fairness (for model checking of MDPs)");
mainLog.println("-nofair ........................ Don't use fairness (for model checking of MDPs) [default]");
mainLog.println("-fixdl ......................... Automatically put self-loops in deadlock states");
mainLog.println("-fixdl ......................... Automatically put self-loops in deadlock states [default]");
mainLog.println("-nofixdl ....................... Do not automatically put self-loops in deadlock states");
mainLog.println("-noprobchecks .................. Disable checks on model probabilities/rates");
mainLog.println("-zerorewardcheck ............... Check for absence of zero-reward loops");
mainLog.println("-nossdetect .................... Disable steady-state detection for CTMC transient computations");

34
prism/src/prism/ProbModel.java

@ -69,8 +69,7 @@ public class ProbModel implements Model
protected JDDNode trans01; // 0-1 transition matrix dd
protected JDDNode start; // start state dd
protected JDDNode reach; // reachable states dd
protected JDDNode deadlocks; // deadlock states dd
protected JDDNode fixdl; // fixed deadlock states dd
protected JDDNode deadlocks; // deadlock states dd (may have been fixed)
protected JDDNode stateRewards[]; // state rewards dds
protected JDDNode transRewards[]; // transition rewards dds
protected JDDNode transActions; // dd for transition action labels (MDPs)
@ -212,6 +211,7 @@ public class ProbModel implements Model
return new StateListMTBDD(reach, this);
}
@Override
public StateList getDeadlockStates()
{
return new StateListMTBDD(deadlocks, this);
@ -244,16 +244,12 @@ public class ProbModel implements Model
return reach;
}
@Override
public JDDNode getDeadlocks()
{
return deadlocks;
}
public JDDNode getFixedDeadlocks()
{
return fixdl;
}
public JDDNode getStateRewards()
{
return getStateRewards(0);
@ -396,7 +392,7 @@ public class ProbModel implements Model
trans = tr;
start = s;
fixdl = JDD.Constant(0);
deadlocks = null;
stateRewards = sr;
transRewards = trr;
numRewardStructs = stateRewards.length; // which should == transRewards.length
@ -601,9 +597,8 @@ public class ProbModel implements Model
numTransitions = JDD.GetNumMinterms(trans01, getNumDDVarsInTrans());
}
// identify any deadlock states
public void findDeadlocks()
@Override
public void findDeadlocks(boolean fix)
{
// find states with at least one transition
JDD.Ref(trans01);
@ -612,17 +607,11 @@ public class ProbModel implements Model
// find reachable states with no transitions
JDD.Ref(reach);
deadlocks = JDD.And(reach, JDD.Not(deadlocks));
}
// remove deadlocks by adding self-loops
public void fixDeadlocks()
{
JDDNode tmp;
if (!deadlocks.equals(JDD.ZERO)) {
if (fix && !deadlocks.equals(JDD.ZERO)) {
// remove deadlocks by adding self-loops
// also update transPerAction info, if present
JDDNode tmp;
JDD.Ref(deadlocks);
tmp = JDD.And(deadlocks, JDD.Identity(allDDRowVars, allDDColVars));
JDD.Ref(tmp);
@ -634,10 +623,6 @@ public class ProbModel implements Model
transPerAction[0] = JDD.Apply(JDD.PLUS, transPerAction[0], tmp);
}
JDD.Deref(tmp);
// update lists of deadlocks
JDD.Deref(fixdl);
fixdl = deadlocks;
deadlocks = JDD.Constant(0);
// update model stats
numTransitions = JDD.GetNumMinterms(trans01, getNumDDVarsInTrans());
}
@ -883,7 +868,6 @@ public class ProbModel implements Model
JDD.Deref(reach);
if (deadlocks != null)
JDD.Deref(deadlocks);
JDD.Deref(fixdl);
for (int i = 0; i < numRewardStructs; i++) {
JDD.Deref(stateRewards[i]);
JDD.Deref(transRewards[i]);

2
prism/src/prism/StateModelChecker.java

@ -976,7 +976,7 @@ public class StateModelChecker implements ModelChecker
// treat special cases
if (expr.getName().equals("deadlock")) {
dd = model.getFixedDeadlocks();
dd = model.getDeadlocks();
JDD.Ref(dd);
return new StateValuesMTBDD(dd, model);
} else if (expr.getName().equals("init")) {

112
prism/src/userinterface/model/GUIModelEvent.java

@ -27,73 +27,55 @@
package userinterface.model;
import parser.ast.ModulesFile;
import prism.Model;
import parser.Values;
import userinterface.util.*;
import parser.ast.ModulesFile;
import userinterface.util.GUIEvent;
public class GUIModelEvent extends GUIEvent
{
//CONSTANTS
public static final int NEW_MODEL = 0; //when no parsed or built model
public static final int LOAD_MODEL = 1; //when model is loaded into text editor
public static final int IMPORT_MODEL = 2; //when model is imported into text editor
public static final int MODEL_PARSED = 3; // when parsed model exists
public static final int MODIFIED_SINCE_SAVE = 4; //when text is modified
public static final int SAVE_MODEL = 5; //when text is saved to file
public static final int MODEL_BUILT = 6; //when built model exists
public static final int MODEL_PARSE_FAILED = 7; //when a failed model parse happens
public static final int MODEL_BUILD_FAILED = 8; //when a failed model build happens
public static final int NEW_LOAD_NOT_RELOAD_MODEL = 9;
//DATA ATTRIBUTES
private ModulesFile file;
private Model model;
private Values buildValues;
/** Creates a new instance of GUIModelEvent */
public GUIModelEvent(int id, ModulesFile file)
{
super(id);
this.file = file;
this.model = null;
}
public GUIModelEvent(int id, Model model)
{
super(id);
this.model = model;
this.file = null;
}
public GUIModelEvent(int id, Model model, Values buildValues)
{
super(id);
this.model = model;
this.file = null;
this.buildValues = buildValues;
}
public GUIModelEvent(int id)
{
super(id);
this.model = null;
this.file = null;
}
public ModulesFile getModulesFile()
{
return file;
}
public Model getModel()
{
return model;
}
public Values getBuildValues()
{
return buildValues;
}
// CONSTANTS
public static final int NEW_MODEL = 0; //when no parsed or built model
public static final int LOAD_MODEL = 1; //when model is loaded into text editor
public static final int IMPORT_MODEL = 2; //when model is imported into text editor
public static final int MODEL_PARSED = 3; // when parsed model exists
public static final int MODIFIED_SINCE_SAVE = 4; //when text is modified
public static final int SAVE_MODEL = 5; //when text is saved to file
public static final int MODEL_BUILT = 6; //when built model exists
public static final int MODEL_PARSE_FAILED = 7; //when a failed model parse happens
public static final int MODEL_BUILD_FAILED = 8; //when a failed model build happens
public static final int NEW_LOAD_NOT_RELOAD_MODEL = 9;
// DATA ATTRIBUTES
private ModulesFile file;
private Values buildValues;
/** Creates a new instance of GUIModelEvent */
public GUIModelEvent(int id, ModulesFile file)
{
super(id);
this.file = file;
}
public GUIModelEvent(int id, Values buildValues)
{
super(id);
this.file = null;
this.buildValues = buildValues;
}
public GUIModelEvent(int id)
{
super(id);
this.file = null;
}
public ModulesFile getModulesFile()
{
return file;
}
public Values getBuildValues()
{
return buildValues;
}
}

699
prism/src/userinterface/model/GUIMultiModel.java
File diff suppressed because it is too large
View File

2888
prism/src/userinterface/model/GUIMultiModelHandler.java
File diff suppressed because it is too large
View File

231
prism/src/userinterface/model/computation/BuildModelThread.java

@ -31,222 +31,63 @@ import javax.swing.*;
import userinterface.*;
import userinterface.model.*;
import parser.*;
import parser.ast.*;
import prism.*;
import userinterface.util.*;
/**
* Thread that performs model construction, whether needed or not.
*/
public class BuildModelThread extends GUIComputationThread
{
@SuppressWarnings("unused")
private GUIMultiModelHandler handler;
private String buildThis;
private boolean isPepa;
private ModulesFile mod;
private Model model;
private Values buildValues;
private boolean forceShow;
private String errMsg;
private PrismLangException parseError;
private PrismException buildError;
private StateList deadlocks;
/** Creates a new instance of BuildModelThread */
// public BuildModelThread(GUIMultiModelHandler handler, String buildThis, boolean isPepa, Values buildValues, boolean forceShow)
// {
// this.handler = handler;
// this.buildThis = buildThis;
// this.isPepa = isPepa;
// this.buildValues = buildValues;
// plug = handler.getGUIPlugin();
// this.forceShow = forceShow;
// }
public BuildModelThread(GUIMultiModelHandler handler, ModulesFile buildParse, Values buildValues, boolean forceShow)
public BuildModelThread(GUIMultiModelHandler handler)
{
super(handler.getGUIPlugin());
this.handler = handler;
this.buildThis = null;
this.mod = buildParse;
this.buildValues = buildValues;
this.forceShow = forceShow;
}
public void run()
{
//Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.startProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
}});
//If need to do parse first...
if(buildThis!=null)
// Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable()
{
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.setTaskBarText("Parsing model...");
}});
// do parsing
try {
// normal prism mode
if(!isPepa) {
mod = prism.parseModelString(buildThis);
}
// pepa mode
else {
mod = prism.importPepaString(buildThis);
}
}
catch (PrismLangException e) {
parseError = e;
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Parsing model... error.");
error(parseError.getMessage());
handler.modelParseFailed(parseError, false);
handler.modelBuildFailed(null);
}});
return;
}
catch (PrismException e) {
throw new RuntimeException("Unexpected PrismException: " + e.getMessage());
}
//If we are here, the parse was successful, notify the interface
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.setTaskBarText("Parsing model... done.");
handler.modelParsedSuccessful(mod);
}});
//give it a break so user can see the ...done before the building model...
try { sleep(100); } catch(InterruptedException e) {}
}
// Check whether there are any undefined constants...
// ...and if there are, get values for them
UndefinedConstants unC = new UndefinedConstants(mod, null);
if(unC.getMFNumUndefined() > 0)
{
if(forceShow || (buildValues == null))
public void run()
{
// notify interface
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.setTaskBarText("Defining constants...");
}});
// show dialog
int result = GUIConstantsPicker.defineConstantsWithDialog(handler.getGUIPlugin().getGUI(), unC, buildValues, null);
// if build cancelled...
if(result != GUIConstantsPicker.VALUES_DONE) {
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Building model... cancelled.");
handler.modelBuildFailed(new PrismException(""));
}});
return;
}
// get build values
buildValues = unC.getMFConstantValues();
plug.startProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
plug.setTaskBarText("Building model...");
}
// notify interface
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.setTaskBarText("Defining constants... done.");
}});
}
else {
// create an empty values object
buildValues = new Values();
}
if (buildValues != null) if (buildValues.getNumValues() > 0) logln("\nModel constants: " + buildValues);
// set undefined constants
try {
mod.setUndefinedConstants(buildValues);
}
catch (PrismException e) {
buildError = e;
errMsg = e.getMessage();
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Building model... error.");
error(errMsg);
handler.modelBuildFailed(buildError);
}});
return;
}
// notify interface
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.setTaskBarText("Building model...");
}});
// do build
});
// Do build
try {
logSeparator();
model = prism.buildModel(mod);
}
catch (PrismException e) {
buildError = e;
errMsg = e.getMessage();
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Building model... error.");
error(errMsg);
handler.modelBuildFailed(buildError);
}});
return;
}
// Check for Deadlocks
deadlocks = model.getDeadlockStates();
if (deadlocks != null) if (deadlocks.size() > 0) {
String[] options = {"Continue", "Display deadlocks"};
int choice = plug.question("Error", "Error: Model contains deadlock states.\nAdd self-loops to these states and continue?\nOr stop and display deadlock states in log?", options);
if (choice == 0) {
logWarning(deadlocks.size() + " deadlock states detected; adding self-loops in these states...");
model.fixDeadlocks();
}
else {
model.printTransInfo(plug.getGUI().getLog());
log("\nError: Model contains " + deadlocks.size() + " deadlock states");
if (deadlocks.size() > 10) {
log(".\nThe first 10 deadlock states are displayed below.\n");
deadlocks.print(plug.getGUI().getLog(), 10);
} else {
log(":\n");
deadlocks.print(plug.getGUI().getLog());
}
model.clear();
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
prism.buildModel();
} catch (PrismException e) {
error(e.getMessage());
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Building model... error.");
handler.modelBuildFailed(new PrismException(""));
plug.logToFront();
}});
return;
}
}
});
return;
}
logln();
model.printTransInfo(plug.getGUI().getLog());
//If we are here, the build was successful, notify the interface
SwingUtilities.invokeLater(new Runnable() { public void run() {
plug.stopProgress();
plug.setTaskBarText("Building model... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
handler.modelBuildSuccessful(model, buildValues);
}});
// If we are here, the build was successful, notify the interface
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
plug.stopProgress();
plug.setTaskBarText("Building model... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
}
});
}
}

31
prism/src/userinterface/model/computation/ComputeSteadyStateThread.java

@ -26,28 +26,31 @@
//==============================================================================
package userinterface.model.computation;
import javax.swing.*;
import userinterface.*;
import userinterface.model.*;
import prism.*;
import userinterface.util.*;
/**
* Thread that performs steady-state probability computation on a model.
*/
public class ComputeSteadyStateThread extends GUIComputationThread
{
@SuppressWarnings("unused")
private GUIMultiModelHandler handler;
private Model computeThis;
/** Creates a new instance of ComputeSteadyStateThread */
public ComputeSteadyStateThread(GUIMultiModelHandler handler, Model computeThis)
public ComputeSteadyStateThread(GUIMultiModelHandler handler)
{
super(handler.getGUIPlugin());
this.handler = handler;
this.computeThis = computeThis;
}
public void run()
{
//notify the interface that we are starting computation
// Notify the interface that we are starting computation
SwingUtilities.invokeLater(new Runnable()
{
public void run()
@ -57,15 +60,11 @@ public class ComputeSteadyStateThread extends GUIComputationThread
plug.setTaskBarText("Computing steady-state probabilities...");
}
});
//Do Computation
// Do Computation
try {
if (!(computeThis.getModelType() == ModelType.CTMC || computeThis.getModelType() == ModelType.DTMC))
throw new PrismException("Can only compute steady-state probabilities for CTMCs");
prism.doSteadyState(computeThis);
}
catch(PrismException e)
{
prism.doSteadyState();
} catch (PrismException e) {
error(e.getMessage());
SwingUtilities.invokeLater(new Runnable()
{
@ -78,8 +77,8 @@ public class ComputeSteadyStateThread extends GUIComputationThread
});
return;
}
//If we get here, computation was successful
// If we get here, computation was successful
SwingUtilities.invokeLater(new Runnable()
{
public void run()

27
prism/src/userinterface/model/computation/ComputeTransientThread.java

@ -26,30 +26,33 @@
//==============================================================================
package userinterface.model.computation;
import javax.swing.*;
import userinterface.*;
import userinterface.model.*;
import prism.*;
import userinterface.util.*;
/**
* Thread that performs transient probability computation on a model.
*/
public class ComputeTransientThread extends GUIComputationThread
{
@SuppressWarnings("unused")
private GUIMultiModelHandler handler;
private Model computeThis;
private double transientTime;
/** Creates a new instance of ComputeTransientThread */
public ComputeTransientThread(GUIMultiModelHandler handler, Model computeThis, double transientTime)
public ComputeTransientThread(GUIMultiModelHandler handler, double transientTime)
{
super(handler.getGUIPlugin());
this.handler = handler;
this.computeThis = computeThis;
this.transientTime = transientTime;
}
public void run()
{
//notify the interface that we are starting computation
// Notify the interface that we are starting computation
SwingUtilities.invokeLater(new Runnable()
{
public void run()
@ -60,14 +63,10 @@ public class ComputeTransientThread extends GUIComputationThread
}
});
//Do Computation
// Do Computation
try {
if (!(computeThis.getModelType() == ModelType.CTMC || computeThis.getModelType() == ModelType.DTMC))
throw new PrismException("Can only compute transient probabilities for DTMCs/CTMCs");
plug.getPrism().doTransient(computeThis, transientTime);
}
catch(PrismException e)
{
prism.doTransient(transientTime);
} catch (PrismException e) {
error(e.getMessage());
SwingUtilities.invokeLater(new Runnable()
{
@ -80,7 +79,7 @@ public class ComputeTransientThread extends GUIComputationThread
});
return;
}
//If we get here, computation was successful
SwingUtilities.invokeLater(new Runnable()
{

106
prism/src/userinterface/model/computation/ExportBuiltModelThread.java

@ -35,85 +35,97 @@ import userinterface.*;
import userinterface.model.*;
import userinterface.util.*;
/**
* Thread that performs export of a built model.
*/
public class ExportBuiltModelThread extends GUIComputationThread
{
@SuppressWarnings("unused")
private GUIMultiModelHandler handler;
private Model m;
private int exportEntity;
private int exportType;
private File exportFile;
private Exception e;
/** Creates a new instance of ExportBuiltModelThread */
public ExportBuiltModelThread(GUIMultiModelHandler handler, Model m, int entity, int type, File f)
public ExportBuiltModelThread(GUIMultiModelHandler handler, int entity, int type, File f)
{
super(handler.getGUIPlugin());
this.handler = handler;
this.m = m;
this.exportEntity = entity;
this.exportType = type;
this.exportFile = f;
}
public void run()
{
try
{
//notify the interface of the start of computation
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
plug.startProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
plug.setTaskBarText("Exporting...");
}});
//Do export
try {
// Notify the interface of the start of computation
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
plug.startProgress();
plug.setTaskBarText("Exporting...");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
}
});
// Do export
try {
switch (exportEntity) {
case GUIMultiModelHandler.STATES_EXPORT:
prism.exportStatesToFile(m, exportType, exportFile);
prism.exportStatesToFile(exportType, exportFile);
break;
case GUIMultiModelHandler.TRANS_EXPORT:
prism.exportTransToFile(m, true, exportType, exportFile);
prism.exportTransToFile(true, exportType, exportFile);
break;
case GUIMultiModelHandler.STATE_REWARDS_EXPORT:
prism.exportStateRewardsToFile(m, exportType, exportFile);
prism.exportStateRewardsToFile(exportType, exportFile);
break;
case GUIMultiModelHandler.TRANS_REWARDS_EXPORT:
prism.exportTransRewardsToFile(m, true, exportType, exportFile);
prism.exportTransRewardsToFile(true, exportType, exportFile);
break;
}
}
catch(FileNotFoundException e)
{
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Exporting... error.");
error("Could not export to file \"" + exportFile + "\"");
}});
} catch (FileNotFoundException e) {
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
plug.stopProgress();
plug.setTaskBarText("Exporting... error.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
error("Could not export to file \"" + exportFile + "\"");
}
});
return;
}
catch(PrismException e2)
{
this.e = e2;
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
plug.setTaskBarText("Exporting... error.");
error(e.getMessage());
}});
} catch (PrismException e2) {
error(e2.getMessage());
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
plug.stopProgress();
plug.setTaskBarText("Exporting... error.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
}
});
return;
}
//If we get here export was successful, notify interface
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
plug.stopProgress();
plug.setTaskBarText("Exporting... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
}});
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
plug.stopProgress();
plug.setTaskBarText("Exporting... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
}
});
}
// catch and ignore any thread exceptions
catch (java.lang.InterruptedException e) {}
catch (java.lang.reflect.InvocationTargetException e) {}
catch (java.lang.InterruptedException e) {
} catch (java.lang.reflect.InvocationTargetException e) {
}
}
}

81
prism/src/userinterface/model/computation/ParseModelThread.java

@ -47,7 +47,7 @@ public class ParseModelThread extends GUIComputationThread
static int counter = 0;
int id;
long before;
/** Creates a new instance of ParseModelThread */
public ParseModelThread(GUIMultiModelHandler handler, String parseThis, boolean isPepa, boolean background)
{
@ -62,54 +62,69 @@ public class ParseModelThread extends GUIComputationThread
public void run()
{
//Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable() { public void run() {
if(!background)plug.startProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
if(!background)plug.setTaskBarText("Parsing model...");
}});
// Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (!background)
plug.startProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_START, plug));
if (!background)
plug.setTaskBarText("Parsing model...");
}
});
// do parsing
try {
// normal prism mode
if(!isPepa) {
if(!background) plug.log("\nParsing model...\n");
if (!isPepa) {
if (!background)
plug.log("\nParsing model...\n");
mod = prism.parseModelString(parseThis);
}
// pepa mode
else {
if(!background) plug.log("\nParsing PEPA model...\n");
if (!background)
plug.log("\nParsing PEPA model...\n");
mod = prism.importPepaString(parseThis);
}
}
catch (PrismLangException err) {
// Load into PRISM once done
prism.loadPRISMModel(mod);
} catch (PrismLangException err) {
parseError = err;
errMsg = err.getMessage();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if(!background) plug.stopProgress();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (!background)
plug.stopProgress();
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_ERROR, plug));
if(!background) plug.setTaskBarText("Parsing model... error.");
if(!background) error(errMsg);
handler.modelParseFailed(parseError, background);
if (!background)
plug.setTaskBarText("Parsing model... error.");
if (!background)
error(errMsg);
handler.modelParseFailed(parseError, background);
}
});
return;
} catch (PrismException e) {
throw new RuntimeException("Unexpected PrismException: " + e.getMessage());
}
catch (PrismException e) {
throw new RuntimeException("Unexpected PrismException: " + e.getMessage());
}
//If we get here, the parse has been successful, notify the interface and tell the handler.
SwingUtilities.invokeLater(new Runnable() { public void run() {
if(!background) plug.stopProgress();
if(!background) plug.setTaskBarText("Parsing model... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
handler.modelParsedSuccessful(mod);
}});
// If we get here, the parse has been successful, notify the interface and tell the handler.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (!background)
plug.stopProgress();
if (!background)
plug.setTaskBarText("Parsing model... done.");
plug.notifyEventListeners(new GUIComputationEvent(GUIComputationEvent.COMPUTATION_DONE, plug));
handler.modelParsedSuccessful(mod);
}
});
}
}

155
prism/src/userinterface/properties/GUIExperiment.java

@ -32,14 +32,11 @@ import parser.*;
import parser.ast.*;
import parser.type.*;
import prism.*;
import pta.DigitalClocks;
import userinterface.*;
import javax.swing.*;
import userinterface.*;
import java.util.*;
import userinterface.util.*;
import userinterface.simulator.networking.*;
public class GUIExperiment
{
@ -48,7 +45,6 @@ public class GUIExperiment
private prism.ResultsCollection results;
private boolean finished = false;
private ModulesFile mod;
private UndefinedConstants cons;
private PropertiesFile prop; //contains 1 property only
@ -63,14 +59,12 @@ public class GUIExperiment
private Result res;
/** Creates a new instance of GUIExperiment */
public GUIExperiment(GUIExperimentTable table, GUIMultiProperties guiProp, PropertiesFile prop, UndefinedConstants cons, ModulesFile mod,
boolean useSimulation)
public GUIExperiment(GUIExperimentTable table, GUIMultiProperties guiProp, PropertiesFile prop, UndefinedConstants cons, boolean useSimulation)
{
this.table = table;
this.guiProp = guiProp;
this.prop = prop;
this.cons = cons;
this.mod = mod;
this.useSimulation = useSimulation;
results = new prism.ResultsCollection(cons, prop.getProperty(0).getResultName());
@ -139,7 +133,7 @@ public class GUIExperiment
public void startExperiment()
{
theThread = new ExperimentThread(guiProp, this, cons, mod, prop);
theThread = new ExperimentThread(guiProp, cons, prop);
running = true;
theThread.start();
}
@ -197,27 +191,18 @@ public class GUIExperiment
class ExperimentThread extends GUIComputationThread
{
private UndefinedConstants undefinedConstants;
private ModulesFile modulesFile;
private PropertiesFile propertiesFile;
private GUIExperiment exp;
public ExperimentThread(GUIMultiProperties guiProp, GUIExperiment exp, UndefinedConstants undefinedConstants, ModulesFile modulesFile,
PropertiesFile propertiesFile)
public ExperimentThread(GUIMultiProperties guiProp, UndefinedConstants undefinedConstants, PropertiesFile propertiesFile)
{
super(guiProp);
this.exp = exp;
this.undefinedConstants = undefinedConstants;
this.modulesFile = modulesFile;
this.propertiesFile = propertiesFile;
}
public void run()
{
int i, k;
boolean clear = true;
Model model = null;
ModulesFile modulesFileToCheck;
int propertyIndex = propertiesFile.getNumProperties() - 1;
Expression propertyToCheck = propertiesFile.getProperty(propertyIndex);
SimulationInformation info = null;
@ -240,14 +225,11 @@ public class GUIExperiment
});
for (i = 0; i < undefinedConstants.getNumModelIterations(); i++) {
definedMFConstants = undefinedConstants.getMFConstantValues();
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
logln("\nModel constants: " + definedMFConstants);
// set values for ModulesFile constants
try {
modulesFile.setUndefinedConstants(definedMFConstants);
definedMFConstants = undefinedConstants.getMFConstantValues();
prism.setPRISMModelConstants(definedMFConstants);
} catch (PrismException e) {
// in case of error, report it (in log only), store as result, and go on to the next model
errorLog(e.getMessage());
@ -260,46 +242,12 @@ public class GUIExperiment
continue;
}
// only do explicit model construction if necessary
if (!useSimulation && modulesFile.getModelType() != ModelType.PTA) {
// build model
try {
logSeparator();
model = prism.buildModel(modulesFile);
clear = false;
} catch (PrismException e) {
// in case of error, report it (in log only), store as result, and go on to the next model
errorLog(e.getMessage());
try {
setMultipleErrors(definedMFConstants, null, e);
} catch (PrismException e2) {
error("Problem storing results");
}
undefinedConstants.iterateModel();
continue;
}
// remove any deadlocks (don't prompt - probably should)
StateList states = model.getDeadlockStates();
if (states != null) {
if (states.size() > 0) {
guiProp.logWarning(states.size() + " deadlock states detected; adding self-loops in these states...");
model.fixDeadlocks();
}
}
// print some model info
guiProp.log("\n");
model.printTransInfo(guiProp.getGUI().getLog());
}
// collect information for simulation if required
if (useSimulation && !reuseInfo) {
try {
info = null;
info = GUISimulationPicker.defineSimulationWithDialog(guiProp.getGUI(), propertyToCheck, modulesFile, "(" + definedMFConstants
+ ")");
info = GUISimulationPicker.defineSimulationWithDialog(guiProp.getGUI(), propertyToCheck, prism.getPRISMModel(), "("
+ definedMFConstants + ")");
} catch (PrismException e) {
// in case of error, report it (in log only), store as result, and go on to the next model
errorLog(e.getMessage());
@ -308,8 +256,6 @@ public class GUIExperiment
} catch (PrismException e2) {
error("Problem storing results");
}
if (!clear)
model.clear();
undefinedConstants.iterateModel();
continue;
}
@ -328,31 +274,11 @@ public class GUIExperiment
}
}
// for distributed simulation, pass control to the GUISimulatorDistributionDialog
if (useSimulation && info.isDistributed()) {
try {
GUISimulatorDistributionDialog dist = new GUISimulatorDistributionDialog(guiProp.getGUI(), prism.getSimulator(), true);
dist.show(exp, this, modulesFile, propertiesFile, undefinedConstants, propertyToCheck, info);
//new GUISimulatorDistributionDialog(guiProp.getGUI(), prism.getSimulator(), true).show(modulesFile, undefinedConstants, propertyToCheck, info);
} catch (PrismException e) {
// in case of error, report it (in log only), store as result, and go on to the next model
errorLog(e.getMessage());
try {
setMultipleErrors(definedMFConstants, null, e);
} catch (PrismException e2) {
error("Problem storing results");
}
if (!clear)
model.clear();
undefinedConstants.iterateModel();
continue;
}
}
// for simulation where "simultaneous property checking" is enabled...
else if (useSimulation && prism.getSettings().getBoolean(PrismSettings.SIMULATOR_SIMULTANEOUS)
&& undefinedConstants.getNumPropertyIterations() > 1) {
try {
// TODO
logSeparator();
logln("\nSimulating: " + propertyToCheck);
if (definedMFConstants != null)
@ -365,11 +291,11 @@ public class GUIExperiment
if (info.getInitialState() == null) {
initialState = null;
} else {
initialState = new parser.State(info.getInitialState(), modulesFile);
initialState = new parser.State(info.getInitialState(), prism.getPRISMModel());
}
// do simulation
prism.modelCheckSimulatorExperiment(modulesFile, propertiesFile, undefinedConstants, results, propertyToCheck, initialState, info
.getMaxPathLength(), info.createSimulationMethod());
prism.modelCheckSimulatorExperiment(propertiesFile, undefinedConstants, results, propertyToCheck, initialState,
info.getMaxPathLength(), info.createSimulationMethod());
// update progress meter
// (all properties simulated simultaneously so can't get more accurate feedback at the moment anyway)
table.progressChanged();
@ -392,57 +318,16 @@ public class GUIExperiment
throw new InterruptedException();
try {
// set values for PropertiesFile constants
// Set values for PropertiesFile constants
if (propertiesFile != null) {
definedPFConstants = undefinedConstants.getPFConstantValues();
propertiesFile.setSomeUndefinedConstants(definedPFConstants);
}
// log output
logSeparator();
logln("\n" + (useSimulation ? "Simulating" : "Model checking") + ": " + propertyToCheck);
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
logln("Model constants: " + definedMFConstants);
if (definedPFConstants != null)
if (definedPFConstants.getNumValues() > 0)
logln("Property constants: " + definedPFConstants);
// for PTAs via digital clocks, do model translation and build
if (modulesFile.getModelType() == ModelType.PTA
&& prism.getSettings().getString(PrismSettings.PRISM_PTA_METHOD).equals("Digital clocks")) {
DigitalClocks dc = new DigitalClocks(prism);
dc.translate(modulesFile, propertiesFile, propertyToCheck);
modulesFileToCheck = dc.getNewModulesFile();
modulesFileToCheck.setUndefinedConstants(modulesFile.getConstantValues());
// build model
logSeparator();
model = prism.buildModel(modulesFileToCheck);
clear = false;
// by construction, deadlocks can only occur from timelocks
StateList states = model.getDeadlockStates();
if (states != null && states.size() > 0) {
throw new PrismException("Timelock in PTA, e.g. in state (" + states.getFirstAsValues() + ")");
}
// print some model info
guiProp.log("\n");
model.printTransInfo(guiProp.getGUI().getLog());
} else {
modulesFileToCheck = modulesFile;
}
// exact (non-approximate) model checking
// Normal model checking
if (!useSimulation) {
// PTA model checking
if (modulesFileToCheck.getModelType() == ModelType.PTA) {
res = prism.modelCheckPTA(modulesFileToCheck, propertiesFile, propertyToCheck);
}
// Non-PTA model checking
else {
res = prism.modelCheck(model, propertiesFile, propertyToCheck);
}
res = prism.modelCheck(propertiesFile, propertyToCheck, definedPFConstants);
}
// approximate (simulation-based) model checking
// Approximate (simulation-based) model checking
else {
// convert initial Values -> State
// (remember: null means use default or pick randomly)
@ -450,10 +335,10 @@ public class GUIExperiment
if (info.getInitialState() == null) {
initialState = null;
} else {
initialState = new parser.State(info.getInitialState(), modulesFileToCheck);
initialState = new parser.State(info.getInitialState(), prism.getPRISMModel());
}
// do simulation
res = prism.modelCheckSimulator(modulesFileToCheck, propertiesFile, propertyToCheck, initialState, info.getMaxPathLength(),
res = prism.modelCheckSimulator(propertiesFile, propertyToCheck, definedPFConstants, initialState, info.getMaxPathLength(),
info.createSimulationMethod());
}
} catch (PrismException e) {
@ -481,8 +366,6 @@ public class GUIExperiment
yield();
}
}
if (!clear)
model.clear();
// iterate to next model
undefinedConstants.iterateModel();
yield();
@ -521,8 +404,6 @@ public class GUIExperiment
catch (InterruptedException e2) {
} catch (java.lang.reflect.InvocationTargetException e2) {
}
if (!clear)
model.clear();
experimentInterrupted();
}
// catch and ignore possible exception from invokeAndWait calls

4
prism/src/userinterface/properties/GUIExperimentTable.java

@ -70,9 +70,9 @@ public class GUIExperimentTable extends JTable
}
}
public int newExperiment(PropertiesFile propFile, UndefinedConstants cons, ModulesFile mf, boolean useSimulation)//propFile only contains 1 con
public int newExperiment(PropertiesFile propFile, UndefinedConstants cons, boolean useSimulation)//propFile only contains 1 con
{
GUIExperiment ge = new GUIExperiment(this, guiProps, propFile, cons, mf, useSimulation);
GUIExperiment ge = new GUIExperiment(this, guiProps, propFile, cons, useSimulation);
return expModel.addExperiment(ge);
}

93
prism/src/userinterface/properties/GUIMultiProperties.java

@ -83,8 +83,6 @@ import parser.type.Type;
import parser.type.TypeDouble;
import parser.type.TypeInt;
import parser.type.TypeInterval;
import prism.Model;
import prism.ModelType;
import prism.PrismException;
import prism.PrismSettings;
import prism.PrismSettingsListener;
@ -102,7 +100,6 @@ import userinterface.properties.computation.LoadPropertiesThread;
import userinterface.properties.computation.ModelCheckThread;
import userinterface.properties.computation.SimulateModelCheckThread;
import userinterface.simulator.GUISimulator;
import userinterface.simulator.networking.GUISimulatorDistributionDialog;
import userinterface.util.GUIComputationEvent;
import userinterface.util.GUIEvent;
import userinterface.util.GUIExitEvent;
@ -111,6 +108,7 @@ import userinterface.util.GUIPrismFileFilter;
/**
* Properties tab of the PRISM GUI.
*/
@SuppressWarnings("serial")
public class GUIMultiProperties extends GUIPlugin implements MouseListener, ListSelectionListener, PrismSettingsListener, ContainerListener
{
//CONSTANTS
@ -124,15 +122,13 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
// Current model (gets updated only by event listening to GUIModel)
private ModulesFile parsedModel;
private Model builtModel;
// Constants for model (updated by events or locally)
private Values mfConstants;
// State
private boolean modified;
private boolean modifiedSinceBuild;
private boolean computing;
private boolean verifyAfterReceiveParseNotification, verifyAfterReceiveBuildNotification, experimentAfterReceiveParseNotification,
private boolean verifyAfterReceiveParseNotification, experimentAfterReceiveParseNotification,
simulateAfterReceiveParseNotification;
private PropertiesFile parsedProperties;
private ArrayList<GUIProperty> propertiesToBeVerified;
@ -171,8 +167,8 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
simulator.setGUIProb(this); // link required
initComponents();
a_newList();
setBuiltModel(null);
setParsedModel(null);
doEnables();
//options = new GUIPropertiesOptions(this);
}
@ -240,18 +236,6 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
propList.repaint();
}
protected void verifyAfterBuild()
{
verifyAfterReceiveBuildNotification = false;
// Start model check process
if (builtModel != null && parsedProperties != null && propertiesToBeVerified != null) {
Thread t = new ModelCheckThread(this, builtModel, parsedProperties, propertiesToBeVerified, mfConstants, pfConstants);
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
}
protected void verifyAfterParse()
{
ArrayList<GUIProperty> validGUIProperties;
@ -278,30 +262,19 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
if (result != GUIConstantsPicker.VALUES_DONE)
return;
}
// Store model constants (even though will be stored again after build)
// Don't set in model: this will be done during build process
// Store model/property constants
mfConstants = uCon.getMFConstantValues();
// Store property constants and set in file
pfConstants = uCon.getPFConstantValues();
getPrism().setPRISMModelConstants(mfConstants);
parsedProperties.setSomeUndefinedConstants(pfConstants);
// Store properties to be verified
propertiesToBeVerified = validGUIProperties;
// If required, trigger build then verify
if (parsedModel.getModelType() != ModelType.PTA) {
verifyAfterReceiveBuildNotification = true;
notifyEventListeners(new GUIPropertiesEvent(GUIPropertiesEvent.REQUEST_MODEL_BUILD, mfConstants));
}
// If no build required (e.g. for PTAs), just do model checking now
else {
// Start model check process
parsedModel.setUndefinedConstants(mfConstants);
if (parsedProperties != null && propertiesToBeVerified != null) {
Thread t = new ModelCheckThread(this, parsedModel, parsedProperties, propertiesToBeVerified, mfConstants, pfConstants);
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
}
for (GUIProperty gp : propertiesToBeVerified)
gp.setConstants(mfConstants, pfConstants);
// Start model checking
Thread t = new ModelCheckThread(this, parsedProperties, propertiesToBeVerified, pfConstants);
t.setPriority(Thread.NORM_PRIORITY);
t.start();
} catch (PrismException e) {
error(e.getMessage());
return;
@ -363,12 +336,19 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
return;
}
// Store model/property constants and set in files
// Store model/property constants
mfConstants = uCon.getMFConstantValues();
pfConstants = uCon.getPFConstantValues();
parsedModel.setUndefinedConstants(mfConstants);
getPrism().setPRISMModelConstants(mfConstants);
parsedProperties.setSomeUndefinedConstants(pfConstants);
for (GUIProperty gp : simulatableGUIProperties)
gp.setConstants(mfConstants, pfConstants);
// Store properties to be verified
propertiesToBeVerified = validGUIProperties;
for (GUIProperty gp : propertiesToBeVerified)
gp.setConstants(mfConstants, pfConstants);
// Get simulation info with dialog
SimulationInformation info = GUISimulationPicker.defineSimulationWithDialog(this.getGUI(), simulatableExprs, parsedModel, null);
@ -377,14 +357,9 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
return;
if (parsedModel != null && parsedProperties != null) {
if (info.isDistributed()) {
new GUISimulatorDistributionDialog(getGUI(), getPrism().getSimulator(), true).show(this, parsedModel, parsedProperties, simulatableGUIProperties,
info);
} else {
Thread t = new SimulateModelCheckThread(this, parsedModel, parsedProperties, simulatableGUIProperties, mfConstants, pfConstants, info);
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
Thread t = new SimulateModelCheckThread(this, parsedProperties, simulatableGUIProperties, pfConstants, info);
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
} catch (PrismException e) {
error(e.getMessage());
@ -470,12 +445,11 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
}
// Use these values to create a new experiment
int i = experiments.newExperiment(parsedProperties, uCon, parsedModel, useSimulation);
int i = experiments.newExperiment(parsedProperties, uCon, useSimulation);
boolean notCancelled = true;
// start the experiment, via the graph dialog if appropriate
if (showGraphDialog) {
GUIGraphPicker ggp = new GUIGraphPicker(getGUI(), this, experiments.getExperiment(i), graphHandler, false);
if (ggp.isGraphCancelled()) {
if (questionYesNo("Do you want to cancel the experiment completely?", 0) == 0)
notCancelled = false;
@ -616,12 +590,6 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
doEnables();
}
protected void setBuiltModel(Model m)
{
builtModel = m;
doEnables();
}
protected void doEnables()
{
// properties panel
@ -730,7 +698,6 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
consTable.newList();
labTable.newList();
setModified(false);
modifiedSinceBuild = true;
setActiveFile(null);
doEnables();
notifyEventListeners(new GUIPropertiesEvent(GUIPropertiesEvent.PROPERTIES_LIST_CHANGED));
@ -1138,16 +1105,13 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
GUIModelEvent me = (GUIModelEvent) e;
if (me.getID() == me.NEW_MODEL) {
//New Model
setBuiltModel(null);
setParsedModel(null);
doEnables();
//newList();
} else if (me.getID() == GUIModelEvent.MODEL_BUILT) {
setBuiltModel(me.getModel());
if (me.getBuildValues() != null)
mfConstants = me.getBuildValues();
modifiedSinceBuild = false;
if (verifyAfterReceiveBuildNotification)
verifyAfterBuild();
doEnables();
} else if (me.getID() == GUIModelEvent.MODEL_PARSED) {
setParsedModel(me.getModulesFile());
if (verifyAfterReceiveParseNotification)
@ -1160,11 +1124,6 @@ public class GUIMultiProperties extends GUIPlugin implements MouseListener, List
verifyAfterReceiveParseNotification = false;
experimentAfterReceiveParseNotification = false;
simulateAfterReceiveParseNotification = false;
} else if (me.getID() == GUIModelEvent.MODEL_BUILD_FAILED) {
verifyAfterReceiveBuildNotification = false;
} else if (me.getID() == GUIModelEvent.MODIFIED_SINCE_SAVE) {
//setBuiltModel(null);
modifiedSinceBuild = true;
} else if (me.getID() == GUIModelEvent.NEW_LOAD_NOT_RELOAD_MODEL) {
if (getPrism().getSettings().getBoolean(PrismSettings.PROPERTIES_CLEAR_LIST_ON_LOAD)) {
a_newList();

77
prism/src/userinterface/properties/computation/ModelCheckThread.java

@ -33,7 +33,6 @@ import javax.swing.*;
import parser.*;
import parser.ast.*;
import prism.*;
import pta.DigitalClocks;
import userinterface.*;
import userinterface.util.*;
import userinterface.properties.*;
@ -45,53 +44,27 @@ public class ModelCheckThread extends GUIComputationThread
{
// Access to GUI (to send notifications etc.)
private GUIMultiProperties parent;
// Model (in most cases, have a Model object; in others, e.g. PTA model checking,
// we just have the language-level model description, i.e. a ModulesFile).
// Currently exactly one-of model/modulesFile is non-null
private Model model;
private ModulesFile modulesFile;
// Properties file and GUI properties (these are assumed to match)
// (Also need properties file for access to constants/labels/etc.)
private PropertiesFile propertiesFile;
private ArrayList<GUIProperty> guiProps;
// Values give to constants
private Values definedMFConstants;
private Values definedPFConstants;
/**
* Create a new instance of ModelCheckThread (where a Model has been built)
*/
public ModelCheckThread(GUIMultiProperties parent, Model model, PropertiesFile propertiesFile, ArrayList<GUIProperty> guiProps, Values definedMFConstants,
Values definedPFConstants)
public ModelCheckThread(GUIMultiProperties parent, PropertiesFile propertiesFile, ArrayList<GUIProperty> guiProps, Values definedPFConstants)
{
super(parent);
this.parent = parent;
this.model = model;
this.modulesFile = null;
this.propertiesFile = propertiesFile;
this.guiProps = guiProps;
this.definedMFConstants = definedMFConstants;
this.definedPFConstants = definedPFConstants;
}
/**
* Create a new instance of ModelCheckThread (where no Model has been built, e.g. PTAs)
*/
public ModelCheckThread(GUIMultiProperties parent, ModulesFile modulesFile, PropertiesFile propertiesFile, ArrayList<GUIProperty> guiProps, Values definedMFConstants,
Values definedPFConstants)
{
this(parent, (Model) null, propertiesFile, guiProps, definedMFConstants, definedPFConstants);
this.modulesFile = modulesFile;
}
public void run()
{
ModulesFile modulesFileToCheck;
boolean clear = true;
if (model == null && modulesFile == null)
return;
// Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable()
{
@ -128,52 +101,7 @@ public class ModelCheckThread extends GUIComputationThread
// Do model checking
try {
// Print info to log
logSeparator();
logln("\nModel checking: " + propertiesFile.getProperty(i));
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
logln("Model constants: " + definedMFConstants);
if (definedPFConstants != null)
if (definedPFConstants.getNumValues() > 0)
logln("Property constants: " + definedPFConstants);
// for PTAs via digital clocks, do model translation and build
if (model == null && modulesFile.getModelType() == ModelType.PTA
&& prism.getSettings().getString(PrismSettings.PRISM_PTA_METHOD).equals("Digital clocks")) {
DigitalClocks dc = new DigitalClocks(prism);
dc.translate(modulesFile, propertiesFile, propertiesFile.getProperty(i));
modulesFileToCheck = dc.getNewModulesFile();
modulesFileToCheck.setUndefinedConstants(modulesFile.getConstantValues());
// build model
logSeparator();
model = prism.buildModel(modulesFileToCheck);
clear = false;
// by construction, deadlocks can only occur from timelocks
StateList states = model.getDeadlockStates();
if (states != null && states.size() > 0) {
throw new PrismException("Timelock in PTA, e.g. in state (" + states.getFirstAsValues() + ")");
}
// print some model info
log("\n");
model.printTransInfo(parent.getGUI().getLog());
} else {
modulesFileToCheck = modulesFile;
}
// No model (PTA, non-digital-clocks) case
if (model == null) {
if (modulesFile.getModelType() != ModelType.PTA)
throw new PrismException("No model to verify");
result = prism.modelCheckPTA(modulesFileToCheck, propertiesFile, propertiesFile.getProperty(i));
}
// Normal model checking
else {
result = prism.modelCheck(model, propertiesFile, propertiesFile.getProperty(i));
}
// Clear model, if required
if (!clear) {
model.clear();
clear = true;
}
result = prism.modelCheck(propertiesFile, propertiesFile.getProperty(i), definedPFConstants);
} catch (PrismException e) {
result = new Result(e);
error(e.getMessage());
@ -186,7 +114,6 @@ public class ModelCheckThread extends GUIComputationThread
//while(!ic.canContinue){}
gp.setResult(result);
gp.setMethodString("Verification");
gp.setConstants(definedMFConstants, definedPFConstants);
gp.setNumberOfWarnings(prism.getMainLog().getNumberOfWarnings());
parent.repaintList();

58
prism/src/userinterface/properties/computation/SimulateModelCheckThread.java

@ -40,32 +40,28 @@ import userinterface.util.*;
import userinterface.properties.*;
/**
* This thread handles the calling of simulation-based
* model checking (sampling) with the given modules file (constants
* defined), properties file (constants defined), list of properties to
* be (approximately) verified and initial state (default/random if null).
* Thread that executes approximate (simulation-based) model checking of a property via PRISM.
* Model should have been loaded into PRISM already. Supplied are:
* properties file (constants defined), list of properties to
* be (approximately) verified and initial state (default/random if null).
*/
public class SimulateModelCheckThread extends GUIComputationThread
{
private GUIMultiProperties parent;
private ModulesFile mf;
private PropertiesFile pf;
private ArrayList<GUIProperty> guiProps;
private Values definedMFConstants;
private Values definedPFConstants;
private int maxPathLength;
private SimulationInformation info;
/** Creates a new instance of SimulateModelCheckThread */
public SimulateModelCheckThread(GUIMultiProperties parent, ModulesFile m, PropertiesFile prFi, ArrayList<GUIProperty> guiProps, Values definedMFConstants,
public SimulateModelCheckThread(GUIMultiProperties parent, PropertiesFile prFi, ArrayList<GUIProperty> guiProps,
Values definedPFConstants, SimulationInformation info)
{
super(parent);
this.parent = parent;
this.mf = m;
this.pf = prFi;
this.guiProps = guiProps;
this.definedMFConstants = definedMFConstants;
this.definedPFConstants = definedPFConstants;
this.info = info;
this.maxPathLength = info.getMaxPathLength();
@ -74,11 +70,8 @@ public class SimulateModelCheckThread extends GUIComputationThread
public void run()
{
boolean allAtOnce = prism.getSettings().getBoolean(PrismSettings.SIMULATOR_SIMULTANEOUS);
SimulationMethod method = info.createSimulationMethod();
if (mf == null)
return;
//Notify user interface of the start of computation
SwingUtilities.invokeLater(new Runnable()
@ -113,33 +106,16 @@ public class SimulateModelCheckThread extends GUIComputationThread
}
try {
// display info
logSeparator();
log("\nSimulating");
if (pf.getNumProperties() == 1) {
logln(": " + properties.get(0));
} else {
logln(" " + pf.getNumProperties() + " properties:");
for (int i = 0; i < properties.size(); i++) {
logln(" " + properties.get(i));
}
}
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
logln("Model constants: " + definedMFConstants);
if (definedPFConstants != null)
if (definedPFConstants.getNumValues() > 0)
logln("Property constants: " + definedPFConstants);
// convert initial Values -> State
// (remember: null means use default or pick randomly)
parser.State initialState;
if (info.getInitialState() == null) {
initialState = null;
} else {
initialState = new parser.State(info.getInitialState(), mf);
initialState = new parser.State(info.getInitialState(), prism.getPRISMModel());
}
// do simulation
results = prism.modelCheckSimulatorSimultaneously(mf, pf, properties, initialState, maxPathLength, method);
results = prism.modelCheckSimulatorSimultaneously(pf, properties, definedPFConstants, initialState, maxPathLength, method);
method.reset();
} catch (PrismException e) {
// in the case of an error which affects all props, store/report it
@ -163,7 +139,6 @@ public class SimulateModelCheckThread extends GUIComputationThread
GUIProperty gp = guiProps.get(i);
gp.setResult((results == null) ? new Result(resultError) : results[i]);
gp.setMethodString("Simulation");
gp.setConstants(definedMFConstants, definedPFConstants);
gp.setNumberOfWarnings(prism.getMainLog().getNumberOfWarnings());
}
}
@ -178,28 +153,18 @@ public class SimulateModelCheckThread extends GUIComputationThread
ict.start();
// do model checking
try {
logSeparator();
logln("\nSimulating" + ": " + pf.getProperty(i));
if (definedMFConstants != null)
if (definedMFConstants.getNumValues() > 0)
logln("Model constants: " + definedMFConstants);
if (definedPFConstants != null)
if (definedPFConstants.getNumValues() > 0)
logln("Property constants: " + definedPFConstants);
// convert initial Values -> State
// (remember: null means use default or pick randomly)
parser.State initialState;
if (info.getInitialState() == null) {
initialState = null;
} else {
initialState = new parser.State(info.getInitialState(), mf);
initialState = new parser.State(info.getInitialState(), prism.getPRISMModel());
}
// do simulation
result = prism.modelCheckSimulator(mf, pf, pf.getProperty(i), initialState, maxPathLength, method);
result = prism.modelCheckSimulator(pf, pf.getProperty(i), definedPFConstants, initialState, maxPathLength, method);
method.reset();
}
catch(PrismException e)
{
} catch (PrismException e) {
result = new Result(e);
error(e.getMessage());
}
@ -213,7 +178,6 @@ public class SimulateModelCheckThread extends GUIComputationThread
}
gp.setResult(result);
gp.setMethodString("Simulation");
gp.setConstants(definedMFConstants, definedPFConstants);
parent.repaintList();
}

Loading…
Cancel
Save