TimQu
6 years ago
16 changed files with 666 additions and 112 deletions
-
33src/storm/storage/expressions/ExpressionManager.cpp
-
18src/storm/storage/expressions/ExpressionManager.h
-
41src/storm/storage/expressions/Type.cpp
-
245src/storm/storage/expressions/Type.h
-
36src/storm/storage/jani/expressions/ArrayAccessExpression.cpp
-
33src/storm/storage/jani/expressions/ArrayAccessExpression.h
-
11src/storm/storage/jani/expressions/ArrayExpression.cpp
-
33src/storm/storage/jani/expressions/ArrayExpression.h
-
72src/storm/storage/jani/expressions/ConstructorArrayExpression.cpp
-
46src/storm/storage/jani/expressions/ConstructorArrayExpression.h
-
51src/storm/storage/jani/expressions/JaniExpressionSubstitutionVisitor.cpp
-
26src/storm/storage/jani/expressions/JaniExpressionSubstitutionVisitor.h
-
19src/storm/storage/jani/expressions/JaniExpressionVisitor.h
-
4src/storm/storage/jani/expressions/JaniExpressions.h
-
68src/storm/storage/jani/expressions/ValueArrayExpression.cpp
-
42src/storm/storage/jani/expressions/ValueArrayExpression.h
@ -0,0 +1,36 @@ |
|||
#include "storm/storage/jani/expressions/ArrayAccessExpression.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
ArrayAccessExpression::ArrayAccessExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& arrayExpression, std::shared_ptr<BaseExpression const> const& indexExpression) : BinaryExpression(manager, type, arrayExpression, indexExpression) { |
|||
// Assert correct types
|
|||
STORM_LOG_ASSERT(getFirstOperand()->getType().isArrayType(), "ArrayAccessExpression for an expression of type " << getFirstOperand()->getType() << "."); |
|||
STORM_LOG_ASSERT(type == getFirstOperand()->getType().getElementType(), "The ArrayAccessExpression should have type " << getFirstOperand()->getType().getElementType() << " but has " << type << " instead."); |
|||
STORM_LOG_ASSERT(getSecondOperand()->getType().isIntegerType(), "The index expression does not have an integer type."); |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ArrayAccessExpression::simplify() const { |
|||
return std::shared_ptr<BaseExpression const>(new ArrayAccessExpression(manager, type, getFirstOperand()->simplify(), getSecondOperand()->simplify())); |
|||
} |
|||
|
|||
boost::any ArrayAccessExpression::accept(ExpressionVisitor& visitor, boost::any const& data) const { |
|||
auto janiVisitor = dynamic_cast<JaniExpressionVisitor*>(&visitor); |
|||
STORM_LOG_THROW(janiVisitor != nullptr, storm::exceptions::UnexpectedException, "Visitor of jani expression should be of type JaniVisitor."); |
|||
return janiVisitor->visit(*this, data); |
|||
} |
|||
|
|||
void ArrayAccessExpression::printToStream(std::ostream& stream) const { |
|||
if (firstOperand->isVariable()) { |
|||
getFirstOperand()->printToStream(stream); |
|||
} else { |
|||
stream << "("; |
|||
getFirstOperand()->printToStream(stream); |
|||
stream << ")"; |
|||
} |
|||
stream << "["; |
|||
getSecondOperand()->printToStream(stream); |
|||
stream << "]"; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/expressions/BaseExpression.h" |
|||
#include "storm/storage/jani/expressions/ExpressionManager.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
/*! |
|||
* Represents an access to an array. |
|||
*/ |
|||
class ArrayAccessExpression : public BinaryExpression { |
|||
public: |
|||
|
|||
ArrayAccessExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& arrayExpression, std::shared_ptr<BaseExpression const> const& indexExpression); |
|||
|
|||
// Instantiate constructors and assignments with their default implementations. |
|||
ArrayAccessExpression(ArrayAccessExpression const& other) = default; |
|||
ArrayAccessExpression& operator=(ArrayAccessExpression const& other) = delete; |
|||
ArrayAccessExpression(ArrayAccessExpression&&) = default; |
|||
ArrayAccessExpression& operator=(ArrayAccessExpression&&) = delete; |
|||
|
|||
virtual ~ArrayAccessExpression() = default; |
|||
|
|||
virtual std::shared_ptr<BaseExpression const> simplify() const override; |
|||
virtual boost::any accept(ExpressionVisitor& visitor, boost::any const& data) const override; |
|||
|
|||
protected: |
|||
virtual void printToStream(std::ostream& stream) const override; |
|||
|
|||
|
|||
}; |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
#include "storm/storage/jani/expressions/ArrayExpression.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
ArrayExpression::ArrayExpression(ExpressionManager const& manager, Type const& type) : BaseExpression(manager, type) { |
|||
// Intentionally left empty
|
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/expressions/BaseExpression.h" |
|||
#include "storm/storage/jani/expressions/ExpressionManager.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
/*! |
|||
* The base class of all array expressions. |
|||
*/ |
|||
class ArrayExpression : public BaseExpression { |
|||
public: |
|||
|
|||
ArrayExpression(ExpressionManager const& manager, Type const& type); |
|||
|
|||
// Instantiate constructors and assignments with their default implementations. |
|||
ArrayExpression(ArrayExpression const& other) = default; |
|||
ArrayExpression& operator=(ArrayExpression const& other) = delete; |
|||
ArrayExpression(ArrayExpression&&) = default; |
|||
ArrayExpression& operator=(ArrayExpression&&) = delete; |
|||
|
|||
virtual ~ArrayExpression() = default; |
|||
|
|||
// Returns the size of the array |
|||
virtual std::shared_ptr<BaseExpression const> size() const = 0; |
|||
|
|||
// Returns the element at position i |
|||
virtual std::shared_ptr<BaseExpression const> at(uint64_t i) const = 0; |
|||
|
|||
|
|||
}; |
|||
} |
|||
} |
@ -0,0 +1,72 @@ |
|||
#include "storm/storage/jani/expressions/ConstructorArrayExpression.h"
|
|||
|
|||
#include "storm/storage/jani/expressions/JaniExpressionVisitor.h"
|
|||
|
|||
#include "storm/exceptions/InvalidArgumentException.h"
|
|||
#include "storm/exceptions/UnexpectedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
ConstructorArrayExpression::ConstructorArrayExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& size, storm::expressions::Variable indexVar, std::shared_ptr<BaseExpression const> const& elementExpression) : ArrayExpression(manager, type), size(size), indexVar(indexVar), elementExpression(elementExpression) { |
|||
// Intentionally left empty
|
|||
} |
|||
|
|||
void ConstructorArrayExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const { |
|||
// The indexVar should not be gathered (unless it is already contained).
|
|||
bool indexVarContained = variables.find(indexVar) != variables.end(); |
|||
size->gatherVariables(variables); |
|||
elementExpression->gatherVariables(variables); |
|||
if (!indexVarContained) { |
|||
variables.erase(indexVar); |
|||
} |
|||
} |
|||
|
|||
bool ConstructorArrayExpression::containsVariables() const { |
|||
if (size->containsVariables()) { |
|||
return true; |
|||
} |
|||
// The index variable should not count
|
|||
std::set<storm::expressions::Variable> variables; |
|||
elementExpression->gatherVariables(variables); |
|||
variables.erase(indexVar); |
|||
return !variables.empty(); |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ConstructorArrayExpression::simplify() const { |
|||
return std::shared_ptr<BaseExpression const>(new ConstructorArrayExpression(manager, type, size->simplify(), indexVar, elementExpression->simplify())); |
|||
} |
|||
|
|||
boost::any ConstructorArrayExpression::accept(ExpressionVisitor& visitor, boost::any const& data) const { |
|||
auto janiVisitor = dynamic_cast<JaniExpressionVisitor*>(&visitor); |
|||
STORM_LOG_THROW(janiVisitor != nullptr, storm::exceptions::UnexpectedException, "Visitor of jani expression should be of type JaniVisitor."); |
|||
return janiVisitor->visit(*this, data); |
|||
} |
|||
|
|||
void ConstructorArrayExpression::printToStream(std::ostream& stream) const { |
|||
stream << "array[ "; |
|||
elementExpression->printToStream(stream); |
|||
stream << " | " << indexVar << "<"; |
|||
size->printToStream(stream); |
|||
stream << " ]"; |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ConstructorArrayExpression::size() const { |
|||
return size; |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ConstructorArrayExpression::at(uint64_t i) const { |
|||
STORM_LOG_THROW(i < elements.size(), storm::exceptions::InvalidArgumentException, "Tried to access the element with index " << i << " of an array of size " << elements.size() << "."); |
|||
return elements[i]; |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> const& ConstructorArrayExpression::getElementExpression() const { |
|||
return elementExpression; |
|||
} |
|||
|
|||
storm::expressions::Variable const& ConstructorArrayExpression::getIndexVar() const { |
|||
return indexVar; |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/jani/expressions/ArrayExpression.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
/*! |
|||
* Represents an array of the given size, where the i'th entry is determined by the elementExpression, where occurrences of indexVar will be substituted by i |
|||
*/ |
|||
class ConstructorArrayExpression : public ArrayExpression { |
|||
public: |
|||
|
|||
ConstructorArrayExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& size, storm::expressions::Variable indexVar, std::shared_ptr<BaseExpression const> const& elementExpression); |
|||
|
|||
|
|||
// Instantiate constructors and assignments with their default implementations. |
|||
ConstructorArrayExpression(ConstructorArrayExpression const& other) = default; |
|||
ConstructorArrayExpression& operator=(ConstructorArrayExpression const& other) = delete; |
|||
ConstructorArrayExpression(ConstructorArrayExpression&&) = default; |
|||
ConstructorArrayExpression& operator=(ConstructorArrayExpression&&) = delete; |
|||
|
|||
virtual ~ConstructorArrayExpression() = default; |
|||
|
|||
virtual void gatherVariables(std::set<storm::expressions::Variable>& variables) const override; |
|||
virtual bool containsVariables() const; |
|||
virtual std::shared_ptr<BaseExpression const> simplify() const override; |
|||
virtual boost::any accept(ExpressionVisitor& visitor, boost::any const& data) const override; |
|||
|
|||
// Returns the size of the array |
|||
virtual std::shared_ptr<BaseExpression const> size() const override; |
|||
|
|||
// Returns the element at position i |
|||
virtual std::shared_ptr<BaseExpression const> at(uint64_t i) const override; |
|||
|
|||
std::shared_ptr<BaseExpression const> const& getElementExpression() const; |
|||
storm::expressions::Variable const& getIndexVar() const; |
|||
protected: |
|||
virtual void printToStream(std::ostream& stream) const override; |
|||
|
|||
private: |
|||
std::shared_ptr<BaseExpression const> size; |
|||
storm::expressions::Variable indexVar; |
|||
std::shared_ptr<BaseExpression const> const& elementExpression; |
|||
}; |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
#include "storm/storage/jani/expressions/JaniExpressionSubstitutionVisitor.h"
|
|||
|
|||
#include "storm/exceptions/InvalidArgumentException.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
template<typename MapType> |
|||
boost::any JaniExpressionSubstitutionVisitor<MapType>::visit(ValueArrayExpression const& expression, boost::any const& data) { |
|||
uint64_t size = expression.getSize()->evaluateAsInt(); |
|||
std::vector<std::shared_ptr<BaseExpression const>> newElements; |
|||
newElements.reserve(size); |
|||
for (uint64_t i = 0; i < size; ++i) { |
|||
newElements.push_back(boost::any_cast<std::shared_ptr<BaseExpression const>>(expression.at(i)->accept(*this, data))); |
|||
} |
|||
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>(new ValueArrayExpression(expression.getManager(), expression.getType(), newElements))); |
|||
} |
|||
|
|||
template<typename MapType> |
|||
boost::any JaniExpressionSubstitutionVisitor<MapType>::visit(ConstructorArrayExpression const& expression, boost::any const& data) { |
|||
std::shared_ptr<BaseExpression const> newSize = boost::any_cast<std::shared_ptr<BaseExpression const>>(expression.getSize()->accept(*this, data)); |
|||
std::shared_ptr<BaseExpression const> elementExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>(expression.getElementExpression()->accept(*this, data)); |
|||
STORM_LOG_THROW(this->variableToExpressionMapping.find(expression.getIndexVar()) == this->variableToExpressionMapping.end(), storm::exceptions::InvalidArgumentException, "substitution of the index variable of a constructorArrayExpression is not possible."); |
|||
|
|||
// If the arguments did not change, we simply push the expression itself.
|
|||
if (newSize.get() == expression.getSize().get() && elementExpression.get() == expression.getElementExpression().get()) { |
|||
return expression.getSharedPointer(); |
|||
} else { |
|||
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>(new ConstructorArrayExpression(expression.getManager(), expression.getType(), newSize, expression.getIndexVar(), elementExpression))); |
|||
} |
|||
} |
|||
|
|||
template<typename MapType> |
|||
boost::any JaniExpressionSubstitutionVisitor<MapType>::visit(ArrayAccessExpression const& expression, boost::any const& data) { |
|||
std::shared_ptr<BaseExpression const> firstExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>(expression.getFirstOperand()->accept(*this, data)); |
|||
std::shared_ptr<BaseExpression const> secondExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>(expression.getSecondOperand()->accept(*this, data)); |
|||
|
|||
// If the arguments did not change, we simply push the expression itself.
|
|||
if (firstExpression.get() == expression.getFirstOperand().get() && secondExpression.get() == expression.getSecondOperand().get()) { |
|||
return expression.getSharedPointer(); |
|||
} else { |
|||
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>(new ArrayAccessExpression(expression.getManager(), expression.getType(), firstExpression, secondExpression))); |
|||
} |
|||
} |
|||
|
|||
|
|||
// Explicitly instantiate the class with map and unordered_map.
|
|||
template class JaniExpressionSubstitutionVisitor<std::map<Variable, Expression>>; |
|||
template class JaniExpressionSubstitutionVisitor<std::unordered_map<Variable, Expression>>; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/expressions/SubstitutionVisitor.h" |
|||
#include "storm/storage/jani/expressions/JaniExpressions.h" |
|||
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
template<typename MapType> |
|||
class JaniExpressionSubstitutionVisitor : public SubstitutionVisitor<MapType>, public ExpressionManager { |
|||
public: |
|||
/*! |
|||
* Creates a new substitution visitor that uses the given map to replace variables. |
|||
* |
|||
* @param variableToExpressionMapping A mapping from variables to expressions. |
|||
*/ |
|||
JaniExpressionSubstitutionVisitor(MapType const& variableToExpressionMapping); |
|||
|
|||
virtual boost::any visit(ValueArrayExpression const& expression, boost::any const& data) override; |
|||
virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) override; |
|||
virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) override; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ */ |
@ -0,0 +1,19 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/expressions/SubstitutionVisitor.h" |
|||
#include "storm/storage/jani/expressions/JaniExpressions.h" |
|||
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
template<typename MapType> |
|||
class JaniExpressionVisitor{ |
|||
public: |
|||
virtual boost::any visit(ValueArrayExpression const& expression, boost::any const& data) = 0; |
|||
virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) = 0; |
|||
virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) = 0; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ */ |
@ -0,0 +1,4 @@ |
|||
#include "storm/storage/expressions/Expressions.h" |
|||
#include "storm/storage/jani/expressions/ArrayAccessExpression.h" |
|||
#include "storm/storage/jani/expressions/ConstructorArrayExpression.h" |
|||
#include "storm/storage/jani/expressions/ValueArrayExpression.h" |
@ -0,0 +1,68 @@ |
|||
#include "storm/storage/jani/expressions/ValueArrayExpression.h"
|
|||
|
|||
#include "storm/storage/jani/expressions/JaniExpressionVisitor.h"
|
|||
|
|||
#include "storm/exceptions/InvalidArgumentException.h"
|
|||
#include "storm/exceptions/UnexpectedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
ValueArrayExpression::ValueArrayExpression(ExpressionManager const& manager, Type const& type, std::vector<std::shared_ptr<BaseExpression const>> const& elements) : ArrayExpression(manager, type), elements(elements) { |
|||
// Intentionally left empty
|
|||
} |
|||
|
|||
void ValueArrayExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const { |
|||
for (auto const& e : elements) { |
|||
e->gatherVariables(variables); |
|||
} |
|||
} |
|||
|
|||
bool ValueArrayExpression::containsVariables() const { |
|||
for (auto const& e : elements) { |
|||
if (e->containsVariables()) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ValueArrayExpression::simplify() const { |
|||
std::vector<std::shared_ptr<BaseExpression const>> simplifiedElements; |
|||
simplifiedElements.reserve(elements.size()); |
|||
for (auto const& e : elements) { |
|||
simplifiedElements.push_back(e->simplify()); |
|||
} |
|||
return std::shared_ptr<BaseExpression const>(new ValueArrayExpression(manager, type, simplifiedElements)); |
|||
} |
|||
|
|||
boost::any ValueArrayExpression::accept(ExpressionVisitor& visitor, boost::any const& data) const { |
|||
auto janiVisitor = dynamic_cast<JaniExpressionVisitor*>(&visitor); |
|||
STORM_LOG_THROW(janiVisitor != nullptr, storm::exceptions::UnexpectedException, "Visitor of jani expression should be of type JaniVisitor."); |
|||
return janiVisitor->visit(*this, data); |
|||
} |
|||
|
|||
void ValueArrayExpression::printToStream(std::ostream& stream) const { |
|||
stream << "array[ "; |
|||
bool first = true; |
|||
for (auto const& e : elements) { |
|||
e->printToStream(stream); |
|||
if (!first) { |
|||
stream << " , "; |
|||
} |
|||
first = false; |
|||
} |
|||
stream << " ]"; |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ValueArrayExpression::size() const { |
|||
return this->manager.integer(elements.size()).getBaseExpressionPointer(); |
|||
} |
|||
|
|||
std::shared_ptr<BaseExpression const> ValueArrayExpression::at(uint64_t i) const { |
|||
STORM_LOG_THROW(i < elements.size(), storm::exceptions::InvalidArgumentException, "Tried to access the element with index " << i << " of an array of size " << elements.size() << "."); |
|||
return elements[i]; |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
#pragma once |
|||
|
|||
#include "storm/storage/jani/expressions/ArrayExpression.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
/*! |
|||
* Represents an array with a given list of elements. |
|||
*/ |
|||
class ValueArrayExpression : public ArrayExpression { |
|||
public: |
|||
|
|||
ValueArrayExpression(ExpressionManager const& manager, Type const& type, std::vector<std::shared_ptr<BaseExpression const>> elements); |
|||
|
|||
|
|||
// Instantiate constructors and assignments with their default implementations. |
|||
ValueArrayExpression(ValueArrayExpression const& other) = default; |
|||
ValueArrayExpression& operator=(ValueArrayExpression const& other) = delete; |
|||
ValueArrayExpression(ValueArrayExpression&&) = default; |
|||
ValueArrayExpression& operator=(ValueArrayExpression&&) = delete; |
|||
|
|||
virtual ~ValueArrayExpression() = default; |
|||
|
|||
virtual void gatherVariables(std::set<storm::expressions::Variable>& variables) const override; |
|||
virtual bool containsVariables() const; |
|||
virtual std::shared_ptr<BaseExpression const> simplify() const override; |
|||
virtual boost::any accept(ExpressionVisitor& visitor, boost::any const& data) const override; |
|||
|
|||
// Returns the size of the array |
|||
virtual std::shared_ptr<BaseExpression const> size() const override; |
|||
|
|||
// Returns the element at position i |
|||
virtual std::shared_ptr<BaseExpression const> at(uint64_t i) const override; |
|||
|
|||
protected: |
|||
virtual void printToStream(std::ostream& stream) const override; |
|||
|
|||
private: |
|||
std::vector<std::shared_ptr<BaseExpression const>> elements; |
|||
}; |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue