Browse Source

accumulation: some fixes

- length of longest path vs number of tracks
- typed accumulation states
accumulation
Sascha Wunderlich 10 years ago
committed by Sascha Wunderlich
parent
commit
6740da5171
  1. 8
      prism/src/explicit/AccumulationProduct.java
  2. 36
      prism/src/explicit/AccumulationProductCounting.java
  3. 56
      prism/src/explicit/AccumulationProductRegular.java
  4. 23
      prism/src/explicit/AccumulationState.java
  5. 1
      prism/src/explicit/AccumulationTrack.java
  6. 4
      prism/src/explicit/AccumulationTransformation.java

8
prism/src/explicit/AccumulationProduct.java

@ -22,7 +22,7 @@ import prism.PrismLog;
public abstract class AccumulationProduct<M extends Model,Component> extends ProductWithProductStates<M>
{
final StoragePool<AccumulationTracker<Component>> trackers;
final StoragePool<AccumulationState> accStates;
final StoragePool<AccumulationState<Component>> accStates;
final BitSet goodStates;
@ -73,8 +73,8 @@ public abstract class AccumulationProduct<M extends Model,Component> extends Pro
for(int i = 0; i < prod_states.size(); i++) {
ProductState fromState = prod_states.get(i);
AccumulationState accState = accStates.getById(fromState.getSecondState());
AccumulationTracker<Component> tracker = trackers.getById(accState.getTrackerId());
AccumulationState<Component> accState = accStates.getById(fromState.getSecondState());
AccumulationTracker<Component> tracker = accState.getTracker(trackers);
result.append(""
+ i
+ "[shape=box, color=black"
@ -82,7 +82,7 @@ public abstract class AccumulationProduct<M extends Model,Component> extends Pro
+ "<TR>"
+ "<TD>" + i + "=" + fromState + "</TD>"
+ "</TR><TR>"
+ "<TD>" + accState + "</TD>"
+ "<TD>" + accState + "</TD>"
+ "</TR><TR>"
+ "<TD>\"" + quoteForDot(tracker.toString()) + "\"</TD>"
+ "</TR>"

36
prism/src/explicit/AccumulationProductCounting.java

@ -48,7 +48,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
public ProductState getSuccessor(ProductState from_state,
Integer dtmc_to_state) throws PrismException {
// Get the current accumulation state
AccumulationState from_accstate = result.accStates.getById(from_state.getSecondState());
AccumulationState<Integer> from_accstate = result.accStates.getById(from_state.getSecondState());
// Get step weights
double[] weights = new double[rewards.size()];
@ -58,7 +58,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
}
// Update accumulation product state, store it and get its ID.
AccumulationState to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
AccumulationState<Integer> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct);
return new ProductState(dtmc_to_state, to_accproduct_id);
@ -67,7 +67,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
@Override
public void notify(ProductState state, Integer index)
throws PrismException {
AccumulationState accState = result.accStates.getById(state.getSecondState());
AccumulationState<Integer> accState = result.accStates.getById(state.getSecondState());
if (result.isGoodAccState(accState, accexp, mc)) {
result.goodStates.set(index);
}
@ -112,7 +112,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
public ProductState getSuccessor(final ProductState from_state,
final int choice_i, final Integer mdp_to_state) throws PrismException {
// Get the current accumulation state
AccumulationState from_accstate = result.accStates.getById(from_state.getSecondState());
AccumulationState<Integer> from_accstate = result.accStates.getById(from_state.getSecondState());
// Get step weights
// THIS IS DIFFERENT FROM ABOVE!
@ -125,7 +125,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
}
// Update accumulation product state, store it and get its ID.
AccumulationState to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
AccumulationState<Integer> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct);
return new ProductState(mdp_to_state, to_accproduct_id);
}
@ -133,7 +133,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
@Override
public void notify(final ProductState state, final Integer index)
throws PrismException {
AccumulationState accState = result.accStates.getById(state.getSecondState());
AccumulationState<Integer> accState = result.accStates.getById(state.getSecondState());
if (result.isGoodAccState(accState, accexp, mc)) {
result.goodStates.set(index);
}
@ -166,7 +166,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
return isFinal;
}
private boolean isGoodAccState(final AccumulationState state, final ExpressionAccumulation accexp, final ProbModelChecker mc)
private boolean isGoodAccState(final AccumulationState<Integer> state, final ExpressionAccumulation accexp, final ProbModelChecker mc)
throws PrismException {
return state.hasGoodTrack();
}
@ -210,13 +210,13 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
return isGood;
}
private AccumulationState updateAccumulationState(final int modelFromStateId,
final AccumulationState accstate, final ExpressionAccumulation accexp,
private AccumulationState<Integer> updateAccumulationState(final int modelFromStateId,
final AccumulationState<Integer> accstate, final ExpressionAccumulation accexp,
final double[] weights, final ProbModelChecker mc) throws PrismException {
// We have the current accumulation state, the current model id and the accumulation expression.
// Get the old tracker and tracks.
AccumulationTracker<Integer> oldTracker = trackers.getById(accstate.getTrackerId());
AccumulationTracker<Integer> oldTracker = accstate.getTracker(trackers);
ArrayList<AccumulationTrack<Integer>> oldTracks = oldTracker.getTracks();
BitSet oldGoodTracks = accstate.getGoodTracks();
@ -259,7 +259,7 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
int newTrackerId = trackers.findOrAdd(newTracker);
return new AccumulationState(newTrackerId, newLastRestartNr, numberOfTracks, newGoodTracks);
return new AccumulationState<>(newTrackerId, newLastRestartNr, numberOfTracks, newGoodTracks);
}
private AccumulationTrack<Integer> updateTrackBounds(final AccumulationTrack<Integer> track,
@ -287,14 +287,22 @@ public class AccumulationProductCounting<M extends Model> extends AccumulationPr
// Generate the initial tracker and product state
AccumulationTracker<Integer> initialTracker = new AccumulationTracker<>(numberOfTracks, numberOfRewards, 0);
int initialTrackerId = trackers.findOrAdd(initialTracker);
AccumulationState initialAccState = new AccumulationState(initialTrackerId, initialActiveTrack, numberOfTracks, initialGoodTracks);
AccumulationState<Integer> initialAccState = new AccumulationState<>(initialTrackerId, initialActiveTrack, numberOfTracks, initialGoodTracks);
int initialAccStateId = accStates.findOrAdd(initialAccState);
return initialAccStateId;
}
protected void createAuxData(final Model graph, final ExpressionAccumulation accexp,
final Vector<? extends Rewards> rewards, final ProbModelChecker mc) throws PrismException {
/**
* Populates fields:
* - numberOfTracks
* @param graph
* @param accexp
* @param rewards
* @param mc
* @throws PrismException
*/
protected void createAuxData(final Model graph, final ExpressionAccumulation accexp, final Vector<? extends Rewards> rewards, final ProbModelChecker mc) throws PrismException {
numberOfTracks = IntegerBound.fromTemporalOperatorBound(accexp.getBoundExpression(), mc.getConstantValues(), true).getHighestInteger()+1;
numberOfWeights = rewards.size();
}

56
prism/src/explicit/AccumulationProductRegular.java

@ -10,6 +10,7 @@ import automata.finite.NondeterministicFiniteAutomaton;
import automata.finite.State;
import explicit.rewards.MCRewards;
import explicit.rewards.MDPRewards;
import explicit.rewards.Rewards;
import parser.ast.AccumulationFactor;
import parser.ast.ExpressionAccumulation;
import parser.ast.ExpressionRegular;
@ -37,7 +38,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
public static AccumulationProductRegular<DTMC> generate(final DTMC graph, final ExpressionAccumulation accexp, final Vector<MCRewards> rewards, final ProbModelChecker mc, BitSet statesOfInterest) throws PrismException {
final AccumulationProductRegular<DTMC> result = new AccumulationProductRegular<DTMC>(graph);
// Create auxiliary data
result.createAuxData(graph, accexp, mc);
result.createAuxData(graph, accexp, rewards, mc);
// Build an operator
class AccumulationDTMCProductOperator implements DTMCProductOperator
@ -53,7 +54,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
public ProductState getSuccessor(ProductState from_state,
Integer dtmc_to_state) throws PrismException {
// Get the current accumulation state
AccumulationState from_accstate = result.accStates.getById(from_state.getSecondState());
AccumulationState<State> from_accstate = result.accStates.getById(from_state.getSecondState());
// Get step weights
double[] weights = new double[rewards.size()];
@ -63,7 +64,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
}
// Update accumulation product state, store it and get its ID.
AccumulationState to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
AccumulationState<State> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct);
return new ProductState(dtmc_to_state, to_accproduct_id);
@ -72,7 +73,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
@Override
public void notify(ProductState state, Integer index)
throws PrismException {
AccumulationState accState = result.accStates.getById(state.getSecondState());
AccumulationState<State> accState = result.accStates.getById(state.getSecondState());
if (result.isGoodAccState(accState, accexp, mc)) {
result.goodStates.set(index);
}
@ -101,7 +102,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
final AccumulationProductRegular<MDP> result = new AccumulationProductRegular<MDP>(graph);
// Create auxiliary data
result.createAuxData(graph, accexp, mc);
result.createAuxData(graph, accexp, rewards, mc);
class AccumulationMDPProductOperator implements MDPProductOperator
{
@ -117,7 +118,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
public ProductState getSuccessor(ProductState from_state,
int choice_i, Integer mdp_to_state) throws PrismException {
// Get the current accumulation state
AccumulationState from_accstate = result.accStates.getById(from_state.getSecondState());
AccumulationState<State> from_accstate = result.accStates.getById(from_state.getSecondState());
// Get step weights
// THIS IS DIFFERENT FROM ABOVE!
@ -130,7 +131,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
}
// Update accumulation product state, store it and get its ID.
AccumulationState to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
AccumulationState<State> to_accproduct = result.updateAccumulationState(from_state.getFirstState(), from_accstate, accexp, weights, mc);
int to_accproduct_id = result.accStates.findOrAdd(to_accproduct);
return new ProductState(mdp_to_state, to_accproduct_id);
@ -139,7 +140,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
@Override
public void notify(ProductState state, Integer index)
throws PrismException {
AccumulationState accState = result.accStates.getById(state.getSecondState());
AccumulationState<State> accState = result.accStates.getById(state.getSecondState());
if (result.isGoodAccState(accState, accexp, mc)) {
result.goodStates.set(index);
}
@ -171,14 +172,14 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
return isFinal;
}
private boolean isGoodAccState(AccumulationState state, ExpressionAccumulation accexp, ProbModelChecker mc) throws PrismException {
//TODO: fill me!
return false;
private boolean isGoodAccState(AccumulationState<State> state, ExpressionAccumulation accexp, ProbModelChecker mc) throws PrismException {
return state.hasGoodTrack();
}
private boolean isGoodTrack(AccumulationTrack<State> track, ExpressionAccumulation accexp, ProbModelChecker mc) throws PrismException {
//System.out.println("Checking " + track + " for goodness...");
mc.getLog().println("Checking " + track + " for goodness...");
// Only final tracks can be good
mc.getLog().println("Final? " + isFinalTrack(track,accexp,mc));
if (!isFinalTrack(track,accexp,mc)) { return false; }
boolean isGood = false;
@ -214,13 +215,13 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
throw new RuntimeException("Oh boy!");
}
//System.out.println("Good? " + isGood);
mc.getLog().println("Good? " + lhs + rhs + " : " + isGood);
return isGood;
}
private AccumulationState updateAccumulationState(final int modelFromStateId,
final AccumulationState accstate, final ExpressionAccumulation accexp,
private AccumulationState<State> updateAccumulationState(final int modelFromStateId,
final AccumulationState<State> accstate, final ExpressionAccumulation accexp,
final double[] weights, final ProbModelChecker mc) throws PrismException {
// We have the current accumulation state, the current model id and the accumulation expression.
@ -268,7 +269,7 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
int newTrackerId = trackers.findOrAdd(newTracker);
return new AccumulationState(newTrackerId, newLastRestartNr, numberOfTracks, newGoodTracks);
return new AccumulationState<State>(newTrackerId, newLastRestartNr, numberOfTracks, newGoodTracks);
}
private AccumulationTrack<State> updateTrackRegular(Integer modelFromStateId, AccumulationTrack<State> track, ExpressionAccumulation accexp, double[] weights, StateModelChecker mc) {
State currentState = track.getComponent();
@ -313,15 +314,25 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
BitSet initialGoodTracks = new BitSet();
// Generate the initial track and product state
AccumulationTracker<State> initialTracker = new AccumulationTracker<>(numberOfTracks, numberOfRewards, initialState);
AccumulationTracker<State> initialTracker = new AccumulationTracker<State>(numberOfTracks, numberOfRewards, initialState);
int initialTrackerId = trackers.findOrAdd(initialTracker);
AccumulationState initialAccState = new AccumulationState(initialTrackerId, initialActiveTrack, numberOfTracks, initialGoodTracks);
AccumulationState<State> initialAccState = new AccumulationState<State>(initialTrackerId, initialActiveTrack, numberOfTracks, initialGoodTracks);
int initialAccStateId = accStates.findOrAdd(initialAccState);
return initialAccStateId;
}
public void createAuxData(final Model graph, final ExpressionAccumulation accexp, final ProbModelChecker mc) throws PrismException {
/**
* Populates fields:
* - automaton with a trimmed deterministic finite automaton and
* - numberOfTracks with the length of its longest path.
*
* @param graph
* @param accexp
* @param mc
* @throws PrismException
*/
public void createAuxData(final Model graph, final ExpressionAccumulation accexp, final Vector<? extends Rewards> rewards, final ProbModelChecker mc) throws PrismException {
mc.getLog().println(" [AP] generating aux data for " + graph + "\n and " + accexp);
// Build labels and DFA
AccumulationModelChecker accMc = new AccumulationModelChecker();
@ -334,12 +345,15 @@ public class AccumulationProductRegular<M extends Model> extends AccumulationPro
automaton = nfa.determinize();
automaton.trim(); // This should remove cycles.
System.out.println(nfa.toDot());
nfa.exportToDotFile("DEBUG-automaton-nfa.dot");
if (!automaton.isAcyclic()) {
throw new PrismException("Cannot handle cyclic automata!");
}
numberOfTracks = automaton.getLongestPathLength();
numberOfTracks = automaton.getLongestPathLength()+1;
mc.getLog().println(" [AP] tracks: " + numberOfTracks);
numberOfWeights= rewards.size();
mc.getLog().println(" [AP] weights: " + numberOfWeights);
}
}

23
prism/src/explicit/AccumulationState.java

@ -10,7 +10,7 @@ import java.util.BitSet;
* @author Sascha Wunderlich
*
*/
public class AccumulationState {
public class AccumulationState<Component> {
final int trackerId;
final BitSet goodTracks;
@ -30,23 +30,15 @@ public class AccumulationState {
public int getTrackerId() {
return trackerId;
}
public int getLastRestartNr() {
return lastRestartNr;
}
public void setLastRestartNr(int lastRestartNr) {
this.lastRestartNr = lastRestartNr;
public AccumulationTracker<Component> getTracker(StoragePool<AccumulationTracker<Component>> trackers) {
return trackers.getById(trackerId);
}
public BitSet getGoodTracks() {
return goodTracks;
}
public boolean isGoodTrack(int trackNr) {
return goodTracks.get(trackNr);
}
public boolean hasGoodTrack() {
return !goodTracks.isEmpty();
}
@ -55,16 +47,13 @@ public class AccumulationState {
return (lastRestartNr + 1) % numberOfTracks;
}
public void advance() {
lastRestartNr = getNextRestartNr();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((goodTracks == null) ? 0 : goodTracks.hashCode());
result = prime * result + lastRestartNr;
result = prime * result + numberOfTracks;
result = prime * result + trackerId;
return result;
}
@ -85,6 +74,8 @@ public class AccumulationState {
return false;
if (lastRestartNr != other.lastRestartNr)
return false;
if (numberOfTracks != other.numberOfTracks)
return false;
if (trackerId != other.trackerId)
return false;
return true;

1
prism/src/explicit/AccumulationTrack.java

@ -23,7 +23,6 @@ public class AccumulationTrack<Component> {
}
public AccumulationTrack(double[] weights, Component component) {
super();
this.weights = weights;
this.component = component;
}

4
prism/src/explicit/AccumulationTransformation.java

@ -131,12 +131,12 @@ public class AccumulationTransformation<M extends Model> implements ModelExpress
//System.out.println("Good states " + goodStates);
// Transform the expression
ReplaceAccumulationExpression replace = new ReplaceAccumulationExpression(accexp, label, product.getNumberOfTracks());
ReplaceAccumulationExpression replace = new ReplaceAccumulationExpression(accexp, label, product.getNumberOfTracks()-1);
transformedExpression = (Expression)transformedExpression.accept(replace);
mc.getLog().println("Transformed " + originalExpression.toString() +
"\n into " + transformedExpression.toString());
//DEBUG: output dotfile
product.exportToDotFile("./out.dot");
product.exportToDotFile("DEBUG-product.dot");
}
public String gensymLabel(String prefix, Model model) {

Loading…
Cancel
Save