summaryrefslogtreecommitdiff
path: root/impl/MaxStrategy.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r--impl/MaxStrategy.hpp158
1 files changed, 88 insertions, 70 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp
index 3ed7972..d908c7b 100644
--- a/impl/MaxStrategy.hpp
+++ b/impl/MaxStrategy.hpp
@@ -9,10 +9,7 @@
template<typename Domain>
struct MaxStrategy {
virtual ~MaxStrategy() { }
- virtual unsigned int get(const MaxExpression<Domain>& e) const = 0;
- virtual unsigned int get(const MaxExpression<Domain>& e) {
- return const_cast<const MaxStrategy*>(this)->get(e);
- }
+ virtual unsigned int get(const MaxExpression<Domain>& e) = 0;
};
unsigned int stack_depth = 1;
@@ -34,24 +31,31 @@ template<typename Domain>
struct DynamicMaxStrategy : public MaxStrategy<Domain> {
DynamicMaxStrategy(
const EquationSystem<Domain>& system
- ) : _frozen(false),
- _system(system),
+ ) : _system(system),
_rho(NULL),
_values(system.maxExpressionCount(), 0),
_stable(system.maxExpressionCount()),
_influence(system.maxExpressionCount(),
IdSet<MaxExpression<Domain> >(system.maxExpressionCount())),
_var_influence(system.variableCount(),
- IdSet<MaxExpression<Domain> >(system.maxExpressionCount()))
+ IdSet<MaxExpression<Domain> >(system.maxExpressionCount())),
+ _frozen(false)
{}
- void setRho(DynamicVariableAssignment<Domain>& rho) {
- _rho = &rho;
+ void freeze() {
+ _frozen = true;
}
- unsigned int get(const MaxExpression<Domain>& e) const {
- // slightly hacky
- return const_cast<DynamicMaxStrategy<Domain>*>(this)->get(e);
+ void thaw() {
+ _frozen = false;
+ }
+
+ bool is_frozen() {
+ return _frozen;
+ }
+
+ void setRho(DynamicVariableAssignment<Domain>& rho) {
+ _rho = &rho;
}
unsigned int get(const MaxExpression<Domain>& e) {
@@ -61,20 +65,18 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> {
}
void invalidate(const Variable<Domain>& v) {
- log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl;
- if (_system[v] && _stable.contains(*_system[v])) {
- _stable.remove(*_system[v]);
- _stable.filter(_var_influence[v]);
-
- IdSet<MaxExpression<Domain> > infl = _var_influence[v];
- _var_influence[v].clear();
- for (typename IdSet<MaxExpression<Domain> >::iterator
- it = infl.begin(),
- end = infl.end();
- it != end;
- ++it) {
- solve(_system.maxExpression(*it));
- }
+ log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl;
+ _stable.filter(_var_influence[v]);
+
+ IdSet<MaxExpression<Domain> > infl = _var_influence[v];
+ _var_influence[v].clear();
+
+ for (typename IdSet<MaxExpression<Domain> >::iterator
+ it = infl.begin(),
+ end = infl.end();
+ it != end;
+ ++it) {
+ solve(_system.maxExpression(*it));
}
}
@@ -84,13 +86,13 @@ private:
_stable.insert(x);
log::strategy << indent() << "Stabilise " << x << std::endl;
- stack_depth++;
- unsigned int val = x.bestStrategy(DependencyAssignment(*this, *_rho, x),
- DependencyStrategy(*this, x));
+ stack_depth++;
+ DependencyAssignment assignment(*this, *_rho, x);
+ DependencyStrategy depStrat(*this, x);
+ unsigned int val = x.bestStrategy(assignment, depStrat);
stack_depth--;
if (val != _values[x]) {
-
log::strategy << x << " => " << *x.arguments()[val] << std::endl;
IdSet<MaxExpression<Domain> > oldInfluence = _influence[x];
@@ -99,6 +101,12 @@ private:
_rho->invalidate(*_system.varFromExpr(x));
+ _rho->thaw();
+ this->freeze();
+ _rho->stabilise();
+ _rho->freeze();
+ this->thaw();
+
_stable.filter(oldInfluence);
for (typename IdSet<MaxExpression<Domain> >::iterator
@@ -118,56 +126,31 @@ private:
}
}
- const DynamicMaxStrategy& freeze() const {
- _frozen = true;
- return *this;
- }
-
- const DynamicMaxStrategy& thaw() const {
- _frozen = false;
- return *this;
- }
-
struct DependencyAssignment : public VariableAssignment<Domain>{
DependencyAssignment(DynamicMaxStrategy& strat,
VariableAssignment<Domain>& rho,
const MaxExpression<Domain>& expr)
: _strat(strat),
_rho(rho),
- _expr(expr) {
+ _expr(expr),
+ _current(strat._system.variableCount()) {
}
- const Domain& operator[](const Variable<Domain>& var) const {
+ const Domain operator[](const Variable<Domain>& var) {
_strat._var_influence[var].insert(_expr);
- return _rho[var];
+ if (_current.contains(var)) {
+ return _rho[var];
+ } else {
+ _current.insert(var);
+ Domain val = _strat._system[var]->eval(_rho, _strat);
+ _current.remove(var);
+ return val;
+ }
}
private:
DynamicMaxStrategy& _strat;
VariableAssignment<Domain>& _rho;
const MaxExpression<Domain>& _expr;
- };
-
- struct InvalidatingAssignment : public VariableAssignment<Domain>{
- InvalidatingAssignment(DynamicVariableAssignment<Domain>& rho)
- : _rho(rho) {
- }
- ~InvalidatingAssignment() {
- for (typename std::set<const Variable<Domain>*>::iterator
- it = seen.begin(),
- ei = seen.end();
- it != ei;
- ++it) {
- if (!_old_stable.contains(**it))
- _rho.invalidate(**it);
- }
- }
- const Domain& operator[](const Variable<Domain>& var) const {
- seen.insert(&var);
- return _rho[var];
- }
- private:
- DynamicVariableAssignment<Domain>& _rho;
- IdSet<Variable<Domain> > _old_stable;
- mutable std::set<const Variable<Domain>*> seen;
+ IdSet<Variable<Domain> > _current;
};
struct DependencyStrategy : public MaxStrategy<Domain> {
@@ -175,7 +158,7 @@ private:
: _strat(strat),
_expr(expr) {
}
- unsigned int get(const MaxExpression<Domain>& e) const {
+ unsigned int get(const MaxExpression<Domain>& e) {
_strat.solve(e);
if (&_expr != &e) {
_strat._influence[e].insert(_expr);
@@ -187,14 +170,49 @@ private:
const MaxExpression<Domain>& _expr;
};
-private:
- mutable bool _frozen;
+private:
const EquationSystem<Domain>& _system;
DynamicVariableAssignment<Domain>* _rho;
IdMap<MaxExpression<Domain>,unsigned int> _values;
IdSet<MaxExpression<Domain> > _stable;
IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > > _influence;
IdMap<Variable<Domain>,IdSet<MaxExpression<Domain> > > _var_influence;
+ bool _frozen;
+};
+
+
+template<typename Domain>
+struct Solver {
+ Solver(const EquationSystem<Domain>& system)
+ : _system(system),
+ _strategy(system),
+ _rho(_system, _strategy, -infinity<Domain>()) {
+ _strategy.setRho(_rho);
+ }
+
+ Domain solve(Variable<Domain>& var) {
+ MaxExpression<Domain>& rhs = *_system[var];
+
+ do {
+ _rho.has_changed(false);
+
+ // improve strategy
+ _rho.freeze();
+ _strategy.thaw();
+ _strategy.get(rhs);
+
+ // iterate fixpoint
+ _strategy.freeze();
+ _rho.thaw();
+ _rho.stabilise();
+ } while (_rho.has_changed());
+
+ return _rho[var];
+ }
+private:
+ const EquationSystem<Domain>& _system;
+ DynamicMaxStrategy<Domain> _strategy;
+ DynamicVariableAssignment<Domain> _rho;
};