1#include "storm-config.h"
35enum class DtmcEngine { PrismSparse, JaniSparse,
Hybrid, PrismDd, JaniDd };
38class SparseGmmxxGmresIluEnvironment {
41 static const DtmcEngine engine = DtmcEngine::PrismSparse;
42 static const bool isExact =
false;
44 typedef storm::models::sparse::Dtmc<ValueType>
ModelType;
45 static storm::Environment createEnvironment() {
46 storm::Environment env;
55class JaniSparseGmmxxGmresIluEnvironment {
58 static const DtmcEngine engine = DtmcEngine::JaniSparse;
59 static const bool isExact =
false;
61 typedef storm::models::sparse::Dtmc<ValueType>
ModelType;
62 static storm::Environment createEnvironment() {
63 storm::Environment env;
72class SparseGmmxxGmresDiagEnvironment {
75 static const DtmcEngine engine = DtmcEngine::PrismSparse;
76 static const bool isExact =
false;
78 typedef storm::models::sparse::Dtmc<ValueType>
ModelType;
79 static storm::Environment createEnvironment() {
80 storm::Environment env;
89class SparseGmmxxBicgstabIluEnvironment {
92 static const DtmcEngine engine = DtmcEngine::PrismSparse;
93 static const bool isExact =
false;
95 typedef storm::models::sparse::Dtmc<ValueType>
ModelType;
96 static storm::Environment createEnvironment() {
97 storm::Environment env;
107class SparseEigenDGmresEnvironment {
110 static const DtmcEngine engine = DtmcEngine::PrismSparse;
111 static const bool isExact =
false;
112 typedef double ValueType;
113 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
114 static storm::Environment createEnvironment() {
115 storm::Environment env;
124class SparseEigenDoubleLUEnvironment {
127 static const DtmcEngine engine = DtmcEngine::PrismSparse;
128 static const bool isExact =
false;
129 typedef double ValueType;
130 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
131 static storm::Environment createEnvironment() {
132 storm::Environment env;
139class SparseEigenRationalLUEnvironment {
142 static const DtmcEngine engine = DtmcEngine::PrismSparse;
143 static const bool isExact =
true;
144 typedef storm::RationalNumber ValueType;
145 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
146 static storm::Environment createEnvironment() {
147 storm::Environment env;
154class SparseRationalEliminationEnvironment {
157 static const DtmcEngine engine = DtmcEngine::PrismSparse;
158 static const bool isExact =
true;
159 typedef storm::RationalNumber ValueType;
160 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
161 static storm::Environment createEnvironment() {
162 storm::Environment env;
168class SparseNativeJacobiEnvironment {
171 static const DtmcEngine engine = DtmcEngine::PrismSparse;
172 static const bool isExact =
false;
173 typedef double ValueType;
174 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
175 static storm::Environment createEnvironment() {
176 storm::Environment env;
184class SparseNativeWalkerChaeEnvironment {
187 static const DtmcEngine engine = DtmcEngine::PrismSparse;
188 static const bool isExact =
false;
189 typedef double ValueType;
190 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
191 static storm::Environment createEnvironment() {
192 storm::Environment env;
201class SparseNativeSorEnvironment {
204 static const DtmcEngine engine = DtmcEngine::PrismSparse;
205 static const bool isExact =
false;
206 typedef double ValueType;
207 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
208 static storm::Environment createEnvironment() {
209 storm::Environment env;
217class SparseNativePowerEnvironment {
220 static const DtmcEngine engine = DtmcEngine::PrismSparse;
221 static const bool isExact =
false;
222 typedef double ValueType;
223 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
224 static storm::Environment createEnvironment() {
225 storm::Environment env;
233class SparseNativeSoundValueIterationEnvironment {
236 static const DtmcEngine engine = DtmcEngine::PrismSparse;
237 static const bool isExact =
false;
238 typedef double ValueType;
239 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
240 static storm::Environment createEnvironment() {
241 storm::Environment env;
244 env.
solver().
native().
setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration);
250class SparseNativeOptimisticValueIterationEnvironment {
253 static const DtmcEngine engine = DtmcEngine::PrismSparse;
254 static const bool isExact =
false;
255 typedef double ValueType;
256 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
257 static storm::Environment createEnvironment() {
258 storm::Environment env;
261 env.
solver().
native().
setMethod(storm::solver::NativeLinearEquationSolverMethod::OptimisticValueIteration);
267class SparseNativeGuessingValueIterationEnvironment {
270 static const DtmcEngine engine = DtmcEngine::PrismSparse;
271 static const bool isExact =
false;
272 typedef double ValueType;
273 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
274 static storm::Environment createEnvironment() {
275 storm::Environment env;
278 env.
solver().
native().
setMethod(storm::solver::NativeLinearEquationSolverMethod::GuessingValueIteration);
284class SparseNativeIntervalIterationEnvironment {
287 static const DtmcEngine engine = DtmcEngine::PrismSparse;
288 static const bool isExact =
false;
289 typedef double ValueType;
290 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
291 static storm::Environment createEnvironment() {
292 storm::Environment env;
302class SparseNativeRationalSearchEnvironment {
305 static const DtmcEngine engine = DtmcEngine::PrismSparse;
306 static const bool isExact =
true;
307 typedef storm::RationalNumber ValueType;
308 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
309 static storm::Environment createEnvironment() {
310 storm::Environment env;
317class SparseTopologicalEigenLUEnvironment {
320 static const DtmcEngine engine = DtmcEngine::PrismSparse;
321 static const bool isExact =
true;
322 typedef storm::RationalNumber ValueType;
323 typedef storm::models::sparse::Dtmc<ValueType> ModelType;
324 static storm::Environment createEnvironment() {
325 storm::Environment env;
334class HybridSylvanGmmxxGmresEnvironment {
337 static const DtmcEngine engine = DtmcEngine::Hybrid;
338 static const bool isExact =
false;
340 typedef storm::models::symbolic::Dtmc<ddType, ValueType>
ModelType;
342 static void checkLibraryAvailable() {
343#ifndef STORM_HAVE_SYLVAN
344 GTEST_SKIP() <<
"Library Sylvan not available.";
348 static storm::Environment createEnvironment() {
349 storm::Environment env;
358class HybridCuddNativeJacobiEnvironment {
361 static const DtmcEngine engine = DtmcEngine::Hybrid;
362 static const bool isExact =
false;
363 typedef double ValueType;
364 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
366 static void checkLibraryAvailable() {
367#ifndef STORM_HAVE_CUDD
368 GTEST_SKIP() <<
"Library CUDD not available.";
372 static storm::Environment createEnvironment() {
373 storm::Environment env;
381class HybridCuddNativeSoundValueIterationEnvironment {
384 static const DtmcEngine engine = DtmcEngine::Hybrid;
385 static const bool isExact =
false;
386 typedef double ValueType;
387 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
389 static void checkLibraryAvailable() {
390#ifndef STORM_HAVE_CUDD
391 GTEST_SKIP() <<
"Library CUDD not available.";
395 static storm::Environment createEnvironment() {
396 storm::Environment env;
405class HybridSylvanNativeRationalSearchEnvironment {
408 static const DtmcEngine engine = DtmcEngine::Hybrid;
409 static const bool isExact =
true;
410 typedef storm::RationalNumber ValueType;
411 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
413 static void checkLibraryAvailable() {
414#ifndef STORM_HAVE_SYLVAN
415 GTEST_SKIP() <<
"Library Sylvan not available.";
419 static storm::Environment createEnvironment() {
420 storm::Environment env;
427class DdSylvanNativePowerEnvironment {
430 static const DtmcEngine engine = DtmcEngine::PrismDd;
431 static const bool isExact =
false;
432 typedef double ValueType;
433 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
435 static void checkLibraryAvailable() {
436#ifndef STORM_HAVE_SYLVAN
437 GTEST_SKIP() <<
"Library Sylvan not available.";
441 static storm::Environment createEnvironment() {
442 storm::Environment env;
450class JaniDdSylvanNativePowerEnvironment {
453 static const DtmcEngine engine = DtmcEngine::JaniDd;
454 static const bool isExact =
false;
455 typedef double ValueType;
456 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
458 static void checkLibraryAvailable() {
459#ifndef STORM_HAVE_SYLVAN
460 GTEST_SKIP() <<
"Library Sylvan not available.";
464 static storm::Environment createEnvironment() {
465 storm::Environment env;
473class DdCuddNativeJacobiEnvironment {
476 static const DtmcEngine engine = DtmcEngine::PrismDd;
477 static const bool isExact =
false;
478 typedef double ValueType;
479 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
481 static void checkLibraryAvailable() {
482#ifndef STORM_HAVE_CUDD
483 GTEST_SKIP() <<
"Library CUDD not available.";
487 static storm::Environment createEnvironment() {
488 storm::Environment env;
496class DdSylvanRationalSearchEnvironment {
499 static const DtmcEngine engine = DtmcEngine::PrismDd;
500 static const bool isExact =
true;
501 typedef storm::RationalNumber ValueType;
502 typedef storm::models::symbolic::Dtmc<ddType, ValueType> ModelType;
504 static void checkLibraryAvailable() {
505#ifndef STORM_HAVE_SYLVAN
506 GTEST_SKIP() <<
"Library Sylvan not available.";
510 static storm::Environment createEnvironment() {
511 storm::Environment env;
518template<
typename TestType>
519class DtmcPrctlModelCheckerTest :
public ::testing::Test {
521 typedef typename TestType::ValueType ValueType;
522 typedef typename storm::models::sparse::Dtmc<ValueType> SparseModelType;
523 typedef typename storm::models::symbolic::Dtmc<TestType::ddType, ValueType> SymbolicModelType;
525 DtmcPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
527 void SetUp()
override {
529 GTEST_SKIP() <<
"Z3 not available.";
531 if constexpr (TestType::engine == DtmcEngine::Hybrid || TestType::engine == DtmcEngine::PrismDd || TestType::engine == DtmcEngine::JaniDd) {
532 TestType::checkLibraryAvailable();
536 storm::Environment
const& env()
const {
539 ValueType
parseNumber(std::string
const& input)
const {
542 ValueType precision()
const {
545 bool isSparseModel()
const {
546 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
548 bool isSymbolicModel()
const {
549 return std::is_same<typename TestType::ModelType, SymbolicModelType>::value;
552 template<
typename MT =
typename TestType::ModelType>
553 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
554 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
555 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
556 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
558 program = program.
preprocess(constantDefinitionString);
559 if (TestType::engine == DtmcEngine::PrismSparse) {
562 }
else if (TestType::engine == DtmcEngine::JaniSparse) {
571 template<
typename MT =
typename TestType::ModelType>
572 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
573 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
574 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
575 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
577 program = program.
preprocess(constantDefinitionString);
578 if (TestType::engine == DtmcEngine::Hybrid || TestType::engine == DtmcEngine::PrismDd) {
581 }
else if (TestType::engine == DtmcEngine::JaniDd) {
583 janiData.first.substituteFunctions();
590 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
591 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
592 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
593 for (
auto const& f : formulas) {
594 result.emplace_back(*f);
599 template<
typename MT =
typename TestType::ModelType>
600 typename std::enable_if<std::is_same<MT, SparseModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type createModelChecker(
601 std::shared_ptr<MT>
const& model)
const {
602 if (TestType::engine == DtmcEngine::PrismSparse || TestType::engine == DtmcEngine::JaniSparse) {
603 return std::make_shared<storm::modelchecker::SparseDtmcPrctlModelChecker<SparseModelType>>(*model);
607 template<
typename MT =
typename TestType::ModelType>
608 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type
609 createModelChecker(std::shared_ptr<MT>
const& model)
const {
610 if (TestType::engine == DtmcEngine::Hybrid) {
611 return std::make_shared<storm::modelchecker::HybridDtmcPrctlModelChecker<SymbolicModelType>>(*model);
612 }
else if (TestType::engine == DtmcEngine::PrismDd || TestType::engine == DtmcEngine::JaniDd) {
613 return std::make_shared<storm::modelchecker::SymbolicDtmcPrctlModelChecker<SymbolicModelType>>(*model);
617 template<
typename MT =
typename TestType::ModelType>
618 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
619 std::function<
void()>
const& f)
const {
623 template<
typename MT =
typename TestType::ModelType>
624 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
625 std::function<
void()>
const& f)
const {
626 model->getManager().execute(f);
629 bool getQualitativeResultAtInitialState(std::shared_ptr<storm::models::Model<ValueType>>
const& model,
630 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
632 result->filter(*filter);
633 return result->asQualitativeCheckResult().forallTrue();
637 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
639 result->filter(*filter);
640 return result->asQuantitativeCheckResult<ValueType>().getMin();
644 storm::Environment _environment;
646 std::unique_ptr<storm::modelchecker::QualitativeCheckResult>
getInitialStateFilter(std::shared_ptr<storm::models::Model<ValueType>>
const& model)
const {
647 if (isSparseModel()) {
648 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult<ValueType>>(model->template as<SparseModelType>()->getInitialStates());
650 return std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<TestType::ddType>>(
651 model->template as<SymbolicModelType>()->getReachableStates(), model->template as<SymbolicModelType>()->getInitialStates());
656typedef ::testing::Types<
658 SparseGmmxxGmresIluEnvironment, JaniSparseGmmxxGmresIluEnvironment, SparseGmmxxGmresDiagEnvironment, SparseGmmxxBicgstabIluEnvironment,
659 HybridSylvanGmmxxGmresEnvironment,
661 SparseEigenDGmresEnvironment, SparseEigenDoubleLUEnvironment, SparseEigenRationalLUEnvironment, SparseRationalEliminationEnvironment,
662 SparseNativeJacobiEnvironment, SparseNativeWalkerChaeEnvironment, SparseNativeSorEnvironment, SparseNativePowerEnvironment,
663 SparseNativeSoundValueIterationEnvironment, SparseNativeOptimisticValueIterationEnvironment, SparseNativeGuessingValueIterationEnvironment,
664 SparseNativeIntervalIterationEnvironment, SparseNativeRationalSearchEnvironment, SparseTopologicalEigenLUEnvironment, HybridCuddNativeJacobiEnvironment,
665 HybridCuddNativeSoundValueIterationEnvironment, HybridSylvanNativeRationalSearchEnvironment, DdSylvanNativePowerEnvironment,
666 JaniDdSylvanNativePowerEnvironment, DdCuddNativeJacobiEnvironment, DdSylvanRationalSearchEnvironment>
672 std::string formulasString =
"P=? [F \"one\"]";
673 formulasString +=
"; P=? [F \"two\"]";
674 formulasString +=
"; P=? [F \"three\"]";
675 formulasString +=
"; R=? [F \"done\"]";
677 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/die.pm", formulasString);
678 auto model = std::move(modelFormulas.first);
679 auto tasks = this->getTasks(modelFormulas.second);
680 this->execute(model, [&]() {
681 EXPECT_EQ(13ul, model->getNumberOfStates());
682 EXPECT_EQ(20ul, model->getNumberOfTransitions());
684 auto checker = this->createModelChecker(model);
685 std::unique_ptr<storm::modelchecker::CheckResult> result;
687 result = checker->check(this->env(), tasks[0]);
690 result = checker->check(this->env(), tasks[1]);
693 result = checker->check(this->env(), tasks[2]);
696 result = checker->check(this->env(), tasks[3]);
702 std::string formulasString =
"P=? [F observe0>1]";
703 formulasString +=
"; P=? [F \"observeIGreater1\"]";
704 formulasString +=
"; P=? [F observe1>1]";
706 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/crowds-4-3.pm", formulasString);
707 auto model = std::move(modelFormulas.first);
708 auto tasks = this->getTasks(modelFormulas.second);
709 this->execute(model, [&]() {
710 EXPECT_EQ(726ul, model->getNumberOfStates());
711 EXPECT_EQ(1146ul, model->getNumberOfTransitions());
713 auto checker = this->createModelChecker(model);
714 std::unique_ptr<storm::modelchecker::CheckResult> result;
716 result = checker->check(this->env(), tasks[0]);
719 result = checker->check(this->env(), tasks[1]);
722 result = checker->check(this->env(), tasks[2]);
727TYPED_TEST(DtmcPrctlModelCheckerTest, SynchronousLeader) {
728 std::string formulasString =
"P=? [F \"elected\"]";
729 formulasString +=
"; P=? [F<=5 \"elected\"]";
730 formulasString +=
"; R=? [F \"elected\"]";
732 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/leader-3-5.pm", formulasString);
733 auto model = std::move(modelFormulas.first);
734 auto tasks = this->getTasks(modelFormulas.second);
735 this->execute(model, [&]() {
736 EXPECT_EQ(273ul, model->getNumberOfStates());
737 EXPECT_EQ(397ul, model->getNumberOfTransitions());
739 auto checker = this->createModelChecker(model);
740 std::unique_ptr<storm::modelchecker::CheckResult> result;
742 result = checker->check(this->env(), tasks[0]);
745 result = checker->check(this->env(), tasks[1]);
748 result = checker->check(this->env(), tasks[2]);
753TEST(DtmcPrctlModelCheckerTest, BoundedReachability) {
754 std::string formulasString =
"P=? [F<=1 \"a\"]";
755 formulasString +=
"; P=? [F[1,1] \"a\"]";
756 formulasString +=
"; P=? [F[0,2] \"a\"]";
758 std::shared_ptr<storm::models::sparse::Model<double>> modelPtr =
768 auto result = checker.
check(env, task);
769 auto filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult<double>>(dtmc->getInitialStates());
770 result->filter(*filter);
771 EXPECT_NEAR(0.2, result->asQuantitativeCheckResult<
double>().getMin(), 0.0001);
775 result = checker.check(env, task);
776 filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult<double>>(dtmc->getInitialStates());
777 result->filter(*filter);
778 EXPECT_NEAR(0.2, result->asQuantitativeCheckResult<
double>().getMin(), 0.0001);
782 result = checker.check(env, task);
783 filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult<double>>(dtmc->getInitialStates());
784 result->filter(*filter);
785 EXPECT_NEAR(0.366, result->asQuantitativeCheckResult<
double>().getMin(), 0.0001);
788TEST(DtmcPrctlModelCheckerTest, AllUntilProbabilities) {
790 GTEST_SKIP() <<
"Z3 not available.";
792 std::string formulasString =
"P=? [F \"one\"]";
793 formulasString +=
"; P=? [F \"two\"]";
794 formulasString +=
"; P=? [F \"three\"]";
798 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, double>> tasks;
799 for (
auto const& f : formulas) {
800 tasks.emplace_back(*f);
803 EXPECT_EQ(13ul, model->getNumberOfStates());
804 EXPECT_EQ(20ul, model->getNumberOfTransitions());
808 initialStates.set(0);
820 initialStates, phiStates, psiStates);
822 EXPECT_NEAR(1.0 / 6, result[7], 1e-6);
823 EXPECT_NEAR(1.0 / 6, result[8], 1e-6);
824 EXPECT_NEAR(1.0 / 6, result[9], 1e-6);
825 EXPECT_NEAR(1.0 / 6, result[10], 1e-6);
826 EXPECT_NEAR(1.0 / 6, result[11], 1e-6);
827 EXPECT_NEAR(1.0 / 6, result[12], 1e-6);
835 EXPECT_NEAR(1, result[0], 1e-6);
836 EXPECT_NEAR(0.5, result[1], 1e-6);
837 EXPECT_NEAR(0.5, result[2], 1e-6);
838 EXPECT_NEAR(0.25, result[5], 1e-6);
839 EXPECT_NEAR(0, result[7], 1e-6);
840 EXPECT_NEAR(0, result[8], 1e-6);
841 EXPECT_NEAR(0, result[9], 1e-6);
842 EXPECT_NEAR(0.125, result[10], 1e-6);
843 EXPECT_NEAR(0.125, result[11], 1e-6);
844 EXPECT_NEAR(0, result[12], 1e-6);
847TYPED_TEST(DtmcPrctlModelCheckerTest, LtlProbabilitiesDie) {
848#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
849 std::string formulasString =
"P=? [(X s>0) U (s=7 & d=2)]";
850 formulasString +=
"; P=? [ X (((s=1) U (s=3)) U (s=7))]";
851 formulasString +=
"; P=? [ (F (X (s=6 & (XX s=5)))) & (F G (d!=5))]";
852 formulasString +=
"; P=? [ F (s=3 U (\"three\"))]";
853 formulasString +=
"; P=? [ F s=3 U (\"three\")]";
854 formulasString +=
"; P=? [ F (s=6) & X \"done\"]";
855 formulasString +=
"; P=? [ (F s=6) & (X \"done\")]";
857 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/die.pm", formulasString);
858 auto model = std::move(modelFormulas.first);
859 auto tasks = this->getTasks(modelFormulas.second);
860 this->execute(model, [&]() {
861 EXPECT_EQ(13ul, model->getNumberOfStates());
862 EXPECT_EQ(20ul, model->getNumberOfTransitions());
864 auto checker = this->createModelChecker(model);
865 std::unique_ptr<storm::modelchecker::CheckResult> result;
868 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
869 result = checker->check(tasks[0]);
872 result = checker->check(tasks[1]);
875 result = checker->check(tasks[2]);
878 result = checker->check(tasks[3]);
881 result = checker->check(tasks[4]);
884 result = checker->check(tasks[5]);
887 result = checker->check(tasks[6]);
890 EXPECT_FALSE(checker->canHandle(tasks[0]));
898TYPED_TEST(DtmcPrctlModelCheckerTest, LtlProbabilitiesSynchronousLeader) {
899#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
900 std::string formulasString =
"P=? [X (u1=true U \"elected\")]";
901 formulasString +=
"; P=? [X !(u1=true U \"elected\")]";
902 formulasString +=
"; P=? [X v1=2 & X v1=1]";
903 formulasString +=
"; P=? [(X v1=2) & (X v1=1)]";
904 formulasString +=
"; P=? [(!X v1=2) & (X v1=1)]";
906 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/leader-3-5.pm", formulasString);
907 auto model = std::move(modelFormulas.first);
908 auto tasks = this->getTasks(modelFormulas.second);
909 this->execute(model, [&]() {
910 EXPECT_EQ(273ul, model->getNumberOfStates());
911 EXPECT_EQ(397ul, model->getNumberOfTransitions());
913 auto checker = this->createModelChecker(model);
914 std::unique_ptr<storm::modelchecker::CheckResult> result;
917 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
918 result = checker->check(tasks[0]);
921 result = checker->check(tasks[1]);
924 result = checker->check(tasks[2]);
927 result = checker->check(tasks[3]);
930 result = checker->check(tasks[4]);
934 EXPECT_FALSE(checker->canHandle(tasks[0]));
942TYPED_TEST(DtmcPrctlModelCheckerTest, HOAProbabilitiesDie) {
944 std::string formulasString =
"P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_UXp0p1.hoa\", \"p0\" -> (s>0), \"p1\" -> (s=7 & d=2) }]";
946 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_UXp0p1.hoa\", \"p0\" -> (s>0), \"p1\" -> (d=4 | d=2) }]";
948 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4), \"p1\" -> \"three\" }]";
950 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=6), \"p1\" -> \"done\" }]";
952 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=6), \"p1\" -> !\"done\" }]";
954 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4 | s=5), \"p1\" -> s=7 & (d=3 | d=5) }]";
956 formulasString +=
"; P>0.3[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4 | s=5), \"p1\" -> s=7 & (d=3 | d=5) }]";
958 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/die.pm", formulasString);
959 auto model = std::move(modelFormulas.first);
960 auto tasks = this->getTasks(modelFormulas.second);
961 this->execute(model, [&]() {
962 EXPECT_EQ(13ul, model->getNumberOfStates());
963 EXPECT_EQ(20ul, model->getNumberOfTransitions());
965 auto checker = this->createModelChecker(model);
966 std::unique_ptr<storm::modelchecker::CheckResult> result;
969 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
970 result = checker->check(tasks[0]);
973 result = checker->check(tasks[1]);
976 result = checker->check(tasks[2]);
979 result = checker->check(tasks[3]);
982 result = checker->check(tasks[4]);
985 result = checker->check(tasks[5]);
988 result = checker->check(tasks[6]);
989 EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
991 EXPECT_FALSE(checker->canHandle(tasks[0]));
996TYPED_TEST(DtmcPrctlModelCheckerTest, SmallDiscount) {
997 if (TypeParam::isExact) {
998 GTEST_SKIP() <<
"Exact computations for discounted properties are not supported.";
1000 std::string formulasString =
"R=? [ C ]";
1001 formulasString +=
"; R=? [ Cdiscount=9/10 ]";
1002 formulasString +=
"; R=? [ Cdiscount=15/16 ]";
1003 formulasString +=
"; R=? [ C<5discount=9/10 ]";
1004 formulasString +=
"; R=? [ C<5discount=15/16 ]";
1005 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/small_discount.nm", formulasString);
1006 auto model = std::move(modelFormulas.first);
1007 auto tasks = this->getTasks(modelFormulas.second);
1008 EXPECT_EQ(3ul, model->getNumberOfStates());
1009 EXPECT_EQ(4ul, model->getNumberOfTransitions());
1011 auto checker = this->createModelChecker(model);
1013 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
1014 std::unique_ptr<storm::modelchecker::CheckResult> result = checker->check(this->env(), tasks[0]);
1017 result = checker->check(this->env(), tasks[1]);
1019 result = checker->check(this->env(), tasks[2]);
1021 result = checker->check(this->env(), tasks[3]);
1023 result = checker->check(this->env(), tasks[4]);
1026 EXPECT_FALSE(checker->canHandle(tasks[0]));
1027 EXPECT_FALSE(checker->canHandle(tasks[1]));
1028 EXPECT_FALSE(checker->canHandle(tasks[2]));
1029 EXPECT_FALSE(checker->canHandle(tasks[3]));
1030 EXPECT_FALSE(checker->canHandle(tasks[4]));
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)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner value)
void setMethod(storm::solver::EigenLinearEquationSolverMethod value)
SolverEnvironment & solver()
void setMethod(storm::solver::GmmxxLinearEquationSolverMethod value)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner value)
void setMaximalNumberOfIterations(uint64_t value)
void setMethod(storm::solver::NativeLinearEquationSolverMethod value)
void setRelativeTerminationCriterion(bool value)
void setPrecision(storm::RationalNumber value)
TopologicalSolverEnvironment & topological()
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
EigenSolverEnvironment & eigen()
void setForceSoundness(bool value)
NativeSolverEnvironment & native()
GmmxxSolverEnvironment & gmmxx()
void setUnderlyingEquationSolverType(storm::solver::EquationSolverType value)
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
static std::vector< SolutionType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
This class represents a discrete-time Markov chain.
Program preprocess(std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions) const
Preprocesses the program by defining the given constant definitions, substituting constants and formu...
A bit vector that is internally represented as a vector of 64-bit values.
A class that holds a possibly non-square matrix in the compressed row storage format.
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< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
std::shared_ptr< storm::models::symbolic::Model< LibraryType, ValueType > > buildSymbolicModel(storm::Environment const &env, storm::storage::SymbolicModelDescription const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas, bool buildFullModel=false, bool applyMaximumProgress=true, bool fixDeadlocks=true)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options, typename storm::builder::ExplicitModelBuilder< ValueType >::Options const &explorationOptions=typename storm::builder::ExplicitModelBuilder< ValueType >::Options())
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.
template std::shared_ptr< storm::models::sparse::Model< double > > parseDirectEncodingModel< double >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
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...
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
#define STORM_EXPENSIVE_TYPED_TEST(test_suite_name, test_name)