diff --git a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index f6cf8ab23..5eb52f1fc 100644 --- a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -211,13 +211,16 @@ namespace storm { template std::vector SparseMdpPrctlHelper::computeReachabilityRewardsHelper(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::function(uint_fast64_t, storm::storage::SparseMatrix const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + + std::vector nondeterminsticChoiceIndices = transitionMatrix.getRowGroupIndices(); + // Determine which states have a reward of infinity by definition. storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true); if (dir == OptimizationDirection::Minimize) { - infinityStates = storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates); + infinityStates = storm::utility::graph::performProb1E(transitionMatrix, nondeterminsticChoiceIndices, backwardTransitions, trueStates, targetStates); } else { - infinityStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates); + infinityStates = storm::utility::graph::performProb1A(transitionMatrix, nondeterminsticChoiceIndices, backwardTransitions, trueStates, targetStates); } infinityStates.complement(); storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates; @@ -245,6 +248,21 @@ namespace storm { // Prepare the right-hand side of the equation system. std::vector b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates); + // This also means that -- when minimizing -- we have to set the entries to infinity that have + // any successor that is an "infinity state". This prevents the action from "being taken" and + // forces the choice that leads to a reward less than infinity. + uint_fast64_t currentRow = 0; + for (auto state : maybeStates) { + for (uint_fast64_t row = nondeterminsticChoiceIndices[state]; row < nondeterminsticChoiceIndices[state + 1]; ++row, ++currentRow) { + for (auto const& element : transitionMatrix.getRow(row)) { + if (infinityStates.get(element.getColumn())) { + b[currentRow] = storm::utility::infinity(); + break; + } + } + } + } + // Create vector for results for maybe states. std::vector x(maybeStates.getNumberOfSetBits()); diff --git a/test/functional/builder/ExplicitPrismModelBuilderTest.cpp b/test/functional/builder/ExplicitPrismModelBuilderTest.cpp index 3387f730d..080b6c16f 100644 --- a/test/functional/builder/ExplicitPrismModelBuilderTest.cpp +++ b/test/functional/builder/ExplicitPrismModelBuilderTest.cpp @@ -10,27 +10,27 @@ TEST(ExplicitPrismModelBuilderTest, Dtmc) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(13ul, model->getNumberOfStates()); EXPECT_EQ(20ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/brp-16-2.pm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(677ul, model->getNumberOfStates()); EXPECT_EQ(867ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/crowds-5-5.pm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(8607ul, model->getNumberOfStates()); EXPECT_EQ(15113ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader-3-5.pm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(273ul, model->getNumberOfStates()); EXPECT_EQ(397ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/nand-5-2.pm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(1728ul, model->getNumberOfStates()); EXPECT_EQ(2505ul, model->getNumberOfTransitions()); } @@ -41,27 +41,27 @@ TEST(ExplicitPrismModelBuilderTest, Ctmc) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/cluster2.sm"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(276ul, model->getNumberOfStates()); EXPECT_EQ(1120ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/embedded2.sm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(3478ul, model->getNumberOfStates()); EXPECT_EQ(14639ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/polling2.sm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(12ul, model->getNumberOfStates()); EXPECT_EQ(22ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/fms2.sm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(810ul, model->getNumberOfStates()); EXPECT_EQ(3699ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/tandem5.sm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(66ul, model->getNumberOfStates()); EXPECT_EQ(189ul, model->getNumberOfTransitions()); } @@ -69,32 +69,32 @@ TEST(ExplicitPrismModelBuilderTest, Ctmc) { TEST(ExplicitPrismModelBuilderTest, Mdp) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/two_dice.nm"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(169ul, model->getNumberOfStates()); EXPECT_EQ(436ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader3.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(364ul, model->getNumberOfStates()); EXPECT_EQ(654ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/coin2-2.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(272ul, model->getNumberOfStates()); EXPECT_EQ(492ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/csma2-2.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(1038ul, model->getNumberOfStates()); EXPECT_EQ(1282ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/firewire3-0.5.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(4093ul, model->getNumberOfStates()); EXPECT_EQ(5585ul, model->getNumberOfTransitions()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/wlan0-2-2.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); EXPECT_EQ(37ul, model->getNumberOfStates()); EXPECT_EQ(59ul, model->getNumberOfTransitions()); } \ No newline at end of file diff --git a/test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp index 420a81530..601851b05 100644 --- a/test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxCtmcCslModelCheckerTest.cpp @@ -34,7 +34,7 @@ TEST(GmmxxCtmcCslModelCheckerTest, Cluster) { #endif options.buildAllRewardModels = false; options.rewardModelsToBuild.insert("num_repairs"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -117,7 +117,7 @@ TEST(GmmxxCtmcCslModelCheckerTest, Embedded) { #endif options.buildAllRewardModels = false; options.rewardModelsToBuild.insert("up"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -179,7 +179,7 @@ TEST(GmmxxCtmcCslModelCheckerTest, Polling) { std::shared_ptr formula(nullptr); // Build the model. - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -226,7 +226,7 @@ TEST(GmmxxCtmcCslModelCheckerTest, Tandem) { typename storm::builder::ExplicitPrismModelBuilder::Options options; #endif options.rewardModelsToBuild.insert("customers"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); diff --git a/test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp b/test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp index c37c7b7bc..bebc48930 100644 --- a/test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp +++ b/test/functional/modelchecker/NativeCtmcCslModelCheckerTest.cpp @@ -32,7 +32,7 @@ TEST(NativeCtmcCslModelCheckerTest, Cluster) { #endif options.buildAllRewardModels = false; options.rewardModelsToBuild.insert("num_repairs"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -108,7 +108,7 @@ TEST(NativeCtmcCslModelCheckerTest, Embedded) { #endif options.buildAllRewardModels = false; options.rewardModelsToBuild.insert("up"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -163,7 +163,7 @@ TEST(NativeCtmcCslModelCheckerTest, Polling) { std::shared_ptr formula(nullptr); // Build the model. - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); @@ -204,7 +204,7 @@ TEST(NativeCtmcCslModelCheckerTest, Tandem) { #endif options.buildAllRewardModels = false; options.rewardModelsToBuild.insert("customers"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options); ASSERT_EQ(storm::models::ModelType::Ctmc, model->getType()); std::shared_ptr> ctmc = model->as>(); uint_fast64_t initialState = *ctmc->getInitialStates().begin(); diff --git a/test/functional/permissiveschedulers/MilpPermissiveSchedulerTest.cpp b/test/functional/permissiveschedulers/MilpPermissiveSchedulerTest.cpp index 894d1df12..5dec78f8d 100644 --- a/test/functional/permissiveschedulers/MilpPermissiveSchedulerTest.cpp +++ b/test/functional/permissiveschedulers/MilpPermissiveSchedulerTest.cpp @@ -28,7 +28,7 @@ TEST(MilpPermissiveSchedulerTest, DieSelection) { options.addConstantDefinitionsFromString(program, ""); options.buildCommandLabels = true; - std::shared_ptr> mdp = storm::builder::ExplicitPrismModelBuilder::translateProgram(program, options)->as>(); + std::shared_ptr> mdp = storm::builder::ExplicitPrismModelBuilder().translateProgram(program, options)->as>(); boost::optional> perms = storm::ps::computePermissiveSchedulerViaMILP<>(*mdp, formula02); EXPECT_NE(perms, boost::none); diff --git a/test/functional/utility/GraphTest.cpp b/test/functional/utility/GraphTest.cpp index d58de5ca9..969bd46fe 100644 --- a/test/functional/utility/GraphTest.cpp +++ b/test/functional/utility/GraphTest.cpp @@ -90,7 +90,7 @@ TEST(GraphTest, SymbolicProb01MinMax) { TEST(GraphTest, ExplicitProb01) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/crowds-5-5.pm"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc); @@ -111,7 +111,7 @@ TEST(GraphTest, ExplicitProb01) { TEST(GraphTest, ExplicitProb01MinMax) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/leader3.nm"); - std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + std::shared_ptr> model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_TRUE(model->getType() == storm::models::ModelType::Mdp); @@ -126,7 +126,7 @@ TEST(GraphTest, ExplicitProb01MinMax) { EXPECT_EQ(364ul, statesWithProbability01.second.getNumberOfSetBits()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/coin2-2.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_TRUE(model->getType() == storm::models::ModelType::Mdp); @@ -147,7 +147,7 @@ TEST(GraphTest, ExplicitProb01MinMax) { EXPECT_EQ(35ul, statesWithProbability01.second.getNumberOfSetBits()); program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/csma2-2.nm"); - model = storm::builder::ExplicitPrismModelBuilder::translateProgram(program); + model = storm::builder::ExplicitPrismModelBuilder().translateProgram(program); ASSERT_TRUE(model->getType() == storm::models::ModelType::Mdp);