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.

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