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
|
#ifndef VARIABLE_ASSIGNMENT_HPP
#define VARIABLE_ASSIGNMENT_HPP
#include "Expression.hpp"
#include "IdMap.hpp"
template<typename Domain>
struct VariableAssignment {
virtual ~VariableAssignment() { }
virtual const Domain& operator[](const Variable<Domain>&) const = 0;
};
#include "EquationSystem.hpp"
template<typename Domain>
struct DynamicMaxStrategy;
template<typename Domain>
struct DynamicVariableAssignment : public VariableAssignment<Domain> {
DynamicVariableAssignment(
const EquationSystem<Domain>& system,
const DynamicMaxStrategy<Domain>& strat
) : _system(system),
_strategy(strat),
_values(system.variableCount(), infinity<Domain>()),
_stable(system.variableCount()),
_influence(system.variableCount(),
IdSet<Variable<Domain>>(system.variableCount()))
{ }
const Domain& operator[](const Variable<Domain>& var) const {
solve(var);
return _values[var];
}
void invalidate(const Variable<Domain>& x) const {
log::fixpoint << indent() << "Invalidating " << x << std::endl;
_stable.remove(x);
_values[x] = infinity<Domain>();
}
private:
void solve(const Variable<Domain>& x) const {
if (!_stable.contains(x)) {
_stable.insert(x);
log::fixpoint << indent() << "Stabilise " << x << std::endl;
stack_depth++;
Domain val = _system[x]->eval(DependencyAssignment(*this, x),
_strategy);
stack_depth--;
if (val != _values[x]) {
log::fixpoint << x << " = " << val << std::endl;
auto oldInfluence = _influence[x];
_influence[x].clear();
_values[x] = val;
_strategy.invalidate(x);
_stable.filter(oldInfluence);
for (auto it = oldInfluence.begin();
it != oldInfluence.end();
++it) {
solve(_system.variable(*it));
}
} else {
log::fixpoint << indent() << x << " did not change" << std::endl;
}
} else {
log::fixpoint << indent() << x << " is stable" << std::endl;
}
}
struct DependencyAssignment : public VariableAssignment<Domain> {
DependencyAssignment(const DynamicVariableAssignment& assignment, const Variable<Domain>& var)
: _assignment(assignment), _var(var) { }
const Domain& operator[](const Variable<Domain>& x) const {
const Domain& result = _assignment[x];
_assignment._influence[x].insert(_var);
return result;
}
private:
const DynamicVariableAssignment& _assignment;
const Variable<Domain>& _var;
};
const EquationSystem<Domain>& _system;
const DynamicMaxStrategy<Domain>& _strategy;
mutable IdMap<Variable<Domain>, Domain> _values;
mutable IdSet<Variable<Domain> > _stable;
mutable IdMap<Variable<Domain>,IdSet<Variable<Domain> > > _influence;
};
#endif
|