18TEST(ValuationTest, StateValuationConstruction) {
20 GTEST_SKIP() <<
"Z3 not available.";
27 std::shared_ptr<storm::models::sparse::Model<double>> model = builder.build();
28 ASSERT_TRUE(model->hasStateValuations());
29 auto const& sv = model->getStateValuations();
30 ASSERT_EQ(sv.getNumberOfEntities(), model->getNumberOfStates());
31 ASSERT_TRUE(sv.getManager().hasVariable(
"s"));
32 ASSERT_TRUE(sv.getManager().hasVariable(
"d"));
33 auto const s = sv.getManager().getVariable(
"s");
34 auto const d = sv.getManager().getVariable(
"d");
35 auto const vars = sv.getAllVariables();
36 ASSERT_EQ(2, vars.size());
37 ASSERT_TRUE(vars.contains(s));
38 ASSERT_TRUE(vars.contains(d));
40 uint64_t
const sinit = *model->getInitialStates().begin();
41 ASSERT_TRUE(sv.entityHasVariable(sinit, s));
42 ASSERT_TRUE(sv.entityHasVariable(sinit, d));
43 EXPECT_EQ(0, sv.getInt64Value(sinit, s));
44 EXPECT_EQ(0, sv.getOptionalInt64Value(sinit, s).value());
45 EXPECT_EQ(0, sv.getOptionalInt64Value(sinit, d).value());
47 auto js = sv.toJson(sinit);
48 EXPECT_EQ(2, js.size());
49 EXPECT_TRUE(js.contains(
"s"));
50 EXPECT_TRUE(js.contains(
"d"));
51 EXPECT_EQ(0, js[
"s"].get<int64_t>());
52 EXPECT_EQ(0, js[
"d"].get<int64_t>());
54 ASSERT_TRUE(model->getStateLabeling().containsLabel(
"three"));
55 ASSERT_TRUE(model->getStates(
"three").hasUniqueSetBit());
56 uint64_t
const three = *model->getStates(
"three").begin();
57 EXPECT_EQ(7, sv.getInt64Value(three, s));
58 EXPECT_EQ(3, sv.getInt64Value(three, d));
60 auto dValues = sv.getInt64Values(d);
61 ASSERT_EQ(sv.getNumberOfEntities(), dValues.size());
62 EXPECT_EQ(3, dValues[three]);
63 int64_t
const sum = std::accumulate(dValues.begin(), dValues.end(), 0ll);
64 EXPECT_EQ(1 + 2 + 3 + 4 + 5 + 6, sum);
67TEST(ValuationTest, StateValuationTransformation) {
69 GTEST_SKIP() <<
"Z3 not available.";
75 std::shared_ptr<storm::models::sparse::Model<double>> model = builder.build();
76 ASSERT_TRUE(model->hasStateValuations());
77 auto const& sv = model->getStateValuations();
79 auto newsv = notransformer.
build(
true);
80 ASSERT_EQ(newsv.getNumberOfEntities(), sv.getNumberOfEntities());
88 transformer.
addExpression(alwaysTrueVar, svar.getExpression() == svar.getExpression());
89 transformer.
addExpression(alwaysFalseVar, dvar.getExpression() < dvar.getExpression());
90 newsv = transformer.
build(
true);
92 ASSERT_EQ(5, vars.size());
93 ASSERT_TRUE(vars.contains(svar));
94 ASSERT_TRUE(vars.contains(dvar));
95 ASSERT_TRUE(vars.contains(sgt3Var));
96 ASSERT_TRUE(vars.contains(alwaysTrueVar));
97 ASSERT_TRUE(vars.contains(alwaysFalseVar));
98 uint64_t
const sinit = *model->getInitialStates().begin();
99 EXPECT_EQ(0, newsv.getInt64Value(sinit, svar));
100 EXPECT_EQ(0, newsv.getInt64Value(sinit, dvar));
101 EXPECT_FALSE(newsv.getBooleanValue(sinit, sgt3Var));
102 EXPECT_TRUE(newsv.getBooleanValue(sinit, alwaysTrueVar));
103 EXPECT_FALSE(newsv.getBooleanValue(sinit, alwaysFalseVar));
105 for (uint64_t state = 0; state < newsv.getNumberOfEntities(); ++state) {
106 ASSERT_TRUE(newsv.getBooleanValue(state, alwaysTrueVar));
107 ASSERT_FALSE(newsv.getBooleanValue(state, alwaysFalseVar));
108 ASSERT_EQ(sv.getInt64Value(state, svar), newsv.getInt64Value(state, svar));
109 ASSERT_EQ(newsv.getBooleanValue(state, sgt3Var), newsv.getInt64Value(state, svar) > 3);
113TEST(ValuationTest, Valuations2classes) {
114 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
115 auto const b = manager->declareBooleanVariable(
"b");
116 auto const i = manager->declareIntegerVariable(
"i");
117 auto const s = manager->declareStringVariable(
"s");
118 auto const r = manager->declareRationalVariable(
"r");
119 std::vector<storm::storage::sparse::ValuationClassDescription> classes;
127 EXPECT_EQ(2 + 5 + 65 + 166 + 2, classes.back().sizeInBits());
128 EXPECT_TRUE(classes.back().hasStringVariable());
135 EXPECT_EQ(64 + 1 + 2 + 5, classes.back().sizeInBits());
136 EXPECT_FALSE(classes.back().hasStringVariable());
139 EXPECT_EQ(0, valuations.numStrings());
140 EXPECT_EQ(2, valuations.numClasses());
141 EXPECT_EQ(classes[0].sizeInBits(), valuations.getClassDescription(0).sizeInBits());
142 EXPECT_EQ(classes[1].sizeInBits(), valuations.getClassDescription(1).sizeInBits());
143 auto const vars = valuations.getAllVariables();
144 EXPECT_EQ(4, vars.size());
145 EXPECT_TRUE(vars.contains(b));
146 EXPECT_TRUE(vars.contains(i));
147 EXPECT_TRUE(vars.contains(s));
148 EXPECT_TRUE(vars.contains(r));
150 std::vector<std::optional<bool>> b_values;
151 std::vector<int64_t> i_values;
152 std::vector<std::optional<std::string>> s_values;
153 std::vector<storm::RationalNumber> r_values;
154 for (uint64_t e = 0; e < 200; ++e) {
157 valuations.emplaceBack<
true>(0, [&](
auto entity,
auto const& var,
auto& value) {
158 using ValueType = std::remove_cvref_t<
decltype(value)>;
159 if constexpr (std::is_same_v<ValueType, std::optional<bool>>) {
161 if (entity % 2 == 0) {
162 value = entity % 4 == 0;
164 b_values.push_back(value);
165 }
else if constexpr (std::is_same_v<ValueType, int64_t>) {
167 value =
static_cast<int64_t
>(entity) % 17 - 4;
168 i_values.push_back(value);
169 }
else if constexpr (std::is_same_v<ValueType, std::optional<std::string>>) {
171 if (entity % 2 == 1) {
172 value =
"str" + std::to_string(entity);
174 s_values.push_back(value);
175 }
else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
179 if (entity % 8 == 0) {
182 r_values.push_back(value);
184 FAIL() <<
"Unexpected variable type " <<
typeid(ValueType).name() <<
" for variable " << var.getName();
189 valuations.emplaceBack<
false, double, bool, int64_t>(1, [&](
auto entity,
auto const& var,
auto& value) {
190 using ValueType = std::remove_cvref_t<
decltype(value)>;
191 if constexpr (std::is_same_v<ValueType, double>) {
193 value =
static_cast<double>(entity) / 3.0;
195 }
else if constexpr (std::is_same_v<ValueType, bool>) {
197 value = entity % 2 == 0;
198 b_values.push_back(value);
200 static_assert(std::is_same_v<ValueType, int64_t>);
202 value =
static_cast<int64_t
>(entity) % 4 - 10;
203 i_values.push_back(value);
206 s_values.push_back(std::nullopt);
210 ASSERT_EQ(200, b_values.size());
211 ASSERT_EQ(200, i_values.size());
212 ASSERT_EQ(200, s_values.size());
213 ASSERT_EQ(200, r_values.size());
214 valuations.readCallback<std::nullopt_t, bool, int64_t, std::string, storm::RationalNumber,
double>([&](
auto entity,
auto const& var,
auto const& value) {
215 using ValueType = std::remove_cvref_t<
decltype(value)>;
216 if constexpr (std::is_same_v<ValueType, std::nullopt_t>) {
217 EXPECT_EQ(0, valuations.getClassOfEntity(entity));
219 EXPECT_FALSE(b_values[entity].has_value());
221 EXPECT_TRUE(var == s);
222 EXPECT_FALSE(s_values[entity].has_value());
224 }
else if constexpr (std::is_same_v<ValueType, bool>) {
226 ASSERT_TRUE(b_values[entity].has_value());
227 EXPECT_EQ(b_values[entity].value(), value);
228 }
else if constexpr (std::is_same_v<ValueType, int64_t>) {
230 EXPECT_EQ(i_values[entity], value);
231 }
else if constexpr (std::is_same_v<ValueType, std::string>) {
233 ASSERT_TRUE(s_values[entity].has_value());
234 EXPECT_EQ(s_values[entity].value(), value);
235 }
else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
236 EXPECT_EQ(0, valuations.getClassOfEntity(entity));
238 EXPECT_EQ(r_values[entity], value);
240 static_assert(std::is_same_v<ValueType, double>);
241 EXPECT_EQ(1, valuations.getClassOfEntity(entity));
248TEST(ValuationTest, ValuationsSingleClass) {
251 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
252 auto const b = manager->declareBooleanVariable(
"b");
253 auto const i = manager->declareIntegerVariable(
"i");
254 auto const d = manager->declareRationalVariable(
"d");
261 EXPECT_EQ(1 + 4 + 64 + 3, desc.sizeInBits());
264 EXPECT_EQ(0u, valuations.
size());
269 EXPECT_EQ(3u, vars.size());
270 EXPECT_TRUE(vars.contains(b));
271 EXPECT_TRUE(vars.contains(i));
272 EXPECT_TRUE(vars.contains(d));
275 std::vector<bool> bVals = {
true,
false,
true,
false,
true,
false};
276 std::vector<int64_t> iVals = {-5, -3, 0, 2, 4, 5};
277 std::vector<double> dVals = {0.0, 1.5, -2.25, 1e10, -1e-5, 3.14};
279 for (uint64_t e = 0; e < 6; ++e) {
280 valuations.
emplaceBack<
false, bool, int64_t,
double>([&](
auto entity,
auto const& var,
auto& value) {
281 using ValueType = std::remove_cvref_t<
decltype(value)>;
282 if constexpr (std::is_same_v<ValueType, bool>) {
283 value = bVals[entity];
284 }
else if constexpr (std::is_same_v<ValueType, int64_t>) {
285 value = iVals[entity];
287 static_assert(std::is_same_v<ValueType, double>);
288 value = dVals[entity];
292 ASSERT_EQ(6u, valuations.
size());
295 for (uint64_t e = 0; e < 6; ++e) {
302 for (uint64_t e = 0; e < 6; ++e) {
303 EXPECT_EQ(bVals[e], valuations.
readValue<
bool>(e, b)) <<
" at entity " << e;
304 EXPECT_EQ(iVals[e], valuations.
readValue<int64_t>(e, i)) <<
" at entity " << e;
305 EXPECT_EQ(dVals[e], valuations.
readValue<
double>(e, d)) <<
" at entity " << e;
312 EXPECT_EQ(
true, valuations.
readValue<
bool>(3, b));
313 EXPECT_EQ(-1, valuations.
readValue<int64_t>(3, i));
314 EXPECT_EQ(99.0, valuations.
readValue<
double>(3, d));
316 EXPECT_EQ(bVals[2], valuations.
readValue<
bool>(2, b));
317 EXPECT_EQ(iVals[4], valuations.
readValue<int64_t>(4, i));
321 ASSERT_EQ(9u, valuations.
size());
322 for (uint64_t e = 0; e < 6; ++e) {
326 EXPECT_EQ(bVals[e], valuations.
readValue<
bool>(e, b)) <<
" at entity " << e;
327 EXPECT_EQ(iVals[e], valuations.
readValue<int64_t>(e, i)) <<
" at entity " << e;
328 EXPECT_EQ(dVals[e], valuations.
readValue<
double>(e, d)) <<
" at entity " << e;
333 EXPECT_EQ(4u, valuations.
size());
334 EXPECT_EQ(bVals[0], valuations.
readValue<
bool>(0, b));
335 EXPECT_EQ(iVals[1], valuations.
readValue<int64_t>(1, i));
336 EXPECT_EQ(dVals[2], valuations.
readValue<
double>(2, d));
339TEST(ValuationTest, ValuationsSelectEntities) {
343 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
344 auto const b = manager->declareBooleanVariable(
"b");
345 auto const i = manager->declareIntegerVariable(
"i");
355 for (uint64_t e = 0; e < 8; ++e) {
356 valuations.
emplaceBack<
false, bool, int64_t>([e](
auto ,
auto const& var,
auto& value) {
357 using ValueType = std::remove_cvref_t<
decltype(value)>;
358 if constexpr (std::is_same_v<ValueType, bool>) {
359 value = (e % 2 == 0);
361 static_assert(std::is_same_v<ValueType, int64_t>);
362 value =
static_cast<int64_t
>(e);
366 ASSERT_EQ(8u, valuations.
size());
370 for (uint64_t e = 1; e < 8; e += 2) {
374 ASSERT_EQ(4u, selectedBv.size());
375 EXPECT_EQ(1u, selectedBv.numClasses());
376 for (uint64_t sel = 0; sel < 4; ++sel) {
377 uint64_t
const origEntity = 2 * sel + 1;
378 EXPECT_EQ(
false, selectedBv.readValue<
bool>(sel, b)) <<
" selected entity " << sel;
379 EXPECT_EQ(
static_cast<int64_t
>(origEntity), selectedBv.readValue<int64_t>(sel, i)) <<
" selected entity " << sel;
383 std::vector<uint64_t>
const indices = {6, 0, 4};
385 ASSERT_EQ(3u, selectedVec.size());
386 EXPECT_EQ(
true, selectedVec.readValue<
bool>(0, b));
387 EXPECT_EQ(6, selectedVec.readValue<int64_t>(0, i));
388 EXPECT_EQ(
true, selectedVec.readValue<
bool>(1, b));
389 EXPECT_EQ(0, selectedVec.readValue<int64_t>(1, i));
390 EXPECT_EQ(
true, selectedVec.readValue<
bool>(2, b));
391 EXPECT_EQ(4, selectedVec.readValue<int64_t>(2, i));
394 ASSERT_EQ(8u, valuations.
size());
395 for (uint64_t e = 0; e < 8; ++e) {
396 EXPECT_EQ(e % 2 == 0, valuations.
readValue<
bool>(e, b)) <<
" at original entity " << e;
397 EXPECT_EQ(
static_cast<int64_t
>(e), valuations.
readValue<int64_t>(e, i)) <<
" at original entity " << e;
401TEST(ValuationTest, RejectsNonCompliantDoubleOrStringSize) {
404 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
405 auto const d = manager->declareRationalVariable(
"d");
408 .name =
"d", .isOptional = std::nullopt, .type = {
storm::umb::Type::Double, 128}, .lower = {}, .upper = {}, .offset = {}};
409 EXPECT_THROW(doubleBuilder.
addVariable(badDouble), storm::exceptions::WrongFormatException);
411 auto const s = manager->declareStringVariable(
"s");
414 .name =
"s", .isOptional = std::nullopt, .type = {
storm::umb::Type::String, 128}, .lower = {}, .upper = {}, .offset = {}};
415 EXPECT_THROW(stringBuilder.
addVariable(badString), storm::exceptions::WrongFormatException);
420 .name =
"d", .isOptional = std::nullopt, .type = {
storm::umb::Type::Double, std::nullopt}, .lower = {}, .upper = {}, .offset = {}};
449TEST(ValuationTest, ResizeInitializesAllNewEntitiesWithDefaults) {
450 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
451 auto const i = manager->declareIntegerVariable(
"i");
452 auto const r = manager->declareRationalVariable(
"r");
453 auto const b = manager->declareBooleanVariable(
"b");
457 {.name =
"i", .isOptional = std::nullopt, .type = {
storm::umb::Type::Int, 8}, .lower = std::nullopt, .upper = -3, .offset = std::nullopt});
464 ASSERT_EQ(5u, storage.
size());
465 for (uint64_t entity = 0; entity < 5; ++entity) {
466 EXPECT_EQ(-3, storage.
readValue<int64_t>(entity, i)) <<
"entity " << entity;
467 EXPECT_EQ(storm::RationalNumber(0), storage.
readValue<storm::RationalNumber>(entity, r)) <<
"entity " << entity;
468 EXPECT_FALSE(storage.
readValue<
bool>(entity, b)) <<
"entity " << entity;
473 ASSERT_EQ(8u, storage.
size());
474 EXPECT_EQ(-7, storage.
readValue<int64_t>(2, i));
475 for (uint64_t entity : {0, 1, 3, 4, 5, 6, 7}) {
476 EXPECT_EQ(-3, storage.
readValue<int64_t>(entity, i)) <<
"entity " << entity;
477 EXPECT_EQ(storm::RationalNumber(0), storage.
readValue<storm::RationalNumber>(entity, r)) <<
"entity " << entity;
481 EXPECT_EQ(3u, storage.
size());
482 EXPECT_EQ(-7, storage.
readValue<int64_t>(2, i));
485TEST(ValuationTest, ResizeMultipleClasses) {
486 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
487 auto const a = manager->declareIntegerVariable(
"a");
488 auto const b = manager->declareIntegerVariable(
"b");
489 std::vector<storm::storage::sparse::ValuationClassDescription> classes;
501 ASSERT_EQ(2u, storage.numClasses());
503 storage.resize(3, 0);
504 storage.resize(7, 1);
505 ASSERT_EQ(7u, storage.size());
506 for (uint64_t entity = 0; entity < 7; ++entity) {
507 EXPECT_EQ(entity < 3 ? 0u : 1u, storage.getClassOfEntity(entity)) <<
"entity " << entity;
510 for (uint64_t entity = 0; entity < 3; ++entity) {
511 storage.writeValue<int64_t>(entity, a, entity + 1);
513 for (uint64_t entity = 3; entity < 7; ++entity) {
514 storage.writeValue<int64_t>(entity, b, -
static_cast<int64_t
>(entity) * 1000);
516 for (uint64_t entity = 0; entity < 3; ++entity) {
517 EXPECT_EQ(
static_cast<int64_t
>(entity + 1), storage.readValue<int64_t>(entity, a));
519 for (uint64_t entity = 3; entity < 7; ++entity) {
520 EXPECT_EQ(-
static_cast<int64_t
>(entity) * 1000, storage.readValue<int64_t>(entity, b));
522 EXPECT_EQ(3u + 4u * 2u, storage.getRawUmbData().valuations->size());
525TEST(ValuationTest, WriteRejectsValuesThatDoNotFitIntoStoredType) {
526 auto manager = std::make_shared<storm::expressions::ExpressionManager>();
527 auto const s = manager->declareIntegerVariable(
"s");
528 auto const u = manager->declareIntegerVariable(
"u");
535 using storm::exceptions::OutOfRangeException;
538 for (int64_t v : std::views::iota(-8, 8)) {
540 EXPECT_EQ(v, storage.
readValue<int64_t>(0, s));
542 for (int64_t v : {-9, -100, 8, 15, 16}) {
549 EXPECT_EQ(-8, storage.
readValue<int64_t>(0, s));
551 for (int64_t v : std::views::iota(0, 16)) {
553 EXPECT_EQ(v, storage.
readValue<int64_t>(0, u));
555 for (int64_t v : {-1, -16, 16, 17}) {