#include "src/storage/prism/Module.h" #include "src/exceptions/ExceptionMacros.h" #include "src/exceptions/OutOfRangeException.h" #include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace prism { Module::Module(std::string const& moduleName, std::vector const& booleanVariables, std::vector const& integerVariables, std::vector const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), booleanVariableToIndexMap(), integerVariables(integerVariables), integerVariableToIndexMap(), commands(commands), actions(), actionsToCommandIndexMap() { // Initialize the internal mappings for fast information retrieval. this->createMappings(); } std::size_t Module::getNumberOfBooleanVariables() const { return this->booleanVariables.size(); } std::size_t Module::getNumberOfIntegerVariables() const { return this->integerVariables.size(); } storm::prism::BooleanVariable const& Module::getBooleanVariable(std::string const& variableName) const { auto const& nameIndexPair = this->booleanVariableToIndexMap.find(variableName); LOG_THROW(nameIndexPair != this->booleanVariableToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Unknown boolean variable '" << variableName << "'."); return this->getBooleanVariables()[nameIndexPair->second]; } std::vector const& Module::getBooleanVariables() const { return this->booleanVariables; } storm::prism::IntegerVariable const& Module::getIntegerVariable(std::string const& variableName) const { auto const& nameIndexPair = this->integerVariableToIndexMap.find(variableName); LOG_THROW(nameIndexPair != this->integerVariableToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Unknown integer variable '" << variableName << "'."); return this->getIntegerVariables()[nameIndexPair->second]; } std::vector const& Module::getIntegerVariables() const { return this->integerVariables; } std::size_t Module::getNumberOfCommands() const { return this->commands.size(); } std::size_t Module::getNumberOfUpdates() const { std::size_t result = 0; for (auto const& command : this->getCommands()) { result += command.getNumberOfUpdates(); } return result; } storm::prism::Command const& Module::getCommand(uint_fast64_t index) const { return this->commands[index]; } std::vector const& Module::getCommands() const { return this->commands; } std::string const& Module::getName() const { return this->moduleName; } std::set const& Module::getActions() const { return this->actions; } bool Module::hasAction(std::string const& action) const { auto const& actionEntry = this->actions.find(action); return actionEntry != this->actions.end(); } std::set const& Module::getCommandIndicesByAction(std::string const& action) const { auto actionsCommandSetPair = this->actionsToCommandIndexMap.find(action); if (actionsCommandSetPair != this->actionsToCommandIndexMap.end()) { return actionsCommandSetPair->second; } LOG_THROW(false, storm::exceptions::OutOfRangeException, "Action name '" << action << "' does not exist in module."); } void Module::createMappings() { // Clear the current mappings. this->actionsToCommandIndexMap.clear(); this->booleanVariableToIndexMap.clear(); this->integerVariableToIndexMap.clear(); // Create the mappings for the variables. for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { this->booleanVariableToIndexMap[this->getBooleanVariables()[i].getName()] = i; } for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { this->integerVariableToIndexMap[this->getIntegerVariables()[i].getName()] = i; } // Add the mapping for all commands. for (uint_fast64_t i = 0; i < this->commands.size(); i++) { std::string const& action = this->commands[i].getActionName(); if (action != "") { if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) { this->actionsToCommandIndexMap.emplace(action, std::set()); } this->actionsToCommandIndexMap[action].insert(i); this->actions.insert(action); } } // For all actions that are "in the module", but for which no command exists, we add the mapping to an empty // set of commands. for (auto const& action : this->actions) { if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) { this->actionsToCommandIndexMap[action] = std::set(); } } } Module Module::restrictCommands(boost::container::flat_set const& indexSet) const { // First construct the new vector of commands. std::vector newCommands; for (auto const& command : commands) { if (indexSet.find(command.getGlobalIndex()) != indexSet.end()) { newCommands.push_back(command); } } return Module(this->getName(), this->getBooleanVariables(), this->getIntegerVariables(), newCommands); } Module Module::substitute(std::map const& substitution) const { std::vector newBooleanVariables; newBooleanVariables.reserve(this->getNumberOfBooleanVariables()); for (auto const& booleanVariable : this->getBooleanVariables()) { newBooleanVariables.emplace_back(booleanVariable.substitute(substitution)); } std::vector newIntegerVariables; newBooleanVariables.reserve(this->getNumberOfIntegerVariables()); for (auto const& integerVariable : this->getIntegerVariables()) { newIntegerVariables.emplace_back(integerVariable.substitute(substitution)); } std::vector newCommands; newCommands.reserve(this->getNumberOfCommands()); for (auto const& command : this->getCommands()) { newCommands.emplace_back(command.substitute(substitution)); } return Module(this->getName(), newBooleanVariables, newIntegerVariables, newCommands, this->getFilename(), this->getLineNumber()); } std::ostream& operator<<(std::ostream& stream, Module const& module) { stream << "module " << module.getName() << std::endl; for (auto const& booleanVariable : module.getBooleanVariables()) { stream << "\t" << booleanVariable << std::endl; } for (auto const& integerVariable : module.getIntegerVariables()) { stream << "\t" << integerVariable << std::endl; } for (auto const& command : module.getCommands()) { stream << "\t" << command << std::endl; } stream << "endmodule" << std::endl; return stream; } } // namespace ir } // namespace storm