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