You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
7.8 KiB
307 lines
7.8 KiB
//==============================================================================
|
|
//
|
|
// Copyright (c) 2002-
|
|
// Authors:
|
|
// * Dave Parker <d.a.parker@cs.bham.ac.uk> (University of Birmingham/Oxford)
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// This file is part of PRISM.
|
|
//
|
|
// PRISM is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// PRISM is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with PRISM; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//==============================================================================
|
|
|
|
package simulator;
|
|
|
|
import parser.State;
|
|
import parser.ast.ModulesFile;
|
|
import prism.PrismLog;
|
|
|
|
/**
|
|
* Class to display a simulation path in text form, sending to a PrismLog.
|
|
*/
|
|
public class PathToText extends PathDisplayer
|
|
{
|
|
/** Log to display path to */
|
|
private PrismLog log;
|
|
|
|
// Model info
|
|
private ModulesFile modulesFile;
|
|
private int numVars;
|
|
private int numRewardStructs;
|
|
private boolean contTime;
|
|
|
|
// Config
|
|
private boolean showTimeCumul = true;
|
|
private boolean showTimeSpent = false;
|
|
private String colSep = " ";
|
|
|
|
// Displayer state
|
|
/** Is the next column the first? */
|
|
private boolean firstCol;
|
|
/** Last state */
|
|
private State lastState;
|
|
/** Last state rewards */
|
|
private double[] lastStateRewards;
|
|
/** Did the displayed info change in the current step? */
|
|
private boolean changed;
|
|
|
|
/**
|
|
* Construct a {@link PathToText} object
|
|
* @param log Log to output path to
|
|
* @param modulesFile Model associated with path
|
|
*/
|
|
public PathToText(PrismLog log, ModulesFile modulesFile)
|
|
{
|
|
this.log = log;
|
|
this.modulesFile = modulesFile;
|
|
|
|
// Get model info
|
|
numVars = modulesFile.getNumVars();
|
|
numRewardStructs = modulesFile.getNumRewardStructs();
|
|
contTime = modulesFile.getModelType().continuousTime();
|
|
}
|
|
|
|
// Setters
|
|
|
|
/**
|
|
* Set whether we show cumulative time (for continuous models only)
|
|
*/
|
|
public void setShowTimeCumul(boolean showTimeCumul)
|
|
{
|
|
this.showTimeCumul = showTimeCumul;
|
|
}
|
|
|
|
/**
|
|
* Set whether we show time spent in each state (for continuous models only)
|
|
*/
|
|
public void setShowTimeSpent(boolean showTimeSpent)
|
|
{
|
|
this.showTimeSpent = showTimeSpent;
|
|
}
|
|
|
|
/**
|
|
* Set the column separator for the table of path contents
|
|
*/
|
|
public void setColSep(String colSep)
|
|
{
|
|
this.colSep = colSep;
|
|
}
|
|
|
|
// Display methods
|
|
|
|
@Override
|
|
public void startDisplay(State initialState, double[] initialStateRewards)
|
|
{
|
|
int j;
|
|
|
|
// Display header
|
|
firstCol = true;
|
|
if (!getShowSnapshots()) {
|
|
log.print(getColSep() + "action");
|
|
if (showProbs)
|
|
log.print(getColSep() + "probability");
|
|
}
|
|
log.print(getColSep() + "step");
|
|
if (contTime && showTimeCumul)
|
|
log.print(getColSep() + "time");
|
|
if (varsToShow == null)
|
|
for (j = 0; j < numVars; j++)
|
|
log.print(getColSep() + modulesFile.getVarName(j));
|
|
else
|
|
for (int v : varsToShow)
|
|
log.print(getColSep() + modulesFile.getVarName(v));
|
|
if (getShowRewards()) {
|
|
if (numRewardStructs == 1) {
|
|
log.print(getColSep() + "state_reward");
|
|
if (!getShowSnapshots())
|
|
log.print(getColSep() + "transition_reward");
|
|
} else {
|
|
for (j = 0; j < numRewardStructs; j++) {
|
|
log.print(getColSep() + "state_reward" + (j + 1));
|
|
if (!getShowSnapshots())
|
|
log.print(getColSep() + "transition_reward" + (j + 1));
|
|
}
|
|
}
|
|
}
|
|
if (!getShowSnapshots()) {
|
|
if (contTime && showTimeSpent)
|
|
log.print(getColSep() + "time_in_state");
|
|
}
|
|
log.println();
|
|
|
|
// Display initial step
|
|
changed = true;
|
|
firstCol = true;
|
|
if (!getShowSnapshots()) {
|
|
log.print(getColSep() + "-");
|
|
if (showProbs)
|
|
log.print(getColSep() + "-");
|
|
}
|
|
log.print(getColSep() + "0");
|
|
if (contTime && showTimeCumul)
|
|
log.print(getColSep() + "0.0");
|
|
lastState = new State(initialState.varValues.length);
|
|
displayState(initialState);
|
|
if (getShowRewards()) {
|
|
lastStateRewards = explicit.Utils.cloneDoubleArray(initialStateRewards);
|
|
}
|
|
if (getShowSnapshots()) {
|
|
log.println();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void displayStep(double timeSpent, double timeCumul, Object action, double probability, double[] transitionRewards, int newStateIndex, State newState, double[] newStateRewards)
|
|
{
|
|
if (!showChangesOnly || changed) {
|
|
// display rewards for last state
|
|
if (getShowRewards()) {
|
|
for (int j = 0; j < numRewardStructs; j++) {
|
|
log.print(getColSep() + lastStateRewards[j]);
|
|
log.print(getColSep() + transitionRewards[j]);
|
|
}
|
|
}
|
|
// display time spent in state
|
|
if (contTime && showTimeSpent)
|
|
log.print(getColSep() + timeSpent);
|
|
log.println();
|
|
}
|
|
|
|
// if required, check whether the info to be displayed changed
|
|
if (showChangesOnly) {
|
|
changed = stateChanged(lastState, newState) || rewardsChanged(lastStateRewards, newStateRewards);
|
|
if (!changed)
|
|
return;
|
|
}
|
|
|
|
firstCol = true;
|
|
|
|
// display action
|
|
log.print(getColSep() + action);
|
|
// display probability/rate
|
|
if (showProbs)
|
|
log.print(getColSep() + probability);
|
|
// display state index
|
|
log.print(getColSep() + newStateIndex);
|
|
// display cumulative time
|
|
if (contTime && showTimeCumul)
|
|
log.print(getColSep() + timeCumul);
|
|
// display state
|
|
displayState(newState);
|
|
// store state rewards
|
|
if (getShowRewards()) {
|
|
explicit.Utils.copyDoubleArray(newStateRewards, lastStateRewards);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void displaySnapshot(double timeCumul, int newStateIndex, State newState, double[] newStateRewards)
|
|
{
|
|
firstCol = true;
|
|
|
|
// display state index
|
|
log.print(getColSep() + newStateIndex);
|
|
// display cumulative time
|
|
if (contTime && showTimeCumul)
|
|
log.print(getColSep() + timeCumul);
|
|
// display state
|
|
displayState(newState);
|
|
// display state rewards
|
|
if (getShowRewards()) {
|
|
for (int j = 0; j < numRewardStructs; j++) {
|
|
log.print(getColSep() + newStateRewards[j]);
|
|
}
|
|
}
|
|
log.println();
|
|
}
|
|
|
|
private void displayState(State state)
|
|
{
|
|
int j;
|
|
if (varsToShow == null) {
|
|
for (j = 0; j < numVars; j++) {
|
|
log.print(getColSep());
|
|
log.print(state.varValues[j]);
|
|
}
|
|
} else {
|
|
for (int v : varsToShow) {
|
|
log.print(getColSep());
|
|
log.print(state.varValues[v]);
|
|
}
|
|
}
|
|
lastState.copy(state);
|
|
}
|
|
|
|
private String getColSep()
|
|
{
|
|
if (firstCol) {
|
|
firstCol = false;
|
|
return "";
|
|
} else {
|
|
return colSep;
|
|
}
|
|
}
|
|
|
|
private boolean stateChanged(State lastState, State newState)
|
|
{
|
|
if (varsToShow == null) {
|
|
for (int j = 0; j < numVars; j++) {
|
|
if (!newState.varValues[j].equals(lastState.varValues[j])) {
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
for (int v : varsToShow) {
|
|
if (!newState.varValues[v].equals(lastState.varValues[v])) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean rewardsChanged(double[] lastStateRewards, double[] newStateRewards)
|
|
{
|
|
if (!showRewards)
|
|
return false;
|
|
for (int j = 0; j < numRewardStructs; j++) {
|
|
if (newStateRewards[j] != lastStateRewards[j]) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void endDisplay()
|
|
{
|
|
if (!getShowSnapshots() && (!showChangesOnly || changed)) {
|
|
// display state rewards for last state
|
|
// (transition rewards unknown because no outgoing transition)
|
|
if (getShowRewards()) {
|
|
for (int j = 0; j < numRewardStructs; j++) {
|
|
log.print(getColSep() + lastStateRewards[j]);
|
|
log.print(getColSep() + "?");
|
|
}
|
|
}
|
|
// display (zero) time spent in state
|
|
if (contTime && showTimeSpent)
|
|
log.print(getColSep() + 0.0);
|
|
log.println();
|
|
}
|
|
}
|
|
}
|