private static SamplerDouble createSamplerForRewardProperty(ExpressionReward expr, ModulesFile mf) throws PrismException { // Extract reward structure index Object rs = expr.getRewardStructIndex(); int rsi = -1; if (mf.getNumRewardStructs() == 0) throw new PrismException("Model has no rewards specified"); if (rs == null) { rsi = 0; } else if (rs instanceof Expression) { rsi = ((Expression) rs).evaluateInt(); rs = new Integer(rsi); // for better error reporting below rsi = (rsi < 1 || rsi > mf.getNumRewardStructs()) ? -1 : rsi - 1; } else if (rs instanceof String) { rsi = mf.getRewardStructIndex((String) rs); } if (rsi == -1) throw new PrismException("Invalid reward structure index \"" + rs + "\""); // Construct sampler based on type ExpressionTemporal exprTemp = (ExpressionTemporal) expr.getExpression(); switch (exprTemp.getOperator()) { case ExpressionTemporal.R_C: if (mf.getModelType().continuousTime()) { // Continuous-time cumulative reward return new SamplerRewardCumulCont(exprTemp, rsi); } else { // Discrete-time cumulative reward return new SamplerRewardCumulDisc(exprTemp, rsi); } case ExpressionTemporal.R_I: if (mf.getModelType().continuousTime()) { // Continuous-time instantaneous reward return new SamplerRewardInstCont(exprTemp, rsi); } else { // Discrete-time instantaneous reward return new SamplerRewardInstDisc(exprTemp, rsi); } case ExpressionTemporal.P_F: // reachability reward return new SamplerRewardReach(exprTemp, rsi); } throw new PrismException("Can't create sampler for property \"" + expr + "\""); }
/** Constructor. */ public PTAModelChecker(Prism prism, ModulesFile modulesFile, PropertiesFile propertiesFile) throws PrismException { this.prism = prism; mainLog = prism.getMainLog(); this.modulesFile = modulesFile; this.propertiesFile = propertiesFile; // Get combined constant values from model/properties constantValues = new Values(); constantValues.addValues(modulesFile.getConstantValues()); if (propertiesFile != null) constantValues.addValues(propertiesFile.getConstantValues()); // Build a combined label list and expand any constants // (note labels in model are ignored (removed) during PTA translation so need to store here) labelList = new LabelList(); for (int i = 0; i < modulesFile.getLabelList().size(); i++) { labelList.addLabel( modulesFile.getLabelList().getLabelNameIdent(i), modulesFile.getLabelList().getLabel(i).deepCopy()); } for (int i = 0; i < propertiesFile.getLabelList().size(); i++) { labelList.addLabel( propertiesFile.getLabelList().getLabelNameIdent(i), propertiesFile.getLabelList().getLabel(i).deepCopy()); } labelList = (LabelList) labelList.replaceConstants(constantValues); // Build mapping from all (original model) variables to non-clocks only int numVars = modulesFile.getNumVars(); nonClockVarMap = new int[numVars]; int count = 0; for (int i = 0; i < numVars; i++) { if (modulesFile.getVarType(i) instanceof TypeClock) { nonClockVarMap[i] = -1; } else { nonClockVarMap[i] = count++; } } }
private static SamplerBoolean createSamplerForProbPathPropertySimple( Expression expr, ModulesFile mf) throws PrismException { // Negation/parentheses if (expr instanceof ExpressionUnaryOp) { ExpressionUnaryOp exprUnary = (ExpressionUnaryOp) expr; // Parentheses if (exprUnary.getOperator() == ExpressionUnaryOp.PARENTH) { // Recurse return createSamplerForProbPathPropertySimple(exprUnary.getOperand(), mf); } // Negation else if (exprUnary.getOperator() == ExpressionUnaryOp.NOT) { // Recurse, then negate meaning SamplerBoolean sampler = createSamplerForProbPathPropertySimple(exprUnary.getOperand(), mf); sampler.negate(); return sampler; } } // Temporal operators else if (expr instanceof ExpressionTemporal) { ExpressionTemporal exprTemp = (ExpressionTemporal) expr; // Next if (exprTemp.getOperator() == ExpressionTemporal.P_X) { return new SamplerNext(exprTemp); } // Until else if (exprTemp.getOperator() == ExpressionTemporal.P_U) { if (exprTemp.hasBounds()) { if (mf.getModelType().continuousTime()) { // Continuous-time bounded until return new SamplerBoundedUntilCont(exprTemp); } else { // Discrete-time bounded until return new SamplerBoundedUntilDisc(exprTemp); } } else { // Unbounded until return new SamplerUntil(exprTemp); } } // Anything else - convert to until and recurse else { return createSamplerForProbPathPropertySimple(exprTemp.convertToUntilForm(), mf); } } throw new PrismException("Can't create sampler for property \"" + expr + "\""); }
/** Model check a property. */ public Result check(Expression expr) throws PrismException { Modules2PTA m2pta; Result res; String resultString; long timer; // Starting model checking timer = System.currentTimeMillis(); // Check for system...endsystem - not supported yet if (modulesFile.getSystemDefn() != null) { throw new PrismException( "The system...endsystem construct is not supported yet (try the digital clocks engine instead)"); } // Translate ModulesFile object into a PTA object mainLog.println("\nBuilding PTA..."); m2pta = new Modules2PTA(prism, modulesFile); pta = m2pta.translate(); mainLog.println("\nPTA: " + pta.infoString()); // Check for references to clocks - not allowed (yet) // (do this before modifications below for better error reporting) expr.accept( new ASTTraverseModify() { public Object visit(ExpressionVar e) throws PrismLangException { if (e.getType() instanceof TypeClock) { throw new PrismLangException( "Properties cannot contain references to clocks (try the digital clocks engine instead)", e); } else { return e; } } }); // Take a copy of property, since will modify expr = expr.deepCopy(); // Remove property refs ands labels from property expr = (Expression) expr.expandPropRefsAndLabels(propertiesFile, labelList); // Evaluate constants in property (easier to do now) expr = (Expression) expr.replaceConstants(constantValues); // Also simplify expression to optimise model checking expr = (Expression) expr.simplify(); // Do model checking res = checkExpression(expr); // Model checking complete timer = System.currentTimeMillis() - timer; mainLog.println("\nModel checking completed in " + (timer / 1000.0) + " secs."); // Print result to log resultString = "Result"; if (!("Result".equals(expr.getResultName()))) resultString += " (" + expr.getResultName().toLowerCase() + ")"; resultString += ": " + res; mainLog.print("\n" + resultString + "\n"); // Return result return res; }