#ifndef EQUATION_SYSTEM_HPP #define EQUATION_SYSTEM_HPP #include "Expression.hpp" template struct MaxStrategy; template struct EquationSystem { virtual ~EquationSystem() { for (int i = 0, size = _vars.size(); i < size; ++i) { delete _vars[i]; } } Variable* newVariable(const std::string&) { _vars.push_back(new Variable(_vars.size())); return _vars[_vars.size()-1]; } unsigned int varCount() const { return _vars.size(); } MaxExpression* newMaxExpression(const std::vector*>& args) { MaxExpression* expr = new MaxExpression(args); expr->id(_max_expressions.size()); _max_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 (_expressions.size() <= v.id()) { _expressions.resize(v.id()+1); } return _expressions[v.id()]; } const Expression*& operator[] (const Variable& v) const { if (_expressions.size() <= v.id()) { throw "Out of range"; } return _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(*_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]] = (*_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::vector*> _vars; std::vector*> _max_expressions; std::vector*> _expressions; }; #include "MaxStrategy.hpp" #endif