Browse Source

Further work on adapting explicit model generator to new PRISM classes.

Former-commit-id: 01cefceb52
tempestpy_adaptions
dehnert 11 years ago
parent
commit
d9345b19e9
  1. 78
      src/adapters/ExplicitModelAdapter.h
  2. 12
      src/parser/PrismParser.cpp
  3. 1
      src/storage/expressions/SimpleValuation.h
  4. 16
      src/storage/prism/Program.cpp
  5. 19
      src/storage/prism/Program.h
  6. 2
      src/utility/IRUtility.h

78
src/adapters/ExplicitModelAdapter.h

@ -15,6 +15,7 @@
#include <queue>
#include <boost/functional/hash.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/algorithm/string.hpp>
#include "src/storage/prism/Program.h"
#include "src/storage/expressions/SimpleValuation.h"
@ -72,6 +73,62 @@ namespace storm {
std::vector<boost::container::flat_set<uint_fast64_t>> choiceLabeling;
};
static std::map<std::string, storm::expressions::Expression> parseConstantDefinitionString(storm::prism::Program const& program, std::string const& constantDefinitionString) {
std::map<std::string, storm::expressions::Expression> constantDefinitions;
std::set<std::string> definedConstants;
if (!constantDefinitionString.empty()) {
// Parse the string that defines the undefined constants of the model and make sure that it contains exactly
// one value for each undefined constant of the model.
std::vector<std::string> definitions;
boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
for (auto& definition : definitions) {
boost::trim(definition);
// Check whether the token could be a legal constant definition.
uint_fast64_t positionOfAssignmentOperator = definition.find('=');
if (positionOfAssignmentOperator == std::string::npos) {
throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: syntax error.";
}
// Now extract the variable name and the value from the string.
std::string constantName = definition.substr(0, positionOfAssignmentOperator);
boost::trim(constantName);
std::string value = definition.substr(positionOfAssignmentOperator + 1);
boost::trim(value);
// Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
if (program.hasConstant(constantName)) {
// Get the actual constant and check whether it's in fact undefined.
auto const& constant = program.getConstant(constantName);
LOG_THROW(!constant.isDefined(), storm::exceptions::InvalidArgumentException, "Illegally trying to define already defined constant '" << constantName <<"'.");
LOG_THROW(definedConstants.find(constantName) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
definedConstants.insert(constantName);
if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Bool) {
if (value == "true") {
constantDefinitions[constantName] = storm::expressions::Expression::createTrue();
} else if (value == "false") {
constantDefinitions[constantName] = storm::expressions::Expression::createFalse();
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
}
} else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Int) {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[constantName] = storm::expressions::Expression::createIntegerLiteral(integerValue);
} else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Double) {
double doubleValue = std::stod(value);
constantDefinitions[constantName] = storm::expressions::Expression::createDoubleLiteral(doubleValue);
}
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: unknown undefined constant " << constantName << ".";
}
}
}
return constantDefinitions;
}
/*!
* Convert the program given at construction time to an abstract model. The type of the model is the one
* specified in the program. The given reward model name selects the rewards that the model will contain.
@ -86,7 +143,11 @@ namespace storm {
*/
static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::prism::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
// Start by defining the undefined constants in the model.
// First, we need to parse the constant definition string.
std::map<std::string, storm::expressions::Expression> constantDefinitions = parseConstantDefinitionString(program, constantDefinitionString);
storm::prism::Program definedProgram = program.defineUndefinedConstants(constantDefinitions);
LOG_THROW(!definedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
ModelComponents modelComponents = buildModelComponents(definedProgram, rewardModelName);
@ -118,13 +179,12 @@ namespace storm {
* Applies an update to the given state and returns the resulting new state object. This methods does not
* modify the given state but returns a new one.
*
* @param variableInformation A structure with information about the variables in the program.
* @params state The state to which to apply the update.
* @params update The update to apply.
* @return The resulting state.
*/
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::prism::Update const& update) {
return applyUpdate(variableInformation, state, state, update);
static StateType* applyUpdate(StateType const* state, storm::prism::Update const& update) {
return applyUpdate(state, state, update);
}
/*!
@ -132,14 +192,22 @@ namespace storm {
* over the variable values of the given base state. This methods does not modify the given state but
* returns a new one.
*
* @param variableInformation A structure with information about the variables in the program.
* @param state The state to which to apply the update.
* @param baseState The state used for evaluating the update.
* @param update The update to apply.
* @return The resulting state.
*/
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
static StateType* applyUpdate(StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
StateType* newState = new StateType(*state);
for (auto const& assignment : update.getAssignments()) {
switch (assignment.getExpression().getReturnType()) {
case storm::expressions::ExpressionReturnType::Bool: newState->setBooleanValue(assignment.getVariableName(), assignment.getExpression().evaluateAsBool(*baseState)); break;
case storm::expressions::ExpressionReturnType::Int:
int_fast64_t newValue = assignment.getExpression().evaluateAsInt(*baseState));
newState->setIntegerValue(assignment.getVariableName(), assignment.getExpression().evaluateAsInt(*baseState)); break;
default: LOG_ASSERT(false, "Invalid type of assignment.");
}
}
for (auto variableAssignmentPair : update.getBooleanAssignments()) {
setValue(newState, variableInformation.booleanVariableToIndexMap.at(variableAssignmentPair.first), variableAssignmentPair.second.getExpression()->getValueAsBool(baseState));
}

12
src/parser/PrismParser.cpp

@ -464,32 +464,32 @@ namespace storm {
storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename());
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
}
storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {

1
src/storage/expressions/SimpleValuation.h

@ -42,6 +42,7 @@ namespace storm {
SimpleValuation(SimpleValuation&&) = default;
SimpleValuation& operator=(SimpleValuation const&) = default;
SimpleValuation& operator=(SimpleValuation&&) = default;
virtual ~SimpleValuation() = default;
/*!
* Compares two simple valuations wrt. equality.

16
src/storage/prism/Program.cpp

@ -5,7 +5,7 @@
namespace storm {
namespace prism {
Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), constantToIndexMap(), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
this->createMappings();
}
@ -22,6 +22,15 @@ namespace storm {
return true;
}
bool Program::hasConstant(std::string const& constantName) const {
return this->constantToIndexMap.find(constantName) != this->constantToIndexMap.end();
}
Constant const& Program::getConstant(std::string const& constantName) const {
auto const& constantIndexPair = this->constantToIndexMap.find(constantName);
return this->getConstants()[constantIndexPair->second];
}
std::vector<Constant> const& Program::getConstants() const {
return this->constants;
}
@ -158,7 +167,10 @@ namespace storm {
}
void Program::createMappings() {
// Build the mappings for global variables, formulas, modules, reward models and labels.
// Build the mappings for constants, global variables, formulas, modules, reward models and labels.
for (uint_fast64_t constantIndex = 0; constantIndex < this->getNumberOfConstants(); ++constantIndex) {
this->constantToIndexMap[this->getConstants()[constantIndex].getConstantName()] = constantIndex;
}
for (uint_fast64_t globalVariableIndex = 0; globalVariableIndex < this->getNumberOfGlobalBooleanVariables(); ++globalVariableIndex) {
this->globalBooleanVariableToIndexMap[this->getGlobalBooleanVariables()[globalVariableIndex].getName()] = globalVariableIndex;
}

19
src/storage/prism/Program.h

@ -65,6 +65,22 @@ namespace storm {
*/
bool hasUndefinedConstants() const;
/*!
* Retrieves whether the given constant exists in the program.
*
* @param constantName The name of the constant to search.
* @return True iff the constant exists in the program.
*/
bool hasConstant(std::string const& constantName) const;
/*!
* Retrieves the constant with the given name if it exists.
*
* @param constantName The name of the constant to retrieve.
* @return The constant with the given name if it exists.
*/
Constant const& getConstant(std::string const& constantName) const;
/*!
* Retrieves all constants defined in the program.
*
@ -269,6 +285,9 @@ namespace storm {
// The undefined constants of the program.
std::vector<Constant> constants;
// A mapping from constant names to their corresponding indices.
std::map<std::string, uint_fast64_t> constantToIndexMap;
// The global boolean variables.
std::vector<BooleanVariable> globalBooleanVariables;

2
src/utility/IRUtility.h

@ -11,7 +11,7 @@
#include <boost/algorithm/string.hpp>
#include "src/storage/LabeledValues.h"
#include "src/ir/IR.h"
#include "src/storage/prism/Program.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "log4cplus/logger.h"

Loading…
Cancel
Save