Storm 1.13.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, "Expected an observation for state " << state << " in line " << lineNumber);
331 }
332 }
333
334 if (line.starts_with("[")) {
335 // Parse rewards
336 size_t posEndReward = line.find(']');
337 STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing in line " << lineNumber << " .");
338 std::string rewardsStr = line.substr(1, posEndReward - 1);
339 STORM_LOG_TRACE("State rewards: " << rewardsStr);
340 std::vector<std::string> rewards;
341 boost::split(rewards, rewardsStr, boost::is_any_of(","));
342 if (stateRewards.size() < rewards.size()) {
343 stateRewards.resize(rewards.size());
344 }
345 auto stateRewardsIt = stateRewards.begin();
346 for (auto const& rew : rewards) {
347 auto rewardValue = parseValue(rew, placeholders, valueParser);
348 if (!storm::utility::isZero(rewardValue)) {
349 if (stateRewardsIt->empty()) {
350 stateRewardsIt->resize(nrStates, storm::utility::zero<ValueType>());
351 }
352 (*stateRewardsIt)[state] = std::move(rewardValue);
353 }
354 ++stateRewardsIt;
355 }
356 line = line.substr(posEndReward + 1);
357 }
358
359 // Parse labels
360 if (!line.empty()) {
361 std::vector<std::string> labels;
362 // Labels are separated by whitespace and can optionally be enclosed in quotation marks
363 // Regex for labels with two cases:
364 // * Enclosed in quotation marks: \"([^\"]+?)\"(?=(\s|$|\"))
365 // - First part matches string enclosed in quotation marks with no quotation mark inbetween (\"([^\"]+?)\")
366 // - second part is lookahead which ensures that after the matched part either whitespace, end of line or a new quotation mark follows
367 // (?=(\s|$|\"))
368 // * Separated by whitespace: [^\s\"]+?(?=(\s|$))
369 // - First part matches string without whitespace and quotation marks [^\s\"]+?
370 // - Second part is again lookahead matching whitespace or end of line (?=(\s|$))
371 std::regex labelRegex(R"(\"([^\"]+?)\"(?=(\s|$|\"))|([^\s\"]+?(?=(\s|$))))");
372
373 // Iterate over matches
374 auto match_begin = std::sregex_iterator(line.begin(), line.end(), labelRegex);
375 auto match_end = std::sregex_iterator();
376 for (std::sregex_iterator i = match_begin; i != match_end; ++i) {
377 std::smatch match = *i;
378 // Find matched group and add as label
379 if (match.length(1) > 0) {
380 labels.push_back(match.str(1));
381 } else {
382 labels.push_back(match.str(3));
383 }
384 }
385
386 for (std::string const& label : labels) {
387 if (!modelComponents.stateLabeling.containsLabel(label)) {
388 modelComponents.stateLabeling.addLabel(label);
389 }
390 modelComponents.stateLabeling.addLabelToState(label, state);
391 STORM_LOG_TRACE("New label: '" << label << "'");
392 }
393 }
394 } else if (line.starts_with("action ")) {
395 // New action
396 if (firstActionForState) {
397 firstActionForState = false;
398 } else {
399 ++row;
400 }
401 STORM_LOG_TRACE("New action: " << row);
402 line = line.substr(7);
403 std::string curString = line;
404 size_t posEnd = line.find(" ");
405 if (posEnd != std::string::npos) {
406 curString = line.substr(0, posEnd);
407 line = line.substr(posEnd + 1);
408 } else {
409 line = "";
410 }
411
412 // curString contains action name.
413 if (options.buildChoiceLabeling) {
414 if (curString != "__NOLABEL__") {
415 if (!modelComponents.choiceLabeling.value().containsLabel(curString)) {
416 modelComponents.choiceLabeling.value().addLabel(curString);
417 }
418 modelComponents.choiceLabeling.value().addLabelToChoice(curString, row);
419 }
420 }
421 // Check for rewards
422 if (line.starts_with("[")) {
423 // Rewards found
424 size_t posEndReward = line.find(']');
425 STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing.");
426 std::string rewardsStr = line.substr(1, posEndReward - 1);
427 STORM_LOG_TRACE("Action rewards: " << rewardsStr);
428 std::vector<std::string> rewards;
429 boost::split(rewards, rewardsStr, boost::is_any_of(","));
430 if (actionRewards.size() < rewards.size()) {
431 actionRewards.resize(rewards.size());
432 }
433 auto actionRewardsIt = actionRewards.begin();
434 for (auto const& rew : rewards) {
435 auto rewardValue = parseValue(rew, placeholders, valueParser);
436 if (!storm::utility::isZero(rewardValue)) {
437 if (actionRewardsIt->size() <= row) {
438 actionRewardsIt->resize(std::max(row + 1, nrStates), storm::utility::zero<ValueType>());
439 }
440 (*actionRewardsIt)[row] = std::move(rewardValue);
441 }
442 ++actionRewardsIt;
443 }
444 line = line.substr(posEndReward + 1);
445 }
446
447 } else {
448 // New transition
449 size_t posColon = line.find(':');
450 STORM_LOG_THROW(posColon != std::string::npos, storm::exceptions::WrongFormatException,
451 "':' not found in '" << line << "' on line " << lineNumber << ".");
452 size_t target = parseNumber<size_t>(line.substr(0, posColon - 1));
453 std::string valueStr = line.substr(posColon + 2);
454 ValueType value = parseValue(valueStr, placeholders, valueParser);
455 STORM_LOG_TRACE("Transition " << row << " -> " << target << ": " << value);
456 STORM_LOG_THROW(target < nrStates, storm::exceptions::WrongFormatException,
457 "In line " << lineNumber << " target state " << target << " is greater than state size " << nrStates);
458 builder.addNextValue(row, target, value);
459 }
460
462 std::cout << "Parsed " << state << "/" << nrStates << " states before abort.\n";
463 STORM_LOG_THROW(false, storm::exceptions::AbortException, "Aborted in state space exploration.");
464 break;
465 }
466
467 } // end state iteration
468 STORM_LOG_TRACE("Finished parsing");
469
470 if (nonDeterministic) {
471 STORM_LOG_THROW(nrChoices == 0 || builder.getLastRow() + 1 == nrChoices, storm::exceptions::WrongFormatException,
472 "Number of actions detected (at least " << builder.getLastRow() + 1 << ") does not match number of actions declared (" << nrChoices
473 << ", in @nr_choices).");
474 }
475
476 // Build transition matrix
477 modelComponents.transitionMatrix = builder.build(row + 1, nrStates, nonDeterministic ? nrStates : 0);
478 STORM_LOG_TRACE("Built matrix");
479
480 // Build reward models
481 uint64_t numRewardModels = std::max(stateRewards.size(), actionRewards.size());
482 for (uint64_t i = 0; i < numRewardModels; ++i) {
483 std::string rewardModelName;
484 if (header.rewardModelNames.size() <= i) {
485 rewardModelName = "rew" + std::to_string(i);
486 } else {
487 rewardModelName = header.rewardModelNames[i];
488 }
489 std::optional<std::vector<ValueType>> stateRewardVector, actionRewardVector;
490 if (i < stateRewards.size() && !stateRewards[i].empty()) {
491 stateRewardVector = std::move(stateRewards[i]);
492 }
493 if (i < actionRewards.size() && !actionRewards[i].empty()) {
494 actionRewards[i].resize(row + 1, storm::utility::zero<ValueType>());
495 actionRewardVector = std::move(actionRewards[i]);
496 }
497 modelComponents.rewardModels.emplace(
498 rewardModelName, storm::models::sparse::StandardRewardModel<ValueType>(std::move(stateRewardVector), std::move(actionRewardVector)));
499 }
500 STORM_LOG_TRACE("Built reward models");
501 return storm::utility::builder::buildModelFromComponents(header.modelType, std::move(modelComponents));
502}
503
504std::shared_ptr<storm::models::ModelBase> parseModel(DirectEncodingValueType valueType, std::istream& file, DrnHeader const& header,
505 DirectEncodingParserOptions const& options) {
506 // Derive output model value type
507 using enum DirectEncodingValueType;
508 if (valueType == Default) {
509 valueType = header.valueType;
510 }
511 STORM_LOG_THROW(valueType != Default, storm::exceptions::WrongFormatException, "Value type cannot be derived from file and is not provided as argument.");
512 // Potentially promote to interval
513 if (header.valueType == DoubleInterval || header.valueType == RationalInterval) {
514 if (valueType == Double) {
515 valueType = DoubleInterval;
516 } else if (valueType == Rational) {
517 valueType = RationalInterval;
518 }
519 }
520 // Derive value type for parsing
521 switch (valueType) {
522 case Double:
523 return parseModel<double>(file, header, options);
524 case Rational:
525 return parseModel<storm::RationalNumber>(file, header, options);
526 case DoubleInterval:
527 return parseModel<storm::Interval>(file, header, options);
528 case RationalInterval:
529 return parseModel<storm::RationalInterval>(file, header, options);
530 case Parametric:
531 return parseModel<storm::RationalFunction>(file, header, options);
532 default:
533 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported value type " << toString(valueType) << ".");
534 }
535}
536
537auto openFileAsInputStream(std::filesystem::path const& file, auto&& f) {
538 auto archiveReader = storm::io::openArchive(file);
539 // Load file either as archive or as regular file
540 if (archiveReader.isReadableArchive()) {
541 std::optional<std::istringstream> filestream;
542 for (auto entry : archiveReader) {
543 if (!entry.isDir()) {
544 STORM_LOG_THROW(!filestream.has_value(), storm::exceptions::WrongFormatException, "Multiple files in archive " << file << ".");
545 STORM_LOG_INFO("Reading file " << entry.name() << " from archive " << file);
546 // Loads the entire content into memory.
547 filestream.emplace(entry.toString());
548 }
549 }
550 STORM_LOG_THROW(filestream.has_value(), storm::exceptions::WrongFormatException, "Empty archive " << file << ".");
551 return f(filestream.value());
552 } else {
553 STORM_LOG_INFO("Reading from file " << file);
554 std::ifstream filestream;
555 storm::io::openFile(file, filestream);
556 auto res = f(filestream);
557 storm::io::closeFile(filestream);
558 return res;
559 }
560}
561
562} // namespace detail
563
564template<typename ValueType, typename RewardModelType>
565std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> parseDirectEncodingModel(std::filesystem::path const& file,
566 DirectEncodingParserOptions const& options) {
567 static_assert(std::is_same_v<ValueType, typename RewardModelType::ValueType>, "ValueType and RewardModelType::ValueType are assumed to be the same.");
568 return detail::openFileAsInputStream(file, [&options](std::istream& filestream) {
569 auto header = detail::parseHeader(filestream);
570 return detail::parseModel<ValueType, RewardModelType>(filestream, header, options);
571 });
572}
573
574std::shared_ptr<storm::models::ModelBase> parseDirectEncodingModel(std::filesystem::path const& file, DirectEncodingValueType valueType,
575 DirectEncodingParserOptions const& options) {
576 return detail::openFileAsInputStream(file, [&valueType, &options](std::istream& filestream) {
577 auto header = detail::parseHeader(filestream);
578 return detail::parseModel(valueType, filestream, header, options);
579 });
580}
581
582// Template instantiations.
583template std::shared_ptr<storm::models::sparse::Model<double>> parseDirectEncodingModel<double>(std::filesystem::path const& file,
584 DirectEncodingParserOptions const& options);
585template std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> parseDirectEncodingModel<storm::RationalNumber>(
586 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
587template std::shared_ptr<storm::models::sparse::Model<storm::Interval>> parseDirectEncodingModel<storm::Interval>(std::filesystem::path const& file,
588 DirectEncodingParserOptions const& options);
589template std::shared_ptr<storm::models::sparse::Model<storm::RationalInterval>> parseDirectEncodingModel<storm::RationalInterval>(
590 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
591template std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> parseDirectEncodingModel<storm::RationalFunction>(
592 std::filesystem::path const& file, DirectEncodingParserOptions const& options);
593
594} // 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:24
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
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:39
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