diff options
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r-- | impl/MaxStrategy.hpp | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index d908c7b..5534597 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -9,7 +9,10 @@ template<typename Domain> struct MaxStrategy { virtual ~MaxStrategy() { } - virtual unsigned int get(const MaxExpression<Domain>& e) = 0; + virtual unsigned int get(const MaxExpression<Domain>& e) { + return const_cast<const MaxStrategy<Domain>*>(this)->get(e); + } + virtual unsigned int get(const MaxExpression<Domain>& e) const = 0; }; unsigned int stack_depth = 1; @@ -39,44 +42,60 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> { IdSet<MaxExpression<Domain> >(system.maxExpressionCount())), _var_influence(system.variableCount(), IdSet<MaxExpression<Domain> >(system.maxExpressionCount())), - _frozen(false) + _changed(false) {} - void freeze() { - _frozen = true; + void setRho(DynamicVariableAssignment<Domain>& rho) { + _rho = ρ } - void thaw() { - _frozen = false; + void hasChanged(bool c) { + _changed = c; } - bool is_frozen() { - return _frozen; + bool hasChanged() const { + return _changed; } - void setRho(DynamicVariableAssignment<Domain>& rho) { - _rho = ρ + unsigned int get(const MaxExpression<Domain>& e) const { + log::strategy << indent() << "Look up " << e << std::endl; + return _values[e]; } unsigned int get(const MaxExpression<Domain>& e) { - if (!_frozen) - solve(e); + log::strategy << indent() << "Solve for " << e << std::endl; + solve(e); return _values[e]; } void invalidate(const Variable<Domain>& v) { log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl; - _stable.filter(_var_influence[v]); + //log::debug << indent() << " var-influence sets " << _var_influence << std::endl; 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)); + invalidate(_system.maxExpression(*it)); + } + } + + void invalidate(const MaxExpression<Domain>& v) { + if (_stable.contains(v)) { + log::strategy << indent() << "Invalidating " << v << std::endl; + //log::debug << indent() << " influence sets " << _influence << std::endl; + _stable.remove(v); + + IdSet<MaxExpression<Domain> > infl = _influence[v]; + for (typename IdSet<MaxExpression<Domain> >::iterator + it = infl.begin(), + end = infl.end(); + it != end; + ++it) { + invalidate(_system.maxExpression(*it)); + } } } @@ -96,16 +115,13 @@ private: log::strategy << x << " => " << *x.arguments()[val] << std::endl; IdSet<MaxExpression<Domain> > oldInfluence = _influence[x]; - _influence[x].clear(); + //_influence[x].clear(); _values[x] = val; + _changed = true; _rho->invalidate(*_system.varFromExpr(x)); - - _rho->thaw(); - this->freeze(); - _rho->stabilise(); - _rho->freeze(); - this->thaw(); + + //_rho->stabilise(); _stable.filter(oldInfluence); @@ -136,15 +152,11 @@ private: _current(strat._system.variableCount()) { } const Domain operator[](const Variable<Domain>& var) { + // solve the strategy for this variable, too + _strat.solve(*_strat._system[var]); _strat._var_influence[var].insert(_expr); - if (_current.contains(var)) { - return _rho[var]; - } else { - _current.insert(var); - Domain val = _strat._system[var]->eval(_rho, _strat); - _current.remove(var); - return val; - } + _strat._influence[*_strat._system[var]].insert(_expr); + return _rho[var]; } private: DynamicMaxStrategy& _strat; @@ -158,11 +170,13 @@ private: : _strat(strat), _expr(expr) { } + unsigned int get(const MaxExpression<Domain>& e) const { + _strat._influence[e].insert(_expr); + return _strat._values[e]; + } unsigned int get(const MaxExpression<Domain>& e) { _strat.solve(e); - if (&_expr != &e) { - _strat._influence[e].insert(_expr); - } + _strat._influence[e].insert(_expr); return _strat._values[e]; } private: @@ -177,7 +191,7 @@ private: IdSet<MaxExpression<Domain> > _stable; IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > > _influence; IdMap<Variable<Domain>,IdSet<MaxExpression<Domain> > > _var_influence; - bool _frozen; + bool _changed; }; @@ -193,19 +207,25 @@ struct Solver { Domain solve(Variable<Domain>& var) { MaxExpression<Domain>& rhs = *_system[var]; - do { - _rho.has_changed(false); + // _rho automatically keeps up to date with changes made to the + // strategy, so you don't need to stabilise it + + _strategy.get(rhs); - // improve strategy - _rho.freeze(); - _strategy.thaw(); - _strategy.get(rhs); - // iterate fixpoint - _strategy.freeze(); - _rho.thaw(); + /* + do { + _strategy.hasChanged(false); + + log::debug << "Stabilise assignment (toplevel)" << std::endl; _rho.stabilise(); - } while (_rho.has_changed()); + + log::debug << "Improve strategy (toplevel)" << std::endl; + // improve strategy + _strategy.get(rhs); + log::debug << (_strategy.hasChanged() ? "Strategy has changed - loop again" : "Strategy has not changed - terminate") << std::endl; + } while (_strategy.hasChanged()); + */ return _rho[var]; } |