diff options
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r-- | impl/MaxStrategy.hpp | 158 |
1 files changed, 88 insertions, 70 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index 3ed7972..d908c7b 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -9,10 +9,7 @@ template<typename Domain> struct MaxStrategy { virtual ~MaxStrategy() { } - virtual unsigned int get(const MaxExpression<Domain>& e) const = 0; - virtual unsigned int get(const MaxExpression<Domain>& e) { - return const_cast<const MaxStrategy*>(this)->get(e); - } + virtual unsigned int get(const MaxExpression<Domain>& e) = 0; }; unsigned int stack_depth = 1; @@ -34,24 +31,31 @@ template<typename Domain> struct DynamicMaxStrategy : public MaxStrategy<Domain> { DynamicMaxStrategy( const EquationSystem<Domain>& system - ) : _frozen(false), - _system(system), + ) : _system(system), _rho(NULL), _values(system.maxExpressionCount(), 0), _stable(system.maxExpressionCount()), _influence(system.maxExpressionCount(), IdSet<MaxExpression<Domain> >(system.maxExpressionCount())), _var_influence(system.variableCount(), - IdSet<MaxExpression<Domain> >(system.maxExpressionCount())) + IdSet<MaxExpression<Domain> >(system.maxExpressionCount())), + _frozen(false) {} - void setRho(DynamicVariableAssignment<Domain>& rho) { - _rho = ρ + void freeze() { + _frozen = true; } - unsigned int get(const MaxExpression<Domain>& e) const { - // slightly hacky - return const_cast<DynamicMaxStrategy<Domain>*>(this)->get(e); + void thaw() { + _frozen = false; + } + + bool is_frozen() { + return _frozen; + } + + void setRho(DynamicVariableAssignment<Domain>& rho) { + _rho = ρ } unsigned int get(const MaxExpression<Domain>& e) { @@ -61,20 +65,18 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> { } void invalidate(const Variable<Domain>& v) { - log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl; - if (_system[v] && _stable.contains(*_system[v])) { - _stable.remove(*_system[v]); - _stable.filter(_var_influence[v]); - - IdSet<MaxExpression<Domain> > infl = _var_influence[v]; - _var_influence[v].clear(); - for (typename IdSet<MaxExpression<Domain> >::iterator - it = infl.begin(), - end = infl.end(); - it != end; - ++it) { - solve(_system.maxExpression(*it)); - } + log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl; + _stable.filter(_var_influence[v]); + + IdSet<MaxExpression<Domain> > infl = _var_influence[v]; + _var_influence[v].clear(); + + for (typename IdSet<MaxExpression<Domain> >::iterator + it = infl.begin(), + end = infl.end(); + it != end; + ++it) { + solve(_system.maxExpression(*it)); } } @@ -84,13 +86,13 @@ private: _stable.insert(x); log::strategy << indent() << "Stabilise " << x << std::endl; - stack_depth++; - unsigned int val = x.bestStrategy(DependencyAssignment(*this, *_rho, x), - DependencyStrategy(*this, x)); + stack_depth++; + DependencyAssignment assignment(*this, *_rho, x); + DependencyStrategy depStrat(*this, x); + unsigned int val = x.bestStrategy(assignment, depStrat); stack_depth--; if (val != _values[x]) { - log::strategy << x << " => " << *x.arguments()[val] << std::endl; IdSet<MaxExpression<Domain> > oldInfluence = _influence[x]; @@ -99,6 +101,12 @@ private: _rho->invalidate(*_system.varFromExpr(x)); + _rho->thaw(); + this->freeze(); + _rho->stabilise(); + _rho->freeze(); + this->thaw(); + _stable.filter(oldInfluence); for (typename IdSet<MaxExpression<Domain> >::iterator @@ -118,56 +126,31 @@ private: } } - const DynamicMaxStrategy& freeze() const { - _frozen = true; - return *this; - } - - const DynamicMaxStrategy& thaw() const { - _frozen = false; - return *this; - } - struct DependencyAssignment : public VariableAssignment<Domain>{ DependencyAssignment(DynamicMaxStrategy& strat, VariableAssignment<Domain>& rho, const MaxExpression<Domain>& expr) : _strat(strat), _rho(rho), - _expr(expr) { + _expr(expr), + _current(strat._system.variableCount()) { } - const Domain& operator[](const Variable<Domain>& var) const { + const Domain operator[](const Variable<Domain>& var) { _strat._var_influence[var].insert(_expr); - return _rho[var]; + if (_current.contains(var)) { + return _rho[var]; + } else { + _current.insert(var); + Domain val = _strat._system[var]->eval(_rho, _strat); + _current.remove(var); + return val; + } } private: DynamicMaxStrategy& _strat; VariableAssignment<Domain>& _rho; const MaxExpression<Domain>& _expr; - }; - - struct InvalidatingAssignment : public VariableAssignment<Domain>{ - InvalidatingAssignment(DynamicVariableAssignment<Domain>& rho) - : _rho(rho) { - } - ~InvalidatingAssignment() { - for (typename std::set<const Variable<Domain>*>::iterator - it = seen.begin(), - ei = seen.end(); - it != ei; - ++it) { - if (!_old_stable.contains(**it)) - _rho.invalidate(**it); - } - } - const Domain& operator[](const Variable<Domain>& var) const { - seen.insert(&var); - return _rho[var]; - } - private: - DynamicVariableAssignment<Domain>& _rho; - IdSet<Variable<Domain> > _old_stable; - mutable std::set<const Variable<Domain>*> seen; + IdSet<Variable<Domain> > _current; }; struct DependencyStrategy : public MaxStrategy<Domain> { @@ -175,7 +158,7 @@ private: : _strat(strat), _expr(expr) { } - unsigned int get(const MaxExpression<Domain>& e) const { + unsigned int get(const MaxExpression<Domain>& e) { _strat.solve(e); if (&_expr != &e) { _strat._influence[e].insert(_expr); @@ -187,14 +170,49 @@ private: const MaxExpression<Domain>& _expr; }; -private: - mutable bool _frozen; +private: const EquationSystem<Domain>& _system; DynamicVariableAssignment<Domain>* _rho; IdMap<MaxExpression<Domain>,unsigned int> _values; IdSet<MaxExpression<Domain> > _stable; IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > > _influence; IdMap<Variable<Domain>,IdSet<MaxExpression<Domain> > > _var_influence; + bool _frozen; +}; + + +template<typename Domain> +struct Solver { + Solver(const EquationSystem<Domain>& system) + : _system(system), + _strategy(system), + _rho(_system, _strategy, -infinity<Domain>()) { + _strategy.setRho(_rho); + } + + Domain solve(Variable<Domain>& var) { + MaxExpression<Domain>& rhs = *_system[var]; + + do { + _rho.has_changed(false); + + // improve strategy + _rho.freeze(); + _strategy.thaw(); + _strategy.get(rhs); + + // iterate fixpoint + _strategy.freeze(); + _rho.thaw(); + _rho.stabilise(); + } while (_rho.has_changed()); + + return _rho[var]; + } +private: + const EquationSystem<Domain>& _system; + DynamicMaxStrategy<Domain> _strategy; + DynamicVariableAssignment<Domain> _rho; }; |