1#include "storm-config.h"
13class DoubleUnsoundEnvironment {
15 using ValueType = double;
16 static ValueType precision() {
19 static storm::Environment getEnv() {
20 storm::Environment env;
27class DoubleSoundEnvironment {
29 using ValueType = double;
30 static ValueType precision() {
33 static storm::Environment getEnv() {
34 storm::Environment env;
41class RationalExactEnvironment {
43 using ValueType = storm::RationalNumber;
44 static ValueType precision() {
47 static storm::Environment getEnv() {
48 storm::Environment env;
55template<
typename TestType>
56class PcaaWeightVectorCheckerTest :
public ::testing::Test {
58 using ValueType =
typename TestType::ValueType;
60 void SetUp()
override {
62 GTEST_SKIP() <<
"Z3 not available.";
66 storm::Environment env()
const {
67 return TestType::getEnv();
70 ValueType precision()
const {
71 return TestType::precision();
74 ValueType
parseNumber(std::string
const& input)
const {
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)));
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 {
95 return std::pair(std::move(mdp), std::move(formulas));
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());
103 [](ValueType acc, ValueType w) -> ValueType { return acc + storm::utility::abs(w); });
105 EXPECT_NO_THROW(wvChecker->check(this->env(), weightVector));
106 EXPECT_EQ(weightVector.size(), expectedPoint.size());
108 auto const point = wvChecker->getAchievablePoint();
109 for (uint64_t i = 0;
i < expectedPoint.size(); ++
i) {
114 ValueType
const prec = this->precision() / (
storm::utility::abs(weightVector[i]) / wvAbsSum);
115 EXPECT_NEAR(expectedPoint[i], point[i], prec)
118 <<
"Missmatch in dimension " <<
i <<
" with weight " << weightVector[
i] <<
" and precision " << prec <<
".";
121 auto const prec = this->precision() * wvLength;
122 EXPECT_NEAR(expectedSum, wvChecker->getOptimalWeightedSum(), prec);
124 EXPECT_NO_THROW(wvChecker->computeScheduler());
128typedef ::testing::Types<DoubleUnsoundEnvironment, DoubleSoundEnvironment, RationalExactEnvironment>
TestingTypes;
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);
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"));
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);
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"));
SolverEnvironment & solver()
void setForceSoundness(bool value)
void setForceExact(bool value)
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)
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)
T dotProduct(std::vector< T > const &firstOperand, std::vector< T > const &secondOperand)
Computes the dot product (aka scalar product) and returns the result.
std::string toString(std::vector< ValueType > const &vector)
Output vector as string.
bool isZero(ValueType const &a)
ValueType abs(ValueType const &number)
ValueType sqrt(ValueType const &number)
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes