#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_ #define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_ #include <memory> #include "src/storage/expressions/BaseExpression.h" #include "src/utility/OsDetection.h" namespace storm { namespace expressions { class Expression { public: Expression() = default; /*! * Creates an expression with the given underlying base expression. * * @param expressionPtr A pointer to the underlying base expression. */ Expression(std::shared_ptr<BaseExpression const> const& expressionPtr); // Instantiate constructors and assignments with their default implementations. Expression(Expression const& other) = default; Expression& operator=(Expression const& other) = default; #ifndef WINDOWS Expression(Expression&&) = default; Expression& operator=(Expression&&) = default; #endif // Static factory methods to create atomic expression parts. static Expression createBooleanLiteral(bool value); static Expression createTrue(); static Expression createFalse(); static Expression createIntegerLiteral(int_fast64_t value); static Expression createDoubleLiteral(double value); static Expression createBooleanVariable(std::string const& variableName); static Expression createIntegerVariable(std::string const& variableName); static Expression createDoubleVariable(std::string const& variableName); static Expression createUndefinedVariable(std::string const& variableName); static Expression createBooleanConstant(std::string const& constantName); static Expression createIntegerConstant(std::string const& constantName); static Expression createDoubleConstant(std::string const& constantName); // Provide operator overloads to conveniently construct new expressions from other expressions. 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||(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<(Expression const& other) const; Expression operator<=(Expression const& other) const; Expression ite(Expression const& thenExpression, Expression const& elseExpression); Expression implies(Expression const& other) const; Expression iff(Expression const& other) const; Expression floor() const; Expression ceil() const; static Expression minimum(Expression const& lhs, Expression const& rhs); static Expression maximum(Expression const& lhs, Expression const& rhs); /*! * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is * done simultaneously, i.e., identifiers appearing in the expressions that were "plugged in" are not * substituted. * * @param identifierToExpressionMap A mapping from identifiers to the expression they are substituted with. * @return An expression in which all identifiers in the key set of the mapping are replaced by the * expression they are mapped to. */ template<template<typename... Arguments> class MapType> Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const; /*! * Substitutes all occurrences of identifiers with different names given by a mapping. * * @param identifierToIdentifierMap A mapping from identifiers to identifiers they are substituted with. * @return An expression in which all identifiers in the key set of the mapping are replaced by the * identifiers they are mapped to. */ template<template<typename... Arguments> class MapType> Expression substitute(MapType<std::string, std::string> const& identifierToIdentifierMap) 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. */ bool evaluateAsBool(Valuation const* valuation = nullptr) 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. */ int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const; /*! * 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. */ double evaluateAsDouble(Valuation const* valuation = nullptr) const; /*! * Simplifies the expression according to some basic rules. * * @return The simplified expression. */ Expression simplify(); /*! * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants. * * @return True iff the expression is constant. */ bool isConstant() const; /*! * Checks if the expression is equal to the boolean literal true. * * @return True iff the expression is equal to the boolean literal true. */ 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. */ 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. */ std::set<std::string> getVariables() const; /*! * Retrieves the set of all constants that appear in the expression. * * @return The set of all constants that appear in the expression. */ std::set<std::string> getConstants() const; /*! * Retrieves the base expression underlying this expression object. Note that prior to calling this, the * expression object must be properly initialized. * * @return A reference to the underlying base expression. */ BaseExpression const& getBaseExpression() const; /*! * Retrieves a pointer to the base expression underlying this expression object. * * @return A pointer to the underlying base expression. */ std::shared_ptr<BaseExpression const> const& getBaseExpressionPointer() const; /*! * Retrieves the return type of the expression. * * @return The return type of the expression. */ ExpressionReturnType getReturnType() const; /*! * Retrieves whether the expression has a numerical return type, i.e., integer or double. * * @return True iff the expression has a numerical return type. */ bool hasNumericalReturnType() const; /*! * Retrieves whether the expression has a boolean return type. * * @return True iff the expression has a boolean return type. */ bool hasBooleanReturnType() const; friend std::ostream& operator<<(std::ostream& stream, Expression const& expression); private: // A pointer to the underlying base expression. std::shared_ptr<BaseExpression const> expressionPtr; }; } } #endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_ */