diff --git a/prism/src/userinterface/simulator/GUISimulatorPathTableModel.java b/prism/src/userinterface/simulator/GUISimulatorPathTableModel.java index 5ba2e15c..3dd88525 100644 --- a/prism/src/userinterface/simulator/GUISimulatorPathTableModel.java +++ b/prism/src/userinterface/simulator/GUISimulatorPathTableModel.java @@ -39,6 +39,7 @@ import parser.ast.ModulesFile; import prism.ModelInfo; import simulator.PathFullInfo; import userinterface.simulator.SimulationView.ActionValue; +import userinterface.simulator.SimulationView.Observ; import userinterface.simulator.SimulationView.RewardStructureColumn; import userinterface.simulator.SimulationView.RewardStructureValue; import userinterface.simulator.SimulationView.TimeValue; @@ -51,11 +52,11 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU private static final long serialVersionUID = 1L; enum PathTableModelGroupType { - STEP, TIME, VARIABLES, REWARDS + STEP, TIME, VARIABLES, OBSERVABLES, REWARDS }; enum GUISimulatorPathTableModelColumn { - ACTION, STEP, TIME_CUMUL, TIME, VARIABLE, REWARD + ACTION, STEP, TIME_CUMUL, TIME, VARIABLE, OBSERVABLE, REWARD }; class PathTableModelGroup { @@ -167,6 +168,8 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU case VARIABLES: int module = (Integer) visibleGroups.get(groupIndex).info; return module == -1 ? "Globals" : modelInfo.getModuleName(module); + case OBSERVABLES: + return "Observables"; case REWARDS: return "Rewards"; default: @@ -189,6 +192,8 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU case VARIABLES: int module = (Integer) visibleGroups.get(groupIndex).info; return module == -1 ? "Global variables" : "Variables of module " + modelInfo.getModuleName(module); + case OBSERVABLES: + return null; case REWARDS: return "State, transition and cumulative rewards"; default: @@ -257,6 +262,9 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU case VARIABLE: Variable var = (Variable) visibleColumns.get(columnIndex).info; return var.toString(); + case OBSERVABLE: + Observ obs = (Observ) visibleColumns.get(columnIndex).info; + return obs.toString(); case REWARD: RewardStructureColumn rewardColumn = (RewardStructureColumn) visibleColumns.get(columnIndex).info; return rewardColumn.getColumnName(); @@ -282,7 +290,10 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU return "Time spent in state"; case VARIABLE: Variable var = (Variable) visibleColumns.get(columnIndex).info; - return "Value of variable \"" + var.toString() + "\""; + return "Value of variable " + var.toString(); + case OBSERVABLE: + Observ obs = (Observ) visibleColumns.get(columnIndex).info; + return "Value of observable " + obs.toString(); case REWARD: RewardStructureColumn rewardColumn = (RewardStructureColumn) visibleColumns.get(columnIndex).info; String rewardName = rewardColumn.getRewardStructure().getColumnName(); @@ -333,6 +344,14 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU variableValue.setValue(result); variableValue.setChanged(rowIndex == 0 || !path.getState(rowIndex - 1).varValues[var.getIndex()].equals(result)); return variableValue; + case OBSERVABLE: + // An observable column + Observ obs = (Observ) visibleColumns.get(columnIndex).info; + Object resultO = path.getObservation(rowIndex).varValues[obs.getIndex()]; + variableValue.setVariable(obs); + variableValue.setValue(resultO); + variableValue.setChanged(rowIndex == 0 || !path.getObservation(rowIndex - 1).varValues[obs.getIndex()].equals(resultO)); + return variableValue; case REWARD: // A reward column RewardStructureColumn rewardColumn = (RewardStructureColumn) visibleColumns.get(columnIndex).info; @@ -427,6 +446,13 @@ public class GUISimulatorPathTableModel extends AbstractTableModel implements GU } } } + // Variables + if (view.getVisibleObservables().size() > 0) { + for (Observ o : view.getVisibleObservables()) { + visibleColumns.add(new PathTableModelColumn(GUISimulatorPathTableModelColumn.OBSERVABLE, o)); + } + visibleGroups.add(new PathTableModelGroup(PathTableModelGroupType.OBSERVABLES, null, visibleColumns.size() - 1)); + } // Rewards if (view.getVisibleRewardColumns().size() > 0) { for (RewardStructureColumn rsc : view.getVisibleRewardColumns()) { diff --git a/prism/src/userinterface/simulator/SimulationView.java b/prism/src/userinterface/simulator/SimulationView.java index c03e57aa..d426b1ac 100644 --- a/prism/src/userinterface/simulator/SimulationView.java +++ b/prism/src/userinterface/simulator/SimulationView.java @@ -35,6 +35,7 @@ import java.util.TreeSet; import parser.ast.ModulesFile; import parser.ast.RewardStruct; import parser.type.Type; +import prism.PrismException; import prism.PrismSettings; import userinterface.simulator.GUIViewDialog.RewardListItem; @@ -48,6 +49,8 @@ public class SimulationView extends Observable private ArrayList visibleVariables; private ArrayList hiddenVariables; + private ArrayList visibleObservables; + private ArrayList visibleRewardColumns; private ArrayList rewards; @@ -63,7 +66,7 @@ public class SimulationView extends Observable this.visibleVariables = new ArrayList(); this.hiddenVariables = new ArrayList(); - + this.visibleObservables = new ArrayList<>(); this.visibleRewardColumns = new ArrayList(); this.rewards = new ArrayList(); @@ -147,6 +150,11 @@ public class SimulationView extends Observable this.notifyObservers(); } + public ArrayList getVisibleObservables() + { + return visibleObservables; + } + public ArrayList getVisibleRewardColumns() { return visibleRewardColumns; @@ -202,6 +210,8 @@ public class SimulationView extends Observable simulator.setRenderer(useChangeRenderer); } + try { + // Time-wise we have a problem. if (!parsedModel.getModelType().continuousTime() && (showTime || showCumulativeTime)) canUseCurrentView = false; @@ -224,6 +234,22 @@ public class SimulationView extends Observable if (allVarNames.size() > 0) canUseCurrentView = false; + // Make a set of all observable names. + TreeSet allObsNames = new TreeSet(); + for (Observ obs : visibleObservables) + allObsNames.add(obs.getName()); + + // Cannot use current view if an observable is not there. + for (int i = 0; i < parsedModel.getNumObservables(); i++) { + if (!allObsNames.remove(parsedModel.getObservableName(i))) { + canUseCurrentView = false; + } + } + + // Cannot use current view if we have too many observable. + if (allObsNames.size() > 0) + canUseCurrentView = false; + // Make a list of all reward structures ArrayList allrew = new ArrayList(); for (RewardStructure rew : rewards) { @@ -251,17 +277,29 @@ public class SimulationView extends Observable if (allrew.size() > 0) canUseCurrentView = false; + + } catch (PrismException e) { + canUseCurrentView = false; + } } if (!canUseCurrentView && pathActive) { visibleVariables.clear(); hiddenVariables.clear(); + visibleObservables.clear(); visibleRewardColumns.clear(); rewards.clear(); { for (int i = 0; i < parsedModel.getNumVars(); i++) { visibleVariables.add(new Variable(i, parsedModel.getVarName(i), parsedModel.getVarType(i), parsedModel.getVarModuleIndex(i))); } + for (int i = 0; i < parsedModel.getNumObservables(); i++) { + try { + visibleObservables.add(new Observ(i, parsedModel.getObservableName(i), parsedModel.getObservableType(i))); + } catch (PrismException e) { + // Don't add if error (should not happen) + } + } for (int r = 0; r < parsedModel.getNumRewardStructs(); r++) { RewardStruct rewardStruct = parsedModel.getRewardStruct(r); String rewardName = rewardStruct.getName(); @@ -295,10 +333,10 @@ public class SimulationView extends Observable */ public class Variable { - private int index; - private String name; - private Type type; - private int moduleIndex; + protected int index; + protected String name; + protected Type type; + protected int moduleIndex; public Variable(int index, String name, Type type, int moduleIndex) { @@ -383,6 +421,19 @@ public class SimulationView extends Observable } } + public class Observ extends Variable + { + public Observ(int index, String name, Type type) + { + super(index, name, type, -1); + } + + public String toString() + { + return "\"" + name + "\""; + } + } + public class ActionValue { private String value;