19template<
typename ValueType>
21 : states(
storm::
storage::BitVector(state + 1)), values({value}) {
25template<
typename ValueType>
28 : states(values.size(), true), values(values), scheduler(scheduler) {
32template<
typename ValueType>
35 : states(values.size(), true), values(
std::move(values)), scheduler(scheduler) {
39template<
typename ValueType>
42 : states(
std::move(states)), values(
std::move(values)), scheduler(scheduler) {
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))) {
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))) {
60template<
typename ValueType>
62 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
64 STORM_LOG_ASSERT(this->states.getNumberOfSetBits() == this->values.size(),
"Expected one value per selected state.");
67template<
typename ValueType>
72 values.reserve(truthValues.
size());
73 for (std::size_t i = 0; i < truthValues.
size(); i++) {
74 values.push_back(toValue(truthValues.
get(i)));
79template<
typename ValueType>
81 return std::make_unique<ExplicitQuantitativeCheckResult<ValueType>>(*this);
84template<
typename ValueType>
86 return state < states.
size() && states.get(state);
89template<
typename ValueType>
91 STORM_LOG_ASSERT(this->hasValueForState(state),
"State '" << state <<
"' has no value.");
92 return states.getNumberOfSetBitsBeforeIndex(state);
95template<
typename ValueType>
100template<
typename ValueType>
105template<
typename ValueType>
110template<
typename ValueType>
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) {
129template<
typename ValueType>
131 return bounds.hasLower();
134template<
typename ValueType>
136 return bounds.hasUpper();
139template<
typename ValueType>
142 return *bounds.lower;
145template<
typename ValueType>
148 return *bounds.upper;
151template<
typename ValueType>
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.");
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.");
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);
175template<
typename ValueType>
177 requires(!std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>)
180 if (bounds.hasLower()) {
183 if (bounds.hasUpper()) {
189template<
typename ValueType>
191 bounds.setExact(values);
194template<
typename ValueType>
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.");
210 uint64_t
const numStates = std::max(filterTruthValues.
size(), states.size());
212 available.
resize(numStates);
214 selected.
resize(numStates);
216 "The check result fails to contain some results referred to by the filter.");
227 states = filterTruthValues;
230template<
typename ValueType>
232 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException,
"Minimum of empty set is not defined.");
236template<
typename ValueType>
238 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException,
"Maximum of empty set is not defined.");
242template<
typename ValueType>
245 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException,
"Minimum/maximum of empty set is not defined.");
249template<
typename ValueType>
251 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException,
"Sum of empty set is not defined.");
255template<
typename ValueType>
257 STORM_LOG_THROW(!values.empty(), storm::exceptions::InvalidOperationException,
"Average of empty set is not defined.");
261template<
typename ValueType>
264 STORM_LOG_THROW(!vector.empty(), storm::exceptions::InvalidOperationException,
"Aggregate of empty set is not defined.");
273 bool hasPositiveInfinity =
false;
274 bool hasNegativeInfinity =
false;
276 for (
auto const& element : vector) {
278 hasPositiveInfinity =
true;
280 hasNegativeInfinity =
true;
285 STORM_LOG_THROW(!hasPositiveInfinity || !hasNegativeInfinity, storm::exceptions::InvalidOperationException,
286 "Cannot compute the sum of values containing both infinity and -infinity.");
287 if (hasPositiveInfinity) {
290 if (hasNegativeInfinity) {
308template<
typename ValueType>
313 result.
lower = aggregateVector(*bounds.lower,
filter);
316 result.
upper = aggregateVector(*bounds.upper,
filter);
321template<
typename ValueType>
323 return static_cast<bool>(scheduler);
326template<
typename ValueType>
328 this->scheduler = std::move(scheduler);
331template<
typename ValueType>
334 return *scheduler.value();
337template<
typename ValueType>
340 return *scheduler.value();
344template<
typename ValueType>
345constexpr bool printsApproximation = std::is_same_v<ValueType, storm::RationalNumber> || std::is_same_v<ValueType, storm::ExtendedRationalNumber>;
347template<
typename ValueType>
356template<
typename ValueType>
361 out << storm::utility::convertNumber<double>(value);
365template<
typename ValueType>
366void print(std::ostream& out, ValueType
const& value) {
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) {
385 }
else if (approximate) {
392 printEnd(lower,
false);
394 printEnd(upper,
false);
397 out <<
" (approx. [";
398 printEnd(lower,
true);
400 printEnd(upper,
true);
405template<
typename ValueType>
406void printRange(std::ostream& out, ValueType
const& min, ValueType
const& max) {
414template<
typename ValueType>
415void printBounds(std::ostream& out, std::optional<ValueType>
const& lower, std::optional<ValueType>
const& upper) {
416 if (!lower && !upper) {
419 if (lower && upper && *lower == *upper) {
420 out <<
". Exact solution.";
423 out <<
". Solution bounds: ";
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;
438template<
typename ValueType>
440 bool minMaxSupported = std::is_same<ValueType, double>::value || std::is_same<ValueType, storm::RationalNumber>::value;
442 if (values.size() >= 10 && minMaxSupported) {
443 std::pair<ExtendedValueType, ExtendedValueType> minmax = this->
getMinMax();
445 if (bounds.isExact()) {
446 out <<
". Exact solution.";
449 std::optional<ExtendedValueType>
const lower =
451 std::optional<ExtendedValueType>
const upper =
455 }
else if (values.size() == 1) {
456 this->printValue(out, 0);
459 for (uint64_t offset = 0; offset < values.size(); ++offset) {
463 this->printValue(out, offset);
471template<
typename ValueType>
473 ValueType
const& bound)
const {
475 switch (comparisonType) {
477 return value < bound;
479 return value <= bound;
481 return value > bound;
483 return value >= bound;
491 for (uint64_t state : states) {
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 <<
".");
500 for (uint64_t offset = 0; offset < values.size(); ++offset) {
501 if (compare(values[offset])) {
515template<
typename ValueType>
518 return values[this->getOffset(state)];
521template<
typename ValueType>
524 return values[this->getOffset(state)];
527template<
typename ValueType>
532template<
typename ValueType>
534 return states.full();
537template<
typename ValueType>
542template<
typename ValueType>
552 std::swap(bounds.lower, bounds.upper);
558template<
typename ValueType>
564 }
else if constexpr (std::is_same_v<storm::utility::ExtendedValueType<ValueType>, ValueType>) {
567 entry[key] = value.getFinite();
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,
578 if (stateValuations) {
579 entry[
"s"] = stateValuations->template toJson<ValueType>(
id);
591 auto labs = stateLabels->getLabelsOfState(
id);
594 json.push_back(std::move(entry));
597template<
typename ValueType>
599 std::optional<storm::models::sparse::StateLabeling>
const& stateLabels)
const {
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.");
ExplicitQualitativeCheckResult< ValueType > & asExplicitQualitativeCheckResult()
A qualitative check result over the states of a sparse model.
storm::storage::BitVector vector_type
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.
std::vector< ValueType > getSentinelValueVector() const
virtual bool hasScheduler() const override
void setUpperBounds(vector_type upperBounds)
virtual std::unique_ptr< CheckResult > clone() const override
virtual ExtendedValueType average() 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.
virtual ExtendedValueType getMax() const override
bool hasUpperBounds() const
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.
std::vector< ValueType > getFiniteValueVector() const
virtual bool isResultForAllStates() const override
std::vector< ExtendedValueType > vector_type
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 bool isExplicit() const override
virtual ExtendedValueType getMin() const override
virtual bool isExplicitQuantitativeCheckResult() const override
virtual std::pair< ExtendedValueType, ExtendedValueType > getMinMax() const
virtual void oneMinus() override
vector_type const & getUpperBoundVector() 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 clearBounds()
Drops all bounds, e.g.
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 ExtendedValueType sum() const override
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.
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.
#define STORM_LOG_THROW_UNCONDITIONALLY(exception, message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
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.
constexpr bool printsApproximation
std::string toString(FilterType ft)
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.
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
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)
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 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
carl::RationalFunction< Polynomial, true > RationalFunction
The aggregate of the values of a quantitative check result, together with the aggregate of each bound...
std::optional< ValueType > upper
std::optional< ValueType > lower
Sound lower and upper bounds on a solution vector.
std::optional< std::vector< ValueType > > lower
std::optional< std::vector< ValueType > > upper