#pragma once #include #include #include "storm/solver/OptimizationDirection.h" #include "storm/logic/ComparisonType.h" #include "storm/storage/BitVector.h" #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/MinMaxLinearEquationSolver.h" namespace storm { namespace storage { template class SparseMatrix; } namespace solver { template class MinMaxLinearEquationSolverFactory; template class LinearEquationSolverFactory; } namespace modelchecker { template class CheckTask; } namespace models { namespace sparse { template class Model; } } namespace solver { template class MinMaxLinearEquationSolver; template class LinearEquationSolver; template class SolveGoal { public: SolveGoal(); template SolveGoal(storm::models::sparse::Model const& model, storm::modelchecker::CheckTask const& checkTask) { if (checkTask.isOptimizationDirectionSet()) { optimizationDirection = checkTask.getOptimizationDirection(); } if (checkTask.isOnlyInitialStatesRelevantSet()) { relevantValueVector = model.getInitialStates(); } if (checkTask.isBoundSet()) { comparisonType = checkTask.getBoundComparisonType(); threshold = checkTask.getBoundThreshold(); } } SolveGoal(bool minimize); SolveGoal(OptimizationDirection d); SolveGoal(OptimizationDirection d, storm::logic::ComparisonType boundComparisonType, ValueType const& boundThreshold, storm::storage::BitVector const& relevantValues); /*! * Flips the comparison type, the direction, and computes the new threshold as 1 - old threshold. */ void oneMinus(); bool hasDirection() const; bool minimize() const; OptimizationDirection direction() const; bool isBounded() const; bool boundIsALowerBound() const; bool boundIsStrict() const; ValueType const& thresholdValue() const; bool hasRelevantValues() const; storm::storage::BitVector& relevantValues(); storm::storage::BitVector const& relevantValues() const; void restrictRelevantValues(storm::storage::BitVector const& filter); void setRelevantValues(storm::storage::BitVector&& values); private: boost::optional optimizationDirection; boost::optional comparisonType; boost::optional threshold; boost::optional relevantValueVector; }; template std::unique_ptr> configureMinMaxLinearEquationSolver(Environment const& env, SolveGoal&& goal, storm::solver::MinMaxLinearEquationSolverFactory const& factory, MatrixType&& matrix) { std::unique_ptr> solver = factory.create(env, std::forward(matrix)); solver->setOptimizationDirection(goal.direction()); if (goal.isBounded()) { if (goal.boundIsALowerBound()) { solver->setTerminationCondition(std::make_unique>(goal.relevantValues(), goal.boundIsStrict(), goal.thresholdValue(), true)); } else { solver->setTerminationCondition(std::make_unique>(goal.relevantValues(), goal.boundIsStrict(), goal.thresholdValue(), false)); } } if (goal.hasRelevantValues()) { solver->setRelevantValues(std::move(goal.relevantValues())); } return solver; } template std::unique_ptr> configureLinearEquationSolver(Environment const& env, SolveGoal&& goal, storm::solver::LinearEquationSolverFactory const& factory, MatrixType&& matrix) { std::unique_ptr> solver = factory.create(env, std::forward(matrix)); if (goal.isBounded()) { solver->setTerminationCondition(std::make_unique>(goal.relevantValues(), goal.boundIsStrict(), goal.thresholdValue(), goal.minimize())); } return solver; } template std::unique_ptr> configureLinearEquationSolver(Environment const& env, SolveGoal&& goal, storm::solver::LinearEquationSolverFactory const& factory, MatrixType&& matrix) { std::unique_ptr> solver = factory.create(env, std::forward(matrix)); return solver; } } }