#ifndef EXPRESSION_HPP #define EXPRESSION_HPP #include #include #include #include "IdMap.hpp" #include "Operator.hpp" template struct VariableAssignment; template struct MaxStrategy; template struct Variable; template struct MaxExpression; template struct Expression { virtual ~Expression() { } virtual const MaxExpression* toMaxExpression() const { return NULL; } virtual MaxExpression* toMaxExpression() { return NULL; } virtual Domain eval(const VariableAssignment&) const = 0; virtual Domain eval(const VariableAssignment& rho, const MaxStrategy&) const { return eval(rho); } virtual void mapTo(Variable&, IdMap, Variable*>&) const { } virtual void print(std::ostream&) const = 0; }; template struct Constant : public Expression { Constant(const Domain& value) : _value(value) { } virtual Domain eval(const VariableAssignment&) const { return _value; } void print(std::ostream& cout) const { cout << _value; } private: Domain _value; }; template struct Variable : public Expression { Variable(const unsigned int& id, const std::string& name) : _id(id), _name(name) { } unsigned int id() const { return _id; } std::string name() const { return _name; } virtual Domain eval(const VariableAssignment& rho) const { return rho[*this]; } void print(std::ostream& cout) const { cout << _name; } private: const unsigned int _id; const std::string _name; }; template struct OperatorExpression : public Expression { OperatorExpression(const Operator& op, const std::vector*>& arguments) : _operator(op), _arguments(arguments) { } virtual Domain eval(const VariableAssignment& rho) const { std::vector argumentValues; for (typename std::vector*>::const_iterator it = _arguments.begin(); it != _arguments.end(); ++it) { argumentValues.push_back((*it)->eval(rho)); } return _operator.eval(argumentValues); } virtual Domain eval(const VariableAssignment& rho, const MaxStrategy& strat) const { std::vector argumentValues; for (typename std::vector*>::const_iterator it = _arguments.begin(); it != _arguments.end(); ++it) { argumentValues.push_back((*it)->eval(rho, strat)); } return _operator.eval(argumentValues); } std::vector*>& arguments() { return _arguments; } const std::vector*>& arguments() const { return _arguments; } const Operator& op() const { return _operator; } virtual void mapTo(Variable& v, IdMap, Variable*>& m) const { for (unsigned int i = 0, length = _arguments.size(); i < length; ++i) { _arguments[i]->mapTo(v, m); } } void print(std::ostream& cout) const { cout << _operator << "("; for (unsigned int i = 0, length = _arguments.size(); i < length; ++i) { if (i > 0) cout << ", "; cout << *_arguments[i]; } cout << ")"; } private: const Operator& _operator; protected: std::vector*> _arguments; }; template struct MaxExpression : public OperatorExpression { MaxExpression(const unsigned int& id, const Maximum& op, const std::vector*>& arguments) : OperatorExpression(op, arguments), _id(id) { } MaxExpression* toMaxExpression() { return this; } const MaxExpression* toMaxExpression() const { return this; } virtual Domain eval(const VariableAssignment& rho, const MaxStrategy& strat) const { return this->_arguments[strat.get(*this)]->eval(rho, strat); } unsigned int bestStrategy(const VariableAssignment& rho, const MaxStrategy& strat) const { Domain bestValue = this->eval(rho, strat); unsigned int bestIndex = strat.get(*this); for (unsigned int i = 0, length = this->_arguments.size(); i < length; ++i) { const Domain value = this->_arguments[i]->eval(rho, strat); if (bestValue < value) { bestValue = value; bestIndex = i; } } return bestIndex; } virtual void mapTo(Variable& v, IdMap, Variable*>& m) const { m[*this] = &v; for (unsigned int i = 0, length = this->_arguments.size(); i < length; ++i) { this->_arguments[i]->mapTo(v, m); } } unsigned int id() const { return _id; } private: const unsigned int _id; }; template std::ostream& operator<<(std::ostream& cout, const Expression& exp) { exp.print(cout); return cout; } #include "VariableAssignment.hpp" #endif