Storm 1.13.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ExpressionManager.cpp
Go to the documentation of this file.
2
8
9namespace storm {
10namespace expressions {
11
12VariableIterator::VariableIterator(ExpressionManager const& manager, std::unordered_map<std::string, uint_fast64_t>::const_iterator nameIndexIterator,
13 std::unordered_map<std::string, uint_fast64_t>::const_iterator nameIndexIteratorEnd, VariableSelection const& selection)
14 : manager(manager), nameIndexIterator(nameIndexIterator), nameIndexIteratorEnd(nameIndexIteratorEnd), selection(selection) {
15 moveUntilNextSelectedElement(false);
16}
17
19 return this->nameIndexIterator == other.nameIndexIterator;
20}
21
23 return !(*this == other);
24}
25
29
31 moveUntilNextSelectedElement();
32 return *this;
33}
34
36 moveUntilNextSelectedElement();
37 return *this;
38}
39
40void VariableIterator::moveUntilNextSelectedElement(bool atLeastOneStep) {
41 if (atLeastOneStep && nameIndexIterator != nameIndexIteratorEnd) {
42 ++nameIndexIterator;
43 }
44
45 // Move the underlying iterator forward until a variable matches the selection.
46 while (nameIndexIterator != nameIndexIteratorEnd &&
47 (selection == VariableSelection::OnlyRegularVariables && (nameIndexIterator->second & ExpressionManager::auxiliaryMask) != 0) &&
48 (selection == VariableSelection::OnlyAuxiliaryVariables && (nameIndexIterator->second & ExpressionManager::auxiliaryMask) == 0)) {
49 ++nameIndexIterator;
50 }
51
52 if (nameIndexIterator != nameIndexIteratorEnd) {
53 currentElement = std::make_pair(Variable(manager.getSharedPointer(), nameIndexIterator->second), manager.getVariableType(nameIndexIterator->second));
54 }
55}
56
58 : nameToIndexMapping(),
59 indexToNameMapping(),
60 indexToTypeMapping(),
61 numberOfBooleanVariables(0),
62 numberOfIntegerVariables(0),
63 numberOfBitVectorVariables(0),
64 numberOfRationalVariables(0),
65 numberOfArrayVariables(0),
66 numberOfStringVariables(0),
67 freshVariableCounter(0) {
68 // Intentionally left empty.
69}
70
72 // Intentionally left empty.
73}
74
75std::shared_ptr<ExpressionManager> ExpressionManager::clone() const {
76 return std::shared_ptr<ExpressionManager>(new ExpressionManager(*this));
77}
78
80 return Expression(std::make_shared<BooleanLiteralExpression>(*this, value));
81}
82
83Expression ExpressionManager::integer(int_fast64_t value) const {
84 return Expression(std::make_shared<IntegerLiteralExpression>(*this, value));
85}
86
88 return Expression(std::make_shared<RationalLiteralExpression>(*this, value));
89}
90
91Expression ExpressionManager::rational(storm::RationalNumber const& value) const {
92 return Expression(std::make_shared<RationalLiteralExpression>(*this, value));
93}
94
96 return this == &other;
97}
98
100 if (!booleanType) {
101 booleanType = Type(this->getSharedPointer(), std::shared_ptr<BaseType>(new BooleanType()));
102 }
103 return booleanType.get();
104}
105
107 if (!integerType) {
108 integerType = Type(this->getSharedPointer(), std::shared_ptr<BaseType>(new IntegerType()));
109 }
110 return integerType.get();
111}
112
113Type const& ExpressionManager::getBitVectorType(std::size_t width) const {
114 Type type(this->getSharedPointer(), std::shared_ptr<BaseType>(new BitVectorType(width)));
115 auto typeIterator = bitvectorTypes.find(type);
116 if (typeIterator == bitvectorTypes.end()) {
117 auto iteratorBoolPair = bitvectorTypes.insert(type);
118 return *iteratorBoolPair.first;
119 }
120 return *typeIterator;
121}
122
124 if (!rationalType) {
125 rationalType = Type(this->getSharedPointer(), std::shared_ptr<BaseType>(new RationalType()));
126 }
127 return rationalType.get();
128}
129
130Type const& ExpressionManager::getArrayType(Type elementType) const {
131 Type type(this->getSharedPointer(), std::shared_ptr<BaseType>(new ArrayType(elementType)));
132 return *arrayTypes.insert(type).first;
133}
134
136 if (!transcendentalNumberType) {
137 transcendentalNumberType = Type(this->getSharedPointer(), std::shared_ptr<BaseType>(new TranscendentalNumberType()));
138 }
139 return transcendentalNumberType.get();
140}
141
143 if (!stringType) {
144 stringType = Type(this->getSharedPointer(), std::shared_ptr<BaseType>(new StringType()));
145 }
146 return stringType.get();
147}
148
149bool ExpressionManager::isValidVariableName(std::string const& name) {
150 return name.size() < 2 || name.at(0) != '_' || name.at(1) != '_';
151}
152
153bool ExpressionManager::variableExists(std::string const& name) const {
154 auto nameIndexPair = nameToIndexMapping.find(name);
155 return nameIndexPair != nameToIndexMapping.end();
156}
157
159 return declareFreshVariable(variable.getType(), true, "_" + variable.getName() + "_");
160}
161
162Variable ExpressionManager::declareVariable(std::string const& name, storm::expressions::Type const& variableType, bool auxiliary) {
163 STORM_LOG_THROW(!variableExists(name), storm::exceptions::InvalidArgumentException, "Variable with name '" << name << "' already exists.");
164 return declareOrGetVariable(name, variableType, auxiliary);
165}
166
167Variable ExpressionManager::declareBooleanVariable(std::string const& name, bool auxiliary) {
168 Variable var = this->declareVariable(name, this->getBooleanType(), auxiliary);
169 return var;
170}
171
172Variable ExpressionManager::declareIntegerVariable(std::string const& name, bool auxiliary) {
173 return this->declareVariable(name, this->getIntegerType(), auxiliary);
174}
175
176Variable ExpressionManager::declareBitVectorVariable(std::string const& name, std::size_t width, bool auxiliary) {
177 return this->declareVariable(name, this->getBitVectorType(width), auxiliary);
178}
179
180Variable ExpressionManager::declareRationalVariable(std::string const& name, bool auxiliary) {
181 return this->declareVariable(name, this->getRationalType(), auxiliary);
182}
183
184Variable ExpressionManager::declareArrayVariable(std::string const& name, Type const& elementType, bool auxiliary) {
185 return this->declareVariable(name, this->getArrayType(elementType), auxiliary);
186}
187
188Variable ExpressionManager::declareOrGetVariable(std::string const& name, storm::expressions::Type const& variableType, bool auxiliary) {
189 return declareOrGetVariable(name, variableType, auxiliary, true);
190}
191
192Variable ExpressionManager::declareOrGetVariable(std::string const& name, storm::expressions::Type const& variableType, bool auxiliary, bool checkName) {
193 STORM_LOG_THROW(!checkName || isValidVariableName(name), storm::exceptions::InvalidArgumentException, "Invalid variable name '" << name << "'.");
194 auto nameIndexPair = nameToIndexMapping.find(name);
195 if (nameIndexPair != nameToIndexMapping.end()) {
196 STORM_LOG_ASSERT(indexToTypeMapping.at(nameIndexPair->second) == variableType, "Tried to declareOrGet variable '"
197 << name << "' of type '" << variableType
198 << "' but there is a variable with that name and different type '"
199 << indexToTypeMapping.at(nameIndexPair->second) << "'.");
200 return Variable(this->getSharedPointer(), nameIndexPair->second);
201 } else {
202 uint64_t offset = 0;
203
204 if (variableType.isBooleanType()) {
205 offset = numberOfBooleanVariables++;
206 } else if (variableType.isIntegerType()) {
207 offset = numberOfIntegerVariables++ + numberOfBitVectorVariables;
208 } else if (variableType.isBitVectorType()) {
209 offset = numberOfBitVectorVariables++ + numberOfIntegerVariables;
210 } else if (variableType.isRationalType()) {
211 offset = numberOfRationalVariables++;
212 } else if (variableType.isArrayType()) {
213 offset = numberOfArrayVariables++;
214 } else if (variableType.isStringType()) {
215 offset = numberOfStringVariables++;
216 } else {
217 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException,
218 "Trying to declare a variable of unsupported type: '" << variableType.getStringRepresentation() << "'.");
219 }
220
221 // Compute the index of the new variable.
222 uint64_t newIndex = offset | variableType.getMask() | (auxiliary ? auxiliaryMask : 0);
223
224 // Properly insert the variable into the data structure.
225 nameToIndexMapping[name] = newIndex;
226 indexToNameMapping[newIndex] = name;
227 indexToTypeMapping[newIndex] = variableType;
228 Variable result(this->getSharedPointer(), newIndex);
229 variableSet.insert(result);
230 return result;
231 }
232}
233
234Variable ExpressionManager::getVariable(std::string const& name) const {
235 auto nameIndexPair = nameToIndexMapping.find(name);
236 STORM_LOG_THROW(nameIndexPair != nameToIndexMapping.end(), storm::exceptions::InvalidArgumentException, "Unknown variable '" << name << "'.");
237 return Variable(this->getSharedPointer(), nameIndexPair->second);
238}
239
240std::set<Variable> const& ExpressionManager::getVariables() const {
241 return variableSet;
242}
243
245 return Expression(getVariable(name));
246}
247
248bool ExpressionManager::hasVariable(std::string const& name) const {
249 return nameToIndexMapping.find(name) != nameToIndexMapping.end();
250}
251
252Variable ExpressionManager::declareFreshVariable(storm::expressions::Type const& variableType, bool auxiliary, std::string const& prefix) {
253 std::string newName = prefix + std::to_string(freshVariableCounter++);
254 return declareOrGetVariable(newName, variableType, auxiliary, false);
255}
256
257Variable ExpressionManager::declareFreshBooleanVariable(bool auxiliary, const std::string& prefix) {
258 return declareFreshVariable(this->getBooleanType(), auxiliary, prefix);
259}
260
261Variable ExpressionManager::declareFreshIntegerVariable(bool auxiliary, const std::string& prefix) {
262 return declareFreshVariable(this->getIntegerType(), auxiliary, prefix);
263}
264
265Variable ExpressionManager::declareFreshRationalVariable(bool auxiliary, const std::string& prefix) {
266 return declareFreshVariable(this->getRationalType(), auxiliary, prefix);
267}
268
269uint_fast64_t ExpressionManager::getNumberOfVariables(storm::expressions::Type const& variableType) const {
270 if (variableType.isBooleanType()) {
271 return numberOfBooleanVariables;
272 } else if (variableType.isIntegerType()) {
273 return numberOfIntegerVariables;
274 } else if (variableType.isBitVectorType()) {
275 return numberOfBitVectorVariables;
276 } else if (variableType.isRationalType()) {
277 return numberOfRationalVariables;
278 } else if (variableType.isArrayType()) {
279 return numberOfArrayVariables;
280 } else if (variableType.isStringType()) {
281 return numberOfStringVariables;
282 }
283 return 0;
284}
285
287 return numberOfBooleanVariables + numberOfIntegerVariables + numberOfBitVectorVariables + numberOfRationalVariables + numberOfArrayVariables +
288 numberOfStringVariables;
289}
290
292 return numberOfBooleanVariables;
293}
294
296 return numberOfIntegerVariables;
297}
298
300 return numberOfBitVectorVariables;
301}
302
304 return numberOfRationalVariables;
305}
306
308 return numberOfRationalVariables;
309}
310
312 return numberOfStringVariables;
313}
314
315std::string const& ExpressionManager::getVariableName(uint_fast64_t index) const {
316 auto indexTypeNamePair = indexToNameMapping.find(index);
317 STORM_LOG_THROW(indexTypeNamePair != indexToNameMapping.end(), storm::exceptions::InvalidArgumentException, "Unknown variable index '" << index << "'.");
318 return indexTypeNamePair->second;
319}
320
321Type const& ExpressionManager::getVariableType(uint_fast64_t index) const {
322 auto indexTypePair = indexToTypeMapping.find(index);
323 STORM_LOG_ASSERT(indexTypePair != indexToTypeMapping.end(), "Unable to retrieve type of unknown variable index '" << index << "'.");
324 return indexTypePair->second;
325}
326
327uint64_t ExpressionManager::getOffset(uint64_t index) const {
328 return index & offsetMask;
329}
330
332 return ExpressionManager::const_iterator(*this, this->nameToIndexMapping.begin(), this->nameToIndexMapping.end(),
334}
335
337 return ExpressionManager::const_iterator(*this, this->nameToIndexMapping.end(), this->nameToIndexMapping.end(),
339}
340
341std::shared_ptr<ExpressionManager> ExpressionManager::getSharedPointer() {
342 return this->shared_from_this();
343}
344
345std::shared_ptr<ExpressionManager const> ExpressionManager::getSharedPointer() const {
346 return this->shared_from_this();
347}
348
349std::ostream& operator<<(std::ostream& out, ExpressionManager const& manager) {
350 out << "manager {\n";
351
352 for (auto const& variableTypePair : manager) {
353 out << "\t" << variableTypePair.second << " " << variableTypePair.first.getName() << " [offset " << variableTypePair.first.getOffset() << ", "
354 << variableTypePair.first.getIndex() << " ]\n";
355 }
356
357 out << "}\n";
358
359 return out;
360}
361
362} // namespace expressions
363} // namespace storm
This class is responsible for managing a set of typed variables and all expressions using these varia...
Variable declareFreshIntegerVariable(bool auxiliary=false, std::string const &prefix="_x")
Declares a variable with integer type whose name is guaranteed to be unique and not yet in use.
Type const & getTranscendentalNumberType() const
Retrieves the transcendental numbers type (i.e.
Type const & getBitVectorType(std::size_t width) const
Retrieves the bit vector type of the given width.
std::set< Variable > const & getVariables() const
Retrieves the set of all variables known to this manager.
Type const & getArrayType(Type elementType) const
Retrieves the array type with the given element type.
uint_fast64_t getNumberOfIntegerVariables() const
Retrieves the number of integer variables.
uint_fast64_t getNumberOfBooleanVariables() const
Retrieves the number of boolean variables.
Variable declareFreshBooleanVariable(bool auxiliary=false, std::string const &prefix="_x")
Declares a variable with Boolean type whose name is guaranteed to be unique and not yet in use.
Variable declareRationalVariable(std::string const &name, bool auxiliary=false)
Declares a new rational variable with a name that must not yet exist and its corresponding type.
uint_fast64_t getNumberOfArrayVariables() const
Retrieves the number of array variables.
uint_fast64_t getNumberOfStringVariables() const
Retrieves the number of string variables.
Variable declareBooleanVariable(std::string const &name, bool auxiliary=false)
Declares a new boolean variable with a name that must not yet exist and its corresponding type.
Expression integer(int_fast64_t value) const
Creates an expression that characterizes the given integer literal.
Type const & getVariableType(uint_fast64_t index) const
Retrieves the type of the variable with the given index.
bool hasVariable(std::string const &name) const
Retrieves whether a variable with the given name is known to the manager.
Variable declareOrGetVariable(std::string const &name, storm::expressions::Type const &variableType, bool auxiliary=false)
Declares a variable with the given name if it does not yet exist.
std::shared_ptr< ExpressionManager > clone() const
Creates a new expression manager with the same set of variables.
Type const & getBooleanType() const
Retrieves the boolean type.
const_iterator end() const
Retrieves an iterator that points beyond the last variable managed by this manager.
uint_fast64_t getOffset(uint_fast64_t index) const
Retrieves the offset of the variable with the given index within the group of equally typed variables...
const_iterator begin() const
Retrieves an iterator to all variables managed by this manager.
Variable declareVariable(std::string const &name, storm::expressions::Type const &variableType, bool auxiliary=false)
Declares a variable with a name that must not yet exist and its corresponding type.
ExpressionManager()
Creates a new manager that is unaware of any variables.
Type const & getIntegerType() const
Retrieves the unbounded integer type.
uint_fast64_t getNumberOfVariables() const
Retrieves the number of variables.
Variable declareFreshRationalVariable(bool auxiliary=false, std::string const &prefix="_x")
Declares a variable with rational type whose name is guaranteed to be unique and not yet in use.
Variable declareVariableCopy(Variable const &variable)
Declares a variable that is a copy of the provided variable (i.e.
Variable declareIntegerVariable(std::string const &name, bool auxiliary=false)
Declares a new integer variable with a name that must not yet exist and its corresponding type.
bool operator==(ExpressionManager const &other) const
Compares the two expression managers for equality, which holds iff they are the very same object.
uint_fast64_t getNumberOfRationalVariables() const
Retrieves the number of rational variables.
uint_fast64_t getNumberOfBitVectorVariables() const
Retrieves the number of bit vector variables.
Variable declareArrayVariable(std::string const &name, Type const &elementType, bool auxiliary=false)
Declares a new array variable with the given name and the given element type.
Expression getVariableExpression(std::string const &name) const
Retrieves an expression that represents the variable with the given name.
Expression rational(double value) const
Creates an expression that characterizes the given rational literal.
Type const & getStringType() const
Retrieves the string type.
Variable declareFreshVariable(storm::expressions::Type const &variableType, bool auxiliary=false, std::string const &prefix="_x")
Declares a variable with the given type whose name is guaranteed to be unique and not yet in use.
std::string const & getVariableName(uint_fast64_t index) const
Retrieves the name of the variable with the given index.
std::shared_ptr< ExpressionManager > getSharedPointer()
Retrieves a shared pointer to the expression manager.
Type const & getRationalType() const
Retrieves the rational type.
Variable declareBitVectorVariable(std::string const &name, std::size_t width, bool auxiliary=false)
Declares a new bit vector variable with a name that must not yet exist and the bounded type of the gi...
Variable getVariable(std::string const &name) const
Retrieves the expression that represents the variable with the given name.
Expression boolean(bool value) const
Creates an expression that characterizes the given boolean literal.
bool isBooleanType() const
Checks whether this type is a boolean type.
Definition Type.cpp:194
bool isStringType() const
Checks whether this type is a string type.
Definition Type.cpp:218
bool isIntegerType() const
Checks whether this type is an integral type.
Definition Type.cpp:198
bool isArrayType() const
Checks whether this type is an array type.
Definition Type.cpp:210
std::string getStringRepresentation() const
Retrieves a string representation of the type.
Definition Type.cpp:222
uint64_t getMask() const
Retrieves the bit mask of the type.
Definition Type.cpp:190
bool isRationalType() const
Checks whether this type is a rational type.
Definition Type.cpp:234
bool isBitVectorType() const
Checks whether this type is a bitvector type.
Definition Type.cpp:202
Type const & getType() const
Retrieves the type of the variable.
Definition Variable.cpp:50
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
bool operator==(VariableIterator const &other) const
VariableIterator(ExpressionManager const &manager, std::unordered_map< std::string, uint_fast64_t >::const_iterator nameIndexIterator, std::unordered_map< std::string, uint_fast64_t >::const_iterator nameIndexIteratorEnd, VariableSelection const &selection)
bool operator!=(VariableIterator const &other) const
std::pair< storm::expressions::Variable, storm::expressions::Type > const value_type
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::ostream & operator<<(std::ostream &stream, BaseExpression const &expression)