/** * 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; }
/** Build a time bounded reachability query into a PTA; return the new target location set. */ private BitSet buildTimeBoundIntoPta( PTA pta, BitSet targetLocs, int timeBound, boolean timeBoundStrict) { String timerClock = null; int timerClockIndex, numLocs, newTargetLoc; String newTargetLocString; List<Transition> trNewList; Transition trNew; BitSet targetLocsNew; boolean toTarget; int i; // Add a timer clock timerClock = "time"; while (pta.getClockIndex(timerClock) != -1) timerClock += "_"; timerClockIndex = pta.addClock(timerClock); // Add a new target location numLocs = pta.getNumLocations(); newTargetLocString = "target"; while (pta.getLocationIndex(newTargetLocString) != -1) newTargetLocString += "_"; newTargetLoc = pta.addLocation(newTargetLocString); // Go through old (on-target) locations for (i = 0; i < numLocs; i++) { trNewList = new ArrayList<Transition>(); for (Transition tr : pta.getTransitions(i)) { // See if the transition can go to a target location toTarget = false; for (Edge e : tr.getEdges()) { if (targetLocs.get(e.getDestination())) { toTarget = true; break; } } // Copy transition, modify edges going to target and add guard if (toTarget) { trNew = new Transition(tr); for (Edge e : trNew.getEdges()) { if (targetLocs.get(e.getDestination())) { e.setDestination(newTargetLoc); } } if (timeBoundStrict) trNew.addGuardConstraint(Constraint.buildLt(timerClockIndex, timeBound)); else trNew.addGuardConstraint(Constraint.buildLeq(timerClockIndex, timeBound)); trNewList.add(trNew); // Modify guard of copied transition if (timeBoundStrict) tr.addGuardConstraint(Constraint.buildGeq(timerClockIndex, timeBound)); else tr.addGuardConstraint(Constraint.buildGt(timerClockIndex, timeBound)); } } // Add new transitions to PTA for (Transition tr : trNewList) { pta.addTransition(tr); } } // Re-generate set of target locations targetLocsNew = new BitSet(pta.getNumLocations()); targetLocsNew.set(newTargetLoc); return targetLocsNew; }