Skip to content

Commit 7c57555

Browse files
committed
caching labels inside modelgenerator
1 parent 890169c commit 7c57555

4 files changed

Lines changed: 113 additions & 43 deletions

File tree

prism/src/explicit/ConstructModel.java

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,11 @@ public Model constructModel(ModelGenerator modelGen, boolean justReach) throws P
410410
permut = null;
411411

412412
if (!justReach && attachLabels) {
413-
attachLabels(modelGen, model);
413+
// Attach labels/bitsets
414+
List <State> statesList = model.getStatesList();
415+
for (String label : model.getLabels()){
416+
model.addLabel(label, modelGen.getLabel(label, statesList));
417+
}
414418
}
415419

416420
return model;
@@ -436,38 +440,6 @@ private void setStateObservation(ModelGenerator modelGen, POMDPSimple pomdp, int
436440
// Set observation/unobservation
437441
pomdp.setObservation(s, sObs, sUnobs, modelGen.getObservableNames());
438442
}
439-
440-
private void attachLabels(ModelGenerator modelGen, ModelExplicit model) throws PrismException
441-
{
442-
int i,j;
443-
// Create storage for labels
444-
int numLabels = modelGen.getNumLabels();
445-
// No need to continue unless this ModelGenerator uses labels
446-
if (numLabels == 0) return;
447-
BitSet[] bitsets = new BitSet[numLabels];
448-
for (j = 0; j < numLabels; j++) {
449-
bitsets[j] = new BitSet();
450-
}
451-
452-
// Get state info
453-
List <State> statesList = model.getStatesList();
454-
int numStates = statesList.size();
455-
456-
// Construct bitsets for labels
457-
for (i = 0; i < numStates; i++) {
458-
State state = statesList.get(i);
459-
Map<String, Boolean> labelValues = modelGen.getLabelValues(state);
460-
for (j = 0; j < numLabels; j++) {
461-
if (labelValues.get(modelGen.getLabelName(j))) {
462-
bitsets[j].set(i);
463-
}
464-
}
465-
}
466-
// Attach labels/bitsets
467-
for (j = 0; j < numLabels; j++) {
468-
model.addLabel(modelGen.getLabelName(j), bitsets[j]);
469-
}
470-
}
471443

472444
/**
473445
* Test method.

prism/src/prism/ModelGenerator.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
package prism;
2929

3030
import parser.State;
31-
import parser.Values;
3231

32+
import java.util.BitSet;
3333
import java.util.Collections;
3434
import java.util.List;
3535
import java.util.Map;
@@ -311,7 +311,7 @@ public default String getTransitionUpdateStringFull(int i, int offset) throws Pr
311311
public State computeTransitionTarget(int i, int offset) throws PrismException;
312312

313313
/**
314-
* Creates a {@link Values} map for all labels in the current state.
314+
* Creates a {@link Map} of (label-name -> label-value) for all labels in the current state.
315315
*/
316316
default Map<String, Boolean> getLabelValues(State state) throws PrismException
317317
{
@@ -320,6 +320,19 @@ default Map<String, Boolean> getLabelValues(State state) throws PrismException
320320
}
321321

322322
/**
323+
* This method creates a BitSet for the given label-name containing all values in the
324+
* order of the given statesList.
325+
* @param name The name of the Label.
326+
* @param statesList The List of states in right order.
327+
* @return a {@link BitSet} of all values from the given label.
328+
* @throws PrismException If the label values aren't cached or not all states have been evaluated
329+
*/
330+
default BitSet getLabel(String name, List<State> statesList) throws PrismException
331+
{
332+
throw new PrismException("Labels are not cached");
333+
}
334+
335+
/**
323336
* Get the observation when entering state {@code state}.
324337
* This is represented as a {@link parser.State} object, with one value per observable.
325338
* For models that are not partially observable, null can be returned.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package simulator;
2+
3+
4+
import common.iterable.Range;
5+
import parser.State;
6+
import parser.ast.LabelList;
7+
import prism.PrismException;
8+
import prism.PrismLangException;
9+
10+
import java.util.BitSet;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
public class LabelsCache
16+
{
17+
// cache internal order of states
18+
Map<State, Integer> stateIndices = new HashMap<>();
19+
Map<String, BitSet> labelValues = new HashMap<>();
20+
LabelList labelList;
21+
22+
LabelsCache(LabelList ll)
23+
{
24+
this.labelList = ll;
25+
for (String label : ll.getLabelNames()) {
26+
labelValues.put(label, new BitSet());
27+
}
28+
}
29+
30+
public boolean getLabelValue(State state, String label)
31+
{
32+
return labelValues.get(label).get(stateIndices.get(state));
33+
}
34+
35+
public Map<String, Boolean> getLabelValues(State state) throws PrismLangException
36+
{
37+
int index;
38+
Map<String, Boolean> stateLabelValues;
39+
40+
if (stateIndices.containsKey(state)) {
41+
index = stateIndices.get(state);
42+
stateLabelValues = new HashMap<>();
43+
labelValues.forEach((name, bitset) -> stateLabelValues.put(name, bitset.get(index)));
44+
} else {
45+
index = addState(state);
46+
stateLabelValues = labelList.getLabelValues(state);
47+
labelValues.forEach((name, bitset) -> bitset.set(index, stateLabelValues.get(name)));
48+
}
49+
return stateLabelValues;
50+
}
51+
52+
private int addState(State state)
53+
{
54+
int nextIndex = stateIndices.size();
55+
stateIndices.put(state, nextIndex);
56+
return nextIndex;
57+
}
58+
59+
public BitSet getLabel(String name, List<State> statesList) throws PrismException
60+
{
61+
// check if all states have been evaluated
62+
for (State state : statesList) {
63+
if (!stateIndices.containsKey(state)) {
64+
throw new PrismException("Labels not evaluated for state: " + state);
65+
}
66+
}
67+
// assuming statesList has efficient indexed access, e.g., ArrayList
68+
BitSet values = labelValues.get(name);
69+
70+
Range indices = new Range(statesList.size()).reversed(); // iterate in revese order to avoid multiple resizing of BitSet
71+
return indices.filter((int i) -> values.get(stateIndices.get(statesList.get(i)))).collect(new BitSet());
72+
}
73+
}

prism/src/simulator/ModulesFileModelGenerator.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package simulator;
22

3-
import java.util.ArrayList;
4-
import java.util.HashMap;
5-
import java.util.List;
6-
import java.util.Map;
7-
83
import parser.State;
94
import parser.Values;
105
import parser.VarList;
@@ -21,6 +16,11 @@
2116
import prism.PrismLangException;
2217
import prism.RewardGenerator;
2318

19+
import java.util.ArrayList;
20+
import java.util.BitSet;
21+
import java.util.List;
22+
import java.util.Map;
23+
2424
public class ModulesFileModelGenerator implements ModelGenerator, RewardGenerator
2525
{
2626
// Parent PrismComponent (logs, settings etc.)
@@ -47,6 +47,9 @@ public class ModulesFileModelGenerator implements ModelGenerator, RewardGenerato
4747
protected TransitionList transitionList;
4848
// Has the transition list been built?
4949
protected boolean transitionListBuilt;
50+
51+
// label value cache
52+
protected LabelsCache labelsCache;
5053

5154
/**
5255
* Build a ModulesFileModelGenerator for a particular PRISM model, represented by a ModuleFile instance.
@@ -75,7 +78,7 @@ public ModulesFileModelGenerator(ModulesFile modulesFile, PrismComponent parent)
7578
if (modulesFile.getSystemDefn() != null) {
7679
throw new PrismException("The system...endsystem construct is not currently supported");
7780
}
78-
81+
7982
// Store basic model info
8083
this.modulesFile = modulesFile;
8184
this.originalModulesFile = modulesFile;
@@ -103,6 +106,9 @@ private void initialise() throws PrismException
103106
labelList = modulesFile.getLabelList();
104107
labelNames = labelList.getLabelNames();
105108

109+
// create label-cache
110+
labelsCache = new LabelsCache(labelList);
111+
106112
// Create data structures for exploring model
107113
updater = new Updater(modulesFile, varList, parent);
108114
transitionList = new TransitionList();
@@ -413,9 +419,15 @@ public State computeTransitionTarget(int index, int offset) throws PrismExceptio
413419
@Override
414420
public Map<String, Boolean> getLabelValues(State state) throws PrismLangException
415421
{
416-
return labelList.getLabelValues(state);
422+
return labelsCache.getLabelValues(state);
417423
}
418-
424+
425+
@Override
426+
public BitSet getLabel(String name, List<State> statesList) throws PrismException
427+
{
428+
return labelsCache.getLabel(name, statesList);
429+
}
430+
419431
@Override
420432
public State getObservation(State state) throws PrismException
421433
{

0 commit comments

Comments
 (0)