diff --git a/src/exceptions/ExceptionMacros.h b/src/exceptions/ExceptionMacros.h new file mode 100644 index 000000000..dabfe25cb --- /dev/null +++ b/src/exceptions/ExceptionMacros.h @@ -0,0 +1,31 @@ +#ifndef STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ +#define STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ + +#include + +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" + +extern log4cplus::Logger logger; + +#ifndef NDEBUG +#define LOG_ASSERT(cond, message) \ +{ \ + if (!(cond)) { \ + LOG4CPLUS_ERROR(logger, message); \ + assert(cond); \ + } \ +} while (false) +#define LOG_THROW(cond, exception, message) \ +{ \ + if (!(cond)) { \ + LOG4CPLUS_ERROR(logger, message); \ + throw exception() << message; \ + } \ +} while (false) +#else +#define LOG_ASSERT(cond, message) /* empty */ +#define LOG_THROW(cond, exception, message) /* empty */ +#endif + +#endif /* STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp new file mode 100644 index 000000000..8a80a3b71 --- /dev/null +++ b/src/storage/expressions/BaseExpression.cpp @@ -0,0 +1,23 @@ +#include "src/storage/expressions/BaseExpression.h" + +namespace storm { + namespace expressions { + BaseExpression::BaseExpression() : returnType(undefined) { + // Intentionally left empty. + } + + BaseExpression::BaseExpression(ExpressionReturnType returnType) : returnType(returnType) { + // Intentionally left empty. + } + + ExpressionReturnType BaseExpression::getReturnType() const { + return this->returnType; + } + + void BaseExpression::checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const { + if (actualType != expectedType) { + throw storm::exceptions::InvalidArgumentException() << errorMessage; + } + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h index 54102464e..0412e11f8 100644 --- a/src/storage/expressions/BaseExpression.h +++ b/src/storage/expressions/BaseExpression.h @@ -3,25 +3,56 @@ #include "src/storage/expressions/Valuation.h" #include "src/storage/expressions/ExpressionVisitor.h" +#include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace expressions { + /*! + * Each node in an expression tree has a uniquely defined type from this enum. + */ + enum ExpressionReturnType {undefined, bool_, int_, double_}; + class BaseExpression { public: - /*! - * Each node in an expression tree has a uniquely defined type from this enum. - */ - enum ReturnType {undefined, bool_, int_, double_}; - virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0; + BaseExpression(); + BaseExpression(ExpressionReturnType returnType); + virtual ~BaseExpression() = default; - virtual bool evaluateAsBool(Valuation const& evaluation) const = 0; + ExpressionReturnType getReturnType() const; + virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0; + virtual bool evaluateAsBool(Valuation const& evaluation) const = 0; virtual double evaluateAsDouble(Valuation const& evaluation) const = 0; virtual std::unique_ptr operator+(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator-(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator-() const = 0; + virtual std::unique_ptr operator*(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator/(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator&(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator|(BaseExpression const& other) const = 0; + virtual std::unique_ptr operator~() const = 0; + virtual std::unique_ptr equals(BaseExpression const& other) const = 0; + virtual std::unique_ptr notEquals(BaseExpression const& other) const = 0; + virtual std::unique_ptr greater(BaseExpression const& other) const = 0; + virtual std::unique_ptr greaterOrEqual(BaseExpression const& other) const = 0; + virtual std::unique_ptr less(BaseExpression const& other) const = 0; + virtual std::unique_ptr lessOrEqual(BaseExpression const& other) const = 0; + virtual std::unique_ptr minimum(BaseExpression const& other) const = 0; + virtual std::unique_ptr maximum(BaseExpression const& other) const = 0; + virtual std::unique_ptr mod(BaseExpression const& other) const = 0; + virtual std::unique_ptr floor() const = 0; + virtual std::unique_ptr ceil() const = 0; + virtual void visit(ExpressionVisitor* visitor) const = 0; + + protected: + void checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const; + + private: + ExpressionReturnType returnType; }; } } diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp index 7ca4e23bf..c73108336 100644 --- a/src/storage/expressions/Expression.cpp +++ b/src/storage/expressions/Expression.cpp @@ -2,6 +2,7 @@ #include #include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/SubstitutionVisitor.h" namespace storm { namespace expressions { @@ -12,7 +13,7 @@ namespace storm { template class MapType> Expression Expression::substitute(MapType const& identifierToExpressionMap) const { SubstitutionVisitor visitor; - return visitor.substitute(this->getBaseExpression(), identifierToExpressionMap); + return visitor.substitute(this->getBaseExpressionPointer(), identifierToExpressionMap); } Expression Expression::operator+(Expression const& other) { @@ -23,6 +24,10 @@ namespace storm { return *this->expressionPtr; } + BaseExpression const* Expression::getBaseExpressionPointer() const { + return this->expressionPtr.get(); + } + template Expression Expression::substitute(std::map const&) const; template Expression Expression::substitute(std::unordered_map const&) const; } diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h index a780a0819..9b2fe78c1 100644 --- a/src/storage/expressions/Expression.h +++ b/src/storage/expressions/Expression.h @@ -8,6 +8,7 @@ namespace storm { namespace expressions { class Expression { + public: Expression() = default; // Static factory methods to create atomic expression parts. @@ -43,6 +44,13 @@ namespace storm { */ BaseExpression const& getBaseExpression() const; + /*! + * Retrieves a pointer to the base expression underlying this expression object. + * + * @return A pointer to the underlying base expression. + */ + BaseExpression const* getBaseExpressionPointer() const; + // A pointer to the underlying base expression. std::unique_ptr expressionPtr; }; diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp new file mode 100644 index 000000000..8c478d682 --- /dev/null +++ b/src/storage/expressions/SubstitutionVisitor.cpp @@ -0,0 +1,17 @@ +#include +#include + +#include "src/storage/expressions/SubstitutionVisitor.h" + +namespace storm { + namespace expressions { + template class MapType> + Expression SubstitutionVisitor::substitute(BaseExpression const* expression, MapType const& identifierToExpressionMap) { + return Expression(); + } + + // Explicitly instantiate substitute with map and unordered_map. + template Expression SubstitutionVisitor::substitute(BaseExpression const* expression, std::map const& identifierToExpressionMap); + template Expression SubstitutionVisitor::substitute(BaseExpression const* expression, std::unordered_map const& identifierToExpressionMap); + } +} diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h index 217b07b23..f65482e3c 100644 --- a/src/storage/expressions/SubstitutionVisitor.h +++ b/src/storage/expressions/SubstitutionVisitor.h @@ -1,7 +1,7 @@ #ifndef STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ #define STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ -#include "src/storage/expressions/BaseExpression.h" +#include "src/storage/expressions/Expression.h" #include "src/storage/expressions/ExpressionVisitor.h" namespace storm { @@ -10,6 +10,8 @@ namespace storm { public: template class MapType> Expression substitute(BaseExpression const* expression, MapType const& identifierToExpressionMap); + + }; } } diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp new file mode 100644 index 000000000..bce5ec0dc --- /dev/null +++ b/src/storage/expressions/VariableExpression.cpp @@ -0,0 +1,56 @@ +#include "src/storage/expressions/VariableExpression.h" +#include "src/exceptions/ExceptionMacros.h" + +namespace storm { + namespace expressions { + VariableExpression::VariableExpression(ExpressionReturnType returnType, std::string const& variableName) : BaseExpression(returnType), variableName(variableName) { + // Intentionally left empty. + } + + std::string const& VariableExpression::getVariableName() const { + return this->variableName; + } + + int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const { + LOG_ASSERT((this->getReturnType() == ExpressionReturnType::int_), "Cannot evaluate expression as integer: return type is not an integer."); + return evaluation.getIntegerValue(this->getVariableName()); + } + + bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const { + LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not an integer."); + return evaluation.getBooleanValue(this->getVariableName()); + } + + double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const { + LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not an integer."); + return evaluation.getDoubleValue(this->getVariableName()); + } + + std::unique_ptr VariableExpression::operator+(BaseExpression const& other) const { + // FIXME + return nullptr; + } + + std::unique_ptr operator-(BaseExpression const& other) const; + std::unique_ptr operator-() const; + std::unique_ptr operator*(BaseExpression const& other) const; + std::unique_ptr operator/(BaseExpression const& other) const; + std::unique_ptr operator&(BaseExpression const& other) const; + std::unique_ptr operator|(BaseExpression const& other) const; + std::unique_ptr operator~() const; + + std::unique_ptr equals(BaseExpression const& other) const; + std::unique_ptr notEquals(BaseExpression const& other) const; + std::unique_ptr greater(BaseExpression const& other) const; + std::unique_ptr greaterOrEqual(BaseExpression const& other) const; + std::unique_ptr less(BaseExpression const& other) const; + std::unique_ptr lessOrEqual(BaseExpression const& other) const; + std::unique_ptr minimum(BaseExpression const& other) const; + std::unique_ptr maximum(BaseExpression const& other) const; + std::unique_ptr mod(BaseExpression const& other) const; + std::unique_ptr floor() const; + std::unique_ptr ceil() const; + + void visit(ExpressionVisitor* visitor) const; + } +} \ No newline at end of file diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h new file mode 100644 index 000000000..2a5381a53 --- /dev/null +++ b/src/storage/expressions/VariableExpression.h @@ -0,0 +1,47 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_ + +#include "src/storage/expressions/BaseExpression.h" + +namespace storm { + namespace expressions { + class VariableExpression : public BaseExpression { + VariableExpression(ExpressionReturnType returnType, std::string const& variableName); + virtual ~VariableExpression() = default; + + std::string const& getVariableName() const; + + virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const; + virtual bool evaluateAsBool(Valuation const& evaluation) const; + virtual double evaluateAsDouble(Valuation const& evaluation) const; + + virtual std::unique_ptr operator+(BaseExpression const& other) const; + virtual std::unique_ptr operator-(BaseExpression const& other) const; + virtual std::unique_ptr operator-() const; + virtual std::unique_ptr operator*(BaseExpression const& other) const; + virtual std::unique_ptr operator/(BaseExpression const& other) const; + virtual std::unique_ptr operator&(BaseExpression const& other) const; + virtual std::unique_ptr operator|(BaseExpression const& other) const; + virtual std::unique_ptr operator~() const; + + virtual std::unique_ptr equals(BaseExpression const& other) const; + virtual std::unique_ptr notEquals(BaseExpression const& other) const; + virtual std::unique_ptr greater(BaseExpression const& other) const; + virtual std::unique_ptr greaterOrEqual(BaseExpression const& other) const; + virtual std::unique_ptr less(BaseExpression const& other) const; + virtual std::unique_ptr lessOrEqual(BaseExpression const& other) const; + virtual std::unique_ptr minimum(BaseExpression const& other) const; + virtual std::unique_ptr maximum(BaseExpression const& other) const; + virtual std::unique_ptr mod(BaseExpression const& other) const; + virtual std::unique_ptr floor() const; + virtual std::unique_ptr ceil() const; + + virtual void visit(ExpressionVisitor* visitor) const; + + private: + std::string variableName; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_ */ \ No newline at end of file