diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp index 8a80a3b71..550e2209f 100644 --- a/src/storage/expressions/BaseExpression.cpp +++ b/src/storage/expressions/BaseExpression.cpp @@ -1,11 +1,8 @@ #include "src/storage/expressions/BaseExpression.h" +#include "src/exceptions/ExceptionMacros.h" namespace storm { - namespace expressions { - BaseExpression::BaseExpression() : returnType(undefined) { - // Intentionally left empty. - } - + namespace expressions { BaseExpression::BaseExpression(ExpressionReturnType returnType) : returnType(returnType) { // Intentionally left empty. } @@ -14,10 +11,24 @@ namespace storm { return this->returnType; } - void BaseExpression::checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const { - if (actualType != expectedType) { - throw storm::exceptions::InvalidArgumentException() << errorMessage; - } + int_fast64_t BaseExpression::evaluateAsInt(Valuation const& evaluation) const { + LOG_ASSERT(false, "Unable to evaluate expression as integer."); + } + + bool BaseExpression::evaluateAsBool(Valuation const& evaluation) const { + LOG_ASSERT(false, "Unable to evaluate expression as boolean."); + } + + double BaseExpression::evaluateAsDouble(Valuation const& evaluation) const { + LOG_ASSERT(false, "Unable to evaluate expression as double."); + } + + bool BaseExpression::isTrue() const { + return false; + } + + bool BaseExpression::isFalse() const { + return false; } } } \ No newline at end of file diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h index 0412e11f8..545289b08 100644 --- a/src/storage/expressions/BaseExpression.h +++ b/src/storage/expressions/BaseExpression.h @@ -1,6 +1,9 @@ #ifndef STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_ #define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_ +#include +#include + #include "src/storage/expressions/Valuation.h" #include "src/storage/expressions/ExpressionVisitor.h" #include "src/exceptions/InvalidArgumentException.h" @@ -12,46 +15,122 @@ namespace storm { */ enum ExpressionReturnType {undefined, bool_, int_, double_}; + /*! + * The base class of all expression classes. + */ class BaseExpression { public: - - BaseExpression(); + /*! + * Constructs a base expression with the given return type. + * + * @param returnType The return type of the expression. + */ BaseExpression(ExpressionReturnType returnType); + + // Create default versions of constructors and assignments. + BaseExpression(BaseExpression const&) = default; + BaseExpression(BaseExpression&&) = default; + BaseExpression& operator=(BaseExpression const&) = default; + BaseExpression& operator=(BaseExpression&&) = default; + + // Make the destructor virtual (to allow destruction via base class pointer) and default it. virtual ~BaseExpression() = default; - ExpressionReturnType getReturnType() const; + /*! + * Evaluates the expression under the valuation of unknowns (variables and constants) given by the + * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean + * an exception is thrown. + * + * @param valuation The valuation of unknowns under which to evaluate the expression. + * @return The boolean value of the expression under the given valuation. + */ + virtual bool evaluateAsBool(Valuation const& valuation) const; + + /*! + * Evaluates the expression under the valuation of unknowns (variables and constants) given by the + * valuation and returns the resulting integer value. If the return type of the expression is not an integer + * an exception is thrown. + * + * @param valuation The valuation of unknowns under which to evaluate the expression. + * @return The integer value of the expression under the given valuation. + */ + virtual int_fast64_t evaluateAsInt(Valuation const& valuation) 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; + /*! + * Evaluates the expression under the valuation of unknowns (variables and constants) given by the + * valuation and returns the resulting double value. If the return type of the expression is not a double + * an exception is thrown. + * + * @param valuation The valuation of unknowns under which to evaluate the expression. + * @return The double value of the expression under the given valuation. + */ + virtual double evaluateAsDouble(Valuation const& valuation) const; - virtual void visit(ExpressionVisitor* visitor) const = 0; + /*! + * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants. + * + * @return True iff the expression is constant. + */ + virtual bool isConstant() const = 0; - protected: - void checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const; + /*! + * Checks if the expression is equal to the boolean literal true. + * + * @return True iff the expression is equal to the boolean literal true. + */ + virtual bool isTrue() const; + + /*! + * Checks if the expression is equal to the boolean literal false. + * + * @return True iff the expression is equal to the boolean literal false. + */ + virtual bool isFalse() const; + + /*! + * Retrieves the set of all variables that appear in the expression. + * + * @return The set of all variables that appear in the expression. + */ + virtual std::set getVariables() const = 0; + + /*! + * Retrieves the set of all constants that appear in the expression. + * + * @return The set of all constants that appear in the expression. + */ + virtual std::set getConstants() const = 0; + + /*! + * Simplifies the expression according to some simple rules. + * + * @return A pointer to the simplified expression. + */ + virtual std::unique_ptr simplify() const = 0; + + /*! + * Accepts the given visitor by calling its visit method. + * + * @param visitor The visitor that is to be accepted. + */ + virtual void accept(ExpressionVisitor* visitor) const = 0; + + /*! + * Performs a deep-copy of the expression. + * + * @return A pointer to a deep-copy of the expression. + */ + virtual std::unique_ptr clone() const = 0; + + /*! + * Retrieves the return type of the expression. + * + * @return The return type of the expression. + */ + ExpressionReturnType getReturnType() const; private: + // The return type of this expression. ExpressionReturnType returnType; }; } diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp new file mode 100644 index 000000000..749b1d1e1 --- /dev/null +++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp @@ -0,0 +1,73 @@ +#include "src/storage/expressions/BinaryBooleanFunctionExpression.h" + +namespace storm { + namespace expressions { + BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) { + // Intentionally left empty. + } + + BinaryBooleanFunctionExpression::OperatorType BinaryBooleanFunctionExpression::getOperatorType() const { + return this->operatorType; + } + + BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) : BinaryExpression(other), operatorType(other.getOperatorType()) { + // Intentionally left empty. + } + + BinaryBooleanFunctionExpression& BinaryBooleanFunctionExpression::operator=(BinaryBooleanFunctionExpression const& other) { + if (this != &other) { + BinaryExpression::operator=(other); + this->operatorType = other.getOperatorType(); + } + return *this; + } + + bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const { + bool firstOperandEvaluation = this->getFirstOperand()->evaluateAsBool(valuation); + bool secondOperandEvaluation = this->getSecondOperand()->evaluateAsBool(valuation); + + bool result; + switch (this->getOperatorType()) { + case AND: result = firstOperandEvaluation && secondOperandEvaluation; break; + case OR: result = firstOperandEvaluation || secondOperandEvaluation; break; + } + + return result; + } + + std::unique_ptr BinaryBooleanFunctionExpression::simplify() const { + std::unique_ptr firstOperandSimplified = this->getFirstOperand()->simplify(); + std::unique_ptr secondOperandSimplified = this->getSecondOperand()->simplify(); + + switch (this->getOperatorType()) { + case AND: if (firstOperandSimplified->isTrue()) { + return secondOperandSimplified; + } else if (firstOperandSimplified->isFalse()) { + return firstOperandSimplified; + } else if (secondOperandSimplified->isTrue()) { + return firstOperandSimplified; + } else if (secondOperandSimplified->isFalse()) { + return secondOperandSimplified; + } + break; + case OR: if (firstOperandSimplified->isTrue()) { + return firstOperandSimplified; + } else if (firstOperandSimplified->isFalse()) { + return secondOperandSimplified; + } else if (secondOperandSimplified->isTrue()) { + return secondOperandSimplified; + } else if (secondOperandSimplified->isFalse()) { + return firstOperandSimplified; + } + } + + return std::unique_ptr(new BinaryBooleanFunctionExpression(this->getReturnType(), std::move(firstOperandSimplified), std::move(secondOperandSimplified), this->getOperatorType())); + } + + void BinaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) const { + visitor->visit(this); + } + + virtual std::unique_ptr clone() const override; + } +} \ No newline at end of file diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h new file mode 100644 index 000000000..f476550d0 --- /dev/null +++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h @@ -0,0 +1,54 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ + +#include "src/storage/expressions/BinaryExpression.h" + +namespace storm { + namespace expressions { + class BinaryBooleanFunctionExpression : public BinaryExpression { + public: + /*! + * An enum type specifying the different operators applicable. + */ + enum OperatorType {AND, OR}; + + /*! + * Creates a binary boolean function expression with the given return type, operands and operator. + * + * @param returnType The return type of the expression. + * @param firstOperand The first operand of the expression. + * @param secondOperand The second operand of the expression. + * @param functionType The operator of the expression. + */ + BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr&& fistOperand, std::unique_ptr&& secondOperand, OperatorType operatorType); + + // Provide custom versions of copy construction and assignment. + BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other); + BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression const& other); + + // Create default variants of move construction/assignment and virtual destructor. + BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression&&) = default; + BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression&&) = default; + virtual ~BinaryBooleanFunctionExpression() = default; + + // Override base class methods. + virtual bool evaluateAsBool(Valuation const& valuation) const override; + virtual std::unique_ptr simplify() const override; + virtual void accept(ExpressionVisitor* visitor) const override; + virtual std::unique_ptr clone() const override; + + /*! + * Retrieves the operator associated with the expression. + * + * @return The operator associated with the expression. + */ + OperatorType getOperatorType() const; + + private: + // The operator of the expression. + OperatorType operatorType; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp new file mode 100644 index 000000000..9038aca41 --- /dev/null +++ b/src/storage/expressions/BinaryExpression.cpp @@ -0,0 +1,47 @@ +#include "src/storage/expressions/BinaryExpression.h" + +namespace storm { + namespace expressions { + BinaryExpression::BinaryExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand) : BaseExpression(returnType), firstOperand(std::move(firstOperand)), secondOperand(std::move(secondOperand)) { + // Intentionally left empty. + } + + BinaryExpression::BinaryExpression(BinaryExpression const& other) : BaseExpression(other.getReturnType()), firstOperand(other.getFirstOperand()->clone()), secondOperand(other.getSecondOperand()->clone()) { + // Intentionally left empty. + } + + BinaryExpression& BinaryExpression::operator=(BinaryExpression const& other) { + if (this != &other) { + this->firstOperand = other.getFirstOperand()->clone(); + this->secondOperand = other.getSecondOperand()->clone(); + } + return *this; + } + + bool BinaryExpression::isConstant() const { + return this->getFirstOperand()->isConstant() && this->getSecondOperand()->isConstant(); + } + + std::set BinaryExpression::getVariables() const { + std::set firstVariableSet = this->getFirstOperand()->getVariables(); + std::set secondVariableSet = this->getSecondOperand()->getVariables(); + firstVariableSet.insert(secondVariableSet.begin(), secondVariableSet.end()); + return firstVariableSet; + } + + std::set BinaryExpression::getConstants() const { + std::set firstConstantSet = this->getFirstOperand()->getVariables(); + std::set secondConstantSet = this->getSecondOperand()->getVariables(); + firstConstantSet.insert(secondConstantSet.begin(), secondConstantSet.end()); + return firstConstantSet; + } + + std::unique_ptr const& BinaryExpression::getFirstOperand() const { + return this->firstOperand; + } + + std::unique_ptr const& BinaryExpression::getSecondOperand() const { + return this->secondOperand; + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h new file mode 100644 index 000000000..a94513cb5 --- /dev/null +++ b/src/storage/expressions/BinaryExpression.h @@ -0,0 +1,60 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_ + +#include "src/storage/expressions/BaseExpression.h" + +namespace storm { + namespace expressions { + /*! + * The base class of all binary expressions. + */ + class BinaryExpression : public BaseExpression { + public: + /*! + * Constructs a binary expression with the given return type and operands. + * + * @param returnType The return type of the expression. + * @param firstOperand The first operand of the expression. + * @param secondOperand The second operand of the expression. + */ + BinaryExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand); + + // Provide custom versions of copy construction and assignment. + BinaryExpression(BinaryExpression const& other); + BinaryExpression& operator=(BinaryExpression const& other); + + // Create default variants of move construction/assignment and virtual destructor. + BinaryExpression(BinaryExpression&&) = default; + BinaryExpression& operator=(BinaryExpression&&) = default; + virtual ~BinaryExpression() = default; + + // Override base class methods. + virtual bool isConstant() const override; + virtual std::set getVariables() const override; + virtual std::set getConstants() const override; + + /*! + * Retrieves the first operand of the expression. + * + * @return The first operand of the expression. + */ + std::unique_ptr const& getFirstOperand() const; + + /*! + * Retrieves the second operand of the expression. + * + * @return The second operand of the expression. + */ + std::unique_ptr const& getSecondOperand() const; + + private: + // The first operand of the expression. + std::unique_ptr firstOperand; + + // The second operand of the expression. + std::unique_ptr secondOperand; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp new file mode 100644 index 000000000..61e491650 --- /dev/null +++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp @@ -0,0 +1,64 @@ +#include + +#include "src/storage/expressions/BinaryNumericalFunctionExpression.h" +#include "src/exceptions/ExceptionMacros.h" + +namespace storm { + namespace expressions { + BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) { + // Intentionally left empty. + } + + BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) : BinaryExpression(other), operatorType(this->getOperatorType()) { + // Intentionally left empty. + } + + BinaryNumericalFunctionExpression& BinaryNumericalFunctionExpression::operator=(BinaryNumericalFunctionExpression const& other) { + if (this != &other) { + BinaryExpression::operator=(other); + this->operatorType = other.getOperatorType(); + } + return *this; + } + + int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const { + LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer."); + int_fast64_t firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation); + int_fast64_t secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation); + switch (this->getOperatorType()) { + case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break; + case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break; + case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break; + case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break; + case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break; + case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break; + } + } + + double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const { + LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer."); + double firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation); + double secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation); + switch (this->getOperatorType()) { + case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break; + case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break; + case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break; + case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break; + case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break; + case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break; + } + } + + std::unique_ptr BinaryNumericalFunctionExpression::simplify() const { + return std::unique_ptr(new BinaryNumericalFunctionExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getOperatorType())); + } + + void BinaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) const { + visitor->visit(this); + } + + std::unique_ptr BinaryNumericalFunctionExpression::clone() const { + return std::unique_ptr(new BinaryNumericalFunctionExpression(*this)); + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h new file mode 100644 index 000000000..56ae3b55d --- /dev/null +++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h @@ -0,0 +1,55 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_ + +#include "src/storage/expressions/BinaryExpression.h" + +namespace storm { + namespace expressions { + class BinaryNumericalFunctionExpression : public BinaryExpression { + public: + /*! + * An enum type specifying the different operators applicable. + */ + enum OperatorType {PLUS, MINUS, TIMES, DIVIDE, MIN, MAX}; + + /*! + * Constructs a binary numerical function expression with the given return type, operands and operator. + * + * @param returnType The return type of the expression. + * @param firstOperand The first operand of the expression. + * @param secondOperand The second operand of the expression. + * @param functionType The operator of the expression. + */ + BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand, OperatorType operatorType); + + // Provide custom versions of copy construction and assignment. + BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other); + BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression const& other); + + // Create default variants of move construction/assignment and virtual destructor. + BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression&&) = default; + BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression&&) = default; + virtual ~BinaryNumericalFunctionExpression() = default; + + // Override base class methods. + virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override; + virtual double evaluateAsDouble(Valuation const& valuation) const override; + virtual std::unique_ptr simplify() const override; + virtual void accept(ExpressionVisitor* visitor) const override; + virtual std::unique_ptr clone() const override; + + /*! + * Retrieves the operator associated with the expression. + * + * @return The operator associated with the expression. + */ + OperatorType getOperatorType() const; + + private: + // The operator of the expression. + OperatorType operatorType; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp new file mode 100644 index 000000000..a203ec2fb --- /dev/null +++ b/src/storage/expressions/BinaryRelationExpression.cpp @@ -0,0 +1,50 @@ +#include "src/storage/expressions/BinaryRelationExpression.h" + +namespace storm { + namespace expressions { + BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand, RelationType relationType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), relationType(relationType) { + // Intentionally left empty. + } + + BinaryRelationExpression::BinaryRelationExpression(BinaryRelationExpression const& other) : BinaryExpression(other), relationType(other.getRelationType()) { + // Intentionally left empty. + } + + BinaryRelationExpression& BinaryRelationExpression::operator=(BinaryRelationExpression const& other) { + if (this != &other) { + BinaryExpression::operator=(other); + this->relationType = other.getRelationType(); + } + return *this; + } + + bool BinaryRelationExpression::evaluateAsBool(Valuation const& valuation) const { + double firstOperandEvaluated = this->getFirstOperand()->evaluateAsDouble(valuation); + double secondOperandEvaluated = this->getSecondOperand()->evaluateAsDouble(valuation); + switch (this->getRelationType()) { + case EQUAL: return firstOperandEvaluated == secondOperandEvaluated; break; + case NOT_EQUAL: return firstOperandEvaluated != secondOperandEvaluated; break; + case GREATER: return firstOperandEvaluated > secondOperandEvaluated; break; + case GREATER_OR_EQUAL: return firstOperandEvaluated >= secondOperandEvaluated; break; + case LESS: return firstOperandEvaluated < secondOperandEvaluated; break; + case LESS_OR_EQUAL: return firstOperandEvaluated <= secondOperandEvaluated; break; + } + } + + std::unique_ptr BinaryRelationExpression::simplify() const { + return std::unique_ptr(new BinaryRelationExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getRelationType())); + } + + void BinaryRelationExpression::accept(ExpressionVisitor* visitor) const { + visitor->visit(this); + } + + std::unique_ptr BinaryRelationExpression::clone() const { + return std::unique_ptr(new BinaryRelationExpression(*this)); + } + + BinaryRelationExpression::RelationType BinaryRelationExpression::getRelationType() const { + return this->relationType; + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h new file mode 100644 index 000000000..7b45cc1c1 --- /dev/null +++ b/src/storage/expressions/BinaryRelationExpression.h @@ -0,0 +1,54 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ + +#include "src/storage/expressions/BinaryExpression.h" + +namespace storm { + namespace expressions { + class BinaryRelationExpression : public BinaryExpression { + public: + /*! + * An enum type specifying the different relations applicable. + */ + enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; + + /*! + * Creates a binary relation expression with the given return type, operands and relation type. + * + * @param returnType The return type of the expression. + * @param firstOperand The first operand of the expression. + * @param secondOperand The second operand of the expression. + * @param relationType The operator of the expression. + */ + BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr&& firstOperand, std::unique_ptr&& secondOperand, RelationType relationType); + + // Provide custom versions of copy construction and assignment. + BinaryRelationExpression(BinaryRelationExpression const& other); + BinaryRelationExpression& operator=(BinaryRelationExpression const& other); + + // Create default variants of move construction/assignment and virtual destructor. + BinaryRelationExpression(BinaryRelationExpression&&) = default; + BinaryRelationExpression& operator=(BinaryRelationExpression&&) = default; + virtual ~BinaryRelationExpression() = default; + + // Override base class methods. + virtual bool evaluateAsBool(Valuation const& valuation) const override; + virtual std::unique_ptr simplify() const override; + virtual void accept(ExpressionVisitor* visitor) const override; + virtual std::unique_ptr clone() const override; + + /*! + * Retrieves the relation associated with the expression. + * + * @return The relation associated with the expression. + */ + RelationType getRelationType() const; + + private: + // The relation type of the expression. + RelationType relationType; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp new file mode 100644 index 000000000..8c40b02af --- /dev/null +++ b/src/storage/expressions/BooleanConstantExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/BooleanConstantExpression.h" + +namespace storm { + namespace expressions { + BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::bool_, constantName) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h new file mode 100644 index 000000000..c337f01c0 --- /dev/null +++ b/src/storage/expressions/BooleanConstantExpression.h @@ -0,0 +1,16 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ + +#include "src/storage/expressions/ConstantExpression.h" + +namespace storm { + namespace expressions { + class BooleanConstantExpression : public ConstantExpression { + public: + BooleanConstantExpression(std::string const& constantName); + virtual ~BooleanConstantExpression() = default; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ */ diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp new file mode 100644 index 000000000..d6cbce747 --- /dev/null +++ b/src/storage/expressions/ConstantExpression.cpp @@ -0,0 +1,13 @@ +#include "src/storage/expressions/ConstantExpression.h" + +namespace storm { + namespace expressions { + ConstantExpression::ConstantExpression(ReturnType returnType, std::string const& constantName) : BaseExpression(returnType), constantName(constantName) { + // Intentionally left empty. + } + + std::string const& ConstantExpression::getConstantName() const { + return this->constantName; + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h new file mode 100644 index 000000000..08fb80321 --- /dev/null +++ b/src/storage/expressions/ConstantExpression.h @@ -0,0 +1,20 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_ + +#include "src/storage/expressions/BaseExpression.h" + +namespace storm { + namespace expressions { + class ConstantExpression : public BaseExpression { + ConstantExpression(ExpressionReturnType returnType, std::string const& constantName); + virtual ~ConstantExpression() = default; + + std::string const& getConstantName() const; + + private: + std::string constantName; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_ */ diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp new file mode 100644 index 000000000..25fa035d4 --- /dev/null +++ b/src/storage/expressions/DoubleConstantExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/DoubleConstantExpression.h" + +namespace storm { + namespace expressions { + DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::double_, constantName) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h new file mode 100644 index 000000000..fc5725642 --- /dev/null +++ b/src/storage/expressions/DoubleConstantExpression.h @@ -0,0 +1,16 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ + +#include "src/storage/expressions/ConstantExpression.h" + +namespace storm { + namespace expressions { + class DoubleConstantExpression : public ConstantExpression { + public: + DoubleConstantExpression(std::string const& constantName); + virtual ~DoubleConstantExpression() = default; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ */ diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h index 9b2fe78c1..c866d64cb 100644 --- a/src/storage/expressions/Expression.h +++ b/src/storage/expressions/Expression.h @@ -14,7 +14,26 @@ namespace storm { // Static factory methods to create atomic expression parts. // Virtual operator overloading. - virtual Expression operator+(Expression const& other); + Expression operator+(Expression const& other) const; + Expression operator-(Expression const& other) const; + Expression operator-() const; + Expression operator*(Expression const& other) const; + Expression operator/(Expression const& other) const; + Expression operator&(Expression const& other) const; + Expression operator|(Expression const& other) const; + Expression operator~() const; + + Expression equals(Expression const& other) const; + Expression notEquals(Expression const& other) const; + Expression greater(Expression const& other) const; + Expression greaterOrEqual(Expression const& other) const; + Expression less(Expression const& other) const; + Expression lessOrEqual(Expression const& other) const; + Expression minimum(Expression const& other) const; + Expression maximum(Expression const& other) const; + Expression mod(Expression const& other) const; + Expression floor() const; + Expression ceil() const; /*! * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is @@ -28,6 +47,13 @@ namespace storm { template class MapType> Expression substitute(MapType const& identifierToExpressionMap) const; + /*! + * Retrieves the return type of the expression. + * + * @return The return type of the expression. + */ + ExpressionReturnType getReturnType() const; + private: /*! * Creates an expression with the given underlying base expression. diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h index e145826b6..59bb99ac1 100644 --- a/src/storage/expressions/ExpressionVisitor.h +++ b/src/storage/expressions/ExpressionVisitor.h @@ -1,10 +1,16 @@ #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_ #define STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_ +#include "src/storage/expressions/BinaryNumericalFunctionExpression.h" +#include "src/storage/expressions/BinaryBooleanFunctionExpression.h" +#include "src/storage/expressions/BinaryRelationExpression.h" + namespace storm { namespace expressions { class ExpressionVisitor { - + virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0; + virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0; + virtual void visit(BinaryRelationExpression const* expression) = 0; }; } } diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp new file mode 100644 index 000000000..0cbf541a7 --- /dev/null +++ b/src/storage/expressions/IntegerConstantExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/IntegerConstantExpression.h" + +namespace storm { + namespace expressions { + IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::int_, constantName) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h new file mode 100644 index 000000000..c39df1c77 --- /dev/null +++ b/src/storage/expressions/IntegerConstantExpression.h @@ -0,0 +1,15 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ + +namespace storm { + namespace expressions { + class IntegerConstantExpression : public ConstantExpression { + public: + IntegerConstantExpression(std::string const& constantName); + virtual ~IntegerConstantExpression() = default; + + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ */ diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp new file mode 100644 index 000000000..1d97ebf41 --- /dev/null +++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/UnaryBooleanFunctionExpression.h" + +namespace storm { + namespace expressions { + UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h new file mode 100644 index 000000000..277ea6637 --- /dev/null +++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h @@ -0,0 +1,21 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ + +namespace storm { + namespace expressions { + class UnaryBooleanFunctionExpression : public UnaryExpression { + /*! + * An enum type specifying the different functions applicable. + */ + enum FunctionType {NOT}; + + UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr&& argument, FunctionType functionType); + virtual ~UnaryBooleanFunctionExpression() = default; + + private: + FunctionType FunctionType; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp new file mode 100644 index 000000000..bf8ab5972 --- /dev/null +++ b/src/storage/expressions/UnaryExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/UnaryExpression.h" + +namespace storm { + namespace expressions { + UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::unique_ptr&& argument) : BaseExpression(returnType), argument(std::move(argument)) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h new file mode 100644 index 000000000..1aee2b349 --- /dev/null +++ b/src/storage/expressions/UnaryExpression.h @@ -0,0 +1,18 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_ + +namespace storm { + namespace expressions { + class UnaryExpression : public BaseExpression { + public: + UnaryExpression(ExpressionReturnType returnType, std::unique_ptr&& argument); + virtual ~UnaryExpression() = default; + + std::unique_ptr const& getArgument() const; + private: + std::unique_ptr argument; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp new file mode 100644 index 000000000..e3cc93fdb --- /dev/null +++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp @@ -0,0 +1,9 @@ +#include "src/storage/expressions/UnaryNumericalFunctionExpression.h" + +namespace storm { + namespace expressions { + UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) { + // Intentionally left empty. + } + } +} \ No newline at end of file diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h new file mode 100644 index 000000000..5dce0b84f --- /dev/null +++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h @@ -0,0 +1,21 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_ + +namespace storm { + namespace expressions { + class UnaryNumericalFunctionExpression : public UnaryExpression { + /*! + * An enum type specifying the different functions applicable. + */ + enum FunctionType {MINUS, FLOOR, CEIL}; + + UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr&& argument, FunctionType functionType); + virtual ~UnaryNumericalFunctionExpression() = default; + + private: + FunctionType FunctionType; + }; + } +} + +#endif /* STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_ */ diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h index c2d0b01cb..5a1a470ce 100644 --- a/src/storage/expressions/Valuation.h +++ b/src/storage/expressions/Valuation.h @@ -1,6 +1,8 @@ #ifndef STORM_STORAGE_EXPRESSIONS_VALUATION_H_ #define STORM_STORAGE_EXPRESSIONS_VALUATION_H_ +#include + namespace storm { namespace expressions { class Valuation { diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp index bce5ec0dc..7b64707fd 100644 --- a/src/storage/expressions/VariableExpression.cpp +++ b/src/storage/expressions/VariableExpression.cpp @@ -17,12 +17,12 @@ namespace storm { } bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const { - LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not an integer."); + LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not a boolean."); 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."); + LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not a double."); return evaluation.getDoubleValue(this->getVariableName()); } @@ -52,5 +52,7 @@ namespace storm { std::unique_ptr ceil() const; void visit(ExpressionVisitor* visitor) const; + + virtual std::unique_ptr clonse() const; } } \ No newline at end of file diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h index 2a5381a53..d4d57907b 100644 --- a/src/storage/expressions/VariableExpression.h +++ b/src/storage/expressions/VariableExpression.h @@ -38,6 +38,8 @@ namespace storm { virtual void visit(ExpressionVisitor* visitor) const; + virtual std::unique_ptr clonse() const; + private: std::string variableName; };