From 2c22cee1f8fa87c527449a8bdc668ea311fdaf64 Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Fri, 27 Apr 2012 13:33:58 +1000 Subject: Bit more work. maxFixpoint should be working now. --- impl/EquationSystem.hpp | 79 +++++++++++++++++++++++++++++++++++++++++++++ impl/MaxStrategy.hpp | 5 +++ impl/Operator.hpp | 15 +++++++-- impl/Solver.hpp | 17 ++++++++++ impl/Variable.hpp | 9 +++--- impl/VariableAssignment.hpp | 44 +++++++++++++++++++++++-- impl/main.cpp | 33 +++++++++++-------- 7 files changed, 181 insertions(+), 21 deletions(-) create mode 100644 impl/EquationSystem.hpp create mode 100644 impl/Solver.hpp diff --git a/impl/EquationSystem.hpp b/impl/EquationSystem.hpp new file mode 100644 index 0000000..065a1a2 --- /dev/null +++ b/impl/EquationSystem.hpp @@ -0,0 +1,79 @@ +#ifndef EQUATION_SYSTEM_HPP +#define EQUATION_SYSTEM_HPP + +#include "Expression.hpp" + +template +struct EquationSystem { + EquationSystem () + : _max_id(0) { } + 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_id++); + return expr; + } + unsigned int maxCount() const { + return _max_id; + } + + 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& v) { + VariableAssignment result(_vars.size()); + for (unsigned int i = 0, size = _vars.size(); i < size; ++i) { + result[_vars[i]] = op(_expressions[i], v); + } + } + + VariableAssignment operator() (const VariableAssignment& rho) { + 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() { + 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; + } + private: + unsigned int _max_id; + std::vector*> _vars; + std::vector*> _expressions; +}; + + +#endif diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index a324359..7a37fb2 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -23,6 +23,9 @@ struct MaxStrategy { } return _assignment[x.id()]; } + T operator() (const EquationSystem& eqns, const VariableAssignment& rho) const { + return eqns.foreach((*this), rho); + } T operator() (const Expression& expr, const VariableAssignment& rho) const { const MaxExpression* max = dynamic_cast*>(&expr); if (max == NULL) { @@ -31,6 +34,8 @@ struct MaxStrategy { return (*expr.arguments()[_assignment[max->id()]])(rho); } } + MaxStrategy improve() { + } private: unsigned int _length; unsigned int* _assignment; diff --git a/impl/Operator.hpp b/impl/Operator.hpp index d6b92f2..3e11443 100644 --- a/impl/Operator.hpp +++ b/impl/Operator.hpp @@ -34,9 +34,9 @@ struct Maximum : public Operator { } }; template -struct Minimumm : public Operator { +struct Minimum : public Operator { virtual T operator() (const std::vector< Expression* >& args, const VariableAssignment& assignment) const { - T value = -infinity(); + T value = infinity(); for (typename std::vector< Expression* >::const_iterator it = args.begin(); it != args.end(); ++it) { @@ -47,6 +47,17 @@ struct Minimumm : public Operator { } }; +template +struct Constant : public Operator { + Constant(const T& val) + : _value(val) { } + T operator() (const std::vector< Expression* >& args, const VariableAssignment& ass) const { + return _value; + } + private: + const T _value; +}; + #include "VariableAssignment.hpp" #include "Expression.hpp" diff --git a/impl/Solver.hpp b/impl/Solver.hpp new file mode 100644 index 0000000..11369bc --- /dev/null +++ b/impl/Solver.hpp @@ -0,0 +1,17 @@ +#ifndef SOLVER_HPP +#define SOLVER_HPP + +#include "Factory.hpp" +#include "VariableAssignment.hpp" + +template +struct Solver { + VariableAssignment solveBF(const EquationSystem& system) { + VariableAssignment result; + for (unsigned int i = 0; i < _var_count; ++i) { + result = system(result); + } + } +}; + +#endif diff --git a/impl/Variable.hpp b/impl/Variable.hpp index 0ba13e9..2386e7a 100644 --- a/impl/Variable.hpp +++ b/impl/Variable.hpp @@ -5,18 +5,19 @@ template struct Variable : public Operator { + Variable(unsigned int id) + : _id(id) { } + Variable(const Variable& other) + : _id(other._id) { } unsigned int id() const { return _id; } - unsigned int id(unsigned int id) { - return (_id = id); - } T operator() (const std::vector< Expression* >& args, const VariableAssignment& ass) const { //assert(args.size() == 0) return ass[*this]; } private: - unsigned int _id; + const unsigned int _id; }; #endif diff --git a/impl/VariableAssignment.hpp b/impl/VariableAssignment.hpp index e41f3d8..a2d0afd 100644 --- a/impl/VariableAssignment.hpp +++ b/impl/VariableAssignment.hpp @@ -6,11 +6,36 @@ template struct VariableAssignment { VariableAssignment(unsigned int length) - : _length(length), _assignment(new T[length]) { } + : _length(length), _assignment(new T[length]) { + for (unsigned int i = 0; i < _length; ++i) { + _assignment[i] = -infinity(); + } + } + VariableAssignment(unsigned int length, const T& initial) + : _length(length), _assignment(new T[length]) { + for (unsigned int i = 0; i < _length; ++i) { + _assignment[i] = initial; + } + } + VariableAssignment(const VariableAssignment& other) + : _length(other._length), _assignment(new T[other._length]) { + for (unsigned int i = 0; i < _length; ++i) { + _assignment[i] = other._assignment[i]; + } + } ~VariableAssignment() { delete[] _assignment; } - const T& operator[] (const Variable x) const { + VariableAssignment& operator=(const VariableAssignment& other) { + delete[] _assignment; + _length = other._length; + _assignment = new T[_length]; + for (unsigned int i = 0; i < _length; ++i) { + _assignment[i] = other._assignment[i]; + } + return *this; + } + const T& operator[] (const Variable& x) const { if (x.id() < 0 || x.id() >= _length) { throw "Array out of bounds"; } @@ -22,6 +47,21 @@ struct VariableAssignment { } return _assignment[x.id()]; } + + VariableAssignment expand(const VariableAssignment& other) { + return expand(other, infinity()); + } + VariableAssignment expand(const VariableAssignment& other, const T& value) { + VariableAssignment expansion(_length); + for (unsigned int i = 0; i < _length; ++i) { + if (_assignment[i] == other._assignment[i]) { + expansion._assignment[i] = _assignment[i]; + } else { + expansion._assignment[i] = value; + } + } + return expansion; + } private: unsigned int _length; T* _assignment; diff --git a/impl/main.cpp b/impl/main.cpp index 589a1e7..6f84cdd 100644 --- a/impl/main.cpp +++ b/impl/main.cpp @@ -4,6 +4,7 @@ #include "Operator.hpp" #include "Expression.hpp" +#include "EquationSystem.hpp" #include "MaxStrategy.hpp" using namespace std; @@ -19,22 +20,28 @@ struct Complete { std::vector< Expression* > empty; int main () { - Variable x; - x.id(0); - Variable y; - y.id(1); + EquationSystem fac; + Variable* x = fac.newVariable("x"); + Variable* y = fac.newVariable("y"); VariableAssignment rho(2); - rho[x] = 12; - rho[y] = 10; - Expression expr(&x, empty); + rho[*x] = 12; + rho[*y] = 10; + Expression expr(x, empty); std::vector*> args; - args.push_back(new Expression(&x, empty)); - args.push_back(new Expression(&y, empty)); - MaxExpression maxExpr(args); - maxExpr.id(0); + args.push_back(new Expression(x, empty)); + args.push_back(new Expression(y, empty)); + args.push_back(new Expression(new Constant(10), empty)); + MaxExpression* maxExpression = fac.newMaxExpression(args); + Expression* minExpression = new Expression(new Minimum(), args); + + MaxStrategy strat(1); - strat[maxExpr] = 0; - cout << strat(maxExpr,rho) << endl; + strat[*maxExpression] = 0; + cout << strat(*maxExpression,rho) << endl; + + fac[*x] = minExpression; + fac[*y] = minExpression; + cout << fac.maxFixpoint()[*x] << endl; return 0; } -- cgit v1.2.3