Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
HybridQuantitativeCheckResult.cpp
Go to the documentation of this file.
2
11
12namespace storm {
13namespace modelchecker {
14template<storm::dd::DdType Type, typename ValueType>
16 storm::dd::Bdd<Type> const& symbolicStates,
17 storm::dd::Add<Type, ValueType> const& symbolicValues,
18 storm::dd::Bdd<Type> const& explicitStates, storm::dd::Odd const& odd,
19 std::vector<ValueType> const& explicitValues)
20 : reachableStates(reachableStates),
21 symbolicStates(symbolicStates),
22 symbolicValues(symbolicValues),
23 explicitStates(explicitStates),
24 odd(odd),
25 explicitValues(explicitValues) {
26 // Intentionally left empty.
27}
28
29template<storm::dd::DdType Type, typename ValueType>
30std::unique_ptr<CheckResult> HybridQuantitativeCheckResult<Type, ValueType>::clone() const {
31 return std::make_unique<HybridQuantitativeCheckResult<Type, ValueType>>(this->reachableStates, this->symbolicStates, this->symbolicValues,
32 this->explicitStates, this->odd, this->explicitValues);
33}
34
35template<storm::dd::DdType Type, typename ValueType>
37 ValueType const& bound) const {
38 storm::dd::Bdd<Type> symbolicResult = symbolicStates;
39
40 // First compute the symbolic part of the result.
41 if (comparisonType == storm::logic::ComparisonType::Less) {
42 symbolicResult &= symbolicValues.less(bound);
43 } else if (comparisonType == storm::logic::ComparisonType::LessEqual) {
44 symbolicResult &= symbolicValues.lessOrEqual(bound);
45 } else if (comparisonType == storm::logic::ComparisonType::Greater) {
46 symbolicResult &= symbolicValues.greater(bound);
47 } else if (comparisonType == storm::logic::ComparisonType::GreaterEqual) {
48 symbolicResult &= symbolicValues.greaterOrEqual(bound);
49 }
50
51 // Then translate the explicit part to a symbolic format and simultaneously to a qualitative result.
52 symbolicResult |= storm::dd::Bdd<Type>::template fromVector<ValueType>(this->reachableStates.getDdManager(), this->explicitValues, this->odd,
53 this->symbolicValues.getContainedMetaVariables(), comparisonType,
54 storm::utility::convertNumber<ValueType>(bound));
55
56 return std::unique_ptr<SymbolicQualitativeCheckResult<Type>>(new SymbolicQualitativeCheckResult<Type>(reachableStates, symbolicResult));
57}
58
59template<storm::dd::DdType Type, typename ValueType>
61 storm::dd::Bdd<Type> allStates = symbolicStates || explicitStates;
62 storm::dd::Odd allStatesOdd = allStates.createOdd();
63
64 std::vector<ValueType> fullExplicitValues = symbolicValues.toVector(allStatesOdd);
65 this->odd.expandExplicitVector(allStatesOdd, this->explicitValues, fullExplicitValues);
66 return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(fullExplicitValues)));
67}
68
69template<storm::dd::DdType Type, typename ValueType>
73
74template<storm::dd::DdType Type, typename ValueType>
76 return (symbolicStates || explicitStates) == reachableStates;
77}
78
79template<storm::dd::DdType Type, typename ValueType>
83
84template<storm::dd::DdType Type, typename ValueType>
88
89template<storm::dd::DdType Type, typename ValueType>
93
94template<storm::dd::DdType Type, typename ValueType>
98
99template<storm::dd::DdType Type, typename ValueType>
103
104template<storm::dd::DdType Type, typename ValueType>
106 return explicitValues;
107}
108
109template<typename ValueType>
110void print(std::ostream& out, ValueType const& value) {
111 if (value == storm::utility::infinity<ValueType>()) {
112 out << "inf";
113 } else {
114 out << value;
115 if (std::is_same<ValueType, storm::RationalNumber>::value) {
116 out << " (approx. " << storm::utility::convertNumber<double>(value) << ")";
117 }
118 }
119}
120
121template<typename ValueType>
122void printRange(std::ostream& out, ValueType const& min, ValueType const& max) {
123 out << "[";
124 if (min == storm::utility::infinity<ValueType>()) {
125 out << "inf";
126 } else {
127 out << min;
128 }
129 out << ", ";
130 if (max == storm::utility::infinity<ValueType>()) {
131 out << "inf";
132 } else {
133 out << max;
134 }
135 out << "]";
136 if (std::is_same<ValueType, storm::RationalNumber>::value) {
137 out << " (approx. [";
138 if (min == storm::utility::infinity<ValueType>()) {
139 out << "inf";
140 } else {
141 out << storm::utility::convertNumber<double>(min);
142 }
143 out << ", ";
144 if (max == storm::utility::infinity<ValueType>()) {
145 out << "inf";
146 } else {
147 out << storm::utility::convertNumber<double>(max);
148 }
149 out << "])";
150 }
151 out << " (range)";
152}
153
154template<storm::dd::DdType Type, typename ValueType>
156 uint64_t totalNumberOfStates = this->symbolicStates.getNonZeroCount() + this->explicitStates.getNonZeroCount();
157 bool minMaxSupported = std::is_same<ValueType, double>::value || std::is_same<ValueType, storm::RationalNumber>::value;
158 bool printAsRange = false;
159
160 if (totalNumberOfStates == 1) {
161 if (this->symbolicStates.isZero()) {
162 print(out, *this->explicitValues.begin());
163 } else {
164 print(out, this->symbolicValues.sumAbstract(this->symbolicValues.getContainedMetaVariables()).getValue());
165 }
166 } else if (totalNumberOfStates >= 10 && minMaxSupported) {
167 printAsRange = true;
168 } else {
169 out << "{";
170 bool first = true;
171 if (!this->symbolicStates.isZero()) {
172 if (this->symbolicValues.isZero()) {
173 out << "0";
174 first = false;
175 } else {
176 for (auto valuationValuePair : this->symbolicValues) {
177 if (!first) {
178 out << ", ";
179 } else {
180 first = false;
181 }
182 print(out, valuationValuePair.second);
183 }
184 if (symbolicStates.getNonZeroCount() != this->symbolicValues.getNonZeroCount()) {
185 out << ", 0";
186 }
187 }
188 }
189 if (!this->explicitStates.isZero()) {
190 for (auto const& element : this->explicitValues) {
191 if (!first) {
192 out << ", ";
193 } else {
194 first = false;
195 }
196 print(out, element);
197 }
198 }
199 out << "}";
200 }
201
202 if (printAsRange) {
203 ValueType min = this->getMin();
204 ValueType max = this->getMax();
205 printRange(out, min, max);
206 }
207 return out;
208}
209
210template<storm::dd::DdType Type, typename ValueType>
212 STORM_LOG_THROW(filter.isSymbolicQualitativeCheckResult(), storm::exceptions::InvalidOperationException,
213 "Cannot filter hybrid check result with non-symbolic filter.");
214
215 // First, we filter the symbolic values.
216 this->symbolicStates = this->symbolicStates && filter.asSymbolicQualitativeCheckResult<Type>().getTruthValuesVector();
217 this->symbolicValues *= symbolicStates.template toAdd<ValueType>();
218
219 // Next, we filter the explicit values.
220
221 // Start by computing the new set of states that is stored explictly and the corresponding ODD.
222 this->explicitStates = this->explicitStates && filter.asSymbolicQualitativeCheckResult<Type>().getTruthValuesVector();
223 storm::dd::Odd newOdd = explicitStates.createOdd();
224
225 // Then compute the new vector of explicit values and set the new data fields.
226 this->explicitValues = explicitStates.filterExplicitVector(this->odd, explicitValues);
227
228 this->odd = newOdd;
229}
230
231template<storm::dd::DdType Type, typename ValueType>
233 // In order to not get false zeros, we need to set the values of all states whose values is not stored
234 // symbolically to infinity.
236 symbolicStates.ite(this->symbolicValues, reachableStates.getDdManager().getConstant(storm::utility::infinity<ValueType>()));
237 ValueType min = tmp.getMin();
238 if (!explicitStates.isZero()) {
239 for (auto const& element : explicitValues) {
240 min = std::min(min, element);
241 }
242 }
243 return min;
244}
245
246template<storm::dd::DdType Type, typename ValueType>
248 ValueType max = this->symbolicValues.getMax();
249 if (!explicitStates.isZero()) {
250 for (auto const& element : explicitValues) {
251 max = std::max(max, element);
252 }
253 }
254 return max;
255}
256
257template<storm::dd::DdType Type, typename ValueType>
259 ValueType sum = symbolicValues.sumAbstract(symbolicValues.getContainedMetaVariables()).getValue();
260 for (auto const& value : explicitValues) {
261 sum += value;
262 }
263 return sum;
264}
265
266template<storm::dd::DdType Type, typename ValueType>
268 return this->sum() / storm::utility::convertNumber<ValueType>((symbolicStates || explicitStates).getNonZeroCount());
269}
270
271template<storm::dd::DdType Type, typename ValueType>
273 storm::dd::Add<Type, ValueType> one = symbolicValues.getDdManager().template getAddOne<ValueType>();
274 storm::dd::Add<Type, ValueType> zero = symbolicValues.getDdManager().template getAddZero<ValueType>();
275 symbolicValues = symbolicStates.ite(one - symbolicValues, zero);
276
277 for (auto& element : explicitValues) {
278 element = storm::utility::one<ValueType>() - element;
279 }
280}
281
282// Explicitly instantiate the class.
285
288} // namespace modelchecker
289} // namespace storm
ValueType getMin() const
Retrieves the lowest function value of any encoding.
Definition Add.cpp:463
Odd createOdd() const
Creates an ODD based on the current BDD.
Definition Bdd.cpp:565
void expandExplicitVector(storm::dd::Odd const &newOdd, std::vector< ValueType > const &oldValues, std::vector< ValueType > &newValues) const
Adds the old values to the new values.
Definition Odd.cpp:76
virtual std::ostream & writeToStream(std::ostream &out) const override
std::vector< ValueType > const & getExplicitValueVector() const
std::unique_ptr< CheckResult > toExplicitQuantitativeCheckResult() const
virtual std::unique_ptr< CheckResult > compareAgainstBound(storm::logic::ComparisonType comparisonType, ValueType const &bound) const override
virtual void filter(QualitativeCheckResult const &filter) override
Filters the current result wrt.
virtual std::unique_ptr< CheckResult > clone() const override
storm::dd::Add< Type, ValueType > const & getSymbolicValueVector() const
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
void print(std::ostream &out, ValueType const &value)
void printRange(std::ostream &out, ValueType const &min, ValueType const &max)
ValueType max(ValueType const &first, ValueType const &second)
ValueType min(ValueType const &first, ValueType const &second)