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.

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