Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DFTStateGenerationInfo.h
Go to the documentation of this file.
1#pragma once
2
3#include <bit>
4#include <cmath>
5
7
8namespace storm::dft {
9namespace storage {
10
12 private:
13 const size_t mUsageInfoBits;
14 const size_t stateIndexSize;
15 std::map<size_t, size_t> mSpareUsageIndex; // id spare -> index first bit in state
16 std::map<size_t, size_t> mSpareActivationIndex; // id spare representative -> index in state
17 std::vector<size_t> mIdToStateIndex; // id -> index first bit in state
18 std::vector<size_t> mImmediateFailedBEs; // list of BEs which are immediately failed
19 std::map<size_t, std::vector<size_t>> mSeqRestrictionPreElements; // id -> list of restriction pre elements
20 std::map<size_t, std::vector<size_t>> mSeqRestrictionPostElements; // id -> list of restriction post elements
21 std::map<size_t, std::vector<size_t>> mMutexRestrictionElements; // id -> list of elements in the same mutexes
22 std::vector<std::pair<size_t, std::vector<size_t>>>
23 mSymmetries; // pair (length of symmetry group, vector indicating the starting points of the symmetry groups)
24
25 public:
26 DFTStateGenerationInfo(size_t nrElements, size_t nrOfSpares, size_t nrRepresentatives, size_t maxSpareChildCount)
27 : mUsageInfoBits(getUsageInfoBits(maxSpareChildCount)),
28 stateIndexSize(getStateVectorSize(nrElements, nrOfSpares, nrRepresentatives, maxSpareChildCount)),
29 mIdToStateIndex(nrElements) {
30 STORM_LOG_ASSERT(maxSpareChildCount < std::pow(2, mUsageInfoBits), "Bit length incorrect.");
31 }
32
38 static size_t getUsageInfoBits(size_t maxSpareChildCount) {
39 return std::bit_width(maxSpareChildCount);
40 }
41
50 static size_t getStateVectorSize(size_t nrElements, size_t nrOfSpares, size_t nrRepresentatives, size_t maxSpareChildCount) {
51 return nrElements * 2 + nrOfSpares * getUsageInfoBits(maxSpareChildCount) + nrRepresentatives;
52 }
53
54 size_t usageInfoBits() const {
55 return mUsageInfoBits;
56 }
57
58 void addStateIndex(size_t id, size_t index) {
59 STORM_LOG_ASSERT(id < mIdToStateIndex.size(), "Id invalid.");
60 STORM_LOG_ASSERT(index < stateIndexSize, "Index invalid.");
61 mIdToStateIndex[id] = index;
62 }
63
64 void addImmediateFailedBE(size_t id) {
65 mImmediateFailedBEs.push_back(id);
66 }
67
68 std::vector<size_t> const& immediateFailedBE() const {
69 return mImmediateFailedBEs;
70 }
71
72 void setRestrictionPreElements(size_t id, std::vector<size_t> const& elems) {
73 mSeqRestrictionPreElements[id] = elems;
74 }
75
76 void setRestrictionPostElements(size_t id, std::vector<size_t> const& elems) {
77 mSeqRestrictionPostElements[id] = elems;
78 }
79
80 void setMutexElements(size_t id, std::vector<size_t> const& elems) {
81 mMutexRestrictionElements[id] = elems;
82 }
83
84 std::vector<size_t> const& seqRestrictionPreElements(size_t index) const {
85 STORM_LOG_ASSERT(mSeqRestrictionPreElements.count(index) > 0, "Index invalid.");
86 return mSeqRestrictionPreElements.at(index);
87 }
88
89 std::vector<size_t> const& seqRestrictionPostElements(size_t index) const {
90 STORM_LOG_ASSERT(mSeqRestrictionPostElements.count(index) > 0, "Index invalid.");
91 return mSeqRestrictionPostElements.at(index);
92 }
93
94 std::vector<size_t> const& mutexRestrictionElements(size_t index) const {
95 STORM_LOG_ASSERT(mMutexRestrictionElements.count(index) > 0, "Index invalid.");
96 return mMutexRestrictionElements.at(index);
97 }
98
99 void addSpareActivationIndex(size_t id, size_t index) {
100 STORM_LOG_ASSERT(index < stateIndexSize, "Index invalid.");
101 mSpareActivationIndex[id] = index;
102 }
103
104 void addSpareUsageIndex(size_t id, size_t index) {
105 STORM_LOG_ASSERT(index < stateIndexSize, "Index invalid.");
106 mSpareUsageIndex[id] = index;
107 }
108
109 size_t getStateIndex(size_t id) const {
110 STORM_LOG_ASSERT(id < mIdToStateIndex.size(), "Id invalid.");
111 return mIdToStateIndex[id];
112 }
113
114 size_t getSpareUsageIndex(size_t id) const {
115 STORM_LOG_ASSERT(mSpareUsageIndex.count(id) > 0, "Id invalid.");
116 return mSpareUsageIndex.at(id);
117 }
118
119 size_t getSpareActivationIndex(size_t id) const {
120 STORM_LOG_ASSERT(mSpareActivationIndex.count(id) > 0, "Id invalid.");
121 return mSpareActivationIndex.at(id);
122 }
123
124 void addSymmetry(size_t length, std::vector<size_t>& startingIndices) {
125 mSymmetries.push_back(std::make_pair(length, startingIndices));
126 }
127
132 // Iterate over possible children
133 for (size_t i = 0; i < mSymmetries.size(); ++i) {
134 size_t childStart = mSymmetries[i].second[0];
135 size_t childLength = mSymmetries[i].first;
136 // Iterate over possible parents
137 for (size_t j = i + 1; j < mSymmetries.size(); ++j) {
138 size_t parentStart = mSymmetries[j].second[0];
139 size_t parentLength = mSymmetries[j].first;
140 // Check if child lies in parent
141 if (parentStart <= childStart && childStart + childLength < parentStart + parentLength) {
142 // We add the symmetry of the child to all symmetric elements in the parent
143 std::vector<std::vector<size_t>> newSymmetries;
144 // Start iteration at 1, because symmetry for child at 0 is already included
145 for (size_t index = 1; index < mSymmetries[j].second.size(); ++index) {
146 std::vector<size_t> newStarts;
147 // Apply child symmetry to all symmetric elements of parent
148 for (size_t symmetryStarts : mSymmetries[i].second) {
149 // Get symmetric element by applying the bijection
150 size_t symmetryOffset = symmetryStarts - parentStart;
151 newStarts.push_back(mSymmetries[j].second[index] + symmetryOffset);
152 }
153 newSymmetries.push_back(newStarts);
154 }
155 // Insert new symmetry after child
156 for (size_t index = 0; index < newSymmetries.size(); ++index) {
157 mSymmetries.insert(mSymmetries.begin() + i + 1 + index, std::make_pair(childLength, newSymmetries[index]));
158 }
159 i += newSymmetries.size();
160 break;
161 }
162 }
163 }
164 }
165
167 for (auto pair : mSymmetries) {
168 STORM_LOG_ASSERT(pair.first > 0, "Empty symmetry.");
169 STORM_LOG_ASSERT(pair.first < stateIndexSize, "Symmetry too long.");
170 for ([[maybe_unused]] size_t index : pair.second) {
171 STORM_LOG_ASSERT(index < stateIndexSize, "Symmetry starting point " << index << " invalid.");
172 STORM_LOG_ASSERT(index + pair.first < stateIndexSize, "Symmetry ending point " << index << " invalid.");
173 }
174 }
175 }
176
177 size_t getSymmetrySize() const {
178 return mSymmetries.size();
179 }
180
181 bool hasSymmetries() const {
182 return !mSymmetries.empty();
183 }
184
185 size_t getSymmetryLength(size_t pos) const {
186 STORM_LOG_ASSERT(pos < mSymmetries.size(), "Pos invalid.");
187 return mSymmetries[pos].first;
188 }
189
190 std::vector<size_t> const& getSymmetryIndices(size_t pos) const {
191 STORM_LOG_ASSERT(pos < mSymmetries.size(), "Pos invalid.");
192 return mSymmetries[pos].second;
193 }
194
195 friend std::ostream& operator<<(std::ostream& os, DFTStateGenerationInfo const& info) {
196 os << "StateGenerationInfo:\n";
197 os << "Length of state vector: " << info.stateIndexSize << '\n';
198 os << "Id to state index:\n";
199 for (size_t id = 0; id < info.mIdToStateIndex.size(); ++id) {
200 os << id << " -> " << info.getStateIndex(id) << '\n';
201 }
202 os << "Spare usage index with usage InfoBits of size " << info.mUsageInfoBits << ":\n";
203 for (auto pair : info.mSpareUsageIndex) {
204 os << pair.first << " -> " << pair.second << '\n';
205 }
206 os << "Spare activation index:\n";
207 for (auto pair : info.mSpareActivationIndex) {
208 os << pair.first << " -> " << pair.second << '\n';
209 }
210 os << "Symmetries:\n";
211 for (auto pair : info.mSymmetries) {
212 os << "Length: " << pair.first << ", starting indices: ";
213 for (size_t index : pair.second) {
214 os << index << ", ";
215 }
216 os << '\n';
217 }
218 return os;
219 }
220};
221
222} // namespace storage
223} // namespace storm::dft
static size_t getStateVectorSize(size_t nrElements, size_t nrOfSpares, size_t nrRepresentatives, size_t maxSpareChildCount)
Get length of BitVector capturing DFT state.
std::vector< size_t > const & immediateFailedBE() const
void addSpareActivationIndex(size_t id, size_t index)
DFTStateGenerationInfo(size_t nrElements, size_t nrOfSpares, size_t nrRepresentatives, size_t maxSpareChildCount)
void generateSymmetries()
Generate more symmetries by combining two symmetries.
void setRestrictionPostElements(size_t id, std::vector< size_t > const &elems)
void setRestrictionPreElements(size_t id, std::vector< size_t > const &elems)
std::vector< size_t > const & mutexRestrictionElements(size_t index) const
std::vector< size_t > const & seqRestrictionPreElements(size_t index) const
std::vector< size_t > const & seqRestrictionPostElements(size_t index) const
friend std::ostream & operator<<(std::ostream &os, DFTStateGenerationInfo const &info)
std::vector< size_t > const & getSymmetryIndices(size_t pos) const
void addSymmetry(size_t length, std::vector< size_t > &startingIndices)
static size_t getUsageInfoBits(size_t maxSpareChildCount)
Get number of bits required to store claiming information for spares in binary format.
void setMutexElements(size_t id, std::vector< size_t > const &elems)
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9