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