#ifndef IMPROVEMENT_OPERATOR_HPP #define IMPROVEMENT_OPERATOR_HPP #include "IdSet.hpp" #include "MaxStrategy.hpp" template struct ImprovementOperator { virtual ~ImprovementOperator() { } virtual bool improve( EquationSystem& system, ConcreteMaxStrategy& strat, StableVariableAssignment& rho, IdSet >& changedIn, IdSet >& changedOut ) const = 0; }; template struct NaiveImprovementOperator : public ImprovementOperator { bool improve( EquationSystem& system, ConcreteMaxStrategy& strat, StableVariableAssignment& rho, IdSet >&, IdSet >& ) const { bool changed = false; for (unsigned int i = 0, length = system.maxExpressionCount(); i < length; ++i) { MaxExpression& expr = system.maxExpression(i); // this relies on the fact that an expression will only be proessed after the expressions // it depends on (which should always be true, as they form a DAG) unsigned int index = expr.bestStrategy(rho, strat); if (index != strat.get(expr)) { changed = true; strat.set(expr, index); } } //log::strategy << strat << std::endl; return changed; } }; template struct RepeatedImprovementOperator : public ImprovementOperator { RepeatedImprovementOperator(const ImprovementOperator& op) : _subImprovement(op) { } bool improve( EquationSystem& system, ConcreteMaxStrategy& strat, StableVariableAssignment& rho, IdSet >& changedIn, IdSet >& changedOut ) const { if (_subImprovement.improve(system, strat, rho, changedIn, changedOut)) { StableVariableAssignment* rho2 = system.eval(rho, strat); improve(system, strat, *rho2, changedIn, changedOut); delete rho2; return true; } return false; } private: const ImprovementOperator& _subImprovement; }; #include "VariableAssignment.hpp" template struct DynamicMaxStrategy : public MaxStrategy { DynamicMaxStrategy( const EquationSystem& system ) : _system(system), _rho(NULL), _values(system), _stable(system.maxExpressionCount()), _influence(system.maxExpressionCount(), IdSet>(system.maxExpressionCount())), _var_influence(system.variableCount(), IdSet>(system.maxExpressionCount())) {} void setRho(DynamicVariableAssignment& rho) { _rho = ρ } unsigned int get(const MaxExpression& e) const { solve(e); return _values.get(e); } void invalidate(const Variable& v) const { log::strategy << "invalidating " << v << " - " << *_system[v] << std::endl; log::strategy << "\t" << _var_influence[v] << std::endl; _stable.filter(_var_influence[v]); for (auto it = _var_influence[v].begin(); it != _var_influence[v].end(); ++it) { solve(_system.maxExpression(*it)); } } private: void solve(const MaxExpression& x) const { if (!_stable.contains(x)) { _stable.insert(x); unsigned int val = x.bestStrategy(DependencyAssignment(*this, *_rho, x), DependencyStrategy(*this, x)); if (val != _values.get(x)) { log::strategy << "Updating strategy for " << x << " to " << val << std::endl; auto oldInfluence = _influence[x]; _influence[x].clear(); _values.set(x, val); _rho->invalidate(*_system.varFromExpr(x)); _stable.filter(oldInfluence); for (auto it = oldInfluence.begin(); it != oldInfluence.end(); ++it) { solve(_system.maxExpression(*it)); } } else { log::strategy << x << " did not change" << std::endl; } } else { log::strategy << x << " is stable" << std::endl; } } struct DependencyAssignment : public VariableAssignment{ DependencyAssignment(const DynamicMaxStrategy& strat, VariableAssignment& rho, const MaxExpression& expr) : _strat(strat), _rho(rho), _expr(expr) { } const Domain& operator[](const Variable& var) const { _strat._var_influence[var].insert(_expr); return _rho[var]; } private: const DynamicMaxStrategy& _strat; VariableAssignment& _rho; const MaxExpression& _expr; }; struct DependencyStrategy : public MaxStrategy { DependencyStrategy(const DynamicMaxStrategy& strat, const MaxExpression& expr) : _strat(strat), _expr(expr) { } unsigned int get(const MaxExpression& e) const { _strat.solve(e); if (&_expr != &e) { _strat._influence[e].insert(_expr); } return _strat._values.get(e); } private: const DynamicMaxStrategy& _strat; const MaxExpression& _expr; }; private: const EquationSystem& _system; mutable DynamicVariableAssignment* _rho; mutable ConcreteMaxStrategy _values; mutable IdSet> _stable; mutable IdMap,IdSet>> _influence; mutable IdMap,IdSet>> _var_influence; }; #endif