You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
14 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/logic/Formulas.h"
  4. #include "src/utility/solver.h"
  5. #include "src/modelchecker/prctl/HybridMdpPrctlModelChecker.h"
  6. #include "src/modelchecker/results/HybridQuantitativeCheckResult.h"
  7. #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
  8. #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
  9. #include "src/parser/PrismParser.h"
  10. #include "src/parser/FormulaParser.h"
  11. #include "src/builder/DdPrismModelBuilder.h"
  12. #include "src/models/symbolic/Dtmc.h"
  13. #include "src/models/symbolic/Mdp.h"
  14. #include "src/models/symbolic/StandardRewardModel.h"
  15. #include "src/settings/SettingsManager.h"
  16. #include "src/settings/SettingsManager.h"
  17. #include "src/settings/modules/GeneralSettings.h"
  18. #include "src/settings/modules/NativeEquationSolverSettings.h"
  19. #include "src/settings/modules/GmmxxEquationSolverSettings.h"
  20. TEST(GmmxxHybridMdpPrctlModelCheckerTest, Dice) {
  21. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/two_dice.nm");
  22. // A parser that we use for conveniently constructing the formulas.
  23. storm::parser::FormulaParser formulaParser;
  24. // Build the die model with its reward model.
  25. #ifdef WINDOWS
  26. storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
  27. #else
  28. typename storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
  29. #endif
  30. options.buildAllRewardModels = false;
  31. options.rewardModelsToBuild.insert("coinflips");
  32. std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::translateProgram(program, options);
  33. EXPECT_EQ(169ul, model->getNumberOfStates());
  34. EXPECT_EQ(436ul, model->getNumberOfTransitions());
  35. ASSERT_EQ(model->getType(), storm::models::ModelType::Mdp);
  36. std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
  37. storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
  38. std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
  39. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  40. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  41. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  42. EXPECT_NEAR(0.0277777612209320068, quantitativeResult1.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  43. EXPECT_NEAR(0.0277777612209320068, quantitativeResult1.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  44. formula = formulaParser.parseSingleFormulaFromString("Pmax=? [F \"two\"]");
  45. result = checker.check(*formula);
  46. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  47. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  48. EXPECT_NEAR(0.0277777612209320068, quantitativeResult2.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  49. EXPECT_NEAR(0.0277777612209320068, quantitativeResult2.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  50. formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"three\"]");
  51. result = checker.check(*formula);
  52. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  53. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  54. EXPECT_NEAR(0.0555555224418640136, quantitativeResult3.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  55. EXPECT_NEAR(0.0555555224418640136, quantitativeResult3.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  56. formula = formulaParser.parseSingleFormulaFromString("Pmax=? [F \"three\"]");
  57. result = checker.check(*formula);
  58. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  59. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult4 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  60. EXPECT_NEAR(0.0555555224418640136, quantitativeResult4.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  61. EXPECT_NEAR(0.0555555224418640136, quantitativeResult4.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  62. formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"four\"]");
  63. result = checker.check(*formula);
  64. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  65. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult5 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  66. EXPECT_NEAR(0.083333283662796020508, quantitativeResult5.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  67. EXPECT_NEAR(0.083333283662796020508, quantitativeResult5.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  68. formula = formulaParser.parseSingleFormulaFromString("Pmax=? [F \"four\"]");
  69. result = checker.check(*formula);
  70. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  71. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult6 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  72. EXPECT_NEAR(0.083333283662796020508, quantitativeResult6.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  73. EXPECT_NEAR(0.083333283662796020508, quantitativeResult6.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  74. formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
  75. result = checker.check(*formula);
  76. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  77. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult7 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  78. EXPECT_NEAR(7.3333294987678528, quantitativeResult7.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  79. EXPECT_NEAR(7.3333294987678528, quantitativeResult7.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  80. formula = formulaParser.parseSingleFormulaFromString("Rmax=? [F \"done\"]");
  81. result = checker.check(*formula);
  82. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  83. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult8 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  84. EXPECT_NEAR(7.3333294987678528, quantitativeResult8.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  85. EXPECT_NEAR(7.3333294987678528, quantitativeResult8.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  86. }
  87. TEST(GmmxxHybridMdpPrctlModelCheckerTest, AsynchronousLeader) {
  88. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader4.nm");
  89. // A parser that we use for conveniently constructing the formulas.
  90. storm::parser::FormulaParser formulaParser;
  91. // Build the die model with its reward model.
  92. #ifdef WINDOWS
  93. storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
  94. #else
  95. typename storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::Options options;
  96. #endif
  97. options.buildAllRewardModels = false;
  98. options.rewardModelsToBuild.insert("rounds");
  99. std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD>::translateProgram(program, options);
  100. EXPECT_EQ(3172ul, model->getNumberOfStates());
  101. EXPECT_EQ(7144ul, model->getNumberOfTransitions());
  102. ASSERT_EQ(model->getType(), storm::models::ModelType::Mdp);
  103. std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
  104. storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
  105. std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");
  106. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  107. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  108. storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult1 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  109. EXPECT_NEAR(1, quantitativeResult1.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  110. EXPECT_NEAR(1, quantitativeResult1.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  111. formula = formulaParser.parseSingleFormulaFromString("Pmax=? [F \"elected\"]");
  112. result = checker.check(*formula);
  113. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  114. storm::modelchecker::SymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult2 = result->asSymbolicQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  115. EXPECT_NEAR(1, quantitativeResult2.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  116. EXPECT_NEAR(1, quantitativeResult2.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  117. formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F<=25 \"elected\"]");
  118. result = checker.check(*formula);
  119. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  120. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult3 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  121. EXPECT_NEAR(0.0625, quantitativeResult3.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  122. EXPECT_NEAR(0.0625, quantitativeResult3.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  123. formula = formulaParser.parseSingleFormulaFromString("Pmax=? [F<=25 \"elected\"]");
  124. result = checker.check(*formula);
  125. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  126. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult4 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  127. EXPECT_NEAR(0.0625, quantitativeResult4.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  128. EXPECT_NEAR(0.0625, quantitativeResult4.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  129. formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"elected\"]");
  130. result = checker.check(*formula);
  131. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  132. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult5 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  133. EXPECT_NEAR(4.2856896106114934, quantitativeResult5.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  134. EXPECT_NEAR(4.2856896106114934, quantitativeResult5.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  135. formula = formulaParser.parseSingleFormulaFromString("Rmax=? [F \"elected\"]");
  136. result = checker.check(*formula);
  137. result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(model->getReachableStates(), model->getInitialStates()));
  138. storm::modelchecker::HybridQuantitativeCheckResult<storm::dd::DdType::CUDD>& quantitativeResult6 = result->asHybridQuantitativeCheckResult<storm::dd::DdType::CUDD>();
  139. EXPECT_NEAR(4.2856896106114934, quantitativeResult6.getMin(), storm::settings::nativeEquationSolverSettings().getPrecision());
  140. EXPECT_NEAR(4.2856896106114934, quantitativeResult6.getMax(), storm::settings::nativeEquationSolverSettings().getPrecision());
  141. }