1#include "storm-config.h"
30enum class MdpEngine { PrismSparse, JaniSparse,
Hybrid, PrismDd, JaniDd };
32class SparseDoubleValueIterationViOpGaussSeidelMultEnvironment {
35 static const MdpEngine engine = MdpEngine::PrismSparse;
36 static const bool isExact =
false;
49class SparseDoubleValueIterationViOpRegularMultEnvironment {
52 static const MdpEngine engine = MdpEngine::PrismSparse;
53 static const bool isExact =
false;
66class SparseDoubleValueIterationNativeGaussSeidelMultEnvironment {
69 static const MdpEngine engine = MdpEngine::PrismSparse;
70 static const bool isExact =
false;
83class SparseDoubleValueIterationNativeRegularMultEnvironment {
86 static const MdpEngine engine = MdpEngine::PrismSparse;
87 static const bool isExact =
false;
100class JaniSparseDoubleValueIterationEnvironment {
103 static const MdpEngine engine = MdpEngine::JaniSparse;
104 static const bool isExact =
false;
115class SparseDoubleIntervalIterationEnvironment {
118 static const MdpEngine engine = MdpEngine::PrismSparse;
119 static const bool isExact =
false;
132class SparseDoubleSoundValueIterationEnvironment {
135 static const MdpEngine engine = MdpEngine::PrismSparse;
136 static const bool isExact =
false;
149class SparseDoubleOptimisticValueIterationEnvironment {
152 static const MdpEngine engine = MdpEngine::PrismSparse;
153 static const bool isExact =
false;
166class SparseDoubleGuessingValueIterationEnvironment {
169 static const MdpEngine engine = MdpEngine::PrismSparse;
170 static const bool isExact =
false;
183class SparseDoubleTopologicalValueIterationEnvironment {
186 static const MdpEngine engine = MdpEngine::PrismSparse;
187 static const bool isExact =
false;
200class SparseDoubleTopologicalSoundValueIterationEnvironment {
203 static const MdpEngine engine = MdpEngine::PrismSparse;
204 static const bool isExact =
false;
218class SparseDoubleTopologicalGuessingValueIterationEnvironment {
221 static const MdpEngine engine = MdpEngine::PrismSparse;
222 static const bool isExact =
false;
236class SparseDoubleLPEnvironment {
239 static const MdpEngine engine = MdpEngine::PrismSparse;
240 static const bool isExact =
false;
251class SparseDoubleViToLPEnvironment {
254 static const MdpEngine engine = MdpEngine::PrismSparse;
255 static const bool isExact =
false;
266class SparseRationalPolicyIterationEnvironment {
269 static const MdpEngine engine = MdpEngine::PrismSparse;
270 static const bool isExact =
true;
280class SparseRationalViToPiEnvironment {
283 static const MdpEngine engine = MdpEngine::PrismSparse;
284 static const bool isExact =
true;
294class SparseRationalRationalSearchEnvironment {
297 static const MdpEngine engine = MdpEngine::PrismSparse;
298 static const bool isExact =
true;
307class HybridCuddDoubleValueIterationEnvironment {
310 static const MdpEngine engine = MdpEngine::Hybrid;
311 static const bool isExact =
false;
315 static void checkLibraryAvailable() {
316#ifndef STORM_HAVE_CUDD
317 GTEST_SKIP() <<
"Library CUDD not available.";
328class HybridSylvanDoubleValueIterationEnvironment {
331 static const MdpEngine engine = MdpEngine::Hybrid;
332 static const bool isExact =
false;
336 static void checkLibraryAvailable() {
337#ifndef STORM_HAVE_SYLVAN
338 GTEST_SKIP() <<
"Library Sylvan not available.";
349class HybridCuddDoubleSoundValueIterationEnvironment {
352 static const MdpEngine engine = MdpEngine::Hybrid;
353 static const bool isExact =
false;
357 static void checkLibraryAvailable() {
358#ifndef STORM_HAVE_CUDD
359 GTEST_SKIP() <<
"Library CUDD not available.";
372class HybridCuddDoubleOptimisticValueIterationEnvironment {
375 static const MdpEngine engine = MdpEngine::Hybrid;
376 static const bool isExact =
false;
380 static void checkLibraryAvailable() {
381#ifndef STORM_HAVE_CUDD
382 GTEST_SKIP() <<
"Library CUDD not available.";
395class HybridCuddDoubleGuessingValueIterationEnvironment {
398 static const MdpEngine engine = MdpEngine::Hybrid;
399 static const bool isExact =
false;
403 static void checkLibraryAvailable() {
404#ifndef STORM_HAVE_CUDD
405 GTEST_SKIP() <<
"Library CUDD not available.";
418class HybridSylvanRationalPolicyIterationEnvironment {
421 static const MdpEngine engine = MdpEngine::Hybrid;
422 static const bool isExact =
true;
426 static void checkLibraryAvailable() {
427#ifndef STORM_HAVE_SYLVAN
428 GTEST_SKIP() <<
"Library Sylvan not available.";
438class DdCuddDoubleValueIterationEnvironment {
441 static const MdpEngine engine = MdpEngine::PrismDd;
442 static const bool isExact =
false;
446 static void checkLibraryAvailable() {
447#ifndef STORM_HAVE_CUDD
448 GTEST_SKIP() <<
"Library CUDD not available.";
459class JaniDdCuddDoubleValueIterationEnvironment {
462 static const MdpEngine engine = MdpEngine::JaniDd;
463 static const bool isExact =
false;
467 static void checkLibraryAvailable() {
468#ifndef STORM_HAVE_CUDD
469 GTEST_SKIP() <<
"Library CUDD not available.";
480class DdSylvanDoubleValueIterationEnvironment {
483 static const MdpEngine engine = MdpEngine::PrismDd;
484 static const bool isExact =
false;
488 static void checkLibraryAvailable() {
489#ifndef STORM_HAVE_SYLVAN
490 GTEST_SKIP() <<
"Library Sylvan not available.";
501class DdCuddDoublePolicyIterationEnvironment {
504 static const MdpEngine engine = MdpEngine::PrismDd;
505 static const bool isExact =
false;
509 static void checkLibraryAvailable() {
510#ifndef STORM_HAVE_CUDD
511 GTEST_SKIP() <<
"Library CUDD not available.";
522class DdSylvanRationalRationalSearchEnvironment {
525 static const MdpEngine engine = MdpEngine::PrismDd;
526 static const bool isExact =
true;
530 static void checkLibraryAvailable() {
531#ifndef STORM_HAVE_SYLVAN
532 GTEST_SKIP() <<
"Library Sylvan not available.";
543template<
typename TestType>
544class MdpPrctlModelCheckerTest :
public ::testing::Test {
546 typedef typename TestType::ValueType
ValueType;
550 MdpPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
552 void SetUp()
override {
554 GTEST_SKIP() <<
"Z3 not available.";
556 if constexpr (TestType::engine == MdpEngine::Hybrid || TestType::engine == MdpEngine::PrismDd || TestType::engine == MdpEngine::JaniDd) {
557 TestType::checkLibraryAvailable();
565 return storm::utility::convertNumber<ValueType>(input);
570 bool isSparseModel()
const {
571 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
573 bool isSymbolicModel()
const {
574 return std::is_same<typename TestType::ModelType, SymbolicModelType>::value;
577 template<
typename MT =
typename TestType::ModelType>
578 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
579 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
580 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
581 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
584 if (TestType::engine == MdpEngine::PrismSparse) {
586 result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<MT>();
587 }
else if (TestType::engine == MdpEngine::JaniSparse) {
589 janiData.first.substituteFunctions();
591 result.first = storm::api::buildSparseModel<ValueType>(janiData.first, result.second)->template as<MT>();
596 template<
typename MT =
typename TestType::ModelType>
597 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
598 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
599 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
600 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
603 if (TestType::engine == MdpEngine::Hybrid || TestType::engine == MdpEngine::PrismDd) {
605 result.first = storm::api::buildSymbolicModel<TestType::ddType, ValueType>(program, result.second)->template as<MT>();
606 }
else if (TestType::engine == MdpEngine::JaniDd) {
608 janiData.first.substituteFunctions();
610 result.first = storm::api::buildSymbolicModel<TestType::ddType, ValueType>(janiData.first, result.second)->template as<MT>();
615 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
616 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
617 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
618 for (
auto const& f : formulas) {
619 result.emplace_back(*f);
624 template<
typename MT =
typename TestType::ModelType>
625 typename std::enable_if<std::is_same<MT, SparseModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type createModelChecker(
626 std::shared_ptr<MT>
const& model)
const {
627 if (TestType::engine == MdpEngine::PrismSparse || TestType::engine == MdpEngine::JaniSparse) {
628 return std::make_shared<storm::modelchecker::SparseMdpPrctlModelChecker<SparseModelType>>(*model);
632 template<
typename MT =
typename TestType::ModelType>
633 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type
634 createModelChecker(std::shared_ptr<MT>
const& model)
const {
635 if (TestType::engine == MdpEngine::Hybrid) {
636 return std::make_shared<storm::modelchecker::HybridMdpPrctlModelChecker<SymbolicModelType>>(*model);
637 }
else if (TestType::engine == MdpEngine::PrismDd || TestType::engine == MdpEngine::JaniDd) {
638 return std::make_shared<storm::modelchecker::SymbolicMdpPrctlModelChecker<SymbolicModelType>>(*model);
642 template<
typename MT =
typename TestType::ModelType>
643 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
644 std::function<
void()>
const& f)
const {
648 template<
typename MT =
typename TestType::ModelType>
649 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
650 std::function<
void()>
const& f)
const {
651 model->getManager().execute(f);
655 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
657 result->filter(*filter);
658 return result->asQualitativeCheckResult().forallTrue();
662 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
664 result->filter(*filter);
665 return result->asQuantitativeCheckResult<
ValueType>().getMin();
672 if (isSparseModel()) {
673 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->template as<SparseModelType>()->getInitialStates());
675 return std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<TestType::ddType>>(
676 model->template as<SymbolicModelType>()->getReachableStates(), model->template as<SymbolicModelType>()->getInitialStates());
681typedef ::testing::Types<SparseDoubleValueIterationViOpGaussSeidelMultEnvironment, SparseDoubleValueIterationViOpRegularMultEnvironment,
682 SparseDoubleValueIterationNativeGaussSeidelMultEnvironment, SparseDoubleValueIterationNativeRegularMultEnvironment,
683 JaniSparseDoubleValueIterationEnvironment, SparseDoubleIntervalIterationEnvironment, SparseDoubleSoundValueIterationEnvironment,
684 SparseDoubleOptimisticValueIterationEnvironment, SparseDoubleGuessingValueIterationEnvironment,
685 SparseDoubleTopologicalValueIterationEnvironment, SparseDoubleTopologicalSoundValueIterationEnvironment,
686 SparseDoubleTopologicalGuessingValueIterationEnvironment, SparseDoubleLPEnvironment, SparseDoubleViToLPEnvironment,
687 SparseRationalPolicyIterationEnvironment, SparseRationalViToPiEnvironment, SparseRationalRationalSearchEnvironment,
688 HybridCuddDoubleValueIterationEnvironment, HybridSylvanDoubleValueIterationEnvironment, HybridCuddDoubleSoundValueIterationEnvironment,
689 HybridCuddDoubleOptimisticValueIterationEnvironment, HybridCuddDoubleGuessingValueIterationEnvironment,
690 HybridSylvanRationalPolicyIterationEnvironment, DdCuddDoubleValueIterationEnvironment, JaniDdCuddDoubleValueIterationEnvironment,
691 DdSylvanDoubleValueIterationEnvironment, DdCuddDoublePolicyIterationEnvironment, DdSylvanRationalRationalSearchEnvironment>
697 std::string formulasString =
"Pmin=? [F \"two\"]";
698 formulasString +=
"; Pmax=? [F \"two\"]";
699 formulasString +=
"; Pmin=? [F \"three\"]";
700 formulasString +=
"; Pmax=? [F \"three\"]";
701 formulasString +=
"; Pmin=? [F \"four\"]";
702 formulasString +=
"; Pmax=? [F \"four\"]";
703 formulasString +=
"; Rmin=? [F \"done\"]";
704 formulasString +=
"; Rmax=? [F \"done\"]";
706 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/two_dice.nm", formulasString);
707 auto model = std::move(modelFormulas.first);
708 auto tasks = this->getTasks(modelFormulas.second);
709 this->execute(model, [&]() {
710 EXPECT_EQ(169ul, model->getNumberOfStates());
711 EXPECT_EQ(436ul, model->getNumberOfTransitions());
714 auto checker = this->createModelChecker(model);
715 std::unique_ptr<storm::modelchecker::CheckResult> result;
717 result = checker->check(this->env(), tasks[0]);
720 result = checker->check(this->env(), tasks[1]);
723 result = checker->check(this->env(), tasks[2]);
726 result = checker->check(this->env(), tasks[3]);
729 result = checker->check(this->env(), tasks[4]);
732 result = checker->check(this->env(), tasks[5]);
735 result = checker->check(this->env(), tasks[6]);
738 result = checker->check(this->env(), tasks[7]);
743TYPED_TEST(MdpPrctlModelCheckerTest, AsynchronousLeader) {
744 std::string formulasString =
"Pmin=? [F \"elected\"]";
745 formulasString +=
"; Pmax=? [F \"elected\"]";
746 formulasString +=
"; Pmin=? [F<=25 \"elected\"]";
747 formulasString +=
"; Pmax=? [F<=25 \"elected\"]";
748 formulasString +=
"; Rmin=? [F \"elected\"]";
749 formulasString +=
"; Rmax=? [F \"elected\"]";
751 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/leader4.nm", formulasString);
752 auto model = std::move(modelFormulas.first);
753 auto tasks = this->getTasks(modelFormulas.second);
754 this->execute(model, [&]() {
755 EXPECT_EQ(3172ul, model->getNumberOfStates());
756 EXPECT_EQ(7144ul, model->getNumberOfTransitions());
758 auto checker = this->createModelChecker(model);
759 std::unique_ptr<storm::modelchecker::CheckResult> result;
761 result = checker->check(this->env(), tasks[0]);
764 result = checker->check(this->env(), tasks[1]);
767 result = checker->check(this->env(), tasks[2]);
770 result = checker->check(this->env(), tasks[3]);
773 result = checker->check(this->env(), tasks[4]);
776 result = checker->check(this->env(), tasks[5]);
781TYPED_TEST(MdpPrctlModelCheckerTest, consensus) {
782 std::string formulasString =
"Pmax=? [F \"finished\"]";
783 formulasString +=
"; Pmax=? [F \"all_coins_equal_1\"]";
784 formulasString +=
"; P<0.8 [F \"all_coins_equal_1\"]";
785 formulasString +=
"; P<0.9 [F \"all_coins_equal_1\"]";
786 formulasString +=
"; Rmax=? [F \"all_coins_equal_1\"]";
787 formulasString +=
"; Rmin=? [F \"all_coins_equal_1\"]";
788 formulasString +=
"; Rmax=? [F \"finished\"]";
789 formulasString +=
"; Rmin=? [F \"finished\"]";
791 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/coin2-2.nm", formulasString);
792 auto model = std::move(modelFormulas.first);
793 auto tasks = this->getTasks(modelFormulas.second);
794 this->execute(model, [&]() {
795 EXPECT_EQ(272ul, model->getNumberOfStates());
796 EXPECT_EQ(492ul, model->getNumberOfTransitions());
798 auto checker = this->createModelChecker(model);
799 std::unique_ptr<storm::modelchecker::CheckResult> result;
801 result = checker->check(this->env(), tasks[0]);
804 result = checker->check(this->env(), tasks[1]);
807 result = checker->check(this->env(), tasks[2]);
808 EXPECT_FALSE(this->getQualitativeResultAtInitialState(model, result));
810 result = checker->check(this->env(), tasks[3]);
811 EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
813 result = checker->check(this->env(), tasks[4]);
816 result = checker->check(this->env(), tasks[5]);
819 result = checker->check(this->env(), tasks[6]);
822 result = checker->check(this->env(), tasks[7]);
827TYPED_TEST(MdpPrctlModelCheckerTest, TinyRewards) {
828 std::string formulasString =
"Rmin=? [F \"target\"]";
829 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/tiny_rewards.nm", formulasString);
830 auto model = std::move(modelFormulas.first);
831 auto tasks = this->getTasks(modelFormulas.second);
832 this->execute(model, [&]() {
833 EXPECT_EQ(3ul, model->getNumberOfStates());
834 EXPECT_EQ(4ul, model->getNumberOfTransitions());
836 auto checker = this->createModelChecker(model);
837 std::unique_ptr<storm::modelchecker::CheckResult> result;
842 if (TypeParam::engine == MdpEngine::PrismDd && this->env().solver().minMax().getMethod() == storm::solver::MinMaxMethod::RationalSearch) {
845 result = checker->check(this->env(), tasks[0]);
852 std::string formulasString =
"R{\"w_1_total\"}max=? [ C ]";
853 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_team3.nm", formulasString);
854 auto model = std::move(modelFormulas.first);
855 auto tasks = this->getTasks(modelFormulas.second);
856 this->execute(model, [&]() {
857 EXPECT_EQ(12475ul, model->getNumberOfStates());
858 EXPECT_EQ(15228ul, model->getNumberOfTransitions());
860 auto checker = this->createModelChecker(model);
861 std::unique_ptr<storm::modelchecker::CheckResult> result;
865 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
866 result = checker->check(this->env(), tasks[0]);
869 EXPECT_FALSE(checker->canHandle(tasks[0]));
874TYPED_TEST(MdpPrctlModelCheckerTest, LtlProbabilitiesCoin) {
875#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
876 std::string formulasString =
"Pmin=? [!(GF \"all_coins_equal_1\")]";
877 formulasString +=
"; Pmax=? [F \"all_coins_equal_1\" U \"finished\"]";
878 formulasString +=
"; P>0.4 [!(GF \"all_coins_equal_1\")]";
879 formulasString +=
"; P<0.6 [F \"all_coins_equal_1\" U \"finished\"]";
881 formulasString +=
"; Pmax=?[ (GF \"all_coins_equal_1\") & ((GF \"all_coins_equal_0\") | (FG \"finished\"))]";
883 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/coin2-2.nm", formulasString);
884 auto model = std::move(modelFormulas.first);
885 auto tasks = this->getTasks(modelFormulas.second);
886 this->execute(model, [&]() {
887 EXPECT_EQ(272ul, model->getNumberOfStates());
888 EXPECT_EQ(492ul, model->getNumberOfTransitions());
890 auto checker = this->createModelChecker(model);
891 std::unique_ptr<storm::modelchecker::CheckResult> result;
894 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
895 result = checker->check(this->env(), tasks[0]);
898 result = checker->check(this->env(), tasks[1]);
901 result = checker->check(this->env(), tasks[2]);
902 EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
904 result = checker->check(this->env(), tasks[3]);
905 EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
907 result = checker->check(this->env(), tasks[4]);
911 EXPECT_FALSE(checker->canHandle(tasks[0]));
919TYPED_TEST(MdpPrctlModelCheckerTest, LtlDice) {
920#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
921 std::string formulasString =
"Pmax=? [ X (((s1=1) U (s1=3)) U (s1=7))]";
922 formulasString +=
"; Pmax=? [ (F (X (s1=6 & (XX s1=5)))) & (F G (d1!=5))]";
923 formulasString +=
"; Pmax=? [ F s1=3 U (\"three\")]";
924 formulasString +=
"; Pmin=? [! F (s2=6) & X \"done\"]";
926 formulasString +=
"; Pmax=? [ ( (G F !(\"two\")) | F G (\"three\") ) & ( (G F !(\"five\") ) | F G (\"seven\") )]";
928 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/two_dice.nm", formulasString);
929 auto model = std::move(modelFormulas.first);
930 auto tasks = this->getTasks(modelFormulas.second);
931 this->execute(model, [&]() {
932 EXPECT_EQ(169ul, model->getNumberOfStates());
933 EXPECT_EQ(436ul, model->getNumberOfTransitions());
935 auto checker = this->createModelChecker(model);
936 std::unique_ptr<storm::modelchecker::CheckResult> result;
939 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
940 result = checker->check(this->env(), tasks[0]);
943 result = checker->check(this->env(), tasks[1]);
946 result = checker->check(this->env(), tasks[2]);
949 result = checker->check(this->env(), tasks[3]);
952 result = checker->check(this->env(), tasks[4]);
956 EXPECT_FALSE(checker->canHandle(tasks[0]));
964TYPED_TEST(MdpPrctlModelCheckerTest, LtlCoinFlips) {
965#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
966 std::string formulasString =
"Pmax=? [ G (true U (heads | \"done\")) ]";
967 formulasString +=
"; Pmin=? [ G (true U (heads | \"done\")) ]";
968 formulasString +=
"; Pmax=? [ G (true U<=10 (heads | \"done\")) ]";
969 formulasString +=
"; Pmin=? [ G (true U<=10 (heads | \"done\")) ]";
970 formulasString +=
"; Pmax=? [ X G (true U<=0 (heads | \"done\")) ]";
971 formulasString +=
"; Pmax=? [ true U[10,12] heads ]";
972 formulasString +=
"; Pmax=? [ X (true U[0,0] heads) ]";
973 formulasString +=
"; Pmax=? [ G (!(P>=1 [\"done\"]) U<=10 (heads | P>=1 [ \"done\"])) ]";
974 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/coin_flips.nm", formulasString);
975 auto model = std::move(modelFormulas.first);
976 auto tasks = this->getTasks(modelFormulas.second);
977 this->execute(model, [&]() {
978 EXPECT_EQ(61ul, model->getNumberOfStates());
979 EXPECT_EQ(177ul, model->getNumberOfTransitions());
981 auto checker = this->createModelChecker(model);
982 std::unique_ptr<storm::modelchecker::CheckResult> result;
985 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
986 result = checker->check(this->env(), tasks[0]);
989 result = checker->check(this->env(), tasks[1]);
992 result = checker->check(this->env(), tasks[2]);
995 result = checker->check(this->env(), tasks[3]);
998 result = checker->check(this->env(), tasks[4]);
1001 result = checker->check(this->env(), tasks[5]);
1004 result = checker->check(this->env(), tasks[6]);
1007 result = checker->check(this->env(), tasks[7]);
1011 EXPECT_FALSE(checker->canHandle(tasks[0]));
1019TYPED_TEST(MdpPrctlModelCheckerTest, HOADice) {
1021 std::string formulasString =
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> \"three\", \"p1\" -> s2=1 }]";
1023 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_UXp0p1.hoa\", \"p0\" -> !(s2=6), \"p1\" -> \"done\" }]";
1025 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/two_dice.nm", formulasString);
1026 auto model = std::move(modelFormulas.first);
1027 auto tasks = this->getTasks(modelFormulas.second);
1028 this->execute(model, [&]() {
1029 EXPECT_EQ(169ul, model->getNumberOfStates());
1030 EXPECT_EQ(436ul, model->getNumberOfTransitions());
1032 auto checker = this->createModelChecker(model);
1033 std::unique_ptr<storm::modelchecker::CheckResult> result;
1036 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
1037 result = checker->check(tasks[0]);
1040 result = checker->check(tasks[1]);
1043 EXPECT_FALSE(checker->canHandle(tasks[0]));
1048TYPED_TEST(MdpPrctlModelCheckerTest, SmallDiscount) {
1049 if (TypeParam::isExact || std::is_same<TypeParam, SparseDoubleLPEnvironment>::value || std::is_same<TypeParam, SparseDoubleViToLPEnvironment>::value) {
1050 GTEST_SKIP() <<
"Exact computations for discounted properties are not supported.";
1052 std::string formulasString =
"Rmax=? [ C ]";
1053 formulasString +=
"; Rmax=? [ Cdiscount=9/10 ]";
1054 formulasString +=
"; Rmax=? [ Cdiscount=15/16 ]";
1055 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/small_discount.nm", formulasString);
1056 auto model = std::move(modelFormulas.first);
1057 auto tasks = this->getTasks(modelFormulas.second);
1058 EXPECT_EQ(4ul, model->getNumberOfStates());
1059 EXPECT_EQ(6ul, model->getNumberOfTransitions());
1061 auto checker = this->createModelChecker(model);
1063 if (TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse) {
1064 std::unique_ptr<storm::modelchecker::CheckResult> result = checker->check(this->env(), tasks[0]);
1066 result = checker->check(this->env(), tasks[1]);
1068 result = checker->check(this->env(), tasks[2]);
1071 EXPECT_FALSE(checker->canHandle(tasks[0]));
1072 EXPECT_FALSE(checker->canHandle(tasks[1]));
1073 EXPECT_FALSE(checker->canHandle(tasks[2]));
1077TYPED_TEST(MdpPrctlModelCheckerTest, OneStateDiscounting) {
1078 if (TypeParam::isExact || std::is_same<TypeParam, SparseDoubleLPEnvironment>::value || std::is_same<TypeParam, SparseDoubleViToLPEnvironment>::value) {
1079 GTEST_SKIP() <<
"Exact computations for discounted properties are not supported.";
1081 std::string formulasString =
"Rmax=? [ Cdiscount=9/10 ]";
1082 formulasString +=
"; Rmax=? [ C<=5discount=9/10 ]";
1083 formulasString +=
"; Rmax=? [ C<=10discount=9/10 ]";
1084 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/mdp/one_state.nm", formulasString);
1085 auto model = std::move(modelFormulas.first);
1086 auto tasks = this->getTasks(modelFormulas.second);
1087 EXPECT_EQ(1ul, model->getNumberOfStates());
1088 EXPECT_EQ(2ul, model->getNumberOfTransitions());
1090 auto checker = this->createModelChecker(model);
1092 if ((TypeParam::engine == MdpEngine::PrismSparse || TypeParam::engine == MdpEngine::JaniSparse)) {
1093 std::unique_ptr<storm::modelchecker::CheckResult> result = checker->check(this->env(), tasks[0]);
1095 result = checker->check(this->env(), tasks[1]);
1097 result = checker->check(this->env(), tasks[2]);
1100 EXPECT_FALSE(checker->canHandle(tasks[0]));
1101 EXPECT_FALSE(checker->canHandle(tasks[1]));
1102 EXPECT_FALSE(checker->canHandle(tasks[2]));
std::unique_ptr< storm::modelchecker::QualitativeCheckResult > getInitialStateFilter(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model)
double getQuantitativeResultAtInitialState(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model, std::unique_ptr< storm::modelchecker::CheckResult > &result)
SolverEnvironment & solver()
void setMultiplicationStyle(storm::solver::MultiplicationStyle value)
void setPrecision(storm::RationalNumber value)
void setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault=false)
void setRelativeTerminationCriterion(bool value)
void setType(storm::solver::MultiplierType value, bool isSetFromDefault=false)
TopologicalSolverEnvironment & topological()
MinMaxSolverEnvironment & minMax()
void setForceSoundness(bool value)
MultiplierEnvironment & multiplier()
void setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod value)
This class represents a (discrete-time) Markov decision process.
This class represents a discrete-time Markov decision process.
std::vector< storm::jani::Property > parsePropertiesForPrismProgram(std::string const &inputString, storm::prism::Program const &program, boost::optional< std::set< std::string > > const &propertyFilter)
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
std::pair< storm::jani::Model, std::vector< storm::jani::Property > > convertPrismToJani(storm::prism::Program const &program, storm::converter::PrismToJaniConverterOptions options)
SFTBDDChecker::ValueType ValueType
NumberType parseNumber(std::string const &value)
Parse number from string.
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
storm::storage::BitVector filter(std::vector< T > const &values, std::function< bool(T const &value)> const &function)
Retrieves a bit vector containing all the indices for which the value at this position makes the give...
bool isInfinity(ValueType const &a)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)