summaryrefslogtreecommitdiff
path: root/impl/MaxStrategy.hpp
blob: aa49c9db98b22c97d9435919855fd00e6c711a6f (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef MAX_STRATEGY_HPP
#define MAX_STRATEGY_HPP

#include <iostream>
#include "Expression.hpp"
#include "EquationSystem.hpp"
#include "VariableAssignment.hpp"

template<typename T>
struct MaxStrategy {
  MaxStrategy()
    : _length(0), _assignment(NULL) { }
  MaxStrategy(unsigned int length)
    : _length(length), _assignment(new unsigned int[length]) {
    for (unsigned int i = 0; i < length; ++i) {
      _assignment[i] = 0;
    }
  }
  MaxStrategy(const MaxStrategy& other)
    : _length(other._length), _assignment(new unsigned int[other._length]) {
    for (unsigned int i = 0; i < other._length; ++i) {
      _assignment[i] = other._assignment[i];
    }
  }

  virtual ~MaxStrategy() {
    delete[] _assignment;
  }

  MaxStrategy<T>& operator=(const MaxStrategy& other) {
    if (_length != other._length) {
      _length = other._length;
      delete[] _assignment;
      _assignment = new unsigned int[_length];
    }
    for (unsigned int i = 0; i < _length; ++i) {
      _assignment[i] = other._assignment[i];
    }
    return *this;
  }

  const unsigned int& operator[] (const MaxExpression<T> x) const {
    if (x.id() >= _length) {
      throw "Array out of bounds";
    }
    return _assignment[x.id()];
  }
  unsigned int& operator[] (const MaxExpression<T>& x) {
    if (x.id() >= _length) {
      throw "Array out of bounds";
    }
    return _assignment[x.id()];
  }
  VariableAssignment<T> operator() (const EquationSystem<T>& eqns, const VariableAssignment<T>& rho) const {
    return eqns.foreach(*this, rho);
  }
  T operator() (const Expression<T>& expr, const VariableAssignment<T>& rho) const {
    const MaxExpression<T>* max = dynamic_cast<const MaxExpression<T>*>(&expr);
    if (max == NULL) {
      return expr(rho);
    } else {
      return (*this)(*max->argument(_assignment[max->id()]), rho);
    }
  }
  MaxStrategy<T> improve(const EquationSystem<T>& s, const VariableAssignment<T>& rho) const {
    MaxStrategy<T> newStrategy(*this);
    for (unsigned int i = 0; i < _length; ++i) {
      const MaxExpression<T>& expr = *s.getMax(i);
      const T oldValue = (*this)(expr, rho);

      // this relies on the fact that deeper MaxExpressions have a lower id
      // than the MaxExpressions containing them. This means that we know that
      // we have enough of a strategy to work with what we have within us
      std::pair<const T,unsigned int> best = expr.bestStrategy(rho, newStrategy);

      if (best.first > oldValue)
        newStrategy[expr] = best.second;
    }
    return newStrategy;
  }

  bool operator== (const MaxStrategy& other) const {
    if (_length != other._length)
      return false;
    for (unsigned int i = 0; i < _length; ++i) {
      if (_assignment[i] != other._assignment[i]) {
        return false;
      }
    }
    return true;
  }
  bool operator!= (const MaxStrategy& other) const {
    return !(*this == other);
  }
  private:
  unsigned int _length;
  unsigned int* _assignment;
};

#endif