#pragma once #include "storm/storage/jani/Constant.h" #include "storm/storage/jani/FunctionDefinition.h" #include "storm/storage/jani/LValue.h" #include "storm/logic/Formula.h" #include "storm/logic/Bound.h" #include "storm/logic/RewardAccumulation.h" #include "storm/exceptions/FileIoException.h" #include "storm/storage/expressions/ExpressionManager.h" #include "storm/adapters/JsonAdapter.h" namespace storm { namespace jani { class Model; class Automaton; class Variable; class Composition; class Property; struct PropertyInterval; } namespace logic { enum class FormulaContext; } namespace parser { /* * The JANI format parser. * Parses Models and Properties */ template class JaniParser { public: typedef std::vector PropertyVector; typedef std::unordered_map VariablesMap; typedef std::unordered_map ConstantsMap; typedef std::unordered_map FunctionsMap; typedef storm::json Json; JaniParser() : expressionManager(new storm::expressions::ExpressionManager()) {} JaniParser(std::string const& jsonstring); static std::pair> parse(std::string const& path, bool parseProperties = true); static std::pair> parseFromString(std::string const& jsonstring, bool parseProperties = true); protected: void readFile(std::string const& path); struct Scope { Scope(std::string description = "global", ConstantsMap const* constants = nullptr, VariablesMap const* globalVars = nullptr, FunctionsMap const* globalFunctions = nullptr, VariablesMap const* localVars = nullptr, FunctionsMap const* localFunctions = nullptr) : description(description) , constants(constants), globalVars(globalVars), globalFunctions(globalFunctions), localVars(localVars), localFunctions(localFunctions) {}; Scope(Scope const& other) = default; std::string description; ConstantsMap const* constants; VariablesMap const* globalVars; FunctionsMap const* globalFunctions; VariablesMap const* localVars; FunctionsMap const* localFunctions; Scope refine(std::string const& prependedDescription = "") const { Scope res(*this); if (prependedDescription != "") { res.description = "'" + prependedDescription + "' at " + res.description; } return res; } Scope& clearVariables() { this->globalVars = nullptr; this->localVars = nullptr; return *this; } }; std::pair> parseModel(bool parseProperties = true); storm::jani::Property parseProperty(storm::jani::Model& model, storm::json const& propertyStructure, Scope const& scope); storm::jani::Automaton parseAutomaton(storm::json const& automatonStructure, storm::jani::Model const& parentModel, Scope const& scope); struct ParsedType { enum class BasicType {Bool, Int, Real}; boost::optional basicType; boost::optional> bounds; std::unique_ptr arrayBase; storm::expressions::Type expressionType; }; void parseType(ParsedType& result, storm::json const& typeStructure, std::string variableName, Scope const& scope); storm::jani::LValue parseLValue(storm::json const& lValueStructure, Scope const& scope); std::shared_ptr parseVariable(storm::json const& variableStructure, bool requireInitialValues, Scope const& scope, std::string const& namePrefix = ""); storm::expressions::Expression parseExpression(storm::json const& expressionStructure, Scope const& scope, bool returnNoneOnUnknownOpString = false, std::unordered_map const& auxiliaryVariables = {}); private: std::shared_ptr parseConstant(storm::json const& constantStructure, Scope const& scope); storm::jani::FunctionDefinition parseFunctionDefinition(storm::json const& functionDefinitionStructure, Scope const& scope, bool firstPass, std::string const& parameterNamePrefix = ""); /** * Helper for parsing the actions of a model. */ void parseActions(storm::json const& actionStructure, storm::jani::Model& parentModel); std::shared_ptr parseFormula(storm::jani::Model& model, storm::json const& propertyStructure, storm::logic::FormulaContext formulaContext, Scope const& scope, boost::optional bound = boost::none); std::vector parseUnaryExpressionArguments(storm::json const& expressionStructure, std::string const& opstring, Scope const& scope, bool returnNoneOnUnknownOpString = false, std::unordered_map const& auxiliaryVariables = {}); std::vector parseBinaryExpressionArguments(storm::json const& expressionStructure, std::string const& opstring, Scope const& scope, bool returnNoneOnUnknownOpString = false, std::unordered_map const& auxiliaryVariables = {}); std::vector> parseUnaryFormulaArgument(storm::jani::Model& model, storm::json const& propertyStructure, storm::logic::FormulaContext formulaContext, std::string const& opstring, Scope const& scope); std::vector> parseBinaryFormulaArguments(storm::jani::Model& model, storm::json const& propertyStructure, storm::logic::FormulaContext formulaContext, std::string const& opstring, Scope const& scope); storm::jani::PropertyInterval parsePropertyInterval(storm::json const& piStructure, Scope const& scope); storm::logic::RewardAccumulation parseRewardAccumulation(storm::json const& accStructure, std::string const& context); std::shared_ptr parseComposition(storm::json const& compositionStructure); storm::expressions::Variable getVariableOrConstantExpression(std::string const& ident, Scope const& scope, std::unordered_map const& auxiliaryVariables = {}); /** * The overall structure currently under inspection. */ storm::json parsedStructure; /** * The expression manager to be used. */ std::shared_ptr expressionManager; std::set labels = {}; bool allowRecursion = true; ////////// // Default values -- assumptions from JANI. ////////// static const bool defaultVariableTransient; static const bool defaultBooleanInitialValue; static const ValueType defaultRationalInitialValue; static const int64_t defaultIntegerInitialValue; static const std::set unsupportedOpstrings; }; } }