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.

235 lines
15 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/settings/SettingMemento.h"
  4. #include "src/parser/PrismParser.h"
  5. #include "src/parser/FormulaParser.h"
  6. #include "src/logic/Formulas.h"
  7. #include "src/builder/ExplicitPrismModelBuilder.h"
  8. #include "src/solver/GmmxxLinearEquationSolver.h"
  9. #include "src/modelchecker/csl/SparseCtmcCslModelChecker.h"
  10. #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
  11. #include "src/settings/SettingsManager.h"
  12. TEST(GmmxxCtmcCslModelCheckerTest, Cluster) {
  13. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  14. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);
  15. // Parse the model description.
  16. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/cluster2.sm");
  17. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  18. std::shared_ptr<storm::logic::Formula> formula(nullptr);
  19. // Build the model.
  20. typename storm::builder::ExplicitPrismModelBuilder<double>::Options options;
  21. options.buildRewards = true;
  22. options.rewardModelName = "num_repairs";
  23. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>::translateProgram(program, options);
  24. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  25. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  26. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  27. // Create model checker.
  28. storm::modelchecker::SparseCtmcCslModelChecker<double> modelchecker(*ctmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
  29. // Start checking properties.
  30. formula = formulaParser.parseFromString("P=? [ F<=100 !\"minimum\"]");
  31. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  32. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  33. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  34. EXPECT_NEAR(5.5461254704419085E-5, quantitativeCheckResult1[initialState], storm::settings::generalSettings().getPrecision());
  35. formula = formulaParser.parseFromString("P=? [ F[100,100] !\"minimum\"]");
  36. checkResult = modelchecker.check(*formula);
  37. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  38. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  39. EXPECT_NEAR(2.3397873548343415E-6, quantitativeCheckResult2[initialState], storm::settings::generalSettings().getPrecision());
  40. formula = formulaParser.parseFromString("P=? [ F[100,2000] !\"minimum\"]");
  41. checkResult = modelchecker.check(*formula);
  42. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  43. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  44. EXPECT_NEAR(0.001105335651650576, quantitativeCheckResult3[initialState], storm::settings::generalSettings().getPrecision());
  45. formula = formulaParser.parseFromString("P=? [ \"minimum\" U<=10 \"premium\"]");
  46. checkResult = modelchecker.check(*formula);
  47. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  48. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  49. EXPECT_NEAR(1, quantitativeCheckResult4[initialState], storm::settings::generalSettings().getPrecision());
  50. formula = formulaParser.parseFromString("P=? [ !\"minimum\" U[1,inf] \"minimum\"]");
  51. checkResult = modelchecker.check(*formula);
  52. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  53. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  54. EXPECT_NEAR(0, quantitativeCheckResult5[initialState], storm::settings::generalSettings().getPrecision());
  55. formula = formulaParser.parseFromString("R=? [C<=100]");
  56. checkResult = modelchecker.check(*formula);
  57. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  58. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  59. EXPECT_NEAR(0.8602815057967503, quantitativeCheckResult6[initialState], storm::settings::generalSettings().getPrecision());
  60. }
  61. TEST(GmmxxCtmcCslModelCheckerTest, Embedded) {
  62. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  63. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);
  64. // Parse the model description.
  65. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/embedded2.sm");
  66. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  67. std::shared_ptr<storm::logic::Formula> formula(nullptr);
  68. // Build the model.
  69. typename storm::builder::ExplicitPrismModelBuilder<double>::Options options;
  70. options.buildRewards = true;
  71. options.rewardModelName = "up";
  72. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>::translateProgram(program, options);
  73. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  74. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  75. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  76. // Create model checker.
  77. storm::modelchecker::SparseCtmcCslModelChecker<double> modelchecker(*ctmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
  78. // Start checking properties.
  79. formula = formulaParser.parseFromString("P=? [ F<=10000 \"down\"]");
  80. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  81. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  82. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  83. EXPECT_NEAR(0.0019216435246119591, quantitativeCheckResult1[initialState], storm::settings::generalSettings().getPrecision());
  84. formula = formulaParser.parseFromString("P=? [ !\"down\" U<=10000 \"fail_actuators\"]");
  85. checkResult = modelchecker.check(*formula);
  86. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  87. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  88. EXPECT_NEAR(3.7079151806696567E-6, quantitativeCheckResult2[initialState], storm::settings::generalSettings().getPrecision());
  89. formula = formulaParser.parseFromString("P=? [ !\"down\" U<=10000 \"fail_io\"]");
  90. checkResult = modelchecker.check(*formula);
  91. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  92. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  93. EXPECT_NEAR(0.001556839327673734, quantitativeCheckResult3[initialState], storm::settings::generalSettings().getPrecision());
  94. formula = formulaParser.parseFromString("P=? [ !\"down\" U<=10000 \"fail_sensors\"]");
  95. checkResult = modelchecker.check(*formula);
  96. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  97. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  98. EXPECT_NEAR(4.429620626755424E-5, quantitativeCheckResult4[initialState], storm::settings::generalSettings().getPrecision());
  99. formula = formulaParser.parseFromString("R=? [C<=10000]");
  100. checkResult = modelchecker.check(*formula);
  101. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  102. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  103. EXPECT_NEAR(2.7720429852369946, quantitativeCheckResult5[initialState], storm::settings::generalSettings().getPrecision());
  104. }
  105. TEST(GmmxxCtmcCslModelCheckerTest, Polling) {
  106. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  107. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);
  108. // Parse the model description.
  109. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/polling2.sm");
  110. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  111. std::shared_ptr<storm::logic::Formula> formula(nullptr);
  112. // Build the model.
  113. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>::translateProgram(program);
  114. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  115. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  116. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  117. // Create model checker.
  118. storm::modelchecker::SparseCtmcCslModelChecker<double> modelchecker(*ctmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
  119. // Start checking properties.
  120. formula = formulaParser.parseFromString("P=?[ F<=10 \"target\"]");
  121. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  122. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  123. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  124. EXPECT_NEAR(1, quantitativeCheckResult1[initialState], storm::settings::generalSettings().getPrecision());
  125. }
  126. TEST(GmmxxCtmcCslModelCheckerTest, Fms) {
  127. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  128. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);
  129. // No properties to check at this point.
  130. }
  131. TEST(GmmxxCtmcCslModelCheckerTest, Tandem) {
  132. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  133. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableGeneralSettings().overridePrismCompatibilityMode(true);
  134. // Parse the model description.
  135. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/tandem5.sm");
  136. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  137. std::shared_ptr<storm::logic::Formula> formula(nullptr);
  138. // Build the model.
  139. typename storm::builder::ExplicitPrismModelBuilder<double>::Options options;
  140. options.buildRewards = true;
  141. options.rewardModelName = "customers";
  142. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>::translateProgram(program, options);
  143. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  144. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  145. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  146. // Create model checker.
  147. storm::modelchecker::SparseCtmcCslModelChecker<double> modelchecker(*ctmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
  148. // Start checking properties.
  149. formula = formulaParser.parseFromString("P=? [ F<=10 \"network_full\" ]");
  150. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  151. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  152. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  153. EXPECT_NEAR(0.015446370562428037, quantitativeCheckResult1[initialState], storm::settings::generalSettings().getPrecision());
  154. formula = formulaParser.parseFromString("P=? [ F<=10 \"first_queue_full\" ]");
  155. checkResult = modelchecker.check(*formula);
  156. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  157. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  158. EXPECT_NEAR(0.999999837225515, quantitativeCheckResult2[initialState], storm::settings::generalSettings().getPrecision());
  159. formula = formulaParser.parseFromString("P=? [\"second_queue_full\" U<=1 !\"second_queue_full\"]");
  160. checkResult = modelchecker.check(*formula);
  161. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  162. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  163. EXPECT_NEAR(1, quantitativeCheckResult3[initialState], storm::settings::generalSettings().getPrecision());
  164. formula = formulaParser.parseFromString("R=? [I=10]");
  165. checkResult = modelchecker.check(*formula);
  166. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  167. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  168. EXPECT_NEAR(5.679243850315877, quantitativeCheckResult4[initialState], storm::settings::generalSettings().getPrecision());
  169. formula = formulaParser.parseFromString("R=? [C<=10]");
  170. checkResult = modelchecker.check(*formula);
  171. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  172. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  173. EXPECT_NEAR(55.44792186036232, quantitativeCheckResult5[initialState], storm::settings::generalSettings().getPrecision());
  174. formula = formulaParser.parseFromString("R=? [F \"first_queue_full\"&\"second_queue_full\"]");
  175. checkResult = modelchecker.check(*formula);
  176. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  177. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  178. EXPECT_NEAR(262.85103661561755, quantitativeCheckResult6[initialState], storm::settings::generalSettings().getPrecision());
  179. }