Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ValueParser.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string.hpp>
4#include <boost/lexical_cast.hpp>
5
13
14namespace storm {
15namespace parser {
16
17template<typename ValueType>
18ValueParser<ValueType>::ParametricData::ParametricData()
19 : manager(new storm::expressions::ExpressionManager()),
20 parser(std::make_unique<ExpressionParser>(*manager)),
21 evaluator(new storm::expressions::ExpressionEvaluator<storm::RationalFunction>(*manager)) {
22 // Set empty mapping to enable expression creation even without parameters
23 parser->setIdentifierMapping(identifierMapping);
24}
25
26template<typename ValueType>
27ValueParser<ValueType>::ParametricData::~ParametricData() = default;
28
29template<typename ValueType>
30void ValueParser<ValueType>::addParameter(std::string const& parameter) {
31 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build (Have you checked storm-pars?).");
32}
33
34template<>
35void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) {
36 storm::expressions::Variable var = data.manager->declareRationalVariable(parameter);
37 data.identifierMapping.emplace(var.getName(), var);
38 data.parser->setIdentifierMapping(data.identifierMapping);
39 STORM_LOG_TRACE("Added parameter: " << var.getName());
40}
41
42template<>
44 storm::RationalFunction rationalFunction = data.evaluator->asRational(data.parser->parseFromString(value));
45 STORM_LOG_TRACE("Parsed expression: " << rationalFunction);
46 return rationalFunction;
47}
48
49template<typename ValueType>
50ValueType ValueParser<ValueType>::parseValue(std::string const& value) const {
51 return parseNumber<ValueType>(value);
52}
53
54template<typename NumberType>
55NumberType parseNumber(std::string const& value) {
56 NumberType result;
57 if (!parseNumber(value, result)) {
58 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse value '" << value << "' into " << typeid(NumberType).name() << ".");
59 }
60 return result;
61}
62
63bool parseDouble(std::string const& value, double& result) {
64 if (boost::conversion::try_lexical_convert(value, result)) {
65 return true;
66 } else {
67 // Try as rational number
68 storm::RationalNumber rationalResult;
69 if (parseNumber(value, rationalResult)) {
70 result = storm::utility::convertNumber<double>(rationalResult);
71 return true;
72 } else {
73 return false;
74 }
75 }
76}
77bool parseInterval(std::string const& value, storm::Interval& result) {
78 // Try whether it is a constant.
79 if (double pointResult; parseNumber(value, pointResult)) {
80 result = storm::Interval(pointResult);
81 return true;
82 }
83
84 std::string intermediate = value;
85 boost::trim(intermediate);
86 carl::BoundType leftBound;
87 carl::BoundType rightBound;
88 if (intermediate.front() == '(') {
89 leftBound = carl::BoundType::STRICT;
90 } else if (intermediate.front() == '[') {
91 leftBound = carl::BoundType::WEAK;
92 } else {
93 return false; // Expect start with '(' or '['.
94 }
95 if (intermediate.back() == ')') {
96 rightBound = carl::BoundType::STRICT;
97 } else if (intermediate.back() == ']') {
98 rightBound = carl::BoundType::WEAK;
99 } else {
100 return false; // Expected end with ')' or ']'.
101 }
102 intermediate = intermediate.substr(1, intermediate.size() - 2);
103
104 std::vector<std::string> words;
105 boost::split(words, intermediate, boost::is_any_of(","));
106 if (words.size() != 2) {
107 return false; // Did not find exactly one comma.
108 }
109 double leftVal, rightVal;
110 boost::trim(words[0]);
111 if (!parseNumber(words[0], leftVal)) {
112 return false; // lower value of interval invalid.
113 }
114 boost::trim(words[1]);
115 if (!parseNumber(words[1], rightVal)) {
116 return false; // upper value of interval invalid.
117 }
118 result = storm::Interval(leftVal, leftBound, rightVal, rightBound);
119 return true;
120}
121
122template<typename NumberType>
123bool parseNumber(std::string const& value, NumberType& result) {
124 if constexpr (std::is_same_v<NumberType, double>) {
125 return parseDouble(value, result);
126 } else if constexpr (std::is_same_v<NumberType, storm::RationalNumber>) {
127 return carl::try_parse(value, result);
128 } else if constexpr (std::is_same_v<NumberType, storm::Interval>) {
129 return parseInterval(value, result);
130 } else {
131 return boost::conversion::try_lexical_convert(value, result);
132 }
133}
134
135// Template instantiations.
136template class ValueParser<double>;
137template class ValueParser<storm::RationalNumber>;
138template class ValueParser<storm::RationalFunction>;
139template class ValueParser<storm::Interval>;
140
141template std::size_t parseNumber<std::size_t>(std::string const&);
142
143} // namespace parser
144} // namespace storm
Variable declareRationalVariable(std::string const &name, bool auxiliary=false)
Declares a new rational variable with a name that must not yet exist and its corresponding type.
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
Parser for values according to their ValueType.
Definition ValueParser.h:23
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
NumberType parseNumber(std::string const &value)
Parse number from string.
bool parseDouble(std::string const &value, double &result)
bool parseInterval(std::string const &value, storm::Interval &result)
SettingsManager const & manager()
Retrieves the settings manager.
carl::Interval< double > Interval
Interval type.
carl::RationalFunction< Polynomial, true > RationalFunction