#include "storm/solver/AbstractEquationSolver.h" #include "storm/adapters/RationalNumberAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/utility/constants.h" #include "storm/utility/macros.h" #include "storm/exceptions/UnmetRequirementException.h" namespace storm { namespace solver { template AbstractEquationSolver::AbstractEquationSolver() { if (storm::settings::getModule().isVerboseSet()) { this->progressMeasurement = storm::utility::ProgressMeasurement("iterations"); } } template void AbstractEquationSolver::setTerminationCondition(std::unique_ptr> terminationCondition) { this->terminationCondition = std::move(terminationCondition); } template void AbstractEquationSolver::resetTerminationCondition() { this->terminationCondition = nullptr; } template bool AbstractEquationSolver::hasCustomTerminationCondition() const { return static_cast(this->terminationCondition); } template TerminationCondition const& AbstractEquationSolver::getTerminationCondition() const { return *terminationCondition; } template std::unique_ptr> const& AbstractEquationSolver::getTerminationConditionPointer() const { return terminationCondition; } template bool AbstractEquationSolver::terminateNow(std::vector const& values, SolverGuarantee const& guarantee) const { if (!this->hasCustomTerminationCondition()) { return false; } return this->getTerminationCondition().terminateNow(values, guarantee); } template bool AbstractEquationSolver::hasRelevantValues() const { return static_cast(relevantValues); } template storm::storage::BitVector const& AbstractEquationSolver::getRelevantValues()const { return relevantValues.get(); } template void AbstractEquationSolver::setRelevantValues(storm::storage::BitVector&& relevantValues) { this->relevantValues = std::move(relevantValues); } template void AbstractEquationSolver::clearRelevantValues() { relevantValues = boost::none; } template bool AbstractEquationSolver::hasLowerBound(BoundType const& type) const { if (type == BoundType::Any) { return static_cast(lowerBound) || static_cast(lowerBounds); } else if (type == BoundType::Global) { return static_cast(lowerBound); } else if (type == BoundType::Local) { return static_cast(lowerBounds); } return false; } template bool AbstractEquationSolver::hasUpperBound(BoundType const& type) const { if (type == BoundType::Any) { return static_cast(upperBound) || static_cast(upperBounds); } else if (type == BoundType::Global) { return static_cast(upperBound); } else if (type == BoundType::Local) { return static_cast(upperBounds); } return false; } template void AbstractEquationSolver::setLowerBound(ValueType const& value) { lowerBound = value; } template void AbstractEquationSolver::setUpperBound(ValueType const& value) { upperBound = value; } template void AbstractEquationSolver::setBounds(ValueType const& lower, ValueType const& upper) { setLowerBound(lower); setUpperBound(upper); } template ValueType const& AbstractEquationSolver::getLowerBound() const { return lowerBound.get(); } template ValueType const& AbstractEquationSolver::getUpperBound() const { return upperBound.get(); } template std::vector const& AbstractEquationSolver::getLowerBounds() const { return lowerBounds.get(); } template std::vector const& AbstractEquationSolver::getUpperBounds() const { return upperBounds.get(); } template void AbstractEquationSolver::setLowerBounds(std::vector const& values) { lowerBounds = values; } template void AbstractEquationSolver::setLowerBounds(std::vector&& values) { lowerBounds = std::move(values); } template void AbstractEquationSolver::setUpperBounds(std::vector const& values) { upperBounds = values; } template void AbstractEquationSolver::setUpperBounds(std::vector&& values) { upperBounds = std::move(values); } template void AbstractEquationSolver::setBounds(std::vector const& lower, std::vector const& upper) { setLowerBounds(lower); setUpperBounds(upper); } template void AbstractEquationSolver::setBoundsFromOtherSolver(AbstractEquationSolver const& other) { if (other.hasLowerBound(BoundType::Global)) { this->setLowerBound(other.getLowerBound()); } if (other.hasLowerBound(BoundType::Local)) { this->setLowerBounds(other.getLowerBounds()); } if (other.hasUpperBound(BoundType::Global)) { this->setUpperBound(other.getUpperBound()); } if (other.hasUpperBound(BoundType::Local)) { this->setUpperBounds(other.getUpperBounds()); } } template void AbstractEquationSolver::clearBounds() { lowerBound = boost::none; upperBound = boost::none; lowerBounds = boost::none; upperBounds = boost::none; } template void AbstractEquationSolver::createLowerBoundsVector(std::vector& lowerBoundsVector) const { if (this->hasLowerBound(BoundType::Local)) { lowerBoundsVector = this->getLowerBounds(); } else { ValueType lowerBound = this->hasLowerBound(BoundType::Global) ? this->getLowerBound() : storm::utility::zero(); for (auto& e : lowerBoundsVector) { e = lowerBound; } } } template void AbstractEquationSolver::createUpperBoundsVector(std::vector& upperBoundsVector) const { STORM_LOG_ASSERT(this->hasUpperBound(), "Expecting upper bound(s)."); if (this->hasUpperBound(BoundType::Global)) { upperBoundsVector.assign(upperBoundsVector.size(), this->getUpperBound()); } else { upperBoundsVector.assign(this->getUpperBounds().begin(), this->getUpperBounds().end()); } } template void AbstractEquationSolver::createUpperBoundsVector(std::unique_ptr>& upperBoundsVector, uint64_t length) const { STORM_LOG_ASSERT(this->hasUpperBound(), "Expecting upper bound(s)."); if (!upperBoundsVector) { if (this->hasUpperBound(BoundType::Local)) { STORM_LOG_ASSERT(length == this->getUpperBounds().size(), "Mismatching sizes."); upperBoundsVector = std::make_unique>(this->getUpperBounds()); } else { upperBoundsVector = std::make_unique>(length, this->getUpperBound()); } } else { createUpperBoundsVector(*upperBoundsVector); } } template bool AbstractEquationSolver::isShowProgressSet() const { return this->progressMeasurement.is_initialized(); } template uint64_t AbstractEquationSolver::getShowProgressDelay() const { STORM_LOG_ASSERT(this->isShowProgressSet(), "Tried to get the progress message delay but progress is not shown."); return this->progressMeasurement->getShowProgressDelay(); } template void AbstractEquationSolver::startMeasureProgress(uint64_t startingIteration) const { if (this->isShowProgressSet()) { this->progressMeasurement->startNewMeasurement(startingIteration); } } template void AbstractEquationSolver::showProgressIterative(uint64_t iteration, boost::optional const& bound) const { if (this->isShowProgressSet()) { if (bound) { this->progressMeasurement->setMaxCount(bound.get()); } this->progressMeasurement->updateProgress(iteration); } } template void AbstractEquationSolver::setPrecision(ValueType const& precision) { STORM_LOG_DEBUG("Setting solver precision for a solver that does not support precisions."); } template class AbstractEquationSolver; template class AbstractEquationSolver; #ifdef STORM_HAVE_CARL template class AbstractEquationSolver; template class AbstractEquationSolver; #endif } }