diff options
Diffstat (limited to 'impl/VariableAssignment.hpp')
-rw-r--r-- | impl/VariableAssignment.hpp | 95 |
1 files changed, 40 insertions, 55 deletions
diff --git a/impl/VariableAssignment.hpp b/impl/VariableAssignment.hpp index 19403a8..2e081e6 100644 --- a/impl/VariableAssignment.hpp +++ b/impl/VariableAssignment.hpp @@ -7,10 +7,7 @@ template<typename Domain> struct VariableAssignment { virtual ~VariableAssignment() { } - virtual const Domain& operator[](const Variable<Domain>&) const = 0; - virtual const Domain& operator[](const Variable<Domain>& x) { - return (*const_cast<const VariableAssignment*>(this))[x]; - } + virtual const Domain operator[](const Variable<Domain>& x) = 0; }; #include "EquationSystem.hpp" @@ -22,58 +19,44 @@ template<typename Domain> struct DynamicVariableAssignment : public VariableAssignment<Domain> { DynamicVariableAssignment( const EquationSystem<Domain>& system, - DynamicMaxStrategy<Domain>& strat + DynamicMaxStrategy<Domain>& strat, + const Domain& value=infinity<Domain>() ) : _system(system), _strategy(strat), - _values(system.variableCount(), unknown(infinity<Domain>())), - _stable(system.variableCount()), + _values(system.variableCount(), value), + _unstable(system.variableCount()), _influence(system.variableCount(), - IdSet<Variable<Domain> >(system.variableCount())), - _frozen(false) + IdSet<Variable<Domain> >(system.variableCount())) { } - void freeze() { - _frozen = true; - } - - void thaw() { - _frozen = false; - } - - bool is_frozen() { - return _frozen; - } - - const Domain& operator[](const Variable<Domain>& var) const { - // slightly hacky - return const_cast<DynamicVariableAssignment<Domain>&>(*this)[var]; + const Domain operator[](const Variable<Domain>& var) { + solve(var); + return _values[var]; } - const Domain& operator[](const Variable<Domain>& var) { - if (!_frozen) + /*void stabilise() { + if (!_unstable.empty()) { + Variable<Domain>& var = _system.variable(*_unstable.begin()); solve(var); - return _values[var]; - } + } + }*/ - void invalidate(const Variable<Domain>& x, bool also_solve=true) { - log::fixpoint << indent() << "Invalidating " << x << std::endl; - if (_stable.contains(x)) { - _stable.remove(x); - _values[x] = unknown(infinity<Domain>()); + void invalidate(const Variable<Domain>& x) { + if (!_unstable.contains(x)) { + log::fixpoint << indent() << "Invalidating " << x << std::endl; + + _unstable.insert(x); + _values[x] = infinity<Domain>(); IdSet<Variable<Domain> > infl = _influence[x]; + _influence[x].clear(); + for (typename IdSet<Variable<Domain> >::iterator - it = infl.begin(), - ei = infl.end(); - it != ei; - ++it) { - invalidate(_system.variable(*it), false); - } - - if (also_solve) { - solve(x); - if (_values[x] == infinity<Domain>()) - _values[x] = _values[x].asKnown(); + it = infl.begin(), + ei = infl.end(); + it != ei; + ++it) { + invalidate(_system.variable(*it)); } } } @@ -81,25 +64,28 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> { private: void solve(const Variable<Domain>& x) { - if (!_stable.contains(x)) { - _stable.insert(x); + if (_unstable.contains(x)) { + _unstable.remove(x); log::fixpoint << indent() << "Stabilise " << x << std::endl; stack_depth++; - Domain val = _system[x]->eval(DependencyAssignment(*this, x), - _strategy); + // we don't want the assignment to affect the strategy, so we're + // going to use a const reference here + const DynamicMaxStrategy<Domain>& const_strat = _strategy; + DependencyAssignment assignment(*this, x); + Domain val = _system[x]->eval(assignment, const_strat); stack_depth--; if (val != _values[x]) { log::fixpoint << x << " = " << val << std::endl; + + _strategy.invalidate(x); IdSet<Variable<Domain> > oldInfluence = _influence[x]; _influence[x].clear(); _values[x] = val; - _strategy.invalidate(x); - - _stable.filter(oldInfluence); + _unstable.absorb(oldInfluence); for (typename IdSet<Variable<Domain> >::iterator it = oldInfluence.begin(); it != oldInfluence.end(); @@ -119,8 +105,8 @@ private: struct DependencyAssignment : public VariableAssignment<Domain> { DependencyAssignment(DynamicVariableAssignment& assignment, const Variable<Domain>& var) : _assignment(assignment), _var(var) { } - const Domain& operator[](const Variable<Domain>& x) const { - const Domain& result = _assignment[x]; + const Domain operator[](const Variable<Domain>& x) { + const Domain result = _assignment[x]; _assignment._influence[x].insert(_var); return result; } @@ -132,9 +118,8 @@ private: const EquationSystem<Domain>& _system; DynamicMaxStrategy<Domain>& _strategy; IdMap<Variable<Domain>, Domain> _values; - IdSet<Variable<Domain> > _stable; + IdSet<Variable<Domain> > _unstable; IdMap<Variable<Domain>,IdSet<Variable<Domain> > > _influence; - bool _frozen; }; #endif |