From 86ca7448849aaaea6db34b1d2bcf8d99d7d7b12c Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Mon, 22 Oct 2012 14:44:57 +1100 Subject: Okay, the solver is now correct. It runs in two separate passes: - improve strategy (for all) - evaluate fixpoint Unfortunately this loses out on locality at the moment. I really want a local solver, so I'll have to see what I can do about that. --- impl/MaxStrategy.hpp | 89 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 15 deletions(-) (limited to 'impl/MaxStrategy.hpp') diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index 96aeef4..f4026dd 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -10,6 +10,9 @@ template struct MaxStrategy { virtual ~MaxStrategy() { } virtual unsigned int get(const MaxExpression& e) const = 0; + virtual unsigned int get(const MaxExpression& e) { + return const_cast(this)->get(e); + } }; unsigned int stack_depth = 1; @@ -38,20 +41,38 @@ struct DynamicMaxStrategy : public MaxStrategy { _influence(system.maxExpressionCount(), IdSet >(system.maxExpressionCount())), _var_influence(system.variableCount(), - IdSet >(system.maxExpressionCount())) + IdSet >(system.maxExpressionCount())), + _frozen(false) {} + void freeze() { + _frozen = true; + } + + void thaw() { + _frozen = false; + } + + bool is_frozen() { + return _frozen; + } + void setRho(DynamicVariableAssignment& rho) { _rho = ρ } unsigned int get(const MaxExpression& e) const { - solve(e); return _values[e]; } - void invalidate(const Variable& v) const { - log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl; + unsigned int get(const MaxExpression& e) { + if (!_frozen) + solve(e); + return _values[e]; + } + + void invalidate(const Variable& v) { + log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl; _stable.filter(_var_influence[v]); IdSet > infl = _var_influence[v]; @@ -67,7 +88,7 @@ struct DynamicMaxStrategy : public MaxStrategy { } private: - void solve(const MaxExpression& x) const { + void solve(const MaxExpression& x) { if (!_stable.contains(x)) { _stable.insert(x); log::strategy << indent() << "Stabilise " << x << std::endl; @@ -106,7 +127,7 @@ private: } struct DependencyAssignment : public VariableAssignment{ - DependencyAssignment(const DynamicMaxStrategy& strat, + DependencyAssignment(DynamicMaxStrategy& strat, VariableAssignment& rho, const MaxExpression& expr) : _strat(strat), @@ -118,13 +139,13 @@ private: return _rho[var]; } private: - const DynamicMaxStrategy& _strat; + DynamicMaxStrategy& _strat; VariableAssignment& _rho; const MaxExpression& _expr; }; struct DependencyStrategy : public MaxStrategy { - DependencyStrategy(const DynamicMaxStrategy& strat, const MaxExpression& expr) + DependencyStrategy(DynamicMaxStrategy& strat, const MaxExpression& expr) : _strat(strat), _expr(expr) { } @@ -136,19 +157,57 @@ private: return _strat._values[e]; } private: - const DynamicMaxStrategy& _strat; + DynamicMaxStrategy& _strat; const MaxExpression& _expr; }; -private: +private: const EquationSystem& _system; - mutable DynamicVariableAssignment* _rho; - mutable IdMap,unsigned int> _values; - mutable IdSet > _stable; - mutable IdMap,IdSet > > _influence; - mutable IdMap,IdSet > > _var_influence; + DynamicVariableAssignment* _rho; + IdMap,unsigned int> _values; + IdSet > _stable; + IdMap,IdSet > > _influence; + IdMap,IdSet > > _var_influence; + bool _frozen; }; + +template +IdMap,T> solve_for(const EquationSystem& system) { + IdMap,T> result(system.variableCount(), infinity()); + + DynamicMaxStrategy strategy(system); + DynamicVariableAssignment rho(system, strategy, -infinity()); + strategy.setRho(rho); + + bool changed; + do { + changed = false; + + // improve strategy + rho.freeze(); + strategy.thaw(); + for (unsigned int i = 0; i < system.variableCount(); ++i) { + strategy.get(*system[system.variable(i)]); + } + + // iterate fixpoint + strategy.freeze(); + rho.thaw(); + for (unsigned int i = 0; i < system.variableCount(); ++i) { + Variable& var = system.variable(i); + T val = rho[var]; + if (result[var] != val) { + result[var] = val; + changed = true; + } + } + } while(changed); + + return result; +} + + /*template std::ostream& operator<<(std::ostream& cout, const MaxStrategy& strat) { strat.print(cout); -- cgit v1.2.3