Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ValuationsStorage.h
Go to the documentation of this file.
1#pragma once
2
3#include <bit>
4#include <concepts>
5#include <cstdint>
6#include <memory>
7#include <optional>
8#include <set>
9#include <span>
10#include <sstream>
11#include <typeinfo>
12
19
23
24namespace storm::expressions {
25template<typename T>
27}
28
29namespace storm::storage::sparse {
30
37template<typename F>
39 std::invocable<F, uint64_t, storm::expressions::Variable const&, bool> || std::invocable<F, uint64_t, storm::expressions::Variable const&, int64_t> ||
40 std::invocable<F, uint64_t, storm::expressions::Variable const&, uint64_t> || std::invocable<F, uint64_t, storm::expressions::Variable const&, double> ||
41 std::invocable<F, uint64_t, storm::expressions::Variable const&, storm::RationalNumber> ||
42 std::invocable<F, uint64_t, storm::expressions::Variable const&, storm::NumberTraits<storm::RationalNumber>::IntegerType> ||
43 std::invocable<F, uint64_t, storm::expressions::Variable const&, std::string_view> ||
44 std::invocable<F, uint64_t, storm::expressions::Variable const&, std::string> ||
45 std::invocable<F, uint64_t, storm::expressions::Variable const&, std::nullopt_t>;
46
53template<typename F>
55 std::invocable<F, uint64_t, storm::expressions::Variable const&, bool&> || std::invocable<F, uint64_t, storm::expressions::Variable const&, int64_t&> ||
56 std::invocable<F, uint64_t, storm::expressions::Variable const&, uint64_t&> || std::invocable<F, uint64_t, storm::expressions::Variable const&, double&> ||
57 std::invocable<F, uint64_t, storm::expressions::Variable const&, storm::RationalNumber&> ||
58 std::invocable<F, uint64_t, storm::expressions::Variable const&, storm::NumberTraits<storm::RationalNumber>::IntegerType&> ||
59 std::invocable<F, uint64_t, storm::expressions::Variable const&, std::string&>;
60
70 public:
72
81 uint64_t const bitOffset; // The first bit holding the variable's data within the valuation.
82 // If the variable is optional, the optional bit is located at bitOffset - 1
83 bool const fits64Bit;
84 };
85
92 std::vector<VariableInformation> const variables;
93 std::shared_ptr<storm::expressions::ExpressionManager const> const expressionManager;
94 uint64_t const sizeInBytes;
95 };
96
101
118 ValuationsStorage(uint64_t numEntities, std::vector<ValuationClassDescription> const& descriptions, std::vector<char> valuations,
119 std::vector<uint64_t> stringMapping, std::vector<char> strings, std::optional<std::vector<uint32_t>> classes = {},
120 std::vector<std::shared_ptr<storm::expressions::ExpressionManager const>> expressionManagers = {});
121
131 ValuationsStorage(uint64_t numEntities, ValuationClassDescription const& description, std::vector<char> valuations,
132 std::shared_ptr<storm::expressions::ExpressionManager const> expressionManager = {});
133
140 ValuationsStorage(std::vector<ValuationClassDescription> const& descriptions,
141 std::vector<std::shared_ptr<storm::expressions::ExpressionManager const>> expressionManagers = {});
142
149 ValuationsStorage(ValuationClassDescription const& description, std::shared_ptr<storm::expressions::ExpressionManager const> expressionManager = {});
150
154 uint64_t size() const;
155
160 uint64_t numClasses() const;
161
165 uint64_t numStrings() const;
166
171 bool hasStrings() const;
172
178 uint64_t getClassOfEntity(uint64_t entity) const;
179
185 ValuationClassDescription getClassDescription(uint64_t classIndex = 0) const;
186
191 storm::expressions::ExpressionManager const& getManager() const;
192
197 storm::expressions::ExpressionManager const& getManager(uint64_t classIndex) const;
198
202 std::set<storm::expressions::Variable> getAllVariables() const;
203
207 bool entityHasVariable(uint64_t entity, storm::expressions::Variable const& variable) const;
208
215 VariableInformation const& getVariableInformation(uint64_t entity, storm::expressions::Variable const& variable) const;
216
222 VariableInformation const& getVariableInformation(storm::expressions::Variable const& variable) const;
223
228 typename storm::umb::UmbModel::Valuation getRawUmbData() const;
229
238 void resize(uint64_t newEntityCount, uint64_t classIndex = 0);
239
252 template<bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
253 void emplaceBack(uint64_t classIndex, Callback const& callback) {
254 STORM_LOG_ASSERT(classIndex < variableClasses.size(),
255 "Class index " << classIndex << " out of bounds. Only " << variableClasses.size() << "classes known.");
256 valuations.resize(valuations.size() + variableClasses[classIndex].sizeInBytes, 0);
257 if (entityClassMappings) {
258 entityClassMappings->toClassMapping.push_back(classIndex);
259 entityClassMappings->toValuationsMapping.push_back(valuations.size());
260 }
261 ++numEntities;
262 writeCallback<false, AllowOptional, AllowedTypes...>(size() - 1, callback);
263 }
264
272 template<bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
273 void emplaceBack(Callback const& callback) {
274 STORM_LOG_ASSERT(variableClasses.size() == 1, "Trying to add a valuation but the class is not unique.");
275 emplaceBack<AllowOptional, AllowedTypes...>(0, callback);
276 }
277
285 template<typename T>
286 ValuationsStorage selectEntities(T const& selectedEntities) const;
287
296 template<typename... AllowedTypes, ValuationReadCallback Callback>
297 void readCallback(uint64_t entity, Callback const& callback) const {
298 for (auto const& varInfo : info(entity).variables) {
299 read<AllowedTypes...>(entity, varInfo, callback);
300 }
301 }
302
311 template<typename... AllowedTypes, ValuationReadCallback Callback>
312 void readCallback(uint64_t entity, storm::expressions::Variable const& variable, Callback const& callback) const {
313 read<AllowedTypes...>(entity, getVariableInformation(entity, variable), callback);
314 }
315
324 template<typename... AllowedTypes, ValuationReadCallback Callback>
325 void readCallback(storm::expressions::Variable const& variable, Callback const& callback) const {
326 if (numClasses() == 1) {
327 // We have only one class, so we can look up the variable info once and use it for all entities
328 auto const& varInfo = getVariableInformation(variable);
329 for (uint64_t entity = 0; entity < size(); ++entity) {
330 read<AllowedTypes...>(entity, varInfo, callback);
331 }
332 } else {
333 for (uint64_t entity = 0; entity < size(); ++entity) {
334 readCallback<AllowedTypes...>(entity, variable, callback);
335 }
336 }
337 }
338
346 template<typename... AllowedTypes, ValuationReadCallback Callback>
347 void readCallback(Callback const& callback) const {
348 for (uint64_t entity = 0; entity < size(); ++entity) {
349 readCallback<AllowedTypes...>(entity, callback);
350 }
351 }
352
362 template<typename ValueType>
363 ValueType readValue(uint64_t entity, storm::expressions::Variable const& variable) const {
364 ValueType result;
365 readCallback<ValueType>(entity, variable, [&](auto, auto, ValueType value) { result = std::move(value); });
366 return result;
367 }
368
375 template<typename RationalValueType>
377
393 template<bool InitializeWithCurrent = false, bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
394 void writeCallback(uint64_t entity, Callback const& callback) {
395 for (auto const& varInfo : info(entity).variables) {
396 write<InitializeWithCurrent, AllowOptional, AllowedTypes...>(entity, varInfo, callback);
397 }
398 }
399
410 template<bool InitializeWithCurrent = false, bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
411 void writeCallback(uint64_t entity, storm::expressions::Variable const& variable, Callback const& callback) {
412 write<InitializeWithCurrent, AllowOptional, AllowedTypes...>(entity, getVariableInformation(entity, variable), callback);
413 }
414
424 template<bool InitializeWithCurrent = false, bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
425 void writeCallback(Callback const& callback) {
426 for (uint64_t entity = 0; entity < size(); ++entity) {
427 writeCallback<InitializeWithCurrent, AllowOptional, AllowedTypes...>(entity, callback);
428 }
429 }
430
440 template<typename ValueType>
441 void writeValue(uint64_t entity, storm::expressions::Variable const& variable, ValueType const& value) {
442 if constexpr (std::is_same_v<ValueType, std::nullopt_t>) {
443 writeCallback<false, true>(entity, variable, [](auto, auto, auto&) { /* intentionally empty */ });
444 } else if constexpr (std::is_same_v<ValueType, std::string_view>) {
445 writeCallback<false, false, std::string>(entity, variable, [&value](auto, auto, std::string& val) { val = value; });
446 } else {
447 writeCallback<false, false, ValueType>(entity, variable, [&value](auto, auto, ValueType& val) { val = value; });
448 }
449 }
450
456 std::size_t hash() const;
457
458 private:
463 template<typename T>
464 static std::string typeName() {
465 if constexpr (std::is_same_v<T, bool>) {
466 return "bool";
467 } else if constexpr (std::is_same_v<T, int64_t>) {
468 return "int64_t";
469 } else if constexpr (std::is_same_v<T, uint64_t>) {
470 return "uint64_t";
471 } else if constexpr (std::is_same_v<T, double>) {
472 return "double";
473 } else if constexpr (std::is_same_v<T, storm::RationalNumber>) {
474 return "storm::RationalNumber";
475 } else if constexpr (std::is_same_v<T, Integer>) {
476 return "Integer (arbitrary-precision)";
477 } else if constexpr (std::is_same_v<T, std::string>) {
478 return "std::string";
479 } else if constexpr (std::is_same_v<T, std::string_view>) {
480 return "std::string_view";
481 } else if constexpr (std::is_same_v<T, std::nullopt_t>) {
482 return "std::nullopt_t";
483 } else {
484 return typeid(T).name();
485 }
486 }
487
492 template<typename... Types>
493 static std::string typeNames() {
494 std::ostringstream oss;
495 [[maybe_unused]] bool first = true;
496 ((oss << (first ? "" : ", ") << typeName<Types>(), first = false), ...);
497 return oss.str();
498 }
499
500 uint64_t numEntities;
501 std::vector<VariablesInformation> variableClasses;
502
503 struct ClassData {
504 std::vector<uint32_t> toClassMapping; // mapping from entity index to class index (size equals number of entities)
505 std::vector<uint64_t> toValuationsMapping; // CSR mapping from entity index to valuations
506 };
507 std::optional<ClassData> entityClassMappings; // present iff there are multiple classes
508
509 std::vector<char> valuations;
510 std::vector<uint64_t> stringMapping;
511 std::vector<char> strings;
512
513 explicit ValuationsStorage(std::vector<VariablesInformation> const& variableClasses);
514
515 VariablesInformation const& info(uint64_t entity) const;
516 std::span<char const> getRawBytes(uint64_t entity) const;
517 std::span<char> getRawBytes(uint64_t entity);
518
519 bool readBit(std::span<char const> bytes, uint64_t position) const;
520 void writeBit(std::span<char> bytes, uint64_t position, bool value) const;
521 uint64_t readUint64(std::span<char const> bytes, uint64_t bitOffset, uint64_t bitSize) const;
522 void writeUint64(std::span<char> bytes, uint64_t bitOffset, uint64_t bitSize, uint64_t value) const;
523
524 template<bool Signed>
525 Integer readInteger(std::span<char const> bytes, uint64_t bitOffset, uint64_t bitSize) const;
526
527 template<bool Signed>
528 void writeInteger(std::span<char> bytes, uint64_t bitOffset, uint64_t bitSize, Integer const& value) const;
529
530 template<typename ValueType>
531 void writeValue(std::span<char> bytes, uint64_t bitOffset, uint64_t bitSize, ValueType const& value);
532
540 template<typename... AllowedTypes, ValuationReadCallback Callback>
541 void read(uint64_t entity, VariableInformation const& varInfo, Callback const& callback) const {
542 auto invokeCallback = [&entity, &varInfo, &callback](auto&& value) -> bool {
543 using ValueType = std::remove_cvref_t<decltype(value)>;
544 bool constexpr IsAllowed = (sizeof...(AllowedTypes) == 0) || std::disjunction_v<std::is_same<ValueType, AllowedTypes>...>;
545 if constexpr (IsAllowed) {
546 callback(entity, varInfo.expressionVariable, std::forward<decltype(value)>(value));
547 }
548 return IsAllowed;
549 };
550
551 if (varInfo.description.isOptional.value_or(false)) {
552 STORM_LOG_ASSERT(varInfo.bitOffset > 0, "Invalid variable information: optional variable must have a preceding presence bit.");
553 if (bool const hasValue = readBit(getRawBytes(entity), varInfo.bitOffset - 1); !hasValue) {
554 if (invokeCallback(std::nullopt)) {
555 return;
556 }
557 }
558 }
559 auto const bitSize = varInfo.description.type.bitSize();
560 using enum storm::umb::Type;
561 if (varInfo.fits64Bit) {
562 STORM_LOG_ASSERT(bitSize <= 64, "Invalid bit size for 64 bit fast path.");
563 uint64_t const rawContent = readUint64(getRawBytes(entity), varInfo.bitOffset, bitSize);
564 switch (varInfo.description.type.type) {
565 case Bool:
566 if (invokeCallback(rawContent != 0)) {
567 return;
568 }
569 break;
570 case Uint:
571 if (int64_t offset = varInfo.description.offset.value_or(0); offset < 0) {
572 // negative offset, output type is int64_t
573 if (invokeCallback(static_cast<int64_t>(rawContent) + offset)) {
574 return;
575 }
576 } else {
577 // non-negative offset, output type is uint64_t but we also try int64_t if uint64_t is not allowed
578 uint64_t const value = rawContent + offset;
579 uint64_t constexpr maxInt64 = std::numeric_limits<int64_t>::max();
580 if (invokeCallback(value) || (value <= maxInt64 && invokeCallback(static_cast<int64_t>(value)))) {
581 return;
582 }
583 }
584 break;
585 case Int: {
586 uint64_t const mostSignificantBitMask = 1ull << (bitSize - 1);
587 bool const isNegative = rawContent & mostSignificantBitMask;
588 // For negative value, take the two's complement (e.g. 1111...1101 is -3)
589 int64_t const value =
590 isNegative ? (-static_cast<int64_t>(~rawContent & (mostSignificantBitMask - 1)) - 1) : static_cast<int64_t>(rawContent);
591 if (invokeCallback(value)) {
592 return;
593 }
594 break;
595 }
596 case Double:
597 if (invokeCallback(std::bit_cast<double>(rawContent))) {
598 return;
599 }
600 break;
601 case Rational:
602 // Reaching this part should not be possible as varInfo.fits64Bit would be false
603 STORM_LOG_ASSERT(false, "Handling of rational values in 64 bit fast path is not implemented.");
604 break;
605 case String:
606 STORM_LOG_ASSERT(rawContent < numStrings(), "String index " << rawContent << " out of bounds (> " << numStrings() << ").");
607 // Prefer the string_view callback
608 if (std::string_view const sv = storm::umb::stringVectorView(strings, stringMapping)[rawContent];
609 invokeCallback(sv) || invokeCallback(std::string(sv))) {
610 return;
611 }
612 break;
613 default:
614 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
615 "ValuationsStorage for variable type '" << varInfo.description.type.toString() << "' are not supported.");
616 }
617 }
618 // reaching this point means that we could not handle the value in the fast path
619 switch (varInfo.description.type.type) {
620 case Bool:
621 // Bools could be encoded with more than 64 bits (which is not reasonable, but possible..)
622 if (invokeCallback(readInteger<false>(getRawBytes(entity), varInfo.bitOffset, bitSize) != Integer(0))) {
623 return;
624 }
625 break;
626 case Uint:
627 case Int: {
628 Integer value = varInfo.description.type.type == Int ? readInteger<true>(getRawBytes(entity), varInfo.bitOffset, bitSize)
629 : readInteger<false>(getRawBytes(entity), varInfo.bitOffset, bitSize);
630 value += storm::utility::convertNumber<Integer>(varInfo.description.offset.value_or(0));
631 if (invokeCallback(value)) {
632 return;
633 }
634 break;
635 }
636 case Double:
637 // Reaching this line happens for two different reasons that are otherwise indistinguishable
638 // here: (a) the field is a compliant 64-bit double but the caller's AllowedTypes didn't
639 // include double (a type mismatch, e.g. reading a double-encoded variable via
640 // getRationalValue/getInt64Value/...) -- fits64Bit is true in this case, and we fall through
641 // to the "not handled" throw below, matching how a mismatched read of any other type is
642 // handled; or (b) the field's declared bit size exceeds 64, which violates the UMB spec for
643 // Double and should be impossible: ValuationDescriptionBuilder::addVariable rejects such
644 // descriptions at construction time (see validateTypeDeclaration).
645 STORM_LOG_ASSERT(varInfo.fits64Bit, "Double variables with more than 64 bits are not compliant.");
646 break;
647 case Rational: {
648 STORM_LOG_ASSERT(bitSize % 2 == 0, "Rational number bit size must be even.");
649 uint64_t const b = bitSize / 2;
650 storm::RationalNumber const numerator = readInteger<true>(getRawBytes(entity), varInfo.bitOffset, b);
651 storm::RationalNumber const denominator = readInteger<false>(getRawBytes(entity), varInfo.bitOffset + b, b);
652 if (invokeCallback(storm::RationalNumber(numerator / denominator))) {
653 return;
654 }
655 break;
656 }
657 case String:
658 // Same reasoning as the Double case above: fits64Bit distinguishes a type mismatch (falls
659 // through to the "not handled" throw below) from a genuine >64-bit violation (asserted
660 // against here, since construction-time validation should now make it impossible).
661 STORM_LOG_ASSERT(varInfo.fits64Bit, "String variables with more than 64 bits are not compliant.");
662 break;
663 default:
664 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
665 "ValuationsStorage for variable type '" << varInfo.description.type.toString() << "' are not supported.");
666 }
667
668 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException,
669 "Variable " << varInfo.description.name << " is stored as " << varInfo.description.type.toString()
670 << ", which cannot be read as any of the requested C++ type(s) [" << typeNames<AllowedTypes...>()
671 << "]. Check that you are using the accessor matching the variable's declared storage type (e.g. "
672 "getDoubleValue instead of getRationalValue for a variable added via addDoubleVariable).");
673 }
674
675 template<bool InitializeWithCurrent = false, bool AllowOptional = false, typename... AllowedTypes, ValuationWriteCallback Callback>
676 void write(uint64_t entity, VariableInformation const& varInfo, Callback const& callback) {
677 auto invokeCallback = [this, &entity, &varInfo, &callback]<typename ValueType>() -> bool {
678 bool constexpr IsAllowed = (sizeof...(AllowedTypes) == 0) || std::disjunction_v<std::is_same<ValueType, AllowedTypes>...>;
679 if constexpr (IsAllowed) {
680 ValueType value;
681 bool isOptional = varInfo.description.isOptional.value_or(false);
682 bool initializeAsUnsetOptional = false;
683 if constexpr (InitializeWithCurrent) {
684 // Initialize with current value (if requested)
685 read<std::nullopt_t, ValueType>(entity, varInfo, [&value, &initializeAsUnsetOptional](auto..., auto&& currentValue) {
686 using CurrentVT = std::remove_cvref_t<decltype(currentValue)>;
687 if constexpr (std::is_same_v<CurrentVT, ValueType>) {
688 value = currentValue;
689 } else {
690 static_assert(std::is_same_v<CurrentVT, std::nullopt_t>);
691 initializeAsUnsetOptional = true;
692 }
693 });
694 } else {
695 initializeAsUnsetOptional = isOptional;
696 if constexpr (std::is_same_v<ValueType, uint64_t> || std::is_same_v<ValueType, int64_t> || std::is_same_v<ValueType, Integer>) {
697 // Explicitly initialize integer values to the lower bound, 0, or the upper bound (in that order)
698 if (varInfo.description.lower && (!std::is_same_v<ValueType, uint64_t> || varInfo.description.lower.value() >= 0)) {
699 value = storm::utility::convertNumber<ValueType>(varInfo.description.lower.value());
700 } else if (!varInfo.description.upper || varInfo.description.upper >= 0) {
702 } else {
703 value = storm::utility::convertNumber<ValueType>(varInfo.description.upper.value());
704 }
705 }
706 }
707 // Invoke the callback. Determine if we need to write a value and ensure that `value` holds the value to write.
708 bool haveToWriteValue = false;
709 if (isOptional) {
710 if constexpr (AllowOptional) {
711 std::optional<ValueType> optionalValue = initializeAsUnsetOptional ? std::optional<ValueType>() : value;
712 callback(entity, varInfo.expressionVariable, optionalValue);
713 if (optionalValue.has_value()) {
714 value = std::move(optionalValue.value());
715 haveToWriteValue = true;
716 }
717 STORM_LOG_ASSERT(varInfo.bitOffset > 0, "Invalid variable information: optional variable must have a preceding presence bit.");
718 writeBit(getRawBytes(entity), varInfo.bitOffset - 1, optionalValue.has_value());
719 } else {
720 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException,
721 "Writing to optional variable " << varInfo.description.name << " was not expected.");
722 }
723 } else {
724 callback(entity, varInfo.expressionVariable, value);
725 haveToWriteValue = true;
726 }
727 if (haveToWriteValue) {
728 // Check bounds and apply the offset for integer variables
729 if constexpr (std::is_same_v<ValueType, uint64_t> || std::is_same_v<ValueType, int64_t> || std::is_same_v<ValueType, Integer>) {
730 if constexpr (std::is_same_v<ValueType, uint64_t> || std::is_same_v<ValueType, int64_t>) {
731 STORM_LOG_THROW(!varInfo.description.lower || std::cmp_greater_equal(value, varInfo.description.lower.value()),
732 storm::exceptions::OutOfRangeException,
733 "Value " << value << " is out of range for variable " << varInfo.description.name
734 << ": value is smaller than lower bound " << varInfo.description.lower.value() << ".");
735 STORM_LOG_THROW(!varInfo.description.upper || std::cmp_less_equal(value, varInfo.description.upper.value()),
736 storm::exceptions::OutOfRangeException,
737 "Value " << value << " is out of range for variable " << varInfo.description.name
738 << ": value is greater than upper bound " << varInfo.description.upper.value() << ".");
739 } else {
740 if (varInfo.description.lower) {
741 STORM_LOG_THROW(value >= storm::utility::convertNumber<Integer>(varInfo.description.lower.value()),
742 storm::exceptions::OutOfRangeException,
743 "Value " << value << " is out of range for variable " << varInfo.description.name
744 << ": value is smaller than lower bound " << varInfo.description.lower.value() << ".");
745 }
746 if (varInfo.description.upper) {
747 STORM_LOG_THROW(value <= storm::utility::convertNumber<Integer>(varInfo.description.upper.value()),
748 storm::exceptions::OutOfRangeException,
749 "Value " << value << " is out of range for variable " << varInfo.description.name
750 << ": value is greater than upper bound " << varInfo.description.upper.value() << ".");
751 }
752 }
753 if (auto offset = varInfo.description.offset.value_or(0); offset != 0) {
754 if constexpr (std::is_same_v<ValueType, uint64_t>) {
755 STORM_LOG_ASSERT(std::cmp_greater_equal(value, offset),
756 "Set negative value " << value << "-" << offset << " to unsigned variable.");
757 value -= offset;
758 } else {
760 }
761 }
762 }
763 // Write the value
764 writeValue(getRawBytes(entity), varInfo.bitOffset, varInfo.description.type.bitSize(), value);
765 }
766 }
767 return IsAllowed;
768 };
769
770 using enum storm::umb::Type;
771 switch (varInfo.description.type.type) {
772 case Bool:
773 if (invokeCallback.template operator()<bool>()) {
774 return;
775 }
776 break;
777 case Uint:
778 if (varInfo.fits64Bit) {
779 if (varInfo.description.offset.value_or(0) >= 0) {
780 // non-negative offset, default output type is uint64_t
781 if (invokeCallback.template operator()<uint64_t>()) {
782 return;
783 }
784 }
785 // take int64_t if uint64_t is not allowed or we have a negative offset
786 if (invokeCallback.template operator()<int64_t>()) {
787 return;
788 }
789 }
790 // finally take Integer if the 64 bit types are not allowed or insufficient
791 if (invokeCallback.template operator()<Integer>()) {
792 return;
793 }
794 break;
795 case Int:
796 // Prefer int64_t if it fits and is allowed.
797 if ((varInfo.fits64Bit && invokeCallback.template operator()<int64_t>()) || invokeCallback.template operator()<Integer>()) {
798 return;
799 }
800 break;
801 case Double:
802 if (invokeCallback.template operator()<double>()) {
803 return;
804 }
805 break;
806 case Rational:
807 if (invokeCallback.template operator()<storm::RationalNumber>()) {
808 return;
809 }
810 break;
811 case String:
812 if (invokeCallback.template operator()<std::string>()) {
813 return;
814 }
815 break;
816 default:
817 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
818 "ValuationsStorage for variable type '" << varInfo.description.type.toString() << "' are not supported.");
819 }
820 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException,
821 "Variable " << varInfo.description.name << " is stored as " << varInfo.description.type.toString()
822 << ", which cannot be written as any of the requested C++ type(s) [" << typeNames<AllowedTypes...>()
823 << "]. Check that you are using the accessor matching the variable's declared storage type (e.g. "
824 "writeDoubleValue instead of writeRationalValue for a variable added via addDoubleVariable).");
825 }
826};
827} // namespace storm::storage::sparse
Stores valuations of variables for a set of entities (e.g.
ValuationsStorage(ValuationsStorage const &)=default
void writeCallback(uint64_t entity, storm::expressions::Variable const &variable, Callback const &callback)
Writes a single variable of the given entity by invoking callback.
ValueType readValue(uint64_t entity, storm::expressions::Variable const &variable) const
Reads a single variable of the given entity and returns its value directly.
storm::umb::UmbModel::Valuation getRawUmbData() const
Exports a snapshot of the raw UMB model valuation data (packed bytes, optional class mapping,...
bool entityHasVariable(uint64_t entity, storm::expressions::Variable const &variable) const
Returns true iff the variable is relevant for the given entity's class, i.e.
ValuationsStorage selectEntities(T const &selectedEntities) const
Constructs a new ValuationsStorage containing only the selected entities, in the order they appear in...
void resize(uint64_t newEntityCount, uint64_t classIndex=0)
Resizes the entity count to newEntityCount.
std::set< storm::expressions::Variable > getAllVariables() const
Returns all expression variables that this valuation assigns values to for at least one class.
void readCallback(uint64_t entity, Callback const &callback) const
Reads all variables of the given entity and invokes callback for each one.
void writeValue(uint64_t entity, storm::expressions::Variable const &variable, ValueType const &value)
Directly writes value to the given variable of entity.
std::size_t hash() const
Computes a hash of the entire valuation data.
uint64_t getClassOfEntity(uint64_t entity) const
Returns the class index of the given entity.
storm::expressions::ExpressionManager const & getManager() const
Returns the expression manager shared by all classes.
void setValuesInEvaluator(uint64_t entity, storm::expressions::ExpressionEvaluator< RationalValueType > &evaluator) const
Reads the variable values for the given entity and sets them into the given expression evaluator.
void emplaceBack(Callback const &callback)
Convenience overload of emplaceBack for single-class ValuationsStorage (asserts numClasses() == 1).
void writeCallback(uint64_t entity, Callback const &callback)
Writes all variables of the given entity by invoking callback for each one.
void writeCallback(Callback const &callback)
Writes all variables of every entity by invoking callback for each (entity, variable) pair.
VariableInformation const & getVariableInformation(uint64_t entity, storm::expressions::Variable const &variable) const
Looks up compiled variable information for the given entity and variable.
void readCallback(Callback const &callback) const
Reads all variables of every entity and invokes callback for each (entity, variable) pair.
ValuationsStorage & operator=(ValuationsStorage &&)=default
ValuationsStorage(ValuationsStorage &&)=default
storm::NumberTraits< storm::RationalNumber >::IntegerType Integer
ValuationsStorage & operator=(ValuationsStorage const &)=default
void readCallback(storm::expressions::Variable const &variable, Callback const &callback) const
Reads the given variable for every entity and invokes callback for each one.
void emplaceBack(uint64_t classIndex, Callback const &callback)
Appends a new entity of the given class and populates its variables via callback.
ValuationClassDescription getClassDescription(uint64_t classIndex=0) const
Reconstructs the ValuationClassDescription for the given class from the stored compiled variable info...
void readCallback(uint64_t entity, storm::expressions::Variable const &variable, Callback const &callback) const
Reads a single variable of the given entity and invokes callback with its value.
Concept for a callback used in readCallback / readValue.
Concept for a callback used in writeCallback / writeValue.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
SFTBDDChecker::ValueType ValueType
auto stringVectorView(SEQ< char >::value_type const &strings, CSR::value_type const &stringMapping)
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
NumberTraits< RationalType >::IntegerType numerator(RationalType const &number)
ValueType zero()
Definition constants.cpp:24
TargetType convertNumber(SourceType const &number)
Compiled information about a single variable within a valuation class.
Compiled information about all variables belonging to one valuation class.
std::shared_ptr< storm::expressions::ExpressionManager const > const expressionManager