#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/storage/BitVector.h" #include "src/utility/macros.h" #include "src/utility/vector.h" #include "src/exceptions/InvalidOperationException.h" #include "src/adapters/CarlAdapter.h" namespace storm { namespace modelchecker { template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult() : values(map_type()) { // Intentionally left empty. } template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult(map_type const& values) : values(values) { // Intentionally left empty. } template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult(map_type&& values) : values(std::move(values)) { // Intentionally left empty. } template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult(storm::storage::sparse::state_type const& state, ValueType const& value) : values(map_type()) { boost::get(values).emplace(state, value); } template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult(vector_type const& values) : values(values) { // Intentionally left empty. } template ExplicitQuantitativeCheckResult::ExplicitQuantitativeCheckResult(vector_type&& values) : values(std::move(values)) { // Intentionally left empty. } template typename ExplicitQuantitativeCheckResult::vector_type const& ExplicitQuantitativeCheckResult::getValueVector() const { return boost::get(values); } template typename ExplicitQuantitativeCheckResult::map_type const& ExplicitQuantitativeCheckResult::getValueMap() const { return boost::get(values); } template void ExplicitQuantitativeCheckResult::filter(QualitativeCheckResult const& filter) { STORM_LOG_THROW(filter.isExplicitQualitativeCheckResult(), storm::exceptions::InvalidOperationException, "Cannot filter explicit check result with non-explicit filter."); STORM_LOG_THROW(filter.isResultForAllStates(), storm::exceptions::InvalidOperationException, "Cannot filter check result with non-complete filter."); ExplicitQualitativeCheckResult const& explicitFilter = filter.asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult::vector_type const& filterTruthValues = explicitFilter.getTruthValuesVector(); if (this->isResultForAllStates()) { map_type newMap; for (auto const& element : filterTruthValues) { newMap.emplace(element, this->getValueVector()[element]); } this->values = newMap; } else { map_type const& map = boost::get(values); map_type newMap; for (auto const& element : map) { if (filterTruthValues.get(element.first)) { newMap.insert(element); } } STORM_LOG_THROW(newMap.size() == filterTruthValues.getNumberOfSetBits(), storm::exceptions::InvalidOperationException, "The check result fails to contain some results referred to by the filter."); this->values = newMap; } } template std::ostream& ExplicitQuantitativeCheckResult::writeToStream(std::ostream& out) const { out << "["; if (this->isResultForAllStates()) { vector_type const& valuesAsVector = boost::get(values); bool first = true; for (auto const& element : valuesAsVector) { if (!first) { out << ", "; } else { first = false; } out << element; } } else { map_type const& valuesAsMap = boost::get(values); bool first = true; for (auto const& element : valuesAsMap) { if (!first) { out << ", "; } else { first = false; } out << element.second; } } out << "]"; return out; } template std::unique_ptr ExplicitQuantitativeCheckResult::compareAgainstBound(storm::logic::ComparisonType comparisonType, double bound) const { if (this->isResultForAllStates()) { vector_type const& valuesAsVector = boost::get(values); storm::storage::BitVector result(valuesAsVector.size()); switch (comparisonType) { case logic::Less: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { if (result[index] < bound) { result.set(index); } } break; case logic::LessEqual: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { if (result[index] <= bound) { result.set(index); } } break; case logic::Greater: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { if (result[index] > bound) { result.set(index); } } break; case logic::GreaterEqual: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { if (result[index] >= bound) { result.set(index); } } break; } return std::unique_ptr(new ExplicitQualitativeCheckResult(std::move(result))); } else { map_type const& valuesAsMap = boost::get(values); std::map result; switch (comparisonType) { case logic::Less: for (auto const& element : valuesAsMap) { result[element.first] = element.second < bound; } break; case logic::LessEqual: for (auto const& element : valuesAsMap) { result[element.first] = element.second <= bound; } break; case logic::Greater: for (auto const& element : valuesAsMap) { result[element.first] = element.second > bound; } break; case logic::GreaterEqual: for (auto const& element : valuesAsMap) { result[element.first] = element.second >= bound; } break; } return std::unique_ptr(new ExplicitQualitativeCheckResult(std::move(result))); } } #ifdef STORM_HAVE_CARL template<> std::unique_ptr ExplicitQuantitativeCheckResult::compareAgainstBound(storm::logic::ComparisonType comparisonType, double bound) const { // Since it is not possible to compare rational functions against bounds, we simply call the base class method. return QuantitativeCheckResult::compareAgainstBound(comparisonType, bound); } #endif template ValueType& ExplicitQuantitativeCheckResult::operator[](storm::storage::sparse::state_type state) { if (this->isResultForAllStates()) { return boost::get(values)[state]; } else { return boost::get(values)[state]; } } template ValueType const& ExplicitQuantitativeCheckResult::operator[](storm::storage::sparse::state_type state) const { if (this->isResultForAllStates()) { return boost::get(values)[state]; } else { map_type const& valuesAsMap = boost::get(values); auto const& keyValuePair = valuesAsMap.find(state); STORM_LOG_THROW(keyValuePair != valuesAsMap.end(), storm::exceptions::InvalidOperationException, "Unknown key '" << state << "'."); return keyValuePair->second; } } template bool ExplicitQuantitativeCheckResult::isExplicit() const { return true; } template bool ExplicitQuantitativeCheckResult::isResultForAllStates() const { return values.which() == 0; } template bool ExplicitQuantitativeCheckResult::isExplicitQuantitativeCheckResult() const { return true; } template class ExplicitQuantitativeCheckResult; #ifdef STORM_HAVE_CARL template class ExplicitQuantitativeCheckResult; #endif } }