#ifndef EQUATION_SYSTEM_HPP #define EQUATION_SYSTEM_HPP #include #include #include #include "Operator.hpp" #include "Expression.hpp" #include "VariableAssignment.hpp" #include "IdMap.hpp" template struct MaxStrategy; template struct EquationSystem { EquationSystem() : _expr_to_var(NULL) { } virtual ~EquationSystem() { for (typename std::set*>::iterator it = _expressions.begin(); it != _expressions.end(); ++it) { delete *it; } for (typename std::set*>::iterator it = _operators.begin(); it != _operators.end(); ++it) { delete *it; } delete _expr_to_var; } MaxExpression& maxExpression(const std::vector*>& arguments) { unsigned int id = _max_expressions.size(); Maximum* max = new Maximum(); MaxExpression* expr = new MaxExpression(id, *max, arguments); _operators.insert(max); _max_expressions.push_back(expr); _expressions.insert(expr); return *expr; } MaxExpression& maxExpression(unsigned int i) const { return *_max_expressions[i]; } unsigned int maxExpressionCount() const { return _max_expressions.size(); } Expression& expression(Operator* op, const std::vector*>& arguments) { Expression* expr = new OperatorExpression(*op, arguments); _operators.insert(op); _expressions.insert(expr); return *expr; } Variable& variable(const std::string& name) { if (_variable_names.find(name) == _variable_names.end()) { // not found - create a new variable and whatnot unsigned int id = _variables.size(); Variable* var = new Variable(id, name); _variables.push_back(var); _right_sides.push_back(NULL); _expressions.insert(var); _variable_names[name] = var; return *var; } else { return *_variable_names[name]; } } Variable& variable(unsigned int id) const { return *_variables[id]; } unsigned int variableCount() const { return _variables.size(); } Constant& constant(const Domain& value) { Constant* constant = new Constant(value); _expressions.insert(constant); return *constant; } MaxExpression* operator[](const Variable& var) const { return _right_sides[var.id()]; } MaxExpression*& operator[](const Variable& var) { return _right_sides[var.id()]; } void indexMaxExpressions() { _expr_to_var = new IdMap,Variable*>(maxExpressionCount(), NULL); for (unsigned int i = 0, length = _right_sides.size(); i < length; ++i) { _right_sides[i]->mapTo(*_variables[i], *_expr_to_var); } } Variable* varFromExpr(const Expression& expr) const { if (_expr_to_var) { // we've indexed: const MaxExpression* maxExpr = dynamic_cast*>(&expr); if (maxExpr) { return (*_expr_to_var)[*maxExpr]; } else { return NULL; } } else { std::cout << "throw exception" << *(char*)NULL; return NULL; //throw "Must index max expressions before attempting lookup"; } } virtual bool equalAssignments(const VariableAssignment& l, const VariableAssignment& r) const { for (unsigned int i = 0, length = _variables.size(); i < length; ++i) { const Variable& var = *_variables[i]; if (l[var] != r[var]) return false; } return true; } void print(std::ostream& cout) const { for (unsigned int i = 0, length = _variables.size(); i < length; ++i) { cout << *_variables[i] << " = " << *_right_sides[i] << std::endl; } } private: std::set*> _operators; std::set*> _expressions; std::vector*> _variables; std::map*> _variable_names; IdMap, Variable*>* _expr_to_var; std::vector*> _max_expressions; std::vector*> _right_sides; }; template std::ostream& operator<<(std::ostream& cout, const EquationSystem& system) { system.print(cout); return cout; } #include "MaxStrategy.hpp" #endif