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.

528 lines
33 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/logic/Formulas.h"
  4. #include "src/utility/solver.h"
  5. #include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
  6. #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
  7. #include "src/settings/SettingsManager.h"
  8. #include "src/parser/AutoParser.h"
  9. TEST(SparseMdpPrctlModelCheckerTest, Dice) {
  10. std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
  11. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Mdp);
  12. std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
  13. ASSERT_EQ(mdp->getNumberOfStates(), 169ull);
  14. ASSERT_EQ(mdp->getNumberOfTransitions(), 436ull);
  15. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  16. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("two");
  17. auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
  18. auto minProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Minimize, eventuallyFormula);
  19. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*minProbabilityOperatorFormula);
  20. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  21. EXPECT_NEAR(0.0277777612209320068, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  22. auto maxProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Maximize, eventuallyFormula);
  23. result = checker.check(*maxProbabilityOperatorFormula);
  24. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  25. EXPECT_NEAR(0.0277777612209320068, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  26. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("three");
  27. eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
  28. minProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Minimize, eventuallyFormula);
  29. result = checker.check(*minProbabilityOperatorFormula);
  30. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  31. EXPECT_NEAR(0.0555555224418640136, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  32. maxProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Maximize, eventuallyFormula);
  33. result = checker.check(*maxProbabilityOperatorFormula);
  34. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  35. EXPECT_NEAR(0.0555555224418640136, quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  36. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("four");
  37. eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
  38. minProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Minimize, eventuallyFormula);
  39. result = checker.check(*minProbabilityOperatorFormula);
  40. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<double>();
  41. EXPECT_NEAR(0.083333283662796020508, quantitativeResult5[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  42. maxProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Maximize, eventuallyFormula);
  43. result = checker.check(*maxProbabilityOperatorFormula);
  44. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<double>();
  45. EXPECT_NEAR(0.083333283662796020508, quantitativeResult6[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  46. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("done");
  47. auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
  48. auto minRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Minimize, reachabilityRewardFormula);
  49. result = checker.check(*minRewardOperatorFormula);
  50. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult7 = result->asExplicitQuantitativeCheckResult<double>();
  51. EXPECT_NEAR(7.333329499, quantitativeResult7[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  52. auto maxRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Maximize, reachabilityRewardFormula);
  53. result = checker.check(*maxRewardOperatorFormula);
  54. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult8 = result->asExplicitQuantitativeCheckResult<double>();
  55. EXPECT_NEAR(7.333329499, quantitativeResult8[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  56. abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", "");
  57. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Mdp);
  58. std::shared_ptr<storm::models::sparse::Mdp<double>> stateRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
  59. storm::modelchecker::SparseMdpPrctlModelChecker<double> stateRewardModelChecker(*stateRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  60. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("done");
  61. reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
  62. minRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Minimize, reachabilityRewardFormula);
  63. result = stateRewardModelChecker.check(*minRewardOperatorFormula);
  64. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult9 = result->asExplicitQuantitativeCheckResult<double>();
  65. EXPECT_NEAR(7.333329499, quantitativeResult9[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  66. maxRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Maximize, reachabilityRewardFormula);
  67. result = stateRewardModelChecker.check(*maxRewardOperatorFormula);
  68. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult10 = result->asExplicitQuantitativeCheckResult<double>();
  69. EXPECT_NEAR(7.333329499, quantitativeResult10[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  70. abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
  71. ASSERT_EQ(abstractModel->getType(), storm::models::ModelType::Mdp);
  72. std::shared_ptr<storm::models::sparse::Mdp<double>> stateAndTransitionRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
  73. storm::modelchecker::SparseMdpPrctlModelChecker<double> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  74. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("done");
  75. reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
  76. minRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Minimize, reachabilityRewardFormula);
  77. result = stateAndTransitionRewardModelChecker.check(*minRewardOperatorFormula);
  78. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult11 = result->asExplicitQuantitativeCheckResult<double>();
  79. EXPECT_NEAR(14.666658998, quantitativeResult11[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  80. maxRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Maximize, reachabilityRewardFormula);
  81. result = stateAndTransitionRewardModelChecker.check(*maxRewardOperatorFormula);
  82. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult12 = result->asExplicitQuantitativeCheckResult<double>();
  83. EXPECT_NEAR(14.666658998, quantitativeResult12[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  84. }
  85. TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) {
  86. std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew");
  87. ASSERT_EQ(storm::models::ModelType::Mdp, abstractModel->getType());
  88. std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
  89. ASSERT_EQ(3172ull, mdp->getNumberOfStates());
  90. ASSERT_EQ(7144ull, mdp->getNumberOfTransitions());
  91. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  92. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
  93. auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula);
  94. auto minProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Minimize, eventuallyFormula);
  95. std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*minProbabilityOperatorFormula);
  96. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  97. EXPECT_NEAR(1, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  98. auto maxProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Maximize, eventuallyFormula);
  99. result = checker.check(*maxProbabilityOperatorFormula);
  100. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  101. EXPECT_NEAR(1, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  102. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
  103. auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
  104. auto boundedUntilFormula = std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, labelFormula, 25);
  105. minProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Minimize, boundedUntilFormula);
  106. result = checker.check(*minProbabilityOperatorFormula);
  107. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  108. EXPECT_NEAR(0.0625, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  109. maxProbabilityOperatorFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(storm::logic::OptimalityType::Maximize, boundedUntilFormula);
  110. result = checker.check(*maxProbabilityOperatorFormula);
  111. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  112. EXPECT_NEAR(0.0625, quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  113. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
  114. auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
  115. auto minRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Minimize, reachabilityRewardFormula);
  116. result = checker.check(*minRewardOperatorFormula);
  117. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<double>();
  118. EXPECT_NEAR(4.285689611, quantitativeResult5[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  119. auto maxRewardOperatorFormula = std::make_shared<storm::logic::RewardOperatorFormula>(storm::logic::OptimalityType::Maximize, reachabilityRewardFormula);
  120. result = checker.check(*maxRewardOperatorFormula);
  121. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<double>();
  122. EXPECT_NEAR(4.285689611, quantitativeResult6[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  123. }
  124. TEST(SparseMdpPrctlModelCheckerTest, LRA_SingleMec) {
  125. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  126. std::shared_ptr<storm::models::sparse::Mdp<double>> mdp;
  127. {
  128. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 2);
  129. matrixBuilder.addNextValue(0, 1, 1.);
  130. matrixBuilder.addNextValue(1, 0, 1.);
  131. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  132. storm::models::sparse::StateLabeling ap(2);
  133. ap.addLabel("a");
  134. ap.addLabelToState("a", 1);
  135. mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap, boost::none, boost::none, boost::none));
  136. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  137. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
  138. auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  139. std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
  140. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  141. EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  142. EXPECT_NEAR(.5, quantitativeResult1[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  143. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  144. result = std::move(checker.check(*lraFormula));
  145. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  146. EXPECT_NEAR(.5, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  147. EXPECT_NEAR(.5, quantitativeResult2[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  148. }
  149. {
  150. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(2, 2, 4);
  151. matrixBuilder.addNextValue(0, 0, .5);
  152. matrixBuilder.addNextValue(0, 1, .5);
  153. matrixBuilder.addNextValue(1, 0, .5);
  154. matrixBuilder.addNextValue(1, 1, .5);
  155. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  156. storm::models::sparse::StateLabeling ap(2);
  157. ap.addLabel("a");
  158. ap.addLabelToState("a", 1);
  159. mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap, boost::none, boost::none, boost::none));
  160. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  161. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
  162. auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  163. std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
  164. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  165. EXPECT_NEAR(.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  166. EXPECT_NEAR(.5, quantitativeResult1[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  167. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  168. result = std::move(checker.check(*lraFormula));
  169. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  170. EXPECT_NEAR(.5, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  171. EXPECT_NEAR(.5, quantitativeResult2[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  172. }
  173. {
  174. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(4, 3, 4, true, true, 3);
  175. matrixBuilder.newRowGroup(0);
  176. matrixBuilder.addNextValue(0, 1, 1);
  177. matrixBuilder.newRowGroup(1);
  178. matrixBuilder.addNextValue(1, 0, 1);
  179. matrixBuilder.addNextValue(2, 2, 1);
  180. matrixBuilder.newRowGroup(3);
  181. matrixBuilder.addNextValue(3, 0, 1);
  182. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  183. storm::models::sparse::StateLabeling ap(3);
  184. ap.addLabel("a");
  185. ap.addLabelToState("a", 2);
  186. ap.addLabel("b");
  187. ap.addLabelToState("b", 0);
  188. ap.addLabel("c");
  189. ap.addLabelToState("c", 0);
  190. ap.addLabelToState("c", 2);
  191. mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap, boost::none, boost::none, boost::none));
  192. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  193. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
  194. auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  195. std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
  196. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  197. EXPECT_NEAR(1. / 3., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  198. EXPECT_NEAR(1. / 3., quantitativeResult1[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  199. EXPECT_NEAR(1. / 3., quantitativeResult1[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  200. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  201. result = std::move(checker.check(*lraFormula));
  202. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  203. EXPECT_NEAR(0.0, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  204. EXPECT_NEAR(0.0, quantitativeResult2[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  205. EXPECT_NEAR(0.0, quantitativeResult2[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  206. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("b");
  207. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  208. result = std::move(checker.check(*lraFormula));
  209. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  210. EXPECT_NEAR(0.5, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  211. EXPECT_NEAR(0.5, quantitativeResult3[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  212. EXPECT_NEAR(0.5, quantitativeResult3[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  213. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  214. result = std::move(checker.check(*lraFormula));
  215. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  216. EXPECT_NEAR(1. / 3., quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  217. EXPECT_NEAR(1. / 3., quantitativeResult4[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  218. EXPECT_NEAR(1. / 3., quantitativeResult4[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  219. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("c");
  220. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  221. result = std::move(checker.check(*lraFormula));
  222. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<double>();
  223. EXPECT_NEAR(2. / 3., quantitativeResult5[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  224. EXPECT_NEAR(2. / 3., quantitativeResult5[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  225. EXPECT_NEAR(2. / 3., quantitativeResult5[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  226. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  227. result = std::move(checker.check(*lraFormula));
  228. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<double>();
  229. EXPECT_NEAR(0.5, quantitativeResult6[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  230. EXPECT_NEAR(0.5, quantitativeResult6[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  231. EXPECT_NEAR(0.5, quantitativeResult6[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  232. }
  233. }
  234. TEST(SparseMdpPrctlModelCheckerTest, LRA) {
  235. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  236. std::shared_ptr<storm::models::sparse::Mdp<double>> mdp;
  237. {
  238. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(4, 3, 4, true, true, 3);
  239. matrixBuilder.newRowGroup(0);
  240. matrixBuilder.addNextValue(0, 1, 1);
  241. matrixBuilder.newRowGroup(1);
  242. matrixBuilder.addNextValue(1, 1, 1);
  243. matrixBuilder.addNextValue(2, 2, 1);
  244. matrixBuilder.newRowGroup(3);
  245. matrixBuilder.addNextValue(3, 2, 1);
  246. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  247. storm::models::sparse::StateLabeling ap(3);
  248. ap.addLabel("a");
  249. ap.addLabelToState("a", 0);
  250. ap.addLabel("b");
  251. ap.addLabelToState("b", 1);
  252. ap.addLabel("c");
  253. ap.addLabelToState("c", 2);
  254. mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap, boost::none, boost::none, boost::none));
  255. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  256. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
  257. auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  258. std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
  259. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  260. EXPECT_NEAR(0.0, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  261. EXPECT_NEAR(0.0, quantitativeResult1[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  262. EXPECT_NEAR(0.0, quantitativeResult1[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  263. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  264. result = std::move(checker.check(*lraFormula));
  265. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  266. EXPECT_NEAR(0.0, quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  267. EXPECT_NEAR(0.0, quantitativeResult2[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  268. EXPECT_NEAR(0.0, quantitativeResult2[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  269. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("b");
  270. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  271. result = std::move(checker.check(*lraFormula));
  272. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
  273. EXPECT_NEAR(1.0, quantitativeResult3[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  274. EXPECT_NEAR(1.0, quantitativeResult3[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  275. EXPECT_NEAR(0.0, quantitativeResult3[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  276. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  277. result = std::move(checker.check(*lraFormula));
  278. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
  279. EXPECT_NEAR(0.0, quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  280. EXPECT_NEAR(0.0, quantitativeResult4[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  281. EXPECT_NEAR(0.0, quantitativeResult4[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  282. labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("c");
  283. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  284. result = std::move(checker.check(*lraFormula));
  285. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult5 = result->asExplicitQuantitativeCheckResult<double>();
  286. EXPECT_NEAR(1.0, quantitativeResult5[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  287. EXPECT_NEAR(1.0, quantitativeResult5[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  288. EXPECT_NEAR(1.0, quantitativeResult5[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  289. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  290. result = std::move(checker.check(*lraFormula));
  291. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult6 = result->asExplicitQuantitativeCheckResult<double>();
  292. EXPECT_NEAR(0.0, quantitativeResult6[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  293. EXPECT_NEAR(0.0, quantitativeResult6[1], storm::settings::nativeEquationSolverSettings().getPrecision());
  294. EXPECT_NEAR(1.0, quantitativeResult6[2], storm::settings::nativeEquationSolverSettings().getPrecision());
  295. }
  296. {
  297. matrixBuilder = storm::storage::SparseMatrixBuilder<double>(22, 15, 28, true, true, 15);
  298. matrixBuilder.newRowGroup(0);
  299. matrixBuilder.addNextValue(0, 1, 1);
  300. matrixBuilder.newRowGroup(1);
  301. matrixBuilder.addNextValue(1, 0, 1);
  302. matrixBuilder.addNextValue(2, 2, 1);
  303. matrixBuilder.addNextValue(3, 4, 0.7);
  304. matrixBuilder.addNextValue(3, 6, 0.3);
  305. matrixBuilder.newRowGroup(4);
  306. matrixBuilder.addNextValue(4, 0, 1);
  307. matrixBuilder.newRowGroup(5);
  308. matrixBuilder.addNextValue(5, 4, 1);
  309. matrixBuilder.addNextValue(6, 5, 0.8);
  310. matrixBuilder.addNextValue(6, 9, 0.2);
  311. matrixBuilder.newRowGroup(7);
  312. matrixBuilder.addNextValue(7, 3, 1);
  313. matrixBuilder.addNextValue(8, 5, 1);
  314. matrixBuilder.newRowGroup(9);
  315. matrixBuilder.addNextValue(9, 3, 1);
  316. matrixBuilder.newRowGroup(10);
  317. matrixBuilder.addNextValue(10, 7, 1);
  318. matrixBuilder.newRowGroup(11);
  319. matrixBuilder.addNextValue(11, 6, 1);
  320. matrixBuilder.addNextValue(12, 8, 1);
  321. matrixBuilder.newRowGroup(13);
  322. matrixBuilder.addNextValue(13, 6, 1);
  323. matrixBuilder.newRowGroup(14);
  324. matrixBuilder.addNextValue(14, 10, 1);
  325. matrixBuilder.newRowGroup(15);
  326. matrixBuilder.addNextValue(15, 9, 1);
  327. matrixBuilder.addNextValue(16, 11, 1);
  328. matrixBuilder.newRowGroup(17);
  329. matrixBuilder.addNextValue(17, 9, 1);
  330. matrixBuilder.newRowGroup(18);
  331. matrixBuilder.addNextValue(18, 5, 0.4);
  332. matrixBuilder.addNextValue(18, 8, 0.3);
  333. matrixBuilder.addNextValue(18, 11, 0.3);
  334. matrixBuilder.newRowGroup(19);
  335. matrixBuilder.addNextValue(19, 7, 0.7);
  336. matrixBuilder.addNextValue(19, 12, 0.3);
  337. matrixBuilder.newRowGroup(20);
  338. matrixBuilder.addNextValue(20, 12, 0.1);
  339. matrixBuilder.addNextValue(20, 13, 0.9);
  340. matrixBuilder.addNextValue(21, 12, 1);
  341. storm::storage::SparseMatrix<double> transitionMatrix = matrixBuilder.build();
  342. storm::models::sparse::StateLabeling ap(15);
  343. ap.addLabel("a");
  344. ap.addLabelToState("a", 1);
  345. ap.addLabelToState("a", 4);
  346. ap.addLabelToState("a", 5);
  347. ap.addLabelToState("a", 7);
  348. ap.addLabelToState("a", 11);
  349. ap.addLabelToState("a", 13);
  350. ap.addLabelToState("a", 14);
  351. mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap, boost::none, boost::none, boost::none));
  352. storm::modelchecker::SparseMdpPrctlModelChecker<double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
  353. auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("a");
  354. auto lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Maximize, labelFormula);
  355. std::unique_ptr<storm::modelchecker::CheckResult> result = std::move(checker.check(*lraFormula));
  356. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
  357. EXPECT_NEAR(37./60., quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  358. EXPECT_NEAR(2./3., quantitativeResult1[3], storm::settings::nativeEquationSolverSettings().getPrecision());
  359. EXPECT_NEAR(0.5, quantitativeResult1[6], storm::settings::nativeEquationSolverSettings().getPrecision());
  360. EXPECT_NEAR(1./3., quantitativeResult1[9], storm::settings::nativeEquationSolverSettings().getPrecision());
  361. EXPECT_NEAR(31./60., quantitativeResult1[12], storm::settings::nativeEquationSolverSettings().getPrecision());
  362. EXPECT_NEAR(101./200., quantitativeResult1[13], storm::settings::nativeEquationSolverSettings().getPrecision());
  363. EXPECT_NEAR(31./60., quantitativeResult1[14], storm::settings::nativeEquationSolverSettings().getPrecision());
  364. lraFormula = std::make_shared<storm::logic::LongRunAverageOperatorFormula>(storm::logic::OptimalityType::Minimize, labelFormula);
  365. result = std::move(checker.check(*lraFormula));
  366. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
  367. EXPECT_NEAR(0.3 / 3., quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
  368. EXPECT_NEAR(0.0, quantitativeResult2[3], storm::settings::nativeEquationSolverSettings().getPrecision());
  369. EXPECT_NEAR(1./3., quantitativeResult2[6], storm::settings::nativeEquationSolverSettings().getPrecision());
  370. EXPECT_NEAR(0.0, quantitativeResult2[9], storm::settings::nativeEquationSolverSettings().getPrecision());
  371. EXPECT_NEAR(0.3 / 3., quantitativeResult2[12], storm::settings::nativeEquationSolverSettings().getPrecision());
  372. EXPECT_NEAR(.79 / 3., quantitativeResult2[13], storm::settings::nativeEquationSolverSettings().getPrecision());
  373. EXPECT_NEAR(0.3 / 3., quantitativeResult2[14], storm::settings::nativeEquationSolverSettings().getPrecision());
  374. }
  375. }