1#include "storm-config.h"
17#ifdef STORM_HAVE_Z3_OPTIMIZE
21class FlowBigMEnvironment {
33class FlowIndicatorEnvironment {
45class BigMEnvironment {
57class IndicatorEnvironment {
69class BigMOrderEnvironment {
81class IndicatorOrderEnvironment {
93class RedundantEnvironment {
105class RedundantOrderEnvironment {
117template<
typename TestType>
118class MultiObjectiveSchedRestModelCheckerTest :
public ::testing::Test {
122 bool isFlowEncoding()
const {
127 auto env = TestType::getEnv();
134 auto env = TestType::getEnv();
141 typedef std::vector<storm::RationalNumber> Point;
144 return storm::utility::convertNumber<ValueType>(input);
147 std::vector<Point> parsePoints(std::vector<std::string>
const& input) {
148 std::vector<Point> result;
149 for (
auto const& i : input) {
151 std::size_t pos1 = 0;
152 std::size_t pos2 =
i.find(
",");
153 while (pos2 != std::string::npos) {
154 currPoint.push_back(
parseNumber(
i.substr(pos1, pos2 - pos1)));
156 pos2 =
i.find(
",", pos1);
159 result.push_back(currPoint);
164 std::set<Point> setMinus(std::vector<Point>
const& lhs, std::vector<Point>
const& rhs) {
165 std::set<Point> result(lhs.begin(), lhs.end());
166 for (
auto const& r : rhs) {
167 for (
auto lIt = result.begin(); lIt != result.end(); ++lIt) {
177 std::string
toString(Point point,
bool asDouble) {
181 for (
auto const& pi : point) {
188 s << storm::utility::convertNumber<double>(pi);
197 std::string getDiffString(std::vector<Point>
const& expected, std::vector<Point>
const& actual) {
198 std::stringstream stream;
199 stream <<
"Unexpected set of Points:\n";
200 stream <<
" Expected | Actual | Point\n";
201 for (
auto const& p : expected) {
202 if (std::find(actual.begin(), actual.end(), p) != actual.end()) {
203 stream <<
" yes | yes | " <<
toString(p,
true) <<
"\n";
205 stream <<
" --> yes | no | " <<
toString(p,
true) <<
"\n";
208 for (
auto const& p : actual) {
209 if (std::find(expected.begin(), expected.end(), p) == expected.end()) {
210 stream <<
" --> no | yes | " <<
toString(p,
true) <<
"\n";
216 bool isSame(std::vector<Point>
const& expected, std::vector<Point>
const& actual, std::string& diffString) {
217 if (expected.size() != actual.size()) {
218 diffString = getDiffString(expected, actual);
221 for (
auto const& p : expected) {
222 if (std::find(actual.begin(), actual.end(), p) == actual.end()) {
223 diffString = getDiffString(expected, actual);
231 template<
typename SparseModelType>
233 std::vector<Point>
const& expected, std::string& errorString) {
235 if (!result->isParetoCurveCheckResult()) {
236 errorString =
"Not a ParetoCurveCheckResult";
239 return isSame(expected, result->template asExplicitParetoCurveCheckResult<ValueType>().getPoints(), errorString);
243typedef ::testing::Types<FlowBigMEnvironment, FlowIndicatorEnvironment, BigMEnvironment, IndicatorEnvironment, BigMOrderEnvironment, IndicatorOrderEnvironment,
244 RedundantEnvironment, RedundantOrderEnvironment>
249TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, steps) {
250 typedef typename TestFixture::ValueType
ValueType;
252 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_stairs.nm";
253 std::string constantsString =
"N=3";
254 std::string formulasAsString =
"multi(Pmax=? [ F y=1], Pmax=? [ F y=2 ]);";
255 formulasAsString +=
"multi(P>=0.375 [ F y=1], Pmax>=0.5 [ F y=2 ]);";
256 formulasAsString +=
"multi(P>=0.4 [ F y=1], Pmax>=0.4 [ F y=2 ]);";
257 formulasAsString +=
"multi(Pmax=? [ F y=1], Pmax>=0.4 [ F y=2 ]);";
258 formulasAsString +=
"multi(Pmax=? [ F y=1], Pmax>=0.9 [ F y=2 ]);";
263 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
265 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
266 storm::api::buildSparseModel<ValueType>(program, formulas)->template as<storm::models::sparse::Mdp<ValueType>>();
267 std::string errorString;
270 uint64_t formulaIndex = 0;
272 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"});
273 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
278 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
279 EXPECT_TRUE(result->asExplicitQualitativeCheckResult()[*mdp->getInitialStates().begin()]);
284 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
285 EXPECT_FALSE(result->asExplicitQualitativeCheckResult()[*mdp->getInitialStates().begin()]);
290 ASSERT_TRUE(result->isExplicitQuantitativeCheckResult());
291 auto expected = storm::utility::convertNumber<ValueType, std::string>(
"0.375");
292 EXPECT_EQ(result->template asExplicitQuantitativeCheckResult<ValueType>()[*mdp->getInitialStates().begin()], expected);
297 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
298 EXPECT_FALSE(result->asExplicitQualitativeCheckResult()[*mdp->getInitialStates().begin()]);
302TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, mecs) {
303 typedef typename TestFixture::ValueType
ValueType;
304 typedef typename TestFixture::Point Point;
305 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_mecs.nm";
306 std::string constantsString =
"";
307 std::string formulasAsString =
"multi(Pmin=? [ F x=3], Pmax=? [ F x=4 ]);";
308 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t1\"]);";
309 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t2\"]);";
310 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F \"t2\"], Pmax=? [F \"t1\"]);";
311 formulasAsString +=
"\nmulti(R{\"test\"}<=0 [C], P<=1 [F \"t2\"], P>=0 [F \"t1\"]);";
312 formulasAsString +=
"\nmulti(R{\"test\"}<=1 [C], P<=1 [F \"t2\"], P>=0.1 [F \"t1\"]);";
316 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
318 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
319 storm::api::buildSparseModel<ValueType>(program, formulas)->template as<storm::models::sparse::Mdp<ValueType>>();
320 std::string errorString;
321 std::vector<Point> expected;
325 uint64_t formulaIndex = 0;
326 expected = this->parsePoints({
"0.5,0.5",
"1,1"});
327 if (this->isFlowEncoding()) {
329 storm::exceptions::InvalidOperationException);
331 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
335 expected = this->parsePoints({
"0,0"});
336 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
339 expected = this->parsePoints({
"0,1"});
340 if (this->isFlowEncoding()) {
342 storm::exceptions::InvalidOperationException);
344 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
348 expected = this->parsePoints({
"0,1,0",
"2,1,1"});
349 if (this->isFlowEncoding()) {
351 storm::exceptions::InvalidOperationException);
353 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
357 if (this->isFlowEncoding()) {
360 storm::exceptions::InvalidOperationException);
363 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
364 EXPECT_TRUE(result->asExplicitQualitativeCheckResult()[*mdp->getInitialStates().begin()]);
369 if (this->isFlowEncoding()) {
372 storm::exceptions::InvalidOperationException);
375 ASSERT_TRUE(result->isExplicitQualitativeCheckResult());
376 EXPECT_FALSE(result->asExplicitQualitativeCheckResult()[*mdp->getInitialStates().begin()]);
381TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, compromise) {
382 typedef typename TestFixture::ValueType
ValueType;
383 typedef typename TestFixture::Point Point;
384 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_compromise.nm";
385 std::string constantsString =
"";
386 std::string formulasAsString =
"multi(Pmax=? [ F x=1], Pmax=? [ F x=2 ]);";
387 formulasAsString +=
"\nmulti(R{\"test\"}min=? [F x=1], Pmax=? [F x=1 ]);";
388 formulasAsString +=
"\nmulti(Pmax=? [F x=1], Pmax=? [F x=2 ], Pmax=? [F x=3 ]);";
389 formulasAsString +=
"\nmulti(R{\"test\"}min=? [C], Pmin=? [F x=2 ], Pmin=? [F x=3]);";
393 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
395 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
396 storm::api::buildSparseModel<ValueType>(program, formulas)->template as<storm::models::sparse::Mdp<ValueType>>();
397 std::string errorString;
398 std::vector<Point> expected;
402 uint64_t formulaIndex = 0;
403 expected = this->parsePoints({
"1,0",
"0,1",
"0.3,3/7"});
404 if (this->isFlowEncoding()) {
406 storm::exceptions::InvalidOperationException);
408 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
412 expected = this->parsePoints({
"0,0.3",
"2,1"});
413 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
416 expected = this->parsePoints({
"1,0,0",
"0,1,0",
"0.3,3/7,4/7"});
417 if (this->isFlowEncoding()) {
419 storm::exceptions::InvalidOperationException);
421 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
425 expected = this->parsePoints({
"0,1,0",
"0,3/7,4/7"});
426 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
428 env = this->getGoalDeterministicEnvironment();
431 expected = this->parsePoints({
"1,1"});
432 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
435 expected = this->parsePoints({
"0,0.3",
"2,1"});
436 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
439 expected = this->parsePoints({
"1,1,0",
"1,3/7,4/7"});
440 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
443 expected = this->parsePoints({
"0,1,0",
"0,3/7,4/7"});
444 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
447TYPED_TEST(MultiObjectiveSchedRestModelCheckerTest, infrew) {
448 typedef typename TestFixture::ValueType
ValueType;
449 typedef typename TestFixture::Point Point;
450 std::string programFile = STORM_TEST_RESOURCES_DIR
"/mdp/multiobj_infrew.nm";
451 std::string constantsString =
"";
452 std::string formulasAsString =
"multi(R{\"one\"}min=? [ F x=2], R{\"two\"}min=? [ C ]);";
456 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
458 std::shared_ptr<storm::models::sparse::Mdp<ValueType>> mdp =
459 storm::api::buildSparseModel<ValueType>(program, formulas)->template as<storm::models::sparse::Mdp<ValueType>>();
460 std::string errorString;
461 std::vector<Point> expected;
465 uint64_t formulaIndex = 0;
466 expected = this->parsePoints({
"10,1"});
467 if (this->isFlowEncoding()) {
469 storm::exceptions::InvalidOperationException);
471 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
474 env = this->getGoalDeterministicEnvironment();
477 expected = this->parsePoints({
"0,1"});
478 EXPECT_TRUE(this->testParetoFormula(env, mdp, *formulas[formulaIndex], expected, errorString)) << errorString;
SolverEnvironment & solver()
ModelCheckerEnvironment & modelchecker()
MultiObjectiveModelCheckerEnvironment & multi()
@ 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)
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)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)