Storm 1.12.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
Model.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string/join.hpp>
4#include <boost/algorithm/string/split.hpp>
5
13#include "storm/io/export.h"
23
24namespace storm {
25namespace models {
26namespace sparse {
27
28template<typename ValueType, typename RewardModelType>
30 : storm::models::Model<ValueType>(modelType),
31 transitionMatrix(components.transitionMatrix),
32 stateLabeling(components.stateLabeling),
33 rewardModels(components.rewardModels),
34 choiceLabeling(components.choiceLabeling),
35 stateValuations(components.stateValuations),
36 choiceOrigins(components.choiceOrigins) {
37 assertValidityOfComponents(components);
38}
39
40template<typename ValueType, typename RewardModelType>
42 : storm::models::Model<ValueType>(modelType),
43 transitionMatrix(std::move(components.transitionMatrix)),
44 stateLabeling(std::move(components.stateLabeling)),
45 rewardModels(std::move(components.rewardModels)),
46 choiceLabeling(std::move(components.choiceLabeling)),
47 stateValuations(std::move(components.stateValuations)),
48 choiceOrigins(std::move(components.choiceOrigins)) {
49 assertValidityOfComponents(components);
50}
51
52template<typename ValueType, typename RewardModelType>
55 // More costly checks are only asserted to avoid doing them in release mode.
56 ValueType const stochasticTolerance =
57 isExact() ? storm::utility::zero<ValueType>()
58 : storm::utility::convertNumber<ValueType>(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
59
60 uint64_t stateCount = this->getNumberOfStates();
61 uint64_t choiceCount = this->getTransitionMatrix().getRowCount();
62
63 // general components for all model types.
64 STORM_LOG_THROW(this->getTransitionMatrix().getColumnCount() == stateCount, storm::exceptions::IllegalArgumentException,
65 "Invalid column count of transition matrix.");
66 {
67 std::string reasonNotProbabilistic [[maybe_unused]];
68 STORM_LOG_ASSERT(components.rateTransitions || this->getTransitionMatrix().isProbabilistic(stochasticTolerance, reasonNotProbabilistic),
69 "The matrix is not probabilistic. " << reasonNotProbabilistic);
70 }
71 STORM_LOG_THROW(this->getStateLabeling().getNumberOfItems() == stateCount, storm::exceptions::IllegalArgumentException,
72 "Invalid item count (" << this->getStateLabeling().getNumberOfItems() << ") of state labeling (states: " << stateCount << ").");
73 for (auto const& rewardModel : this->getRewardModels()) {
74 STORM_LOG_THROW(!rewardModel.second.hasStateRewards() || rewardModel.second.getStateRewardVector().size() == stateCount,
75 storm::exceptions::IllegalArgumentException,
76 "Invalid size (" << rewardModel.second.getStateRewardVector().size() << ") of state reward vector (states:" << stateCount << ").");
78 !rewardModel.second.hasStateActionRewards() || rewardModel.second.getStateActionRewardVector().size() == choiceCount,
79 storm::exceptions::IllegalArgumentException,
80 "Invalid size (" << rewardModel.second.getStateActionRewardVector().size() << ") of state action reward vector (expected:" << choiceCount << ").");
82 !rewardModel.second.hasTransitionRewards() || rewardModel.second.getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()),
83 "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
84 }
86 !this->hasChoiceLabeling() || this->getChoiceLabeling().getNumberOfItems() == choiceCount, storm::exceptions::IllegalArgumentException,
87 "Invalid choice count of choice labeling (choices: " << choiceCount << " vs. labeling:" << this->getChoiceLabeling().getNumberOfItems() << ").");
89 !this->hasStateValuations() || this->getStateValuations().getNumberOfStates() == stateCount, storm::exceptions::IllegalArgumentException,
90 "Invalid state count for state valuations (states: " << stateCount << " vs. valuations:" << this->getStateValuations().getNumberOfStates() << ").");
92 !this->hasChoiceOrigins() || this->getChoiceOrigins()->getNumberOfChoices() == choiceCount, storm::exceptions::IllegalArgumentException,
93 "Invalid choice count for choice origins. (choices: " << choiceCount << " vs. origins:" << this->getChoiceOrigins()->getNumberOfChoices() << ").");
94
95 // Branch on type of nondeterminism
96 if (this->isOfType(ModelType::Dtmc) || this->isOfType(ModelType::Ctmc)) {
97 STORM_LOG_THROW(this->getTransitionMatrix().hasTrivialRowGrouping(), storm::exceptions::IllegalArgumentException,
98 "Can not create deterministic model: Transition matrix has non-trivial row grouping.");
99 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getRowCount(), storm::exceptions::IllegalArgumentException,
100 "Can not create deterministic model: Number of rows of transition matrix does not match state count.");
101 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getColumnCount(), storm::exceptions::IllegalArgumentException,
102 "Can not create deterministic model: Number of columns of transition matrix does not match state count.");
103 STORM_LOG_ERROR_COND(!components.player1Matrix.is_initialized(), "Player 1 matrix given for a model that is no stochastic game (will be ignored).");
104 } else if (this->isOfType(ModelType::Mdp) || this->isOfType(ModelType::MarkovAutomaton) || this->isOfType(ModelType::Pomdp) ||
105 this->isOfType(ModelType::Smg)) {
106 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getRowGroupCount(), storm::exceptions::IllegalArgumentException,
107 "Can not create nondeterministic model: Number of row groups ("
108 << this->getTransitionMatrix().getRowGroupCount() << ") of transition matrix does not match state count (" << stateCount << ").");
109 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getColumnCount(), storm::exceptions::IllegalArgumentException,
110 "Can not create nondeterministic model: Number of columns of transition matrix does not match state count.");
111 STORM_LOG_ERROR_COND(!components.player1Matrix.is_initialized(), "Player 1 matrix given for a model that is no stochastic game (will be ignored).");
112 } else if (this->isOfType(ModelType::S2pg)) {
113 STORM_LOG_THROW(components.player1Matrix.is_initialized(), storm::exceptions::IllegalArgumentException,
114 "No player 1 matrix given for stochastic game.");
115 STORM_LOG_ASSERT(components.player1Matrix->isProbabilistic(0),
116 "Can not create stochastic game: There is a row in the p1 matrix with not exactly one entry.");
117 STORM_LOG_THROW(stateCount == components.player1Matrix->getRowGroupCount(), storm::exceptions::IllegalArgumentException,
118 "Can not create stochastic game: Number of row groups of p1 matrix does not match state count.");
119 STORM_LOG_THROW(this->getTransitionMatrix().getRowGroupCount() == components.player1Matrix->getColumnCount(),
120 storm::exceptions::IllegalArgumentException,
121 "Can not create stochastic game: Number of row groups of p2 matrix does not match column count of p1 matrix.");
122 } else {
123 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Invalid model type.");
124 }
125
126 // Branch on continuous/discrete timing
127 if (this->isOfType(ModelType::Ctmc) || this->isOfType(ModelType::MarkovAutomaton)) {
128 STORM_LOG_THROW(components.rateTransitions || components.exitRates.is_initialized(), storm::exceptions::IllegalArgumentException,
129 "Can not create continuous time model: no rates are given.");
130 STORM_LOG_THROW(!components.exitRates.is_initialized() || components.exitRates->size() == stateCount, storm::exceptions::IllegalArgumentException,
131 "Size of exit rate vector does not match state count.");
132 STORM_LOG_THROW(this->isOfType(ModelType::Ctmc) || components.markovianStates.is_initialized(), storm::exceptions::IllegalArgumentException,
133 "Can not create Markov Automaton: no Markovian states given.");
134 } else {
135 STORM_LOG_WARN_COND(!components.rateTransitions && !components.exitRates.is_initialized(),
136 "Rates specified for discrete-time model. The rates will be ignored.");
137 }
138 STORM_LOG_WARN_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(),
139 "Markovian states given for a model that is not a Markov automaton (will be ignored).");
140
141 // Treat stochastic multiplayer games
142 if (this->isOfType(ModelType::Smg)) {
143 STORM_LOG_THROW(components.statePlayerIndications.is_initialized(), storm::exceptions::IllegalArgumentException,
144 "Can not create stochastic multiplayer game: Missing player indications.");
145 // playerNameToIndexMap is optional.
147 stateCount == components.statePlayerIndications->size(), storm::exceptions::IllegalArgumentException,
148 "Size of state player indications (" << components.statePlayerIndications->size() << ") of SMG does not match state count (" << stateCount << ").");
149 } else {
150 STORM_LOG_WARN_COND(!components.statePlayerIndications.is_initialized(),
151 "statePlayerIndications given for a model that is not a stochastic multiplayer game (will be ignored).");
152 STORM_LOG_WARN_COND(!components.playerNameToIndexMap.is_initialized(),
153 "playerNameToIndexMap given for a model that is not a stochastic multiplayer game (will be ignored).");
154 }
155}
157template<typename ValueType, typename RewardModelType>
161
162template<typename ValueType, typename RewardModelType>
164 return this->getTransitionMatrix().getColumnCount();
165}
166
167template<typename ValueType, typename RewardModelType>
169 return this->getTransitionMatrix().getNonzeroEntryCount();
171
172template<typename ValueType, typename RewardModelType>
174 return this->getTransitionMatrix().getRowCount();
175}
176
177template<typename ValueType, typename RewardModelType>
179 return this->getStates("init");
180}
181
182template<typename ValueType, typename RewardModelType>
184 return this->getStateLabeling().setStates("init", states);
185}
186
187template<typename ValueType, typename RewardModelType>
189 return stateLabeling.getStates(label);
190}
192template<typename ValueType, typename RewardModelType>
193bool Model<ValueType, RewardModelType>::hasLabel(std::string const& label) const {
194 return stateLabeling.containsLabel(label);
195}
196
197template<typename ValueType, typename RewardModelType>
199 return transitionMatrix;
200}
201
202template<typename ValueType, typename RewardModelType>
206
207template<typename ValueType, typename RewardModelType>
208bool Model<ValueType, RewardModelType>::hasRewardModel(std::string const& rewardModelName) const {
209 return this->rewardModels.find(rewardModelName) != this->rewardModels.end();
210}
212template<typename ValueType, typename RewardModelType>
214 STORM_LOG_ASSERT(this->hasRewardModel(rewardModelName), "Model has no reward model.");
215 return this->rewardModels.find(rewardModelName)->second;
217
218template<typename ValueType, typename RewardModelType>
219RewardModelType const& Model<ValueType, RewardModelType>::getRewardModel(std::string const& rewardModelName) const {
220 auto it = this->rewardModels.find(rewardModelName);
221 if (it == this->rewardModels.end()) {
222 if (rewardModelName.empty()) {
223 if (this->hasUniqueRewardModel()) {
224 return this->getUniqueRewardModel();
225 } else {
226 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException,
227 "Unable to refer to default reward model, because there is no default model or it is not unique.");
228 }
229 } else {
230 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "The requested reward model '" << rewardModelName << "' does not exist.");
231 }
232 }
233 return it->second;
234}
235
236template<typename ValueType, typename RewardModelType>
238 auto it = this->rewardModels.find(rewardModelName);
239 if (it == this->rewardModels.end()) {
240 if (rewardModelName.empty()) {
241 if (this->hasUniqueRewardModel()) {
242 return this->getUniqueRewardModel();
243 } else {
244 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException,
245 "Unable to refer to default reward model, because there is no default model or it is not unique.");
246 }
247 } else {
248 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "The requested reward model '" << rewardModelName << "' does not exist.");
249 }
250 }
251 return it->second;
253
254template<typename ValueType, typename RewardModelType>
255void Model<ValueType, RewardModelType>::addRewardModel(std::string const& rewardModelName, RewardModelType const& newRewardModel) {
256 if (this->hasRewardModel(rewardModelName)) {
257 STORM_LOG_THROW(!(this->hasRewardModel(rewardModelName)), storm::exceptions::IllegalArgumentException,
258 "A reward model with the given name '" << rewardModelName << "' already exists.");
260 STORM_LOG_ASSERT(newRewardModel.isCompatible(this->getNumberOfStates(), this->getTransitionMatrix().getRowCount()), "New reward model is not compatible.");
261 this->rewardModels.emplace(rewardModelName, newRewardModel);
262}
263
264template<typename ValueType, typename RewardModelType>
265bool Model<ValueType, RewardModelType>::removeRewardModel(std::string const& rewardModelName) {
266 auto it = this->rewardModels.find(rewardModelName);
267 bool res = (it != this->rewardModels.end());
268 if (res) {
269 this->rewardModels.erase(it->first);
270 }
271 return res;
272}
273
274template<typename ValueType, typename RewardModelType>
275void Model<ValueType, RewardModelType>::restrictRewardModels(std::set<std::string> const& keptRewardModels) {
276 std::set<std::string> removedRewardModels;
277 for (auto const& rewModel : this->getRewardModels()) {
278 if (keptRewardModels.find(rewModel.first) == keptRewardModels.end()) {
279 removedRewardModels.insert(rewModel.first);
280 }
282 for (auto const& rewModelName : removedRewardModels) {
283 this->removeRewardModel(rewModelName);
284 }
285}
286
287template<typename ValueType, typename RewardModelType>
289 return this->getNumberOfRewardModels() == 1;
290}
291
292template<typename ValueType, typename RewardModelType>
294 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
295 return this->rewardModels.begin()->first;
296}
297
298template<typename ValueType, typename RewardModelType>
300 return !this->rewardModels.empty();
301}
302
303template<typename ValueType, typename RewardModelType>
305 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
306 return this->rewardModels.cbegin()->second;
307}
308
309template<typename ValueType, typename RewardModelType>
311 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
312 return this->rewardModels.begin()->second;
313}
314
315template<typename ValueType, typename RewardModelType>
317 return this->rewardModels.size();
318}
319template<typename ValueType, typename RewardModelType>
323
324template<typename ValueType, typename RewardModelType>
326 return stateLabeling;
327}
328
329template<typename ValueType, typename RewardModelType>
331 return static_cast<bool>(choiceLabeling);
332}
333
334template<typename ValueType, typename RewardModelType>
338
339template<typename ValueType, typename RewardModelType>
340std::optional<storm::models::sparse::ChoiceLabeling> const& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() const {
341 return choiceLabeling;
342}
343
344template<typename ValueType, typename RewardModelType>
345std::optional<storm::models::sparse::ChoiceLabeling>& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() {
346 return choiceLabeling;
347}
348
349template<typename ValueType, typename RewardModelType>
351 return static_cast<bool>(stateValuations);
352}
353
354template<typename ValueType, typename RewardModelType>
358
359template<typename ValueType, typename RewardModelType>
360std::optional<storm::storage::sparse::StateValuations> const& Model<ValueType, RewardModelType>::getOptionalStateValuations() const {
361 return stateValuations;
362}
364template<typename ValueType, typename RewardModelType>
365std::optional<storm::storage::sparse::StateValuations>& Model<ValueType, RewardModelType>::getOptionalStateValuations() {
366 return stateValuations;
367}
368
369template<typename ValueType, typename RewardModelType>
371 return static_cast<bool>(choiceOrigins);
372}
374template<typename ValueType, typename RewardModelType>
375std::shared_ptr<storm::storage::sparse::ChoiceOrigins> const& Model<ValueType, RewardModelType>::getChoiceOrigins() const {
376 return choiceOrigins.value();
377}
378
379template<typename ValueType, typename RewardModelType>
380std::optional<std::shared_ptr<storm::storage::sparse::ChoiceOrigins>> const& Model<ValueType, RewardModelType>::getOptionalChoiceOrigins() const {
381 return choiceOrigins;
382}
383
384template<typename ValueType, typename RewardModelType>
385std::optional<std::shared_ptr<storm::storage::sparse::ChoiceOrigins>>& Model<ValueType, RewardModelType>::getOptionalChoiceOrigins() {
386 return choiceOrigins;
387}
388
389template<typename ValueType, typename RewardModelType>
391 this->printModelInformationHeaderToStream(out);
392 this->printModelInformationFooterToStream(out);
393}
394
395template<typename ValueType, typename RewardModelType>
397 std::size_t seed = 0;
398 boost::hash_combine(seed, transitionMatrix.hash());
399 boost::hash_combine(seed, stateLabeling.hash());
400 for (auto const& rewModel : rewardModels) {
401 boost::hash_combine(seed, rewModel.second.hash());
403 if (choiceLabeling) {
404 boost::hash_combine(seed, choiceLabeling->hash());
405 }
406 if (stateValuations) {
407 boost::hash_combine(seed, stateValuations->hash());
408 }
409 if (choiceOrigins) {
410 boost::hash_combine(seed, choiceOrigins.value()->hash());
411 }
412 return seed;
413}
414
415template<typename ValueType, typename RewardModelType>
417 out << "-------------------------------------------------------------- \n";
418 out << "Model type: \t" << (storm::IsIntervalType<ValueType> ? "I" : "") << this->getType() << " (sparse)\n";
419 out << "States: \t" << this->getNumberOfStates() << '\n';
420 out << "Transitions: \t" << this->getNumberOfTransitions() << '\n';
421}
422
423template<typename ValueType, typename RewardModelType>
425 this->printRewardModelsInformationToStream(out);
426 out << "State Labels: \t";
427 this->getStateLabeling().printLabelingInformationToStream(out);
428 out << "Choice Labels: \t";
429 if (this->hasChoiceLabeling()) {
430 this->getChoiceLabeling().printLabelingInformationToStream(out);
431 } else {
432 out << "none\n";
433 }
434 out << "-------------------------------------------------------------- \n";
435}
436
437template<typename ValueType, typename RewardModelType>
439 if (this->rewardModels.size()) {
440 std::vector<std::string> rewardModelNames;
441 std::for_each(this->rewardModels.cbegin(), this->rewardModels.cend(),
442 [&rewardModelNames](typename std::pair<std::string, RewardModelType> const& nameRewardModelPair) {
443 if (nameRewardModelPair.first.empty()) {
444 rewardModelNames.push_back("(default)");
445 } else {
446 rewardModelNames.push_back(nameRewardModelPair.first);
447 }
448 });
449 out << "Reward Models: " << boost::join(rewardModelNames, ", ") << '\n';
450 } else {
451 out << "Reward Models: none\n";
452 }
453}
454
455template<typename ValueType, typename RewardModelType>
456void Model<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, size_t maxWidthLabel, bool includeLabeling,
457 storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue,
458 std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring,
459 std::vector<std::string> const* colors, std::vector<uint_fast64_t>*, bool finalizeOutput) const {
460 outStream << "digraph model {\n";
461
462 // Write all states to the stream.
463 for (uint_fast64_t state = 0, highestStateIndex = this->getNumberOfStates() - 1; state <= highestStateIndex; ++state) {
464 if (subsystem == nullptr || subsystem->get(state)) {
465 outStream << "\t" << state;
466 if (includeLabeling || firstValue != nullptr || secondValue != nullptr || stateColoring != nullptr || hasStateValuations()) {
467 outStream << " [ ";
468
469 // If we need to print some extra information, do so now.
470 if (includeLabeling || firstValue != nullptr || secondValue != nullptr || hasStateValuations()) {
471 outStream << "label = \"" << state;
472 if (hasStateValuations()) {
473 std::string stateInfo = getStateValuations().getStateInfo(state);
474 std::vector<std::string> results;
475 boost::split(results, stateInfo, [](char c) { return c == ','; });
476 storm::io::outputFixedWidth(outStream, results, maxWidthLabel);
477 }
478 outStream << ": ";
479
480 // Now print the state labeling to the stream if requested.
481 if (includeLabeling) {
482 outStream << "{";
483 storm::io::outputFixedWidth(outStream, this->getLabelsOfState(state), maxWidthLabel);
484 outStream << "}";
485 }
486
487 outStream << this->additionalDotStateInfo(state);
488
489 // If we are to include some values for the state as well, we do so now.
490 if (firstValue != nullptr || secondValue != nullptr) {
491 outStream << " [";
492 if (firstValue != nullptr) {
493 outStream << (*firstValue)[state];
494 if (secondValue != nullptr) {
495 outStream << ", ";
496 }
497 }
498 if (secondValue != nullptr) {
499 outStream << (*secondValue)[state];
500 }
501 outStream << "]";
502 }
503 outStream << "\"";
504
505 // Now, we color the states if there were colors given.
506 if (stateColoring != nullptr && colors != nullptr) {
507 outStream << ", ";
508 outStream << " style = filled, fillcolor = " << (*colors)[(*stateColoring)[state]];
509 }
510 }
511 outStream << " ]";
512 }
513 outStream << ";\n";
514 }
515 }
516
517 // If this methods has not been called from a derived class, we want to close the digraph here.
518 if (finalizeOutput) {
519 outStream << "}\n";
520 }
521}
522
523template<typename ValueType, typename RewardModelType>
524void Model<ValueType, RewardModelType>::writeJsonToStream(std::ostream& outStream) const {
525 STORM_LOG_WARN_COND(this->getNumberOfStates() < 10000 && this->getNumberOfTransitions() < 100000,
526 "Exporting a large model to json. This might take some time and will result in a very large file.");
527 using JsonValueType = storm::RationalNumber;
529 for (uint64_t state = 0; state < getNumberOfStates(); ++state) {
530 storm::json<JsonValueType> stateChoicesJson;
531 stateChoicesJson["id"] = state;
532 if (hasStateValuations()) {
533 stateChoicesJson["s"] = getStateValuations().template toJson<JsonValueType>(state);
534 }
535 auto labels = getLabelsOfState(state);
536 stateChoicesJson["lab"] = labels;
537 storm::json<JsonValueType> stateRewardsJson;
538 for (auto const& rm : rewardModels) {
539 if (rm.second.hasStateRewards()) {
540 auto const& r = rm.second.getStateReward(state);
541 if (!storm::utility::isZero(r)) {
542 stateRewardsJson[rm.first] = storm::utility::to_string(r);
543 }
544 }
545 }
546 if (!stateRewardsJson.empty()) {
547 stateChoicesJson["rew"] = std::move(stateRewardsJson);
548 }
549
550 // For CTMCs we need to scale the transition probabilities as the transition matrix contains rates.
551 // This is not the case for MA.
552 auto rateForProbabilityScaling = storm::utility::one<ValueType>();
553 if (this->isOfType(storm::models::ModelType::Ctmc)) {
554 auto const& ctmc = this->template as<storm::models::sparse::Ctmc<ValueType, RewardModelType>>();
555 rateForProbabilityScaling = ctmc->getExitRateVector()[state];
556 stateChoicesJson["rate"] = storm::utility::to_string(rateForProbabilityScaling);
557 } else if (this->isOfType(storm::models::ModelType::MarkovAutomaton)) {
558 auto const& ma = this->template as<storm::models::sparse::MarkovAutomaton<ValueType, RewardModelType>>();
559 if (ma->isMarkovianState(state)) {
560 stateChoicesJson["rate"] = storm::utility::to_string(ma->getExitRate(state)); // Only export rate for Markovian states
561 }
562 }
563
564 storm::json<JsonValueType> choicesJson;
565 for (uint64_t choiceIndex = getTransitionMatrix().getRowGroupIndices()[state]; choiceIndex < getTransitionMatrix().getRowGroupIndices()[state + 1];
566 ++choiceIndex) {
568 if (hasChoiceOrigins() && getChoiceOrigins()->getIdentifier(choiceIndex) != getChoiceOrigins()->getIdentifierForChoicesWithNoOrigin()) {
569 choiceJson["origin"] = getChoiceOrigins()->getChoiceAsJson(choiceIndex);
570 }
571 if (hasChoiceLabeling()) {
572 auto choiceLabels = getChoiceLabeling().getLabelsOfChoice(choiceIndex);
573 if (!choiceLabels.empty()) {
574 choiceJson["lab"] = choiceLabels;
575 }
576 }
577 choiceJson["id"] = choiceIndex;
578 storm::json<JsonValueType> choiceRewardsJson;
579 for (auto const& rm : rewardModels) {
580 if (rm.second.hasStateActionRewards()) {
581 auto r = rm.second.getStateActionReward(choiceIndex);
582 if (!storm::utility::isZero(r)) {
583 choiceRewardsJson[rm.first] = storm::utility::to_string(r);
584 }
585 }
586 }
587 if (!choiceRewardsJson.empty()) {
588 choiceRewardsJson["rew"] = std::move(choiceRewardsJson);
589 }
591 for (auto const& entry : transitionMatrix.getRow(choiceIndex)) {
593 successor["id"] = entry.getColumn();
594 successor["prob"] = storm::utility::to_string<ValueType>(entry.getValue() / rateForProbabilityScaling);
595 successors.push_back(successor);
596 }
597 choiceJson["succ"] = std::move(successors);
598 choicesJson.push_back(choiceJson);
599 }
600 stateChoicesJson["c"] = std::move(choicesJson);
601 output.push_back(std::move(stateChoicesJson));
602 }
603 outStream << storm::dumpJson(output);
604}
605
606template<>
608 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Json export not implemented for this model type.");
609}
610
611template<typename ValueType, typename RewardModelType>
613 return "";
614}
615
616template<typename ValueType, typename RewardModelType>
618 return this->stateLabeling.getLabelsOfState(state);
619}
620
621template<typename ValueType, typename RewardModelType>
623 for (auto const& entry : this->getTransitionMatrix().getRowGroup(state)) {
624 if (entry.getColumn() != state) {
625 return false;
626 }
627 if (!storm::utility::isOne(entry.getValue())) {
628 return false;
629 }
630 }
631 return true;
632}
633
634template<typename ValueType, typename RewardModelType>
636 return true;
637}
638
639template<typename ValueType, typename RewardModelType>
641 return std::is_same<ValueType, storm::RationalFunction>::value;
642}
643
644template<typename ValueType, typename RewardModelType>
646 return std::is_same<ValueType, storm::Interval>::value;
647}
648
649template<typename ValueType, typename RewardModelType>
651 if (!this->supportsParameters()) {
652 return false;
653 }
654 // Check for parameters
655 for (auto const& entry : this->getTransitionMatrix()) {
656 if (!storm::utility::isConstant(entry.getValue())) {
657 return true;
658 }
659 }
660 // Only constant values present
661 return false;
662}
663
664template<typename ValueType, typename RewardModelType>
666 if (!this->supportsUncertainty()) {
667 return false;
668 }
669 // Check for intervals
670 for (auto const& entry : this->getTransitionMatrix()) {
671 if (!storm::utility::isConstant(entry.getValue())) {
672 return true;
673 }
674 }
675 // Only constant values present
676 return false;
677}
678
679template<typename ValueType, typename RewardModelType>
683
684template<typename ValueType, typename RewardModelType>
685std::unordered_map<std::string, RewardModelType>& Model<ValueType, RewardModelType>::getRewardModels() {
686 return this->rewardModels;
687}
688
689template<typename ValueType, typename RewardModelType>
690std::unordered_map<std::string, RewardModelType> const& Model<ValueType, RewardModelType>::getRewardModels() const {
691 return this->rewardModels;
692}
693
694std::set<storm::RationalFunctionVariable> getProbabilityParameters(Model<storm::RationalFunction> const& model) {
696}
697
698std::set<storm::RationalFunctionVariable> getRewardParameters(Model<storm::RationalFunction> const& model) {
699 std::set<storm::RationalFunctionVariable> result;
700 for (auto rewModel : model.getRewardModels()) {
701 std::set<storm::RationalFunctionVariable> tmp = getRewardModelParameters(rewModel.second);
702 result.insert(tmp.begin(), tmp.end());
703 }
704 return result;
705}
706
707std::set<storm::RationalFunctionVariable> getRateParameters(Model<storm::RationalFunction> const& model) {
709 auto const& ctmc = model.template as<storm::models::sparse::Ctmc<storm::RationalFunction>>();
710 return storm::utility::vector::getVariables(ctmc->getExitRateVector());
712 auto const& ma = model.template as<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>>();
713 return storm::utility::vector::getVariables(ma->getExitRates());
714 } else {
715 return {};
716 }
717}
718
719std::set<storm::RationalFunctionVariable> getAllParameters(Model<storm::RationalFunction> const& model) {
720 std::set<storm::RationalFunctionVariable> parameters = getProbabilityParameters(model);
721 std::set<storm::RationalFunctionVariable> rewardParameters = getRewardParameters(model);
722 parameters.insert(rewardParameters.begin(), rewardParameters.end());
723 std::set<storm::RationalFunctionVariable> rateParameters = getRateParameters(model);
724 parameters.insert(rateParameters.begin(), rateParameters.end());
725 return parameters;
726}
727
728template class Model<double>;
730template class Model<storm::RationalNumber>;
731template class Model<storm::Interval>;
732template class Model<storm::RationalFunction>;
733} // namespace sparse
734} // namespace models
735} // namespace storm
virtual bool isExact() const
Checks whether the model is exact.
Definition ModelBase.cpp:62
virtual bool hasParameters() const
Checks whether the model has parameters.
Definition ModelBase.cpp:58
virtual bool isSparseModel() const
Checks whether the model is a sparse model.
Definition ModelBase.cpp:11
bool isOfType(storm::models::ModelType const &modelType) const
Checks whether the model is of the given type.
Definition ModelBase.cpp:27
virtual bool supportsUncertainty() const
Does it support uncertainty (e.g., via interval-valued entries).
Definition ModelBase.cpp:23
virtual bool supportsParameters() const
Checks whether the model supports parameters.
Definition ModelBase.cpp:54
This class manages the labeling of the choice space with a number of (atomic) labels.
Base class for all sparse models.
Definition Model.h:30
storm::models::sparse::ChoiceLabeling const & getChoiceLabeling() const
Retrieves the labels for the choices of the model.
Definition Model.cpp:335
RewardModelType const & getUniqueRewardModel() const
Retrieves the unique reward model, if there exists exactly one.
Definition Model.cpp:304
bool hasRewardModel() const
Retrieves whether the model has at least one reward model.
Definition Model.cpp:299
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:198
virtual std::size_t hash() const
Definition Model.cpp:396
Model(Model< ValueType, RewardModelType > const &other)=default
void setInitialStates(storm::storage::BitVector const &states)
Overwrites the initial states of the model.
Definition Model.cpp:183
void printModelInformationFooterToStream(std::ostream &out) const
Prints the information footer (reward models, labels and size in memory) of the model to the specifie...
Definition Model.cpp:424
virtual void printModelInformationToStream(std::ostream &out) const override
Prints information about the model to the specified stream.
Definition Model.cpp:390
std::unordered_map< std::string, RewardModelType > const & getRewardModels() const
Retrieves the reward models.
Definition Model.cpp:690
void restrictRewardModels(std::set< std::string > const &keptRewardModels)
Removes all reward models whose name is not in the given set.
Definition Model.cpp:275
bool hasStateValuations() const
Retrieves whether this model was build with state valuations.
Definition Model.cpp:350
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
Definition Model.cpp:188
bool removeRewardModel(std::string const &rewardModelName)
Removes the reward model with the given name from the model.
Definition Model.cpp:265
void printRewardModelsInformationToStream(std::ostream &out) const
Prints information about the reward models to the specified stream.
Definition Model.cpp:438
std::set< std::string > getLabelsOfState(storm::storage::sparse::state_type state) const
Retrieves the set of labels attached to the given state.
Definition Model.cpp:617
std::optional< std::shared_ptr< storm::storage::sparse::ChoiceOrigins > > const & getOptionalChoiceOrigins() const
Retrieves an optional value that contains the choice origins if there are some.
Definition Model.cpp:380
RewardModelType & rewardModel(std::string const &rewardModelName)
Definition Model.cpp:213
virtual uint_fast64_t getNumberOfChoices() const override
Returns the number of choices ine the model.
Definition Model.cpp:173
storm::storage::sparse::StateValuations const & getStateValuations() const
Retrieves the valuations of the states of the model.
Definition Model.cpp:355
void addRewardModel(std::string const &rewardModelName, RewardModelType const &rewModel)
Adds a reward model to the model.
Definition Model.cpp:255
std::shared_ptr< storm::storage::sparse::ChoiceOrigins > const & getChoiceOrigins() const
Retrieves the origins of the choices of the model.
Definition Model.cpp:375
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
Definition Model.cpp:158
bool hasChoiceLabeling() const
Retrieves whether this model has a labeling of the choices.
Definition Model.cpp:330
uint_fast64_t getNumberOfRewardModels() const
Retrieves the number of reward models associated with this model.
Definition Model.cpp:316
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
Definition Model.cpp:320
void printModelInformationHeaderToStream(std::ostream &out) const
Prints the information header (number of states and transitions) of the model to the specified stream...
Definition Model.cpp:416
std::optional< storm::models::sparse::ChoiceLabeling > const & getOptionalChoiceLabeling() const
Retrieves an optional value that contains the choice labeling if there is one.
Definition Model.cpp:340
CRewardModelType RewardModelType
Definition Model.h:33
virtual bool hasUniqueRewardModel() const override
Retrieves whether the model has a unique reward model.
Definition Model.cpp:288
std::optional< storm::storage::sparse::StateValuations > const & getOptionalStateValuations() const
Retrieves an optional value that contains the state valuations if there are some.
Definition Model.cpp:360
virtual uint_fast64_t getNumberOfTransitions() const override
Returns the number of (non-zero) transitions of the model.
Definition Model.cpp:168
bool hasChoiceOrigins() const
Retrieves whether this model was build with choice origins.
Definition Model.cpp:370
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
Definition Model.cpp:163
bool hasLabel(std::string const &label) const
Retrieves whether the given label is a valid label in this model.
Definition Model.cpp:193
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
Definition Model.cpp:219
virtual std::string const & getUniqueRewardModelName() const override
Retrieves the name of the unique reward model, if there exists exactly one.
Definition Model.cpp:293
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:178
This class manages the labeling of the state space with a number of (atomic) labels.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that holds a possibly non-square matrix in the compressed row storage format.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:52
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
void outputFixedWidth(std::ostream &stream, Container const &output, size_t maxWidth=30)
Output list of strings with linebreaks according to fixed width.
Definition export.h:60
std::set< storm::RationalFunctionVariable > getRateParameters(Model< storm::RationalFunction > const &model)
Get all parameters occurring in rates.
Definition Model.cpp:707
std::set< storm::RationalFunctionVariable > getRewardParameters(Model< storm::RationalFunction > const &model)
Get all parameters occurring in rewards.
Definition Model.cpp:698
std::set< storm::RationalFunctionVariable > getRewardModelParameters(StandardRewardModel< storm::RationalFunction > const &rewModel)
std::set< storm::RationalFunctionVariable > getProbabilityParameters(Model< storm::RationalFunction > const &model)
Get all probability parameters occurring on transitions.
Definition Model.cpp:694
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
Definition Model.cpp:719
std::set< storm::RationalFunctionVariable > getVariables(SparseMatrix< storm::RationalFunction > const &matrix)
std::set< storm::RationalFunctionVariable > getVariables(std::vector< storm::RationalFunction > const &vector)
bool isOne(ValueType const &a)
Definition constants.cpp:34
bool isConstant(ValueType const &)
bool isZero(ValueType const &a)
Definition constants.cpp:39
std::string to_string(ValueType const &value)
nlohmann::basic_json< std::map, std::vector, std::string, bool, int64_t, uint64_t, ValueType > json
Definition JsonForward.h:10
std::string dumpJson(storm::json< ValueType > const &j, bool compact)
Dumps the given json object, producing a String.
boost::optional< storm::storage::BitVector > markovianStates
boost::optional< std::vector< storm::storage::PlayerIndex > > statePlayerIndications
boost::optional< storm::storage::SparseMatrix< storm::storage::sparse::state_type > > player1Matrix
boost::optional< std::map< std::string, storm::storage::PlayerIndex > > playerNameToIndexMap
boost::optional< std::vector< ValueType > > exitRates