Storm 1.14.0.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,
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 (storm::utility::isInfinity(value)) {
112 out << "inf";
113 } else {
114 out << value;
115 if (std::is_same_v<ValueType, storm::RationalNumber> || std::is_same_v<ValueType, storm::ExtendedRationalNumber>) {
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 print(out, min);
125 out << ", ";
126 print(out, max);
127 out << "]";
128 if (std::is_same_v<ValueType, storm::RationalNumber> || std::is_same_v<ValueType, storm::ExtendedRationalNumber>) {
129 out << " (approx. [";
131 out << "inf";
132 } else {
133 out << storm::utility::convertNumber<double>(min);
134 }
135 out << ", ";
137 out << "inf";
138 } else {
139 out << storm::utility::convertNumber<double>(max);
140 }
141 out << "])";
142 }
143 out << " (range)";
144}
145
146template<storm::dd::DdType Type, typename ValueType>
148 uint64_t totalNumberOfStates = this->symbolicStates.getNonZeroCount() + this->explicitStates.getNonZeroCount();
149 bool minMaxSupported = std::is_same<ValueType, double>::value || std::is_same<ValueType, storm::RationalNumber>::value;
150 bool printAsRange = false;
151
152 if (totalNumberOfStates == 1) {
153 if (this->symbolicStates.isZero()) {
154 print(out, storm::utility::fromSentinel(*this->explicitValues.begin()));
155 } else {
156 print(out, storm::utility::fromSentinel(this->symbolicValues.sumAbstract(this->symbolicValues.getContainedMetaVariables()).getValue()));
157 }
158 } else if (totalNumberOfStates >= 10 && minMaxSupported) {
159 printAsRange = true;
160 } else {
161 out << "{";
162 bool first = true;
163 if (!this->symbolicStates.isZero()) {
164 if (this->symbolicValues.isZero()) {
165 out << "0";
166 first = false;
167 } else {
168 for (auto valuationValuePair : this->symbolicValues) {
169 if (!first) {
170 out << ", ";
171 } else {
172 first = false;
173 }
174 print(out, storm::utility::fromSentinel(valuationValuePair.second));
175 }
176 if (symbolicStates.getNonZeroCount() != this->symbolicValues.getNonZeroCount()) {
177 out << ", 0";
178 }
179 }
180 }
181 if (!this->explicitStates.isZero()) {
182 for (auto const& element : this->explicitValues) {
183 if (!first) {
184 out << ", ";
185 } else {
186 first = false;
187 }
188 print(out, storm::utility::fromSentinel(element));
189 }
190 }
191 out << "}";
192 }
193
194 if (printAsRange) {
195 printRange(out, this->getMin(), this->getMax());
196 }
197 return out;
198}
199
200template<storm::dd::DdType Type, typename ValueType>
202 STORM_LOG_THROW(filter.isSymbolicQualitativeCheckResult(), storm::exceptions::InvalidOperationException,
203 "Cannot filter hybrid check result with non-symbolic filter.");
204
205 // First, we filter the symbolic values.
206 this->symbolicStates = this->symbolicStates && filter.asSymbolicQualitativeCheckResult<Type>().getTruthValuesVector();
207 this->symbolicValues *= symbolicStates.template toAdd<ValueType>();
208
209 // Next, we filter the explicit values.
210
211 // Start by computing the new set of states that is stored explictly and the corresponding ODD.
212 this->explicitStates = this->explicitStates && filter.asSymbolicQualitativeCheckResult<Type>().getTruthValuesVector();
213 storm::dd::Odd newOdd = explicitStates.createOdd();
214
215 // Then compute the new vector of explicit values and set the new data fields.
216 this->explicitValues = explicitStates.filterExplicitVector(this->odd, explicitValues);
217
218 this->odd = newOdd;
219}
220
221template<storm::dd::DdType Type, typename ValueType>
223 // In order to not get false zeros, we need to set the values of all states whose values is not stored
224 // symbolically to infinity.
226 symbolicStates.ite(this->symbolicValues, reachableStates.getDdManager().getConstant(storm::utility::infinity<ValueType>()));
228 if (!explicitStates.isZero()) {
229 for (auto const& element : explicitValues) {
230 min = std::min(min, storm::utility::fromSentinel(element));
231 }
232 }
233 return min;
234}
235
236template<storm::dd::DdType Type, typename ValueType>
238 ExtendedValueType max = storm::utility::fromSentinel(this->symbolicValues.getMax());
239 if (!explicitStates.isZero()) {
240 for (auto const& element : explicitValues) {
241 max = std::max(max, storm::utility::fromSentinel(element));
242 }
243 }
244 return max;
245}
246
247template<storm::dd::DdType Type, typename ValueType>
249 // The sentinel has to be recognised before the symbolic leaves are added up: two of them would sum to twice the
250 // sentinel, which is a value like any other. This goes away together with the sentinel on the decision diagram
251 // leaves. The explicit values below are converted one by one and need no such guard.
252 bool const hasInfiniteSymbolicValue = !symbolicValues.equals(symbolicValues.getDdManager().getConstant(storm::utility::infinity<ValueType>())).isZero();
253 ExtendedValueType sum = hasInfiniteSymbolicValue
255 : storm::utility::fromSentinel(symbolicValues.sumAbstract(symbolicValues.getContainedMetaVariables()).getValue());
256 for (auto const& value : explicitValues) {
258 }
259 return sum;
260}
261
262template<storm::dd::DdType Type, typename ValueType>
266
267template<storm::dd::DdType Type, typename ValueType>
269 storm::dd::Add<Type, ValueType> one = symbolicValues.getDdManager().template getAddOne<ValueType>();
270 storm::dd::Add<Type, ValueType> zero = symbolicValues.getDdManager().template getAddZero<ValueType>();
271 symbolicValues = symbolicStates.ite(one - symbolicValues, zero);
272
273 for (auto& element : explicitValues) {
274 element = storm::utility::one<ValueType>() - element;
275 }
276}
277
278// Explicitly instantiate the class.
281
284} // namespace modelchecker
285} // 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
A quantitative check result over the states of a sparse model.
virtual std::ostream & writeToStream(std::ostream &out) const override
typename QuantitativeCheckResult< ValueType >::ExtendedValueType ExtendedValueType
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:39
void print(std::ostream &out, ValueType const &value)
void printRange(std::ostream &out, ValueType const &min, ValueType const &max)
ExtendedValueType< ValueType > positiveInfinity()
ExtendedValueType< ValueType > fromSentinel(ValueType &&value)
Recognises the value that storm::utility::infinity still yields for the value types that have no infi...
ValueType infinity()
Definition constants.cpp:31
ValueType one()
Definition constants.cpp:21
bool isInfinity(ValueType const &a)
TargetType convertNumber(SourceType const &number)