Browse Source

Merge branch 'master' into newrewardmodel

Former-commit-id: bdd48128d1
main
dehnert 11 years ago
parent
commit
6c5f6b5d5e
  1. 1
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  2. 6
      src/modelchecker/AbstractModelChecker.cpp
  3. 6
      src/modelchecker/csl/helper/HybridCtmcCslHelper.cpp
  4. 8
      src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp
  5. 1
      src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp
  6. 9
      src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
  7. 1
      src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
  8. 2
      src/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp
  9. 5
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
  10. 2
      src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
  11. 20
      src/settings/modules/GeneralSettings.cpp
  12. 20
      src/settings/modules/GeneralSettings.h
  13. 3
      src/settings/modules/GlpkSettings.cpp
  14. 3
      src/settings/modules/GmmxxEquationSolverSettings.cpp
  15. 4
      src/settings/modules/GurobiSettings.cpp
  16. 4
      src/settings/modules/NativeEquationSolverSettings.cpp
  17. 3
      src/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp
  18. 55
      src/solver/GmmxxMinMaxLinearEquationSolver.cpp
  19. 18
      src/solver/GmmxxMinMaxLinearEquationSolver.h
  20. 5
      src/solver/LinearEquationSolver.h
  21. 27
      src/solver/MinMaxLinearEquationSolver.cpp
  22. 53
      src/solver/MinMaxLinearEquationSolver.h
  23. 72
      src/solver/NativeMinMaxLinearEquationSolver.cpp
  24. 19
      src/solver/NativeMinMaxLinearEquationSolver.h
  25. 32
      src/solver/SolverSelectionOptions.cpp
  26. 20
      src/solver/SolverSelectionOptions.h
  27. 19
      src/solver/TopologicalMinMaxLinearEquationSolver.cpp
  28. 4
      src/solver/TopologicalMinMaxLinearEquationSolver.h
  29. 5
      src/storage/BitVector.cpp
  30. 5
      src/storage/BitVector.h
  31. 16
      src/storage/SparseMatrix.cpp
  32. 12
      src/storage/SparseMatrix.h
  33. 15
      src/storage/prism/Assignment.cpp
  34. 7
      src/storage/prism/Assignment.h
  35. 16
      src/storage/prism/Command.cpp
  36. 8
      src/storage/prism/Command.h
  37. 12
      src/storage/prism/Program.cpp
  38. 11
      src/storage/prism/Update.cpp
  39. 6
      src/storage/prism/Update.h
  40. 53
      src/utility/ConstantsComparator.cpp
  41. 5
      src/utility/ConstantsComparator.h
  42. 28
      src/utility/ExtendSettingEnumWithSelectionField.h
  43. 2
      src/utility/cli.cpp
  44. 63
      src/utility/constants.cpp
  45. 9
      src/utility/constants.h
  46. 28
      src/utility/solver.cpp
  47. 23
      src/utility/solver.h
  48. 36
      src/utility/vector.h
  49. 2
      test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp
  50. 103
      test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
  51. 2
      test/functional/modelchecker/GmmxxHybridCtmcCslModelCheckerTest.cpp
  52. 63
      test/functional/modelchecker/GmmxxHybridDtmcPrctlModelCheckerTest.cpp
  53. 3
      test/functional/modelchecker/GmmxxHybridMdpPrctlModelCheckerTest.cpp
  54. 2
      test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp
  55. 2
      test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp
  56. 98
      test/functional/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
  57. 2
      test/functional/modelchecker/NativeHybridCtmcCslModelCheckerTest.cpp
  58. 63
      test/functional/modelchecker/NativeHybridDtmcPrctlModelCheckerTest.cpp
  59. 2
      test/functional/modelchecker/NativeHybridMdpPrctlModelCheckerTest.cpp
  60. 2
      test/functional/modelchecker/NativeMdpPrctlModelCheckerTest.cpp
  61. 77
      test/functional/modelchecker/SparseDtmcEliminationModelCheckerTest.cpp
  62. 63
      test/functional/modelchecker/SymbolicDtmcPrctlModelCheckerTest.cpp
  63. 2
      test/functional/modelchecker/SymbolicMdpPrctlModelCheckerTest.cpp
  64. 1
      test/functional/solver/FullySymbolicGameSolverTest.cpp
  65. 2
      test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp
  66. 11
      test/functional/solver/MinMaxTechniqueSelectionTest.cpp
  67. 2
      test/functional/solver/NativeMinMaxLinearEquationSolverTest.cpp
  68. 15
      test/functional/storage/BitVectorTest.cpp
  69. 14
      test/functional/utility/VectorTest.cpp
  70. 1
      test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
  71. 1
      test/performance/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp
  72. 2
      test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
  73. 2
      test/performance/modelchecker/NativeMdpPrctlModelCheckerTest.cpp

1
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -17,6 +17,7 @@
#include "src/utility/graph.h"
#include "src/utility/counterexamples.h"
#include "src/utility/solver.h"
#include "src/solver/LpSolver.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"

6
src/modelchecker/AbstractModelChecker.cpp

@ -160,7 +160,7 @@ namespace storm {
// If the probability bound is 0 or 1, is suffices to do qualitative model checking.
bool qualitative = false;
if (stateFormula.hasBound()) {
if (stateFormula.getBound() == storm::utility::zero<double>() || stateFormula.getBound() == storm::utility::one<double>()) {
if (storm::utility::isZero(stateFormula.getBound()) || storm::utility::isOne(stateFormula.getBound())) {
qualitative = true;
}
}
@ -192,7 +192,7 @@ namespace storm {
// If the reward bound is 0, is suffices to do qualitative model checking.
bool qualitative = false;
if (stateFormula.hasBound()) {
if (stateFormula.getBound() == storm::utility::zero<double>()) {
if (storm::utility::isZero(stateFormula.getBound())) {
qualitative = true;
}
}
@ -224,7 +224,7 @@ namespace storm {
// If the reward bound is 0, is suffices to do qualitative model checking.
bool qualitative = false;
if (stateFormula.hasBound()) {
if (stateFormula.getBound() == storm::utility::zero<double>()) {
if (storm::utility::isZero(stateFormula.getBound())) {
qualitative = true;
}
}

6
src/modelchecker/csl/helper/HybridCtmcCslHelper.cpp

@ -45,7 +45,7 @@ namespace storm {
std::unique_ptr<CheckResult> HybridCtmcCslHelper<DdType, ValueType>::computeBoundedUntilProbabilities(storm::models::symbolic::Model<DdType> const& model, storm::dd::Add<DdType> const& rateMatrix, storm::dd::Add<DdType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// If the time bounds are [0, inf], we rather call untimed reachability.
if (lowerBound == storm::utility::zero<ValueType>() && upperBound == storm::utility::infinity<ValueType>()) {
if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) {
return computeUntilProbabilities(model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative, linearEquationSolverFactory);
}
@ -60,11 +60,11 @@ namespace storm {
STORM_LOG_INFO("Found " << statesWithProbabilityGreater0NonPsi.getNonZeroCount() << " 'maybe' states.");
if (!statesWithProbabilityGreater0NonPsi.isZero()) {
if (upperBound == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(upperBound)) {
// In this case, the interval is of the form [0, 0].
return std::unique_ptr<CheckResult>(new SymbolicQuantitativeCheckResult<DdType>(model.getReachableStates(), psiStates.toAdd()));
} else {
if (lowerBound == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(lowerBound)) {
// In this case, the interval is of the form [0, t].
// Note that this excludes [0, inf] since this is untimed reachability and we considered this case earlier.

8
src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp

@ -25,7 +25,7 @@ namespace storm {
uint_fast64_t numberOfStates = rateMatrix.getRowCount();
// If the time bounds are [0, inf], we rather call untimed reachability.
if (lowerBound == storm::utility::zero<ValueType>() && upperBound == storm::utility::infinity<ValueType>()) {
if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) {
return computeUntilProbabilities(rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative, linearEquationSolverFactory);
}
@ -43,12 +43,12 @@ namespace storm {
STORM_LOG_INFO("Found " << statesWithProbabilityGreater0NonPsi.getNumberOfSetBits() << " 'maybe' states.");
if (!statesWithProbabilityGreater0NonPsi.empty()) {
if (upperBound == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(upperBound)) {
// In this case, the interval is of the form [0, 0].
result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::one<ValueType>());
} else {
if (lowerBound == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(lowerBound)) {
// In this case, the interval is of the form [0, t].
// Note that this excludes [0, inf] since this is untimed reachability and we considered this case earlier.
@ -228,7 +228,7 @@ namespace storm {
ValueType lambda = timeBound * uniformizationRate;
// If no time can pass, the current values are the result.
if (lambda == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(lambda)) {
return values;
}

1
src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp

@ -14,6 +14,7 @@
#include "src/utility/numerical.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/solver/LpSolver.h"
#include "src/exceptions/InvalidStateException.h"

9
src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp

@ -9,8 +9,7 @@
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/utility/macros.h"
#include "src/utility/graph.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/settings/modules/GeneralSettings.h"
@ -54,7 +53,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(pathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
@ -65,14 +64,14 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel(), this->getModel().getTransitionMatrix(), rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
}
template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel(), this->getModel().getTransitionMatrix(), rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
}

1
src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp

@ -10,6 +10,7 @@
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/settings/modules/GeneralSettings.h"

2
src/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp

@ -13,6 +13,8 @@
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/modelchecker/results/HybridQuantitativeCheckResult.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/exceptions/InvalidPropertyException.h"
namespace storm {

5
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

@ -6,6 +6,9 @@
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/solver/LpSolver.h"
#include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h"
@ -363,7 +366,7 @@ namespace storm {
std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC");
solver->setModelSense(minimize ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
//// First, we need to create the variables for the problem.
// First, we need to create the variables for the problem.
std::map<uint_fast64_t, storm::expressions::Variable> stateToVariableMap;
for (auto const& stateChoicesPair : mec) {
std::string variableName = "h" + std::to_string(stateChoicesPair.first);

2
src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp

@ -946,7 +946,7 @@ namespace storm {
for (auto const& element : row) {
// If the probability is zero, we skip this entry.
if (element.getValue() == storm::utility::zero<ValueType>()) {
if (storm::utility::isZero(element.getValue())) {
continue;
}

20
src/settings/modules/GeneralSettings.cpp

@ -6,7 +6,7 @@
#include "src/settings/OptionBuilder.h"
#include "src/settings/ArgumentBuilder.h"
#include "src/settings/Argument.h"
#include "src/solver/SolverSelectionOptions.h"
#include "src/exceptions/InvalidSettingsException.h"
@ -231,12 +231,12 @@ namespace storm {
return this->getOption(timeoutOptionName).getArgumentByName("time").getValueAsUnsignedInteger();
}
GeneralSettings::EquationSolver GeneralSettings::getEquationSolver() const {
storm::solver::EquationSolverType GeneralSettings::getEquationSolver() const {
std::string equationSolverName = this->getOption(eqSolverOptionName).getArgumentByName("name").getValueAsString();
if (equationSolverName == "gmm++") {
return GeneralSettings::EquationSolver::Gmmxx;
return storm::solver::EquationSolverType::Gmmxx;
} else if (equationSolverName == "native") {
return GeneralSettings::EquationSolver::Native;
return storm::solver::EquationSolverType::Native;
}
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown equation solver '" << equationSolverName << "'.");
}
@ -245,12 +245,12 @@ namespace storm {
return this->getOption(eqSolverOptionName).getHasOptionBeenSet();
}
GeneralSettings::LpSolver GeneralSettings::getLpSolver() const {
storm::solver::LpSolverType GeneralSettings::getLpSolver() const {
std::string lpSolverName = this->getOption(lpSolverOptionName).getArgumentByName("name").getValueAsString();
if (lpSolverName == "gurobi") {
return GeneralSettings::LpSolver::Gurobi;
return storm::solver::LpSolverType::Gurobi;
} else if (lpSolverName == "glpk") {
return GeneralSettings::LpSolver::glpk;
return storm::solver::LpSolverType::Glpk;
}
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown LP solver '" << lpSolverName << "'.");
}
@ -287,12 +287,12 @@ namespace storm {
return this->getOption(prismCompatibilityOptionName).getHasOptionBeenSet();
}
GeneralSettings::MinMaxTechnique GeneralSettings::getMinMaxEquationSolvingTechnique() const {
storm::solver::MinMaxTechnique GeneralSettings::getMinMaxEquationSolvingTechnique() const {
std::string minMaxEquationSolvingTechnique = this->getOption(minMaxEquationSolvingTechniqueOptionName).getArgumentByName("name").getValueAsString();
if (minMaxEquationSolvingTechnique == "valueIteration") {
return GeneralSettings::MinMaxTechnique::ValueIteration;
return storm::solver::MinMaxTechnique::ValueIteration;
} else if (minMaxEquationSolvingTechnique == "policyIteration") {
return GeneralSettings::MinMaxTechnique::PolicyIteration;
return storm::solver::MinMaxTechnique::PolicyIteration;
}
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'.");
}

20
src/settings/modules/GeneralSettings.h

@ -5,6 +5,12 @@
#include "src/settings/modules/ModuleSettings.h"
namespace storm {
namespace solver {
enum class EquationSolverType;
enum class LpSolverType;
enum class MinMaxTechnique;
}
namespace settings {
namespace modules {
@ -16,14 +22,6 @@ namespace storm {
// An enumeration of all engines.
enum class Engine { Sparse, Hybrid, Dd };
// An enumeration of all available LP solvers.
enum class LpSolver { Gurobi, glpk };
// An enumeration of all available equation solvers.
enum class EquationSolver { Gmmxx, Native };
// An enumeration of all available Min/Max equation solver techniques.
enum class MinMaxTechnique { ValueIteration, PolicyIteration };
/*!
* Creates a new set of general settings that is managed by the given manager.
@ -251,7 +249,7 @@ namespace storm {
*
* @return The selected convergence criterion.
*/
EquationSolver getEquationSolver() const;
storm::solver::EquationSolverType getEquationSolver() const;
/*!
* Retrieves whether a equation solver has been set.
@ -265,7 +263,7 @@ namespace storm {
*
* @return The selected LP solver.
*/
LpSolver getLpSolver() const;
storm::solver::LpSolverType getLpSolver() const;
/*!
* Retrieves whether the export-to-dot option was set.
@ -336,7 +334,7 @@ namespace storm {
*
* @return The selected min/max equation solving technique.
*/
MinMaxTechnique getMinMaxEquationSolvingTechnique() const;
storm::solver::MinMaxTechnique getMinMaxEquationSolvingTechnique() const;
bool check() const override;

3
src/settings/modules/GlpkSettings.cpp

@ -6,6 +6,7 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace settings {
@ -34,7 +35,7 @@ namespace storm {
bool GlpkSettings::check() const {
if (isOutputSet() || isIntegerToleranceSet()) {
STORM_LOG_WARN_COND(storm::settings::generalSettings().getLpSolver() == storm::settings::modules::GeneralSettings::LpSolver::glpk, "glpk is not selected as the used LP solver, so setting options for glpk has no effect.");
STORM_LOG_WARN_COND(storm::settings::generalSettings().getLpSolver() == storm::solver::LpSolverType::Glpk, "glpk is not selected as the preferred LP solver, so setting options for glpk might have no effect.");
}
return true;

3
src/settings/modules/GmmxxEquationSolverSettings.cpp

@ -7,6 +7,7 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace settings {
@ -108,7 +109,7 @@ namespace storm {
// This list does not include the precision, because this option is shared with other modules.
bool optionsSet = isLinearEquationSystemMethodSet() || isPreconditioningMethodSet() || isRestartIterationCountSet() | isMaximalIterationCountSet() || isConvergenceCriterionSet();
STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx || !optionsSet, "gmm++ is not selected as the equation solver, so setting options for gmm++ has no effect.");
STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::solver::EquationSolverType::Gmmxx || !optionsSet, "gmm++ is not selected as the preferred equation solver, so setting options for gmm++ might have no effect.");
return true;
}

4
src/settings/modules/GurobiSettings.cpp

@ -6,7 +6,7 @@
#include "src/settings/Argument.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace settings {
namespace modules {
@ -46,7 +46,7 @@ namespace storm {
bool GurobiSettings::check() const {
if (isOutputSet() || isIntegerToleranceSet() || isNumberOfThreadsSet()) {
STORM_LOG_WARN_COND(storm::settings::generalSettings().getLpSolver() == storm::settings::modules::GeneralSettings::LpSolver::Gurobi, "Gurobi is not selected as the used LP solver, so setting options for Gurobi has no effect.");
STORM_LOG_WARN_COND(storm::settings::generalSettings().getLpSolver() == storm::solver::LpSolverType::Gurobi, "Gurobi is not selected as the preferred LP solver, so setting options for Gurobi might have no effect.");
}
return true;

4
src/settings/modules/NativeEquationSolverSettings.cpp

@ -6,7 +6,7 @@
#include "src/settings/OptionBuilder.h"
#include "src/settings/ArgumentBuilder.h"
#include "src/settings/Argument.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace settings {
@ -81,7 +81,7 @@ namespace storm {
// This list does not include the precision, because this option is shared with other modules.
bool optionSet = isLinearEquationSystemTechniqueSet() || isMaximalIterationCountSet() || isConvergenceCriterionSet();
STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::settings::modules::GeneralSettings::EquationSolver::Native || !optionSet, "Native is not selected as the equation solver, so setting options for native has no effect.");
STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::solver::EquationSolverType::Native || !optionSet, "Native is not selected as the preferred equation solver, so setting options for native might have no effect.");
return true;
}

3
src/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp

@ -7,6 +7,7 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace settings {
@ -54,7 +55,7 @@ namespace storm {
bool TopologicalValueIterationEquationSolverSettings::check() const {
bool optionsSet = isMaximalIterationCountSet() || isPrecisionSet() || isConvergenceCriterionSet();
STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx || !optionsSet, "gmm++ is not selected as the equation solver, so setting options for gmm++ has no effect.");
//STORM_LOG_WARN_COND(storm::settings::generalSettings().getEquationSolver() == storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx || !optionsSet, "gmm++ is not selected as the equation solver, so setting options for gmm++ has no effect.");
return true;
}

55
src/solver/GmmxxMinMaxLinearEquationSolver.cpp

@ -14,27 +14,24 @@ namespace storm {
namespace solver {
template<typename ValueType>
GmmxxMinMaxLinearEquationSolver<ValueType>::GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : gmmxxMatrix(storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(A)), stormMatrix(A), rowGroupIndices(A.getRowGroupIndices()) {
// Get the settings object to customize solving.
storm::settings::modules::GmmxxEquationSolverSettings const& settings = storm::settings::gmmxxEquationSolverSettings();
storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::generalSettings();
// Get appropriate settings.
precision = settings.getPrecision();
relative = settings.getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative;
maximalNumberOfIterations = settings.getMaximalIterationCount();
useValueIteration = (generalSettings.getMinMaxEquationSolvingTechnique() == storm::settings::modules::GeneralSettings::MinMaxTechnique::ValueIteration);
GmmxxMinMaxLinearEquationSolver<ValueType>::GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, MinMaxTechniqueSelection preferredTechnique, bool trackPolicy) :
MinMaxLinearEquationSolver<ValueType>(A, storm::settings::gmmxxEquationSolverSettings().getPrecision(), \
storm::settings::gmmxxEquationSolverSettings().getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative,\
storm::settings::gmmxxEquationSolverSettings().getMaximalIterationCount(), trackPolicy, preferredTechnique),
gmmxxMatrix(storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(A)), rowGroupIndices(A.getRowGroupIndices()) {
}
template<typename ValueType>
GmmxxMinMaxLinearEquationSolver<ValueType>::GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool useValueIteration, bool relative) : gmmxxMatrix(storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(A)), stormMatrix(A), rowGroupIndices(A.getRowGroupIndices()), precision(precision), relative(relative), maximalNumberOfIterations(maximalNumberOfIterations), useValueIteration(useValueIteration) {
GmmxxMinMaxLinearEquationSolver<ValueType>::GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, MinMaxTechniqueSelection tech, bool relative, bool trackPolicy) : MinMaxLinearEquationSolver<ValueType>(A, precision, relative, maximalNumberOfIterations, trackPolicy, tech), gmmxxMatrix(storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(A)), rowGroupIndices(A.getRowGroupIndices()) {
// Intentionally left empty.
}
template<typename ValueType>
void GmmxxMinMaxLinearEquationSolver<ValueType>::solveEquationSystem(bool minimize, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult, std::vector<ValueType>* newX) const {
if (useValueIteration) {
if (this->useValueIteration) {
// Set up the environment for the power method. If scratch memory was not provided, we need to create it.
bool multiplyResultMemoryProvided = true;
if (multiplyResult == nullptr) {
@ -56,18 +53,14 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations) {
// Compute x' = A*x + b.
gmm::mult(*gmmxxMatrix, *currentX, *multiplyResult);
gmm::add(b, *multiplyResult);
// Reduce the vector x by applying min/max over all nondeterministic choices.
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, *newX, rowGroupIndices);
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, *newX, rowGroupIndices);
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, *newX, rowGroupIndices);
// Determine whether the method converged.
converged = storm::utility::vector::equalModuloPrecision(*currentX, *newX, this->precision, this->relative);
@ -99,7 +92,7 @@ namespace storm {
} else {
// We will use Policy Iteration to solve the given system.
// We first guess an initial choice resolution which will be refined after each iteration.
std::vector<typename storm::storage::SparseMatrix<ValueType>::index_type> choiceVector(rowGroupIndices.size() - 1);
this->policy = std::vector<storm::storage::sparse::state_type>(this->A.getRowGroupIndices().size() - 1);
// Create our own multiplyResult for solving the deterministic sub-instances.
std::vector<ValueType> deterministicMultiplyResult(rowGroupIndices.size() - 1);
@ -126,13 +119,13 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations) {
// Take the sub-matrix according to the current choices
storm::storage::SparseMatrix<ValueType> submatrix = stormMatrix.selectRowsFromRowGroups(choiceVector, true);
storm::storage::SparseMatrix<ValueType> submatrix = this->A.selectRowsFromRowGroups(this->policy, true);
submatrix.convertToEquationSystem();
GmmxxLinearEquationSolver<ValueType> gmmLinearEquationSolver(submatrix, storm::solver::GmmxxLinearEquationSolver<double>::SolutionMethod::Gmres, precision, maximalNumberOfIterations, storm::solver::GmmxxLinearEquationSolver<double>::Preconditioner::None, relative, 50);
storm::utility::vector::selectVectorValues<ValueType>(subB, choiceVector, rowGroupIndices, b);
GmmxxLinearEquationSolver<ValueType> gmmLinearEquationSolver(submatrix, storm::solver::GmmxxLinearEquationSolver<double>::SolutionMethod::Gmres, this->precision, this->maximalNumberOfIterations, storm::solver::GmmxxLinearEquationSolver<double>::Preconditioner::None, this->relative, 50);
storm::utility::vector::selectVectorValues<ValueType>(subB, this->policy, rowGroupIndices, b);
// Copy X since we will overwrite it
std::copy(currentX->begin(), currentX->end(), newX->begin());
@ -146,11 +139,8 @@ namespace storm {
// Reduce the vector x by applying min/max over all nondeterministic choices.
// Here, we capture which choice was taken in each state, thereby refining our initial guess.
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, *newX, rowGroupIndices, &choiceVector);
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, *newX, rowGroupIndices, &choiceVector);
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, *newX, rowGroupIndices, &(this->policy));
// Determine whether the method converged.
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, static_cast<ValueType>(this->precision), this->relative);
@ -199,11 +189,8 @@ namespace storm {
gmm::add(*b, *multiplyResult);
}
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, x, rowGroupIndices);
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, x, rowGroupIndices);
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, x, rowGroupIndices);
}
if (!multiplyResultMemoryProvided) {

18
src/solver/GmmxxMinMaxLinearEquationSolver.h

@ -20,7 +20,7 @@ namespace storm {
*
* @param A The matrix defining the coefficients of the linear equation system.
*/
GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A);
GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, MinMaxTechniqueSelection preferredTechnique = MinMaxTechniqueSelection::FROMSETTINGS, bool trackPolicy = false);
/*!
* Constructs a min/max linear equation solver with the given parameters.
@ -31,7 +31,7 @@ namespace storm {
* @param relative If set, the relative error rather than the absolute error is considered for convergence
* detection.
*/
GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool useValueIteration, bool relative = true);
GmmxxMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, MinMaxTechniqueSelection tech, bool relative, bool trackPolicy = false);
virtual void performMatrixVectorMultiplication(bool minimize, std::vector<ValueType>& x, std::vector<ValueType>* b = nullptr, uint_fast64_t n = 1, std::vector<ValueType>* multiplyResult = nullptr) const override;
@ -41,23 +41,9 @@ namespace storm {
// The (gmm++) matrix associated with this equation solver.
std::unique_ptr<gmm::csr_matrix<ValueType>> gmmxxMatrix;
// A reference to the original sparse matrix.
storm::storage::SparseMatrix<ValueType> const& stormMatrix;
// A reference to the row group indices of the original matrix.
std::vector<uint_fast64_t> const& rowGroupIndices;
// The required precision for the iterative methods.
double precision;
// Sets whether the relative or absolute error is to be considered for convergence detection.
bool relative;
// The maximal number of iterations to do before iteration is aborted.
uint_fast64_t maximalNumberOfIterations;
// Whether value iteration or policy iteration is to be used.
bool useValueIteration;
};
} // namespace solver
} // namespace storm

5
src/solver/LinearEquationSolver.h

@ -15,6 +15,11 @@ namespace storm {
template<class Type>
class LinearEquationSolver {
public:
virtual ~LinearEquationSolver() {
// Intentionally left empty.
}
/*!
* Solves the equation system A*x = b. The matrix A is required to be square and have a unique solution.
* The solution of the set of linear equations will be written to the vector x. Note that the matrix A has

27
src/solver/MinMaxLinearEquationSolver.cpp

@ -0,0 +1,27 @@
#include "MinMaxLinearEquationSolver.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/utility/macros.h"
#include "src/exceptions/NotImplementedException.h"
#include <cstdint>
namespace storm {
namespace solver {
AbstractMinMaxLinearEquationSolver::AbstractMinMaxLinearEquationSolver(double precision, bool relativeError, uint_fast64_t maximalIterations, bool trackPolicy, MinMaxTechniqueSelection prefTech) :
precision(precision), relative(relativeError), maximalNumberOfIterations(maximalIterations), trackPolicy(trackPolicy)
{
if(prefTech == MinMaxTechniqueSelection::FROMSETTINGS) {
useValueIteration = (storm::settings::generalSettings().getMinMaxEquationSolvingTechnique() == storm::solver::MinMaxTechnique::ValueIteration);
} else {
useValueIteration = (prefTech == MinMaxTechniqueSelection::ValueIteration);
}
}
std::vector<storm::storage::sparse::state_type> AbstractMinMaxLinearEquationSolver::getPolicy() const {
STORM_LOG_THROW(!useValueIteration, storm::exceptions::NotImplementedException, "Getting policies after value iteration is not yet supported!");
return policy;
}
}
}

53
src/solver/MinMaxLinearEquationSolver.h

@ -2,7 +2,9 @@
#define STORM_SOLVER_MINMAXLINEAREQUATIONSOLVER_H_
#include <vector>
#include <cstdint>
#include "SolverSelectionOptions.h"
#include "src/storage/sparse/StateType.h"
namespace storm {
namespace storage {
@ -10,6 +12,38 @@ namespace storm {
}
namespace solver {
/**
* Abstract base class which provides value-type independent helpers.
*/
class AbstractMinMaxLinearEquationSolver {
public:
void setPolicyTracking(bool setToTrue=true);
std::vector<storm::storage::sparse::state_type> getPolicy() const;
protected:
AbstractMinMaxLinearEquationSolver(double precision, bool relativeError, uint_fast64_t maximalIterations, bool trackPolicy, MinMaxTechniqueSelection prefTech);
/// The required precision for the iterative methods.
double precision;
/// Sets whether the relative or absolute error is to be considered for convergence detection.
bool relative;
/// The maximal number of iterations to do before iteration is aborted.
uint_fast64_t maximalNumberOfIterations;
/// Whether value iteration or policy iteration is to be used.
bool useValueIteration;
/// Whether we track the policy we generate.
bool trackPolicy;
///
mutable std::vector<storm::storage::sparse::state_type> policy;
};
/*!
* A interface that represents an abstract nondeterministic linear equation solver. In addition to solving
@ -17,8 +51,20 @@ namespace storm {
* provided.
*/
template<class ValueType>
class MinMaxLinearEquationSolver {
class MinMaxLinearEquationSolver : public AbstractMinMaxLinearEquationSolver {
protected:
MinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& matrix, double precision, bool relativeError, uint_fast64_t maxNrIterations, bool trackPolicy, MinMaxTechniqueSelection prefTech) :
AbstractMinMaxLinearEquationSolver(precision, relativeError, maxNrIterations, trackPolicy, prefTech),
A(matrix) {
// Intentionally left empty.
}
public:
virtual ~MinMaxLinearEquationSolver() {
// Intentionally left empty.
}
/*!
* Solves the equation system x = min/max(A*x + b) given by the parameters. Note that the matrix A has
* to be given upon construction time of the solver object.
@ -54,6 +100,9 @@ namespace storm {
* @return The result of the repeated matrix-vector multiplication as the content of the vector x.
*/
virtual void performMatrixVectorMultiplication(bool minimize, std::vector<ValueType>& x, std::vector<ValueType>* b = nullptr, uint_fast64_t n = 1, std::vector<ValueType>* multiplyResult = nullptr) const = 0;
protected:
storm::storage::SparseMatrix<ValueType> const& A;
};
} // namespace solver

72
src/solver/NativeMinMaxLinearEquationSolver.cpp

@ -14,30 +14,29 @@ namespace storm {
namespace solver {
template<typename ValueType>
NativeMinMaxLinearEquationSolver<ValueType>::NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : A(A) {
// Get the settings object to customize solving.
storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings();
storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::generalSettings();
// Get appropriate settings.
precision = settings.getPrecision();
relative = settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative;
maximalNumberOfIterations = settings.getMaximalIterationCount();
useValueIteration = (generalSettings.getMinMaxEquationSolvingTechnique() == storm::settings::modules::GeneralSettings::MinMaxTechnique::ValueIteration);
NativeMinMaxLinearEquationSolver<ValueType>::NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, MinMaxTechniqueSelection preferredTechnique, bool trackPolicy) :
MinMaxLinearEquationSolver<ValueType>(A, storm::settings::nativeEquationSolverSettings().getPrecision(), \
storm::settings::nativeEquationSolverSettings().getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative, \
storm::settings::nativeEquationSolverSettings().getMaximalIterationCount(), trackPolicy, preferredTechnique)
{
// Intentionally left empty.
}
template<typename ValueType>
NativeMinMaxLinearEquationSolver<ValueType>::NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool useValueIteration, bool relative) : A(A), precision(precision), relative(relative), maximalNumberOfIterations(maximalNumberOfIterations), useValueIteration(useValueIteration) {
NativeMinMaxLinearEquationSolver<ValueType>::NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, MinMaxTechniqueSelection tech, bool relative, bool trackPolicy) :
MinMaxLinearEquationSolver<ValueType>(A, precision, \
relative, \
maximalNumberOfIterations, trackPolicy, tech) {
// Intentionally left empty.
}
template<typename ValueType>
void NativeMinMaxLinearEquationSolver<ValueType>::solveEquationSystem(bool minimize, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult, std::vector<ValueType>* newX) const {
if (useValueIteration) {
if (this->useValueIteration) {
// Set up the environment for the power method. If scratch memory was not provided, we need to create it.
bool multiplyResultMemoryProvided = true;
if (multiplyResult == nullptr) {
multiplyResult = new std::vector<ValueType>(A.getRowCount());
multiplyResult = new std::vector<ValueType>(this->A.getRowCount());
multiplyResultMemoryProvided = false;
}
std::vector<ValueType>* currentX = &x;
@ -54,21 +53,17 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the
// user-specified maximum number of iterations.
while (!converged && iterations < maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations) {
// Compute x' = A*x + b.
A.multiplyWithVector(*currentX, *multiplyResult);
this->A.multiplyWithVector(*currentX, *multiplyResult);
storm::utility::vector::addVectors(*multiplyResult, b, *multiplyResult);
// Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost
// element of the min/max operator stack.
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, *newX, A.getRowGroupIndices());
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, *newX, A.getRowGroupIndices());
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, *newX, this->A.getRowGroupIndices());
// Determine whether the method converged.
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, static_cast<ValueType>(precision), relative);
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, static_cast<ValueType>(this->precision), this->relative);
// Update environment variables.
std::swap(currentX, newX);
@ -98,11 +93,11 @@ namespace storm {
} else {
// We will use Policy Iteration to solve the given system.
// We first guess an initial choice resolution which will be refined after each iteration.
std::vector<typename storm::storage::SparseMatrix<ValueType>::index_type> choiceVector(A.getRowGroupIndices().size() - 1);
this->policy = std::vector<storm::storage::sparse::state_type>(this->A.getRowGroupIndices().size() - 1);
// Create our own multiplyResult for solving the deterministic sub-instances.
std::vector<ValueType> deterministicMultiplyResult(A.getRowGroupIndices().size() - 1);
std::vector<ValueType> subB(A.getRowGroupIndices().size() - 1);
std::vector<ValueType> deterministicMultiplyResult(this->A.getRowGroupIndices().size() - 1);
std::vector<ValueType> subB(this->A.getRowGroupIndices().size() - 1);
// Check whether intermediate storage was provided and create it otherwise.
bool multiplyResultMemoryProvided = true;
@ -126,13 +121,13 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations) {
// Take the sub-matrix according to the current choices
storm::storage::SparseMatrix<ValueType> submatrix = A.selectRowsFromRowGroups(choiceVector, true);
storm::storage::SparseMatrix<ValueType> submatrix = this->A.selectRowsFromRowGroups(this->policy, true);
submatrix.convertToEquationSystem();
NativeLinearEquationSolver<ValueType> nativeLinearEquationSolver(submatrix);
storm::utility::vector::selectVectorValues<ValueType>(subB, choiceVector, A.getRowGroupIndices(), b);
storm::utility::vector::selectVectorValues<ValueType>(subB, this->policy, this->A.getRowGroupIndices(), b);
// Copy X since we will overwrite it
std::copy(currentX->begin(), currentX->end(), newX->begin());
@ -141,16 +136,13 @@ namespace storm {
nativeLinearEquationSolver.solveEquationSystem(*newX, subB, &deterministicMultiplyResult);
// Compute x' = A*x + b. This step is necessary to allow the choosing of the optimal policy for the next iteration.
A.multiplyWithVector(*newX, *multiplyResult);
this->A.multiplyWithVector(*newX, *multiplyResult);
storm::utility::vector::addVectors(*multiplyResult, b, *multiplyResult);
// Reduce the vector x by applying min/max over all nondeterministic choices.
// Here, we capture which choice was taken in each state, thereby refining our initial guess.
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, *newX, A.getRowGroupIndices(), &choiceVector);
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, *newX, A.getRowGroupIndices(), &choiceVector);
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, *newX, this->A.getRowGroupIndices(), &(this->policy));
// Determine whether the method converged.
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, static_cast<ValueType>(this->precision), this->relative);
@ -166,6 +158,7 @@ namespace storm {
} else {
LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
}
// If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result
// is currently stored in currentX, but x is the output vector.
@ -189,13 +182,13 @@ namespace storm {
// If scratch memory was not provided, we need to create it.
bool multiplyResultMemoryProvided = true;
if (multiplyResult == nullptr) {
multiplyResult = new std::vector<ValueType>(A.getRowCount());
multiplyResult = new std::vector<ValueType>(this->A.getRowCount());
multiplyResultMemoryProvided = false;
}
// Now perform matrix-vector multiplication as long as we meet the bound of the formula.
for (uint_fast64_t i = 0; i < n; ++i) {
A.multiplyWithVector(x, *multiplyResult);
this->A.multiplyWithVector(x, *multiplyResult);
// Add b if it is non-null.
if (b != nullptr) {
@ -204,11 +197,8 @@ namespace storm {
// Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost
// element of the min/max operator stack.
if (minimize) {
storm::utility::vector::reduceVectorMin(*multiplyResult, x, A.getRowGroupIndices());
} else {
storm::utility::vector::reduceVectorMax(*multiplyResult, x, A.getRowGroupIndices());
}
storm::utility::vector::reduceVectorMinOrMax(minimize, *multiplyResult, x, this->A.getRowGroupIndices());
}
if (!multiplyResultMemoryProvided) {

19
src/solver/NativeMinMaxLinearEquationSolver.h

@ -19,7 +19,7 @@ namespace storm {
*
* @param A The matrix defining the coefficients of the linear equation system.
*/
NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A);
NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, MinMaxTechniqueSelection preferredTechnique = MinMaxTechniqueSelection::FROMSETTINGS, bool trackPolicy = false);
/*!
* Constructs a min/max linear equation solver with the given parameters.
@ -30,27 +30,12 @@ namespace storm {
* @param relative If set, the relative error rather than the absolute error is considered for convergence
* detection.
*/
NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool useValueIteration, bool relative = true);
NativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, MinMaxTechniqueSelection tech, bool relative = true, bool trackPolicy = false);
virtual void performMatrixVectorMultiplication(bool minimize, std::vector<ValueType>& x, std::vector<ValueType>* b = nullptr, uint_fast64_t n = 1, std::vector<ValueType>* newX = nullptr) const override;
virtual void solveEquationSystem(bool minimize, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult = nullptr, std::vector<ValueType>* newX = nullptr) const override;
protected:
// A reference to the matrix the gives the coefficients of the linear equation system.
storm::storage::SparseMatrix<ValueType> const& A;
// The required precision for the iterative methods.
double precision;
// Sets whether the relative or absolute error is to be considered for convergence detection.
bool relative;
// The maximal number of iterations to do before iteration is aborted.
uint_fast64_t maximalNumberOfIterations;
// Whether value iteration or policy iteration is to be used.
bool useValueIteration;
};
} // namespace solver
} // namespace storm

32
src/solver/SolverSelectionOptions.cpp

@ -0,0 +1,32 @@
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace solver {
std::string toString(MinMaxTechnique m) {
switch(m) {
case MinMaxTechnique::PolicyIteration:
return "policy";
case MinMaxTechnique::ValueIteration:
return "value";
}
}
std::string toString(LpSolverType t) {
switch(t) {
case LpSolverType::Gurobi:
return "Gurobi";
case LpSolverType::Glpk:
return "Glpk";
}
}
std::string toString(EquationSolverType t) {
switch(t) {
case EquationSolverType::Native:
return "Native";
case EquationSolverType::Gmmxx:
return "Gmmxx";
}
}
}
}

20
src/solver/SolverSelectionOptions.h

@ -0,0 +1,20 @@
#ifndef SOLVERSELECTIONOPTIONS_H
#define SOLVERSELECTIONOPTIONS_H
#include "src/utility/ExtendSettingEnumWithSelectionField.h"
namespace storm {
namespace solver {
ExtendEnumsWithSelectionField(MinMaxTechnique, PolicyIteration, ValueIteration)
ExtendEnumsWithSelectionField(LpSolverType, Gurobi, Glpk)
ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx)
}
}
#endif

19
src/solver/TopologicalMinMaxLinearEquationSolver.cpp

@ -27,19 +27,12 @@ namespace storm {
namespace solver {
template<typename ValueType>
TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : NativeMinMaxLinearEquationSolver<ValueType>(A) {
TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) :
NativeMinMaxLinearEquationSolver<ValueType>(A, storm::settings::topologicalValueIterationEquationSolverSettings().getPrecision(), \
storm::settings::topologicalValueIterationEquationSolverSettings().getMaximalIterationCount(), MinMaxTechniqueSelection::ValueIteration, \
storm::settings::topologicalValueIterationEquationSolverSettings().getConvergenceCriterion() == storm::settings::modules::TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Relative)
{
// Get the settings object to customize solving.
//storm::settings::Settings* settings = storm::settings::Settings::getInstance();
auto settings = storm::settings::topologicalValueIterationEquationSolverSettings();
// Get appropriate settings.
//this->maximalNumberOfIterations = settings->getOptionByLongName("maxiter").getArgument(0).getValueAsUnsignedInteger();
//this->precision = settings->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
//this->relative = !settings->isSet("absolute");
this->maximalNumberOfIterations = settings.getMaximalIterationCount();
this->precision = settings.getPrecision();
this->relative = (settings.getConvergenceCriterion() == storm::settings::modules::TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Relative);
auto generalSettings = storm::settings::generalSettings();
this->enableCuda = generalSettings.isCudaSet();
#ifdef STORM_HAVE_CUDA
@ -48,7 +41,7 @@ namespace storm {
}
template<typename ValueType>
TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : NativeMinMaxLinearEquationSolver<ValueType>(A, precision, maximalNumberOfIterations, relative) {
TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : NativeMinMaxLinearEquationSolver<ValueType>(A, precision, maximalNumberOfIterations, MinMaxTechniqueSelection::ValueIteration ,relative) {
// Intentionally left empty.
}

4
src/solver/TopologicalMinMaxLinearEquationSolver.h

@ -30,7 +30,7 @@ namespace storm {
*
* @param A The matrix defining the coefficients of the linear equation system.
*/
TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A);
TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A);
/*!
* Constructs a min/max linear equation solver with the given parameters.
@ -41,7 +41,7 @@ namespace storm {
* @param relative If set, the relative error rather than the absolute error is considered for convergence
* detection.
*/
TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool relative = true);
TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision, uint_fast64_t maximalNumberOfIterations, bool relative = true);
virtual void solveEquationSystem(bool minimize, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult = nullptr, std::vector<ValueType>* newX = nullptr) const override;
private:

5
src/storage/BitVector.cpp

@ -78,6 +78,11 @@ namespace storm {
set(begin, end);
}
BitVector::BitVector(uint_fast64_t length, std::vector<uint_fast64_t> setEntries) : BitVector(length, setEntries.begin(), setEntries.end())
{
// Intentionally left empty.
}
BitVector::BitVector(uint_fast64_t bucketCount, uint_fast64_t bitCount) : bitCount(bitCount), bucketVector(bucketCount) {
STORM_LOG_ASSERT((bucketCount << 6) == bitCount, "Bit count does not match number of buckets.");
}

5
src/storage/BitVector.h

@ -118,6 +118,11 @@ namespace storm {
template<typename InputIterator>
BitVector(uint_fast64_t length, InputIterator first, InputIterator last);
/*!
* Creates a bit vector that has exactly the bits set that are given by the vector
*/
BitVector(uint_fast64_t length, std::vector<uint_fast64_t> setEntries);
/*!
* Performs a deep copy of the given bit vector.
*

16
src/storage/SparseMatrix.cpp

@ -12,6 +12,7 @@
#include "src/storage/BitVector.h"
#include "src/utility/constants.h"
#include "src/utility/ConstantsComparator.h"
#include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/NotImplementedException.h"
@ -346,10 +347,10 @@ namespace storm {
for (index_type row = 0; row < this->getRowCount(); ++row) {
for (const_iterator it1 = this->begin(row), ite1 = this->end(row), it2 = other.begin(row), ite2 = other.end(row); it1 != ite1 && it2 != ite2; ++it1, ++it2) {
// Skip over all zero entries in both matrices.
while (it1 != ite1 && it1->getValue() == storm::utility::zero<ValueType>()) {
while (it1 != ite1 && storm::utility::isZero(it1->getValue())) {
++it1;
}
while (it2 != ite2 && it2->getValue() == storm::utility::zero<ValueType>()) {
while (it2 != ite2 && storm::utility::isZero(it2->getValue())) {
++it2;
}
if ((it1 == ite1) || (it2 == ite2)) {
@ -1065,6 +1066,17 @@ namespace storm {
return sum;
}
template<typename ValueType>
bool SparseMatrix<ValueType>::isProbabilistic() const {
storm::utility::ConstantsComparator<ValueType> comparator;
for(index_type row = 0; row < this->rowCount; ++row) {
if(!comparator.isOne(getRowSum(row))) {
return false;
}
}
return true;
}
template<typename ValueType>
bool SparseMatrix<ValueType>::isSubmatrixOf(SparseMatrix<ValueType> const& matrix) const {
// Check for matching sizes.

12
src/storage/SparseMatrix.h

@ -33,6 +33,9 @@ namespace storm {
// Forward declare matrix class.
template<typename T> class SparseMatrix;
typedef uint_fast64_t SparseMatrixIndexType;
template<typename IndexType, typename ValueType>
class MatrixEntry {
public:
@ -128,7 +131,7 @@ namespace storm {
template<typename ValueType>
class SparseMatrixBuilder {
public:
typedef uint_fast64_t index_type;
typedef SparseMatrixIndexType index_type;
typedef ValueType value_type;
/*!
@ -300,7 +303,7 @@ namespace storm {
friend class storm::solver::TopologicalValueIterationMinMaxLinearEquationSolver<ValueType>;
friend class SparseMatrixBuilder<ValueType>;
typedef uint_fast64_t index_type;
typedef SparseMatrixIndexType index_type;
typedef ValueType value_type;
typedef typename std::vector<MatrixEntry<index_type, value_type>>::iterator iterator;
typedef typename std::vector<MatrixEntry<index_type, value_type>>::const_iterator const_iterator;
@ -738,6 +741,10 @@ namespace storm {
*/
value_type getRowSum(index_type row) const;
/*!
* Checks for each row whether it sums to one.
*/
bool isProbabilistic() const;
/*!
* Checks if the current matrix is a submatrix of the given matrix, where a matrix A is called a submatrix
* of B if B has no entries in position where A has none. Additionally, the matrices must be of equal size.
@ -942,6 +949,7 @@ namespace storm {
// A vector indicating the row groups of the matrix.
std::vector<index_type> rowGroupIndices;
};
} // namespace storage

15
src/storage/prism/Assignment.cpp

@ -1,4 +1,5 @@
#include "Assignment.h"
#include <cassert>
namespace storm {
namespace prism {
@ -22,6 +23,20 @@ namespace storm {
return Assignment(this->getVariable(), this->getExpression().substitute(substitution).simplify(), this->getFilename(), this->getLineNumber());
}
bool Assignment::isIdentity() const {
if(this->expression.isVariable()) {
assert(this->expression.getVariables().size() == 1);
//if( variable == *(this->expression.getVariables().begin())) {
// std::cout << variable.getName() << " == " << (this->expression.getVariables().begin())->getName() << std::endl;
//}
//else {
// std::cout << "********" << variable.getName() << " != " << (this->expression.getVariables().begin())->getName() << std::endl;
//}
return variable == *(this->expression.getVariables().begin());
}
return false;
}
std::ostream& operator<<(std::ostream& stream, Assignment const& assignment) {
stream << "(" << assignment.getVariableName() << "' = " << assignment.getExpression() << ")";
return stream;

7
src/storage/prism/Assignment.h

@ -60,6 +60,13 @@ namespace storm {
*/
Assignment substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
/*!
* Checks whether the assignment is an identity (lhs equals rhs)
*
* @return true iff the assignment is of the form a' = a.
*/
bool isIdentity() const;
friend std::ostream& operator<<(std::ostream& stream, Assignment const& assignment);
private:

16
src/storage/prism/Command.cpp

@ -1,4 +1,5 @@
#include "Command.h"
#include <cassert>
namespace storm {
namespace prism {
@ -31,6 +32,7 @@ namespace storm {
}
storm::prism::Update const& Command::getUpdate(uint_fast64_t index) const {
assert(index < getNumberOfUpdates());
return this->updates[index];
}
@ -71,6 +73,20 @@ namespace storm {
return true;
}
Command Command::removeIdentityAssignmentsFromUpdates() const {
std::vector<Update> newUpdates;
newUpdates.reserve(this->getNumberOfUpdates());
for (auto const& update : this->getUpdates()) {
newUpdates.emplace_back(update.removeIdentityAssignments());
}
return copyWithNewUpdates(std::move(newUpdates));
}
Command Command::copyWithNewUpdates(std::vector<Update> && newUpdates) const {
return Command(this->globalIndex, this->markovian, this->getActionIndex(), this->getActionName(), guardExpression, newUpdates, this->getFilename(), this->getLineNumber());
}
std::ostream& operator<<(std::ostream& stream, Command const& command) {
if (command.isMarkovian()) {
stream << "<" << command.getActionName() << "> ";

8
src/storage/prism/Command.h

@ -128,6 +128,12 @@ namespace storm {
friend std::ostream& operator<<(std::ostream& stream, Command const& command);
/**
* Removes identity assignments from the updates
* @return The resulting command
*/
Command removeIdentityAssignmentsFromUpdates() const;
private:
// The index of the action associated with this command.
uint_fast64_t actionIndex;
@ -150,6 +156,8 @@ namespace storm {
// A flag indicating whether the command is labeled.
bool labeled;
Command copyWithNewUpdates(std::vector<Update>&& newUpdates) const;
};
} // namespace prism

12
src/storage/prism/Program.cpp

@ -802,6 +802,14 @@ namespace storm {
std::vector<Module> newModules;
std::vector<Constant> newConstants = this->getConstants();
for (auto const& module : this->getModules()) {
// Remove identity assignments from the updates
std::vector<Command> newCommands;
for (auto const& command : module.getCommands()) {
newCommands.emplace_back(command.removeIdentityAssignmentsFromUpdates());
}
// Substitute Variables by Global constants if possible.
std::map<storm::expressions::Variable, storm::expressions::Expression> booleanVars;
std::map<storm::expressions::Variable, storm::expressions::Expression> integerVars;
for (auto const& variable : module.getBooleanVariables()) {
@ -811,7 +819,7 @@ namespace storm {
integerVars.emplace(variable.getExpressionVariable(), variable.getInitialValueExpression());
}
for (auto const& command : module.getCommands()) {
for (auto const& command : newCommands) {
// Check all updates.
for (auto const& update : command.getUpdates()) {
// Check all assignments.
@ -842,7 +850,7 @@ namespace storm {
}
}
newModules.emplace_back(module.getName(), newBVars, newIVars, module.getCommands());
newModules.emplace_back(module.getName(), newBVars, newIVars, newCommands);
for(auto const& entry : booleanVars) {
newConstants.emplace_back(entry.first, entry.second);

11
src/storage/prism/Update.cpp

@ -53,6 +53,17 @@ namespace storm {
return Update(this->getGlobalIndex(), this->getLikelihoodExpression().substitute(substitution), newAssignments, this->getFilename(), this->getLineNumber());
}
Update Update::removeIdentityAssignments() const {
std::vector<Assignment> newAssignments;
newAssignments.reserve(getNumberOfAssignments());
for(auto const& ass : this->assignments) {
if(!ass.isIdentity()) {
newAssignments.push_back(ass);
}
}
return Update(this->globalIndex, this->likelihoodExpression, newAssignments, getFilename(), getLineNumber());
}
std::ostream& operator<<(std::ostream& stream, Update const& update) {
stream << update.getLikelihoodExpression() << " : ";
if (update.getAssignments().empty()) {

6
src/storage/prism/Update.h

@ -73,6 +73,12 @@ namespace storm {
* @return The resulting update.
*/
Update substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
/*!
* Removes all assignments which do not change the variable.
*
* @return The resulting update.
*/
Update removeIdentityAssignments() const;
friend std::ostream& operator<<(std::ostream& stream, Update const& assignment);

53
src/utility/ConstantsComparator.cpp

@ -8,22 +8,22 @@ namespace storm {
namespace utility {
template<typename ValueType>
bool ConstantsComparator<ValueType>::isOne(ValueType const& value) const {
return value == one<ValueType>();
return isOne(value);
}
template<typename ValueType>
bool ConstantsComparator<ValueType>::isZero(ValueType const& value) const {
return value == zero<ValueType>();
return isZero(value);
}
template<typename ValueType>
bool ConstantsComparator<ValueType>::isEqual(ValueType const& value1, ValueType const& value2) const {
return value1 == value2;
}
template<typename ValueType>
bool ConstantsComparator<ValueType>::isConstant(ValueType const& value) const {
return true;
return isConstant(value);
}
template<typename ValueType>
@ -86,49 +86,7 @@ namespace storm {
bool ConstantsComparator<double>::isConstant(double const& value) const {
return true;
}
#ifdef STORM_HAVE_CARL
ConstantsComparator<storm::RationalFunction>::ConstantsComparator() {
// Intentionally left empty.
}
bool ConstantsComparator<storm::RationalFunction>::isOne(storm::RationalFunction const& value) const {
return value.isOne();
}
bool ConstantsComparator<storm::RationalFunction>::isZero(storm::RationalFunction const& value) const {
return value.isZero();
}
bool ConstantsComparator<storm::RationalFunction>::isEqual(storm::RationalFunction const& value1, storm::RationalFunction const& value2) const {
return value1 == value2;
}
bool ConstantsComparator<storm::RationalFunction>::isConstant(storm::RationalFunction const& value) const {
return value.isConstant();
}
ConstantsComparator<storm::Polynomial>::ConstantsComparator() {
// Intentionally left empty.
}
bool ConstantsComparator<storm::Polynomial>::isOne(storm::Polynomial const& value) const {
return value.isOne();
}
bool ConstantsComparator<storm::Polynomial>::isZero(storm::Polynomial const& value) const {
return value.isZero();
}
bool ConstantsComparator<storm::Polynomial>::isEqual(storm::Polynomial const& value1, storm::Polynomial const& value2) const {
return value1 == value2;
}
bool ConstantsComparator<storm::Polynomial>::isConstant(storm::Polynomial const& value) const {
return value.isConstant();
}
#endif
// Explicit instantiations.
template class ConstantsComparator<double>;
template class ConstantsComparator<float>;
@ -137,6 +95,7 @@ namespace storm {
#ifdef STORM_HAVE_CARL
template class ConstantsComparator<RationalFunction>;
template class ConstantsComparator<Polynomial>;
template class ConstantsComparator<Interval>;
#endif
}
}

5
src/utility/ConstantsComparator.h

@ -10,7 +10,7 @@ namespace storm {
class ConstantsComparator {
public:
// This needs to be in here, otherwise the template specializations are not used properly.
ConstantsComparator();
ConstantsComparator() = default;
bool isOne(ValueType const& value) const;
@ -21,9 +21,6 @@ namespace storm {
bool isConstant(ValueType const& value) const;
bool isInfinity(ValueType const& value) const;
private:
ValueType precision;
};
// For floats we specialize this class and consider the comparison modulo some predefined precision.

28
src/utility/ExtendSettingEnumWithSelectionField.h

@ -0,0 +1,28 @@
#ifndef EXTENDSETTINGENUMWITHSELECTIONFIELD_H
#define EXTENDSETTINGENUMWITHSELECTIONFIELD_H
#include <string>
#include <cassert>
#define ExtendEnumsWithSelectionField( NAME, ...) \
enum class NAME : int { __VA_ARGS__ }; \
enum class NAME##Selection : int { __VA_ARGS__, FROMSETTINGS }; \
std::string toString(NAME); \
inline NAME convert(NAME##Selection e) { \
assert(e != NAME##Selection::FROMSETTINGS); \
return static_cast< NAME >(e); \
} \
inline std::string toString(NAME##Selection e) { \
if(e == NAME##Selection::FROMSETTINGS) { \
return "[from settings]"; \
}\
else { \
return toString(convert(e)); \
} \
}
#endif /* EXTENDSETTINGENUMWITHSELECTIONFIELD_H */

2
src/utility/cli.cpp

@ -212,7 +212,7 @@ namespace storm {
boost::optional<storm::prism::Program> program;
if (settings.isSymbolicSet()) {
std::string const& programFile = settings.getSymbolicModelFilename();
program = storm::parser::PrismParser::parse(programFile).simplify();
program = storm::parser::PrismParser::parse(programFile).simplify().simplify();
program->checkValidity();
}

63
src/utility/constants.cpp

@ -25,7 +25,52 @@ namespace storm {
return std::numeric_limits<ValueType>::infinity();
}
template<typename ValueType>
bool isOne(ValueType const& a) {
return a == one<ValueType>();
}
template<typename ValueType>
bool isZero(ValueType const& a) {
return a == zero<ValueType>();
}
template<typename ValueType>
bool isConstant(ValueType const& a) {
return true;
}
#ifdef STORM_HAVE_CARL
template<>
bool isOne(storm::RationalFunction const& a) {
return a.isOne();
}
template<>
bool isZero(storm::RationalFunction const& a) {
return a.isZero();
}
template<>
bool isConstant(storm::RationalFunction const& a) {
return a.isConstant();
}
template<>
bool isOne(storm::Polynomial const& a) {
return a.isOne();
}
template<>
bool isZero(storm::Polynomial const& a) {
return a.isZero();
}
template<>
bool isConstant(storm::Polynomial const& a) {
return a.isConstant();
}
template<>
storm::RationalFunction infinity() {
// FIXME: this does not work.
@ -65,9 +110,7 @@ namespace storm {
template<>
RationalFunction&& simplify(RationalFunction&& value);
#endif
#ifdef STORM_HAVE_CARL
template<>
RationalFunction pow(RationalFunction const& value, uint_fast64_t exponent) {
return carl::pow(value, exponent);
@ -91,7 +134,7 @@ namespace storm {
return std::move(value);
}
#endif
template<typename IndexType, typename ValueType>
storm::storage::MatrixEntry<IndexType, ValueType> simplify(storm::storage::MatrixEntry<IndexType, ValueType> matrixEntry) {
simplify(matrixEntry.getValue());
@ -111,6 +154,10 @@ namespace storm {
}
// Explicit instantiations.
template bool isOne(double const& value);
template bool isZero(double const& value);
template bool isConstant(double const& value);
template double one();
template double zero();
template double infinity();
@ -123,6 +170,10 @@ namespace storm {
template storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>& simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>& matrixEntry);
template storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>&& simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>&& matrixEntry);
template bool isOne(float const& value);
template bool isZero(float const& value);
template bool isConstant(float const& value);
template float one();
template float zero();
template float infinity();
@ -135,6 +186,10 @@ namespace storm {
template storm::storage::MatrixEntry<storm::storage::sparse::state_type, float>& simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, float>& matrixEntry);
template storm::storage::MatrixEntry<storm::storage::sparse::state_type, float>&& simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, float>&& matrixEntry);
template bool isOne(int const& value);
template bool isZero(int const& value);
template bool isConstant(int const& value);
template int one();
template int zero();
template int infinity();

9
src/utility/constants.h

@ -30,6 +30,15 @@ namespace storm {
template<typename ValueType>
ValueType infinity();
template<typename ValueType>
bool isOne(ValueType const& a);
template<typename ValueType>
bool isZero(ValueType const& a);
template<typename ValueType>
bool isConstant(ValueType const& a);
template<typename ValueType>
ValueType pow(ValueType const& value, uint_fast64_t exponent);

28
src/utility/solver.cpp

@ -1,9 +1,9 @@
#include "src/utility/solver.h"
#include "src/settings/SettingsManager.h"
#include "src/solver/SymbolicGameSolver.h"
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/solver/NativeLinearEquationSolver.h"
#include "src/solver/GmmxxLinearEquationSolver.h"
@ -16,10 +16,16 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/exceptions/InvalidSettingsException.h"
namespace storm {
namespace utility {
namespace solver {
template<storm::dd::DdType Type, typename ValueType>
std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<Type, ValueType>> SymbolicLinearEquationSolverFactory<Type, ValueType>::create(storm::dd::Add<Type> const& A, storm::dd::Bdd<Type> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) const {
return std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<Type, ValueType>>(new storm::solver::SymbolicLinearEquationSolver<Type, ValueType>(A, allRows, rowMetaVariables, columnMetaVariables, rowColumnMetaVariablePairs));
@ -37,10 +43,10 @@ namespace storm {
template<typename ValueType>
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
storm::settings::modules::GeneralSettings::EquationSolver equationSolver = storm::settings::generalSettings().getEquationSolver();
storm::solver::EquationSolverType equationSolver = storm::settings::generalSettings().getEquationSolver();
switch (equationSolver) {
case storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::GmmxxLinearEquationSolver<ValueType>(matrix));
case storm::settings::modules::GeneralSettings::EquationSolver::Native: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::NativeLinearEquationSolver<ValueType>(matrix));
case storm::solver::EquationSolverType::Gmmxx: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::GmmxxLinearEquationSolver<ValueType>(matrix));
case storm::solver::EquationSolverType::Native: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::NativeLinearEquationSolver<ValueType>(matrix));
default: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::GmmxxLinearEquationSolver<ValueType>(matrix));
}
}
@ -76,10 +82,10 @@ namespace storm {
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> MinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
storm::settings::modules::GeneralSettings::EquationSolver equationSolver = storm::settings::generalSettings().getEquationSolver();
storm::solver::EquationSolverType equationSolver = storm::settings::generalSettings().getEquationSolver();
switch (equationSolver) {
case storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
case storm::settings::modules::GeneralSettings::EquationSolver::Native: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::NativeMinMaxLinearEquationSolver<ValueType>(matrix));
case storm::solver::EquationSolverType::Gmmxx: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
case storm::solver::EquationSolverType::Native: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::NativeMinMaxLinearEquationSolver<ValueType>(matrix));
default: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
}
}
@ -100,10 +106,10 @@ namespace storm {
}
std::unique_ptr<storm::solver::LpSolver> LpSolverFactory::create(std::string const& name) const {
storm::settings::modules::GeneralSettings::LpSolver lpSolver = storm::settings::generalSettings().getLpSolver();
storm::solver::LpSolverType lpSolver = storm::settings::generalSettings().getLpSolver();
switch (lpSolver) {
case storm::settings::modules::GeneralSettings::LpSolver::Gurobi: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GurobiLpSolver(name));
case storm::settings::modules::GeneralSettings::LpSolver::glpk: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GlpkLpSolver(name));
case storm::solver::LpSolverType::Gurobi: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GurobiLpSolver(name));
case storm::solver::LpSolverType::Glpk: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GlpkLpSolver(name));
default: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GurobiLpSolver(name));
}
}

23
src/utility/solver.h

@ -6,17 +6,28 @@
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/solver/NativeLinearEquationSolver.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/solver/LpSolver.h"
#include "src/storage/dd/DdType.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/exceptions/InvalidSettingsException.h"
#include "src/utility/ExtendSettingEnumWithSelectionField.h"
namespace storm {
namespace solver {
template<storm::dd::DdType T> class SymbolicGameSolver;
template<storm::dd::DdType T, typename V> class SymbolicLinearEquationSolver;
template<typename V> class LinearEquationSolver;
template<typename V> class MinMaxLinearEquationSolver;
class LpSolver;
}
namespace dd {
template<storm::dd::DdType T> class Add;
template<storm::dd::DdType T> class Bdd;
}
namespace expressions {
class Variable;
}
namespace utility {
namespace solver {
template<storm::dd::DdType Type, typename ValueType>
class SymbolicLinearEquationSolverFactory {
public:

36
src/utility/vector.h

@ -350,6 +350,22 @@ namespace storm {
return filter(values, fnc);
}
/**
* Sum the entries from values that are set to one in the filter vector.
* @param values
* @param filter
* @return The sum of the values with a corresponding one in the filter.
*/
template<typename VT>
VT sum_if(std::vector<VT> const& values, storm::storage::BitVector const& filter) {
assert(values.size() >= filter.size());
VT sum = storm::utility::zero<VT>();
for(uint_fast64_t i : filter) {
sum += values[i];
}
return sum;
}
/*!
* Reduces the given source vector by selecting an element according to the given filter out of each row group.
*
@ -434,7 +450,7 @@ namespace storm {
}
#endif
}
/*!
* Reduces the given source vector by selecting the smallest element out of each row group.
*
@ -461,6 +477,24 @@ namespace storm {
reduceVector<T>(source, target, rowGrouping, std::greater<T>(), choices);
}
/*!
* Reduces the given source vector by selecting either the smallest or the largest out of each row group.
*
* @param minimize If true, select the smallest, else select the largest.
* @param source The source vector which is to be reduced.
* @param target The target vector into which a single element from each row group is written.
* @param rowGrouping A vector that specifies the begin and end of each group of elements in the source vector.
* @param choices If non-null, this vector is used to store the choices made during the selection.
*/
template<class T>
void reduceVectorMinOrMax(bool minimize, std::vector<T> const& source, std::vector<T>& target, std::vector<uint_fast64_t> const& rowGrouping, std::vector<uint_fast64_t>* choices = nullptr) {
if(minimize) {
reduceVectorMin(source, target, rowGrouping, choices);
} else {
reduceVectorMax(source, target, rowGrouping, choices);
}
}
/*!
* Compares the given elements and determines whether they are equal modulo the given precision. The provided flag
* additionaly specifies whether the error is computed in relative or absolute terms.

2
test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp

@ -13,6 +13,8 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
TEST(GmmxxCtmcCslModelCheckerTest, Cluster) {

103
test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/logic/Formulas.h"
#include "src/utility/solver.h"
#include "src/models/sparse/StandardRewardModel.h"
@ -9,12 +10,16 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/SettingMemento.h"
#include "src/parser/AutoParser.h"
TEST(GmmxxDtmcPrctlModelCheckerTest, Die) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -24,34 +29,30 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
result = checker.check(*eventuallyFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(11.0/3.0, quantitativeResult4[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
@ -61,6 +62,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", "");
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -69,26 +73,23 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.3328800375801578281, quantitativeResult1[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
result = checker.check(*eventuallyFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.1522194965, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.32153724292835045, quantitativeResult3[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
@ -98,6 +99,10 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
ASSERT_EQ(12400ull, dtmc->getNumberOfStates());
@ -105,27 +110,23 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0, quantitativeResult1[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 20);
result = checker.check(*boundedUntilFormula);
formula = parser.parseFromString("P=? [F<=20 \"elected\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.9999965911265462636, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
result = checker.check(*reachabilityRewardFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.044879046, quantitativeResult3[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
@ -135,6 +136,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::storage::SparseMatrixBuilder<double> matrixBuilder;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc;
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
{
matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 2);
matrixBuilder.addNextValue(0, 1, 1.);
@ -149,10 +153,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -174,10 +177,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -199,10 +201,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1. / 3., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -215,6 +216,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) {
storm::storage::SparseMatrixBuilder<double> matrixBuilder;
std::shared_ptr<storm::models::sparse::Dtmc<double>> mdp;
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
{
matrixBuilder = storm::storage::SparseMatrixBuilder<double>(15, 15, 20, true);
matrixBuilder.addNextValue(0, 1, 1);
@ -260,10 +264,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.3 / 3., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());

2
test/functional/modelchecker/GmmxxHybridCtmcCslModelCheckerTest.cpp

@ -18,6 +18,8 @@
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
TEST(GmmxxHybridCtmcCslModelCheckerTest, Cluster) {
// Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);

63
test/functional/modelchecker/GmmxxHybridDtmcPrctlModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/logic/Formulas.h"
#include "src/utility/solver.h"
#include "src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h"
@ -15,9 +16,14 @@
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Die) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -36,40 +42,36 @@ TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Die) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult4 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -80,6 +82,9 @@ TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Die) {
TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Crowds) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/crowds-5-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::translateProgram(program);
EXPECT_EQ(8607ul, model->getNumberOfStates());
EXPECT_EQ(15113ul, model->getNumberOfTransitions());
@ -90,30 +95,27 @@ TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Crowds) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.3328800375801578281, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.3328800375801578281, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.1522194965, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.1522194965, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -124,6 +126,9 @@ TEST(GmmxxHybridDtmcPrctlModelCheckerTest, Crowds) {
TEST(GmmxxHybridDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader-3-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -142,31 +147,27 @@ TEST(GmmxxHybridDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 20);
formula = parser.parseFromString("P=? [F<=20 \"elected\"]");
result = checker.check(*boundedUntilFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();

3
test/functional/modelchecker/GmmxxHybridMdpPrctlModelCheckerTest.cpp

@ -14,8 +14,9 @@
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
TEST(GmmxxHybridMdpPrctlModelCheckerTest, Dice) {

2
test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp

@ -11,6 +11,8 @@
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/parser/AutoParser.h"
TEST(GmmxxMdpPrctlModelCheckerTest, Dice) {

2
test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp

@ -10,8 +10,8 @@
#include "src/models/sparse/StandardRewardModel.h"
#include "src/modelchecker/csl/SparseCtmcCslModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/modules/GeneralSettings.h"

98
test/functional/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/settings/SettingMemento.h"
#include "src/logic/Formulas.h"
#include "src/utility/solver.h"
@ -10,12 +11,17 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/SettingMemento.h"
#include "src/parser/AutoParser.h"
TEST(SparseDtmcPrctlModelCheckerTest, Die) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -25,34 +31,30 @@ TEST(SparseDtmcPrctlModelCheckerTest, Die) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(3.6666650772094727, quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -63,6 +65,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, Crowds) {
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
ASSERT_EQ(8607ull, dtmc->getNumberOfStates());
@ -70,26 +75,23 @@ TEST(SparseDtmcPrctlModelCheckerTest, Crowds) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.33288205191646525, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.15222066094730619, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.32153900158185761, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -99,6 +101,10 @@ TEST(SparseDtmcPrctlModelCheckerTest, SynchronousLeader) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
ASSERT_EQ(12400ull, dtmc->getNumberOfStates());
@ -106,27 +112,23 @@ TEST(SparseDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 20);
formula = parser.parseFromString("P=? [F<=20 \"elected\"]");
result = checker.check(*boundedUntilFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.9999965911265462636, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0448979589010925, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -136,6 +138,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::storage::SparseMatrixBuilder<double> matrixBuilder;
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc;
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
{
matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 2);
matrixBuilder.addNextValue(0, 1, 1.);
@ -150,10 +155,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -175,10 +179,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -200,10 +203,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1. / 3., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
@ -216,6 +218,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRA) {
storm::storage::SparseMatrixBuilder<double> matrixBuilder;
std::shared_ptr<storm::models::sparse::Dtmc<double>> mdp;
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
{
matrixBuilder = storm::storage::SparseMatrixBuilder<double>(15, 15, 20, true);
matrixBuilder.addNextValue(0, 1, 1);
@ -261,10 +266,9 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRA) {
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(labelFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("LRA=? [\"a\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*formula));
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.3 / 3., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());

2
test/functional/modelchecker/NativeHybridCtmcCslModelCheckerTest.cpp

@ -17,6 +17,8 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
TEST(NativeHybridCtmcCslModelCheckerTest, Cluster) {
// Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);

63
test/functional/modelchecker/NativeHybridDtmcPrctlModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/logic/Formulas.h"
#include "src/utility/solver.h"
#include "src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h"
@ -16,9 +17,14 @@
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
TEST(NativeHybridDtmcPrctlModelCheckerTest, Die) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -37,40 +43,36 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Die) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult4 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -81,6 +83,9 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Die) {
TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/crowds-5-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::translateProgram(program);
EXPECT_EQ(8607ul, model->getNumberOfStates());
EXPECT_EQ(15113ul, model->getNumberOfTransitions());
@ -91,30 +96,27 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.33288205191646525, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.33288205191646525, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.15222066094730619, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.15222066094730619, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -125,6 +127,9 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds) {
TEST(NativeHybridDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader-3-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -143,31 +148,27 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::modelchecker::HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0, quantitativeResult1.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0, quantitativeResult1.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 20);
formula = parser.parseFromString("P=? [F<=20 \"elected\"]");
result = checker.check(*boundedUntilFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMin(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMax(), storm::settings::gmmxxEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();

2
test/functional/modelchecker/NativeHybridMdpPrctlModelCheckerTest.cpp

@ -16,6 +16,8 @@
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
TEST(NativeHybridMdpPrctlModelCheckerTest, Dice) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/two_dice.nm");

2
test/functional/modelchecker/NativeMdpPrctlModelCheckerTest.cpp

@ -10,6 +10,8 @@
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/parser/AutoParser.h"
TEST(SparseMdpPrctlModelCheckerTest, Dice) {

77
test/functional/modelchecker/SparseDtmcEliminationModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/logic/Formulas.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h"
@ -14,6 +15,9 @@
TEST(SparseDtmcEliminationModelCheckerTest, Die) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -23,34 +27,30 @@ TEST(SparseDtmcEliminationModelCheckerTest, Die) {
storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc);
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3[0], storm::settings::generalSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(11.0/3.0, quantitativeResult4[0], storm::settings::generalSettings().getPrecision());
@ -59,6 +59,9 @@ TEST(SparseDtmcEliminationModelCheckerTest, Die) {
TEST(SparseDtmcEliminationModelCheckerTest, Crowds) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", "");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -68,50 +71,37 @@ TEST(SparseDtmcEliminationModelCheckerTest, Crowds) {
storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc);
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.3328800375801578281, quantitativeResult1[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
result = checker.check(*eventuallyFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.1522194965, quantitativeResult2[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
result = checker.check(*eventuallyFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.32153724292835045, quantitativeResult3[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
auto labelFormula2 = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
auto eventuallyFormula2 = std::make_shared<storm::logic::EventuallyFormula>(labelFormula2);
auto conditionalFormula = std::make_shared<storm::logic::ConditionalPathFormula>(eventuallyFormula, eventuallyFormula2);
formula = parser.parseFromString("P=? [F \"observe0Greater1\" || F \"observeIGreater1\"]");
result = checker.check(*conditionalFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.15330064292476167, quantitativeResult4[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\" || F \"observe0Greater1\"]");
labelFormula2 = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
eventuallyFormula2 = std::make_shared<storm::logic::EventuallyFormula>(labelFormula2);
conditionalFormula = std::make_shared<storm::logic::ConditionalPathFormula>(eventuallyFormula, eventuallyFormula2);
result = checker.check(*conditionalFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(0.96592521978041668, quantitativeResult5[0], storm::settings::generalSettings().getPrecision());
@ -120,6 +110,9 @@ TEST(SparseDtmcEliminationModelCheckerTest, Crowds) {
TEST(SparseDtmcEliminationModelCheckerTest, SynchronousLeader) {
std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
@ -128,18 +121,16 @@ TEST(SparseDtmcEliminationModelCheckerTest, SynchronousLeader) {
storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc);
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0, quantitativeResult1[0], storm::settings::generalSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
EXPECT_NEAR(1.0448979, quantitativeResult3[0], storm::settings::generalSettings().getPrecision());

63
test/functional/modelchecker/SymbolicDtmcPrctlModelCheckerTest.cpp

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/parser/FormulaParser.h"
#include "src/logic/Formulas.h"
#include "src/utility/solver.h"
#include "src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h"
@ -12,11 +13,16 @@
#include "src/models/symbolic/Dtmc.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/modules/GeneralSettings.h"
TEST(SymbolicDtmcPrctlModelCheckerTest, Die) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -35,40 +41,36 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Die) {
storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>(new storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("one");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"one\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult1.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"two\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult2.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"three\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0/6.0, quantitativeResult3.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
auto done = std::make_shared<storm::logic::AtomicLabelFormula>("done");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(done);
formula = parser.parseFromString("R=? [F \"done\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult4 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -79,6 +81,9 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Die) {
TEST(SymbolicDtmcPrctlModelCheckerTest, Crowds) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/crowds-5-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::translateProgram(program);
EXPECT_EQ(8607ul, model->getNumberOfStates());
EXPECT_EQ(15113ul, model->getNumberOfTransitions());
@ -89,30 +94,27 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Crowds) {
storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>(new storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observe0Greater1");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"observe0Greater1\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.33288236360191303, quantitativeResult1.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.33288236360191303, quantitativeResult1.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeIGreater1");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeIGreater1\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.15222081144084315, quantitativeResult2.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.15222081144084315, quantitativeResult2.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("observeOnlyTrueSender");
eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
formula = parser.parseFromString("P=? [F \"observeOnlyTrueSender\"]");
result = checker.check(*eventuallyFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
@ -123,6 +125,9 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Crowds) {
TEST(SymbolicDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader-3-5.pm");
// A parser that we use for conveniently constructing the formulas.
storm::parser::FormulaParser parser;
// Build the die model with its reward model.
#ifdef WINDOWS
storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
@ -141,31 +146,27 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, SynchronousLeader) {
storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*dtmc, std::unique_ptr<storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>(new storm::utility::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>()));
auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
std::shared_ptr<storm::logic::Formula> formula = parser.parseFromString("P=? [F \"elected\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*eventuallyFormula);
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(1.0, quantitativeResult1.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(1.0, quantitativeResult1.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 20);
formula = parser.parseFromString("P=? [F<=20 \"elected\"]");
result = checker.check(*boundedUntilFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
EXPECT_NEAR(0.99999989760000074, quantitativeResult2.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
formula = parser.parseFromString("R=? [F \"elected\"]");
result = checker.check(*reachabilityRewardFormula);
result = checker.check(*formula);
result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();

2
test/functional/modelchecker/SymbolicMdpPrctlModelCheckerTest.cpp

@ -13,6 +13,8 @@
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/modules/GeneralSettings.h"
TEST(SymbolicMdpPrctlModelCheckerTest, Dice) {

1
test/functional/solver/FullySymbolicGameSolverTest.cpp

@ -7,6 +7,7 @@
#include "src/utility/solver.h"
#include "src/settings/SettingsManager.h"
#include "src/solver/SymbolicGameSolver.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"

2
test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp

@ -78,7 +78,7 @@ TEST(GmmxxMinMaxLinearEquationSolver, SolveWithPolicyIteration) {
std::vector<double> b = { 0.099, 0.5 };
storm::settings::modules::GmmxxEquationSolverSettings const& settings = storm::settings::gmmxxEquationSolverSettings();
storm::solver::GmmxxMinMaxLinearEquationSolver<double> solver(A, settings.getPrecision(), settings.getMaximalIterationCount(), false, settings.getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative);
storm::solver::GmmxxMinMaxLinearEquationSolver<double> solver(A, settings.getPrecision(), settings.getMaximalIterationCount(), storm::solver::MinMaxTechniqueSelection::PolicyIteration, settings.getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative);
ASSERT_NO_THROW(solver.solveEquationSystem(true, x, b));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::gmmxxEquationSolverSettings().getPrecision());

11
test/functional/solver/MinMaxTechniqueSelectionTest.cpp

@ -0,0 +1,11 @@
#include "gtest/gtest.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
TEST( MinMaxTechnique, Simple ) {
storm::solver::MinMaxTechniqueSelection ts = storm::solver::MinMaxTechniqueSelection::PolicyIteration;
storm::solver::MinMaxTechnique t = storm::solver::MinMaxTechnique::PolicyIteration;
ASSERT_EQ(convert(ts), t);
}

2
test/functional/solver/NativeMinMaxLinearEquationSolverTest.cpp

@ -79,7 +79,7 @@ TEST(NativeMinMaxLinearEquationSolver, SolveWithPolicyIteration) {
std::vector<double> b = { 0.099, 0.5 };
storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings();
storm::solver::NativeMinMaxLinearEquationSolver<double> solver(A, settings.getPrecision(), settings.getMaximalIterationCount(), false, settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative);
storm::solver::NativeMinMaxLinearEquationSolver<double> solver(A, settings.getPrecision(), settings.getMaximalIterationCount(), storm::solver::MinMaxTechniqueSelection::PolicyIteration, settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative);
ASSERT_NO_THROW(solver.solveEquationSystem(true, x, b));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::nativeEquationSolverSettings().getPrecision());

15
test/functional/storage/BitVectorTest.cpp

@ -39,6 +39,21 @@ TEST(BitVectorTest, InitFromIterator) {
}
}
TEST(BitVectorTest, InitFromIntVector) {
std::vector<uint_fast64_t> valueVector = {0, 4, 10};
storm::storage::BitVector vector(32, valueVector);
ASSERT_EQ(32ul, vector.size());
for (uint_fast64_t i = 0; i < 32; ++i) {
if (i == 0 || i == 4 || i == 10) {
ASSERT_TRUE(vector.get(i));
} else {
ASSERT_FALSE(vector.get(i));
}
}
}
TEST(BitVectorTest, GetSet) {
storm::storage::BitVector vector(32);

14
test/functional/utility/VectorTest.cpp

@ -0,0 +1,14 @@
#include "gtest/gtest.h"
#include "storm-config.h"
#include "src/storage/BitVector.h"
#include "src/utility/vector.h"
TEST(VectorTest, sum_if) {
std::vector<double> a = {1.0, 2.0, 4.0, 8.0, 16.0};
storm::storage::BitVector f1(5, {2,4});
storm::storage::BitVector f2(5, {3,4});
ASSERT_EQ(20.0, storm::utility::vector::sum_if(a, f1));
ASSERT_EQ(24.0, storm::utility::vector::sum_if(a, f2));
}

1
test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp

@ -2,6 +2,7 @@
#include "storm-config.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/SettingMemento.h"
#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"

1
test/performance/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp

@ -2,6 +2,7 @@
#include "storm-config.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/utility/solver.h"

2
test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp

@ -2,6 +2,8 @@
#include "storm-config.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GmmxxEquationSolverSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/settings/SettingMemento.h"
#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"

2
test/performance/modelchecker/NativeMdpPrctlModelCheckerTest.cpp

@ -4,6 +4,8 @@
#include "src/settings/SettingsManager.h"
#include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
#include "src/utility/solver.h"
#include "src/parser/AutoParser.h"

Loading…
Cancel
Save