#ifndef EQUATION_SYSTEM_HPP #define EQUATION_SYSTEM_HPP #include #include "Expression.hpp" template struct MaxStrategy; template struct EquationSystem { virtual ~EquationSystem() { for (int i = 0, size = _expressions.size(); i < size; ++i) { delete _expressions[i]; } for (int i = 0, size = _vars.size(); i < size; ++i) { delete _vars[i]; } } Variable* newVariable(const std::string& name) { typename std::map*>::iterator it = _var_names.find(name); if (it == _var_names.end()) { Variable* newVar = new Variable(_vars.size(), name); _vars.push_back(newVar); _var_names[name] = newVar; return _vars[_vars.size()-1]; } else { return it->second; } } const std::vector*> vars() const { return _vars; } unsigned int varCount() const { return _vars.size(); } Expression* newExpression(Operator* op, const std::vector*>& args) { Expression* expr = new Expression(op, args); _expressions.push_back(expr); return expr; } MaxExpression* newMaxExpression(const std::vector*>& args) { MaxExpression* expr = new MaxExpression(args); expr->id(_max_expressions.size()); _max_expressions.push_back(expr); _expressions.push_back(expr); return expr; } unsigned int maxCount() const { return _max_expressions.count(); } const MaxExpression* getMax(unsigned int i) const { return _max_expressions[i]; } MaxStrategy strategy() const { return MaxStrategy(_max_expressions.size()); } VariableAssignment assignment() const { return VariableAssignment(_vars.size()); } Expression*& operator[] (const Variable& v) { if (_right_expressions.size() <= v.id()) { _right_expressions.resize(v.id()+1); } return _right_expressions[v.id()]; } const Expression*& operator[] (const Variable& v) const { if (_right_expressions.size() <= v.id()) { throw "Out of range"; } return _right_expressions[v.id()]; } template VariableAssignment foreach(F op, const VariableAssignment& rho) const { VariableAssignment result(_vars.size()); for (unsigned int i = 0, size = _vars.size(); i < size; ++i) { result[*_vars[i]] = op(*_right_expressions[i], rho); } return result; } VariableAssignment operator() (const VariableAssignment& rho) const { VariableAssignment result(_vars.size()); for (unsigned int i = 0, size = _vars.size(); i < size; ++i) { result[*_vars[i]] = (*_right_expressions[i])(rho); } return result; } VariableAssignment maxFixpoint() const { unsigned int size = _vars.size(); VariableAssignment result(size, infinity()); for (unsigned int i = 0; i < size; ++i) { result = (*this)(result); } result = result.expand((*this)(result), -infinity()); for (unsigned int i = 0; i < size-1; ++i) { result = (*this)(result); } return result; } VariableAssignment maxFixpoint(const MaxStrategy& strat) const { unsigned int size = _vars.size(); VariableAssignment result(size, infinity()); for (unsigned int i = 0; i < size; ++i) { result = strat(*this, result); } result = result.expand(strat(*this, result), -infinity()); for (unsigned int i = 0; i < size-1; ++i) { result = strat(*this, result); } return result; } VariableAssignment minFixpoint() const { VariableAssignment rho = assignment(); VariableAssignment lastRho = assignment(); MaxStrategy strat = strategy(); do { lastRho = rho; strat = strat.improve(*this, rho); rho = maxFixpoint(strat); } while(lastRho != rho); return rho; } private: std::map*> _var_names; std::vector*> _vars; std::vector*> _max_expressions; std::vector*> _expressions; std::vector*> _right_expressions; }; #include "MaxStrategy.hpp" #endif