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.

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