From 785d762d4f5d69e3c89855f68cb0654aace4608d Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Mon, 2 Jul 2012 17:44:17 +1000 Subject: Dependency-aware smart fixpoint. Slows it down *heaps* for the moment. Still need to add the MaxStrategy part, which should speed it up a fair bit. At the moment it has to do a fair bit more work for no benefit. --- impl/FixpointAlgorithm.hpp | 101 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 16 deletions(-) (limited to 'impl/FixpointAlgorithm.hpp') diff --git a/impl/FixpointAlgorithm.hpp b/impl/FixpointAlgorithm.hpp index b39a915..350047f 100644 --- a/impl/FixpointAlgorithm.hpp +++ b/impl/FixpointAlgorithm.hpp @@ -9,36 +9,64 @@ template struct FixpointAlgorithm { virtual ~FixpointAlgorithm() { } - virtual VariableAssignment* maxFixpoint(const EquationSystem&) const = 0; + virtual void maxFixpoint( + const EquationSystem& system, + StableVariableAssignment& rho, + IdSet >& changedIn, + IdSet >& changedOut + ) = 0; }; template struct NaiveFixpointAlgorithm : public FixpointAlgorithm { - virtual VariableAssignment* maxFixpoint(const EquationSystem& system) const { + NaiveFixpointAlgorithm(const EquationSystem& system) + : _system(system) { } + virtual void maxFixpoint( + const EquationSystem& system, + StableVariableAssignment& rhoOut, + IdSet >& changedIn, + IdSet >& changedOut + ) { VariableAssignment* rho = NULL; VariableAssignment* result = system.assignment(infinity()); do { if (rho) delete rho; rho = result; - result = system.eval(*rho); - } while (!system.equalAssignments(*rho, *result)); + result = _system.eval(*rho); + } while (!_system.equalAssignments(*rho, *result)); if (rho) delete rho; - return result; + + for (unsigned int i = 0, length = system.variableCount(); i < length; ++i) { + Variable var = system.variable(i); + rhoOut[var] = (*result)[var]; + } } + private: + const EquationSystem& _system; }; template struct SmartFixpointAlgorithm : public FixpointAlgorithm { + SmartFixpointAlgorithm(const EquationSystem& system) + : _system(system), + _influence(system.variableCount(), IdSet >(system.variableCount())){ + } + struct DynamicVariableAssignment : public VariableAssignment { - DynamicVariableAssignment(const EquationSystem& system) - : _system(system), - _values(system.variableCount(), infinity()), - _stable(system.variableCount()), - _influence(system.variableCount(), IdSet >(system.variableCount())) { } + DynamicVariableAssignment( + const EquationSystem& system, + IdMap,IdSet > >& influence, + StableVariableAssignment& rho, + IdSet >& stable, + IdSet >& changed + ) : _system(system), + _values(rho), + _stable(stable), + _changed(changed), + _influence(influence) { } const Domain& operator[](const Variable& var) const { solve(var); - //std::cout << _values << std::endl; return _values[var]; } @@ -54,6 +82,7 @@ struct SmartFixpointAlgorithm : public FixpointAlgorithm { IdSet > oldInfluence = _influence[x]; _influence[x].clear(); _values[x] = val; + _changed.insert(x); _stable.filter(oldInfluence); @@ -62,6 +91,7 @@ struct SmartFixpointAlgorithm : public FixpointAlgorithm { ++it) { solve(_system.variable(*it)); } + _influence[x] = oldInfluence; } } } @@ -80,14 +110,53 @@ struct SmartFixpointAlgorithm : public FixpointAlgorithm { }; const EquationSystem& _system; - mutable IdMap,Domain> _values; - mutable IdSet > _stable; - mutable IdMap,IdSet > > _influence; + StableVariableAssignment& _values; + IdSet >& _stable; + IdSet >& _changed; + IdMap,IdSet > >& _influence; }; - virtual VariableAssignment* maxFixpoint(const EquationSystem& system) const { - return new DynamicVariableAssignment(system); + void invalidate(const IdSet >& set, IdSet >& changed, StableVariableAssignment& rho) const { + for (typename IdSet >::iterator it = set.begin(), + end = set.end(); + it != end; + ++it) { + Variable& var = _system.variable(*it); + if (!changed.contains(var)) { + rho[var] = infinity(); + changed.insert(var); + invalidate(_influence[var], changed, rho); + } + } + } + + virtual void maxFixpoint( + const EquationSystem& system, + StableVariableAssignment& rhoOut, + IdSet >& changedIn, + IdSet >& changedOut + ) { + for (typename IdSet >::iterator it = changedIn.begin(), + end = changedIn.end(); + it != end; + ++it) { + //std::cout << *it << " "; + Variable& var = _system.variable(*it); + rhoOut[var] = infinity(); + invalidate(_influence[var], changedIn, rhoOut); + } + + changedIn.invert(); + DynamicVariableAssignment rho(system, _influence, rhoOut, changedIn, changedOut); + for (unsigned int i = 0, length = system.variableCount(); i < length; ++i) { + rho[system.variable(i)]; + } + /*std::cout << _influence << std::endl; + std::cout << std::endl;*/ } + private: + const EquationSystem& _system; + IdMap,IdSet > > _influence; }; #endif -- cgit v1.2.3