7 changed files with 494 additions and 266 deletions
-
241prism/src/explicit/AccumulationProduct.java
-
270prism/src/explicit/AccumulationProductComplex.java
-
18prism/src/explicit/AccumulationProductComplexCounting.java
-
18prism/src/explicit/AccumulationProductComplexRegular.java
-
89prism/src/explicit/AccumulationTransformation.java
-
115prism/src/parser/visitor/ReplaceAccumulationExpression.java
-
9prism/src/prism/PrismSettings.java
@ -0,0 +1,270 @@ |
|||
package explicit; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.BitSet; |
|||
import java.util.Iterator; |
|||
import java.util.Map; |
|||
import java.util.Vector; |
|||
|
|||
import parser.ast.ExpressionAccumulation; |
|||
import parser.ast.Expression; |
|||
import prism.PrismException; |
|||
|
|||
import common.Dottable; |
|||
import explicit.rewards.MCRewards; |
|||
import explicit.rewards.Rewards; |
|||
|
|||
/** |
|||
* An AccumulationProduct has ProductStates, where the first component is the |
|||
* stateId in the original model, and the second component is the index of an |
|||
* AccumulationTracker. |
|||
* |
|||
* @author Sascha Wunderlich |
|||
* |
|||
* @param <M> |
|||
*/ |
|||
|
|||
public abstract class AccumulationProductComplex<M extends Model,Component> extends AccumulationProduct<M,Component> implements Dottable |
|||
{ |
|||
protected final ArrayList<BitSet> initStates; |
|||
protected final ArrayList<BitSet> runStates; |
|||
protected final ArrayList<BitSet> goalStates; |
|||
|
|||
public AccumulationProductComplex(M originalModel) { |
|||
super(originalModel); |
|||
initStates = new ArrayList<>(); |
|||
runStates = new ArrayList<>(); |
|||
goalStates = new ArrayList<>(); |
|||
} |
|||
|
|||
public final BitSet getInitStates(int track) { |
|||
return initStates.get(track); |
|||
} |
|||
|
|||
public final BitSet getRunStates(int track) { |
|||
return runStates.get(track); |
|||
} |
|||
|
|||
public final BitSet getGoalStates(int track) { |
|||
return goalStates.get(track); |
|||
} |
|||
|
|||
protected void generateTrackInfo(ProductState state, Integer index, ExpressionAccumulation accexp, ProbModelChecker mc) throws PrismException { |
|||
AccumulationState<Component> accState = accStates.getById(state.getSecondState()); |
|||
AccumulationTracker<Component> tracker = accState.getTracker(trackers); |
|||
|
|||
for(int trackIdx=0; trackIdx<tracker.getTracks().size(); trackIdx++) { |
|||
AccumulationTrack<Component> track = tracker.getTracks().get(trackIdx); |
|||
|
|||
// Is this an initial |
|||
if (trackIdx==accState.lastRestartNr) { |
|||
initStates.get(trackIdx).set(index); |
|||
} |
|||
|
|||
// Is this a running track? |
|||
if (track != null) { |
|||
runStates.get(trackIdx).set(index); |
|||
} |
|||
|
|||
// Is this a goal track? |
|||
if (isGoalTrack(track, accexp, mc)) { |
|||
goalStates.get(trackIdx).set(index); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** Checks whether a track is final according to the bound in the accumulation expression and the context in mc. |
|||
* @param track |
|||
* @param accexp |
|||
* @param mc |
|||
* @return |
|||
* @throws PrismException |
|||
*/ |
|||
protected abstract boolean isFinalTrack(final AccumulationTrack<Component> track, final ExpressionAccumulation accexp, final ProbModelChecker mc) |
|||
throws PrismException; |
|||
|
|||
/** Get the initial Component of the accumulation monitor. |
|||
* @return |
|||
*/ |
|||
protected abstract Component getInitialComponent(); |
|||
|
|||
/** Update the Component of the accumulation monitor when leaving modelFromStateId. |
|||
* @param modelFromStateId |
|||
* @param track |
|||
* @param accexp |
|||
* @param mc |
|||
* @return |
|||
*/ |
|||
protected abstract Component updateComponent(Integer modelFromStateId, final AccumulationTrack<Component> track, |
|||
final ExpressionAccumulation accexp, final StateModelChecker mc); |
|||
|
|||
/** Updates a single AccumulationTrack. Used in updateAccumulationState. |
|||
* |
|||
* Uses updateComponent to get the next Component, accumulates the current weights |
|||
* and makes a new track. |
|||
* @param modelFromStateId |
|||
* @param track |
|||
* @param accexp |
|||
* @param weights |
|||
* @param mc |
|||
* @return |
|||
*/ |
|||
protected final AccumulationTrack<Component> updateTrack(Integer modelFromStateId, final AccumulationTrack<Component> track, |
|||
final ExpressionAccumulation accexp, final double[] weights, final StateModelChecker mc) { |
|||
Component nextComponent = updateComponent(modelFromStateId, track, accexp, mc); |
|||
|
|||
// If we are done, return null-Track |
|||
if (nextComponent == null) { return null; } |
|||
|
|||
// Otherwise, we update the weights and increase the step. |
|||
double[] newweights = new double[weights.length]; |
|||
for (int i = 0; i < weights.length; i++) { |
|||
newweights[i] = weights[i] + track.getWeights()[i]; |
|||
} |
|||
|
|||
return new AccumulationTrack<Component>(newweights, nextComponent); |
|||
} |
|||
|
|||
/** Generates a new accumulation state from an old one. |
|||
* |
|||
* To do so, it reads the necessary information from the model and its rewards |
|||
* and updates all tracks and their goodness accordingly. |
|||
* @param modelFromStateId |
|||
* @param accstate |
|||
* @param accexp |
|||
* @param weights |
|||
* @param mc |
|||
* @return |
|||
* @throws PrismException |
|||
*/ |
|||
protected final AccumulationState<Component> updateAccumulationState(final int modelFromStateId, |
|||
final AccumulationState<Component> accstate, final ExpressionAccumulation accexp, |
|||
final double[] weights, final ProbModelChecker mc) throws PrismException { |
|||
|
|||
// Check if we even need to fire here. |
|||
if(accexp.hasFireOn()) { |
|||
boolean stutter = true; |
|||
for(Expression f : accexp.getFireOn()) { |
|||
if(mc.checkExpression(originalModel, f, null).getBitSet().get(modelFromStateId)) { |
|||
//mc.getLog().println("f:" + f); |
|||
stutter = false; |
|||
break; |
|||
} |
|||
} |
|||
// If this is a stutter action, we can return the same accstate. Copies are made on modification. |
|||
if(stutter) { return accstate; } |
|||
} |
|||
// ...otherwise proceed. |
|||
|
|||
// Get the old tracker and tracks. |
|||
AccumulationTracker<Component> oldTracker = accstate.getTracker(trackers); |
|||
ArrayList<AccumulationTrack<Component>> oldTracks = oldTracker.getTracks(); |
|||
|
|||
// This restart will be... |
|||
int newLastRestartNr = accstate.getNextRestartNr(); |
|||
//mc.getLog().print(newLastRestartNr); |
|||
|
|||
// Build the new tracks and determine their goodness; |
|||
ArrayList<AccumulationTrack<Component>> newTracks = new ArrayList<>(); |
|||
|
|||
int trackNr = 0; |
|||
for(AccumulationTrack<Component> oldTrack : oldTracks) { |
|||
|
|||
AccumulationTrack<Component> newTrack; |
|||
|
|||
// restart or advance |
|||
if(trackNr == newLastRestartNr) { |
|||
// If we have a restart, we produce an initial track and let it advance. |
|||
AccumulationTrack<Component> freshTrack = new AccumulationTrack<Component>(numberOfWeights, getInitialComponent()); |
|||
//newTrack = updateTrack(modelFromStateId, freshTrack, accexp, weights, mc); |
|||
newTrack = freshTrack; |
|||
} else if (oldTrack == null) { |
|||
// If the old track is undefined, the new track is as well. |
|||
newTrack = null; |
|||
} else { |
|||
// Otherwise, the track is defined and advances. |
|||
assert oldTrack != null; |
|||
newTrack = updateTrack(modelFromStateId, oldTrack, accexp, weights, mc); |
|||
} |
|||
|
|||
newTracks.add(newTrack); |
|||
trackNr++; |
|||
} |
|||
|
|||
//Create a new tracker with the right tracks and add it to storage. |
|||
AccumulationTracker<Component> newTracker = new AccumulationTracker<>(newTracks); |
|||
int newTrackerId = trackers.findOrAdd(newTracker); |
|||
|
|||
return new AccumulationState<>(newTrackerId, newLastRestartNr, numberOfTracks); |
|||
} |
|||
|
|||
protected String labelString(Integer stateId) { |
|||
StringBuffer result = new StringBuffer(); |
|||
|
|||
for(int t=0; t<numberOfTracks; t++) { |
|||
result.append(" " + t); |
|||
if(initStates.get(t).get(stateId)) { result.append("I"); continue; } |
|||
if(goalStates.get(t).get(stateId)) { result.append("G"); continue; } |
|||
if(runStates.get(t).get(stateId)) { result.append("R"); continue; } |
|||
result.append("_"); |
|||
} |
|||
|
|||
return result.toString(); |
|||
} |
|||
|
|||
@Override |
|||
public String toDot() { |
|||
StringBuffer result = new StringBuffer(); |
|||
|
|||
result.append("digraph " + originalModel.getModelType() + " {\n"); |
|||
|
|||
for(int i = 0; i < prod_states.size(); i++) { |
|||
ProductState fromState = prod_states.get(i); |
|||
AccumulationState<Component> accState = accStates.getById(fromState.getSecondState()); |
|||
AccumulationTracker<Component> tracker = accState.getTracker(trackers); |
|||
result.append("" |
|||
+ i |
|||
+ "[shape=box, color=black" |
|||
+ " label= < <TABLE BORDER=\"0\">" |
|||
+ "<TR>" |
|||
+ "<TD>" + i + "=" + fromState + "</TD>" |
|||
+ "</TR><TR>" |
|||
+ "<TD> " + accState + "</TD>" |
|||
+ "</TR><TR>" |
|||
+ "<TD> " + labelString(i) + "</TD>" |
|||
+ "</TR><TR>" |
|||
+ "<TD>\"" + Dottable.quoteForDot(tracker.toString()) + "\"</TD>" |
|||
+ "</TR>" |
|||
+ " </TABLE> >]\n"); |
|||
|
|||
switch(productModel.getModelType()) { |
|||
case DTMC: |
|||
DTMCExplicit castDTMC = (DTMCExplicit)productModel; |
|||
Iterator<Map.Entry<Integer, Double>> dtmcIter = castDTMC.getTransitionsIterator(i); |
|||
while (dtmcIter.hasNext()) { |
|||
Map.Entry<Integer, Double> e = dtmcIter.next(); |
|||
result.append(i + " -> " + e.getKey() + " [ label=\""); |
|||
result.append(e.getValue() + "\" ];\n"); |
|||
} |
|||
break; |
|||
case MDP: |
|||
MDPExplicit castMDP = (MDPExplicit)productModel; |
|||
for(int c = 0; c < castMDP.getNumChoices(i); c++) { |
|||
Iterator<Map.Entry<Integer, Double>> mdpIter = castMDP.getTransitionsIterator(i, c); |
|||
while (mdpIter.hasNext()) { |
|||
Map.Entry<Integer, Double> e = mdpIter.next(); |
|||
result.append(i + " -> " + e.getKey() + " [ label=\""); |
|||
result.append(c + "," + e.getValue() + "\" ];\n"); |
|||
} |
|||
} |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
result.append("}"); |
|||
|
|||
return result.toString(); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue