/** * Determine which locations in the PTA satisfy a (Boolean) expression. Note: This is rather * inefficiently at the moment. TODO: potentially use explicit.StateMC on dummy model eventually */ private BitSet checkLocationExpression(Expression expr) throws PrismException { int i, n; BitSet res; // Labels - expand and recurse // (note: currently not used - these are expanded earlier) if (expr instanceof ExpressionLabel) { ExpressionLabel exprLabel = (ExpressionLabel) expr; if (exprLabel.getName().equals("deadlock")) throw new PrismException("The \"deadlock\" label is not yet supported for PTAs"); if (exprLabel.getName().equals("init")) throw new PrismException("The \"init\" label is not yet supported for PTAs"); i = labelList.getLabelIndex(exprLabel.getName()); if (i == -1) throw new PrismException("Unknown label \"" + exprLabel.getName() + "\" in property"); // Check recursively return checkLocationExpression(labelList.getLabel(i)); } // Other expressions... else { List<Object> states; // Object[] state; states = pta.getLocationNameList(); n = states.size(); res = new BitSet(n); for (i = 0; i < n; i++) { // state = (Object[])states.get(i); State state = (State) states.get(i); if (expr.evaluateBoolean(state, nonClockVarMap)) { res.set(i); } } } return res; }
/** 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; }