#ifndef EXPRESSION_H #define EXPRESSION_H #include #include #include #include template struct Expression; #include "Operator.hpp" template struct Maximum : public Operator { const T eval(const std::vector >& v, const std::map& m) const { //assert(v.size() == 1); T value = -INFINITY; for (typename std::vector >::const_iterator it = v.begin(); it != v.end(); ++it) { const T result = it->eval(m); value = (value < result ? result : value); } return value; } virtual std::string output() const { return "max"; } }; template struct Minimum : public Operator { const T eval(const std::vector >& v, const std::map& m) const { //assert(v.size() == 1); T value = INFINITY; for (typename std::vector >::const_iterator it = v.begin(); it != v.end(); ++it) { const T result = it->eval(m); value = (value < result ? value : result); } return value; } virtual std::string output() const { return "min"; } }; template struct Expression { Expression(unsigned int id, Operator* o, const std::vector< Expression >& a) : _id(id), _operator(o), _arguments(a) { } virtual const T eval(std::map m) const { return _operator->eval(_arguments, m); } virtual Expression maxStrategyEager(const std::map assignment) const { if (dynamic_cast*>(_operator) != NULL) { T bestVal; const Expression* best = NULL; for (typename std::vector >::const_iterator it = _arguments.begin(); it != _arguments.end(); ++it) { T nextVal = it->eval(assignment); if (best == NULL || nextVal > bestVal) { best = &(*it); bestVal = nextVal; } } return best->maxStrategyEager(assignment); } std::vector > newArgs; for (typename std::vector >::const_iterator it = _arguments.begin(); it != _arguments.end(); ++it) { newArgs.push_back(it->maxStrategyEager(assignment)); } return Expression(_operator, newArgs); } std::string output() const { std::string result = _operator->output() + "("; for (typename std::vector >::const_iterator it = _arguments.begin(); it != _arguments.end(); ++it) { if (it != _arguments.begin()) { result += ", "; } result += it->output(); } return result + ")"; } virtual ~Expression() {} private: unsigned int _id; Operator* _operator; std::vector< Expression > _arguments; template friend std::ostream& operator<<(std::ostream&, const Expression&); }; template std::ostream& operator<<(std::ostream& cout, const Expression& e) { cout << e._operator->output() << "(" << ")"; return cout; } #endif