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
7.9 KiB
268 lines
7.9 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.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
|
|
import parser.ast.Declaration;
|
|
import parser.ast.DeclarationBool;
|
|
import parser.ast.DeclarationInt;
|
|
import parser.ast.DeclarationType;
|
|
import parser.ast.Expression;
|
|
import parser.ast.Module;
|
|
import parser.ast.ModulesFile;
|
|
import parser.type.Type;
|
|
import parser.type.TypeBool;
|
|
import parser.type.TypeInt;
|
|
import prism.ModelType;
|
|
import prism.Prism;
|
|
import prism.PrismException;
|
|
import prism.PrismLog;
|
|
|
|
/**
|
|
* Class to build a (partial) ModulesFile corresponding to imported explicit-state file storage of a model.
|
|
* Basically, the ModulesFile just stores the model type and variable info.
|
|
* The number of states in the model is also extracted.
|
|
*/
|
|
public class ExplicitFiles2ModulesFile
|
|
{
|
|
// Prism stuff
|
|
private Prism prism;
|
|
private PrismLog mainLog;
|
|
|
|
// Num states
|
|
private int numStates = 0;
|
|
|
|
public ExplicitFiles2ModulesFile(Prism prism)
|
|
{
|
|
this.prism = prism;
|
|
mainLog = prism.getMainLog();
|
|
}
|
|
|
|
/**
|
|
* Get the number of states
|
|
* (determined from either states file or transitions file).
|
|
*/
|
|
public int getNumStates()
|
|
{
|
|
return numStates;
|
|
}
|
|
|
|
/**
|
|
* Build a ModulesFile corresponding to the passed in states/transitions files.
|
|
* If {@code typeOverride} is null, we assume model is an MDP.
|
|
*/
|
|
public ModulesFile buildModulesFile(File statesFile, File transFile, ModelType typeOverride) throws PrismException
|
|
{
|
|
ModulesFile modulesFile;
|
|
ModelType modelType;
|
|
|
|
// Generate ModulesFile from states or transitions file, depending what is available
|
|
if (statesFile != null) {
|
|
modulesFile = createVarInfoFromStatesFile(statesFile);
|
|
} else {
|
|
modulesFile = createVarInfoFromTransFile(transFile);
|
|
}
|
|
|
|
// Set model type: if no preference stated, assume default of MDP
|
|
modelType = (typeOverride == null) ? ModelType.MDP : typeOverride;
|
|
modulesFile.setModelType(modelType);
|
|
|
|
return modulesFile;
|
|
}
|
|
|
|
/**
|
|
* Build a ModulesFile corresponding to a states file.
|
|
*/
|
|
private ModulesFile createVarInfoFromStatesFile(File statesFile) throws PrismException
|
|
{
|
|
BufferedReader in;
|
|
String s, ss[];
|
|
int i, j, lineNum = 0;
|
|
Module m;
|
|
Declaration d;
|
|
DeclarationType dt;
|
|
// Var info
|
|
int numVars;
|
|
String varNames[];
|
|
int varMins[];
|
|
int varMaxs[];
|
|
int varRanges[];
|
|
Type varTypes[];
|
|
ModulesFile modulesFile;
|
|
|
|
try {
|
|
// open file for reading
|
|
in = new BufferedReader(new FileReader(statesFile));
|
|
// read first line and extract var names
|
|
s = in.readLine();
|
|
lineNum = 1;
|
|
if (s == null)
|
|
throw new PrismException("empty states file");
|
|
s = s.trim();
|
|
if (s.charAt(0) != '(' || s.charAt(s.length() - 1) != ')')
|
|
throw new PrismException("badly formatted state");
|
|
s = s.substring(1, s.length() - 1);
|
|
varNames = s.split(",");
|
|
numVars = varNames.length;
|
|
// create arrays to store info about vars
|
|
varMins = new int[numVars];
|
|
varMaxs = new int[numVars];
|
|
varRanges = new int[numVars];
|
|
varTypes = new Type[numVars];
|
|
// read remaining lines
|
|
s = in.readLine();
|
|
lineNum++;
|
|
numStates = 0;
|
|
while (s != null) {
|
|
// skip blank lines
|
|
s = s.trim();
|
|
if (s.length() > 0) {
|
|
// increment state count
|
|
numStates++;
|
|
// split string
|
|
s = s.substring(s.indexOf('(') + 1, s.indexOf(')'));
|
|
ss = s.split(",");
|
|
if (ss.length != numVars)
|
|
throw new PrismException("wrong number of variables");
|
|
// for each variable...
|
|
for (i = 0; i < numVars; i++) {
|
|
// if this is the first state, establish variable type
|
|
if (numStates == 1) {
|
|
if (ss[i].equals("true") || ss[i].equals("false"))
|
|
varTypes[i] = TypeBool.getInstance();
|
|
else
|
|
varTypes[i] = TypeInt.getInstance();
|
|
}
|
|
// check for new min/max values (ints only)
|
|
if (varTypes[i] instanceof TypeInt) {
|
|
j = Integer.parseInt(ss[i]);
|
|
if (numStates == 1) {
|
|
varMins[i] = varMaxs[i] = j;
|
|
} else {
|
|
if (j < varMins[i])
|
|
varMins[i] = j;
|
|
if (j > varMaxs[i])
|
|
varMaxs[i] = j;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// read next line
|
|
s = in.readLine();
|
|
lineNum++;
|
|
}
|
|
// compute variable ranges
|
|
for (i = 0; i < numVars; i++) {
|
|
if (varTypes[i] instanceof TypeInt) {
|
|
varRanges[i] = varMaxs[i] - varMins[i];
|
|
// if range = 0, increment maximum - we don't allow zero-range variables
|
|
if (varRanges[i] == 0)
|
|
varMaxs[i]++;
|
|
}
|
|
}
|
|
// close file
|
|
in.close();
|
|
} catch (IOException e) {
|
|
throw new PrismException("File I/O error reading from \"" + statesFile + "\"");
|
|
} catch (NumberFormatException e) {
|
|
throw new PrismException("Error detected at line " + lineNum + " of states file \"" + statesFile + "\"");
|
|
} catch (PrismException e) {
|
|
throw new PrismException("Error detected (" + e.getMessage() + ") at line " + lineNum + " of states file \"" + statesFile + "\"");
|
|
}
|
|
// create modules file
|
|
modulesFile = new ModulesFile();
|
|
m = new Module("M");
|
|
for (i = 0; i < numVars; i++) {
|
|
if (varTypes[i] instanceof TypeInt) {
|
|
dt = new DeclarationInt(Expression.Int(varMins[i]), Expression.Int(varMaxs[i]));
|
|
d = new Declaration(varNames[i], dt);
|
|
d.setStart(Expression.Int(varMins[i]));
|
|
} else {
|
|
dt = new DeclarationBool();
|
|
d = new Declaration(varNames[i], dt);
|
|
d.setStart(Expression.False());
|
|
}
|
|
m.addDeclaration(d);
|
|
}
|
|
modulesFile.addModule(m);
|
|
modulesFile.tidyUp();
|
|
|
|
return modulesFile;
|
|
}
|
|
|
|
/**
|
|
* Build a ModulesFile corresponding to a transitions file.
|
|
*/
|
|
private ModulesFile createVarInfoFromTransFile(File transFile) throws PrismException
|
|
{
|
|
BufferedReader in;
|
|
String s, ss[];
|
|
int lineNum = 0;
|
|
Module m;
|
|
Declaration d;
|
|
DeclarationType dt;
|
|
ModulesFile modulesFile;
|
|
|
|
try {
|
|
// open file for reading
|
|
in = new BufferedReader(new FileReader(transFile));
|
|
// read first line and extract num states
|
|
s = in.readLine();
|
|
lineNum = 1;
|
|
if (s == null)
|
|
throw new PrismException("empty transitions file");
|
|
s = s.trim();
|
|
ss = s.split(" ");
|
|
if (ss.length < 2)
|
|
throw new PrismException("");
|
|
numStates = Integer.parseInt(ss[0]);
|
|
// close file
|
|
in.close();
|
|
} catch (IOException e) {
|
|
throw new PrismException("File I/O error reading from \"" + transFile + "\"");
|
|
} catch (NumberFormatException e) {
|
|
throw new PrismException("Error detected at line " + lineNum + " of transition matrix file \"" + transFile + "\"");
|
|
} catch (PrismException e) {
|
|
throw new PrismException("Error detected (" + e.getMessage() + ") at line " + lineNum + " of transition matrix file \"" + transFile + "\"");
|
|
}
|
|
// create modules file
|
|
modulesFile = new ModulesFile();
|
|
m = new Module("M");
|
|
dt = new DeclarationInt(Expression.Int(0), Expression.Int(numStates - 1));
|
|
d = new Declaration("x", dt);
|
|
d.setStart(Expression.Int(0));
|
|
m.addDeclaration(d);
|
|
modulesFile.addModule(m);
|
|
modulesFile.tidyUp();
|
|
|
|
return modulesFile;
|
|
}
|
|
}
|