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.

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