summaryrefslogtreecommitdiff
path: root/impl/MaxStrategy.hpp
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-22 14:44:57 +1100
committerCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-22 14:44:57 +1100
commit86ca7448849aaaea6db34b1d2bcf8d99d7d7b12c (patch)
treeacc843137f53cfc8cb2b847374c3d06789a9505e /impl/MaxStrategy.hpp
parent39bcfdc55a09e437482768903f6093ab1dd60a61 (diff)
Okay, the solver is now correct.
It runs in two separate passes: - improve strategy (for all) - evaluate fixpoint Unfortunately this loses out on locality at the moment. I really want a local solver, so I'll have to see what I can do about that.
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r--impl/MaxStrategy.hpp89
1 files changed, 74 insertions, 15 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp
index 96aeef4..f4026dd 100644
--- a/impl/MaxStrategy.hpp
+++ b/impl/MaxStrategy.hpp
@@ -10,6 +10,9 @@ 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);
+ }
};
unsigned int stack_depth = 1;
@@ -38,20 +41,38 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> {
_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 freeze() {
+ _frozen = true;
+ }
+
+ void thaw() {
+ _frozen = false;
+ }
+
+ bool is_frozen() {
+ return _frozen;
+ }
+
void setRho(DynamicVariableAssignment<Domain>& rho) {
_rho = &rho;
}
unsigned int get(const MaxExpression<Domain>& e) const {
- solve(e);
return _values[e];
}
- void invalidate(const Variable<Domain>& v) const {
- log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl;
+ unsigned int get(const MaxExpression<Domain>& e) {
+ if (!_frozen)
+ solve(e);
+ return _values[e];
+ }
+
+ void invalidate(const Variable<Domain>& v) {
+ log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl;
_stable.filter(_var_influence[v]);
IdSet<MaxExpression<Domain> > infl = _var_influence[v];
@@ -67,7 +88,7 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> {
}
private:
- void solve(const MaxExpression<Domain>& x) const {
+ void solve(const MaxExpression<Domain>& x) {
if (!_stable.contains(x)) {
_stable.insert(x);
log::strategy << indent() << "Stabilise " << x << std::endl;
@@ -106,7 +127,7 @@ private:
}
struct DependencyAssignment : public VariableAssignment<Domain>{
- DependencyAssignment(const DynamicMaxStrategy& strat,
+ DependencyAssignment(DynamicMaxStrategy& strat,
VariableAssignment<Domain>& rho,
const MaxExpression<Domain>& expr)
: _strat(strat),
@@ -118,13 +139,13 @@ private:
return _rho[var];
}
private:
- const DynamicMaxStrategy& _strat;
+ DynamicMaxStrategy& _strat;
VariableAssignment<Domain>& _rho;
const MaxExpression<Domain>& _expr;
};
struct DependencyStrategy : public MaxStrategy<Domain> {
- DependencyStrategy(const DynamicMaxStrategy& strat, const MaxExpression<Domain>& expr)
+ DependencyStrategy(DynamicMaxStrategy& strat, const MaxExpression<Domain>& expr)
: _strat(strat),
_expr(expr) {
}
@@ -136,19 +157,57 @@ private:
return _strat._values[e];
}
private:
- const DynamicMaxStrategy& _strat;
+ DynamicMaxStrategy& _strat;
const MaxExpression<Domain>& _expr;
};
-private:
+private:
const EquationSystem<Domain>& _system;
- mutable DynamicVariableAssignment<Domain>* _rho;
- mutable IdMap<MaxExpression<Domain>,unsigned int> _values;
- mutable IdSet<MaxExpression<Domain> > _stable;
- mutable IdMap<MaxExpression<Domain>,IdSet<MaxExpression<Domain> > > _influence;
- mutable IdMap<Variable<Domain>,IdSet<MaxExpression<Domain> > > _var_influence;
+ 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 T>
+IdMap<Variable<T>,T> solve_for(const EquationSystem<T>& system) {
+ IdMap<Variable<T>,T> result(system.variableCount(), infinity<T>());
+
+ DynamicMaxStrategy<T> strategy(system);
+ DynamicVariableAssignment<T> rho(system, strategy, -infinity<T>());
+ strategy.setRho(rho);
+
+ bool changed;
+ do {
+ changed = false;
+
+ // improve strategy
+ rho.freeze();
+ strategy.thaw();
+ for (unsigned int i = 0; i < system.variableCount(); ++i) {
+ strategy.get(*system[system.variable(i)]);
+ }
+
+ // iterate fixpoint
+ strategy.freeze();
+ rho.thaw();
+ for (unsigned int i = 0; i < system.variableCount(); ++i) {
+ Variable<T>& var = system.variable(i);
+ T val = rho[var];
+ if (result[var] != val) {
+ result[var] = val;
+ changed = true;
+ }
+ }
+ } while(changed);
+
+ return result;
+}
+
+
/*template<typename Domain>
std::ostream& operator<<(std::ostream& cout, const MaxStrategy<Domain>& strat) {
strat.print(cout);