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