You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
8.0 KiB
166 lines
8.0 KiB
#include "storm/solver/TerminationCondition.h"
|
|
#include "storm/utility/vector.h"
|
|
|
|
#include "storm/adapters/RationalFunctionAdapter.h"
|
|
|
|
#include "storm/utility/macros.h"
|
|
#include "storm/exceptions/InvalidArgumentException.h"
|
|
|
|
namespace storm {
|
|
namespace solver {
|
|
|
|
template<typename ValueType>
|
|
bool TerminationCondition<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const {
|
|
return terminateNow([¤tValues] (uint64_t const& i) {return currentValues[i];}, guarantee);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool NoTerminationCondition<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const {
|
|
return false;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool NoTerminationCondition<ValueType>::requiresGuarantee(SolverGuarantee const&) const {
|
|
return false;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
TerminateIfFilteredSumExceedsThreshold<ValueType>::TerminateIfFilteredSumExceedsThreshold(storm::storage::BitVector const& filter, ValueType const& threshold, bool strict) : threshold(threshold), filter(filter), strict(strict) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredSumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const {
|
|
if (guarantee != SolverGuarantee::LessOrEqual) {
|
|
return false;
|
|
}
|
|
|
|
ValueType sum = storm::utility::zero<ValueType>();
|
|
for (auto pos : filter) {
|
|
sum += valueGetter(pos);
|
|
// Exiting this loop early is not possible as values might be negative
|
|
}
|
|
return strict ? sum > this->threshold : sum >= this->threshold;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredSumExceedsThreshold<ValueType>::requiresGuarantee(SolverGuarantee const& guarantee) const {
|
|
return guarantee == SolverGuarantee::LessOrEqual;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
TerminateIfFilteredExtremumExceedsThreshold<ValueType>::TerminateIfFilteredExtremumExceedsThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) {
|
|
// Intentionally left empty.
|
|
STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set.");
|
|
cachedExtremumIndex = this->filter.getNextSetIndex(0);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const {
|
|
if (guarantee != SolverGuarantee::LessOrEqual) {
|
|
return false;
|
|
}
|
|
|
|
ValueType extremum = valueGetter(cachedExtremumIndex);
|
|
if (useMinimum && (this->strict ? extremum <= this->threshold : extremum < this->threshold)) {
|
|
// The extremum can only become smaller so we can return right now.
|
|
return false;
|
|
}
|
|
|
|
if (useMinimum) {
|
|
if (this->strict) {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::min(valueGetter(pos), extremum);
|
|
if (extremum <= this->threshold) {
|
|
cachedExtremumIndex = pos;
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::min(valueGetter(pos), extremum);
|
|
if (extremum < this->threshold) {
|
|
cachedExtremumIndex = pos;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::max(valueGetter(pos), extremum);
|
|
}
|
|
}
|
|
|
|
return this->strict ? extremum > this->threshold : extremum >= this->threshold;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::requiresGuarantee(SolverGuarantee const& guarantee) const {
|
|
return guarantee == SolverGuarantee::LessOrEqual;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
TerminateIfFilteredExtremumBelowThreshold<ValueType>::TerminateIfFilteredExtremumBelowThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) {
|
|
STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set.");
|
|
cachedExtremumIndex = this->filter.getNextSetIndex(0);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const {
|
|
if (guarantee != SolverGuarantee::GreaterOrEqual) {
|
|
return false;
|
|
}
|
|
|
|
ValueType extremum = valueGetter(cachedExtremumIndex);
|
|
if (!useMinimum && (this->strict ? extremum >= this->threshold : extremum > this->threshold)) {
|
|
// The extremum can only become larger so we can return right now.
|
|
return false;
|
|
}
|
|
|
|
if (useMinimum) {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::min(valueGetter(pos), extremum);
|
|
}
|
|
} else {
|
|
if (this->strict) {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::max(valueGetter(pos), extremum);
|
|
if (extremum >= this->threshold) {
|
|
cachedExtremumIndex = pos;
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
for (auto pos : this->filter) {
|
|
extremum = std::max(valueGetter(pos), extremum);
|
|
if (extremum > this->threshold) {
|
|
cachedExtremumIndex = pos;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this->strict ? extremum < this->threshold : extremum <= this->threshold;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::requiresGuarantee(SolverGuarantee const& guarantee) const {
|
|
return guarantee == SolverGuarantee::GreaterOrEqual;
|
|
}
|
|
|
|
template class TerminationCondition<double>;
|
|
template class NoTerminationCondition<double>;
|
|
template class TerminateIfFilteredSumExceedsThreshold<double>;
|
|
template class TerminateIfFilteredExtremumExceedsThreshold<double>;
|
|
template class TerminateIfFilteredExtremumBelowThreshold<double>;
|
|
#ifdef STORM_HAVE_CARL
|
|
template class TerminationCondition<storm::RationalNumber>;
|
|
template class NoTerminationCondition<storm::RationalNumber>;
|
|
template class TerminateIfFilteredSumExceedsThreshold<storm::RationalNumber>;
|
|
template class TerminateIfFilteredExtremumExceedsThreshold<storm::RationalNumber>;
|
|
template class TerminateIfFilteredExtremumBelowThreshold<storm::RationalNumber>;
|
|
#endif
|
|
|
|
}
|
|
}
|