/** Construct the parallel composition of two PTAs. */ public PTA compose(PTA pta1, PTA pta2) { Set<String> alpha1, alpha2, alpha1only, alpha2only, sync; Transition transition; Edge edge; double prob; IndexPair state; int src, dest; // Store PTAs locally and create new one to store parallel composition this.pta1 = pta1; this.pta2 = pta2; par = new PTA(); // New set of clocks is union of sets for two PTAs for (String s : pta1.clockNames) { par.getOrAddClock(s); } for (String s : pta2.clockNames) { par.getOrAddClock(s); } // Get alphabets, compute intersection etc. alpha1 = pta1.getAlphabet(); alpha2 = pta2.getAlphabet(); // System.out.println("alpha1: " + alpha1); // System.out.println("alpha2: " + alpha2); sync = new LinkedHashSet<String>(); alpha1only = new LinkedHashSet<String>(); alpha2only = new LinkedHashSet<String>(); for (String a : alpha1) { if (!("".equals(a)) && alpha2.contains(a)) { sync.add(a); } else { alpha1only.add(a); } } for (String a : alpha2) { if (!alpha1.contains(a)) { alpha2only.add(a); } } // Explicitly add tau to action lists alpha1only.add(""); alpha2only.add(""); // System.out.println("alpha1only: " + alpha1only); // System.out.println("alpha2only: " + alpha2only); // System.out.println("sync: " + sync); // Initialise states storage states = new IndexedSet<IndexPair>(); explore = new LinkedList<IndexPair>(); // Add initial location addState(0, 0); src = -1; while (!explore.isEmpty()) { // Pick next state to explore // (they are stored in order found so know index is src+1) state = explore.removeFirst(); src++; // Go through asynchronous transitions of PTA 1 for (String a : alpha1only) { for (Transition transition1 : pta1.getTransitionsByAction(state.i1, a)) { // Create new transition transition = par.addTransition(src, a); // Copy guard for (Constraint c : transition1.getGuardConstraints()) transition.addGuardConstraint(c.deepCopy().renameClocks(pta1, par)); // Combine edges for (Edge edge1 : transition1.getEdges()) { prob = edge1.getProbability(); dest = addState(edge1.getDestination(), state.i2); edge = transition.addEdge(prob, dest); // Copy resets for (Map.Entry<Integer, Integer> e : edge1.getResets()) { edge.addReset(PTA.renameClock(pta1, par, e.getKey()), e.getValue()); } } } } // Go through asynchronous transitions of PTA 2 for (String a : alpha2only) { for (Transition transition2 : pta2.getTransitionsByAction(state.i2, a)) { // Create new transition transition = par.addTransition(src, a); // Copy guard for (Constraint c : transition2.getGuardConstraints()) transition.addGuardConstraint(c.deepCopy().renameClocks(pta2, par)); // Combine edges for (Edge edge2 : transition2.getEdges()) { prob = edge2.getProbability(); dest = addState(state.i1, edge2.getDestination()); edge = transition.addEdge(prob, dest); // Copy resets for (Map.Entry<Integer, Integer> e : edge2.getResets()) { edge.addReset(PTA.renameClock(pta2, par, e.getKey()), e.getValue()); } } } } // Go through synchronous transitions for (String a : sync) { for (Transition transition1 : pta1.getTransitionsByAction(state.i1, a)) { for (Transition transition2 : pta2.getTransitionsByAction(state.i2, a)) { // Create new transition transition = par.addTransition(src, a); // Guard is conjunction of guards for (Constraint c : transition1.getGuardConstraints()) transition.addGuardConstraint(c.deepCopy().renameClocks(pta1, par)); for (Constraint c : transition2.getGuardConstraints()) transition.addGuardConstraint(c.deepCopy().renameClocks(pta2, par)); // Combine edges for (Edge edge1 : transition1.getEdges()) { for (Edge edge2 : transition2.getEdges()) { prob = edge1.getProbability() * edge2.getProbability(); dest = addState(edge1.getDestination(), edge2.getDestination()); edge = transition.addEdge(prob, dest); // Reset set is union of reset sets for (Map.Entry<Integer, Integer> e : edge1.getResets()) { edge.addReset(PTA.renameClock(pta1, par, e.getKey()), e.getValue()); } for (Map.Entry<Integer, Integer> e : edge2.getResets()) { edge.addReset(PTA.renameClock(pta2, par, e.getKey()), e.getValue()); } } } } } } } return par; }
/** 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; }