Browse Source

param/exact: protect against malformed rates / probabilities

Reject infinity and NaN. For exact mode (or constant functions), also
reject negative rates and probabilities.
master
Joachim Klein 8 years ago
committed by Dave Parker
parent
commit
622faad3e1
  1. 26
      prism/src/param/ModelBuilder.java

26
prism/src/param/ModelBuilder.java

@ -327,7 +327,7 @@ public final class ModelBuilder extends PrismComponent
*/ */
private ParamModel doModelConstruction(ModelGeneratorSymbolic modelGenSym) throws PrismException private ParamModel doModelConstruction(ModelGeneratorSymbolic modelGenSym) throws PrismException
{ {
ModelType modelType;
final ModelType modelType;
if (!modelGenSym.hasSingleInitialState()) { if (!modelGenSym.hasSingleInitialState()) {
throw new PrismNotSupportedException("Cannot do explicit-state reachability if there are multiple initial states"); throw new PrismNotSupportedException("Cannot do explicit-state reachability if there are multiple initial states");
@ -399,11 +399,35 @@ public final class ModelBuilder extends PrismComponent
for (int succNr = 0; succNr < numSuccessors; succNr++) { for (int succNr = 0; succNr < numSuccessors; succNr++) {
State stateNew = modelGenSym.computeTransitionTarget(choiceNr, succNr); State stateNew = modelGenSym.computeTransitionTarget(choiceNr, succNr);
Function probFn = modelGenSym.getTransitionProbabilityFunction(choiceNr, succNr); Function probFn = modelGenSym.getTransitionProbabilityFunction(choiceNr, succNr);
if (modelType == ModelType.CTMC) {
// check rate (non-normal?)
if (probFn.isInf() || probFn.isMInf() || probFn.isNaN()) {
throw new PrismException("For state " + state.toString(modelGenSym) + ", illegal rate " + probFn.asBigRational());
}
// check rate, if constant (negative?)
if (probFn.isConstant() && probFn.asBigRational().signum() < 0) {
throw new PrismException("For state " + state.toString(modelGenSym) + ", negative rate " + probFn.asBigRational());
}
}
// divide by sumOut // divide by sumOut
// for DTMC, this normalises over the choices // for DTMC, this normalises over the choices
// for CTMC this builds the embedded DTMC // for CTMC this builds the embedded DTMC
// for MDP this does nothing (sumOut is set to 1) // for MDP this does nothing (sumOut is set to 1)
probFn = probFn.divide(sumOut); probFn = probFn.divide(sumOut);
if (modelType == ModelType.DTMC || modelType == ModelType.MDP) {
// check probability (non-normal?)
if (probFn.isInf() || probFn.isMInf() || probFn.isNaN()) {
throw new PrismException("For state " + state.toString(modelGenSym) + ", illegal probability " + probFn.asBigRational());
}
// check probability, if constant (negative?)
if (probFn.isConstant() && probFn.asBigRational().signum() < 0) {
throw new PrismException("For state " + state.toString(modelGenSym) + ", negative probability " + probFn.asBigRational());
}
}
model.addTransition(permut[states.get(stateNew)], probFn, action == null ? "" : action.toString()); model.addTransition(permut[states.get(stateNew)], probFn, action == null ? "" : action.toString());
} }
if (isNonDet) { if (isNonDet) {

Loading…
Cancel
Save