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.
268 lines
6.0 KiB
268 lines
6.0 KiB
//==============================================================================
|
|
//
|
|
// Copyright (c) 2002-
|
|
// Authors:
|
|
// * Dave Parker <david.parker@comlab.ox.ac.uk> (University of 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 parser;
|
|
|
|
import java.util.*;
|
|
|
|
import parser.ast.ModulesFile;
|
|
import prism.PrismLangException;
|
|
|
|
/**
|
|
* Class to store a model state, i.e. a mapping from variables to values.
|
|
* Stores as an array of Objects, where indexing is defined by the ModulesFile.
|
|
*/
|
|
public class State implements Comparable<State>
|
|
{
|
|
public Object varValues[];
|
|
|
|
/**
|
|
* Construct empty (uninitialised) state.
|
|
* @param n Number of variables.
|
|
*/
|
|
public State(int n)
|
|
{
|
|
varValues = new Object[n];
|
|
}
|
|
|
|
/**
|
|
* Construct by copying existing State object.
|
|
* @param s State to copy.
|
|
*/
|
|
public State(State s)
|
|
{
|
|
this(s.varValues.length);
|
|
copy(s);
|
|
}
|
|
|
|
/**
|
|
* Construct by concatenating two existing State objects.
|
|
*/
|
|
public State(State s1, State s2)
|
|
{
|
|
Object[] arr1 = (Object[]) s1.varValues;
|
|
Object[] arr2 = (Object[]) s2.varValues;
|
|
varValues = new Object[arr1.length + arr2.length];
|
|
int i;
|
|
for (i = 0; i < arr1.length; i++)
|
|
varValues[i] = arr1[i];
|
|
for (i = 0; i < arr2.length; i++)
|
|
varValues[arr1.length + i] = arr2[i];
|
|
}
|
|
|
|
/**
|
|
* Construct by copying existing Values object.
|
|
* Need access to a ModulesFile in case variables are not ordered correctly.
|
|
* Throws an exception if any variables are undefined.
|
|
* @param v Values object to copy.
|
|
* @param mf Corresponding ModulesFile (for variable info/ordering)
|
|
*/
|
|
public State(Values v, ModulesFile mf) throws PrismLangException
|
|
{
|
|
int i, j, n;
|
|
n = v.getNumValues();
|
|
if (n != mf.getNumVars()) {
|
|
throw new PrismLangException("Wrong number of variables in state");
|
|
}
|
|
varValues = new Object[n];
|
|
for (i = 0; i < n; i++) {
|
|
varValues[i] = null;
|
|
}
|
|
for (i = 0; i < n; i++) {
|
|
j = mf.getVarIndex(v.getName(i));
|
|
if (j == -1) {
|
|
throw new PrismLangException("Unknown variable " + v.getName(i) + " in state");
|
|
}
|
|
if (varValues[i] != null) {
|
|
throw new PrismLangException("Duplicated variable " + v.getName(i) + " in state");
|
|
}
|
|
varValues[i] = v.getValue(i);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear: set all values to null
|
|
*/
|
|
public void clear()
|
|
{
|
|
int i, n;
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++)
|
|
varValues[i] = null;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public void setValue(int i, Object val)
|
|
{
|
|
varValues[i] = val;
|
|
}
|
|
|
|
/**
|
|
* Copy contents of an existing state.
|
|
* @param s State to copy.
|
|
*/
|
|
public void copy(State s)
|
|
{
|
|
int i, n;
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++)
|
|
varValues[i] = s.varValues[i];
|
|
}
|
|
|
|
@Override
|
|
public int hashCode()
|
|
{
|
|
// Simple hash code
|
|
return varValues.length > 0 ? varValues[0].hashCode() : 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o)
|
|
{
|
|
if (o == this)
|
|
return true;
|
|
if (!(o instanceof State))
|
|
return false;
|
|
|
|
int i, n;
|
|
State s = (State) o;
|
|
n = varValues.length;
|
|
if (n != s.varValues.length)
|
|
return false;
|
|
for (i = 0; i < n; i++) {
|
|
if (!(varValues[i]).equals(s.varValues[i]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public int compareTo(State s)
|
|
{
|
|
int i, j, n;
|
|
Object svv[], o1, o2;
|
|
// Can't compare to null
|
|
if (s == null)
|
|
throw new NullPointerException();
|
|
// States of different size are incomparable
|
|
svv = s.varValues;
|
|
n = varValues.length;
|
|
if (n != svv.length)
|
|
throw new ClassCastException("States are different sizes");
|
|
// Go through array
|
|
for (i = 0; i < n; i++) {
|
|
o1 = varValues[i];
|
|
o2 = svv[i];
|
|
if (o1 instanceof Integer && o2 instanceof Integer) {
|
|
j = ((Integer) o1).compareTo((Integer) o2);
|
|
if (j != 0)
|
|
return j;
|
|
else
|
|
continue;
|
|
} else if (o1 instanceof Boolean && o2 instanceof Boolean) {
|
|
j = ((Boolean) o1).compareTo((Boolean) o2);
|
|
if (j != 0)
|
|
return j;
|
|
else
|
|
continue;
|
|
} else {
|
|
throw new ClassCastException("Can't compare " + o1.getClass() + " and " + o2.getClass());
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Get string representation, e.g. "(0,true,5)".
|
|
*/
|
|
@Override
|
|
public String toString()
|
|
{
|
|
int i, n;
|
|
String s = "(";
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++) {
|
|
if (i > 0)
|
|
s += ",";
|
|
s += varValues[i];
|
|
}
|
|
s += ")";
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Get string representation, without outer parentheses, e.g. "0,true,5".
|
|
*/
|
|
public String toStringNoParentheses()
|
|
{
|
|
int i, n;
|
|
String s = "";
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++) {
|
|
if (i > 0)
|
|
s += ",";
|
|
s += varValues[i];
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Get string representation, e.g. "(a=0,b=true,c=5)",
|
|
* with variables names (taken from a String list).
|
|
*/
|
|
public String toString(List<String> varNames)
|
|
{
|
|
int i, n;
|
|
String s = "(";
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++) {
|
|
if (i > 0)
|
|
s += ",";
|
|
s += varNames.get(i) + "=" + varValues[i];
|
|
}
|
|
s += ")";
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Get string representation, e.g. "(a=0,b=true,c=5)",
|
|
* with variables names (taken from a ModulesFile).
|
|
*/
|
|
public String toString(ModulesFile mf)
|
|
{
|
|
int i, n;
|
|
String s = "(";
|
|
n = varValues.length;
|
|
for (i = 0; i < n; i++) {
|
|
if (i > 0)
|
|
s += ",";
|
|
s += mf.getVarName(i) + "=" + varValues[i];
|
|
}
|
|
s += ")";
|
|
return s;
|
|
}
|
|
}
|