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.

270 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. #include "src/storage/expressions/ExpressionManager.h"
  18. TEST(GmmxxCtmcCslModelCheckerTest, Cluster) {
  19. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  20. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  21. // Parse the model description.
  22. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/cluster2.sm");
  23. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  24. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  25. // Build the model.
  26. storm::generator::NextStateGeneratorOptions options;
  27. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("num_repairs")).build();
  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<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  33. // Start checking properties.
  34. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  39. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  44. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  49. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  54. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  59. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  64. formula = formulaParser.parseSingleFormulaFromString("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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  69. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"minimum\"]");
  70. checkResult = modelchecker.check(*formula);
  71. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  72. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult8 = checkResult->asExplicitQuantitativeCheckResult<double>();
  73. EXPECT_NEAR(0.99999766034263426, quantitativeCheckResult8[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  74. }
  75. TEST(GmmxxCtmcCslModelCheckerTest, Embedded) {
  76. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  77. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  78. // Parse the model description.
  79. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/embedded2.sm");
  80. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  81. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  82. // Build the model.
  83. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("up")).build();
  84. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  85. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  86. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  87. // Create model checker.
  88. storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  89. // Start checking properties.
  90. formula = formulaParser.parseSingleFormulaFromString("P=? [ F<=10000 \"down\"]");
  91. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  92. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  93. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  94. EXPECT_NEAR(0.0019216435246119591, quantitativeCheckResult1[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  95. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_actuators\"]");
  96. checkResult = modelchecker.check(*formula);
  97. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  98. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  99. EXPECT_NEAR(3.7079151806696567E-6, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  100. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_io\"]");
  101. checkResult = modelchecker.check(*formula);
  102. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  103. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  104. EXPECT_NEAR(0.001556839327673734, quantitativeCheckResult3[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  105. formula = formulaParser.parseSingleFormulaFromString("P=? [ !\"down\" U<=10000 \"fail_sensors\"]");
  106. checkResult = modelchecker.check(*formula);
  107. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  108. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  109. EXPECT_NEAR(4.429620626755424E-5, quantitativeCheckResult4[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  110. formula = formulaParser.parseSingleFormulaFromString("R=? [C<=10000]");
  111. checkResult = modelchecker.check(*formula);
  112. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  113. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  114. EXPECT_NEAR(2.7745274082080154, quantitativeCheckResult5[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  115. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"fail_sensors\"]");
  116. checkResult = modelchecker.check(*formula);
  117. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  118. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  119. EXPECT_NEAR(0.93458866427696596, quantitativeCheckResult6[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  120. }
  121. TEST(GmmxxCtmcCslModelCheckerTest, 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::mutableIOSettings().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 const> formula(nullptr);
  128. // Build the model.
  129. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true)).build();
  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::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<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::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  141. formula = formulaParser.parseSingleFormulaFromString("LRA=?[\"target\"]");
  142. checkResult = modelchecker.check(*formula);
  143. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  144. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  145. EXPECT_NEAR(0.20079750055570736, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  146. }
  147. TEST(GmmxxCtmcCslModelCheckerTest, Fms) {
  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::mutableIOSettings().overridePrismCompatibilityMode(true);
  150. // No properties to check at this point.
  151. }
  152. TEST(GmmxxCtmcCslModelCheckerTest, Tandem) {
  153. // Set the PRISM compatibility mode temporarily. It is set to its old value once the returned object is destructed.
  154. std::unique_ptr<storm::settings::SettingMemento> enablePrismCompatibility = storm::settings::mutableIOSettings().overridePrismCompatibilityMode(true);
  155. // Parse the model description.
  156. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/tandem5.sm");
  157. storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
  158. std::shared_ptr<storm::logic::Formula const> formula(nullptr);
  159. // Build the model.
  160. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, storm::generator::NextStateGeneratorOptions(false, true). addRewardModel("customers")).build();
  161. ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType());
  162. std::shared_ptr<storm::models::sparse::Ctmc<double>> ctmc = model->as<storm::models::sparse::Ctmc<double>>();
  163. uint_fast64_t initialState = *ctmc->getInitialStates().begin();
  164. // Create model checker.
  165. storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<double>> modelchecker(*ctmc, std::make_unique<storm::solver::GmmxxLinearEquationSolverFactory<double>>());
  166. // Start checking properties.
  167. formula = formulaParser.parseSingleFormulaFromString("P=? [ F<=10 \"network_full\" ]");
  168. std::unique_ptr<storm::modelchecker::CheckResult> checkResult = modelchecker.check(*formula);
  169. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  170. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult1 = checkResult->asExplicitQuantitativeCheckResult<double>();
  171. EXPECT_NEAR(0.015446370562428037, quantitativeCheckResult1[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  172. formula = formulaParser.parseSingleFormulaFromString("P=? [ F<=10 \"first_queue_full\" ]");
  173. checkResult = modelchecker.check(*formula);
  174. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  175. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult2 = checkResult->asExplicitQuantitativeCheckResult<double>();
  176. EXPECT_NEAR(0.999999837225515, quantitativeCheckResult2[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  177. formula = formulaParser.parseSingleFormulaFromString("P=? [\"second_queue_full\" U<=1 !\"second_queue_full\"]");
  178. checkResult = modelchecker.check(*formula);
  179. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  180. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult3 = checkResult->asExplicitQuantitativeCheckResult<double>();
  181. EXPECT_NEAR(1, quantitativeCheckResult3[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  182. formula = formulaParser.parseSingleFormulaFromString("R=? [I=10]");
  183. checkResult = modelchecker.check(*formula);
  184. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  185. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult4 = checkResult->asExplicitQuantitativeCheckResult<double>();
  186. EXPECT_NEAR(5.679243850315877, quantitativeCheckResult4[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  187. formula = formulaParser.parseSingleFormulaFromString("R=? [C<=10]");
  188. checkResult = modelchecker.check(*formula);
  189. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  190. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult5 = checkResult->asExplicitQuantitativeCheckResult<double>();
  191. EXPECT_NEAR(55.44792186036232, quantitativeCheckResult5[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  192. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"first_queue_full\"&\"second_queue_full\"]");
  193. checkResult = modelchecker.check(*formula);
  194. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  195. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult6 = checkResult->asExplicitQuantitativeCheckResult<double>();
  196. EXPECT_NEAR(262.85103661561755, quantitativeCheckResult6[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  197. formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"first_queue_full\"]");
  198. checkResult = modelchecker.check(*formula);
  199. ASSERT_TRUE(checkResult->isExplicitQuantitativeCheckResult());
  200. storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeCheckResult7 = checkResult->asExplicitQuantitativeCheckResult<double>();
  201. EXPECT_NEAR(0.9100373532, quantitativeCheckResult7[initialState], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  202. }