Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
StateBehaviorTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
5
6TEST(StateBehaviorTest, StartNewChoiceAndClear) {
8 EXPECT_TRUE(behavior.empty());
9 EXPECT_FALSE(behavior.wasExpanded());
10
11 auto& c0 = behavior.startNewChoice(3, true);
12 c0.addProbability(1, 0.25);
13 c0.addProbability(2, 0.75);
14 c0.getRewards().push_back(5.0);
15 auto& c1 = behavior.startNewChoice(4);
16 c1.addProbability(0, 1.0);
17 behavior.setExpanded();
18 behavior.addStateReward(2.0);
19
20 ASSERT_EQ(2u, behavior.getNumberOfChoices());
21 ASSERT_EQ(2u, behavior.getChoices().size());
22 EXPECT_EQ(3u, behavior.getChoices()[0].getActionIndex());
23 EXPECT_TRUE(behavior.getChoices()[0].isMarkovian());
24 EXPECT_EQ(2u, behavior.getChoices()[0].size());
25 EXPECT_EQ(4u, behavior.getChoices()[1].getActionIndex());
26 EXPECT_EQ(2, std::distance(behavior.begin(), behavior.end()));
27
28 behavior.clear();
29 EXPECT_TRUE(behavior.empty());
30 EXPECT_FALSE(behavior.wasExpanded());
31 EXPECT_EQ(0u, behavior.getNumberOfChoices());
32 EXPECT_EQ(0, std::distance(behavior.begin(), behavior.end()));
33 EXPECT_TRUE(behavior.getStateRewards().empty());
34
35 // The reused choice must be completely reset
36 auto& reused = behavior.startNewChoice(7);
37 EXPECT_EQ(7u, reused.getActionIndex());
38 EXPECT_FALSE(reused.isMarkovian());
39 EXPECT_EQ(0u, reused.size());
40 EXPECT_TRUE(reused.getRewards().empty());
41 EXPECT_FALSE(reused.hasLabels());
42 EXPECT_FALSE(reused.hasOriginData());
43 EXPECT_DOUBLE_EQ(0.0, reused.getTotalMass());
44 EXPECT_EQ(1u, behavior.getNumberOfChoices());
45}
46
47TEST(StateBehaviorTest, AddChoiceAndRemove) {
49 for (uint64_t i = 0; i < 4; ++i) {
51 choice.addProbability(i, 1.0);
52 behavior.addChoice(std::move(choice));
53 }
54 ASSERT_EQ(4u, behavior.getNumberOfChoices());
55 behavior.removeLastChoices(2);
56 ASSERT_EQ(2u, behavior.getNumberOfChoices());
57 EXPECT_EQ(1u, behavior.getChoices().back().getActionIndex());
58 // Adding after removal reuses the slot
60 behavior.addChoice(std::move(choice));
61 ASSERT_EQ(3u, behavior.getNumberOfChoices());
62 EXPECT_EQ(9u, behavior.getChoices().back().getActionIndex());
63 behavior.clearChoices();
64 EXPECT_TRUE(behavior.empty());
65}
66
67TEST(StateBehaviorTest, CopyOnlyContainsActiveChoices) {
69 behavior.startNewChoice(1).addProbability(0, 1.0);
70 behavior.startNewChoice(2).addProbability(1, 1.0);
71 behavior.startNewChoice(3).addProbability(2, 1.0);
72 behavior.addStateReward(1.5);
73 behavior.setExpanded();
74 behavior.removeLastChoices(2); // Only the first choice is active
75
77 EXPECT_EQ(1u, copy.getNumberOfChoices());
78 EXPECT_EQ(1, std::distance(copy.begin(), copy.end()));
79 EXPECT_TRUE(copy.wasExpanded());
80 ASSERT_EQ(1u, copy.getStateRewards().size());
81
83 assigned.startNewChoice(5);
84 assigned.startNewChoice(6);
85 assigned = behavior;
86 EXPECT_EQ(1u, assigned.getNumberOfChoices());
87 EXPECT_EQ(1u, assigned.getChoices()[0].getActionIndex());
88}
89
90TEST(StateBehaviorTest, Move) {
92 behavior.startNewChoice(1).addProbability(0, 1.0);
93 behavior.startNewChoice(2).addProbability(1, 1.0);
94 behavior.addStateReward(1.5);
95 behavior.setExpanded();
96
97 storm::generator::StateBehavior<double> moved(std::move(behavior));
98 EXPECT_EQ(2u, moved.getNumberOfChoices());
99 EXPECT_EQ(2u, moved.getChoices().size());
100 EXPECT_EQ(2, std::distance(moved.begin(), moved.end()));
101 EXPECT_TRUE(moved.wasExpanded());
102 EXPECT_EQ(1u, moved.getStateRewards().size());
103
104 // The source of the move is a valid empty behavior that can be reused
105 // NOLINTBEGIN(bugprone-use-after-move): We explicitly test the state of moved-from objects
106 EXPECT_TRUE(behavior.empty());
107 EXPECT_EQ(0u, behavior.getNumberOfChoices());
108 EXPECT_EQ(0u, behavior.getChoices().size());
109 EXPECT_EQ(0, std::distance(behavior.begin(), behavior.end()));
110 EXPECT_FALSE(behavior.wasExpanded());
111 EXPECT_TRUE(behavior.getStateRewards().empty());
112 behavior.startNewChoice(5);
113 EXPECT_EQ(1u, behavior.getNumberOfChoices());
114 // NOLINTEND(bugprone-use-after-move)
115
117 assigned.startNewChoice(9);
118 assigned = std::move(moved);
119 EXPECT_EQ(2u, assigned.getNumberOfChoices());
120 EXPECT_EQ(2u, assigned.getChoices()[1].getActionIndex());
121 // NOLINTBEGIN(bugprone-use-after-move): We explicitly test the state of moved-from objects
122 EXPECT_TRUE(moved.empty());
123 EXPECT_EQ(0, std::distance(moved.begin(), moved.end()));
124 // NOLINTEND(bugprone-use-after-move)
125}
126
127TEST(StateBehaviorTest, AddChoicesSumsAllRewards) {
129 a.addProbability(0, 1.0);
130 a.getRewards() = {1.0, 10.0, 100.0};
132 b.addProbability(1, 2.0);
133 b.getRewards() = {2.0, 20.0, 200.0};
134 a.add(b);
135 ASSERT_EQ(3u, a.getRewards().size());
136 EXPECT_DOUBLE_EQ(3.0, a.getRewards()[0]);
137 EXPECT_DOUBLE_EQ(30.0, a.getRewards()[1]);
138 EXPECT_DOUBLE_EQ(300.0, a.getRewards()[2]);
139 EXPECT_DOUBLE_EQ(3.0, a.getTotalMass());
140}
141
142TEST(StateBehaviorTest, CopyAssignmentReusesAndGrows) {
144 for (uint64_t i = 0; i < 3; ++i) {
145 auto& choice = source.startNewChoice(i + 1, i == 1);
146 choice.addProbability(i, 0.5);
147 choice.addProbability(i + 10, 0.5);
148 choice.getRewards() = {static_cast<double>(i)};
149 }
150 source.addStateReward(4.0);
151 source.setExpanded();
152
153 // Target with fewer choices than the source (the choices vector has to grow)
155 small.startNewChoice(42).addProbability(7, 1.0);
156 small = source;
157 ASSERT_EQ(3u, small.getNumberOfChoices());
158 for (uint64_t i = 0; i < 3; ++i) {
159 EXPECT_EQ(i + 1, small.getChoices()[i].getActionIndex());
160 EXPECT_EQ(i == 1, small.getChoices()[i].isMarkovian());
161 EXPECT_EQ(2u, small.getChoices()[i].size());
162 EXPECT_DOUBLE_EQ(static_cast<double>(i), small.getChoices()[i].getRewards().at(0));
163 }
164 EXPECT_TRUE(small.wasExpanded());
165 ASSERT_EQ(1u, small.getStateRewards().size());
166
167 // Target with more (stale) choices than the source: only the active ones are visible afterwards
169 for (uint64_t i = 0; i < 5; ++i) {
170 large.startNewChoice(100 + i).addProbability(i, 1.0);
171 }
173 twoChoices.startNewChoice(1).addProbability(0, 1.0);
174 twoChoices.startNewChoice(2).addProbability(1, 1.0);
175 large = twoChoices;
176 ASSERT_EQ(2u, large.getNumberOfChoices());
177 EXPECT_EQ(2, std::distance(large.begin(), large.end()));
178 EXPECT_EQ(1u, large.getChoices()[0].getActionIndex());
179 EXPECT_EQ(2u, large.getChoices()[1].getActionIndex());
180 EXPECT_EQ(1u, large.getChoices()[1].size());
181 EXPECT_FALSE(large.wasExpanded());
182}
TEST(StateBehaviorTest, StartNewChoiceAndClear)
void addChoice(Choice< ValueType, StateType > &&choice)
Adds the given choice to the behavior of the state.
void addStateReward(ValueType const &stateReward)
Adds the given state reward to the behavior of the state.
void removeLastChoices(std::size_t numberOfChoices)
Removes the last given number of choices.
bool empty() const
Retrieves whether the behavior is empty in the sense that there are no available choices.
std::vector< Choice< ValueType, StateType > >::const_iterator end() const
Retrieves an iterator past the choices available in the behavior.
std::span< Choice< ValueType, StateType > const > getChoices() const
Retrieves the choices.
std::vector< Choice< ValueType, StateType > >::const_iterator begin() const
Retrieves an iterator to the choices available in the behavior.
bool wasExpanded() const
Retrieves whether the state was expanded.
void clearChoices()
Removes all choices (but keeps the state rewards and the allocated memory of the choices for reuse).
std::vector< ValueType > const & getStateRewards() const
Retrieves the list of state rewards under selected reward models.
void clear()
Resets this to an empty behavior, i.e.
std::size_t getNumberOfChoices() const
Retrieves the number of choices in the behavior.
void setExpanded(bool newValue=true)
Sets whether the state was expanded.
Choice< ValueType, StateType > & startNewChoice(uint_fast64_t actionIndex=0, bool markovian=false)
Adds a new empty choice with the given action index and returns a reference to it.
std::vector< ValueType > const & getRewards() const
Retrieves the rewards for this choice under selected reward models.
Definition Choice.cpp:187
void add(Choice const &other)
Adds the given choice to the current one.
Definition Choice.cpp:34
ValueType getTotalMass() const
Retrieves the total mass of this choice.
Definition Choice.cpp:166
void addProbability(StateType const &state, ValueType const &value)
Adds the given probability value to the given state in the underlying distribution.
Definition Choice.cpp:171