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.

268 lines
19 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/ExplicitModelBuilder.h"
  8. #include "src/solver/GmmxxLinearEquationSolver.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/GeneralSettings.h"
  14. #include "src/settings/modules/IOSettings.h"
  15. #include "src/settings/modules/NativeEquationSolverSettings.h"
  16. #include "src/settings/modules/GmmxxEquationSolverSettings.h"
  17. TEST(GmmxxCtmcCslModelCheckerTest, Cluster) {
  18. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  19. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  20. // Parse the model description.
  21. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/cluster2.sm");
  22. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  23. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  24. // Build the model.
  25. storm::generator::NextStateGeneratorOptions options;
  26. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("num_repairs")).build();
  27. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  28. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  29. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  30. // Create model checker.
  31. storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  32. // Start checking properties.
  33. formula = formulaParser.parseSingleFormulaFromString("P=? [ F<=100 !\"minimum\"]");
  34. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  35. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  36. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  37. EXPECT_NEAR(5.5461254704419085E-5, quantitativeCheckResult1[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  38. formula = formulaParser.parseSingleFormulaFromString("P=? [ F[100,100] !\"minimum\"]");
  39. checkResult = modelchecker.check(*formula);
  40. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  41. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  42. EXPECT_NEAR(2.3397873548343415E-6, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  43. formula = formulaParser.parseSingleFormulaFromString("P=? [ F[100,2000] !\"minimum\"]");
  44. checkResult = modelchecker.check(*formula);
  45. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  46. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  47. EXPECT_NEAR(0.001105335651670241, quantitativeCheckResult3[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  48. formula = formulaParser.parseSingleFormulaFromString("P=? [ \"minimum\" U<=10 \"premium\"]");
  49. checkResult = modelchecker.check(*formula);
  50. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  51. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  52. EXPECT_NEAR(1, quantitativeCheckResult4[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  53. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"minimum\" U[1,inf] \"minimum\"]");
  54. checkResult = modelchecker.check(*formula);
  55. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  56. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  57. EXPECT_NEAR(0, quantitativeCheckResult5[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> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  62. EXPECT_NEAR(0.9999999033633374, quantitativeCheckResult6[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  63. formula = formulaParser.parseSingleFormulaFromString("R=? [C<=100]");
  64. checkResult = modelchecker.check(*formula);
  65. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  66. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult7 = checkResult->asExplicitQuantitativeCheckResult<double>();
  67. EXPECT_NEAR(0.8602815057967503, quantitativeCheckResult7[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  68. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"minimum\"]");
  69. checkResult = modelchecker.check(*formula);
  70. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  71. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult8 = checkResult->asExplicitQuantitativeCheckResult<double>();
  72. EXPECT_NEAR(0.99999766034263426, quantitativeCheckResult8[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  73. }
  74. TEST(GmmxxCtmcCslModelCheckerTest, 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. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("up")).build();
  83. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  84. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  85. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  86. // Create model checker.
  87. storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  88. // Start checking properties.
  89. formula = formulaParser.parseSingleFormulaFromString("P=? [ F<=10000 \"down\"]");
  90. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  91. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  92. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  93. EXPECT_NEAR(0.0019216435246119591, quantitativeCheckResult1[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  94. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_actuators\"]");
  95. checkResult = modelchecker.check(*formula);
  96. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  97. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  98. EXPECT_NEAR(3.7079151806696567E-6, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  99. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_io\"]");
  100. checkResult = modelchecker.check(*formula);
  101. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  102. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  103. EXPECT_NEAR(0.001556839327673734, quantitativeCheckResult3[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  104. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_sensors\"]");
  105. checkResult = modelchecker.check(*formula);
  106. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  107. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  108. EXPECT_NEAR(4.429620626755424E-5, quantitativeCheckResult4[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  109. formula = formulaParser.parseSingleFormulaFromString("R=? [C<=10000]");
  110. checkResult = modelchecker.check(*formula);
  111. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  112. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  113. EXPECT_NEAR(2.7745274082080154, quantitativeCheckResult5[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  114. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"fail_sensors\"]");
  115. checkResult = modelchecker.check(*formula);
  116. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  117. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  118. EXPECT_NEAR(0.93458866427696596, quantitativeCheckResult6[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  119. }
  120. TEST(GmmxxCtmcCslModelCheckerTest, Polling) {
  121. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  122. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  123. // Parse the model description.
  124. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/polling2.sm");
  125. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  126. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  127. // Build the model.
  128. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true)).build();
  129. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  130. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  131. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  132. // Create model checker.
  133. storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  134. // Start checking properties.
  135. formula = formulaParser.parseSingleFormulaFromString("P=?[ F<=10 \"target\"]");
  136. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  137. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  138. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  139. EXPECT_NEAR(1, quantitativeCheckResult1[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  140. formula = formulaParser.parseSingleFormulaFromString("LRA=?[\"target\"]");
  141. checkResult = modelchecker.check(*formula);
  142. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  143. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  144. EXPECT_NEAR(0.20079750055570736, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  145. }
  146. TEST(GmmxxCtmcCslModelCheckerTest, Fms) {
  147. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  148. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  149. // No properties to check at this point.
  150. }
  151. TEST(GmmxxCtmcCslModelCheckerTest, Tandem) {
  152. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  153. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  154. // Parse the model description.
  155. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/tandem5.sm");
  156. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  157. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  158. // Build the model.
  159. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("customers")).build();
  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<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  165. // Start checking properties.
  166. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  171. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  176. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  181. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  186. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  191. formula = formulaParser.parseSingleFormulaFromString("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.85103661561755, quantitativeCheckResult6[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  196. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"first_queue_full\"]");
  197. checkResult = modelchecker.check(*formula);
  198. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  199. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult7 = checkResult->asExplicitQuantitativeCheckResult<double>();
  200. EXPECT_NEAR(0.9100373532, quantitativeCheckResult7[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  201. }