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.

425 lines
25 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/parser/FormulaParser.h"
  4. #include "src/logic/Formulas.h"
  5. #include "src/solver/EigenLinearEquationSolver.h"
  6. #include "src/models/sparse/StandardRewardModel.h"
  7. #include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
  8. #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
  9. #include "src/settings/SettingsManager.h"
  10. #include "src/settings/modules/GeneralSettings.h"
  11. #include "src/settings/modules/EigenEquationSolverSettings.h"
  12. #include "src/settings/modules/NativeEquationSolverSettings.h"
  13. #include "src/settings/SettingMemento.h"
  14. #include "src/parser/AutoParser.h"
  15. #include "src/parser/PrismParser.h"
  16. #include "src/builder/ExplicitModelBuilder.h"
  17. TEST(EigenDtmcPrctlModelCheckerTest, Die) {
  18. std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
  19. // A parser that we use for conveniently constructing the formulas.
  20. storm::parser::FormulaParser formulaParser;
  21. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
  22. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
  23. ASSERT_EQ(dtmc->getNumberOfStates(), 13ull);
  24. ASSERT_EQ(dtmc->getNumberOfTransitions(), 20ull);
  25. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  26. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]");
  27. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  28. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  29. EXPECT_NEAR(1.0 / 6.0, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  30. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"two\"]");
  31. result = checker.check(*formula);
  32. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  33. EXPECT_NEAR(1.0 / 6.0, quantitativeResult2[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  34. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"three\"]");
  35. result = checker.check(*formula);
  36. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  37. EXPECT_NEAR(1.0 / 6.0, quantitativeResult3[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  38. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"done\"]");
  39. result = checker.check(*formula);
  40. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  41. EXPECT_NEAR(11.0 / 3.0, quantitativeResult4[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  42. }
  43. #ifdef STORM_HAVE_CARL
  44. TEST(EigenDtmcPrctlModelCheckerTest, Die_RationalNumber) {
  45. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm");
  46. storm::generator::NextStateGeneratorOptions options;
  47. options.setBuildAllLabels().setBuildAllRewardModels();
  48. std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> model = storm::builder::ExplicitModelBuilder<storm::RationalNumber>(program, options).build();
  49. // A parser that we use for conveniently constructing the formulas.
  50. storm::parser::FormulaParser formulaParser;
  51. ASSERT_EQ(model->getType(), storm::models::ModelType::Dtmc);
  52. std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalNumber>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalNumber>>();
  53. ASSERT_EQ(dtmc->getNumberOfStates(), 13ull);
  54. ASSERT_EQ(dtmc->getNumberOfTransitions(), 20ull);
  55. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<storm::RationalNumber>>());
  56. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]");
  57. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  58. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalNumber>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<storm::RationalNumber>();
  59. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult1[0]);
  60. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"two\"]");
  61. result = checker.check(*formula);
  62. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalNumber>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<storm::RationalNumber>();
  63. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult2[0]);
  64. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"three\"]");
  65. result = checker.check(*formula);
  66. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalNumber>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<storm::RationalNumber>();
  67. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult3[0]);
  68. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"done\"]");
  69. result = checker.check(*formula);
  70. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalNumber>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<storm::RationalNumber>();
  71. EXPECT_EQ(storm::RationalNumber(11) / storm::RationalNumber(3), quantitativeResult4[0]);
  72. }
  73. TEST(EigenDtmcPrctlModelCheckerTest, Die_RationalFunction) {
  74. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/parametric_die.pm");
  75. storm::generator::NextStateGeneratorOptions options;
  76. options.setBuildAllLabels().setBuildAllRewardModels();
  77. std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program, options).build();
  78. // A parser that we use for conveniently constructing the formulas.
  79. storm::parser::FormulaParser formulaParser;
  80. ASSERT_EQ(model->getType(), storm::models::ModelType::Dtmc);
  81. std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
  82. ASSERT_EQ(dtmc->getNumberOfStates(), 13ull);
  83. ASSERT_EQ(dtmc->getNumberOfTransitions(), 20ull);
  84. std::map<storm::RationalFunctionVariable, storm::RationalNumber> instantiation;
  85. std::set<storm::RationalFunctionVariable> variables = storm::models::sparse::getProbabilityParameters(*dtmc);
  86. ASSERT_EQ(variables.size(), 1ull);
  87. instantiation.emplace(*variables.begin(), storm::RationalNumber(1) / storm::RationalNumber(2));
  88. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<storm::RationalFunction>>());
  89. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]");
  90. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  91. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalFunction>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<storm::RationalFunction>();
  92. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult1[0].evaluate(instantiation));
  93. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"two\"]");
  94. result = checker.check(*formula);
  95. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalFunction>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<storm::RationalFunction>();
  96. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult2[0].evaluate(instantiation));
  97. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"three\"]");
  98. result = checker.check(*formula);
  99. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalFunction>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<storm::RationalFunction>();
  100. EXPECT_EQ(storm::RationalNumber(1) / storm::RationalNumber(6), quantitativeResult3[0].evaluate(instantiation));
  101. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"done\"]");
  102. result = checker.check(*formula);
  103. storm::modelchecker::ExplicitQuantitativeCheckResult<storm::RationalFunction>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<storm::RationalFunction>();
  104. EXPECT_EQ(storm::RationalNumber(11) / storm::RationalNumber(3), quantitativeResult4[0].evaluate(instantiation));
  105. }
  106. #endif
  107. TEST(EigenDtmcPrctlModelCheckerTest, Crowds) {
  108. std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", "");
  109. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
  110. // A parser that we use for conveniently constructing the formulas.
  111. storm::parser::FormulaParser formulaParser;
  112. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
  113. ASSERT_EQ(8607ull, dtmc->getNumberOfStates());
  114. ASSERT_EQ(15113ull, dtmc->getNumberOfTransitions());
  115. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::solver::LinearEquationSolverFactory<double>>(new storm::solver::EigenLinearEquationSolverFactory<double>()));
  116. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"observe0Greater1\"]");
  117. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  118. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  119. EXPECT_NEAR(0.3328800375801578281, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  120. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"observeIGreater1\"]");
  121. result = checker.check(*formula);
  122. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  123. EXPECT_NEAR(0.1522194965, quantitativeResult2[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  124. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"observeOnlyTrueSender\"]");
  125. result = checker.check(*formula);
  126. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  127. EXPECT_NEAR(0.32153724292835045, quantitativeResult3[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  128. }
  129. TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) {
  130. std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
  131. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Dtmc);
  132. // A parser that we use for conveniently constructing the formulas.
  133. storm::parser::FormulaParser formulaParser;
  134. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = abstractModel->as<storm::models::sparse::Dtmc<double>>();
  135. ASSERT_EQ(12400ull, dtmc->getNumberOfStates());
  136. ASSERT_EQ(16495ull, dtmc->getNumberOfTransitions());
  137. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  138. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"elected\"]");
  139. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  140. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  141. EXPECT_NEAR(1.0, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  142. formula = formulaParser.parseSingleFormulaFromString("P=? [F<=20 \"elected\"]");
  143. result = checker.check(*formula);
  144. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  145. EXPECT_NEAR(0.9999965911265462636, quantitativeResult2[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  146. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"elected\"]");
  147. result = checker.check(*formula);
  148. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  149. EXPECT_NEAR(1.0448979591836789, quantitativeResult3[0], storm::settings::getModule<storm::settings::modules::EigenEquationSolverSettings>().getPrecision());
  150. }
  151. TEST(EigenDtmcPrctlModelCheckerTest, LRASingleBscc) {
  152. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  153. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc;
  154. // A parser that we use for conveniently constructing the formulas.
  155. storm::parser::FormulaParser formulaParser;
  156. {
  157. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 2);
  158. matrixBuilder.addNextValue(0, 1, 1.);
  159. matrixBuilder.addNextValue(1, 0, 1.);
  160. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  161. storm::models::sparse::StateLabeling ap(2);
  162. ap.addLabel("a");
  163. ap.addLabelToState("a", 1);
  164. dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
  165. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  166. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
  167. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  168. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  169. EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  170. EXPECT_NEAR(.5, quantitativeResult1[1], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  171. }
  172. {
  173. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 4);
  174. matrixBuilder.addNextValue(0, 0, .5);
  175. matrixBuilder.addNextValue(0, 1, .5);
  176. matrixBuilder.addNextValue(1, 0, .5);
  177. matrixBuilder.addNextValue(1, 1, .5);
  178. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  179. storm::models::sparse::StateLabeling ap(2);
  180. ap.addLabel("a");
  181. ap.addLabelToState("a", 1);
  182. dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
  183. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  184. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
  185. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  186. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  187. EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  188. EXPECT_NEAR(.5, quantitativeResult1[1], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  189. }
  190. {
  191. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(3, 3, 3);
  192. matrixBuilder.addNextValue(0, 1, 1);
  193. matrixBuilder.addNextValue(1, 2, 1);
  194. matrixBuilder.addNextValue(2, 0, 1);
  195. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  196. storm::models::sparse::StateLabeling ap(3);
  197. ap.addLabel("a");
  198. ap.addLabelToState("a", 2);
  199. dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
  200. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  201. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
  202. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  203. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  204. EXPECT_NEAR(1. / 3., quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  205. EXPECT_NEAR(1. / 3., quantitativeResult1[1], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  206. EXPECT_NEAR(1. / 3., quantitativeResult1[2], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  207. }
  208. }
  209. TEST(EigenDtmcPrctlModelCheckerTest, LRA) {
  210. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  211. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc;
  212. // A parser that we use for conveniently constructing the formulas.
  213. storm::parser::FormulaParser formulaParser;
  214. {
  215. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(15, 15, 20, true);
  216. matrixBuilder.addNextValue(0, 1, 1);
  217. matrixBuilder.addNextValue(1, 4, 0.7);
  218. matrixBuilder.addNextValue(1, 6, 0.3);
  219. matrixBuilder.addNextValue(2, 0, 1);
  220. matrixBuilder.addNextValue(3, 5, 0.8);
  221. matrixBuilder.addNextValue(3, 9, 0.2);
  222. matrixBuilder.addNextValue(4, 3, 1);
  223. matrixBuilder.addNextValue(5, 3, 1);
  224. matrixBuilder.addNextValue(6, 7, 1);
  225. matrixBuilder.addNextValue(7, 8, 1);
  226. matrixBuilder.addNextValue(8, 6, 1);
  227. matrixBuilder.addNextValue(9, 10, 1);
  228. matrixBuilder.addNextValue(10, 9, 1);
  229. matrixBuilder.addNextValue(11, 9, 1);
  230. matrixBuilder.addNextValue(12, 5, 0.4);
  231. matrixBuilder.addNextValue(12, 8, 0.3);
  232. matrixBuilder.addNextValue(12, 11, 0.3);
  233. matrixBuilder.addNextValue(13, 7, 0.7);
  234. matrixBuilder.addNextValue(13, 12, 0.3);
  235. matrixBuilder.addNextValue(14, 12, 1);
  236. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  237. storm::models::sparse::StateLabeling ap(15);
  238. ap.addLabel("a");
  239. ap.addLabelToState("a", 1);
  240. ap.addLabelToState("a", 4);
  241. ap.addLabelToState("a", 5);
  242. ap.addLabelToState("a", 7);
  243. ap.addLabelToState("a", 11);
  244. ap.addLabelToState("a", 13);
  245. ap.addLabelToState("a", 14);
  246. dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
  247. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  248. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
  249. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  250. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  251. EXPECT_NEAR(0.3 / 3., quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  252. EXPECT_NEAR(0.0, quantitativeResult1[3], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  253. EXPECT_NEAR(1. / 3., quantitativeResult1[6], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  254. EXPECT_NEAR(0.0, quantitativeResult1[9], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  255. EXPECT_NEAR(0.3 / 3., quantitativeResult1[12], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  256. EXPECT_NEAR(.79 / 3., quantitativeResult1[13], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  257. EXPECT_NEAR(0.3 / 3., quantitativeResult1[14], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  258. }
  259. }
  260. TEST(EigenDtmcPrctlModelCheckerTest, Conditional) {
  261. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/test_conditional.pm");
  262. storm::generator::NextStateGeneratorOptions options;
  263. options.setBuildAllLabels().setBuildAllRewardModels();
  264. std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program, options).build();
  265. ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc);
  266. ASSERT_EQ(4ul, model->getNumberOfStates());
  267. ASSERT_EQ(5ul, model->getNumberOfTransitions());
  268. std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = model->as<storm::models::sparse::Dtmc<double>>();
  269. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::make_unique<storm::solver::EigenLinearEquationSolverFactory<double>>());
  270. // A parser that we use for conveniently constructing the formulas.
  271. storm::parser::FormulaParser formulaParser;
  272. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\"]");
  273. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
  274. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  275. EXPECT_NEAR(0.5, quantitativeResult1[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  276. formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"condition\"]");
  277. result = checker.check(*formula);
  278. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  279. EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult2[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  280. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\"]");
  281. result = checker.check(*formula);
  282. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  283. EXPECT_EQ(storm::utility::infinity<double>(), quantitativeResult3[0]);
  284. formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"condition\"]");
  285. result = checker.check(*formula);
  286. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  287. EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult4[0], storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
  288. }