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

//==============================================================================
//
// 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();
}
}
}