#ifndef FIXPOINT_ALGORITHM_HPP #define FIXPOINT_ALGORITHM_HPP #include "IdSet.hpp" #include "IdMap.hpp" #include "VariableAssignment.hpp" #include "EquationSystem.hpp" template struct FixpointAlgorithm { virtual ~FixpointAlgorithm() { } virtual VariableAssignment* maxFixpoint(const EquationSystem&) const = 0; }; template struct NaiveFixpointAlgorithm : public FixpointAlgorithm { virtual VariableAssignment* maxFixpoint(const EquationSystem& system) const { VariableAssignment* rho = NULL; VariableAssignment* result = system.assignment(infinity()); do { if (rho) delete rho; rho = result; result = system.eval(*rho); } while (!system.equalAssignments(*rho, *result)); if (rho) delete rho; return result; } }; template struct SmartFixpointAlgorithm : public FixpointAlgorithm { struct DynamicVariableAssignment : public VariableAssignment { DynamicVariableAssignment(const EquationSystem& system) : _system(system), _evaluating(NULL), _values(system.variableCount(), -infinity()), _stable(system.variableCount()), _haveValue(system.variableCount()), _influence(system.variableCount(), IdSet >(system.variableCount())), _id(0) { } const Domain& operator[](const Variable& var) const { _id++; solve(var); for (unsigned int i = 0; i < _id; ++i) { std::cout << " "; } std::cout << "operator[] " << var.name() << " => " << _values[var] << std::endl; _id--; if (_evaluating) { _influence[var].insert(*_evaluating); } return _values[var]; } private: void solve(const Variable& x) const { if (!_stable.contains(x)) { _stable.insert(x); for (unsigned int i = 0; i < _id; ++i) { std::cout << " "; } std::cout << "solve(" << x.name() << ") " << &x << " " << _evaluating << std::endl; std::cout << _stable << std::endl; const Variable* oldEval = _evaluating; _evaluating = &x; Domain val = _system[x]->eval(*this); _evaluating = oldEval; if (val != _values[x]) { IdSet > oldInfluence = _influence[x]; _influence[x].clear(); _values[x] = val; _stable.filter(oldInfluence); for (typename IdSet >::iterator it = oldInfluence.begin(); it != oldInfluence.end(); ++it) { solve(_system.variable(*it)); } } } } const EquationSystem& _system; mutable const Variable* _evaluating; mutable IdMap,Domain> _values; mutable IdSet > _stable; mutable IdSet > _haveValue; mutable IdMap,IdSet > > _influence; mutable unsigned int _id; }; virtual VariableAssignment* maxFixpoint(const EquationSystem& system) const { return new DynamicVariableAssignment(system); } }; #endif