9 changed files with 155 additions and 789 deletions
-
4prism/src/explicit/AccumulationContext.java
-
71prism/src/explicit/AccumulationProduct.java
-
139prism/src/explicit/AccumulationProductComplex.java
-
28prism/src/explicit/AccumulationProductCounting.java
-
28prism/src/explicit/AccumulationProductRegular.java
-
107prism/src/explicit/AccumulationProductSimple.java
-
195prism/src/explicit/AccumulationProductSimpleCounting.java
-
228prism/src/explicit/AccumulationProductSimpleRegular.java
-
144prism/src/explicit/AccumulationTransformation.java
@ -1,139 +0,0 @@ |
|||
package explicit; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.BitSet; |
|||
import java.util.Iterator; |
|||
import java.util.Map; |
|||
|
|||
import prism.PrismException; |
|||
|
|||
import common.Dottable; |
|||
|
|||
/** |
|||
* 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, AccumulationContext ctx) { |
|||
super(originalModel, ctx); |
|||
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) 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); |
|||
|
|||
boolean isInitial = trackIdx==accState.lastRestartNr; |
|||
boolean isRunning = track != null; |
|||
boolean isGoal = accState.getGoodTracks().get(trackIdx); // isGoalTrack(track) |
|||
|
|||
// Is this an initial |
|||
initStates.get(trackIdx).set(index, isInitial); |
|||
|
|||
// Is this a running track? (Initial tracks are NOT running) |
|||
runStates.get(trackIdx).set(index, isRunning && !isInitial); |
|||
|
|||
// Is this a goal track? |
|||
goalStates.get(trackIdx).set(index, isGoal); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
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(); |
|||
} |
|||
} |
|||
@ -1,107 +0,0 @@ |
|||
package explicit; |
|||
|
|||
import java.util.BitSet; |
|||
import java.util.Iterator; |
|||
import java.util.Map; |
|||
|
|||
import prism.PrismException; |
|||
|
|||
import common.Dottable; |
|||
|
|||
/** |
|||
* 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 AccumulationProductSimple<M extends Model,Component> extends AccumulationProduct<M,Component> implements Dottable |
|||
{ |
|||
protected final BitSet goodStates; |
|||
|
|||
public AccumulationProductSimple(M originalModel, AccumulationContext ctx) { |
|||
super(originalModel, ctx); |
|||
goodStates = new BitSet(); |
|||
} |
|||
|
|||
public final BitSet getGoodStates() { |
|||
return goodStates; |
|||
} |
|||
|
|||
protected void generateStateInfo(ProductState state, Integer index) throws PrismException { |
|||
AccumulationState<Component> accState = accStates.getById(state.getSecondState()); |
|||
goodStates.set(index, accState.hasGoodTracks()); |
|||
} |
|||
|
|||
protected String labelString(Integer stateId) { |
|||
StringBuffer result = new StringBuffer(); |
|||
if(goodStates.get(stateId)) { result.append("G: "); } |
|||
|
|||
for(int t=0; t<numberOfTracks; t++) { |
|||
result.append(" " + t); |
|||
if(accStates.getById(prod_states.get(stateId).getSecondState()).getGoodTracks().get(t)) { result.append("+"); 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(); |
|||
} |
|||
} |
|||
@ -1,195 +0,0 @@ |
|||
package explicit; |
|||
|
|||
import java.util.BitSet; |
|||
|
|||
import explicit.rewards.Rewards; |
|||
import prism.IntegerBound; |
|||
import prism.PrismException; |
|||
|
|||
/** |
|||
* 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 class AccumulationProductSimpleCounting<M extends Model> extends AccumulationProductSimple<M,Integer> |
|||
{ |
|||
|
|||
public AccumulationProductSimpleCounting(M originalModel, AccumulationContext ctx) { |
|||
super(originalModel, ctx); |
|||
} |
|||
|
|||
@SuppressWarnings("unchecked") |
|||
public static <T extends Model, R extends Rewards> AccumulationProductSimpleCounting<T> generate(final Model graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
switch(graph.getModelType()) { |
|||
case DTMC: |
|||
return (AccumulationProductSimpleCounting<T>)generate((DTMC) graph, ctx, statesOfInterest); |
|||
case MDP: |
|||
return (AccumulationProductSimpleCounting<T>)generate((MDP) graph, ctx, statesOfInterest); |
|||
default: |
|||
throw new PrismException("Can't handle accumulation product for " + graph.getModelType()); |
|||
} |
|||
} |
|||
|
|||
public static AccumulationProductSimpleCounting<DTMC> generate(final DTMC graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
final AccumulationProductSimpleCounting<DTMC> result = new AccumulationProductSimpleCounting<DTMC>(graph,ctx); |
|||
// Create auxiliary data |
|||
result.createAuxData(graph); |
|||
|
|||
// Build an operator |
|||
class AccumulationDTMCProductOperator implements DTMCProductOperator |
|||
{ |
|||
@Override |
|||
public ProductState getInitialState(Integer dtmc_state) |
|||
throws PrismException { |
|||
int initialAccStateId = result.createInitialStateId(); |
|||
return new ProductState(dtmc_state, initialAccStateId); |
|||
} |
|||
|
|||
@Override |
|||
public ProductState getSuccessor(ProductState from_state, Integer dtmc_to_state) throws PrismException { |
|||
// Get the current accumulation state |
|||
AccumulationState<Integer> from_accstate = result.accStates.getById(from_state.getSecondState()); |
|||
|
|||
// Get step weights |
|||
double[] weights = ctx.getWeights(from_state.getFirstState()); |
|||
|
|||
// Update accumulation product state, store it and get its ID. |
|||
AccumulationState<Integer> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, weights); |
|||
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct); |
|||
|
|||
return new ProductState(dtmc_to_state, to_accproduct_id); |
|||
} |
|||
|
|||
@Override |
|||
public void notify(ProductState state, Integer index) |
|||
throws PrismException { |
|||
result.generateStateInfo(state, index); |
|||
} |
|||
|
|||
@Override |
|||
public void finish() throws PrismException { |
|||
// Do nothing |
|||
} |
|||
|
|||
@Override |
|||
public DTMC getGraph() { |
|||
return graph; |
|||
} |
|||
} |
|||
|
|||
// Apply the operator |
|||
AccumulationDTMCProductOperator op = new AccumulationDTMCProductOperator(); |
|||
ProductWithProductStates.generate(op, result, statesOfInterest); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public static AccumulationProductSimpleCounting<MDP> generate(final MDP graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
// This is basically the same thing as for DTMCs |
|||
final AccumulationProductSimpleCounting<MDP> result = new AccumulationProductSimpleCounting<MDP>(graph, ctx); |
|||
|
|||
// Create auxiliary data |
|||
result.createAuxData(graph); |
|||
|
|||
class AccumulationMDPProductOperator implements MDPProductOperator |
|||
{ |
|||
|
|||
@Override |
|||
public ProductState getInitialState(final Integer MDP_state) |
|||
throws PrismException { |
|||
int initialAccStateId = result.createInitialStateId(); |
|||
return new ProductState(MDP_state, initialAccStateId); |
|||
} |
|||
|
|||
@Override |
|||
public ProductState getSuccessor(final ProductState from_state, final int choice_i, final Integer mdp_to_state) throws PrismException { |
|||
// Get the current accumulation state |
|||
AccumulationState<Integer> from_accstate = result.accStates.getById(from_state.getSecondState()); |
|||
|
|||
// Get step weights |
|||
// THIS IS DIFFERENT FROM ABOVE! |
|||
double[] weights = ctx.getWeights(from_state.getFirstState(), choice_i); |
|||
|
|||
// Update accumulation product state, store it and get its ID. |
|||
AccumulationState<Integer> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, weights); |
|||
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct); |
|||
return new ProductState(mdp_to_state, to_accproduct_id); |
|||
} |
|||
|
|||
@Override |
|||
public void notify(final ProductState state, final Integer index) |
|||
throws PrismException { |
|||
result.generateStateInfo(state, index); |
|||
} |
|||
|
|||
@Override |
|||
public void finish() throws PrismException { |
|||
// Do nothing |
|||
//mc.getLog().println("."); |
|||
} |
|||
|
|||
@Override |
|||
public MDP getGraph() { |
|||
return graph; |
|||
} |
|||
} |
|||
|
|||
AccumulationMDPProductOperator op = new AccumulationMDPProductOperator(); |
|||
ProductWithProductStates.generate(op, result, statesOfInterest); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
protected boolean isFinalTrack(final AccumulationTrack<Integer> track) throws PrismException { |
|||
boolean isFinal = false; |
|||
if ( track != null ) { |
|||
Integer step = track.getComponent(); |
|||
if ( step > 0 ) { // if the step is 0, we cannot have a goal state. |
|||
IntegerBound stepBound = IntegerBound.fromTemporalOperatorBound(ctx.accexp.getBoundExpression(), ctx.mc.getConstantValues(), true); |
|||
isFinal = stepBound.isInBounds(step); |
|||
} |
|||
} |
|||
return isFinal; |
|||
} |
|||
|
|||
@Override |
|||
protected Integer getInitialComponent() { |
|||
return 0; |
|||
} |
|||
|
|||
@Override |
|||
protected Integer updateComponent(Integer modelFromStateId, final AccumulationTrack<Integer> track) { |
|||
int currentStep = track.getComponent(); |
|||
|
|||
int maxStep = 0; |
|||
try { |
|||
maxStep = IntegerBound.fromTemporalOperatorBound(ctx.accexp.getBoundExpression(), ctx.mc.getConstantValues(), true).getHighestInteger(); |
|||
} catch(PrismException e) { |
|||
throw new RuntimeException("..."); |
|||
} |
|||
|
|||
int nextStep = currentStep+1; |
|||
if(nextStep > maxStep) { return null; } |
|||
return nextStep; |
|||
} |
|||
|
|||
/** |
|||
* Populates fields: |
|||
* - numberOfTracks with the highest relevant integer plus one, and |
|||
* - numberOfWeights with the size of the reward vector. |
|||
* @param graph |
|||
* @param accexp |
|||
* @param rewards |
|||
* @param mc |
|||
* @throws PrismException |
|||
*/ |
|||
protected void createAuxData(final Model graph) throws PrismException { |
|||
numberOfTracks = IntegerBound.fromTemporalOperatorBound(ctx.accexp.getBoundExpression(), ctx.mc.getConstantValues(), true).getHighestInteger()+1; |
|||
numberOfWeights = ctx.rewards.size(); |
|||
} |
|||
} |
|||
@ -1,228 +0,0 @@ |
|||
package explicit; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.BitSet; |
|||
|
|||
import automata.finite.DeterministicFiniteAutomaton; |
|||
import automata.finite.EdgeLabel; |
|||
import automata.finite.NondeterministicFiniteAutomaton; |
|||
import automata.finite.State; |
|||
import explicit.rewards.Rewards; |
|||
import parser.ast.ExpressionRegular; |
|||
import prism.PrismException; |
|||
import prism.PrismSettings; |
|||
|
|||
/** |
|||
* 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 class AccumulationProductSimpleRegular<M extends Model> extends AccumulationProductSimple<M,State> |
|||
{ |
|||
protected DeterministicFiniteAutomaton<String> automaton; |
|||
|
|||
public AccumulationProductSimpleRegular(M originalModel, AccumulationContext ctx) { |
|||
super(originalModel, ctx); |
|||
} |
|||
|
|||
@SuppressWarnings("unchecked") |
|||
public static <T extends Model, R extends Rewards> AccumulationProductSimpleRegular<T> generate(final Model graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
switch(graph.getModelType()) { |
|||
case DTMC: |
|||
return (AccumulationProductSimpleRegular<T>)generate((DTMC) graph, ctx, statesOfInterest); |
|||
case MDP: |
|||
return (AccumulationProductSimpleRegular<T>)generate((MDP) graph, ctx, statesOfInterest); |
|||
default: |
|||
throw new PrismException("Can't handle accumulation product for " + graph.getModelType()); |
|||
} |
|||
} |
|||
|
|||
public static AccumulationProductSimpleRegular<DTMC> generate(final DTMC graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
final AccumulationProductSimpleRegular<DTMC> result = new AccumulationProductSimpleRegular<DTMC>(graph, ctx); |
|||
// Create auxiliary data |
|||
result.createAuxData(graph); |
|||
|
|||
// Build an operator |
|||
class AccumulationDTMCProductOperator implements DTMCProductOperator |
|||
{ |
|||
@Override |
|||
public ProductState getInitialState(Integer dtmc_state) |
|||
throws PrismException { |
|||
int initialAccStateId = result.createInitialStateId(); |
|||
return new ProductState(dtmc_state, initialAccStateId); |
|||
} |
|||
|
|||
@Override |
|||
public ProductState getSuccessor(ProductState from_state, |
|||
Integer dtmc_to_state) throws PrismException { |
|||
// Get the current accumulation state |
|||
AccumulationState<State> from_accstate = result.accStates.getById(from_state.getSecondState()); |
|||
|
|||
// Get step weights |
|||
double[] weights = ctx.getWeights(from_state.getFirstState()); |
|||
|
|||
// Update accumulation product state, store it and get its ID. |
|||
AccumulationState<State> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, weights); |
|||
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct); |
|||
|
|||
return new ProductState(dtmc_to_state, to_accproduct_id); |
|||
} |
|||
|
|||
@Override |
|||
public void notify(ProductState state, Integer index) |
|||
throws PrismException { |
|||
result.generateStateInfo(state, index); |
|||
} |
|||
|
|||
@Override |
|||
public void finish() throws PrismException { |
|||
// Do nothing |
|||
} |
|||
|
|||
@Override |
|||
public DTMC getGraph() { |
|||
return graph; |
|||
} |
|||
} |
|||
|
|||
// Apply the operator |
|||
AccumulationDTMCProductOperator op = new AccumulationDTMCProductOperator(); |
|||
ProductWithProductStates.generate(op, result, statesOfInterest); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public static AccumulationProductSimpleRegular<MDP> generate(final MDP graph, AccumulationContext ctx, BitSet statesOfInterest) throws PrismException { |
|||
// This is basically the same thing as for DTMCs |
|||
final AccumulationProductSimpleRegular<MDP> result = new AccumulationProductSimpleRegular<MDP>(graph, ctx); |
|||
|
|||
// Create auxiliary data |
|||
result.createAuxData(graph); |
|||
|
|||
class AccumulationMDPProductOperator implements MDPProductOperator |
|||
{ |
|||
|
|||
@Override |
|||
public ProductState getInitialState(final Integer MDP_state) |
|||
throws PrismException { |
|||
int initialAccStateId = result.createInitialStateId(); |
|||
return new ProductState(MDP_state, initialAccStateId); |
|||
} |
|||
|
|||
@Override |
|||
public ProductState getSuccessor(final ProductState from_state, |
|||
final int choice_i, final Integer mdp_to_state) throws PrismException { |
|||
// Get the current accumulation state |
|||
AccumulationState<State> from_accstate = result.accStates.getById(from_state.getSecondState()); |
|||
|
|||
// Get step weights |
|||
double[] weights = ctx.getWeights(from_state.getFirstState(), choice_i); |
|||
|
|||
// Update accumulation product state, store it and get its ID. |
|||
AccumulationState<State> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, weights); |
|||
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct); |
|||
return new ProductState(mdp_to_state, to_accproduct_id); |
|||
} |
|||
|
|||
@Override |
|||
public void notify(final ProductState state, final Integer index) |
|||
throws PrismException { |
|||
result.generateStateInfo(state, index); |
|||
} |
|||
|
|||
@Override |
|||
public void finish() throws PrismException { |
|||
// Do nothing |
|||
//mc.getLog().println("."); |
|||
} |
|||
|
|||
@Override |
|||
public MDP getGraph() { |
|||
return graph; |
|||
} |
|||
} |
|||
|
|||
AccumulationMDPProductOperator op = new AccumulationMDPProductOperator(); |
|||
ProductWithProductStates.generate(op, result, statesOfInterest); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
protected boolean isFinalTrack(AccumulationTrack<State> track) throws PrismException { |
|||
boolean isFinal = false; |
|||
if ( track != null ) { |
|||
isFinal = automaton.isAcceptingState(track.getComponent()); |
|||
} |
|||
|
|||
return isFinal; |
|||
} |
|||
|
|||
@Override |
|||
protected State getInitialComponent() { |
|||
return automaton.getInitialState(); |
|||
} |
|||
|
|||
@Override |
|||
protected State updateComponent(Integer modelFromStateId, final AccumulationTrack<State> track) { |
|||
State currentState = track.getComponent(); |
|||
|
|||
// Build EdgeLabel from labels. |
|||
// labels is a BitSet with labels L0,...,Ln |
|||
ArrayList<String> edgeSymbols = new ArrayList<>(); |
|||
BitSet edgeValues = new BitSet(); |
|||
|
|||
for (int i=0; i < labels.size(); i++) { |
|||
// Each bitLabel contains one L |
|||
edgeSymbols.add(i, "L"+i); |
|||
if(labels.get(i).get(modelFromStateId)) { |
|||
edgeValues.set(i); |
|||
} |
|||
} |
|||
|
|||
EdgeLabel<String> edgeLabel = new EdgeLabel<>(edgeSymbols, edgeValues); |
|||
|
|||
State nextState = automaton.getSuccessor(currentState,edgeLabel); |
|||
if(nextState == null) { return null; } |
|||
return nextState; |
|||
} |
|||
|
|||
/** |
|||
* Populates fields: |
|||
* - numberOfTracks with the highest relevant integer plus one, and |
|||
* - numberOfWeights with the size of the reward vector. |
|||
* @param graph |
|||
* @param accexp |
|||
* @param rewards |
|||
* @param mc |
|||
* @throws PrismException |
|||
*/ |
|||
protected void createAuxData(final Model graph) throws PrismException { |
|||
// Build labels and DFA |
|||
AccumulationModelChecker accMc = new AccumulationModelChecker(); |
|||
ExpressionRegular reg = (ExpressionRegular)accMc.checkMaximalStateFormulas((ProbModelChecker) ctx.mc, graph, ctx.accexp.getRegularExpression(), labels); |
|||
|
|||
// Create and store the actual DFA |
|||
NondeterministicFiniteAutomaton<String> nfa = NondeterministicFiniteAutomaton.fromExpressionRegular(reg); |
|||
//System.out.println(nfa.toDot()); |
|||
|
|||
automaton = nfa.determinize(); |
|||
automaton.trim(); // This should remove cycles. |
|||
|
|||
if(ctx.mc.getSettings().getBoolean(PrismSettings.ACC_GENERATE_DOTS)) { |
|||
nfa.exportToDotFile("DEBUG-automaton-nfa.dot"); |
|||
automaton.exportToDotFile("DEBUG-automaton-dfa.dot"); |
|||
} |
|||
|
|||
if (!automaton.isAcyclic()) { |
|||
throw new PrismException("Cannot handle cyclic automata!"); |
|||
} |
|||
|
|||
numberOfTracks = automaton.getLongestPathLength()+1; |
|||
numberOfWeights= ctx.rewards.size(); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue