Storm 1.14.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::declareStringVariable(std::string const& name, bool auxiliary) {
189 return this->declareVariable(name, this->getStringType(), auxiliary);
190}
191
192Variable ExpressionManager::declareOrGetVariable(std::string const& name, storm::expressions::Type const& variableType, bool auxiliary) {
193 return declareOrGetVariable(name, variableType, auxiliary, true);
194}
195
196Variable ExpressionManager::declareOrGetVariable(std::string const& name, storm::expressions::Type const& variableType, bool auxiliary, bool checkName) {
197 STORM_LOG_THROW(!checkName || isValidVariableName(name), storm::exceptions::InvalidArgumentException, "Invalid variable name '" << name << "'.");
198 auto nameIndexPair = nameToIndexMapping.find(name);
199 if (nameIndexPair != nameToIndexMapping.end()) {
200 STORM_LOG_ASSERT(indexToTypeMapping.at(nameIndexPair->second) == variableType, "Tried to declareOrGet variable '"
201 << name << "' of type '" << variableType
202 << "' but there is a variable with that name and different type '"
203 << indexToTypeMapping.at(nameIndexPair->second) << "'.");
204 return Variable(this->getSharedPointer(), nameIndexPair->second);
205 } else {
206 uint64_t offset = 0;
207
208 if (variableType.isBooleanType()) {
209 offset = numberOfBooleanVariables++;
210 } else if (variableType.isIntegerType()) {
211 offset = numberOfIntegerVariables++ + numberOfBitVectorVariables;
212 } else if (variableType.isBitVectorType()) {
213 offset = numberOfBitVectorVariables++ + numberOfIntegerVariables;
214 } else if (variableType.isRationalType()) {
215 offset = numberOfRationalVariables++;
216 } else if (variableType.isArrayType()) {
217 offset = numberOfArrayVariables++;
218 } else if (variableType.isStringType()) {
219 offset = numberOfStringVariables++;
220 } else {
221 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException,
222 "Trying to declare a variable of unsupported type: '" << variableType.getStringRepresentation() << "'.");
223 }
224
225 // Compute the index of the new variable.
226 uint64_t newIndex = offset | variableType.getMask() | (auxiliary ? auxiliaryMask : 0);
227
228 // Properly insert the variable into the data structure.
229 nameToIndexMapping[name] = newIndex;
230 indexToNameMapping[newIndex] = name;
231 indexToTypeMapping[newIndex] = variableType;
232 Variable result(this->getSharedPointer(), newIndex);
233 variableSet.insert(result);
234 return result;
235 }
236}
237
238Variable ExpressionManager::getVariable(std::string const& name) const {
239 auto nameIndexPair = nameToIndexMapping.find(name);
240 STORM_LOG_THROW(nameIndexPair != nameToIndexMapping.end(), storm::exceptions::InvalidArgumentException, "Unknown variable '" << name << "'.");
241 return Variable(this->getSharedPointer(), nameIndexPair->second);
242}
243
244std::set<Variable> const& ExpressionManager::getVariables() const {
245 return variableSet;
246}
247
249 return Expression(getVariable(name));
250}
251
252bool ExpressionManager::hasVariable(std::string const& name) const {
253 return nameToIndexMapping.find(name) != nameToIndexMapping.end();
254}
255
256Variable ExpressionManager::declareFreshVariable(storm::expressions::Type const& variableType, bool auxiliary, std::string const& prefix) {
257 std::string newName = prefix + std::to_string(freshVariableCounter++);
258 return declareOrGetVariable(newName, variableType, auxiliary, false);
259}
260
261Variable ExpressionManager::declareFreshBooleanVariable(bool auxiliary, const std::string& prefix) {
262 return declareFreshVariable(this->getBooleanType(), auxiliary, prefix);
263}
264
265Variable ExpressionManager::declareFreshIntegerVariable(bool auxiliary, const std::string& prefix) {
266 return declareFreshVariable(this->getIntegerType(), auxiliary, prefix);
267}
268
269Variable ExpressionManager::declareFreshRationalVariable(bool auxiliary, const std::string& prefix) {
270 return declareFreshVariable(this->getRationalType(), auxiliary, prefix);
271}
272
273uint_fast64_t ExpressionManager::getNumberOfVariables(storm::expressions::Type const& variableType) const {
274 if (variableType.isBooleanType()) {
275 return numberOfBooleanVariables;
276 } else if (variableType.isIntegerType()) {
277 return numberOfIntegerVariables;
278 } else if (variableType.isBitVectorType()) {
279 return numberOfBitVectorVariables;
280 } else if (variableType.isRationalType()) {
281 return numberOfRationalVariables;
282 } else if (variableType.isArrayType()) {
283 return numberOfArrayVariables;
284 } else if (variableType.isStringType()) {
285 return numberOfStringVariables;
286 }
287 return 0;
288}
289
291 return numberOfBooleanVariables + numberOfIntegerVariables + numberOfBitVectorVariables + numberOfRationalVariables + numberOfArrayVariables +
292 numberOfStringVariables;
293}
294
296 return numberOfBooleanVariables;
297}
298
300 return numberOfIntegerVariables;
301}
302
304 return numberOfBitVectorVariables;
305}
306
308 return numberOfRationalVariables;
309}
310
312 return numberOfRationalVariables;
313}
314
316 return numberOfStringVariables;
317}
318
319std::string const& ExpressionManager::getVariableName(uint_fast64_t index) const {
320 auto indexTypeNamePair = indexToNameMapping.find(index);
321 STORM_LOG_THROW(indexTypeNamePair != indexToNameMapping.end(), storm::exceptions::InvalidArgumentException, "Unknown variable index '" << index << "'.");
322 return indexTypeNamePair->second;
323}
324
325Type const& ExpressionManager::getVariableType(uint_fast64_t index) const {
326 auto indexTypePair = indexToTypeMapping.find(index);
327 STORM_LOG_ASSERT(indexTypePair != indexToTypeMapping.end(), "Unable to retrieve type of unknown variable index '" << index << "'.");
328 return indexTypePair->second;
329}
330
331uint64_t ExpressionManager::getOffset(uint64_t index) const {
332 return index & offsetMask;
333}
334
336 return ExpressionManager::const_iterator(*this, this->nameToIndexMapping.begin(), this->nameToIndexMapping.end(),
338}
339
341 return ExpressionManager::const_iterator(*this, this->nameToIndexMapping.end(), this->nameToIndexMapping.end(),
343}
344
345std::shared_ptr<ExpressionManager> ExpressionManager::getSharedPointer() {
346 return this->shared_from_this();
347}
348
349std::shared_ptr<ExpressionManager const> ExpressionManager::getSharedPointer() const {
350 return this->shared_from_this();
351}
352
353std::ostream& operator<<(std::ostream& out, ExpressionManager const& manager) {
354 out << "manager {\n";
355
356 for (auto const& variableTypePair : manager) {
357 out << "\t" << variableTypePair.second << " " << variableTypePair.first.getName() << " [offset " << variableTypePair.first.getOffset() << ", "
358 << variableTypePair.first.getIndex() << " ]\n";
359 }
360
361 out << "}\n";
362
363 return out;
364}
365
366} // namespace expressions
367} // 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.
Variable declareStringVariable(std::string const &name, bool auxiliary=false)
Declares a new string variable with the given name.
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:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
std::ostream & operator<<(std::ostream &stream, BaseExpression const &expression)