Storm 1.13.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
UmbModel.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string/join.hpp>
4#include <sstream>
5
8
9namespace storm::umb {
10
12 std::stringstream info;
13 if (index.modelData) {
14 info << index.modelData->name.value_or("<unnamed_model>");
15 if (index.modelData->version) {
16 info << " v" << index.modelData->version.value();
17 }
18 } else {
19 info << "<unnamed_model>";
20 }
21 return info.str();
22}
23
24std::string UmbModel::getModelInformation() const {
25 std::stringstream info;
26 info << "UMB Model " << getShortModelInformation() << "\n";
27 auto optionalPrint = [&info](std::string const& label, auto const& value) {
28 if (value) {
29 info << "\t* " << label << ": " << value.value() << "\n";
30 }
31 };
32 if (index.modelData) {
33 auto const& md = index.modelData.value();
34 if (md.authors && !md.authors->empty()) {
35 info << "\t* Authors: " << boost::join(md.authors.value(), "; ") << "\n";
36 }
37 optionalPrint("Description", md.description);
38 optionalPrint("Comment", md.comment);
39 optionalPrint("DOI", md.doi);
40 optionalPrint("URL", md.url);
41 }
42 if (index.fileData) {
43 auto const& fd = index.fileData.value();
44 if (fd.tool) {
45 info << "\t* Created with tool: " << fd.tool.value();
46 if (fd.toolVersion) {
47 info << " v" << fd.toolVersion.value();
48 }
49 info << "\n";
50 }
51 if (fd.creationDate) {
52 info << "\t* Creation date: " << fd.creationDateAsString() << "\n";
53 }
54 if (fd.parameters) {
55 info << "\t* Parameters:\n" << storm::dumpJson(fd.parameters.value()) << "\n";
56 }
57 }
58 return info.str();
59}
60
61storm::OptionalRef<UmbModel::Annotation> UmbModel::annotation(std::string const& annotationType, bool createIfMissing) {
62 if (createIfMissing) {
63 return annotations[annotationType];
64 }
65 auto it = annotations.find(annotationType);
66 if (it != annotations.end()) {
67 return it->second;
68 }
69 return {};
70}
71
73 auto it = annotations.find(annotationType);
74 if (it != annotations.end()) {
75 return it->second;
76 }
77 return {};
78}
79
81 return annotation("aps", createIfMissing);
82}
83
87
89 return annotation("rewards", createIfMissing);
90}
91
95
96bool UmbModel::validate(std::ostream& errors) const {
97 return storm::umb::validate(*this, errors);
98}
99
103
105 auto getSize = [](storm::umb::GenericVector& v) -> uint64_t {
106 if (v.isType<storm::RationalNumber>()) {
107 return ValueEncoding::getMinimalRationalSize(v.template get<storm::RationalNumber>(), true);
108 } else if (v.isType<storm::RationalInterval>()) {
109 return ValueEncoding::getMinimalRationalIntervalSize(v.template get<storm::RationalInterval>(), true);
110 }
111 return 0ull;
112 };
113 auto encodeForSize = [](storm::umb::GenericVector& v, uint64_t const size) {
114 if (v.isType<storm::RationalNumber>()) {
115 auto values = ValueEncoding::createUint64FromRationalRange(v.template get<storm::RationalNumber>(), size);
116 v.template set<uint64_t>(std::move(values));
117 } else if (v.isType<storm::RationalInterval>()) {
118 auto values = ValueEncoding::createUint64FromRationalIntervalRange(v.template get<storm::RationalInterval>(), size);
119 v.template set<uint64_t>(std::move(values));
120 }
121 };
122 auto encode = [&getSize, &encodeForSize](storm::umb::GenericVector& v, std::optional<uint64_t>& size) {
123 if (v.isType<storm::RationalNumber>() || v.isType<storm::RationalInterval>()) {
124 size = getSize(v);
125 encodeForSize(v, size.value());
126 }
127 };
128
129 if (index.transitionSystem.branchProbabilityType.has_value()) {
130 encode(branchToProbability, index.transitionSystem.branchProbabilityType->size);
131 }
132 if (index.transitionSystem.exitRateType.has_value()) {
133 encode(stateToExitRate, index.transitionSystem.exitRateType->size);
134 }
135 if (index.transitionSystem.observationProbabilityType.has_value()) {
136 if (stateObservations.has_value()) {
137 encode(stateObservations->probabilities, index.transitionSystem.observationProbabilityType->size);
138 }
139 if (branchObservations.has_value()) {
140 encode(branchObservations->probabilities, index.transitionSystem.observationProbabilityType->size);
141 }
142 }
143 for (auto& [annotationType, annotation] : annotations) {
144 for (auto& [annotationName, annotationValues] : annotation) {
145 // Get encoding bit sizes. Note that if the annotation applies to multiple entities, we need to use the maximum size.
146 uint64_t valueSize{0}, probSize{0};
147 boost::pfr::for_each_field(annotationValues, [&valueSize, &probSize, &getSize](auto& entity) {
148 if (entity.has_value()) {
149 valueSize = std::max(valueSize, getSize(entity->values));
150 probSize = std::max(probSize, getSize(entity->probabilities));
151 }
152 });
153 // encode
154 if (valueSize > 0 || probSize > 0) {
155 STORM_LOG_ASSERT(index.annotation(annotationType).has_value() && index.annotation(annotationType)->contains(annotationName),
156 "There are annotation files stored for annotations/" << annotationType << "/" << annotationName
157 << ", but no corresponding entry in the index.");
158 auto& indexAnnotation = index.annotation(annotationType)->at(annotationName);
159 if (valueSize > 0) {
160 indexAnnotation.type.size = valueSize;
161 boost::pfr::for_each_field(annotationValues, [&valueSize, &encodeForSize](auto& entity) {
162 if (entity.has_value()) {
163 encodeForSize(entity->values, valueSize);
164 }
165 });
166 }
167 if (probSize > 0) {
168 STORM_LOG_ASSERT(indexAnnotation.probabilityType.has_value(), "Found annotation probabilities but no type in index.");
169 indexAnnotation.probabilityType.value().size = probSize;
170 boost::pfr::for_each_field(annotationValues, [&probSize, &encodeForSize](auto& entity) {
171 if (entity.has_value()) {
172 encodeForSize(entity->probabilities, probSize);
173 }
174 });
175 }
176 }
177 }
178 }
179}
180
182 auto decode = [](storm::umb::GenericVector& v, std::optional<SizedType> const type) {
183 if (type.has_value() && type->type == Type::Rational && v.isType<uint64_t>()) {
184 auto valueView = ValueEncoding::uint64ToRationalRangeView(v.template get<uint64_t>(), type->bitSize());
185 std::vector<storm::RationalNumber> values(valueView.begin(), valueView.end());
186 v.template set<storm::RationalNumber>(std::move(values));
187 } else if (type.has_value() && type->type == Type::RationalInterval && v.isType<uint64_t>()) {
188 auto valueView = ValueEncoding::uint64ToRationalIntervalRangeView(v.template get<uint64_t>(), type->bitSize());
189 std::vector<storm::RationalInterval> values(valueView.begin(), valueView.end());
190 v.template set<storm::RationalInterval>(std::move(values));
191 }
192 };
193
194 if (index.transitionSystem.branchProbabilityType.has_value()) {
195 decode(branchToProbability, index.transitionSystem.branchProbabilityType.value());
196 }
197 if (index.transitionSystem.exitRateType.has_value()) {
198 decode(stateToExitRate, index.transitionSystem.exitRateType.value());
199 }
200 if (index.transitionSystem.observationProbabilityType.has_value()) {
201 if (stateObservations.has_value()) {
202 decode(stateObservations->probabilities, index.transitionSystem.observationProbabilityType.value());
203 }
204 if (branchObservations.has_value()) {
205 decode(branchObservations->probabilities, index.transitionSystem.observationProbabilityType.value());
206 }
207 }
208
209 for (auto& [annotationType, annotation] : annotations) {
210 for (auto& [annotationName, annotationValues] : annotation) {
211 STORM_LOG_ASSERT(index.annotation(annotationType).has_value() && index.annotation(annotationType)->contains(annotationName),
212 "There are annotation files stored for annotations/" << annotationType << "/" << annotationName
213 << ", but no corresponding entry in the index.");
214 auto const& annotationIndex = index.annotation(annotationType)->at(annotationName);
215 boost::pfr::for_each_field(annotationValues, [&annotationIndex, &decode](auto& entity) {
216 if (entity.has_value()) {
217 decode(entity->values, annotationIndex.type);
218 decode(entity->probabilities, annotationIndex.probabilityType.value());
219 }
220 });
221 }
222 }
223}
224
225} // namespace storm::umb
Helper class that optionally holds a reference to an object of type T.
Definition OptionalRef.h:48
storm::OptionalRef< Annotation > annotation(std::string const &annotationType, bool createIfMissing=false)
Gets the annotation data with the given annotation type.
Definition UmbModel.cpp:61
std::map< std::string, Annotation > annotations
Definition UmbModel.h:67
storm::OptionalRef< Annotation const > rewards() const
Definition UmbModel.cpp:92
storm::OptionalRef< Annotation const > aps() const
Definition UmbModel.cpp:84
std::string getShortModelInformation() const
Retrieves a short string that can be used to refer to the model in user output.
Definition UmbModel.cpp:11
void validateOrThrow() const
Validates the UmbModel.
Definition UmbModel.cpp:100
bool validate(std::ostream &errors) const
Validates the given UMB model and writes potential errors to the given output stream.
Definition UmbModel.cpp:96
TO1< AnyValueType > branchToProbability
Definition UmbModel.h:35
std::string getModelInformation() const
Retrieves a string that describes the model in more detail.
Definition UmbModel.cpp:24
void decodeRationals()
Decodes all rational values stored in the model from their UMB bit representation.
Definition UmbModel.cpp:181
TO1< AnyValueType > stateToExitRate
Definition UmbModel.h:30
ModelIndex index
Definition UmbModel.h:24
void encodeRationals()
Encodes all rational values stored in the model into their UMB bit representation.
Definition UmbModel.cpp:104
std::optional< Observations > branchObservations
Definition UmbModel.h:51
std::optional< Observations > stateObservations
Definition UmbModel.h:51
static uint64_t getMinimalRationalSize(InputRange &&input, bool multiplesOf64)
static uint64_t getMinimalRationalIntervalSize(InputRange &&input, bool multiplesOf64)
static std::vector< uint64_t > createUint64FromRationalRange(InputRange &&input, uint64_t const numberSize)
static auto uint64ToRationalIntervalRangeView(InputRange &&input, uint64_t const numberSize)
static auto uint64ToRationalRangeView(InputRange &&input, uint64_t const numberSize)
static std::vector< uint64_t > createUint64FromRationalIntervalRange(InputRange &&input, uint64_t const numberSize)
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
@ RationalInterval
Definition Type.h:11
bool validate(storm::umb::UmbModel const &umbModel, std::ostream &err)
Validates the given UMB model and writes potential errors to the given output stream.
void validateOrThrow(storm::umb::UmbModel const &umbModel)
Validates the given UMB model.
carl::Interval< storm::RationalNumber > RationalInterval
std::string dumpJson(storm::json< ValueType > const &j, bool compact)
Dumps the given json object, producing a String.