Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DirectEncodingParser.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string.hpp>
4#include <iostream>
5#include <istream>
6#include <regex>
7#include <sstream>
8#include <string>
9
20#include "storm/io/file.h"
25
26namespace storm::parser {
27
28namespace detail {
29
30DirectEncodingValueType valueTypeFromString(std::string const& valueTypeStr) {
31 if (valueTypeStr == "double") {
33 } else if (valueTypeStr == "double-interval") {
35 } else if (valueTypeStr == "rational") {
37 } else if (valueTypeStr == "rational-interval") {
39 } else if (valueTypeStr == "parametric") {
41 } else {
42 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Unknown value type '" << valueTypeStr << "'.");
43 }
44}
45
46std::string toString(DirectEncodingValueType const& vt) {
47 using enum DirectEncodingValueType;
48 switch (vt) {
49 case Default:
50 return "default";
51 case Double:
52 return "double";
53 case DoubleInterval:
54 return "double-interval";
55 case Rational:
56 return "rational";
58 return "rational-interval";
59 case Parametric:
60 return "parametric";
61 }
62 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected value type.");
63}
64
65template<typename ValueType>
66std::string valueTypeToString() {
67 if constexpr (std::is_same_v<ValueType, double>) {
68 return "double";
69 } else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
70 return "rational";
71 } else if constexpr (std::is_same_v<ValueType, storm::Interval>) {
72 return "double-interval";
73 } else if constexpr (std::is_same_v<ValueType, storm::RationalFunction>) {
74 return "parametric";
75 } else {
76 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected value type.");
77 }
78}
79
80template<typename OutputValueType>
82 // Return true iff we can output a model with the given OutputValueType, given that the file is encoded using the given fileValueType
83 using enum DirectEncodingValueType;
84 if (fileValueType == Default) {
85 return true; // If no value type is given, just try to parse and let the value parser throw
86 }
87 if constexpr (std::is_same_v<OutputValueType, double> || std::is_same_v<OutputValueType, storm::RationalNumber>) {
88 return fileValueType == Double || fileValueType == Rational;
89 } else if constexpr (std::is_same_v<OutputValueType, storm::Interval>) {
90 return fileValueType == Double || fileValueType == Rational || fileValueType == DoubleInterval || fileValueType == RationalInterval;
91 } else if constexpr (std::is_same_v<OutputValueType, storm::RationalInterval>) {
92 return fileValueType == Double || fileValueType == Rational || fileValueType == DoubleInterval || fileValueType == RationalInterval;
93 } else if constexpr (std::is_same_v<OutputValueType, storm::RationalFunction>) {
94 return fileValueType == Double || fileValueType == Rational || fileValueType == Parametric;
95 } else {
96 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected output value type." << toString(fileValueType) << ".");
97 }
98}
99
100struct DrnHeader {
103 uint64_t nrStates{0}, nrChoices{0};
104 std::vector<std::string> parameters;
105 std::unordered_map<std::string, std::string> placeholders;
106 std::vector<std::string> rewardModelNames;
107};
108
109DrnHeader parseHeader(std::istream& file) {
110 DrnHeader header;
111 // Parse header
112 std::string line;
113 bool sawModelType{false}, sawParameters{false};
114 while (storm::io::getline(file, line)) {
115 if (line.empty() || line.starts_with("//")) {
116 continue;
117 }
118
119 if (line.starts_with("@type: ")) {
120 // Parse model type
121 STORM_LOG_THROW(!sawModelType, storm::exceptions::WrongFormatException, "Type declared twice.");
122 header.modelType = storm::models::getModelType(line.substr(7));
123 STORM_LOG_TRACE("Model type: " << header.modelType);
124 STORM_LOG_THROW(header.modelType != storm::models::ModelType::S2pg, storm::exceptions::NotSupportedException,
125 "Stochastic Two Player Games in DRN format are not supported.");
126 sawModelType = true;
127 } else if (line.starts_with("@value_type: ")) {
128 // Parse value type
129 STORM_LOG_THROW(header.valueType == DirectEncodingValueType::Default, storm::exceptions::WrongFormatException, "Value type declared twice.");
130 header.valueType = valueTypeFromString(line.substr(13));
131 } else if (line == "@parameters") {
132 // Parse parameters
133 STORM_LOG_THROW(!sawParameters, storm::exceptions::WrongFormatException, "Parameters declared twice.");
134 storm::io::getline(file, line);
135 if (line != "") {
136 boost::split(header.parameters, line, boost::is_any_of(" "));
137 }
138 sawParameters = true;
139 } else if (line == "@placeholders") {
140 // Parse placeholders
141 while (storm::io::getline(file, line)) {
142 size_t posColon = line.find(':');
143 STORM_LOG_THROW(posColon != std::string::npos, storm::exceptions::WrongFormatException, "':' not found.");
144 std::string placeName = line.substr(0, posColon - 1);
145 STORM_LOG_THROW(placeName.front() == '$', storm::exceptions::WrongFormatException, "Placeholder must start with dollar symbol $.");
146 std::string valueStr = line.substr(posColon + 2);
147 auto ret = header.placeholders.emplace(placeName.substr(1), valueStr);
148 STORM_LOG_THROW(ret.second, storm::exceptions::WrongFormatException, "Placeholder '$" << placeName << "' was already defined before.");
149 if (file.peek() == '@') {
150 // Next character is @ -> placeholder definitions ended
151 break;
152 }
153 }
154 } else if (line == "@reward_models") {
155 // Parse reward models
156 STORM_LOG_THROW(header.rewardModelNames.empty(), storm::exceptions::WrongFormatException, "Reward model names declared twice.");
157 storm::io::getline(file, line);
158 boost::split(header.rewardModelNames, line, boost::is_any_of("\t "));
159 } else if (line == "@nr_states") {
160 // Parse no. of states
161 STORM_LOG_THROW(header.nrStates == 0, storm::exceptions::WrongFormatException, "Number states declared twice.");
162 storm::io::getline(file, line);
163 header.nrStates = parseNumber<size_t>(line);
164 } else if (line == "@nr_choices") {
165 STORM_LOG_THROW(header.nrChoices == 0, storm::exceptions::WrongFormatException, "Number of actions declared twice.");
166 storm::io::getline(file, line);
167 header.nrChoices = parseNumber<size_t>(line);
168 } else if (line == "@model") {
169 // Parse rest of the model
170 STORM_LOG_THROW(sawModelType, storm::exceptions::WrongFormatException, "Model type has to be declared before model.");
171 STORM_LOG_THROW(header.nrStates != 0, storm::exceptions::WrongFormatException, "No. of states has to be declared before model.");
172 STORM_LOG_WARN_COND(header.nrChoices != 0, "No. of actions has to be declared. We may continue now, but future versions might not support this.");
173 // Done parsing header
174 // We might have no @value_type section but a non-empty list of parameters which means that the value type must be parametric.
175 if (header.valueType == DirectEncodingValueType::Default && !header.parameters.empty()) {
177 }
178 return header;
179 } else {
180 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse line '" << line << "'.");
181 }
182 }
183 // If we reach this point, we reached end of file before @model was found.
184 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Reached end of file before @model was found.");
185}
186
187template<typename ValueType>
188ValueType parseValue(std::string const& valueStr, std::unordered_map<std::string, ValueType> const& placeholders, ValueParser<ValueType> const& valueParser) {
189 if (valueStr.starts_with("$")) {
190 auto it = placeholders.find(valueStr.substr(1));
191 STORM_LOG_THROW(it != placeholders.end(), storm::exceptions::WrongFormatException, "Placeholder " << valueStr << " unknown.");
192 return it->second;
193 } else {
194 // Use default value parser
195 return valueParser.parseValue(valueStr);
196 }
197}
198
199template<typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
200std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> parseModel(std::istream& file, DrnHeader const& header,
201 DirectEncodingParserOptions const& options) {
202 // Initialize value parsing
204 isCompatibleValueType<ValueType>(header.valueType), storm::exceptions::WrongFormatException,
205 "Value type '" << toString(header.valueType) << "' in DRN file is not compatible with output value type '" << valueTypeToString<ValueType>() << "'.");
206 STORM_LOG_TRACE("Parsing model with file value type '" << toString(header.valueType) << "' into model with output value type '"
207 << valueTypeToString<ValueType>() << "'.");
208 ValueParser<ValueType> valueParser;
209 for (std::string const& parameter : header.parameters) {
210 STORM_LOG_TRACE("New parameter: " << parameter);
211 valueParser.addParameter(parameter);
212 }
213 std::unordered_map<std::string, ValueType> placeholders;
214 for (auto const& [placeName, valueStr] : header.placeholders) {
215 ValueType v = parseValue(valueStr, placeholders, valueParser);
216 STORM_LOG_TRACE("Placeholder " << placeName << " for value " << v);
217 placeholders.emplace(placeName, std::move(v));
218 }
219 size_t const nrStates = header.nrStates;
220 size_t const nrChoices = header.nrChoices;
222 bool const nonDeterministic = (header.modelType == storm::models::ModelType::Mdp || header.modelType == storm::models::ModelType::MarkovAutomaton ||
224 bool const continuousTime = (header.modelType == storm::models::ModelType::Ctmc || header.modelType == storm::models::ModelType::MarkovAutomaton);
226 modelComponents.stateLabeling = storm::models::sparse::StateLabeling(nrStates);
227 modelComponents.observabilityClasses = std::vector<uint32_t>();
228 modelComponents.observabilityClasses->resize(nrStates);
229 if (options.buildChoiceLabeling) {
230 STORM_LOG_THROW(nrChoices != 0, storm::exceptions::WrongFormatException,
231 "No. of actions (@nr_choices) has to be declared when building a model with choice labeling.");
232 modelComponents.choiceLabeling = storm::models::sparse::ChoiceLabeling(nrChoices);
233 }
234 std::vector<std::vector<ValueType>> stateRewards;
235 std::vector<std::vector<ValueType>> actionRewards;
236 if (continuousTime) {
237 modelComponents.exitRates = std::vector<ValueType>(nrStates);
239 modelComponents.markovianStates = storm::storage::BitVector(nrStates);
240 }
241 }
242 // We parse rates for continuous time models.
244 modelComponents.rateTransitions = true;
245 }
246
247 // Iterate over all lines
248 std::string line;
249 size_t row = 0;
250 size_t state = 0;
251 uint64_t lineNumber = 0;
252 bool firstState = true;
253 bool firstActionForState = true;
254 while (storm::io::getline(file, line)) {
255 lineNumber++;
256 if (line.starts_with("//")) {
257 continue;
258 }
259 if (line.empty()) {
260 continue;
261 }
262 STORM_LOG_TRACE("Parsing line no " << lineNumber << " : " << line);
263 boost::trim_left(line);
264 if (line.starts_with("state ")) {
265 // New state
266 if (firstState) {
267 firstState = false;
268 } else {
269 ++state;
270 ++row;
271 }
272 firstActionForState = true;
273 STORM_LOG_TRACE("New state " << state);
274 STORM_LOG_THROW(state <= nrStates, storm::exceptions::WrongFormatException, "More states detected than declared (in @nr_states).");
275
276 // Parse state id
277 line = line.substr(6); // Remove "state "
278 std::string curString = line;
279 size_t posEnd = line.find(" ");
280 if (posEnd != std::string::npos) {
281 curString = line.substr(0, posEnd);
282 line = line.substr(posEnd + 1);
283 } else {
284 line = "";
285 }
286 size_t parsedId = parseNumber<size_t>(curString);
287 STORM_LOG_THROW(state == parsedId, storm::exceptions::WrongFormatException,
288 "In line " << lineNumber << " state ids are not ordered and without gaps. Expected " << state << " but got " << parsedId << ".");
289 if (nonDeterministic) {
290 STORM_LOG_TRACE("new Row Group starts at " << row << ".");
291 builder.newRowGroup(row);
292 STORM_LOG_THROW(nrChoices == 0 || builder.getCurrentRowGroupCount() <= nrChoices, storm::exceptions::WrongFormatException,
293 "More actions detected than declared (in @nr_choices).");
294 }
295
296 if (continuousTime) {
297 // Parse exit rate for CTMC or MA
298 STORM_LOG_THROW(line.starts_with("!"), storm::exceptions::WrongFormatException, "Exit rate missing in " << lineNumber << ".");
299 line = line.substr(1); // Remove "!"
300 curString = line;
301 posEnd = line.find(" ");
302 if (posEnd != std::string::npos) {
303 curString = line.substr(0, posEnd);
304 line = line.substr(posEnd + 1);
305 } else {
306 line = "";
307 }
308 ValueType exitRate = parseValue(curString, placeholders, valueParser);
310 modelComponents.markovianStates.get().set(state);
311 }
312 STORM_LOG_TRACE("Exit rate " << exitRate);
313 modelComponents.exitRates.get()[state] = exitRate;
314 }
315
317 if (line.starts_with("{")) {
318 size_t posEndObservation = line.find("}");
319 std::string observation = line.substr(1, posEndObservation - 1);
320 STORM_LOG_TRACE("State observation " << observation);
321 modelComponents.observabilityClasses.value()[state] = std::stoi(observation);
322 line = line.substr(posEndObservation + 1);
323 if (!line.empty()) {
324 STORM_LOG_THROW(line.starts_with(" "), storm::exceptions::WrongFormatException,
325 "Expected whitespace after observation in line " << lineNumber << ".");
326
327 line = line.substr(1);
328 }
329 } else {
330 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException,
331 "Expected an observation for state " << state << " in line " << lineNumber << ".");
332 }
333 }
334
335 if (line.starts_with("[")) {
336 // Parse rewards
337 size_t posEndReward = line.find(']');
338 STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing in line " << lineNumber << " .");
339 std::string rewardsStr = line.substr(1, posEndReward - 1);
340 STORM_LOG_TRACE("State rewards: " << rewardsStr);
341 std::vector<std::string> rewards;
342 boost::split(rewards, rewardsStr, boost::is_any_of(","));
343 if (stateRewards.size() < rewards.size()) {
344 stateRewards.resize(rewards.size());
345 }
346 auto stateRewardsIt = stateRewards.begin();
347 for (auto const& rew : rewards) {
348 auto rewardValue = parseValue(rew, placeholders, valueParser);
349 if (!storm::utility::isZero(rewardValue)) {
350 if (stateRewardsIt->empty()) {
351 stateRewardsIt->resize(nrStates, storm::utility::zero<ValueType>());
352 }
353 (*stateRewardsIt)[state] = std::move(rewardValue);
354 }
355 ++stateRewardsIt;
356 }
357 line = line.substr(posEndReward + 1);
358 }
359
360 // Parse labels
361 if (!line.empty()) {
362 std::vector<std::string> labels;
363 // Labels are separated by whitespace and can optionally be enclosed in quotation marks
364 // Regex for labels with two cases:
365 // * Enclosed in quotation marks: \"([^\"]+?)\"(?=(\s|$|\"))
366 // - First part matches string enclosed in quotation marks with no quotation mark inbetween (\"([^\"]+?)\")
367 // - second part is lookahead which ensures that after the matched part either whitespace, end of line or a new quotation mark follows
368 // (?=(\s|$|\"))
369 // * Separated by whitespace: [^\s\"]+?(?=(\s|$))
370 // - First part matches string without whitespace and quotation marks [^\s\"]+?
371 // - Second part is again lookahead matching whitespace or end of line (?=(\s|$))
372 std::regex labelRegex(R"(\"([^\"]+?)\"(?=(\s|$|\"))|([^\s\"]+?(?=(\s|$))))");
373
374 // Iterate over matches
375 auto match_begin = std::sregex_iterator(line.begin(), line.end(), labelRegex);
376 auto match_end = std::sregex_iterator();
377 for (std::sregex_iterator i = match_begin; i != match_end; ++i) {
378 std::smatch match = *i;
379 // Find matched group and add as label
380 if (match.length(1) > 0) {
381 labels.push_back(match.str(1));
382 } else {
383 labels.push_back(match.str(3));
384 }
385 }
386
387 for (std::string const& label : labels) {
388 if (!modelComponents.stateLabeling.containsLabel(label)) {
389 modelComponents.stateLabeling.addLabel(label);
390 }
391 modelComponents.stateLabeling.addLabelToState(label, state);
392 STORM_LOG_TRACE("New label: '" << label << "'");
393 }
394 }
395 } else if (line.starts_with("action ")) {
396 // New action
397 if (firstActionForState) {
398 firstActionForState = false;
399 } else {
400 ++row;
401 }
402 STORM_LOG_TRACE("New action: " << row);
403 line = line.substr(7);
404 std::string curString = line;
405 size_t posEnd = line.find(" ");
406 if (posEnd != std::string::npos) {
407 curString = line.substr(0, posEnd);
408 line = line.substr(posEnd + 1);
409 } else {
410 line = "";
411 }
412
413 // curString contains action name.
414 if (options.buildChoiceLabeling) {
415 if (curString != "__NOLABEL__") {
416 if (!modelComponents.choiceLabeling.value().containsLabel(curString)) {
417 modelComponents.choiceLabeling.value().addLabel(curString);
418 }
419 modelComponents.choiceLabeling.value().addLabelToChoice(curString, row);
420 }
421 }
422 // Check for rewards
423 if (line.starts_with("[")) {
424 // Rewards found
425 size_t posEndReward = line.find(']');
426 STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing.");
427 std::string rewardsStr = line.substr(1, posEndReward - 1);
428 STORM_LOG_TRACE("Action rewards: " << rewardsStr);
429 std::vector<std::string> rewards;
430 boost::split(rewards, rewardsStr, boost::is_any_of(","));
431 if (actionRewards.size() < rewards.size()) {
432 actionRewards.resize(rewards.size());
433 }
434 auto actionRewardsIt = actionRewards.begin();
435 for (auto const& rew : rewards) {
436 auto rewardValue = parseValue(rew, placeholders, valueParser);
437 if (!storm::utility::isZero(rewardValue)) {
438 if (actionRewardsIt->size() <= row) {
439 actionRewardsIt->resize(std::max(row + 1, nrStates), storm::utility::zero<ValueType>());
440 }
441 (*actionRewardsIt)[row] = std::move(rewardValue);
442 }
443 ++actionRewardsIt;
444 }
445 line = line.substr(posEndReward + 1);
446 }
447
448 } else {
449 // New transition
450 size_t posColon = line.find(':');
451 STORM_LOG_THROW(posColon != std::string::npos, storm::exceptions::WrongFormatException,
452 "':' not found in '" << line << "' on line " << lineNumber << ".");
453 size_t target = parseNumber<size_t>(line.substr(0, posColon - 1));
454 std::string valueStr = line.substr(posColon + 2);
455 ValueType value = parseValue(valueStr, placeholders, valueParser);
456 STORM_LOG_TRACE("Transition " << row << " -> " << target << ": " << value);
457 STORM_LOG_THROW(target < nrStates, storm::exceptions::WrongFormatException,
458 "In line " << lineNumber << " target state " << target << " is greater than state size " << nrStates << ".");
459 builder.addNextValue(row, target, value);
460 }
461
463 std::cout << "Parsed " << state << "/" << nrStates << " states before abort.\n";
464 STORM_LOG_THROW(false, storm::exceptions::AbortException, "Aborted in state space exploration.");
465 break;
466 }
467
468 } // end state iteration
469 STORM_LOG_TRACE("Finished parsing");
470
471 if (nonDeterministic) {
472 STORM_LOG_THROW(nrChoices == 0 || builder.getLastRow() + 1 == nrChoices, storm::exceptions::WrongFormatException,
473 "Number of actions detected (at least " << builder.getLastRow() + 1 << ") does not match number of actions declared (" << nrChoices
474 << ", in @nr_choices).");
475 }
476
477 // Build transition matrix
478 modelComponents.transitionMatrix = builder.build(row + 1, nrStates, nonDeterministic ? nrStates : 0);
479 STORM_LOG_TRACE("Built matrix");
480
481 // Build reward models
482 uint64_t numRewardModels = std::max(stateRewards.size(), actionRewards.size());
483 for (uint64_t i = 0; i < numRewardModels; ++i) {
484 std::string rewardModelName;
485 if (header.rewardModelNames.size() <= i) {
486 rewardModelName = "rew" + std::to_string(i);
487 } else {
488 rewardModelName = header.rewardModelNames[i];
489 }
490 std::optional<std::vector<ValueType>> stateRewardVector, actionRewardVector;
491 if (i < stateRewards.size() && !stateRewards[i].empty()) {
492 stateRewardVector = std::move(stateRewards[i]);
493 }
494 if (i < actionRewards.size() && !actionRewards[i].empty()) {
495 actionRewards[i].resize(row + 1, storm::utility::zero<ValueType>());
496 actionRewardVector = std::move(actionRewards[i]);
497 }
498 modelComponents.rewardModels.emplace(
499 rewardModelName, storm::models::sparse::StandardRewardModel<ValueType>(std::move(stateRewardVector), std::move(actionRewardVector)));
500 }
501 STORM_LOG_TRACE("Built reward models");
502 return storm::utility::builder::buildModelFromComponents(header.modelType, std::move(modelComponents));
503}
504
505std::shared_ptr<storm::models::ModelBase> parseModel(DirectEncodingValueType valueType, std::istream& file, DrnHeader const& header,
506 DirectEncodingParserOptions const& options) {
507 // Derive output model value type
508 using enum DirectEncodingValueType;
509 if (valueType == Default) {
510 valueType = header.valueType;
511 }
512 STORM_LOG_THROW(valueType != Default, storm::exceptions::WrongFormatException, "Value type cannot be derived from file and is not provided as argument.");
513 // Potentially promote to interval
514 if (header.valueType == DoubleInterval || header.valueType == RationalInterval) {
515 if (valueType == Double) {
516 valueType = DoubleInterval;
517 } else if (valueType == Rational) {
518 valueType = RationalInterval;
519 }
520 }
521 // Derive value type for parsing
522 switch (valueType) {
523 case Double:
524 return parseModel<double>(file, header, options);
525 case Rational:
526 return parseModel<storm::RationalNumber>(file, header, options);
527 case DoubleInterval:
528 return parseModel<storm::Interval>(file, header, options);
529 case RationalInterval:
530 return parseModel<storm::RationalInterval>(file, header, options);
531 case Parametric:
532 return parseModel<storm::RationalFunction>(file, header, options);
533 default:
534 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported value type " << toString(valueType) << ".");
535 }
536}
537
538auto openFileAsInputStream(std::filesystem::path const& file, auto&& f) {
539 auto archiveReader = storm::io::openArchive(file);
540 // Load file either as archive or as regular file
541 if (archiveReader.isReadableArchive()) {
542 std::optional<std::istringstream> filestream;
543 for (auto entry : archiveReader) {
544 if (!entry.isDir()) {
545 STORM_LOG_THROW(!filestream.has_value(), storm::exceptions::WrongFormatException, "Multiple files in archive " << file << ".");
546 STORM_LOG_INFO("Reading file " << entry.name() << " from archive " << file);
547 // Loads the entire content into memory.
548 filestream.emplace(entry.toString());
549 }
550 }
551 STORM_LOG_THROW(filestream.has_value(), storm::exceptions::WrongFormatException, "Empty archive " << file << ".");
552 return f(filestream.value());
553 } else {
554 STORM_LOG_INFO("Reading from file " << file);
555 std::ifstream filestream;
556 storm::io::openFile(file, filestream);
557 auto res = f(filestream);
558 storm::io::closeFile(filestream);
559 return res;
560 }
561}
562
563} // namespace detail
564
565template<typename ValueType, typename RewardModelType>
566std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> parseDirectEncodingModel(std::filesystem::path const& file,
567 DirectEncodingParserOptions const& options) {
568 static_assert(std::is_same_v<ValueType, typename RewardModelType::ValueType>, "ValueType and RewardModelType::ValueType are assumed to be the same.");
569 return detail::openFileAsInputStream(file, [&options](std::istream& filestream) {
570 auto header = detail::parseHeader(filestream);
571 return detail::parseModel<ValueType, RewardModelType>(filestream, header, options);
572 });
573}
574
575std::shared_ptr<storm::models::ModelBase> parseDirectEncodingModel(std::filesystem::path const& file, DirectEncodingValueType valueType,
576 DirectEncodingParserOptions const& options) {
577 return detail::openFileAsInputStream(file, [&valueType, &options](std::istream& filestream) {
578 auto header = detail::parseHeader(filestream);
579 return detail::parseModel(valueType, filestream, header, options);
580 });
581}
582
583// Template instantiations.
584template std::shared_ptr<storm::models::sparse::Model<double>> parseDirectEncodingModel<double>(std::filesystem::path const& file,
585 DirectEncodingParserOptions const& options);
586template std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> parseDirectEncodingModel<storm::RationalNumber>(
587 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
588template std::shared_ptr<storm::models::sparse::Model<storm::Interval>> parseDirectEncodingModel<storm::Interval>(std::filesystem::path const& file,
589 DirectEncodingParserOptions const& options);
590template std::shared_ptr<storm::models::sparse::Model<storm::RationalInterval>> parseDirectEncodingModel<storm::RationalInterval>(
591 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
592template std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> parseDirectEncodingModel<storm::RationalFunction>(
593 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
594
595} // namespace storm::parser
This class manages the labeling of the choice space with a number of (atomic) labels.
void addLabel(std::string const &label)
Adds a new label to the labelings.
bool containsLabel(std::string const &label) const
Checks whether a label is registered within this labeling.
This class manages the labeling of the state space with a number of (atomic) labels.
void addLabelToState(std::string const &label, storm::storage::sparse::state_type state)
Adds a label to a given state.
Parser for values according to their ValueType.
Definition ValueParser.h:23
void addParameter(std::string const &parameter)
Add declaration of parameter.
ValueType parseValue(std::string const &value) const
Parse ValueType from string.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
A class that can be used to build a sparse matrix by adding value by value.
#define STORM_LOG_INFO(message)
Definition logging.h:27
#define STORM_LOG_TRACE(message)
Definition logging.h:15
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:36
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
ArchiveReader openArchive(std::filesystem::path const &file)
Reads an archive file.
std::basic_istream< CharT, Traits > & getline(std::basic_istream< CharT, Traits > &input, std::basic_string< CharT, Traits, Allocator > &str)
Overloaded getline function which handles different types of newline ( and \r).
Definition file.h:80
void closeFile(std::ofstream &stream)
Close the given file after writing.
Definition file.h:47
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.
Definition file.h:18
ModelType getModelType(std::string const &type)
Definition ModelType.cpp:9
std::shared_ptr< storm::models::sparse::Model< ValueType, RewardModelType > > parseModel(std::istream &file, DrnHeader const &header, DirectEncodingParserOptions const &options)
DrnHeader parseHeader(std::istream &file)
auto openFileAsInputStream(std::filesystem::path const &file, auto &&f)
bool isCompatibleValueType(DirectEncodingValueType fileValueType)
std::string toString(DirectEncodingValueType const &vt)
DirectEncodingValueType valueTypeFromString(std::string const &valueTypeStr)
ValueType parseValue(std::string const &valueStr, std::unordered_map< std::string, ValueType > const &placeholders, ValueParser< ValueType > const &valueParser)
Contains all file parsers and helper classes.
template std::shared_ptr< storm::models::sparse::Model< storm::RationalFunction > > parseDirectEncodingModel< storm::RationalFunction >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
NumberType parseNumber(std::string const &value)
Parse number from string.
template std::shared_ptr< storm::models::sparse::Model< storm::RationalInterval > > parseDirectEncodingModel< storm::RationalInterval >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
template std::shared_ptr< storm::models::sparse::Model< double > > parseDirectEncodingModel< double >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
std::shared_ptr< storm::models::sparse::Model< ValueType, RewardModelType > > parseDirectEncodingModel(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
Parses the given file in DRN format.
template std::shared_ptr< storm::models::sparse::Model< storm::Interval > > parseDirectEncodingModel< storm::Interval >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
template std::shared_ptr< storm::models::sparse::Model< storm::RationalNumber > > parseDirectEncodingModel< storm::RationalNumber >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
std::shared_ptr< storm::models::sparse::Model< ValueType, RewardModelType > > buildModelFromComponents(storm::models::ModelType modelType, storm::storage::sparse::ModelComponents< ValueType, RewardModelType > &&components)
Definition builder.cpp:20
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
bool isZero(ValueType const &a)
Definition constants.cpp:42
ValueType zero()
Definition constants.cpp:24
carl::Interval< storm::RationalNumber > RationalInterval
std::vector< std::string > rewardModelNames
std::vector< std::string > parameters
std::unordered_map< std::string, std::string > placeholders
std::unordered_map< std::string, RewardModelType > rewardModels
storm::storage::SparseMatrix< ValueType > transitionMatrix
boost::optional< storm::storage::BitVector > markovianStates
std::optional< storm::models::sparse::ChoiceLabeling > choiceLabeling
storm::models::sparse::StateLabeling stateLabeling
std::optional< std::vector< uint32_t > > observabilityClasses
boost::optional< std::vector< ValueType > > exitRates