summaryrefslogtreecommitdiff
path: root/impl/MaxStrategy.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'impl/MaxStrategy.hpp')
-rw-r--r--impl/MaxStrategy.hpp83
1 files changed, 63 insertions, 20 deletions
diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp
index 06f61b7..2be9f4c 100644
--- a/impl/MaxStrategy.hpp
+++ b/impl/MaxStrategy.hpp
@@ -46,6 +46,16 @@ struct MaxStrategy : public EquationSystem<Domain> {
: _system(system), _expressions(system.variableCount(), NULL), _strategy(system.maxExpressionCount(), 0) {
}
+ ~MaxStrategy() {
+ for (int i = 0, length = _system.variableCount();
+ i < length;
+ ++i) {
+ Expression<Domain>* expr = _expressions[_system.variable(i)];
+ if (expr)
+ delete expr;
+ }
+ }
+
const Expression<Domain>* operator[](const Variable<Domain>& v) const {
if (_expressions[v] == NULL) {
Expression<Domain>* expression = new MaxStrategyExpression<Domain>(*_system[v], _strategy);
@@ -92,29 +102,62 @@ struct MaxStrategy : public EquationSystem<Domain> {
return _system.equalAssignments(l, r);
}
- void improve(const VariableAssignment<Domain>& rho) {
- for (unsigned int i = 0, length = _system.maxExpressionCount();
- i < length;
- ++i) {
- MaxExpression<Domain>& expr = _system.maxExpression(i);
- Domain bestValue = MaxStrategyExpression<Domain>(expr, _strategy).eval(rho);
- unsigned int bestIndex = this->get(expr);
-
- // this relies on the fact that an expression will only be proessed after the expressions
- // it depends on (which should always be true, as they form a DAG)
- const std::vector<Expression<Domain>*> args = expr.arguments();
- for (unsigned int j = 0, length = args.size();
- j < length;
- ++j) {
- const Domain value = MaxStrategyExpression<Domain>(*args[j], _strategy).eval(rho);
- if (bestValue < value) {
- bestValue = value;
- bestIndex = j;
+
+ struct ImprovementOperator {
+ virtual ~ImprovementOperator() { }
+ virtual bool improve(MaxStrategy<Domain>&, const VariableAssignment<Domain>&) const = 0;
+ };
+ bool improve(const ImprovementOperator& op, const VariableAssignment<Domain>& rho) {
+ return op.improve(*this, rho);
+ }
+
+ struct NaiveImprovementOperator : public ImprovementOperator {
+ bool improve(MaxStrategy<Domain>& strat, const VariableAssignment<Domain>& rho) const {
+ bool changed = false;
+ for (unsigned int i = 0, length = strat._system.maxExpressionCount();
+ i < length;
+ ++i) {
+ MaxExpression<Domain>& expr = strat._system.maxExpression(i);
+ Domain bestValue = MaxStrategyExpression<Domain>(expr, strat._strategy).eval(rho);
+ unsigned int lastIndex= strat.get(expr);
+ unsigned int bestIndex = strat.get(expr);
+
+ // this relies on the fact that an expression will only be proessed after the expressions
+ // it depends on (which should always be true, as they form a DAG)
+ const std::vector<Expression<Domain>*> args = expr.arguments();
+ for (unsigned int j = 0, length = args.size();
+ j < length;
+ ++j) {
+ const Domain value = MaxStrategyExpression<Domain>(*args[j], strat._strategy).eval(rho);
+ if (bestValue < value) {
+ bestValue = value;
+ bestIndex = j;
+ }
+ }
+ if (bestIndex != lastIndex) {
+ changed = true;
+ strat.set(expr, bestIndex);
}
}
- this->set(expr, bestIndex);
+ return changed;
}
- }
+ };
+
+ struct RepeatedImprovementOperator : public ImprovementOperator {
+ RepeatedImprovementOperator(const ImprovementOperator& op)
+ : _subImprovement(op) { }
+ bool improve(MaxStrategy<Domain>& strat, const VariableAssignment<Domain>& rho) const {
+ if (_subImprovement.improve(strat, rho)) {
+ VariableAssignment<Domain>* rho2 = strat.eval(rho);
+ improve(strat, *rho2);
+ delete rho2;
+ return true;
+ }
+ return false;
+ }
+ private:
+ const ImprovementOperator& _subImprovement;
+ };
void print(std::ostream& cout) const {
cout << _system << std::endl;