Storm 1.13.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
PcaaWeightVectorCheckerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
5#include "storm/api/storm.h"
10
11namespace {
12
13class DoubleUnsoundEnvironment {
14 public:
15 using ValueType = double;
16 static ValueType precision() {
17 return 1e-6;
18 }
19 static storm::Environment getEnv() {
20 storm::Environment env;
21 env.solver().setForceSoundness(false);
22 env.solver().setForceExact(false);
23 return env;
24 }
25};
26
27class DoubleSoundEnvironment {
28 public:
29 using ValueType = double;
30 static ValueType precision() {
31 return 1e-6;
32 }
33 static storm::Environment getEnv() {
34 storm::Environment env;
35 env.solver().setForceSoundness(true);
36 env.solver().setForceExact(false);
37 return env;
38 }
39};
40
41class RationalExactEnvironment {
42 public:
43 using ValueType = storm::RationalNumber;
44 static ValueType precision() {
46 }
47 static storm::Environment getEnv() {
48 storm::Environment env;
49 env.solver().setForceSoundness(false);
50 env.solver().setForceExact(true);
51 return env;
52 }
53};
54
55template<typename TestType>
56class PcaaWeightVectorCheckerTest : public ::testing::Test {
57 public:
58 using ValueType = typename TestType::ValueType;
59
60 void SetUp() override {
61#ifndef STORM_HAVE_Z3
62 GTEST_SKIP() << "Z3 not available.";
63#endif
64 }
65
66 storm::Environment env() const {
67 return TestType::getEnv();
68 }
69
70 ValueType precision() const {
71 return TestType::precision();
72 }
73
74 ValueType parseNumber(std::string const& input) const {
76 }
77
78 std::vector<ValueType> parseVector(std::string const& input) const {
79 auto const pos = input.rfind(',');
80 if (pos != std::string::npos) {
81 auto result = parseVector(input.substr(0, pos));
82 result.push_back(parseNumber(input.substr(pos + 1)));
83 return result;
84 } else {
85 return {parseNumber(input)};
86 }
87 }
88
89 std::pair<std::shared_ptr<storm::models::sparse::Mdp<ValueType>>, std::vector<std::shared_ptr<storm::logic::Formula const>>> getMdpAndFormulasFromPrism(
90 std::string const& prismFileString, std::string const& constantsString, std::string const& formulasString) const {
91 auto program = storm::api::parseProgram(prismFileString);
92 program = storm::utility::prism::preprocess(program, constantsString);
94 auto mdp = storm::api::buildSparseModel<ValueType>(program, formulas)->template as<storm::models::sparse::Mdp<ValueType>>();
95 return std::pair(std::move(mdp), std::move(formulas));
96 }
97
98 void testWeightVectorCheck(auto const& wvChecker, std::vector<ValueType> const& weightVector, std::vector<ValueType> const& expectedPoint,
99 ValueType const& expectedSum) {
100 wvChecker->setWeightedPrecision(this->precision());
101 ValueType const wvLength = storm::utility::sqrt(storm::utility::vector::dotProduct(weightVector, weightVector));
102 ValueType const wvAbsSum = std::accumulate(weightVector.begin(), weightVector.end(), storm::utility::zero<ValueType>(),
103 [](ValueType acc, ValueType w) -> ValueType { return acc + storm::utility::abs(w); });
104
105 EXPECT_NO_THROW(wvChecker->check(this->env(), weightVector));
106 EXPECT_EQ(weightVector.size(), expectedPoint.size());
107 // Check point
108 auto const point = wvChecker->getAchievablePoint();
109 for (uint64_t i = 0; i < expectedPoint.size(); ++i) {
110 if (storm::utility::isZero(weightVector[i])) {
111 continue;
112 }
113 // Dimensions with relatively low weight don't require as much precision.
114 ValueType const prec = this->precision() / (storm::utility::abs(weightVector[i]) / wvAbsSum);
115 EXPECT_NEAR(expectedPoint[i], point[i], prec)
116 << "Found point " << storm::utility::vector::toString(point) << " for weight vector " << storm::utility::vector::toString(weightVector)
117 << "does not match expected point " << storm::utility::vector::toString(expectedPoint) << ".\n"
118 << "Missmatch in dimension " << i << " with weight " << weightVector[i] << " and precision " << prec << ".";
119 }
120 // Check weighted sum
121 auto const prec = this->precision() * wvLength;
122 EXPECT_NEAR(expectedSum, wvChecker->getOptimalWeightedSum(), prec);
123 // Check if scheduler compuatation finishes without throwing.
124 EXPECT_NO_THROW(wvChecker->computeScheduler());
125 }
126};
127
128typedef ::testing::Types<DoubleUnsoundEnvironment, DoubleSoundEnvironment, RationalExactEnvironment> TestingTypes;
129TYPED_TEST_SUITE(PcaaWeightVectorCheckerTest, TestingTypes, );
130
131TYPED_TEST(PcaaWeightVectorCheckerTest, oneDimWalk) {
132 auto [mdp, formulas] = this->getMdpAndFormulasFromPrism(STORM_TEST_RESOURCES_DIR "/mdp/one_dim_walk.nm", "N=2",
133 "multi(R{\"l\"}min=? [F x=N | x=0 ], R{\"r\"}min=? [F x=N | x=0 ]);");
134 using MdpType = typename std::remove_reference_t<decltype(*mdp)>;
136 this->env(), *mdp, formulas[0]->asMultiObjectiveFormula(), true);
137 auto const wvChecker = storm::modelchecker::multiobjective::createWeightVectorChecker(preprocessresult);
138 this->testWeightVectorCheck(wvChecker, this->parseVector("2/3,1/3"), this->parseVector("0,2"), this->parseNumber("-2/3"));
139 this->testWeightVectorCheck(wvChecker, this->parseVector("1/4,3/4"), this->parseVector("2,0"), this->parseNumber("-1/2"));
140 this->testWeightVectorCheck(wvChecker, this->parseVector("1000,1"), this->parseVector("0,2"), this->parseNumber("-2"));
141}
142
143TYPED_TEST(PcaaWeightVectorCheckerTest, two_dice) {
144 auto [mdp, formulas] = this->getMdpAndFormulasFromPrism(STORM_TEST_RESOURCES_DIR "/mdp/two_dice.nm", "", "multi(Tmax=? [F s1=7 ], Tmax=? [F s2=7 ]);");
145 using MdpType = typename std::remove_reference_t<decltype(*mdp)>;
147 this->env(), *mdp, formulas[0]->asMultiObjectiveFormula(), true);
148 auto const wvChecker = storm::modelchecker::multiobjective::createWeightVectorChecker(preprocessresult);
149 this->testWeightVectorCheck(wvChecker, this->parseVector("9/10,1/10"), this->parseVector("22/3,17/3"), this->parseNumber("43/6"));
150 this->testWeightVectorCheck(wvChecker, this->parseVector("300,3"), this->parseVector("22/3,17/3"), this->parseNumber("2217"));
151 this->testWeightVectorCheck(wvChecker, this->parseVector("-3/4,-1/4"), this->parseVector("11/3,22/3"), this->parseNumber("-55/12"));
152 this->testWeightVectorCheck(wvChecker, this->parseVector("3/4,-1/4"), this->parseVector("22/3,11/3"), this->parseNumber("55/12"));
153 this->testWeightVectorCheck(wvChecker, this->parseVector("-3/4,1/4"), this->parseVector("11/3,22/3"), this->parseNumber("-11/12"));
154}
155
156} // namespace
SolverEnvironment & solver()
static ReturnType preprocess(Environment const &env, SparseModelType const &originalModel, storm::logic::MultiObjectiveFormula const &originalFormula, bool produceScheduler)
Preprocesses the given model w.r.t.
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)
Definition builder.h:109
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::unique_ptr< PcaaWeightVectorChecker< ModelType > > createWeightVectorChecker(preprocessing::SparseMultiObjectivePreprocessorResult< ModelType > const &preprocessorResult)
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)
Definition prism.cpp:13
T dotProduct(std::vector< T > const &firstOperand, std::vector< T > const &secondOperand)
Computes the dot product (aka scalar product) and returns the result.
Definition vector.h:473
std::string toString(std::vector< ValueType > const &vector)
Output vector as string.
Definition vector.h:1179
bool isZero(ValueType const &a)
Definition constants.cpp:39
ValueType abs(ValueType const &number)
ValueType zero()
Definition constants.cpp:24
ValueType sqrt(ValueType const &number)
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
Definition GraphTest.cpp:62
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
Definition GraphTest.cpp:59