1#include "storm-config.h"
19class FlowBigMEnvironment {
21 static storm::Environment getEnv() {
22 storm::Environment env;
31class FlowIndicatorEnvironment {
33 static storm::Environment getEnv() {
34 storm::Environment env;
43class BigMEnvironment {
45 static storm::Environment getEnv() {
46 storm::Environment env;
55class IndicatorEnvironment {
57 static storm::Environment getEnv() {
58 storm::Environment env;
67class BigMOrderEnvironment {
69 static storm::Environment getEnv() {
70 storm::Environment env;
79class IndicatorOrderEnvironment {
81 static storm::Environment getEnv() {
82 storm::Environment env;
91class RedundantEnvironment {
93 static storm::Environment getEnv() {
94 storm::Environment env;
103class RedundantOrderEnvironment {
105 static storm::Environment getEnv() {
106 storm::Environment env;
115template<
typename TestType>
116class MultiObjectiveSchedRestModelCheckerTest :
public ::testing::Test {
118 typedef storm::RationalNumber ValueType;
120 void SetUp()
override {
122 GTEST_SKIP() <<
"Z3 not available.";
126 bool isFlowEncoding()
const {
130 storm::Environment getPositionalDeterministicEnvironment() {
131 auto env = TestType::getEnv();
137 storm::Environment getGoalDeterministicEnvironment() {
138 auto env = TestType::getEnv();
145 typedef std::vector<storm::RationalNumber> Point;
147 ValueType
parseNumber(std::string
const& input)
const {
151 std::vector<Point> parsePoints(std::vector<std::string>
const& input) {
152 std::vector<Point> result;
153 for (
auto const& i : input) {
155 std::size_t pos1 = 0;
156 std::size_t pos2 =
i.find(
",");
157 while (pos2 != std::string::npos) {
158 currPoint.push_back(
parseNumber(
i.substr(pos1, pos2 - pos1)));
160 pos2 =
i.find(
",", pos1);
163 result.push_back(currPoint);
168 std::set<Point> setMinus(std::vector<Point>
const& lhs, std::vector<Point>
const& rhs) {
169 std::set<Point> result(lhs.begin(), lhs.end());
170 for (
auto const& r : rhs) {
171 for (
auto lIt = result.begin(); lIt != result.end(); ++lIt) {
181 std::string
toString(Point point,
bool asDouble) {
185 for (
auto const& pi : point) {
192 s << storm::utility::convertNumber<double>(pi);
201 std::string getDiffString(std::vector<Point>
const& expected, std::vector<Point>
const& actual) {
202 std::stringstream stream;
203 stream <<
"Unexpected set of Points:\n";
204 stream <<
" Expected | Actual | Point\n";
205 for (
auto const& p : expected) {
206 if (std::find(actual.begin(), actual.end(), p) != actual.end()) {
207 stream <<
" yes | yes | " <<
toString(p,
true) <<
"\n";
209 stream <<
" --> yes | no | " <<
toString(p,
true) <<
"\n";
212 for (
auto const& p : actual) {
213 if (std::find(expected.begin(), expected.end(), p) == expected.end()) {
214 stream <<
" --> no | yes | " <<
toString(p,
true) <<
"\n";
220 bool isSame(std::vector<Point>
const& expected, std::vector<Point>
const& actual, std::string& diffString) {
221 if (expected.size() != actual.size()) {
222 diffString = getDiffString(expected, actual);
225 for (
auto const& p : expected) {
226 if (std::find(actual.begin(), actual.end(), p) == actual.end()) {
227 diffString = getDiffString(expected, actual);
235 template<
typename SparseModelType>
236 bool testParetoFormula(storm::Environment
const& env, SparseModelType
const& model, storm::logic::Formula
const& formula,
237 std::vector<Point>
const& expected, std::string& errorString) {
239 if (!result->isParetoCurveCheckResult()) {
240 errorString =
"Not a ParetoCurveCheckResult";
243 return isSame(expected, result->template asExplicitParetoCurveCheckResult<ValueType>().getPoints(), errorString);
247typedef ::testing::Types<FlowBigMEnvironment, FlowIndicatorEnvironment, BigMEnvironment, IndicatorEnvironment, BigMOrderEnvironment, IndicatorOrderEnvironment,
248 RedundantEnvironment, RedundantOrderEnvironment>
253TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, steps) {
254 typedef typename TestFixture::ValueType
ValueType;
256 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_stairs.nm";
257 std::string constantsString =
"N=3";
258 std::string formulasAsString =
"multi(Pmax=? [ F y=1], Pmax=? [ F y=2 ]);";
259 formulasAsString +=
"multi(P>=0.375 [ F y=1], Pmax>=0.5 [ F y=2 ]);";
260 formulasAsString +=
"multi(P>=0.4 [ F y=1], Pmax>=0.4 [ F y=2 ]);";
261 formulasAsString +=
"multi(Pmax=? [ F y=1], Pmax>=0.4 [ F y=2 ]);";
262 formulasAsString +=
"multi(Pmax=? [ F y=1], Pmax>=0.9 [ F y=2 ]);";
267 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
269 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
271 std::string errorString;
274 uint64_t formulaIndex = 0;
276 auto expected = this->parsePoints({
"0.875,0",
"0,0.875",
"0.125,0.75",
"0.25,0.625",
"0.375,0.5",
"0.5,0.375",
"0.625,0.25",
"0.75,0.125"});
277 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
282 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
283 EXPECT_TRUE(result->template asExplicitQualitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()]);
288 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
289 EXPECT_FALSE(result->template asExplicitQualitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()]);
294 ASSERT_TRUE(result->isExplicitQuantitativeCheckResult());
296 EXPECT_EQ(result->template asExplicitQuantitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()], expected);
301 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
302 EXPECT_FALSE(result->template asExplicitQualitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()]);
306TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, mecs) {
307 typedef typename TestFixture::ValueType
ValueType;
308 typedef typename TestFixture::Point Point;
309 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_mecs.nm";
310 std::string constantsString =
"";
311 std::string formulasAsString =
"multi(Pmin=? [ F x=3], Pmax=? [ F x=4 ]);";
312 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t1\"]);";
313 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t2\"]);";
314 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t2\"], Pmax=? [F \"t1\"]);";
315 formulasAsString +=
"\nmulti(R{\"test\"}<=0 [C], P<=1 [F \"t2\"], P>=0 [F \"t1\"]);";
316 formulasAsString +=
"\nmulti(R{\"test\"}<=1 [C], P<=1 [F \"t2\"], P>=0.1 [F \"t1\"]);";
320 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
322 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
324 std::string errorString;
325 std::vector<Point> expected;
329 uint64_t formulaIndex = 0;
330 expected = this->parsePoints({
"0.5,0.5",
"1,1"});
331 if (this->isFlowEncoding()) {
333 storm::exceptions::InvalidOperationException);
335 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
339 expected = this->parsePoints({
"0,0"});
340 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
343 expected = this->parsePoints({
"0,1"});
344 if (this->isFlowEncoding()) {
346 storm::exceptions::InvalidOperationException);
348 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
352 expected = this->parsePoints({
"0,1,0",
"2,1,1"});
353 if (this->isFlowEncoding()) {
355 storm::exceptions::InvalidOperationException);
357 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
361 if (this->isFlowEncoding()) {
364 storm::exceptions::InvalidOperationException);
367 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
368 EXPECT_TRUE(result->template asExplicitQualitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()]);
373 if (this->isFlowEncoding()) {
376 storm::exceptions::InvalidOperationException);
379 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
380 EXPECT_FALSE(result->template asExplicitQualitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()]);
385TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, compromise) {
386 typedef typename TestFixture::ValueType
ValueType;
387 typedef typename TestFixture::Point Point;
388 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_compromise.nm";
389 std::string constantsString =
"";
390 std::string formulasAsString =
"multi(Pmax=? [ F x=1], Pmax=? [ F x=2 ]);";
391 formulasAsString +=
"\nmulti(R{\"test\"}min=? [F x=1], Pmax=? [F x=1 ]);";
392 formulasAsString +=
"\nmulti(Pmax=? [F x=1], Pmax=? [F x=2 ], Pmax=? [F x=3 ]);";
393 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F x=2 ], Pmin=? [F x=3]);";
397 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
399 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
401 std::string errorString;
402 std::vector<Point> expected;
406 uint64_t formulaIndex = 0;
407 expected = this->parsePoints({
"1,0",
"0,1",
"0.3,3/7"});
408 if (this->isFlowEncoding()) {
410 storm::exceptions::InvalidOperationException);
412 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
416 expected = this->parsePoints({
"0,0.3",
"2,1"});
417 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
420 expected = this->parsePoints({
"1,0,0",
"0,1,0",
"0.3,3/7,4/7"});
421 if (this->isFlowEncoding()) {
423 storm::exceptions::InvalidOperationException);
425 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
429 expected = this->parsePoints({
"0,1,0",
"0,3/7,4/7"});
430 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
432 env = this->getGoalDeterministicEnvironment();
435 expected = this->parsePoints({
"1,1"});
436 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
439 expected = this->parsePoints({
"0,0.3",
"2,1"});
440 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
443 expected = this->parsePoints({
"1,1,0",
"1,3/7,4/7"});
444 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
447 expected = this->parsePoints({
"0,1,0",
"0,3/7,4/7"});
448 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
451TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, infrew) {
452 typedef typename TestFixture::ValueType
ValueType;
453 typedef typename TestFixture::Point Point;
454 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_infrew.nm";
455 std::string constantsString =
"";
456 std::string formulasAsString =
"multi(R{\"one\"}min=? [ F x=2], R{\"two\"}min=? [ C ]);";
460 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
462 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
464 std::string errorString;
465 std::vector<Point> expected;
469 uint64_t formulaIndex = 0;
470 expected = this->parsePoints({
"10,1"});
471 if (this->isFlowEncoding()) {
473 storm::exceptions::InvalidOperationException);
475 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
478 env = this->getGoalDeterministicEnvironment();
481 expected = this->parsePoints({
"0,1"});
482 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
SolverEnvironment & solver()
ModelCheckerEnvironment & modelchecker()
MultiObjectiveModelCheckerEnvironment & multi()
EncodingType const & getEncodingType() const
@ Classic
Pick automatically.
@ Flow
The classic backwards encoding.
void setUseBsccOrderEncoding(bool value)
void setUseRedundantBsccConstraints(bool value)
void setEncodingType(EncodingType const &value)
void setSchedulerRestriction(storm::storage::SchedulerClass const &value)
void setUseIndicatorConstraints(bool value)
void setForceExact(bool value)
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)
SFTBDDChecker::ValueType ValueType
std::string toString(DFTElementType const &type)
std::unique_ptr< CheckResult > performMultiObjectiveModelChecking(Environment const &env, SparseModelType const &model, storm::logic::MultiObjectiveFormula const &formula, bool produceScheduler)
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)
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)