Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
EpochManager.cpp
Go to the documentation of this file.
2
4
6
7namespace storm {
8namespace modelchecker {
9namespace helper {
10namespace rewardbounded {
11
12EpochManager::EpochManager() : dimensionCount(0) {
13 // Intentionally left empty
14}
15
16EpochManager::EpochManager(uint64_t dimensionCount) : dimensionCount(dimensionCount) {
17 STORM_LOG_THROW(dimensionCount > 0, storm::exceptions::IllegalArgumentException, "Invoked EpochManager with zero dimension count.");
18 STORM_LOG_THROW(dimensionCount <= 64, storm::exceptions::IllegalArgumentException, "Invoked EpochManager with too many dimensions.");
19 bitsPerDimension = 64 / dimensionCount;
20 if (dimensionCount == 1) {
21 dimensionBitMask = -1ull;
22 } else {
23 dimensionBitMask = (1ull << bitsPerDimension) - 1;
24 }
25
26 if (dimensionCount * bitsPerDimension == 64ull) {
27 relevantBitsMask = -1ull;
28 } else {
29 relevantBitsMask = (1ull << (dimensionCount * bitsPerDimension)) - 1;
30 }
31}
32
34 return relevantBitsMask;
35}
36
38 return 0;
39}
40
41uint64_t const& EpochManager::getDimensionCount() const {
42 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
43 return dimensionCount;
44}
45
46bool EpochManager::compareEpochClass(Epoch const& epoch1, Epoch const& epoch2) const {
47 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
48 uint64_t mask = dimensionBitMask;
49 for (uint64_t d = 0; d < dimensionCount; ++d) {
50 if (((epoch1 & mask) == mask) != ((epoch2 & mask) == mask)) {
51 assert(getEpochClass(epoch1) != getEpochClass(epoch2));
52 return false;
53 }
54 mask = mask << bitsPerDimension;
55 }
56 assert(getEpochClass(epoch1) == getEpochClass(epoch2));
57 return true;
58}
59
61 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
62 EpochClass result = 0;
63 uint64_t dimensionMask = dimensionBitMask;
64 uint64_t classMask = 1;
65 for (uint64_t d = 0; d < dimensionCount; ++d) {
66 if ((epoch & dimensionMask) == dimensionMask) {
67 result |= classMask;
68 }
69 classMask = classMask << 1;
70 dimensionMask = dimensionMask << bitsPerDimension;
71 }
72 return result;
73}
74
75typename EpochManager::Epoch EpochManager::getSuccessorEpoch(Epoch const& epoch, Epoch const& step) const {
76 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
77 STORM_LOG_ASSERT(!hasBottomDimension(step), "The given step has at least one bottom dimension.");
78
79 // Start with dimension zero
80 uint64_t mask = dimensionBitMask;
81 uint64_t e_d = epoch & mask;
82 uint64_t s_d = step & mask;
83 uint64_t result = (e_d < s_d || e_d == mask) ? mask : e_d - s_d;
84
85 // Consider the remaining dimensions
86 for (uint64_t d = 1; d < dimensionCount; ++d) {
87 mask = mask << bitsPerDimension;
88 e_d = epoch & mask;
89 s_d = step & mask;
90 result |= ((e_d < s_d || e_d == mask) ? mask : e_d - s_d);
91 }
92 return result;
93}
94
95std::vector<typename EpochManager::Epoch> EpochManager::getPredecessorEpochs(Epoch const& epoch, Epoch const& step) const {
96 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
97 STORM_LOG_ASSERT(!hasBottomDimension(step), "The given step has at least one bottom dimension.");
98 std::set<Epoch> resultAsSet;
99 gatherPredecessorEpochs(resultAsSet, epoch, step);
100 return std::vector<Epoch>(resultAsSet.begin(), resultAsSet.end());
101}
102
103void EpochManager::gatherPredecessorEpochs(std::set<Epoch>& gatheredPredecessorEpochs, Epoch const& epoch, Epoch const& step) const {
104 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
105 STORM_LOG_ASSERT(!hasBottomDimension(step), "The given step has at least one bottom dimension.");
106 Epoch currStep = step;
107 uint64_t d = 0;
108 while (d < dimensionCount) {
109 Epoch predecessor = epoch;
110 for (uint64_t dPrime = 0; dPrime < dimensionCount; ++dPrime) {
111 uint64_t step_dPrime = getDimensionOfEpoch(currStep, dPrime);
112 if (isBottomDimension(predecessor, dPrime)) {
113 if (step_dPrime != 0) {
114 setDimensionOfEpoch(predecessor, dPrime, step_dPrime - 1);
115 }
116 } else {
117 setDimensionOfEpoch(predecessor, dPrime, getDimensionOfEpoch(predecessor, dPrime) + step_dPrime);
118 }
119 }
120 assert(epoch == getSuccessorEpoch(predecessor, step));
121 gatheredPredecessorEpochs.insert(predecessor);
122
123 do {
124 if (isBottomDimension(epoch, d)) {
125 uint64_t step_d = getDimensionOfEpoch(currStep, d);
126 if (step_d == 0) {
127 setDimensionOfEpoch(currStep, d, getDimensionOfEpoch(step, d));
128 } else {
129 setDimensionOfEpoch(currStep, d, step_d - 1);
130 d = 0;
131 break;
132 }
133 }
134 ++d;
135 } while (d < dimensionCount);
136 }
137}
138
139bool EpochManager::isValidDimensionValue(uint64_t const& value) const {
140 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
141 return ((value & dimensionBitMask) == value) && value != dimensionBitMask;
142}
143
144bool EpochManager::isZeroEpoch(Epoch const& epoch) const {
145 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
146 return (epoch & relevantBitsMask) == 0;
147}
148
149bool EpochManager::isBottomEpoch(Epoch const& epoch) const {
150 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
151 return (epoch & relevantBitsMask) == relevantBitsMask;
152}
153
154bool EpochManager::hasBottomDimension(Epoch const& epoch) const {
155 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
156 uint64_t mask = dimensionBitMask;
157 for (uint64_t d = 0; d < dimensionCount; ++d) {
158 if ((epoch | mask) == epoch) {
159 return true;
160 }
161 mask = mask << bitsPerDimension;
162 }
163 return false;
164}
165
167 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
168 uint64_t mask = (1 << dimensionCount) - 1;
169 return (epochClass & mask) != 0;
170}
171
172bool EpochManager::isPredecessorEpochClass(EpochClass const& epochClass1, EpochClass const& epochClass2) const {
173 return (epochClass1 & epochClass2) == epochClass1;
174}
175
176void EpochManager::setBottomDimension(Epoch& epoch, uint64_t const& dimension) const {
177 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
178 epoch |= (dimensionBitMask << (dimension * bitsPerDimension));
179}
180
181void EpochManager::setDimensionOfEpoch(Epoch& epoch, uint64_t const& dimension, uint64_t const& value) const {
182 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
183 STORM_LOG_ASSERT(isValidDimensionValue(value), "The dimension value " << value << " is too high.");
184 epoch &= ~(dimensionBitMask << (dimension * bitsPerDimension));
185 epoch |= (value << (dimension * bitsPerDimension));
186}
187
188void EpochManager::setDimensionOfEpochClass(EpochClass& epochClass, uint64_t const& dimension, bool const& setToBottom) const {
189 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
190 if (setToBottom) {
191 epochClass |= (1 << dimension);
192 } else {
193 epochClass &= ~(1 << dimension);
194 }
195}
196
197bool EpochManager::isBottomDimension(Epoch const& epoch, uint64_t const& dimension) const {
198 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
199 return (epoch | (dimensionBitMask << (dimension * bitsPerDimension))) == epoch;
200}
201
202bool EpochManager::isBottomDimensionEpochClass(EpochClass const& epochClass, uint64_t const& dimension) const {
203 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
204 return (epochClass | (1 << dimension)) == epochClass;
205}
206
207uint64_t EpochManager::getDimensionOfEpoch(Epoch const& epoch, uint64_t const& dimension) const {
208 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
209 return (epoch >> (dimension * bitsPerDimension)) & dimensionBitMask;
210}
211
212uint64_t EpochManager::getSumOfDimensions(Epoch const& epoch) const {
213 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
214 uint64_t sumOfDimensions = 0;
215 for (uint64_t dim = 0; dim < getDimensionCount(); ++dim) {
216 if (!isBottomDimension(epoch, dim)) {
217 sumOfDimensions += getDimensionOfEpoch(epoch, dim) + 1;
218 }
219 }
220 return sumOfDimensions;
221}
222
223std::string EpochManager::toString(Epoch const& epoch) const {
224 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
225 std::string res = "<" + (isBottomDimension(epoch, 0) ? "_" : std::to_string(getDimensionOfEpoch(epoch, 0)));
226 for (uint64_t d = 1; d < dimensionCount; ++d) {
227 res += ", ";
228 res += (isBottomDimension(epoch, d) ? "_" : std::to_string(getDimensionOfEpoch(epoch, d)));
229 }
230 res += ">";
231 return res;
232}
233
234bool EpochManager::epochClassZigZagOrder(Epoch const& epoch1, Epoch const& epoch2) const {
235 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
236
237 // Return true iff epoch 1 has to be computed before epoch 2
238
239 if (!compareEpochClass(epoch1, epoch2)) {
240 return epochClassOrder(getEpochClass(epoch1), getEpochClass(epoch2));
241 }
242
243 // check whether the sum of dimensions is the same
244 uint64_t e1Sum = 0;
245 uint64_t e2Sum = 0;
246 for (uint64_t dim = 0; dim < dimensionCount; ++dim) {
247 if (!isBottomDimension(epoch1, dim)) {
248 assert(!isBottomDimension(epoch2, dim));
249 e1Sum += getDimensionOfEpoch(epoch1, dim);
250 e2Sum += getDimensionOfEpoch(epoch2, dim);
251 }
252 }
253 if (e1Sum < e2Sum) {
254 return true;
255 } else if (e1Sum > e2Sum) {
256 return false;
257 }
258
259 // find the first dimension where the epochs do not match.
260 // if the sum is even, we search from left to right, otherwise from right to left
261 bool sumEven = (e1Sum % 2) == 0;
262 if (sumEven) {
263 for (uint64_t dim = 0; dim < dimensionCount; ++dim) {
264 uint64_t e1Value = getDimensionOfEpoch(epoch1, dim);
265 uint64_t e2Value = getDimensionOfEpoch(epoch2, dim);
266 if (e1Value < e2Value) {
267 return true;
268 } else if (e1Value > e2Value) {
269 return false;
270 }
271 }
272 } else {
273 uint64_t dim = dimensionCount;
274 while (dim > 0) {
275 --dim;
276 uint64_t e1Value = getDimensionOfEpoch(epoch1, dim);
277 uint64_t e2Value = getDimensionOfEpoch(epoch2, dim);
278 if (e1Value < e2Value) {
279 return true;
280 } else if (e1Value > e2Value) {
281 return false;
282 }
283 }
284 }
285
286 // reaching this point means that the epochs are equal
287 assert(epoch1 == epoch2);
288 return false;
289}
290
291bool EpochManager::epochClassOrder(EpochClass const& epochClass1, EpochClass const& epochClass2) const {
292 STORM_LOG_ASSERT(dimensionCount > 0, "Invoked EpochManager with zero dimension count.");
293
294 if (epochClass1 == epochClass2) {
295 return false;
296 }
297
298 // Return true iff epochClass 1 is a successor class of epochClass 2
299
300 // Check whether the number of bottom dimensions is not equal
301 int64_t count;
302 EpochClass ec = epochClass1;
303 for (count = 0; ec; ++count) {
304 ec &= ec - 1;
305 }
306 ec = epochClass2;
307 for (; ec; --count) {
308 ec &= ec - 1;
309 }
310 if (count > 0) {
311 return true;
312 } else if (count < 0) {
313 return false;
314 }
315
316 return epochClass1 < epochClass2;
317}
318} // namespace rewardbounded
319} // namespace helper
320} // namespace modelchecker
321} // namespace storm
void gatherPredecessorEpochs(std::set< Epoch > &gatheredPredecessorEpochs, Epoch const &epoch, Epoch const &step) const
uint64_t getSumOfDimensions(Epoch const &epoch) const
bool isPredecessorEpochClass(EpochClass const &epochClass1, EpochClass const &epochClass2) const
bool isBottomDimension(Epoch const &epoch, uint64_t const &dimension) const
void setDimensionOfEpochClass(EpochClass &epochClass, uint64_t const &dimension, bool const &setToBottom) const
Epoch getSuccessorEpoch(Epoch const &epoch, Epoch const &step) const
bool isValidDimensionValue(uint64_t const &value) const
bool hasBottomDimensionEpochClass(EpochClass const &epochClass) const
bool epochClassOrder(EpochClass const &epochClass1, EpochClass const &epochClass2) const
bool compareEpochClass(Epoch const &epoch1, Epoch const &epoch2) const
uint64_t getDimensionOfEpoch(Epoch const &epoch, uint64_t const &dimension) const
EpochClass getEpochClass(Epoch const &epoch) const
void setDimensionOfEpoch(Epoch &epoch, uint64_t const &dimension, uint64_t const &value) const
std::vector< Epoch > getPredecessorEpochs(Epoch const &epoch, Epoch const &step) const
void setBottomDimension(Epoch &epoch, uint64_t const &dimension) const
bool isBottomDimensionEpochClass(EpochClass const &epochClass, uint64_t const &dimension) const
bool epochClassZigZagOrder(Epoch const &epoch1, Epoch const &epoch2) const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
LabParser.cpp.
Definition cli.cpp:18