Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
LocalExpressionInformation.cpp
Go to the documentation of this file.
2
4
5#include <boost/algorithm/string/join.hpp>
7
9
10namespace storm::gbar {
11namespace abstraction {
12
13template<storm::dd::DdType DdType>
15 : relevantVariables(abstractionInformation.getAbstractedVariables()),
16 expressionBlocks(relevantVariables.size()),
17 abstractionInformation(abstractionInformation) {
18 // Assign each variable to a new block.
19 uint_fast64_t currentBlock = 0;
20 variableBlocks.resize(relevantVariables.size());
21 for (auto const& variable : relevantVariables) {
22 this->variableToBlockMapping[variable] = currentBlock;
23 this->variableToExpressionsMapping[variable] = std::set<uint_fast64_t>();
24 variableBlocks[currentBlock].insert(variable);
25 ++currentBlock;
26 }
27}
28
29template<storm::dd::DdType DdType>
30std::map<uint64_t, uint64_t> LocalExpressionInformation<DdType>::addExpression(uint_fast64_t globalExpressionIndex) {
31 storm::expressions::Expression const& expression = abstractionInformation.get().getPredicateByIndex(globalExpressionIndex);
32
33 // Register the expression for all variables that appear in it.
34 std::set<storm::expressions::Variable> expressionVariables = expression.getVariables();
35 for (auto const& variable : expressionVariables) {
36 variableToExpressionsMapping[variable].insert(globalExpressionIndex);
37 }
38
39 // Add the expression to the block of the first variable. When relating the variables, the blocks will
40 // get merged (if necessary).
41 STORM_LOG_ASSERT(!expressionVariables.empty(), "Found no variables in expression.");
42 expressionBlocks[getBlockIndexOfVariable(*expressionVariables.begin())].insert(globalExpressionIndex);
43
44 // Add expression and relate all the appearing variables.
45 return this->relate(expressionVariables);
46}
47
48template<storm::dd::DdType DdType>
50 return getBlockIndexOfVariable(firstVariable) == getBlockIndexOfVariable(secondVariable);
51}
52
53template<storm::dd::DdType DdType>
54std::map<uint64_t, uint64_t> LocalExpressionInformation<DdType>::relate(storm::expressions::Variable const& firstVariable,
55 storm::expressions::Variable const& secondVariable) {
56 return this->relate({firstVariable, secondVariable});
57}
58
59template<storm::dd::DdType DdType>
60std::map<uint64_t, uint64_t> LocalExpressionInformation<DdType>::relate(std::set<storm::expressions::Variable> const& variables) {
61 // Determine all blocks that need to be merged.
62 std::set<uint_fast64_t> blocksToMerge;
63 for (auto const& variable : variables) {
64 blocksToMerge.insert(getBlockIndexOfVariable(variable));
65 }
66
67 STORM_LOG_ASSERT(variables.empty() || !blocksToMerge.empty(), "Found no blocks to merge.");
68
69 // If we found a single block only, there is nothing to do.
70 if (blocksToMerge.size() <= 1) {
71 std::map<uint64_t, uint64_t> identity;
72 for (uint64_t i = 0; i < getNumberOfBlocks(); ++i) {
73 identity.emplace_hint(identity.end(), i, i);
74 }
75 return identity;
76 }
77
78 return this->mergeBlocks(blocksToMerge);
79}
80
81template<storm::dd::DdType DdType>
82std::map<uint64_t, uint64_t> LocalExpressionInformation<DdType>::mergeBlocks(std::set<uint_fast64_t> const& blocksToMerge) {
83 std::map<uint64_t, uint64_t> oldToNewIndices;
84
85 // Merge all blocks into the block to keep.
86 std::vector<std::set<storm::expressions::Variable>> newVariableBlocks;
87 std::vector<std::set<uint_fast64_t>> newExpressionBlocks;
88
89 std::set<uint_fast64_t>::const_iterator blocksToMergeIt = blocksToMerge.begin();
90 std::set<uint_fast64_t>::const_iterator blocksToMergeIte = blocksToMerge.end();
91
92 // Determine which block to keep (to merge the other blocks into).
93 uint_fast64_t blockToKeep = *blocksToMergeIt;
94 ++blocksToMergeIt;
95
96 for (uint_fast64_t blockIndex = 0; blockIndex < variableBlocks.size(); ++blockIndex) {
97 // If the block is the next one to merge into the block to keep, do so now.
98 if (blocksToMergeIt != blocksToMergeIte && *blocksToMergeIt == blockIndex && blockIndex != blockToKeep) {
99 // Adjust the mapping for all variables of the old block.
100 for (auto const& variable : variableBlocks[blockIndex]) {
101 variableToBlockMapping[variable] = blockToKeep;
102 }
103 oldToNewIndices[blockIndex] = blockToKeep;
104
105 newVariableBlocks[blockToKeep].insert(variableBlocks[blockIndex].begin(), variableBlocks[blockIndex].end());
106 newExpressionBlocks[blockToKeep].insert(expressionBlocks[blockIndex].begin(), expressionBlocks[blockIndex].end());
107 ++blocksToMergeIt;
108 } else {
109 // Otherwise just move the current block to the new partition.
110 oldToNewIndices[blockIndex] = newVariableBlocks.size();
111
112 // Adjust the mapping for all variables of the old block.
113 for (auto const& variable : variableBlocks[blockIndex]) {
114 variableToBlockMapping[variable] = newVariableBlocks.size();
115 }
116
117 newVariableBlocks.emplace_back(std::move(variableBlocks[blockIndex]));
118 newExpressionBlocks.emplace_back(std::move(expressionBlocks[blockIndex]));
119 }
120 }
121
122 variableBlocks = std::move(newVariableBlocks);
123 expressionBlocks = std::move(newExpressionBlocks);
124
125 return oldToNewIndices;
126}
127
128template<storm::dd::DdType DdType>
129std::set<storm::expressions::Variable> const& LocalExpressionInformation<DdType>::getBlockOfVariable(storm::expressions::Variable const& variable) const {
130 return variableBlocks[getBlockIndexOfVariable(variable)];
131}
132
133template<storm::dd::DdType DdType>
135 return this->variableBlocks.size();
136}
137
138template<storm::dd::DdType DdType>
139std::set<storm::expressions::Variable> const& LocalExpressionInformation<DdType>::getVariableBlockWithIndex(uint_fast64_t blockIndex) const {
140 return this->variableBlocks[blockIndex];
141}
142
143template<storm::dd::DdType DdType>
145 STORM_LOG_ASSERT(this->relevantVariables.find(variable) != this->relevantVariables.end(), "Illegal variable '" << variable.getName() << "' for partition.");
146 return this->variableToBlockMapping.find(variable)->second;
147}
148
149template<storm::dd::DdType DdType>
150std::set<uint_fast64_t> LocalExpressionInformation<DdType>::getBlockIndicesOfVariables(std::set<storm::expressions::Variable> const& variables) const {
151 std::set<uint_fast64_t> result;
152 for (auto const& variable : variables) {
153 result.insert(getBlockIndexOfVariable(variable));
154 }
155 return result;
156}
157
158template<storm::dd::DdType DdType>
160 return this->expressionBlocks[getBlockIndexOfVariable(variable)];
161}
162
163template<storm::dd::DdType DdType>
164std::set<uint_fast64_t> LocalExpressionInformation<DdType>::getRelatedExpressions(std::set<storm::expressions::Variable> const& variables) const {
165 // Start by determining the indices of all expression blocks that are related to any of the variables.
166 std::set<uint_fast64_t> relatedExpressionBlockIndices;
167 for (auto const& variable : variables) {
168 relatedExpressionBlockIndices.insert(getBlockIndexOfVariable(variable));
169 }
170
171 // Then join the expressions of these blocks and return the result.
172 std::set<uint_fast64_t> result;
173 for (auto const& blockIndex : relatedExpressionBlockIndices) {
174 result.insert(expressionBlocks[blockIndex].begin(), expressionBlocks[blockIndex].end());
175 }
176 return result;
177}
178
179template<storm::dd::DdType DdType>
181 STORM_LOG_ASSERT(this->relevantVariables.find(variable) != this->relevantVariables.end(), "Illegal variable '" << variable.getName() << "' for partition.");
182 return this->variableToExpressionsMapping.find(variable)->second;
183}
184
185template<storm::dd::DdType DdType>
186std::set<uint_fast64_t> LocalExpressionInformation<DdType>::getExpressionsUsingVariables(std::set<storm::expressions::Variable> const& variables) const {
187 std::set<uint_fast64_t> result;
188
189 for (auto const& variable : variables) {
190 STORM_LOG_ASSERT(this->relevantVariables.find(variable) != this->relevantVariables.end(),
191 "Illegal variable '" << variable.getName() << "' for partition.");
192 auto it = this->variableToExpressionsMapping.find(variable);
193 result.insert(it->second.begin(), it->second.end());
194 }
195
196 return result;
197}
198
199template<storm::dd::DdType DdType>
200std::set<uint_fast64_t> const& LocalExpressionInformation<DdType>::getExpressionBlock(uint64_t index) const {
201 return expressionBlocks[index];
202}
203
204template<storm::dd::DdType DdType>
205std::ostream& operator<<(std::ostream& out, LocalExpressionInformation<DdType> const& partition) {
206 std::vector<std::string> blocks;
207 for (uint_fast64_t index = 0; index < partition.variableBlocks.size(); ++index) {
208 auto const& variableBlock = partition.variableBlocks[index];
209 auto const& expressionBlock = partition.expressionBlocks[index];
210
211 std::vector<std::string> variablesInBlock;
212 for (auto const& variable : variableBlock) {
213 variablesInBlock.push_back(variable.getName());
214 }
215
216 std::vector<std::string> expressionsInBlock;
217 for (auto const& expressionIndex : expressionBlock) {
218 std::stringstream stream;
219 stream << partition.abstractionInformation.get().getPredicateByIndex(expressionIndex);
220 expressionsInBlock.push_back(stream.str());
221 }
222
223 blocks.push_back("<[" + boost::algorithm::join(variablesInBlock, ", ") + "], [" + boost::algorithm::join(expressionsInBlock, ", ") + "]>");
224 }
225
226 out << "{";
227 out << boost::join(blocks, ", ");
228 out << "}";
229 return out;
230}
231
232template class LocalExpressionInformation<storm::dd::DdType::CUDD>;
233template class LocalExpressionInformation<storm::dd::DdType::Sylvan>;
234
235template std::ostream& operator<<(std::ostream& out, LocalExpressionInformation<storm::dd::DdType::CUDD> const& partition);
236template std::ostream& operator<<(std::ostream& out, LocalExpressionInformation<storm::dd::DdType::Sylvan> const& partition);
237} // namespace abstraction
238} // namespace storm::gbar
std::set< storm::expressions::Variable > getVariables() const
Retrieves the set of all variables that appear in the expression.
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
std::map< uint64_t, uint64_t > addExpression(uint_fast64_t globalExpressionIndex)
Adds the expression and therefore indirectly may cause blocks of variables to be merged.
bool areRelated(storm::expressions::Variable const &firstVariable, storm::expressions::Variable const &secondVariable)
Retrieves whether the two given variables are in the same block of the partition.
std::set< uint_fast64_t > getExpressionsUsingVariables(std::set< storm::expressions::Variable > const &variables) const
Retrieves the indices of the expressions in which the given variables appear.
std::set< storm::expressions::Variable > const & getBlockOfVariable(storm::expressions::Variable const &variable) const
Retrieves the block of related variables of the given variable.
std::set< uint_fast64_t > getBlockIndicesOfVariables(std::set< storm::expressions::Variable > const &variables) const
Retrieves the block indices of the given variables.
std::map< uint64_t, uint64_t > relate(storm::expressions::Variable const &firstVariable, storm::expressions::Variable const &secondVariable)
Places the given variables in the same block of the partition and performs the implied merges.
std::set< uint_fast64_t > const & getExpressionsUsingVariable(storm::expressions::Variable const &variable) const
Retrieves the indices of the expressions in which the given variable appears.
uint_fast64_t getNumberOfBlocks() const
Retrieves the number of blocks of the variable partition.
std::set< uint_fast64_t > const & getRelatedExpressions(storm::expressions::Variable const &variable) const
Retrieves the indices of the expressions related to the given variable.
std::set< storm::expressions::Variable > const & getVariableBlockWithIndex(uint_fast64_t blockIndex) const
Retrieves the block with the given index.
std::set< uint_fast64_t > const & getExpressionBlock(uint64_t index) const
Retrieves the expression block with the given index.
uint_fast64_t getBlockIndexOfVariable(storm::expressions::Variable const &variable) const
Retrieves the block index of the given variable.
LocalExpressionInformation(AbstractionInformation< DdType > const &abstractionInformation)
Constructs a new variable partition.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
std::ostream & operator<<(std::ostream &out, LocalExpressionInformation< DdType > const &partition)