diff options
| author | Carlo Zancanaro <carlo@carlo-laptop> | 2012-05-28 13:00:50 +1000 | 
|---|---|---|
| committer | Carlo Zancanaro <carlo@carlo-laptop> | 2012-05-28 13:00:50 +1000 | 
| commit | ea05c9c5fa30b8822f618e861d12a09df1f8f017 (patch) | |
| tree | cb8717d9773ef77978dc8e1d9093560e3cf26532 /impl/FixpointAlgorithm.hpp | |
| parent | ee8547cf3c89c51ff10603814e6f745466bc4c79 (diff) | |
Fix memory error and x = max(-inf, expr) stuff.
Diffstat (limited to 'impl/FixpointAlgorithm.hpp')
| -rw-r--r-- | impl/FixpointAlgorithm.hpp | 98 | 
1 files changed, 98 insertions, 0 deletions
diff --git a/impl/FixpointAlgorithm.hpp b/impl/FixpointAlgorithm.hpp new file mode 100644 index 0000000..ed97bec --- /dev/null +++ b/impl/FixpointAlgorithm.hpp @@ -0,0 +1,98 @@ +#ifndef FIXPOINT_ALGORITHM_HPP +#define FIXPOINT_ALGORITHM_HPP + +#include "VariableAssignment.hpp" + +template<typename T> +struct EquationSystem; +template<typename T> +struct MaxStrategy; + +template<typename T> +struct FixpointAlgorithm { +  virtual VariableAssignment<T> maxFixpoint(const MaxStrategy<T>&, const EquationSystem<T>&) const = 0; +}; + +#include "EquationSystem.hpp" +#include "MaxStrategy.hpp" + +template<typename T> +struct NaiveFixpoint : public FixpointAlgorithm<T> { +  virtual VariableAssignment<T> maxFixpoint(const MaxStrategy<T>& strat, const EquationSystem<T>& system) const { +    unsigned int size = system.varCount(); +    VariableAssignment<T> newResult(size, infinity<T>()); +    VariableAssignment<T> result(0); +    do { +      result = newResult; +      newResult = strat(system, result); +    } while (newResult != result); +    return result; +  } +}; + + +template<typename T> +struct RecursiveFixpoint : public FixpointAlgorithm<T> { +  // this is a "VariableAssignment" which actually performs a recursive +  // call to determine what value to return +  struct EvaluatingVariableAssignment : public VariableAssignment<T> { +    EvaluatingVariableAssignment(const MaxStrategy<T>& strategy, const EquationSystem<T>& system) +      : VariableAssignment<T>(system.varCount(), infinity<T>()), +        _strategy(strategy), _system(system), +        _evaluating(NULL), +        _influence(system.varCount(), IdSet<Variable<T> >(system.varCount())), +        _stable(system.varCount()) { +    } +    virtual T& operator[] (const Variable<T>& x) const { +      if (_evaluating == NULL) { +        solve(x); +        return VariableAssignment<T>::_assignment[x.id()]; +      } else { +        solve(x); +        _influence[x].insert(*_evaluating); +        return VariableAssignment<T>::_assignment[x.id()]; +      } +    } +    void solve(const Variable<T>& x) const { +      if (!_stable.contains(x)) { +        _stable.insert(x); + +        const Variable<T>* oldEval = _evaluating; +        _evaluating = &x; +        T t = _strategy(*_system[x], *this); +        _evaluating = oldEval; + +        if (t != VariableAssignment<T>::_assignment[x.id()]) { +          IdSet<Variable<T> > oldInfluence = _influence[x]; +          _influence[x].clear(); // clear out our idea of what x influences +          VariableAssignment<T>::_assignment[x.id()] = t; + +          _stable.filter(oldInfluence); // whatever x influences needs to be re-evaluated + +          for (typename IdSet<Variable<T> >::iterator it = oldInfluence.begin(); +               it != oldInfluence.end(); +               ++it) { +            solve(*_system.getVar(*it)); +          } +        } +      } +    } +    private: +    const MaxStrategy<T>& _strategy; +    const EquationSystem<T>& _system; +    mutable const Variable<T>* _evaluating; +    mutable IdMap<Variable<T>, IdSet<Variable<T> > > _influence; +    mutable IdSet<Variable<T> > _stable; +  }; + +  virtual VariableAssignment<T> maxFixpoint(const MaxStrategy<T>& strat, const EquationSystem<T>& system) const { +    EvaluatingVariableAssignment assignment(strat, system); +    VariableAssignment<T> result(system.varCount()); +    for (unsigned int i = 0; i < system.varCount(); ++i) { +      result[*system.getVar(i)] = assignment[*system.getVar(i)]; +    } +    return result; +  } +}; + +#endif  | 
