Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ExplicitQuantitativeCheckResult.cpp
Go to the documentation of this file.
1#include "storm/adapters/RationalNumberAdapter.h" // Must come first. TODO: fix
2
4
5#include <algorithm>
6
15
16namespace storm {
17namespace modelchecker {
18
19template<typename ValueType>
21 : states(storm::storage::BitVector(state + 1)), values({value}) {
22 states.set(state);
23}
24
25template<typename ValueType>
27 std::optional<std::shared_ptr<storm::storage::Scheduler<ValueType>>> scheduler)
28 : states(values.size(), true), values(values), scheduler(scheduler) {
29 // Intentionally left empty.
30}
31
32template<typename ValueType>
34 std::optional<std::shared_ptr<storm::storage::Scheduler<ValueType>>> scheduler)
35 : states(values.size(), true), values(std::move(values)), scheduler(scheduler) {
36 // Intentionally left empty.
37}
38
39template<typename ValueType>
41 std::optional<std::shared_ptr<storm::storage::Scheduler<ValueType>>> scheduler)
42 : states(std::move(states)), values(std::move(values)), scheduler(scheduler) {
43 STORM_LOG_ASSERT(this->states.getNumberOfSetBits() == this->values.size(), "Expected one value per selected state.");
44}
45
46template<typename ValueType>
48 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
49 : states(values.size(), true), values(storm::utility::widen(std::vector<ValueType>(values))) {
50 // Intentionally left empty.
51}
52
53template<typename ValueType>
55 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
56 : states(values.size(), true), values(storm::utility::widen(std::move(values))) {
57 // Intentionally left empty.
58}
59
60template<typename ValueType>
62 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
63 : states(std::move(states)), values(storm::utility::widen(std::move(values))) {
64 STORM_LOG_ASSERT(this->states.getNumberOfSetBits() == this->values.size(), "Expected one value per selected state.");
65}
66
67template<typename ValueType>
69 auto const toValue = [](bool truthValue) { return truthValue ? storm::utility::one<ExtendedValueType>() : storm::utility::zero<ExtendedValueType>(); };
70
71 storm::storage::BitVector const& truthValues = other.getTruthValuesVector();
72 values.reserve(truthValues.size());
73 for (std::size_t i = 0; i < truthValues.size(); i++) {
74 values.push_back(toValue(truthValues.get(i)));
75 }
76 states = other.getStates();
77}
78
79template<typename ValueType>
80std::unique_ptr<CheckResult> ExplicitQuantitativeCheckResult<ValueType>::clone() const {
81 return std::make_unique<ExplicitQuantitativeCheckResult<ValueType>>(*this);
82}
83
84template<typename ValueType>
86 return state < states.size() && states.get(state);
87}
88
89template<typename ValueType>
90uint64_t ExplicitQuantitativeCheckResult<ValueType>::getOffset(storm::storage::sparse::state_type state) const {
91 STORM_LOG_ASSERT(this->hasValueForState(state), "State '" << state << "' has no value.");
92 return states.getNumberOfSetBitsBeforeIndex(state);
93}
94
95template<typename ValueType>
99
100template<typename ValueType>
104
105template<typename ValueType>
109
110template<typename ValueType>
114
115template<typename ValueType>
117 if constexpr (!std::is_same_v<ExtendedValueType, ValueType>) {
118 std::vector<ValueType> result;
119 result.reserve(values.size());
120 for (auto const& value : values) {
121 result.push_back(storm::utility::toSentinel<ValueType>(value));
122 }
123 return result;
124 } else {
125 return values;
126 }
127}
128
129template<typename ValueType>
131 return bounds.hasLower();
132}
133
134template<typename ValueType>
136 return bounds.hasUpper();
137}
138
139template<typename ValueType>
141 STORM_LOG_THROW(this->hasLowerBounds(), storm::exceptions::InvalidOperationException, "Unable to retrieve unknown lower bounds.");
142 return *bounds.lower;
143}
144
145template<typename ValueType>
147 STORM_LOG_THROW(this->hasUpperBounds(), storm::exceptions::InvalidOperationException, "Unable to retrieve unknown upper bounds.");
148 return *bounds.upper;
149}
150
151template<typename ValueType>
156
157template<typename ValueType>
159 this->bounds.lower = std::move(lowerBounds);
160 STORM_LOG_ASSERT(bounds.encloses(values), "Bounds must have the same size as the values and enclose them.");
161}
162
163template<typename ValueType>
165 this->bounds.upper = std::move(upperBounds);
166 STORM_LOG_ASSERT(bounds.encloses(values), "Bounds must have the same size as the values and enclose them.");
167}
168
169template<typename ValueType>
171 STORM_LOG_ASSERT(bounds.encloses(values), "Bounds must have the same size as the values and enclose them.");
172 this->bounds = std::move(bounds);
173}
174
175template<typename ValueType>
177 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
178{
180 if (bounds.hasLower()) {
181 widened.lower = storm::utility::widen(std::move(*bounds.lower));
182 }
183 if (bounds.hasUpper()) {
184 widened.upper = storm::utility::widen(std::move(*bounds.upper));
185 }
186 this->setBounds(std::move(widened));
187}
188
189template<typename ValueType>
191 bounds.setExact(values);
192}
193
194template<typename ValueType>
198
199template<typename ValueType>
201 STORM_LOG_THROW(filter.isExplicitQualitativeCheckResult(), storm::exceptions::InvalidOperationException,
202 "Cannot filter explicit check result with non-explicit filter.");
203 STORM_LOG_THROW(filter.isResultForAllStates(), storm::exceptions::InvalidOperationException, "Cannot filter check result with non-complete filter.");
204 STORM_LOG_THROW(filter.hasValueType<ValueType>(), storm::exceptions::InvalidOperationException, "Filter has unexpected value type.");
206 typename ExplicitQualitativeCheckResult<ValueType>::vector_type const& filterTruthValues = explicitFilter.getTruthValuesVector();
207
208 // Line the filter up with the states this result has values for. The two need not span the same range of
209 // states, e.g. if this result holds a value for a single state only.
210 uint64_t const numStates = std::max(filterTruthValues.size(), states.size());
211 storm::storage::BitVector available = states;
212 available.resize(numStates);
213 storm::storage::BitVector selected(filterTruthValues);
214 selected.resize(numStates);
215 STORM_LOG_THROW(selected.isSubsetOf(available), storm::exceptions::InvalidOperationException,
216 "The check result fails to contain some results referred to by the filter.");
217
218 storm::storage::BitVector const keep = selected % available;
219
220 if (this->hasLowerBounds()) {
221 bounds.lower = storm::utility::vector::filterVector(*bounds.lower, keep);
222 }
223 if (this->hasUpperBounds()) {
224 bounds.upper = storm::utility::vector::filterVector(*bounds.upper, keep);
225 }
226 values = storm::utility::vector::filterVector(values, keep);
227 states = filterTruthValues;
228}
229
230template<typename ValueType>
232 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException, "Minimum of empty set is not defined.");
233 return aggregateVector(values, FilterType::MIN);
234}
235
236template<typename ValueType>
238 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException, "Maximum of empty set is not defined.");
239 return aggregateVector(values, FilterType::MAX);
240}
241
242template<typename ValueType>
243std::pair<typename ExplicitQuantitativeCheckResult<ValueType>::ExtendedValueType, typename ExplicitQuantitativeCheckResult<ValueType>::ExtendedValueType>
245 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException, "Minimum/maximum of empty set is not defined.");
246 return storm::utility::minmax(values);
247}
248
249template<typename ValueType>
251 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException, "Sum of empty set is not defined.");
252 return aggregateVector(values, FilterType::SUM);
253}
254
255template<typename ValueType>
257 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException, "Average of empty set is not defined.");
258 return aggregateVector(values, FilterType::AVG);
259}
260
261template<typename ValueType>
262typename ExplicitQuantitativeCheckResult<ValueType>::ExtendedValueType ExplicitQuantitativeCheckResult<ValueType>::aggregateVector(vector_type const& vector,
263 FilterType filter) {
264 STORM_LOG_THROW(!vector.empty(), storm::exceptions::InvalidOperationException, "Aggregate of empty set is not defined.");
265 switch (filter) {
266 case FilterType::MIN:
267 return storm::utility::minimum(vector);
268 case FilterType::MAX:
269 return storm::utility::maximum(vector);
270 case FilterType::SUM: {
271 // Infinities are kept out of the running sum, since adding infinities is not always defined.
272 // If the vector does contain an infinity, the results are decided by it.
273 bool hasPositiveInfinity = false;
274 bool hasNegativeInfinity = false;
276 for (auto const& element : vector) {
277 if (storm::utility::isInfinity(element)) {
278 hasPositiveInfinity = true;
279 } else if (storm::utility::isNegativeInfinity(element)) {
280 hasNegativeInfinity = true;
281 } else {
282 sum += element;
283 }
284 }
285 STORM_LOG_THROW(!hasPositiveInfinity || !hasNegativeInfinity, storm::exceptions::InvalidOperationException,
286 "Cannot compute the sum of values containing both infinity and -infinity.");
287 if (hasPositiveInfinity) {
289 }
290 if (hasNegativeInfinity) {
292 }
293 return sum;
294 }
295 case FilterType::AVG: {
296 ExtendedValueType const total = aggregateVector(vector, FilterType::SUM);
298 // Dividing an infinite sum by the finite number of values leaves it unchanged.
299 return total;
300 }
302 }
303 default:
304 STORM_LOG_THROW_UNCONDITIONALLY(storm::exceptions::InvalidOperationException, "The filter " << toString(filter) << " does not aggregate values.");
305 }
306}
307
308template<typename ValueType>
310 FilterType filter) const {
312 if (this->hasLowerBounds()) {
313 result.lower = aggregateVector(*bounds.lower, filter);
314 }
315 if (this->hasUpperBounds()) {
316 result.upper = aggregateVector(*bounds.upper, filter);
317 }
318 return result;
319}
320
321template<typename ValueType>
323 return static_cast<bool>(scheduler);
324}
325
326template<typename ValueType>
328 this->scheduler = std::move(scheduler);
329}
330
331template<typename ValueType>
333 STORM_LOG_THROW(this->hasScheduler(), storm::exceptions::InvalidOperationException, "Unable to retrieve non-existing scheduler.");
334 return *scheduler.value();
335}
336
337template<typename ValueType>
339 STORM_LOG_THROW(this->hasScheduler(), storm::exceptions::InvalidOperationException, "Unable to retrieve non-existing scheduler.");
340 return *scheduler.value();
341}
342
343// Whether a value of this type is printed with its decimal approximation alongside.
344template<typename ValueType>
345constexpr bool printsApproximation = std::is_same_v<ValueType, storm::RationalNumber> || std::is_same_v<ValueType, storm::ExtendedRationalNumber>;
346
347template<typename ValueType>
348void printExact(std::ostream& out, ValueType const& value) {
349 if (storm::utility::isInfinity(value)) {
350 out << "inf";
351 } else {
352 out << value;
353 }
354}
355
356template<typename ValueType>
357void printApproximation(std::ostream& out, ValueType const& value) {
358 if (storm::utility::isInfinity(value)) {
359 out << "inf";
360 } else {
361 out << storm::utility::convertNumber<double>(value);
362 }
363}
364
365template<typename ValueType>
366void print(std::ostream& out, ValueType const& value) {
367 printExact(out, value);
368 if constexpr (printsApproximation<ValueType>) {
369 if (!storm::utility::isInfinity(value)) {
370 out << " (approx. ";
371 printApproximation(out, value);
372 out << ")";
373 }
374 }
375}
376
380template<typename ValueType>
381void printInterval(std::ostream& out, std::optional<ValueType> const& lower, std::optional<ValueType> const& upper) {
382 auto const printEnd = [&out](std::optional<ValueType> const& value, bool approximate) {
383 if (!value) {
384 out << "?";
385 } else if (approximate) {
386 printApproximation(out, *value);
387 } else {
388 printExact(out, *value);
389 }
390 };
391 out << "[";
392 printEnd(lower, false);
393 out << ", ";
394 printEnd(upper, false);
395 out << "]";
396 if constexpr (printsApproximation<ValueType>) {
397 out << " (approx. [";
398 printEnd(lower, true);
399 out << ", ";
400 printEnd(upper, true);
401 out << "])";
402 }
403}
404
405template<typename ValueType>
406void printRange(std::ostream& out, ValueType const& min, ValueType const& max) {
407 printInterval<ValueType>(out, min, max);
408 out << " (range)";
409}
410
414template<typename ValueType>
415void printBounds(std::ostream& out, std::optional<ValueType> const& lower, std::optional<ValueType> const& upper) {
416 if (!lower && !upper) {
417 return;
418 }
419 if (lower && upper && *lower == *upper) {
420 out << ". Exact solution.";
421 return;
422 }
423 out << ". Solution bounds: ";
424 printInterval(out, lower, upper);
425 out << ".";
426}
427
428template<typename ValueType>
429void ExplicitQuantitativeCheckResult<ValueType>::printValue(std::ostream& out, uint64_t offset) const {
430 print(out, values[offset]);
431 std::optional<ExtendedValueType> const lower =
432 this->hasLowerBounds() ? std::optional<ExtendedValueType>(this->getLowerBoundVector()[offset]) : std::nullopt;
433 std::optional<ExtendedValueType> const upper =
434 this->hasUpperBounds() ? std::optional<ExtendedValueType>(this->getUpperBoundVector()[offset]) : std::nullopt;
435 printBounds(out, lower, upper);
436}
437
438template<typename ValueType>
439std::ostream& ExplicitQuantitativeCheckResult<ValueType>::writeToStream(std::ostream& out) const {
440 bool minMaxSupported = std::is_same<ValueType, double>::value || std::is_same<ValueType, storm::RationalNumber>::value;
441
442 if (values.size() >= 10 && minMaxSupported) {
443 std::pair<ExtendedValueType, ExtendedValueType> minmax = this->getMinMax();
444 printRange(out, minmax.first, minmax.second);
445 if (bounds.isExact()) {
446 out << ". Exact solution.";
447 } else {
448 // The smallest lower and the largest upper bound enclose all values.
449 std::optional<ExtendedValueType> const lower =
450 this->hasLowerBounds() ? std::optional<ExtendedValueType>(storm::utility::minimum(this->getLowerBoundVector())) : std::nullopt;
451 std::optional<ExtendedValueType> const upper =
452 this->hasUpperBounds() ? std::optional<ExtendedValueType>(storm::utility::maximum(this->getUpperBoundVector())) : std::nullopt;
453 printBounds(out, lower, upper);
454 }
455 } else if (values.size() == 1) {
456 this->printValue(out, 0);
457 } else {
458 out << "{";
459 for (uint64_t offset = 0; offset < values.size(); ++offset) {
460 if (offset > 0) {
461 out << ", ";
462 }
463 this->printValue(out, offset);
464 }
465 out << "}";
466 }
467
468 return out;
469}
470
471template<typename ValueType>
473 ValueType const& bound) const {
474 auto const compare = [&comparisonType, &bound](ExtendedValueType const& value) {
475 switch (comparisonType) {
477 return value < bound;
479 return value <= bound;
481 return value > bound;
483 return value >= bound;
484 }
485 return false;
486 };
487
488 // A comparison is only sound if the bound falls outside the lower and upper bound of the result.
489 if (this->hasLowerBounds() && this->hasUpperBounds()) {
490 uint64_t offset = 0;
491 for (uint64_t state : states) {
492 STORM_LOG_WARN_COND(!((*bounds.lower)[offset] < bound && bound < (*bounds.upper)[offset]),
493 "The bound " << bound << " lies between the lower bound " << (*bounds.lower)[offset] << " and the upper bound "
494 << (*bounds.upper)[offset] << ", so the comparison against it is not decided at state " << state << ".");
495 ++offset;
496 }
497 }
498
499 storm::storage::BitVector result(values.size());
500 for (uint64_t offset = 0; offset < values.size(); ++offset) {
501 if (compare(values[offset])) {
502 result.set(offset);
503 }
504 }
505 return std::unique_ptr<CheckResult>(new ExplicitQualitativeCheckResult<ValueType>(states, std::move(result), scheduler));
506}
507
508template<>
510 storm::RationalFunction const& bound) const {
511 // Since it is not possible to compare rational functions against bounds, we simply call the base class method.
512 return QuantitativeCheckResult::compareAgainstBound(comparisonType, bound);
513}
514
515template<typename ValueType>
520
521template<typename ValueType>
526
527template<typename ValueType>
531
532template<typename ValueType>
534 return states.full();
535}
536
537template<typename ValueType>
541
542template<typename ValueType>
545 if (this->hasLowerBounds()) {
547 }
548 if (this->hasUpperBounds()) {
550 }
551 // Inverse the bounds, lb = 1 - ub and ub = 1 - lb.
552 std::swap(bounds.lower, bounds.upper);
553}
554
558template<typename ValueType>
560 if (storm::utility::isInfinity(value)) {
561 entry[key] = "inf";
562 } else if (storm::utility::isNegativeInfinity(value)) {
563 entry[key] = "-inf";
564 } else if constexpr (std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>) {
565 entry[key] = value;
566 } else {
567 entry[key] = value.getFinite();
568 }
569}
570
571template<typename ValueType>
573 std::optional<storm::storage::sparse::Valuations> const& stateValuations = std::nullopt,
574 std::optional<storm::models::sparse::StateLabeling> const& stateLabels = std::nullopt,
575 std::optional<storm::utility::ExtendedValueType<ValueType>> const& lowerBound = std::nullopt,
576 std::optional<storm::utility::ExtendedValueType<ValueType>> const& upperBound = std::nullopt) {
577 typename storm::json<ValueType> entry;
578 if (stateValuations) {
579 entry["s"] = stateValuations->template toJson<ValueType>(id);
580 } else {
581 entry["s"] = id;
582 }
583 insertJsonValue(entry, "v", value);
584 if (lowerBound) {
585 insertJsonValue(entry, "lb", *lowerBound);
586 }
587 if (upperBound) {
588 insertJsonValue(entry, "ub", *upperBound);
589 }
590 if (stateLabels) {
591 auto labs = stateLabels->getLabelsOfState(id);
592 entry["l"] = labs;
593 }
594 json.push_back(std::move(entry));
595}
596
597template<typename ValueType>
598storm::json<ValueType> ExplicitQuantitativeCheckResult<ValueType>::toJson(std::optional<storm::storage::sparse::Valuations> const& stateValuations,
599 std::optional<storm::models::sparse::StateLabeling> const& stateLabels) const {
601 uint64_t offset = 0;
602 this->forEachState([&](storm::storage::sparse::state_type state, ExtendedValueType const& value) {
603 insertJsonEntry(result, state, value, stateValuations, stateLabels,
604 this->hasLowerBounds() ? std::make_optional(this->getLowerBoundVector()[offset]) : std::nullopt,
605 this->hasUpperBounds() ? std::make_optional(this->getUpperBoundVector()[offset]) : std::nullopt);
606 ++offset;
607 });
608 return result;
609}
610
611template<>
613 std::optional<storm::storage::sparse::Valuations> const&, std::optional<storm::models::sparse::StateLabeling> const&) const {
614 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export of Check results is not supported for Rational Functions.");
615}
616
620} // namespace modelchecker
621} // namespace storm
ExplicitQualitativeCheckResult< ValueType > & asExplicitQualitativeCheckResult()
A qualitative check result over the states of a sparse model.
storm::storage::BitVector const & getStates() const
Retrieves the states this result holds truth values for.
vector_type const & getTruthValuesVector() const
Retrieves the truth values, one per state this result is for.
A quantitative check result over the states of a sparse model.
ExtendedValueType & operator[](storm::storage::sparse::state_type state)
Retrieves the value of the given state.
virtual std::ostream & writeToStream(std::ostream &out) const override
void setLowerBounds(vector_type lowerBounds)
Sets sound bounds on the actual values.
virtual std::unique_ptr< CheckResult > clone() const override
storm::storage::Scheduler< ValueType > const & getScheduler() const
bool hasValueForState(storm::storage::sparse::state_type state) const
Retrieves whether the result holds a value for the given state.
ExplicitQuantitativeCheckResult(storm::storage::sparse::state_type const &state, ExtendedValueType const &value)
Creates a result that holds the given value for the given state only.
virtual AggregatedValue< ExtendedValueType > aggregate(FilterType filter) const override
Aggregates the values of this result with the given filter, and each bound it carries alongside.
storm::json< ValueType > toJson(std::optional< storm::storage::sparse::Valuations > const &stateValuations=std::nullopt, std::optional< storm::models::sparse::StateLabeling > const &stateLabels=std::nullopt) const
virtual std::pair< ExtendedValueType, ExtendedValueType > getMinMax() const
void setValuesExact()
States that the values of this result are the exact ones, i.e.
virtual void filter(QualitativeCheckResult const &filter) override
Filters the current result wrt.
void setBounds(storm::solver::SolutionBounds< ExtendedValueType > bounds)
QuantitativeCheckResult< ValueType >::ExtendedValueType ExtendedValueType
vector_type const & getValueVector() const
Retrieves the values, one per state this result is for.
void setScheduler(std::unique_ptr< storm::storage::Scheduler< ValueType > > &&scheduler)
storm::solver::SolutionBounds< ExtendedValueType > const & getSolutionBounds() const
Retrieves both bounds at once, either of which may be unset.
bool hasLowerBounds() const
Retrieves whether sound lower resp.
vector_type const & getLowerBoundVector() const
Retrieves the sound lower resp.
virtual std::unique_ptr< CheckResult > compareAgainstBound(storm::logic::ComparisonType comparisonType, ValueType const &bound) const override
storm::storage::BitVector const & getStates() const
Retrieves the states this result holds values for.
virtual AggregatedValue< ExtendedValueType > aggregate(FilterType filter) const
Aggregates the values of this result with the given filter, and each bound it carries alongside.
virtual std::unique_ptr< CheckResult > compareAgainstBound(storm::logic::ComparisonType comparisonType, ValueType const &bound) const
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool isSubsetOf(BitVector const &other) const
Checks whether all bits that are set in the current bit vector are also set in the given bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class defines which action is chosen in a particular state of a non-deterministic model.
Definition Scheduler.h:18
#define STORM_LOG_THROW_UNCONDITIONALLY(exception, message)
Definition macros.h:48
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
Expression sum(std::vector< storm::expressions::Expression > const &expressions)
void insertJsonEntry(storm::json< JsonRationalType > &json, uint64_t const &id, bool value, std::optional< storm::storage::sparse::Valuations > const &stateValuations=std::nullopt, std::optional< storm::models::sparse::StateLabeling > const &stateLabels=std::nullopt)
void print(std::ostream &out, ValueType const &value)
void printInterval(std::ostream &out, std::optional< ValueType > const &lower, std::optional< ValueType > const &upper)
Writes the given interval, an unknown end of it as "?".
void printRange(std::ostream &out, ValueType const &min, ValueType const &max)
void printExact(std::ostream &out, ValueType const &value)
void insertJsonValue(storm::json< ValueType > &entry, std::string const &key, storm::utility::ExtendedValueType< ValueType > const &value)
Writes the given value under the given key, spelling out an infinity that the plain value type cannot...
void printBounds(std::ostream &out, std::optional< ValueType > const &lower, std::optional< ValueType > const &upper)
Writes the given bounds on the solution, and nothing at all if neither side is known.
std::string toString(FilterType ft)
Definition FilterType.cpp:9
void printApproximation(std::ostream &out, ValueType const &value)
void subtractFromConstantOneVector(std::vector< T > &vector)
Subtracts the given vector from the constant one-vector and writes the result to the input vector.
Definition vector.h:278
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
Definition vector.h:1069
ExtendedValueType< ValueType > positiveInfinity()
std::vector< ExtendedValueType< ValueType > > widen(std::vector< ValueType > &&values)
Widens a vector of finite values into the extended value type.
ExtendedValueType< ValueType > negativeInfinity()
bool isNegativeInfinity(ExtendedNumber< ValueType > const &number)
ValueType minimum(std::vector< ValueType > const &values)
ValueType zero()
Definition constants.cpp:26
std::conditional_t< storm::NumberTraits< ValueType >::HasInfinity, ValueType, ExtendedNumber< ValueType > > ExtendedValueType
The type to use for values that may be infinite.
std::pair< ValueType, ValueType > minmax(std::vector< ValueType > const &values)
std::vector< ValueType > narrowFinite(std::vector< ExtendedValueType< ValueType > > &&values)
The counterpart of widen for a vector all of whose values are finite.
ValueType toSentinel(ExtendedValueType< ValueType > const &value)
The counterpart of fromSentinel: hands an extended value back to a part of Storm that still expects t...
ValueType one()
Definition constants.cpp:21
ValueType maximum(std::vector< ValueType > const &values)
bool isInfinity(ValueType const &a)
TargetType convertNumber(SourceType const &number)
nlohmann::basic_json< std::map, std::vector, std::string, bool, int64_t, uint64_t, ValueType > json
Definition JsonForward.h:11
carl::RationalFunction< Polynomial, true > RationalFunction
The aggregate of the values of a quantitative check result, together with the aggregate of each bound...
Sound lower and upper bounds on a solution vector.
std::optional< std::vector< ValueType > > lower
std::optional< std::vector< ValueType > > upper