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