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.

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