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;
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;
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]);
701TYPED_TEST(DtmcPrctlModelCheckerTest, Crowds) {
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);
834 EXPECT_NEAR(1, result[0], 1e-6);
835 EXPECT_NEAR(0.5, result[1], 1e-6);
836 EXPECT_NEAR(0.5, result[2], 1e-6);
837 EXPECT_NEAR(0.25, result[5], 1e-6);
838 EXPECT_NEAR(0, result[7], 1e-6);
839 EXPECT_NEAR(0, result[8], 1e-6);
840 EXPECT_NEAR(0, result[9], 1e-6);
841 EXPECT_NEAR(0.125, result[10], 1e-6);
842 EXPECT_NEAR(0.125, result[11], 1e-6);
843 EXPECT_NEAR(0, result[12], 1e-6);
846TYPED_TEST(DtmcPrctlModelCheckerTest, LtlProbabilitiesDie) {
847#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
848 std::string formulasString =
"P=? [(X s>0) U (s=7 & d=2)]";
849 formulasString +=
"; P=? [ X (((s=1) U (s=3)) U (s=7))]";
850 formulasString +=
"; P=? [ (F (X (s=6 & (XX s=5)))) & (F G (d!=5))]";
851 formulasString +=
"; P=? [ F (s=3 U (\"three\"))]";
852 formulasString +=
"; P=? [ F s=3 U (\"three\")]";
853 formulasString +=
"; P=? [ F (s=6) & X \"done\"]";
854 formulasString +=
"; P=? [ (F s=6) & (X \"done\")]";
856 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/die.pm", formulasString);
857 auto model = std::move(modelFormulas.first);
858 auto tasks = this->getTasks(modelFormulas.second);
859 this->execute(model, [&]() {
860 EXPECT_EQ(13ul, model->getNumberOfStates());
861 EXPECT_EQ(20ul, model->getNumberOfTransitions());
863 auto checker = this->createModelChecker(model);
864 std::unique_ptr<storm::modelchecker::CheckResult> result;
867 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
868 result = checker->check(tasks[0]);
871 result = checker->check(tasks[1]);
874 result = checker->check(tasks[2]);
877 result = checker->check(tasks[3]);
880 result = checker->check(tasks[4]);
883 result = checker->check(tasks[5]);
886 result = checker->check(tasks[6]);
889 EXPECT_FALSE(checker->canHandle(tasks[0]));
897TYPED_TEST(DtmcPrctlModelCheckerTest, LtlProbabilitiesSynchronousLeader) {
898#ifdef STORM_HAVE_LTL_MODELCHECKING_SUPPORT
899 std::string formulasString =
"P=? [X (u1=true U \"elected\")]";
900 formulasString +=
"; P=? [X !(u1=true U \"elected\")]";
901 formulasString +=
"; P=? [X v1=2 & X v1=1]";
902 formulasString +=
"; P=? [(X v1=2) & (X v1=1)]";
903 formulasString +=
"; P=? [(!X v1=2) & (X v1=1)]";
905 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/leader-3-5.pm", formulasString);
906 auto model = std::move(modelFormulas.first);
907 auto tasks = this->getTasks(modelFormulas.second);
908 this->execute(model, [&]() {
909 EXPECT_EQ(273ul, model->getNumberOfStates());
910 EXPECT_EQ(397ul, model->getNumberOfTransitions());
912 auto checker = this->createModelChecker(model);
913 std::unique_ptr<storm::modelchecker::CheckResult> result;
916 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
917 result = checker->check(tasks[0]);
920 result = checker->check(tasks[1]);
923 result = checker->check(tasks[2]);
926 result = checker->check(tasks[3]);
929 result = checker->check(tasks[4]);
933 EXPECT_FALSE(checker->canHandle(tasks[0]));
941TYPED_TEST(DtmcPrctlModelCheckerTest, HOAProbabilitiesDie) {
943 std::string formulasString =
"P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_UXp0p1.hoa\", \"p0\" -> (s>0), \"p1\" -> (s=7 & d=2) }]";
945 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_UXp0p1.hoa\", \"p0\" -> (s>0), \"p1\" -> (d=4 | d=2) }]";
947 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4), \"p1\" -> \"three\" }]";
949 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=6), \"p1\" -> \"done\" }]";
951 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=6), \"p1\" -> !\"done\" }]";
953 formulasString +=
"; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR
"/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4 | s=5), \"p1\" -> s=7 & (d=3 | d=5) }]";
955 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) }]";
957 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/die.pm", formulasString);
958 auto model = std::move(modelFormulas.first);
959 auto tasks = this->getTasks(modelFormulas.second);
960 this->execute(model, [&]() {
961 EXPECT_EQ(13ul, model->getNumberOfStates());
962 EXPECT_EQ(20ul, model->getNumberOfTransitions());
964 auto checker = this->createModelChecker(model);
965 std::unique_ptr<storm::modelchecker::CheckResult> result;
968 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
969 result = checker->check(tasks[0]);
972 result = checker->check(tasks[1]);
975 result = checker->check(tasks[2]);
978 result = checker->check(tasks[3]);
981 result = checker->check(tasks[4]);
984 result = checker->check(tasks[5]);
987 result = checker->check(tasks[6]);
988 EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
990 EXPECT_FALSE(checker->canHandle(tasks[0]));
995TYPED_TEST(DtmcPrctlModelCheckerTest, SmallDiscount) {
996 if (TypeParam::isExact) {
997 GTEST_SKIP() <<
"Exact computations for discounted properties are not supported.";
999 std::string formulasString =
"R=? [ C ]";
1000 formulasString +=
"; R=? [ Cdiscount=9/10 ]";
1001 formulasString +=
"; R=? [ Cdiscount=15/16 ]";
1002 formulasString +=
"; R=? [ C<5discount=9/10 ]";
1003 formulasString +=
"; R=? [ C<5discount=15/16 ]";
1004 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/dtmc/small_discount.nm", formulasString);
1005 auto model = std::move(modelFormulas.first);
1006 auto tasks = this->getTasks(modelFormulas.second);
1007 EXPECT_EQ(3ul, model->getNumberOfStates());
1008 EXPECT_EQ(4ul, model->getNumberOfTransitions());
1010 auto checker = this->createModelChecker(model);
1012 if (TypeParam::engine == DtmcEngine::PrismSparse || TypeParam::engine == DtmcEngine::JaniSparse) {
1013 std::unique_ptr<storm::modelchecker::CheckResult> result = checker->check(this->env(), tasks[0]);
1016 result = checker->check(this->env(), tasks[1]);
1018 result = checker->check(this->env(), tasks[2]);
1020 result = checker->check(this->env(), tasks[3]);
1022 result = checker->check(this->env(), tasks[4]);
1025 EXPECT_FALSE(checker->canHandle(tasks[0]));
1026 EXPECT_FALSE(checker->canHandle(tasks[1]));
1027 EXPECT_FALSE(checker->canHandle(tasks[2]));
1028 EXPECT_FALSE(checker->canHandle(tasks[3]));
1029 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.
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)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options)
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::shared_ptr< storm::models::symbolic::Model< LibraryType, ValueType > > buildSymbolicModel(storm::storage::SymbolicModelDescription const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas, bool buildFullModel=false, bool applyMaximumProgress=true)
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
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::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...
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes