Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SymbolicModelDescription.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string.hpp>
4
14
15namespace storm {
16namespace storage {
17
19 // Intentionally left empty.
20}
21
23 // Intentionally left empty.
24}
25
27 this->modelDescription = model;
28 return *this;
29}
30
32 this->modelDescription = program;
33 return *this;
34}
35
37 return static_cast<bool>(modelDescription);
38}
39
41 return modelDescription.get().which() == 0;
42}
43
45 return modelDescription.get().which() == 1;
46}
47
49 if (this->isJaniModel()) {
50 storm::jani::Model const& janiModel = this->asJaniModel();
51 switch (janiModel.getModelType()) {
60 default:
61 STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Expected other JANI model type.");
62 }
63 } else {
64 storm::prism::Program const& prismProgram = this->asPrismProgram();
65 switch (prismProgram.getModelType()) {
78 default:
79 STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Expected other PRISM model type.");
80 }
81 }
82}
83
85 if (this->isPrismProgram()) {
86 return this->asPrismProgram().getManager();
87 } else {
88 return this->asJaniModel().getManager();
89 }
90}
91
93 modelDescription = model;
94}
95
97 modelDescription = program;
98}
99
101 STORM_LOG_THROW(isJaniModel(), storm::exceptions::InvalidOperationException,
102 "Cannot retrieve JANI model, because the symbolic description has a different type.");
103 return boost::get<storm::jani::Model>(modelDescription.get());
104}
105
107 STORM_LOG_THROW(isJaniModel(), storm::exceptions::InvalidOperationException,
108 "Cannot retrieve JANI model, because the symbolic description has a different type.");
109 return boost::get<storm::jani::Model>(modelDescription.get());
110}
111
113 STORM_LOG_THROW(isPrismProgram(), storm::exceptions::InvalidOperationException,
114 "Cannot retrieve JANI model, because the symbolic description has a different type.");
115 return boost::get<storm::prism::Program>(modelDescription.get());
116}
117
119 STORM_LOG_THROW(isPrismProgram(), storm::exceptions::InvalidOperationException,
120 "Cannot retrieve JANI model, because the symbolic description has a different type.");
121 return boost::get<storm::prism::Program>(modelDescription.get());
122}
123
124std::vector<std::string> SymbolicModelDescription::getParameterNames() const {
125 std::vector<std::string> result;
126 if (isJaniModel()) {
127 for (auto const& c : asJaniModel().getUndefinedConstants()) {
128 result.push_back(c.get().getName());
129 }
130 } else {
131 for (auto const& c : asPrismProgram().getUndefinedConstants()) {
132 result.push_back(c.get().getName());
133 }
134 }
135 return result;
136}
137
139 if (this->isJaniModel()) {
140 return *this;
141 }
142 if (this->isPrismProgram()) {
143 return SymbolicModelDescription(this->asPrismProgram().toJani(makeVariablesGlobal, ""));
144 } else {
145 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot transform model description to the JANI format.");
146 }
147}
148
149std::pair<SymbolicModelDescription, std::vector<storm::jani::Property>> SymbolicModelDescription::toJani(std::vector<storm::jani::Property> const& properties,
150 bool makeVariablesGlobal) const {
151 if (this->isJaniModel()) {
152 return std::make_pair(*this, std::vector<storm::jani::Property>());
153 }
154 if (this->isPrismProgram()) {
155 auto modelProperties = this->asPrismProgram().toJani(properties, makeVariablesGlobal, "");
156 return std::make_pair(SymbolicModelDescription(modelProperties.first), modelProperties.second);
157 } else {
158 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot transform model description to the JANI format.");
159 }
160}
161
162SymbolicModelDescription SymbolicModelDescription::preprocess(std::string const& constantDefinitionString) const {
163 return this->preprocess(this->parseConstantDefinitions(constantDefinitionString));
164}
165
167 std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantDefinitions) const {
168 if (this->isJaniModel()) {
169 return SymbolicModelDescription(this->asJaniModel().preprocess(constantDefinitions));
170 } else if (this->isPrismProgram()) {
171 return SymbolicModelDescription(this->asPrismProgram().preprocess(constantDefinitions));
172 }
173 return *this;
174}
175
176std::map<storm::expressions::Variable, storm::expressions::Expression> SymbolicModelDescription::parseConstantDefinitions(
177 std::string const& constantDefinitionString) const {
178 if (this->isJaniModel()) {
179 return parseConstantDefinitionString(this->asJaniModel().getManager(), constantDefinitionString);
180 } else {
181 return parseConstantDefinitionString(this->asPrismProgram().getManager(), constantDefinitionString);
182 }
183}
184
186 if (this->isPrismProgram()) {
187 return this->asPrismProgram().hasUndefinedConstants();
188 } else {
189 return this->asJaniModel().hasUndefinedConstants();
190 }
191}
192
193std::vector<storm::expressions::Variable> SymbolicModelDescription::getUndefinedConstants() const {
194 std::vector<storm::expressions::Variable> result;
195 if (this->isPrismProgram()) {
196 std::vector<std::reference_wrapper<storm::prism::Constant const>> constants = this->asPrismProgram().getUndefinedConstants();
197 for (auto const& constant : constants) {
198 result.emplace_back(constant.get().getExpressionVariable());
199 }
200 } else {
201 std::vector<std::reference_wrapper<storm::jani::Constant const>> constants = this->asJaniModel().getUndefinedConstants();
202 for (auto const& constant : constants) {
203 result.emplace_back(constant.get().getExpressionVariable());
204 }
205 }
206 return result;
207}
208
209std::ostream& operator<<(std::ostream& out, SymbolicModelDescription const& model) {
210 if (model.isPrismProgram()) {
211 out << model.asPrismProgram();
212 } else if (model.isJaniModel()) {
213 out << model.asJaniModel();
214 } else {
215 out << "unkown symbolic model description";
216 }
217 return out;
218}
219
220std::ostream& operator<<(std::ostream& out, SymbolicModelDescription::ModelType const& type) {
221 switch (type) {
223 out << "dtmc";
224 break;
226 out << "ctmc";
227 break;
229 out << "mdp";
230 break;
232 out << "ma";
233 break;
235 out << "pomdp";
236 break;
238 out << "smg";
239 break;
240 }
241 return out;
242}
243
244std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::expressions::ExpressionManager const& manager,
245 std::string const& constantDefinitionString) {
246 std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
247 std::set<storm::expressions::Variable> definedConstants;
248
249 if (!constantDefinitionString.empty()) {
250 std::vector<std::string> definitions;
251 boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
252 for (auto& definition : definitions) {
253 boost::trim(definition);
254
255 std::size_t positionOfAssignmentOperator = definition.find('=');
256 STORM_LOG_THROW(positionOfAssignmentOperator != std::string::npos, storm::exceptions::WrongFormatException,
257 "Illegal constant definition string: syntax error.");
258
259 std::string constantName = definition.substr(0, positionOfAssignmentOperator);
260 boost::trim(constantName);
261 std::string value = definition.substr(positionOfAssignmentOperator + 1);
262 boost::trim(value);
263
264 if (manager.hasVariable(constantName)) {
265 auto const& variable = manager.getVariable(constantName);
266 STORM_LOG_THROW(definedConstants.find(variable) == definedConstants.end(), storm::exceptions::WrongFormatException,
267 "Illegally trying to define constant '" << constantName << "' twice.");
268 definedConstants.insert(variable);
269
270 if (manager.hasVariable(value)) {
271 auto const& valueVariable = manager.getVariable(value);
273 variable.getType() == valueVariable.getType(), storm::exceptions::WrongFormatException,
274 "Illegally trying to define constant '" << constantName << "' by constant '" << valueVariable.getName() << " of different type.");
275 constantDefinitions[variable] = valueVariable.getExpression();
276 } else if (variable.hasBooleanType()) {
277 if (value == "true") {
278 constantDefinitions[variable] = manager.boolean(true);
279 } else if (value == "false") {
280 constantDefinitions[variable] = manager.boolean(false);
281 } else {
282 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Illegal value for boolean constant: " << value << ".");
283 }
284 } else if (variable.hasIntegerType()) {
285 std::size_t position = 0;
286 int_fast64_t integerValue = 0;
287 bool valid = true;
288 try {
289 integerValue = std::stoll(value, &position);
290 } catch (std::exception&) {
291 valid = false;
292 }
293 STORM_LOG_THROW(valid && position == value.size(), storm::exceptions::WrongFormatException,
294 "Illegal value for integer constant: " << value << ".");
295 constantDefinitions[variable] = manager.integer(integerValue);
296 } else if (variable.hasRationalType()) {
297 try {
298 storm::RationalNumber rationalValue = storm::utility::convertNumber<storm::RationalNumber>(value);
299 constantDefinitions[variable] = manager.rational(rationalValue);
300 } catch (std::exception& e) {
301 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException,
302 "Illegal constant definition string '" << constantName << "=" << value << "': " << e.what() << ".");
303 }
304 }
305 } else {
306 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException,
307 "Illegal constant definition string: unknown undefined constant '" << constantName << "'.");
308 }
309 }
310 }
311
312 return constantDefinitions;
313}
314} // namespace storage
315} // namespace storm
This class is responsible for managing a set of typed variables and all expressions using these varia...
bool hasUndefinedConstants() const
Retrieves whether the model still has undefined constants.
Definition Model.cpp:1079
storm::expressions::ExpressionManager & getManager() const
Retrieves the expression manager responsible for the expressions in the model.
Definition Model.cpp:109
ModelType const & getModelType() const
Retrieves the type of the model.
Definition Model.cpp:117
std::vector< std::reference_wrapper< Constant const > > getUndefinedConstants() const
Retrieves all undefined constants of the model.
Definition Model.cpp:1088
ModelType getModelType() const
Retrieves the model type of the model.
Definition Program.cpp:243
std::vector< std::reference_wrapper< Constant const > > getUndefinedConstants() const
Retrieves the undefined constants in the program.
Definition Program.cpp:364
storm::expressions::ExpressionManager & getManager() const
Retrieves the manager responsible for the expressions of this program.
Definition Program.cpp:2388
bool hasUndefinedConstants() const
Retrieves whether there are undefined constants of any type in the program.
Definition Program.cpp:281
storm::jani::Model toJani(bool allVariablesGlobal=true, std::string suffix="") const
Converts the PRISM model into an equivalent JANI model.
Definition Program.cpp:2350
std::map< storm::expressions::Variable, storm::expressions::Expression > parseConstantDefinitions(std::string const &constantDefinitionString) const
SymbolicModelDescription & operator=(storm::jani::Model const &model)
storm::prism::Program const & asPrismProgram() const
std::vector< storm::expressions::Variable > getUndefinedConstants() const
storm::expressions::ExpressionManager & getManager() const
std::vector< std::string > getParameterNames() const
SymbolicModelDescription toJani(bool makeVariablesGlobal=true) const
void setModel(storm::jani::Model const &model)
storm::jani::Model const & asJaniModel() const
SymbolicModelDescription preprocess(std::string const &constantDefinitionString="") const
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
std::map< storm::expressions::Variable, storm::expressions::Expression > parseConstantDefinitionString(storm::expressions::ExpressionManager const &manager, std::string const &constantDefinitionString)
Parses a comma-separated string of constant definitions (e.g.
std::ostream & operator<<(std::ostream &out, ParameterRegion< ParametricType > const &region)
TargetType convertNumber(SourceType const &number)