#include "gtest/gtest.h" #include "storm-config.h" #ifdef STORM_HAVE_HYPRO #include "storm/modelchecker/multiobjective/pcaa.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ParetoCurveCheckResult.h" #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/storage/geometry/Polytope.h" #include "storm/storage/geometry/Hyperrectangle.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/SettingsManager.h" #include "storm/utility/storm.h" /* Rationals for MAs not supported at this point TEST(SparseMaPcaaModelCheckerTest, serverRationalNumbers) { std::string programFile = STORM_CPP_BASE_PATH "/examples/multiobjective/ma/server/server.ma"; std::string formulasAsString = "multi(Tmax=? [ F \"error\" ], Pmax=? [ F \"processB\" ]) "; // pareto // formulasAsString += "; \n multi(..)"; // programm, model, formula storm::prism::Program program = storm::parseProgram(programFile); program.checkValidity(); std::vector> formulas = storm::parseFormulasForProgram(formulasAsString, program); storm::generator::NextStateGeneratorOptions options(formulas); std::shared_ptr> ma = storm::builder::ExplicitModelBuilder(program, options).build()->as>(); storm::modelchecker::SparseMarkovAutomatonCslModelChecker> checker(*ma); std::unique_ptr result = checker.check(storm::modelchecker::CheckTask(*formulas[0], true)); ASSERT_TRUE(result->isParetoCurveCheckResult()); storm::RationalNumber p1 = storm::utility::convertNumber(11.0); p1 /= storm::utility::convertNumber(6.0); storm::RationalNumber p2 = storm::utility::convertNumber(1.0); p2 /= storm::utility::convertNumber(2.0); std::vector p = {p1, p2}; storm::RationalNumber q1 = storm::utility::convertNumber(29.0); q1 /= storm::utility::convertNumber(18.0); storm::RationalNumber q2 = storm::utility::convertNumber(2.0); q2 /= storm::utility::convertNumber(3.0); std::vector q = {q1, q2}; auto expectedAchievableValues = storm::storage::geometry::Polytope::createDownwardClosure(std::vector>({p,q})); EXPECT_TRUE(expectedAchievableValues->contains(result->asParetoCurveCheckResult().getUnderApproximation())); EXPECT_TRUE(result->asParetoCurveCheckResult().getUnderApproximation()->contains(expectedAchievableValues)); }*/ TEST(SparseMaPcaaModelCheckerTest, server) { std::string programFile = STORM_CPP_BASE_PATH "/examples/multiobjective/ma/server/server.ma"; std::string formulasAsString = "multi(Tmax=? [ F \"error\" ], Pmax=? [ F \"processB\" ]) "; // pareto // formulasAsString += "; \n multi(..)"; // programm, model, formula storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, ""); std::vector> formulas = storm::parseFormulasForPrismProgram(formulasAsString, program); std::shared_ptr> ma = storm::buildSparseModel(program, formulas, true)->as>(); storm::modelchecker::SparseMarkovAutomatonCslModelChecker> checker(*ma); std::unique_ptr result = storm::modelchecker::multiobjective::performPcaa(*ma, formulas[0]->asMultiObjectiveFormula()); ASSERT_TRUE(result->isParetoCurveCheckResult()); std::vector p = {11.0/6.0, 1.0/2.0}; std::vector q = {29.0/18.0, 2.0/3.0}; auto expectedAchievableValues = storm::storage::geometry::Polytope::createDownwardClosure(std::vector>({p,q})); // due to precision issues, we enlarge one of the polytopes before checking containement std::vector lb = {-storm::settings::getModule().getPrecision(), -storm::settings::getModule().getPrecision()}; std::vector ub = {storm::settings::getModule().getPrecision(), storm::settings::getModule().getPrecision()}; auto bloatingBox = storm::storage::geometry::Hyperrectangle(lb,ub).asPolytope(); EXPECT_TRUE(expectedAchievableValues->minkowskiSum(bloatingBox)->contains(result->asParetoCurveCheckResult().getUnderApproximation())); EXPECT_TRUE(result->asParetoCurveCheckResult().getUnderApproximation()->minkowskiSum(bloatingBox)->contains(expectedAchievableValues)); } #endif /* STORM_HAVE_HYPRO */