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.

467 lines
25 KiB

  1. #include "test/storm_gtest.h"
  2. #include "test/storm_gtest.h"
  3. #include "storm-config.h"
  4. #include "storm/api/builder.h"
  5. #include "storm-conv/api/storm-conv.h"
  6. #include "storm-parsers/api/model_descriptions.h"
  7. #include "storm/api/properties.h"
  8. #include "storm-parsers/api/properties.h"
  9. #include "storm-parsers/parser/FormulaParser.h"
  10. #include "storm/logic/Formulas.h"
  11. #include "storm/solver/StandardMinMaxLinearEquationSolver.h"
  12. #include "storm/models/sparse/StandardRewardModel.h"
  13. #include "storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
  14. #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h"
  15. #include "storm/settings/SettingsManager.h"
  16. #include "storm/settings/modules/GeneralSettings.h"
  17. #include "storm/settings/modules/NativeEquationSolverSettings.h"
  18. #include "storm-parsers/parser/AutoParser.h"
  19. #include "storm/environment/solver/LongRunAverageSolverEnvironment.h"
  20. namespace {
  21. class SparseValueTypeValueIterationEnvironment {
  22. public:
  23. static const bool isExact = false;
  24. typedef double ValueType;
  25. typedef storm::models::sparse::Mdp<ValueType> ModelType;
  26. static storm::Environment createEnvironment() {
  27. storm::Environment env;
  28. env.solver().lra().setNondetLraMethod(storm::solver::LraMethod::ValueIteration);
  29. env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-10));
  30. return env;
  31. }
  32. };
  33. class SparseValueTypeLinearProgrammingEnvironment {
  34. public:
  35. static const bool isExact = false;
  36. typedef double ValueType;
  37. typedef storm::models::sparse::Mdp<ValueType> ModelType;
  38. static storm::Environment createEnvironment() {
  39. storm::Environment env;
  40. env.solver().lra().setNondetLraMethod(storm::solver::LraMethod::LinearProgramming);
  41. env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-10));
  42. return env;
  43. }
  44. };
  45. class SparseRationalLinearProgrammingEnvironment {
  46. public:
  47. static const bool isExact = true;
  48. typedef storm::RationalNumber ValueType;
  49. typedef storm::models::sparse::Mdp<ValueType> ModelType;
  50. static storm::Environment createEnvironment() {
  51. storm::Environment env;
  52. env.solver().lra().setNondetLraMethod(storm::solver::LraMethod::LinearProgramming);
  53. return env;
  54. }
  55. };
  56. template<typename TestType>
  57. class LraMdpPrctlModelCheckerTest : public ::testing::Test {
  58. public:
  59. typedef typename TestType::ValueType ValueType;
  60. typedef typename storm::models::sparse::Mdp<ValueType> SparseModelType;
  61. LraMdpPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
  62. storm::Environment const& env() const { return _environment; }
  63. ValueType parseNumber(std::string const& input) const { return storm::utility::convertNumber<ValueType>(input);}
  64. ValueType precision() const { return TestType::isExact ? parseNumber("0") : parseNumber("1e-6");}
  65. bool isSparseModel() const { return std::is_same<typename TestType::ModelType, SparseModelType>::value; }
  66. std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> buildModelFormulas(std::string const& pathToPrismFile, std::string const& formulasAsString, std::string const& constantDefinitionString = "") const {
  67. std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
  68. storm::prism::Program program = storm::api::parseProgram(pathToPrismFile);
  69. program = storm::utility::prism::preprocess(program, constantDefinitionString);
  70. result.second = storm::api::extractFormulasFromProperties(storm::api::parsePropertiesForPrismProgram(formulasAsString, program));
  71. result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<SparseModelType>();
  72. return result;
  73. }
  74. std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) const {
  75. std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
  76. for (auto const& f : formulas) {
  77. result.emplace_back(*f);
  78. }
  79. return result;
  80. }
  81. private:
  82. storm::Environment _environment;
  83. };
  84. typedef ::testing::Types<
  85. SparseValueTypeValueIterationEnvironment,
  86. SparseValueTypeLinearProgrammingEnvironment
  87. #ifdef STORM_HAVE_Z3_OPTIMIZE
  88. , SparseRationalLinearProgrammingEnvironment
  89. #endif
  90. > TestingTypes;
  91. TYPED_TEST_SUITE(LraMdpPrctlModelCheckerTest, TestingTypes,);
  92. TYPED_TEST(LraMdpPrctlModelCheckerTest, LRA_SingleMec) {
  93. typedef typename TestFixture::ValueType ValueType;
  94. storm::storage::SparseMatrixBuilder<ValueType> matrixBuilder;
  95. std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp;
  96. // A parser that we use for conveniently constructing the formulas.
  97. storm::parser::FormulaParser formulaParser;
  98. {
  99. matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(2, 2, 2);
  100. matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
  101. matrixBuilder.addNextValue(1, 0, this->parseNumber("1"));
  102. storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
  103. storm::models::sparse::StateLabeling ap(2);
  104. ap.addLabel("a");
  105. ap.addLabelToState("a", 1);
  106. mdp.reset(new storm::models::sparse::Mdp<ValueType>(transitionMatrix, ap));
  107. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  108. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
  109. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
  110. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<ValueType>();
  111. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[0], this->precision());
  112. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[1], this->precision());
  113. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"a\"]");
  114. result = checker.check(this->env(), *formula);
  115. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<ValueType>();
  116. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult2[0], this->precision());
  117. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult2[1], this->precision());
  118. }
  119. {
  120. matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(2, 2, 4);
  121. matrixBuilder.addNextValue(0, 0, this->parseNumber("0.5"));
  122. matrixBuilder.addNextValue(0, 1, this->parseNumber("0.5"));
  123. matrixBuilder.addNextValue(1, 0, this->parseNumber("0.5"));
  124. matrixBuilder.addNextValue(1, 1, this->parseNumber("0.5"));
  125. storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
  126. storm::models::sparse::StateLabeling ap(2);
  127. ap.addLabel("a");
  128. ap.addLabelToState("a", 1);
  129. mdp.reset(new storm::models::sparse::Mdp<ValueType>(transitionMatrix, ap));
  130. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  131. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
  132. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
  133. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<ValueType>();
  134. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[0], this->precision());
  135. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[1], this->precision());
  136. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"a\"]");
  137. result = checker.check(this->env(), *formula);
  138. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<ValueType>();
  139. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult2[0], this->precision());
  140. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult2[1], this->precision());
  141. }
  142. {
  143. matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(4, 3, 4, true, true, 3);
  144. matrixBuilder.newRowGroup(0);
  145. matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
  146. matrixBuilder.newRowGroup(1);
  147. matrixBuilder.addNextValue(1, 0, this->parseNumber("1"));
  148. matrixBuilder.addNextValue(2, 2, this->parseNumber("1"));
  149. matrixBuilder.newRowGroup(3);
  150. matrixBuilder.addNextValue(3, 0, this->parseNumber("1"));
  151. storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
  152. storm::models::sparse::StateLabeling ap(3);
  153. ap.addLabel("a");
  154. ap.addLabelToState("a", 2);
  155. ap.addLabel("b");
  156. ap.addLabelToState("b", 0);
  157. ap.addLabel("c");
  158. ap.addLabelToState("c", 0);
  159. ap.addLabelToState("c", 2);
  160. mdp.reset(new storm::models::sparse::Mdp<ValueType>(transitionMatrix, ap));
  161. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  162. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
  163. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
  164. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<ValueType>();
  165. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[0], this->precision());
  166. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[1], this->precision());
  167. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[2], this->precision());
  168. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"a\"]");
  169. result = checker.check(this->env(), *formula);
  170. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<ValueType>();
  171. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[0], this->precision());
  172. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[1], this->precision());
  173. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[2], this->precision());
  174. formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"b\"]");
  175. result = checker.check(this->env(), *formula);
  176. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<ValueType>();
  177. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult3[0], this->precision());
  178. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult3[1], this->precision());
  179. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult3[2], this->precision());
  180. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"b\"]");
  181. result = checker.check(this->env(), *formula);
  182. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<ValueType>();
  183. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult4[0], this->precision());
  184. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult4[1], this->precision());
  185. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult4[2], this->precision());
  186. formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"c\"]");
  187. result = checker.check(this->env(), *formula);
  188. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<ValueType>();
  189. EXPECT_NEAR(this->parseNumber("2/3"), quantitativeResult5[0], this->precision());
  190. EXPECT_NEAR(this->parseNumber("2/3"), quantitativeResult5[1], this->precision());
  191. EXPECT_NEAR(this->parseNumber("2/3"), quantitativeResult5[2], this->precision());
  192. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"c\"]");
  193. result = checker.check(this->env(), *formula);
  194. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<ValueType>();
  195. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult6[0], this->precision());
  196. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult6[1], this->precision());
  197. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult6[2], this->precision());
  198. }
  199. }
  200. TYPED_TEST(LraMdpPrctlModelCheckerTest, LRA) {
  201. typedef typename TestFixture::ValueType ValueType;
  202. storm::storage::SparseMatrixBuilder<ValueType> matrixBuilder;
  203. std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp;
  204. // A parser that we use for conveniently constructing the formulas.
  205. storm::parser::FormulaParser formulaParser;
  206. {
  207. matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(4, 3, 4, true, true, 3);
  208. matrixBuilder.newRowGroup(0);
  209. matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
  210. matrixBuilder.newRowGroup(1);
  211. matrixBuilder.addNextValue(1, 1, this->parseNumber("1"));
  212. matrixBuilder.addNextValue(2, 2, this->parseNumber("1"));
  213. matrixBuilder.newRowGroup(3);
  214. matrixBuilder.addNextValue(3, 2, this->parseNumber("1"));
  215. storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
  216. storm::models::sparse::StateLabeling ap(3);
  217. ap.addLabel("a");
  218. ap.addLabelToState("a", 0);
  219. ap.addLabel("b");
  220. ap.addLabelToState("b", 1);
  221. ap.addLabel("c");
  222. ap.addLabelToState("c", 2);
  223. mdp.reset(new storm::models::sparse::Mdp<ValueType>(transitionMatrix, ap));
  224. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  225. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
  226. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
  227. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<ValueType>();
  228. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult1[0], this->precision());
  229. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult1[1], this->precision());
  230. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult1[2], this->precision());
  231. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"a\"]");
  232. result = checker.check(this->env(), *formula);
  233. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<ValueType>();
  234. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[0], this->precision());
  235. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[1], this->precision());
  236. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[2], this->precision());
  237. formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"b\"]");
  238. result = checker.check(this->env(), *formula);
  239. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<ValueType>();
  240. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult3[0], this->precision());
  241. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult3[1], this->precision());
  242. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult3[2], this->precision());
  243. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"b\"]");
  244. result = checker.check(this->env(), *formula);
  245. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<ValueType>();
  246. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult4[0], this->precision());
  247. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult4[1], this->precision());
  248. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult4[2], this->precision());
  249. formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"c\"]");
  250. result = checker.check(this->env(), *formula);
  251. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<ValueType>();
  252. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult5[0], this->precision());
  253. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult5[1], this->precision());
  254. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult5[2], this->precision());
  255. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"c\"]");
  256. result = checker.check(this->env(), *formula);
  257. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<ValueType>();
  258. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult6[0], this->precision());
  259. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult6[1], this->precision());
  260. EXPECT_NEAR(this->parseNumber("1"), quantitativeResult6[2], this->precision());
  261. }
  262. {
  263. matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(22, 15, 28, true, true, 15);
  264. matrixBuilder.newRowGroup(0);
  265. matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
  266. matrixBuilder.newRowGroup(1);
  267. matrixBuilder.addNextValue(1, 0, this->parseNumber("1"));
  268. matrixBuilder.addNextValue(2, 2, this->parseNumber("1"));
  269. matrixBuilder.addNextValue(3, 4, this->parseNumber("0.7"));
  270. matrixBuilder.addNextValue(3, 6, this->parseNumber("0.3"));
  271. matrixBuilder.newRowGroup(4);
  272. matrixBuilder.addNextValue(4, 0, this->parseNumber("1"));
  273. matrixBuilder.newRowGroup(5);
  274. matrixBuilder.addNextValue(5, 4, this->parseNumber("1"));
  275. matrixBuilder.addNextValue(6, 5, this->parseNumber("0.8"));
  276. matrixBuilder.addNextValue(6, 9, this->parseNumber("0.2"));
  277. matrixBuilder.newRowGroup(7);
  278. matrixBuilder.addNextValue(7, 3, this->parseNumber("1"));
  279. matrixBuilder.addNextValue(8, 5, this->parseNumber("1"));
  280. matrixBuilder.newRowGroup(9);
  281. matrixBuilder.addNextValue(9, 3, this->parseNumber("1"));
  282. matrixBuilder.newRowGroup(10);
  283. matrixBuilder.addNextValue(10, 7, this->parseNumber("1"));
  284. matrixBuilder.newRowGroup(11);
  285. matrixBuilder.addNextValue(11, 6, this->parseNumber("1"));
  286. matrixBuilder.addNextValue(12, 8, this->parseNumber("1"));
  287. matrixBuilder.newRowGroup(13);
  288. matrixBuilder.addNextValue(13, 6, this->parseNumber("1"));
  289. matrixBuilder.newRowGroup(14);
  290. matrixBuilder.addNextValue(14, 10, this->parseNumber("1"));
  291. matrixBuilder.newRowGroup(15);
  292. matrixBuilder.addNextValue(15, 9, this->parseNumber("1"));
  293. matrixBuilder.addNextValue(16, 11, this->parseNumber("1"));
  294. matrixBuilder.newRowGroup(17);
  295. matrixBuilder.addNextValue(17, 9, this->parseNumber("1"));
  296. matrixBuilder.newRowGroup(18);
  297. matrixBuilder.addNextValue(18, 5, this->parseNumber("0.4"));
  298. matrixBuilder.addNextValue(18, 8, this->parseNumber("0.3"));
  299. matrixBuilder.addNextValue(18, 11, this->parseNumber("0.3"));
  300. matrixBuilder.newRowGroup(19);
  301. matrixBuilder.addNextValue(19, 7, this->parseNumber("0.7"));
  302. matrixBuilder.addNextValue(19, 12, this->parseNumber("0.3"));
  303. matrixBuilder.newRowGroup(20);
  304. matrixBuilder.addNextValue(20, 12, this->parseNumber("0.1"));
  305. matrixBuilder.addNextValue(20, 13, this->parseNumber("0.9"));
  306. matrixBuilder.addNextValue(21, 12, this->parseNumber("1"));
  307. storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
  308. storm::models::sparse::StateLabeling ap(15);
  309. ap.addLabel("a");
  310. ap.addLabelToState("a", 1);
  311. ap.addLabelToState("a", 4);
  312. ap.addLabelToState("a", 5);
  313. ap.addLabelToState("a", 7);
  314. ap.addLabelToState("a", 11);
  315. ap.addLabelToState("a", 13);
  316. ap.addLabelToState("a", 14);
  317. mdp.reset(new storm::models::sparse::Mdp<ValueType>(transitionMatrix, ap));
  318. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  319. std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
  320. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
  321. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<ValueType>();
  322. EXPECT_NEAR(this->parseNumber("37 / 60"), quantitativeResult1[0], this->precision());
  323. EXPECT_NEAR(this->parseNumber("2/3"), quantitativeResult1[3], this->precision());
  324. EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[6], this->precision());
  325. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[9], this->precision());
  326. EXPECT_NEAR(this->parseNumber("31 / 60"), quantitativeResult1[12], this->precision());
  327. EXPECT_NEAR(this->parseNumber("101 / 200"), quantitativeResult1[13], this->precision());
  328. EXPECT_NEAR(this->parseNumber("31 / 60"), quantitativeResult1[14], this->precision());
  329. formula = formulaParser.parseSingleFormulaFromString("LRAmin=? [\"a\"]");
  330. result = checker.check(this->env(), *formula);
  331. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<ValueType>();
  332. EXPECT_NEAR(this->parseNumber("0.1"), quantitativeResult2[0], this->precision());
  333. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[3], this->precision());
  334. EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult2[6], this->precision());
  335. EXPECT_NEAR(this->parseNumber("0"), quantitativeResult2[9], this->precision());
  336. EXPECT_NEAR(this->parseNumber("0.1"), quantitativeResult2[12], this->precision());
  337. EXPECT_NEAR(this->parseNumber("79 / 300"), quantitativeResult2[13], this->precision());
  338. EXPECT_NEAR(this->parseNumber("0.1"), quantitativeResult2[14], this->precision());
  339. }
  340. }
  341. TYPED_TEST(LraMdpPrctlModelCheckerTest, cs_nfail) {
  342. typedef typename TestFixture::ValueType ValueType;
  343. std::string formulasString = "R{\"grants\"}max=? [ MP ]";
  344. auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR "/mdp/cs_nfail3.nm", formulasString);
  345. auto model = std::move(modelFormulas.first);
  346. auto tasks = this->getTasks(modelFormulas.second);
  347. EXPECT_EQ(184ul, model->getNumberOfStates());
  348. EXPECT_EQ(541ul, model->getNumberOfTransitions());
  349. ASSERT_EQ(model->getType(), storm::models::ModelType::Mdp);
  350. auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
  351. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  352. std::unique_ptr<storm::modelchecker::CheckResult> result;
  353. result = checker.check(this->env(), tasks[0]);
  354. storm::modelchecker::ExplicitQuantitativeCheckResult<ValueType>& quantitativeResult = result->asExplicitQuantitativeCheckResult<ValueType>();
  355. EXPECT_NEAR(this->parseNumber("333/1000"), quantitativeResult[*mdp->getInitialStates().begin()], this->precision());
  356. }
  357. }