Browse Source

Support for parsing jani model from string

tempestpy_adaptions
Matthias Volk 4 years ago
parent
commit
c12c0352f7
No known key found for this signature in database GPG Key ID: 83A57678F739FCD3
  1. 25
      src/storm-parsers/api/model_descriptions.cpp
  2. 2
      src/storm-parsers/api/model_descriptions.h
  3. 8
      src/storm-parsers/parser/JaniParser.cpp
  4. 1
      src/storm-parsers/parser/JaniParser.h
  5. 385
      src/test/storm/parser/JaniParserTest.cpp

25
src/storm-parsers/api/model_descriptions.cpp

@ -22,10 +22,7 @@ namespace storm {
return program;
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModel(std::string const& filename, boost::optional<std::vector<std::string>> const& propertyFilter) {
bool parseProperties = !propertyFilter.is_initialized() || !propertyFilter.get().empty();
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> modelAndFormulae = storm::parser::JaniParser<storm::RationalNumber>::parse(filename, parseProperties);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> filterProperties(std::pair<storm::jani::Model, std::vector<storm::jani::Property>>& modelAndFormulae, boost::optional<std::vector<std::string>> const& propertyFilter) {
// eliminate unselected properties.
if (propertyFilter.is_initialized()) {
std::vector<storm::jani::Property> newProperties;
@ -46,13 +43,31 @@ namespace storm {
modelAndFormulae.first.checkValid();
return modelAndFormulae;
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModel(std::string const& filename, boost::optional<std::vector<std::string>> const& propertyFilter) {
bool parseProperties = !propertyFilter.is_initialized() || !propertyFilter.get().empty();
auto modelAndFormulae = storm::parser::JaniParser<storm::RationalNumber>::parse(filename, parseProperties);
return filterProperties(modelAndFormulae, propertyFilter);
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModelFromString(std::string const& jsonstring, boost::optional<std::vector<std::string>> const& propertyFilter) {
bool parseProperties = !propertyFilter.is_initialized() || !propertyFilter.get().empty();
auto modelAndFormulae = storm::parser::JaniParser<storm::RationalNumber>::parseFromString(jsonstring, parseProperties);
return filterProperties(modelAndFormulae, propertyFilter);
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModel(std::string const& filename, storm::jani::ModelFeatures const& supportedFeatures, boost::optional<std::vector<std::string>> const& propertyFilter) {
auto modelAndFormulae = parseJaniModel(filename, propertyFilter);
simplifyJaniModel(modelAndFormulae.first, modelAndFormulae.second, supportedFeatures);
return modelAndFormulae;
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModelFromString(std::string const& jsonstring, storm::jani::ModelFeatures const& supportedFeatures, boost::optional<std::vector<std::string>> const& propertyFilter) {
auto modelAndFormulae = parseJaniModelFromString(jsonstring, propertyFilter);
simplifyJaniModel(modelAndFormulae.first, modelAndFormulae.second, supportedFeatures);
return modelAndFormulae;
}
void simplifyJaniModel(storm::jani::Model& model, std::vector<storm::jani::Property>& properties , storm::jani::ModelFeatures const& supportedFeatures) {
auto nonEliminatedFeatures = model.restrictToFeatures(supportedFeatures, properties);
STORM_LOG_THROW(nonEliminatedFeatures.empty(), storm::exceptions::NotSupportedException, "The used model feature(s) " << nonEliminatedFeatures.toString() << " is/are not in the list of supported features.");

2
src/storm-parsers/api/model_descriptions.h

@ -21,6 +21,8 @@ namespace storm {
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModel(std::string const& filename, boost::optional<std::vector<std::string>> const& propertyFilter = boost::none);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModel(std::string const& filename, storm::jani::ModelFeatures const& allowedFeatures, boost::optional<std::vector<std::string>> const& propertyFilter = boost::none);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModelFromString(std::string const& jsonstring, boost::optional<std::vector<std::string>> const& propertyFilter = boost::none);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseJaniModelFromString(std::string const& jsonstring, storm::jani::ModelFeatures const& allowedFeatures, boost::optional<std::vector<std::string>> const& propertyFilter = boost::none);
void simplifyJaniModel(storm::jani::Model& model, std::vector<storm::jani::Property>& properties , storm::jani::ModelFeatures const& supportedFeatures);
}

8
src/storm-parsers/parser/JaniParser.cpp

@ -84,7 +84,13 @@ namespace storm {
}
template <typename ValueType>
JaniParser<ValueType>::JaniParser(std::string const& jsonstring) {
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> JaniParser<ValueType>::parseFromString(std::string const& jsonstring, bool parseProperties) {
JaniParser parser(jsonstring);
return parser.parseModel(parseProperties);
}
template <typename ValueType>
JaniParser<ValueType>::JaniParser(std::string const& jsonstring) : expressionManager(new storm::expressions::ExpressionManager()) {
parsedStructure = Json::parse(jsonstring);
}

1
src/storm-parsers/parser/JaniParser.h

@ -42,6 +42,7 @@ namespace storm {
JaniParser() : expressionManager(new storm::expressions::ExpressionManager()) {}
JaniParser(std::string const& jsonstring);
static std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parse(std::string const& path, bool parseProperties = true);
static std::pair<storm::jani::Model, std::vector<storm::jani::Property>> parseFromString(std::string const& jsonstring, bool parseProperties = true);
protected:
void readFile(std::string const& path);

385
src/test/storm/parser/JaniParserTest.cpp

@ -0,0 +1,385 @@
#include <storm/exceptions/InvalidArgumentException.h>
#include "test/storm_gtest.h"
#include "storm-config.h"
#include "storm-parsers/parser/JaniParser.h"
#include "storm-parsers/api/model_descriptions.h"
#include "storm/storage/jani/Property.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/ModelType.h"
TEST(JaniParser, DieExampleTest) {
std::string testInput = R"({
"jani-version": 1,
"name": "die.jani",
"type": "dtmc",
"features": [ "derived-operators" ],
"variables": [
{
"name": "s",
"type": {
"base": "int",
"kind": "bounded",
"lower-bound": 0,
"upper-bound": 7
},
"initial-value": 0
},
{
"name": "d",
"type": {
"base": "int",
"kind": "bounded",
"lower-bound": 0,
"upper-bound": 6
},
"initial-value": 0
}
],
"properties": [
{
"name": "Probability to throw a six",
"expression": {
"op": "filter",
"fun": "max",
"states": { "op": "initial" },
"values": {
"op": "Pmin",
"exp": {
"op": "U",
"left": true,
"right": {
"op": "",
"left": {
"op": "=",
"left": "s",
"right": 7
},
"right": {
"op": "=",
"left": "d",
"right": 6
}
}
}
}
}
},
{
"name": "Expected number of coin flips",
"expression": {
"op": "filter",
"fun": "max",
"states": { "op": "initial" },
"values": {
"op": "Emin",
"accumulate": [ "steps" ],
"exp": 1,
"reach": {
"op": "=",
"left": "s",
"right": 7
}
}
}
}
],
"automata": [
{
"name": "die",
"locations": [{ "name": "l" }],
"initial-locations": ["l"],
"edges": [
{
"location": "l",
"guard": {
"exp": {
"op": "=",
"left": "s",
"right": 0
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 1
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 2
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 1
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 3
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 4
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 2
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 5
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 6
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 3
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 1
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 1
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 4
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 2
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 3
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 5
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 4
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 5
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 6
}
},
"destinations": [
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 2
}
]
},
{
"location": "l",
"probability": { "exp": 0.5 },
"assignments": [
{
"ref": "s",
"value": 7
},
{
"ref": "d",
"value": 6
}
]
}
]
},
{
"location": "l",
"guard": {
"exp": {
"left": "s",
"op": "=",
"right": 7
}
},
"destinations": [
{
"location": "l",
"assignments": [
{
"ref": "s",
"value": 7
}
]
}
]
}
]
}
],
"system": {
"elements": [ { "automaton": "die" } ]
}
})";
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> result;
EXPECT_NO_THROW(result = storm::api::parseJaniModelFromString(testInput));
EXPECT_EQ(storm::jani::ModelType::DTMC, result.first.getModelType());
EXPECT_TRUE(result.first.hasGlobalVariable("s"));
EXPECT_EQ(1ul, result.first.getNumberOfAutomata());
}
TEST(JaniParser, UnassignedVariablesTest) {
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> result;
EXPECT_NO_THROW(result = storm::api::parseJaniModel(STORM_TEST_RESOURCES_DIR "/mdp/unassigned-variables.jani"));
EXPECT_EQ(storm::jani::ModelType::MDP, result.first.getModelType());
EXPECT_TRUE(result.first.hasConstant("c"));
EXPECT_EQ(2ul, result.first.getNumberOfAutomata());
}
Loading…
Cancel
Save