60TEST(ToStateBasedObservationTransformer, PassesLocalActionIndicesToCallback) {
61 auto const mdp = buildMdp();
62 std::vector<std::pair<uint64_t, uint64_t>> observedStateActions;
66 [&observedStateActions](uint64_t state, uint64_t action, uint64_t) {
67 observedStateActions.emplace_back(state, action);
72 EXPECT_NE(
nullptr, result);
73 EXPECT_EQ((std::vector<std::pair<uint64_t, uint64_t>>{{0, 0}, {0, 1}, {1, 0}, {1, 1}, {2, 0}}), observedStateActions);
76TEST(ToStateBasedObservationTransformer, KeepsNonInitialStateWithoutIncomingTransitions) {
77 auto const mdp = std::make_shared<storm::models::sparse::Mdp<double>>(buildComponentsWithUnreachableState());
82 ASSERT_NE(
nullptr, result);
83 EXPECT_EQ(3u, result->getNumberOfStates());
84 EXPECT_EQ(3u, result->getNumberOfChoices());
85 EXPECT_EQ((std::vector<uint32_t>{0, 1, 0}), result->getObservations());
86 EXPECT_TRUE(result->getStateLabeling().getStates(
"isolated").get(2));
87 EXPECT_FALSE(result->getInitialStates().get(2));
88 EXPECT_EQ(1u, result->getTransitionMatrix().getRowGroupSize(2));
89 EXPECT_EQ(1u, result->getTransitionMatrix().getRow(2).begin()->getColumn());
90 EXPECT_EQ(7.0, result->getRewardModel(
"r").getStateReward(2));
91 EXPECT_EQ(3.0, result->getRewardModel(
"r").getStateActionReward(2));
94TEST(ToStateBasedObservationTransformer, RewardAwareTransformationKeepsUnreachableState) {
95 auto components = buildComponentsWithUnreachableState();
96 components.observabilityClasses = std::vector<uint32_t>{0, 1, 2};
97 auto const pomdp = std::make_shared<storm::models::sparse::Pomdp<double>>(std::move(components));
101 ASSERT_NE(
nullptr, result);
102 EXPECT_EQ(4u, result->getNumberOfStates());
103 EXPECT_EQ((std::vector<uint32_t>{0, 3, 4, 0}), result->getObservations());
104 EXPECT_TRUE(result->getStateLabeling().getStates(
"isolated").get(3));
105 EXPECT_EQ(7.0, result->getRewardModel(
"r").getStateReward(3));
106 EXPECT_EQ(3.0, result->getRewardModel(
"r").getStateActionReward(3));
109TEST(ToStateBasedObservationTransformer, DropsUnreachableStateWithDifferentActionCount) {
126 ASSERT_NE(
nullptr, result);
127 EXPECT_EQ(2u, result->getNumberOfStates());
128 EXPECT_EQ(2u, result->getNumberOfChoices());
129 EXPECT_EQ((std::vector<uint32_t>{0, 0}), result->getObservations());
130 for (uint64_t state = 0; state < result->getNumberOfStates(); ++state) {
131 for (
auto peer : result->getStatesWithObservation(result->getObservation(state))) {
132 EXPECT_EQ(result->getTransitionMatrix().getRowGroupSize(state), result->getTransitionMatrix().getRowGroupSize(peer));
162TEST(ToStateBasedObservationTransformer, RemapsMetadataAndIgnoresUnreachablePredecessorObservations) {
183 for (
auto const& [label, choice] : std::vector<std::pair<std::string, uint64_t>>{{
"removed", 1}, {
"go", 3}, {
"wait", 4}, {
"finish", 5}}) {
188 "r",
storm::models::sparse::StandardRewardModel<double>(std::vector<double>{10, 20, 30, 40}, std::vector<double>{100, 200, 201, 300, 301, 400}));
190 std::vector<std::tuple<uint64_t, uint64_t, uint64_t>> callbackArguments;
194 [&callbackArguments](uint64_t state, uint64_t action, uint64_t target) {
195 callbackArguments.emplace_back(state, action, target);
196 return state == 0 ? 1 : (state == 1 ? 99 : target);
200 ASSERT_NE(
nullptr, result);
201 EXPECT_EQ((std::vector<std::tuple<uint64_t, uint64_t, uint64_t>>{{0, 0, 2}, {2, 0, 3}, {2, 1, 2}, {3, 0, 3}}), callbackArguments);
202 EXPECT_EQ(4u, result->getNumberOfStates());
203 EXPECT_EQ(6u, result->getNumberOfChoices());
204 EXPECT_EQ((std::vector<uint32_t>{0, 1, 2, 3}), result->getObservations());
205 EXPECT_TRUE(result->getStateLabeling().getStates(
"removed").empty());
206 EXPECT_EQ(2u, result->getStateLabeling().getStates(
"target").getNumberOfSetBits());
207 EXPECT_TRUE(result->getStateLabeling().getStates(
"target").get(1));
208 EXPECT_TRUE(result->getStateLabeling().getStates(
"target").get(2));
209 EXPECT_EQ(1u, result->getInitialStates().getNumberOfSetBits());
210 EXPECT_TRUE(result->getInitialStates().get(0));
211 EXPECT_EQ((std::vector<double>{10, 30, 30, 40}), result->getRewardModel(
"r").getStateRewardVector());
212 EXPECT_EQ((std::vector<double>{100, 300, 301, 300, 301, 400}), result->getRewardModel(
"r").getStateActionRewardVector());
213 EXPECT_TRUE(result->getChoiceLabeling().getChoices(
"removed").empty());
214 EXPECT_EQ(2u, result->getChoiceLabeling().getChoices(
"go").getNumberOfSetBits());
215 EXPECT_EQ(2u, result->getChoiceLabeling().getChoices(
"wait").getNumberOfSetBits());
216 std::vector<uint64_t>
const expectedTargets{1, 3, 2, 3, 2, 3};
217 auto const& resultMatrix = result->getTransitionMatrix();
218 for (uint64_t choice = 0; choice < expectedTargets.size(); ++choice) {
219 auto const row = resultMatrix.getRow(choice);
220 ASSERT_EQ(1u, row.getNumberOfEntries());
221 EXPECT_EQ(expectedTargets[choice], row.begin()->getColumn());
222 EXPECT_EQ(1.0, row.begin()->getValue());
223 if (choice == 1 || choice == 3) {
224 EXPECT_TRUE(result->getChoiceLabeling().getChoiceHasLabel(
"go", choice));
225 }
else if (choice == 2 || choice == 4) {
226 EXPECT_TRUE(result->getChoiceLabeling().getChoiceHasLabel(
"wait", choice));
229 EXPECT_TRUE(result->getChoiceLabeling().getChoiceHasLabel(
"finish", 5));
232TEST(ToStateBasedObservationTransformer, RetainsAllInitialStates) {
234 for (uint64_t state = 0; state < 3; ++state) {
246 [](uint64_t state, uint64_t, uint64_t) {
247 EXPECT_NE(1u, state);
252 ASSERT_NE(
nullptr, result);
253 EXPECT_EQ(3u, result->getNumberOfStates());
254 EXPECT_EQ((std::vector<uint32_t>{0, 0, 1}), result->getObservations());
255 EXPECT_EQ(2u, result->getInitialStates().getNumberOfSetBits());
256 EXPECT_TRUE(result->getInitialStates().get(0));
257 EXPECT_TRUE(result->getInitialStates().get(1));
258 EXPECT_FALSE(result->getInitialStates().get(2));
261TEST(ToStateBasedObservationTransformer, IgnoresZeroProbabilityTransitionsWhenDroppingUnreachableStates) {
273 std::vector<std::tuple<uint64_t, uint64_t, uint64_t>> callbackArguments;
274 auto observationFunction = [&callbackArguments](uint64_t state, uint64_t action, uint64_t target) {
275 callbackArguments.emplace_back(state, action, target);
281 ASSERT_NE(
nullptr, result);
282 EXPECT_EQ(1u, result->getNumberOfStates());
283 EXPECT_EQ(1u, result->getNumberOfChoices());
284 EXPECT_EQ(1u, result->getTransitionMatrix().getEntryCount());
285 EXPECT_EQ((std::vector<std::tuple<uint64_t, uint64_t, uint64_t>>{{0, 0, 0}}), callbackArguments);
287 callbackArguments.clear();
289 EXPECT_EQ(2u, unpruned->getNumberOfStates());
290 EXPECT_EQ(3u, unpruned->getTransitionMatrix().getEntryCount());
291 EXPECT_EQ((std::vector<std::tuple<uint64_t, uint64_t, uint64_t>>{{0, 0, 0}, {0, 0, 1}, {1, 0, 1}}), callbackArguments);
294TEST(ToStateBasedObservationTransformer, RewardAwareTransformationDropsUnreachableState) {
295 auto components = buildComponentsWithUnreachableState();
296 components.observabilityClasses = std::vector<uint32_t>{0, 1, 2};
297 auto const pomdp = std::make_shared<storm::models::sparse::Pomdp<double>>(std::move(components),
true);
301 ASSERT_NE(
nullptr, result);
302 EXPECT_EQ(2u, result->getNumberOfStates());
303 EXPECT_EQ(2u, result->getNumberOfChoices());
304 EXPECT_EQ((std::vector<uint32_t>{0, 3}), result->getObservations());
305 EXPECT_TRUE(result->getStateLabeling().getStates(
"isolated").empty());
306 EXPECT_EQ((std::vector<double>{0.0, 0.0}), result->getRewardModel(
"r").getStateRewardVector());
307 EXPECT_EQ((std::vector<double>{1.0, 1.0}), result->getRewardModel(
"r").getStateActionRewardVector());
308 EXPECT_TRUE(result->isCanonic());