Storm 1.14.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
14#include "storm/io/export.h"
22
23namespace storm {
24namespace models {
25namespace sparse {
26
27template<typename ValueType, typename RewardModelType>
29 : storm::models::Model<ValueType>(other),
30 transitionMatrix(other.transitionMatrix),
31 stateLabeling(other.stateLabeling),
32 rewardModels(other.rewardModels),
33 choiceLabeling(other.choiceLabeling),
34 stateValuations(other.stateValuations),
35 choiceOrigins(other.choiceOrigins),
36 stochasticTolerance(other.stochasticTolerance ? std::make_unique<ValueType>(*other.stochasticTolerance) : nullptr) {
37 // Intentionally left empty.
38}
39
40template<typename ValueType, typename RewardModelType>
42 if (this != &other) {
44 transitionMatrix = other.transitionMatrix;
45 stateLabeling = other.stateLabeling;
46 rewardModels = other.rewardModels;
47 choiceLabeling = other.choiceLabeling;
48 stateValuations = other.stateValuations;
49 choiceOrigins = other.choiceOrigins;
50 stochasticTolerance = other.stochasticTolerance ? std::make_unique<ValueType>(*other.stochasticTolerance) : nullptr;
51 }
52 return *this;
53}
54
55template<typename ValueType, typename RewardModelType>
57 : storm::models::Model<ValueType>(modelType),
58 transitionMatrix(components.transitionMatrix),
59 stateLabeling(components.stateLabeling),
60 rewardModels(components.rewardModels),
61 choiceLabeling(components.choiceLabeling),
62 stateValuations(components.stateValuations),
63 choiceOrigins(components.choiceOrigins) {
64 stochasticTolerance = std::make_unique<ValueType>(components.stochasticTolerance.value_or(
66 assertValidityOfComponents(components);
67}
68
69template<typename ValueType, typename RewardModelType>
71 : storm::models::Model<ValueType>(modelType),
72 transitionMatrix(std::move(components.transitionMatrix)),
73 stateLabeling(std::move(components.stateLabeling)),
74 rewardModels(std::move(components.rewardModels)),
75 choiceLabeling(std::move(components.choiceLabeling)),
76 stateValuations(std::move(components.stateValuations)),
77 choiceOrigins(std::move(components.choiceOrigins)) {
78 stochasticTolerance = std::make_unique<ValueType>(components.stochasticTolerance.value_or(
80 assertValidityOfComponents(components);
82
83template<typename ValueType, typename RewardModelType>
84void Model<ValueType, RewardModelType>::assertValidityOfComponents(
86 // More costly checks are only asserted to avoid doing them in release mode.
87
88 uint64_t stateCount = this->getNumberOfStates();
89 uint64_t choiceCount = this->getTransitionMatrix().getRowCount();
90
91 // general components for all model types.
92 STORM_LOG_THROW(this->getTransitionMatrix().getColumnCount() == stateCount, storm::exceptions::IllegalArgumentException,
93 "Invalid column count of transition matrix.");
94 {
95 [[maybe_unused]] std::string reasonNotProbabilistic;
96 STORM_LOG_ASSERT(components.rateTransitions || this->getTransitionMatrix().isProbabilistic(*this->stochasticTolerance, reasonNotProbabilistic),
97 "The matrix is not probabilistic. " << reasonNotProbabilistic);
98 }
99 STORM_LOG_THROW(this->getStateLabeling().getNumberOfItems() == stateCount, storm::exceptions::IllegalArgumentException,
100 "Invalid item count (" << this->getStateLabeling().getNumberOfItems() << ") of state labeling (states: " << stateCount << ").");
101 for (auto const& rewardModel : this->getRewardModels()) {
102 STORM_LOG_THROW(!rewardModel.second.hasStateRewards() || rewardModel.second.getStateRewardVector().size() == stateCount,
103 storm::exceptions::IllegalArgumentException,
104 "Invalid size (" << rewardModel.second.getStateRewardVector().size() << ") of state reward vector (states:" << stateCount << ").");
106 !rewardModel.second.hasStateActionRewards() || rewardModel.second.getStateActionRewardVector().size() == choiceCount,
107 storm::exceptions::IllegalArgumentException,
108 "Invalid size (" << rewardModel.second.getStateActionRewardVector().size() << ") of state action reward vector (expected:" << choiceCount << ").");
110 !rewardModel.second.hasTransitionRewards() || rewardModel.second.getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()),
111 "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
112 }
114 !this->hasChoiceLabeling() || this->getChoiceLabeling().getNumberOfItems() == choiceCount, storm::exceptions::IllegalArgumentException,
115 "Invalid choice count of choice labeling (choices: " << choiceCount << " vs. labeling:" << this->getChoiceLabeling().getNumberOfItems() << ").");
117 !this->hasStateValuations() || this->getStateValuations().getNumberOfEntities() == stateCount, storm::exceptions::IllegalArgumentException,
118 "Invalid state count for state valuations (states: " << stateCount << " vs. valuations:" << this->getStateValuations().getNumberOfEntities() << ").");
120 !this->hasChoiceOrigins() || this->getChoiceOrigins()->getNumberOfChoices() == choiceCount, storm::exceptions::IllegalArgumentException,
121 "Invalid choice count for choice origins. (choices: " << choiceCount << " vs. origins:" << this->getChoiceOrigins()->getNumberOfChoices() << ").");
122
123 // Branch on type of nondeterminism
124 if (this->isOfType(ModelType::Dtmc) || this->isOfType(ModelType::Ctmc)) {
125 STORM_LOG_THROW(this->getTransitionMatrix().hasTrivialRowGrouping(), storm::exceptions::IllegalArgumentException,
126 "Can not create deterministic model: Transition matrix has non-trivial row grouping.");
127 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getRowCount(), storm::exceptions::IllegalArgumentException,
128 "Can not create deterministic model: Number of rows of transition matrix does not match state count.");
129 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getColumnCount(), storm::exceptions::IllegalArgumentException,
130 "Can not create deterministic model: Number of columns of transition matrix does not match state count.");
131 STORM_LOG_ERROR_COND(!components.player1Matrix.is_initialized(), "Player 1 matrix given for a model that is no stochastic game (will be ignored).");
132 } else if (this->isOfType(ModelType::Mdp) || this->isOfType(ModelType::MarkovAutomaton) || this->isOfType(ModelType::Pomdp) ||
133 this->isOfType(ModelType::Smg)) {
134 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getRowGroupCount(), storm::exceptions::IllegalArgumentException,
135 "Can not create nondeterministic model: Number of row groups ("
136 << this->getTransitionMatrix().getRowGroupCount() << ") of transition matrix does not match state count (" << stateCount << ").");
137 STORM_LOG_THROW(stateCount == this->getTransitionMatrix().getColumnCount(), storm::exceptions::IllegalArgumentException,
138 "Can not create nondeterministic model: Number of columns of transition matrix does not match state count.");
139 STORM_LOG_ERROR_COND(!components.player1Matrix.is_initialized(), "Player 1 matrix given for a model that is no stochastic game (will be ignored).");
140 } else if (this->isOfType(ModelType::S2pg)) {
141 STORM_LOG_THROW(components.player1Matrix.is_initialized(), storm::exceptions::IllegalArgumentException,
142 "No player 1 matrix given for stochastic game.");
143 STORM_LOG_ASSERT(components.player1Matrix->isProbabilistic(0),
144 "Can not create stochastic game: There is a row in the p1 matrix with not exactly one entry.");
145 STORM_LOG_THROW(stateCount == components.player1Matrix->getRowGroupCount(), storm::exceptions::IllegalArgumentException,
146 "Can not create stochastic game: Number of row groups of p1 matrix does not match state count.");
147 STORM_LOG_THROW(this->getTransitionMatrix().getRowGroupCount() == components.player1Matrix->getColumnCount(),
148 storm::exceptions::IllegalArgumentException,
149 "Can not create stochastic game: Number of row groups of p2 matrix does not match column count of p1 matrix.");
150 } else {
151 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Invalid model type.");
152 }
153
154 // Branch on continuous/discrete timing
155 if (this->isOfType(ModelType::Ctmc) || this->isOfType(ModelType::MarkovAutomaton)) {
156 STORM_LOG_THROW(components.rateTransitions || components.exitRates.is_initialized(), storm::exceptions::IllegalArgumentException,
157 "Can not create continuous time model: no rates are given.");
158 STORM_LOG_THROW(!components.exitRates.is_initialized() || components.exitRates->size() == stateCount, storm::exceptions::IllegalArgumentException,
159 "Size of exit rate vector does not match state count.");
160 STORM_LOG_THROW(this->isOfType(ModelType::Ctmc) || components.markovianStates.is_initialized(), storm::exceptions::IllegalArgumentException,
161 "Can not create Markov Automaton: no Markovian states given.");
162 } else {
163 STORM_LOG_WARN_COND(!components.rateTransitions && !components.exitRates.is_initialized(),
164 "Rates specified for discrete-time model. The rates will be ignored.");
165 }
166 STORM_LOG_WARN_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(),
167 "Markovian states given for a model that is not a Markov automaton (will be ignored).");
168
169 // Treat stochastic multiplayer games
170 if (this->isOfType(ModelType::Smg)) {
171 STORM_LOG_THROW(components.statePlayerIndications.is_initialized(), storm::exceptions::IllegalArgumentException,
172 "Can not create stochastic multiplayer game: Missing player indications.");
173 // playerNameToIndexMap is optional.
175 stateCount == components.statePlayerIndications->size(), storm::exceptions::IllegalArgumentException,
176 "Size of state player indications (" << components.statePlayerIndications->size() << ") of SMG does not match state count (" << stateCount << ").");
177 } else {
178 STORM_LOG_WARN_COND(!components.statePlayerIndications.is_initialized(),
179 "statePlayerIndications given for a model that is not a stochastic multiplayer game (will be ignored).");
180 STORM_LOG_WARN_COND(!components.playerNameToIndexMap.is_initialized(),
181 "playerNameToIndexMap given for a model that is not a stochastic multiplayer game (will be ignored).");
182 }
183}
184
185template<typename ValueType, typename RewardModelType>
189
190template<typename ValueType, typename RewardModelType>
192 return this->getTransitionMatrix().getColumnCount();
193}
194
195template<typename ValueType, typename RewardModelType>
197 return this->getTransitionMatrix().getNonzeroEntryCount();
198}
199
200template<typename ValueType, typename RewardModelType>
202 return this->getTransitionMatrix().getRowCount();
203}
204
205template<typename ValueType, typename RewardModelType>
209
210template<typename ValueType, typename RewardModelType>
212 return this->getStateLabeling().setStates("init", states);
213}
214
215template<typename ValueType, typename RewardModelType>
217 return stateLabeling.getStates(label);
218}
219
220template<typename ValueType, typename RewardModelType>
221bool Model<ValueType, RewardModelType>::hasLabel(std::string const& label) const {
222 return stateLabeling.containsLabel(label);
224
225template<typename ValueType, typename RewardModelType>
230template<typename ValueType, typename RewardModelType>
235template<typename ValueType, typename RewardModelType>
236bool Model<ValueType, RewardModelType>::hasRewardModel(std::string const& rewardModelName) const {
237 return this->rewardModels.find(rewardModelName) != this->rewardModels.end();
238}
239
240template<typename ValueType, typename RewardModelType>
242 STORM_LOG_ASSERT(this->hasRewardModel(rewardModelName), "Model has no reward model.");
243 return this->rewardModels.find(rewardModelName)->second;
244}
245
246template<typename ValueType, typename RewardModelType>
247RewardModelType const& Model<ValueType, RewardModelType>::getRewardModel(std::string const& rewardModelName) const {
248 auto it = this->rewardModels.find(rewardModelName);
249 if (it == this->rewardModels.end()) {
250 if (rewardModelName.empty()) {
251 if (this->hasUniqueRewardModel()) {
252 return this->getUniqueRewardModel();
253 } else {
254 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException,
255 "Unable to refer to default reward model, because there is no default model or it is not unique.");
256 }
257 } else {
258 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "The requested reward model '" << rewardModelName << "' does not exist.");
259 }
260 }
261 return it->second;
262}
264template<typename ValueType, typename RewardModelType>
266 auto it = this->rewardModels.find(rewardModelName);
267 if (it == this->rewardModels.end()) {
268 if (rewardModelName.empty()) {
269 if (this->hasUniqueRewardModel()) {
270 return this->getUniqueRewardModel();
271 } else {
272 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException,
273 "Unable to refer to default reward model, because there is no default model or it is not unique.");
274 }
275 } else {
276 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "The requested reward model '" << rewardModelName << "' does not exist.");
277 }
278 }
279 return it->second;
280}
281
282template<typename ValueType, typename RewardModelType>
283void Model<ValueType, RewardModelType>::addRewardModel(std::string const& rewardModelName, RewardModelType const& newRewardModel) {
284 if (this->hasRewardModel(rewardModelName)) {
285 STORM_LOG_THROW(!this->hasRewardModel(rewardModelName), storm::exceptions::IllegalArgumentException,
286 "A reward model with the given name '" << rewardModelName << "' already exists.");
287 }
288 STORM_LOG_ASSERT(newRewardModel.isCompatible(this->getNumberOfStates(), this->getTransitionMatrix().getRowCount()), "New reward model is not compatible.");
289 this->rewardModels.emplace(rewardModelName, newRewardModel);
290}
291
292template<typename ValueType, typename RewardModelType>
293bool Model<ValueType, RewardModelType>::removeRewardModel(std::string const& rewardModelName) {
294 auto it = this->rewardModels.find(rewardModelName);
295 bool res = (it != this->rewardModels.end());
296 if (res) {
297 this->rewardModels.erase(it->first);
298 }
299 return res;
300}
301
302template<typename ValueType, typename RewardModelType>
303void Model<ValueType, RewardModelType>::restrictRewardModels(std::set<std::string> const& keptRewardModels) {
304 std::set<std::string> removedRewardModels;
305 for (auto const& rewModel : this->getRewardModels()) {
306 if (keptRewardModels.find(rewModel.first) == keptRewardModels.end()) {
307 removedRewardModels.insert(rewModel.first);
308 }
309 }
310 for (auto const& rewModelName : removedRewardModels) {
311 this->removeRewardModel(rewModelName);
312 }
314
315template<typename ValueType, typename RewardModelType>
319
320template<typename ValueType, typename RewardModelType>
322 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
323 return this->rewardModels.begin()->first;
324}
325
326template<typename ValueType, typename RewardModelType>
328 return !this->rewardModels.empty();
329}
330
331template<typename ValueType, typename RewardModelType>
333 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
334 return this->rewardModels.cbegin()->second;
335}
336
337template<typename ValueType, typename RewardModelType>
339 STORM_LOG_THROW(this->getNumberOfRewardModels() == 1, storm::exceptions::IllegalFunctionCallException, "The reward model is not unique.");
340 return this->rewardModels.begin()->second;
341}
343template<typename ValueType, typename RewardModelType>
345 return this->rewardModels.size();
346}
347template<typename ValueType, typename RewardModelType>
351
352template<typename ValueType, typename RewardModelType>
356
357template<typename ValueType, typename RewardModelType>
359 return static_cast<bool>(choiceLabeling);
360}
361
362template<typename ValueType, typename RewardModelType>
366
367template<typename ValueType, typename RewardModelType>
368std::optional<storm::models::sparse::ChoiceLabeling> const& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() const {
369 return choiceLabeling;
370}
371
372template<typename ValueType, typename RewardModelType>
373std::optional<storm::models::sparse::ChoiceLabeling>& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() {
374 return choiceLabeling;
375}
376
377template<typename ValueType, typename RewardModelType>
379 return static_cast<bool>(stateValuations);
380}
382template<typename ValueType, typename RewardModelType>
386
387template<typename ValueType, typename RewardModelType>
388std::optional<storm::storage::sparse::Valuations> const& Model<ValueType, RewardModelType>::getOptionalStateValuations() const {
389 return stateValuations;
390}
392template<typename ValueType, typename RewardModelType>
393std::optional<storm::storage::sparse::Valuations>& Model<ValueType, RewardModelType>::getOptionalStateValuations() {
394 return stateValuations;
395}
396
397template<typename ValueType, typename RewardModelType>
399 return static_cast<bool>(choiceOrigins);
400}
401
402template<typename ValueType, typename RewardModelType>
403std::shared_ptr<storm::storage::sparse::ChoiceOrigins> const& Model<ValueType, RewardModelType>::getChoiceOrigins() const {
404 return choiceOrigins.value();
405}
406
407template<typename ValueType, typename RewardModelType>
408std::optional<std::shared_ptr<storm::storage::sparse::ChoiceOrigins>> const& Model<ValueType, RewardModelType>::getOptionalChoiceOrigins() const {
409 return choiceOrigins;
411
412template<typename ValueType, typename RewardModelType>
413std::optional<std::shared_ptr<storm::storage::sparse::ChoiceOrigins>>& Model<ValueType, RewardModelType>::getOptionalChoiceOrigins() {
414 return choiceOrigins;
415}
416
417template<typename ValueType, typename RewardModelType>
421}
422
423template<typename ValueType, typename RewardModelType>
425 std::size_t seed = 0;
426 boost::hash_combine(seed, transitionMatrix.hash());
427 boost::hash_combine(seed, stateLabeling.hash());
428 for (auto const& rewModel : rewardModels) {
429 boost::hash_combine(seed, rewModel.second.hash());
430 }
431 if (choiceLabeling) {
432 boost::hash_combine(seed, choiceLabeling->hash());
433 }
434 if (stateValuations) {
435 boost::hash_combine(seed, stateValuations->hash());
436 }
437 if (choiceOrigins) {
438 boost::hash_combine(seed, choiceOrigins.value()->hash());
439 }
440 return seed;
441}
443template<typename ValueType, typename RewardModelType>
445 out << "-------------------------------------------------------------- \n";
446 out << "Model type: \t" << (storm::IsIntervalType<ValueType> ? "I" : "") << this->getType() << " (sparse)\n";
447 out << "States: \t" << this->getNumberOfStates() << '\n';
448 out << "Transitions: \t" << this->getNumberOfTransitions() << '\n';
449}
450
451template<typename ValueType, typename RewardModelType>
454 out << "State Labels: \t";
455 this->getStateLabeling().printLabelingInformationToStream(out);
456 out << "Choice Labels: \t";
457 if (this->hasChoiceLabeling()) {
458 this->getChoiceLabeling().printLabelingInformationToStream(out);
459 } else {
460 out << "none\n";
461 }
462 out << "-------------------------------------------------------------- \n";
463}
464
465template<typename ValueType, typename RewardModelType>
467 if (this->rewardModels.size()) {
468 std::vector<std::string> rewardModelNames;
469 std::for_each(this->rewardModels.cbegin(), this->rewardModels.cend(),
470 [&rewardModelNames](typename std::pair<std::string, RewardModelType> const& nameRewardModelPair) {
471 if (nameRewardModelPair.first.empty()) {
472 rewardModelNames.push_back("(default)");
473 } else {
474 rewardModelNames.push_back(nameRewardModelPair.first);
475 }
476 });
477 out << "Reward Models: " << boost::join(rewardModelNames, ", ") << '\n';
478 } else {
479 out << "Reward Models: none\n";
480 }
481}
482
483template<typename ValueType, typename RewardModelType>
484void Model<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, size_t maxWidthLabel, bool includeLabeling,
485 storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue,
486 std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring,
487 std::vector<std::string> const* colors, std::vector<uint_fast64_t>*, bool finalizeOutput) const {
488 outStream << "digraph model {\n";
489
490 // Write all states to the stream.
491 for (uint_fast64_t state = 0, highestStateIndex = this->getNumberOfStates() - 1; state <= highestStateIndex; ++state) {
492 if (subsystem == nullptr || subsystem->get(state)) {
493 outStream << "\t" << state;
494 if (includeLabeling || firstValue != nullptr || secondValue != nullptr || stateColoring != nullptr || hasStateValuations()) {
495 outStream << " [ ";
496
497 // If we need to print some extra information, do so now.
498 if (includeLabeling || firstValue != nullptr || secondValue != nullptr || hasStateValuations()) {
499 outStream << "label = \"" << state;
500 if (hasStateValuations()) {
501 std::string stateInfo = getStateValuations().toString(state);
502 std::vector<std::string> results;
503 boost::split(results, stateInfo, [](char c) { return c == ','; });
504 storm::io::outputFixedWidth(outStream, results, maxWidthLabel);
505 }
506 outStream << ": ";
507
508 // Now print the state labeling to the stream if requested.
509 if (includeLabeling) {
510 outStream << "{";
511 storm::io::outputFixedWidth(outStream, this->getLabelsOfState(state), maxWidthLabel);
512 outStream << "}";
513 }
514
515 outStream << this->additionalDotStateInfo(state);
516
517 // If we are to include some values for the state as well, we do so now.
518 if (firstValue != nullptr || secondValue != nullptr) {
519 outStream << " [";
520 if (firstValue != nullptr) {
521 outStream << (*firstValue)[state];
522 if (secondValue != nullptr) {
523 outStream << ", ";
524 }
525 }
526 if (secondValue != nullptr) {
527 outStream << (*secondValue)[state];
528 }
529 outStream << "]";
530 }
531 outStream << "\"";
532
533 // Now, we color the states if there were colors given.
534 if (stateColoring != nullptr && colors != nullptr) {
535 outStream << ", ";
536 outStream << " style = filled, fillcolor = " << (*colors)[(*stateColoring)[state]];
537 }
538 }
539 outStream << " ]";
540 }
541 outStream << ";\n";
542 }
543 }
544
545 // If this methods has not been called from a derived class, we want to close the digraph here.
546 if (finalizeOutput) {
547 outStream << "}\n";
548 }
549}
550
551template<typename ValueType, typename RewardModelType>
552void Model<ValueType, RewardModelType>::writeJsonToStream(std::ostream& outStream) const {
553 STORM_LOG_WARN_COND(this->getNumberOfStates() < 10000 && this->getNumberOfTransitions() < 100000,
554 "Exporting a large model to json. This might take some time and will result in a very large file.");
555 using JsonValueType = storm::RationalNumber;
557 for (uint64_t state = 0; state < getNumberOfStates(); ++state) {
558 storm::json<JsonValueType> stateChoicesJson;
559 stateChoicesJson["id"] = state;
560 if (hasStateValuations()) {
561 stateChoicesJson["s"] = getStateValuations().template toJson<JsonValueType>(state);
562 }
563 auto labels = getLabelsOfState(state);
564 stateChoicesJson["lab"] = labels;
565 storm::json<JsonValueType> stateRewardsJson;
566 for (auto const& rm : rewardModels) {
567 if (rm.second.hasStateRewards()) {
568 auto const& r = rm.second.getStateReward(state);
569 if (!storm::utility::isZero(r)) {
570 stateRewardsJson[rm.first] = storm::utility::to_string(r);
571 }
572 }
573 }
574 if (!stateRewardsJson.empty()) {
575 stateChoicesJson["rew"] = std::move(stateRewardsJson);
576 }
577
578 // For CTMCs we need to scale the transition probabilities as the transition matrix contains rates.
579 // This is not the case for MA.
580 auto rateForProbabilityScaling = storm::utility::one<ValueType>();
582 auto const& ctmc = this->template as<storm::models::sparse::Ctmc<ValueType, RewardModelType>>();
583 rateForProbabilityScaling = ctmc->getExitRateVector()[state];
584 stateChoicesJson["rate"] = storm::utility::to_string(rateForProbabilityScaling);
587 if (ma->isMarkovianState(state)) {
588 stateChoicesJson["rate"] = storm::utility::to_string(ma->getExitRate(state)); // Only export rate for Markovian states
589 }
590 }
591
592 storm::json<JsonValueType> choicesJson;
593 for (uint64_t choiceIndex = getTransitionMatrix().getRowGroupIndices()[state]; choiceIndex < getTransitionMatrix().getRowGroupIndices()[state + 1];
594 ++choiceIndex) {
596 if (hasChoiceOrigins() && getChoiceOrigins()->getIdentifier(choiceIndex) != getChoiceOrigins()->getIdentifierForChoicesWithNoOrigin()) {
597 choiceJson["origin"] = getChoiceOrigins()->getChoiceAsJson(choiceIndex);
598 }
599 if (hasChoiceLabeling()) {
600 auto choiceLabels = getChoiceLabeling().getLabelsOfChoice(choiceIndex);
601 if (!choiceLabels.empty()) {
602 choiceJson["lab"] = choiceLabels;
603 }
604 }
605 choiceJson["id"] = choiceIndex;
606 storm::json<JsonValueType> choiceRewardsJson;
607 for (auto const& rm : rewardModels) {
608 if (rm.second.hasStateActionRewards()) {
609 auto r = rm.second.getStateActionReward(choiceIndex);
610 if (!storm::utility::isZero(r)) {
611 choiceRewardsJson[rm.first] = storm::utility::to_string(r);
612 }
613 }
614 }
615 if (!choiceRewardsJson.empty()) {
616 choiceJson["rew"] = std::move(choiceRewardsJson);
617 }
619 for (auto const& entry : transitionMatrix.getRow(choiceIndex)) {
621 successor["id"] = entry.getColumn();
622 successor["prob"] = storm::utility::to_string<ValueType>(entry.getValue() / rateForProbabilityScaling);
623 successors.push_back(successor);
624 }
625 choiceJson["succ"] = std::move(successors);
626 choicesJson.push_back(choiceJson);
627 }
628 stateChoicesJson["c"] = std::move(choicesJson);
629 output.push_back(std::move(stateChoicesJson));
630 }
631 outStream << storm::dumpJson(output);
632}
633
634template<>
636 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Json export not implemented for this model type.");
637}
638
639template<typename ValueType, typename RewardModelType>
641 return "";
642}
643
644template<typename ValueType, typename RewardModelType>
646 return this->stateLabeling.getLabelsOfState(state);
647}
648
649template<typename ValueType, typename RewardModelType>
651 for (auto const& entry : this->getTransitionMatrix().getRowGroup(state)) {
652 if (entry.getColumn() != state) {
653 return false;
654 }
655 if (!storm::utility::isOne(entry.getValue())) {
656 return false;
657 }
658 }
659 return true;
660}
661
662template<typename ValueType, typename RewardModelType>
664 return true;
665}
666
667template<typename ValueType, typename RewardModelType>
669 return std::is_same<ValueType, storm::RationalFunction>::value;
670}
671
672template<typename ValueType, typename RewardModelType>
676
677template<typename ValueType, typename RewardModelType>
679 if (!this->supportsParameters()) {
680 return false;
681 }
682 // Check for parameters
683 for (auto const& entry : this->getTransitionMatrix()) {
684 if (!storm::utility::isConstant(entry.getValue())) {
685 return true;
686 }
687 }
688 // Only constant values present
689 return false;
690}
691
692template<typename ValueType, typename RewardModelType>
694 if (!this->supportsUncertainty()) {
695 return false;
696 }
697 // Check for intervals
698 for (auto const& entry : this->getTransitionMatrix()) {
699 if (!storm::utility::isConstant(entry.getValue())) {
700 return true;
701 }
702 }
703 // Only constant values present
704 return false;
705}
706
707template<typename ValueType, typename RewardModelType>
711
712template<typename ValueType, typename RewardModelType>
714 return *this->stochasticTolerance;
715}
716
717template<typename ValueType, typename RewardModelType>
719 *this->stochasticTolerance = tolerance;
720}
721
722template<typename ValueType, typename RewardModelType>
723std::unordered_map<std::string, RewardModelType>& Model<ValueType, RewardModelType>::getRewardModels() {
724 return this->rewardModels;
725}
726
727template<typename ValueType, typename RewardModelType>
728std::unordered_map<std::string, RewardModelType> const& Model<ValueType, RewardModelType>::getRewardModels() const {
729 return this->rewardModels;
730}
731
732std::set<storm::RationalFunctionVariable> getProbabilityParameters(Model<storm::RationalFunction> const& model) {
734}
735
736std::set<storm::RationalFunctionVariable> getRewardParameters(Model<storm::RationalFunction> const& model) {
737 std::set<storm::RationalFunctionVariable> result;
738 for (auto rewModel : model.getRewardModels()) {
739 std::set<storm::RationalFunctionVariable> tmp = getRewardModelParameters(rewModel.second);
740 result.insert(tmp.begin(), tmp.end());
741 }
742 return result;
743}
744
745std::set<storm::RationalFunctionVariable> getRateParameters(Model<storm::RationalFunction> const& model) {
747 auto const& ctmc = model.template as<storm::models::sparse::Ctmc<storm::RationalFunction>>();
748 return storm::utility::vector::getVariables(ctmc->getExitRateVector());
750 auto const& ma = model.template as<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>>();
751 return storm::utility::vector::getVariables(ma->getExitRates());
752 } else {
753 return {};
754 }
755}
756
757std::set<storm::RationalFunctionVariable> getAllParameters(Model<storm::RationalFunction> const& model) {
758 std::set<storm::RationalFunctionVariable> parameters = getProbabilityParameters(model);
759 std::set<storm::RationalFunctionVariable> rewardParameters = getRewardParameters(model);
760 parameters.insert(rewardParameters.begin(), rewardParameters.end());
761 std::set<storm::RationalFunctionVariable> rateParameters = getRateParameters(model);
762 parameters.insert(rateParameters.begin(), rateParameters.end());
763 return parameters;
764}
765
766template class Model<double>;
768template class Model<storm::RationalNumber>;
770template class Model<storm::Interval>;
771template class Model<storm::RationalInterval>;
772template class Model<storm::RationalFunction>;
773} // namespace sparse
774} // namespace models
775} // namespace storm
static constexpr double DefaultModelTolerance
The default tolerance up to which probabilities and rates are considered equal.
Definition Environment.h:42
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 ModelType getType() const
Return the actual type of the model.
Definition ModelBase.cpp:7
virtual bool isSparseModel() const
Checks whether the model is a sparse model.
Definition ModelBase.cpp:11
std::shared_ptr< ModelType > as()
Casts the model into the model type given by the template parameter.
Definition ModelBase.h:38
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:34
storm::models::sparse::ChoiceLabeling const & getChoiceLabeling() const
Retrieves the labels for the choices of the model.
Definition Model.cpp:363
RewardModelType const & getUniqueRewardModel() const
Retrieves the unique reward model, if there exists exactly one.
Definition Model.cpp:332
std::optional< storm::storage::sparse::Valuations > const & getOptionalStateValuations() const
Retrieves an optional value that contains the state valuations if there are some.
Definition Model.cpp:388
bool hasRewardModel() const
Retrieves whether the model has at least one reward model.
Definition Model.cpp:327
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Definition Model.cpp:226
virtual std::size_t hash() const
Definition Model.cpp:424
virtual bool hasUncertainty() const
Checks whether the model actually is uncertain, i.e., whether there is a non-singleton transition rel...
Definition Model.cpp:693
void setInitialStates(storm::storage::BitVector const &states)
Overwrites the initial states of the model.
Definition Model.cpp:211
virtual bool supportsUncertainty() const override
Does it support uncertainty (e.g., via interval-valued entries).
Definition Model.cpp:673
Model & operator=(Model< ValueType, RewardModelType > const &other)
Definition Model.cpp:41
virtual void printModelInformationToStream(std::ostream &out) const override
Prints information about the model to the specified stream.
Definition Model.cpp:418
std::unordered_map< std::string, RewardModelType > const & getRewardModels() const
Retrieves the reward models.
Definition Model.cpp:728
void restrictRewardModels(std::set< std::string > const &keptRewardModels)
Removes all reward models whose name is not in the given set.
Definition Model.cpp:303
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
Definition Model.cpp:216
bool removeRewardModel(std::string const &rewardModelName)
Removes the reward model with the given name from the model.
Definition Model.cpp:293
void printRewardModelsInformationToStream(std::ostream &out) const
Prints information about the reward models to the specified stream.
Definition Model.cpp:466
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:645
storm::storage::sparse::Valuations const & getStateValuations() const
Definition Model.cpp:383
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:408
RewardModelType & rewardModel(std::string const &rewardModelName)
Definition Model.cpp:241
void addRewardModel(std::string const &rewardModelName, RewardModelType const &rewModel)
Adds a reward model to the model.
Definition Model.cpp:283
ValueType const & getStochasticTolerance() const
Retrieves the tolerance up to which the model components are considered valid.
Definition Model.cpp:713
std::shared_ptr< storm::storage::sparse::ChoiceOrigins > const & getChoiceOrigins() const
Definition Model.cpp:403
void setStochasticTolerance(ValueType const &tolerance)
Sets the tolerance up to which the model components are considered valid.
Definition Model.cpp:718
Model(Model< ValueType, RewardModelType > const &other)
Definition Model.cpp:28
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
Definition Model.cpp:186
bool isSinkState(uint64_t sink) const
Definition Model.cpp:650
bool hasChoiceLabeling() const
Retrieves whether this model has a labeling of the choices.
Definition Model.cpp:358
uint_fast64_t getNumberOfRewardModels() const
Retrieves the number of reward models associated with this model.
Definition Model.cpp:344
virtual bool hasRewardModel(std::string const &rewardModelName) const override
Definition Model.cpp:236
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
Definition Model.cpp:348
virtual void writeJsonToStream(std::ostream &outStream) const
Writes a JSON representation of the model to the given stream.
Definition Model.cpp:552
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:444
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:368
virtual bool supportsParameters() const override
Checks whether the model supports parameters.
Definition Model.cpp:668
virtual bool hasUniqueRewardModel() const override
Retrieves whether the model has a unique reward model.
Definition Model.cpp:316
virtual std::string additionalDotStateInfo(uint64_t state) const
Return a string that is additonally added to the state information in the dot stream.
Definition Model.cpp:640
virtual uint_fast64_t getNumberOfTransitions() const override
Returns the number of (non-zero) transitions of the model.
Definition Model.cpp:196
bool hasLabel(std::string const &label) const
Retrieves whether the given label is a valid label in this model.
Definition Model.cpp:221
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
Definition Model.cpp:247
virtual std::string const & getUniqueRewardModelName() const override
Retrieves the name of the unique reward model, if there exists exactly one.
Definition Model.cpp:321
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:206
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.
Provides access to valuations of variables for a set of entities (e.g.
Definition Valuations.h:28
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:68
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
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:745
std::set< storm::RationalFunctionVariable > getRewardParameters(Model< storm::RationalFunction > const &model)
Get all parameters occurring in rewards.
Definition Model.cpp:736
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:732
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
Definition Model.cpp:757
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:39
bool isConstant(ValueType const &)
bool isZero(ValueType const &a)
Definition constants.cpp:44
ValueType zero()
Definition constants.cpp:26
std::string to_string(ValueType const &value)
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
nlohmann::basic_json< std::map, std::vector, std::string, bool, int64_t, uint64_t, ValueType > json
Definition JsonForward.h:11
constexpr bool IsIntervalType
Helper to check if a type is an interval.
std::string dumpJson(storm::json< ValueType > const &j, bool compact)
Dumps the given json object, producing a String.
static const bool IsExact
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
std::optional< ValueType > stochasticTolerance