summaryrefslogtreecommitdiff
path: root/impl/VariableAssignment.hpp
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@carlo-laptop>2012-10-30 20:56:38 +1100
committerCarlo Zancanaro <carlo@carlo-laptop>2012-10-30 20:56:38 +1100
commit6a4786bde976e9a023c7f65a395384d214c5102c (patch)
treef3dd303f21dfa0be269a932dd05438041a290f27 /impl/VariableAssignment.hpp
parentff2030f3a19926334fbe3a043c5f88622c17c2f8 (diff)
parent95b82ea3830c3a34455323167894647e3aa773a6 (diff)
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Conflicts: impl/test/run
Diffstat (limited to 'impl/VariableAssignment.hpp')
-rw-r--r--impl/VariableAssignment.hpp95
1 files changed, 40 insertions, 55 deletions
diff --git a/impl/VariableAssignment.hpp b/impl/VariableAssignment.hpp
index 19403a8..2e081e6 100644
--- a/impl/VariableAssignment.hpp
+++ b/impl/VariableAssignment.hpp
@@ -7,10 +7,7 @@
template<typename Domain>
struct VariableAssignment {
virtual ~VariableAssignment() { }
- virtual const Domain& operator[](const Variable<Domain>&) const = 0;
- virtual const Domain& operator[](const Variable<Domain>& x) {
- return (*const_cast<const VariableAssignment*>(this))[x];
- }
+ virtual const Domain operator[](const Variable<Domain>& x) = 0;
};
#include "EquationSystem.hpp"
@@ -22,58 +19,44 @@ template<typename Domain>
struct DynamicVariableAssignment : public VariableAssignment<Domain> {
DynamicVariableAssignment(
const EquationSystem<Domain>& system,
- DynamicMaxStrategy<Domain>& strat
+ DynamicMaxStrategy<Domain>& strat,
+ const Domain& value=infinity<Domain>()
) : _system(system),
_strategy(strat),
- _values(system.variableCount(), unknown(infinity<Domain>())),
- _stable(system.variableCount()),
+ _values(system.variableCount(), value),
+ _unstable(system.variableCount()),
_influence(system.variableCount(),
- IdSet<Variable<Domain> >(system.variableCount())),
- _frozen(false)
+ IdSet<Variable<Domain> >(system.variableCount()))
{ }
- void freeze() {
- _frozen = true;
- }
-
- void thaw() {
- _frozen = false;
- }
-
- bool is_frozen() {
- return _frozen;
- }
-
- const Domain& operator[](const Variable<Domain>& var) const {
- // slightly hacky
- return const_cast<DynamicVariableAssignment<Domain>&>(*this)[var];
+ const Domain operator[](const Variable<Domain>& var) {
+ solve(var);
+ return _values[var];
}
- const Domain& operator[](const Variable<Domain>& var) {
- if (!_frozen)
+ /*void stabilise() {
+ if (!_unstable.empty()) {
+ Variable<Domain>& var = _system.variable(*_unstable.begin());
solve(var);
- return _values[var];
- }
+ }
+ }*/
- void invalidate(const Variable<Domain>& x, bool also_solve=true) {
- log::fixpoint << indent() << "Invalidating " << x << std::endl;
- if (_stable.contains(x)) {
- _stable.remove(x);
- _values[x] = unknown(infinity<Domain>());
+ void invalidate(const Variable<Domain>& x) {
+ if (!_unstable.contains(x)) {
+ log::fixpoint << indent() << "Invalidating " << x << std::endl;
+
+ _unstable.insert(x);
+ _values[x] = infinity<Domain>();
IdSet<Variable<Domain> > infl = _influence[x];
+ _influence[x].clear();
+
for (typename IdSet<Variable<Domain> >::iterator
- it = infl.begin(),
- ei = infl.end();
- it != ei;
- ++it) {
- invalidate(_system.variable(*it), false);
- }
-
- if (also_solve) {
- solve(x);
- if (_values[x] == infinity<Domain>())
- _values[x] = _values[x].asKnown();
+ it = infl.begin(),
+ ei = infl.end();
+ it != ei;
+ ++it) {
+ invalidate(_system.variable(*it));
}
}
}
@@ -81,25 +64,28 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> {
private:
void solve(const Variable<Domain>& x) {
- if (!_stable.contains(x)) {
- _stable.insert(x);
+ if (_unstable.contains(x)) {
+ _unstable.remove(x);
log::fixpoint << indent() << "Stabilise " << x << std::endl;
stack_depth++;
- Domain val = _system[x]->eval(DependencyAssignment(*this, x),
- _strategy);
+ // we don't want the assignment to affect the strategy, so we're
+ // going to use a const reference here
+ const DynamicMaxStrategy<Domain>& const_strat = _strategy;
+ DependencyAssignment assignment(*this, x);
+ Domain val = _system[x]->eval(assignment, const_strat);
stack_depth--;
if (val != _values[x]) {
log::fixpoint << x << " = " << val << std::endl;
+
+ _strategy.invalidate(x);
IdSet<Variable<Domain> > oldInfluence = _influence[x];
_influence[x].clear();
_values[x] = val;
- _strategy.invalidate(x);
-
- _stable.filter(oldInfluence);
+ _unstable.absorb(oldInfluence);
for (typename IdSet<Variable<Domain> >::iterator it = oldInfluence.begin();
it != oldInfluence.end();
@@ -119,8 +105,8 @@ private:
struct DependencyAssignment : public VariableAssignment<Domain> {
DependencyAssignment(DynamicVariableAssignment& assignment, const Variable<Domain>& var)
: _assignment(assignment), _var(var) { }
- const Domain& operator[](const Variable<Domain>& x) const {
- const Domain& result = _assignment[x];
+ const Domain operator[](const Variable<Domain>& x) {
+ const Domain result = _assignment[x];
_assignment._influence[x].insert(_var);
return result;
}
@@ -132,9 +118,8 @@ private:
const EquationSystem<Domain>& _system;
DynamicMaxStrategy<Domain>& _strategy;
IdMap<Variable<Domain>, Domain> _values;
- IdSet<Variable<Domain> > _stable;
+ IdSet<Variable<Domain> > _unstable;
IdMap<Variable<Domain>,IdSet<Variable<Domain> > > _influence;
- bool _frozen;
};
#endif