You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
19 KiB
417 lines
19 KiB
#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
|
|
#define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
|
|
|
|
#include <memory>
|
|
#include <map>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "storm/storage/expressions/BaseExpression.h"
|
|
#include "storm/utility/OsDetection.h"
|
|
|
|
namespace storm {
|
|
namespace expressions {
|
|
// Foward-declare expression manager class.
|
|
class ExpressionManager;
|
|
class Variable;
|
|
class ExpressionVisitor;
|
|
|
|
class Expression {
|
|
public:
|
|
friend class ExpressionManager;
|
|
friend class Variable;
|
|
template<typename MapType> friend class SubstitutionVisitor;
|
|
|
|
friend Expression operator+(Expression const& first, Expression const& second);
|
|
friend Expression operator+(Expression const& first, int64_t second);
|
|
friend Expression operator+(int64_t first, Expression const& second);
|
|
friend Expression operator-(Expression const& first, Expression const& second);
|
|
friend Expression operator-(Expression const& first, int64_t second);
|
|
friend Expression operator-(int64_t first, Expression const& second);
|
|
friend Expression operator-(Expression const& first);
|
|
friend Expression operator*(Expression const& first, Expression const& second);
|
|
friend Expression operator/(Expression const& first, Expression const& second);
|
|
friend Expression operator^(Expression const& first, Expression const& second);
|
|
friend Expression operator&&(Expression const& first, Expression const& second);
|
|
friend Expression operator||(Expression const& first, Expression const& second);
|
|
friend Expression operator!(Expression const& first);
|
|
friend Expression operator==(Expression const& first, Expression const& second);
|
|
friend Expression operator!=(Expression const& first, Expression const& second);
|
|
friend Expression operator>(Expression const& first, Expression const& second);
|
|
friend Expression operator>=(Expression const& first, Expression const& second);
|
|
friend Expression operator<(Expression const& first, Expression const& second);
|
|
friend Expression operator<=(Expression const& first, Expression const& second);
|
|
friend Expression operator>(Expression const& first, int64_t second);
|
|
friend Expression operator>=(Expression const& first, int64_t second);
|
|
friend Expression operator<(Expression const& first, int64_t second);
|
|
friend Expression operator<=(Expression const& first, int64_t second);
|
|
friend Expression ite(Expression const& condition, Expression const& thenExpression, Expression const& elseExpression);
|
|
friend Expression implies(Expression const& first, Expression const& second);
|
|
friend Expression iff(Expression const& first, Expression const& second);
|
|
friend Expression xclusiveor(Expression const& first, Expression const& second);
|
|
friend Expression abs(Expression const& first);
|
|
friend Expression truncate(Expression const& first);
|
|
friend Expression sign(Expression const& first);
|
|
friend Expression floor(Expression const& first);
|
|
friend Expression ceil(Expression const& first);
|
|
friend Expression minimum(Expression const& first, Expression const& second);
|
|
friend Expression maximum(Expression const& first, Expression const& second);
|
|
|
|
Expression() = default;
|
|
|
|
/*!
|
|
* Creates an expression representing the given variable.
|
|
*
|
|
* @param variable The variable to represent.
|
|
*/
|
|
Expression(Variable const& variable);
|
|
|
|
/*!
|
|
* 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
|
|
|
|
/*!
|
|
* Converts the expression to an expression over the variables of the provided expression manager.
|
|
*/
|
|
Expression changeManager(ExpressionManager const& newExpressionManager) const;
|
|
|
|
/*!
|
|
* Substitutes all occurrences of the variables according to the given map. Note that this substitution is
|
|
* done simultaneously, i.e., variables appearing in the expressions that were "plugged in" are not
|
|
* substituted.
|
|
*
|
|
* @param variableToExpressionMap A mapping from variables 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.
|
|
*/
|
|
Expression substitute(std::map<Variable, Expression> const& variableToExpressionMap) const;
|
|
|
|
/*!
|
|
* Substitutes all occurrences of the variables according to the given map. Note that this substitution is
|
|
* done simultaneously, i.e., variables appearing in the expressions that were "plugged in" are not
|
|
* substituted.
|
|
*
|
|
* @param variableToExpressionMap A mapping from variables 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.
|
|
*/
|
|
Expression substitute(std::unordered_map<Variable, Expression> const& variableToExpressionMap) const;
|
|
|
|
/*!
|
|
* Evaluates the expression under the valuation of variables 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 variables 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 variables 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() const;
|
|
|
|
/*!
|
|
* Retrieves the operator of a function application. This is only legal to call if the expression is
|
|
* function application.
|
|
*
|
|
* @return The operator associated with the function application.
|
|
*/
|
|
OperatorType getOperator() const;
|
|
|
|
/*!
|
|
* Checks if the expression is a function application (of any sort).
|
|
*
|
|
* @return True iff the expression is a function application.
|
|
*/
|
|
bool isFunctionApplication() const;
|
|
|
|
/*!
|
|
* Retrieves the arity of the expression.
|
|
*
|
|
* @return The arity of the expression.
|
|
*/
|
|
uint_fast64_t getArity() const;
|
|
|
|
/*!
|
|
* Retrieves the given operand from the expression.
|
|
*
|
|
* @param operandIndex The index of the operand to retrieve. This must be lower than the arity of the expression.
|
|
* @return The operand at the given index.
|
|
*/
|
|
Expression getOperand(uint_fast64_t operandIndex) const;
|
|
|
|
/*!
|
|
* Retrieves the identifier associated with this expression. This is only legal to call if the expression
|
|
* is a variable.
|
|
*
|
|
* @return The identifier associated with this expression.
|
|
*/
|
|
std::string const& getIdentifier() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression contains a variable.
|
|
*
|
|
* @return True iff the expression contains a variable.
|
|
*/
|
|
bool containsVariables() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression is a literal.
|
|
*
|
|
* @return True iff the expression is a literal.
|
|
*/
|
|
bool isLiteral() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression is a variable.
|
|
*
|
|
* @return True iff the expression is a variable.
|
|
*/
|
|
bool isVariable() 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;
|
|
|
|
/*!
|
|
* Checks whether the two expressions are the same. Note that this does not check for syntactical or even
|
|
* semantical equivalence, but only returns true if both are the very same expressions.
|
|
*
|
|
* @return True iff the two expressions are the same.
|
|
*/
|
|
bool areSame(storm::expressions::Expression const& other) const;
|
|
|
|
/*!
|
|
* Retrieves whether this expression is a relation expression, i.e., an expression that has a relation
|
|
* (equal, not equal, less, less or equal, etc.) as its top-level operator.
|
|
*
|
|
* @return True iff the expression is a relation expression.
|
|
*/
|
|
bool isRelationalExpression() const;
|
|
|
|
/*!
|
|
* Retrieves whether this expression is a linear expression.
|
|
*
|
|
* @return True iff the expression is linear.
|
|
*/
|
|
bool isLinear() 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<storm::expressions::Variable> getVariables() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression contains any of the given variables.
|
|
*
|
|
* @param variables The variables to search for.
|
|
* @return True iff any of the variables appear in the expression.
|
|
*/
|
|
bool containsVariable(std::set<storm::expressions::Variable> const& variables) 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 manager responsible for this expression.
|
|
*
|
|
* @return The manager responsible for this expression.
|
|
*/
|
|
ExpressionManager const& getManager() const;
|
|
|
|
/*!
|
|
* Retrieves the type of the expression.
|
|
*
|
|
* @return The type of the expression.
|
|
*/
|
|
Type const& getType() 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 hasNumericalType() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression has a rational return type.
|
|
*
|
|
* @return True iff the expression has a rational return type.
|
|
*/
|
|
bool hasRationalType() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression has a boolean return type.
|
|
*
|
|
* @return True iff the expression has a boolean return type.
|
|
*/
|
|
bool hasBooleanType() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression has an integral return type.
|
|
*
|
|
* @return True iff the expression has a integral return type.
|
|
*/
|
|
bool hasIntegerType() const;
|
|
|
|
/*!
|
|
* Retrieves whether the expression has an integral return type.
|
|
*
|
|
* @return True iff the expression has a integral return type.
|
|
*/
|
|
bool hasBitVectorType() const;
|
|
|
|
/*!
|
|
* Accepts the given visitor.
|
|
*
|
|
* @param visitor The visitor to accept.
|
|
*/
|
|
boost::any accept(ExpressionVisitor& visitor, boost::any const& data) const;
|
|
|
|
/*!
|
|
* Converts the expression into a string.
|
|
*
|
|
* @return The string representation of the expression.
|
|
*/
|
|
std::string toString() const;
|
|
|
|
/*!
|
|
* Checks whether the object encapsulates a base-expression.
|
|
*/
|
|
bool isInitialized() const;
|
|
|
|
/*!
|
|
* Checks whether the two expressions are syntatically the same.
|
|
*/
|
|
bool isSyntacticallyEqual(storm::expressions::Expression const& other) 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;
|
|
};
|
|
|
|
// Provide operator overloads to conveniently construct new expressions from other expressions.
|
|
Expression operator+(Expression const& first, Expression const& second);
|
|
Expression operator+(Expression const& first, int64_t second);
|
|
Expression operator+(int64_t first, Expression const& second);
|
|
Expression operator-(Expression const& first, Expression const& second);
|
|
Expression operator-(Expression const& first, int64_t second);
|
|
Expression operator-(int64_t first, Expression const& second);
|
|
Expression operator-(Expression const& first);
|
|
Expression operator*(Expression const& first, Expression const& second);
|
|
Expression operator/(Expression const& first, Expression const& second);
|
|
Expression operator^(Expression const& first, Expression const& second);
|
|
Expression operator&&(Expression const& first, Expression const& second);
|
|
Expression operator||(Expression const& first, Expression const& second);
|
|
Expression operator!(Expression const& first);
|
|
Expression operator==(Expression const& first, Expression const& second);
|
|
Expression operator!=(Expression const& first, Expression const& second);
|
|
Expression operator>(Expression const& first, Expression const& second);
|
|
Expression operator>=(Expression const& first, Expression const& second);
|
|
Expression operator<(Expression const& first, Expression const& second);
|
|
Expression operator<=(Expression const& first, Expression const& second);
|
|
Expression operator>(Expression const& first, int64_t second);
|
|
Expression operator>=(Expression const& first, int64_t second);
|
|
Expression operator<(Expression const& first, int64_t second);
|
|
Expression operator<=(Expression const& first, int64_t second);
|
|
Expression ite(Expression const& condition, Expression const& thenExpression, Expression const& elseExpression);
|
|
Expression implies(Expression const& first, Expression const& second);
|
|
Expression iff(Expression const& first, Expression const& second);
|
|
Expression xclusiveor(Expression const& first, Expression const& second);
|
|
Expression abs(Expression const& first);
|
|
Expression truncate(Expression const& first);
|
|
Expression sign(Expression const& first);
|
|
Expression floor(Expression const& first);
|
|
Expression ceil(Expression const& first);
|
|
Expression minimum(Expression const& first, Expression const& second);
|
|
Expression maximum(Expression const& first, Expression const& second);
|
|
Expression disjunction(std::vector<storm::expressions::Expression> const& expressions);
|
|
Expression conjunction(std::vector<storm::expressions::Expression> const& expressions);
|
|
Expression sum(std::vector<storm::expressions::Expression> const& expressions);
|
|
Expression apply(std::vector<storm::expressions::Expression> const& expressions, std::function<Expression (Expression const&, Expression const&)> const& function);
|
|
|
|
}
|
|
}
|
|
|
|
namespace std {
|
|
template <>
|
|
struct less<storm::expressions::Expression> {
|
|
bool operator()(storm::expressions::Expression const& lhs, storm::expressions::Expression const& rhs) const {
|
|
return lhs.getBaseExpressionPointer() < rhs.getBaseExpressionPointer();
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<storm::expressions::Expression> {
|
|
size_t operator()(storm::expressions::Expression const& e) const {
|
|
return reinterpret_cast<size_t>(e.getBaseExpressionPointer().get());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct equal_to<storm::expressions::Expression> {
|
|
bool operator()(storm::expressions::Expression const& e1, storm::expressions::Expression const& e2) const {
|
|
return e1.areSame(e2);
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_ */
|