diff options
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | impl/Complete.hpp | 30 | ||||
-rw-r--r-- | impl/EquationSystem.hpp | 2 | ||||
-rw-r--r-- | impl/Expression.hpp | 10 | ||||
-rw-r--r-- | impl/MaxStrategy.hpp | 73 | ||||
-rw-r--r-- | impl/VariableAssignment.hpp | 30 | ||||
-rw-r--r-- | impl/main.cpp | 7 | ||||
-rw-r--r-- | impl/test/10.eqns | 9 | ||||
-rw-r--r-- | impl/test/10.soln | 9 | ||||
-rw-r--r-- | impl/test/7.eqns | 2 | ||||
-rw-r--r-- | impl/test/8.eqns | 4 | ||||
-rw-r--r-- | impl/test/8.soln | 4 | ||||
-rw-r--r-- | impl/test/9.eqns | 5 | ||||
-rw-r--r-- | impl/test/9.soln | 5 |
14 files changed, 156 insertions, 45 deletions
@@ -1,3 +1,14 @@ /impl/build/* /impl/parser/* +*.log +*.dvi +*.ps +*.aux +*.blg +*.bbl +*.toc +*.lof +*.lot +*.out +*~ gmon.out diff --git a/impl/Complete.hpp b/impl/Complete.hpp index e3ec15a..336ab24 100644 --- a/impl/Complete.hpp +++ b/impl/Complete.hpp @@ -7,23 +7,38 @@ template<typename T> T infinity() { } +template<typename T> +T unknown(const T&) { } template<typename T> struct Complete { Complete() - : _value(0), _infinity(false) { } + : _value(0), _infinity(false), _unknown(false) { } Complete(const T& value) - : _value(value), _infinity(false) { } + : _value(value), _infinity(false), _unknown(false) { } Complete(const T& value, const bool& infinity) - : _value(value), _infinity(infinity) { + : _value(value), _infinity(infinity), _unknown(false) { assert(value != 0 || infinity == false); } Complete(const Complete& other) - : _value(other._value), _infinity(other._infinity) { } + : _value(other._value), _infinity(other._infinity), _unknown(other._unknown) { } + Complete(const Complete& other, bool unknown) + : _value(other._value), _infinity(other._infinity), _unknown(unknown) { } + + Complete asUnknown() const { + return Complete(*this, true); + } + Complete asKnown() const { + return Complete(*this, false); + } + bool isUnknown() const { + return _unknown; + } Complete& operator=(const Complete& other) { _value = other._value; _infinity = other._infinity; + _unknown = other._unknown; return *this; } Complete& operator+=(const Complete& other) { @@ -102,6 +117,7 @@ struct Complete { private: T _value; bool _infinity; + bool _unknown; }; template<typename Z> @@ -114,6 +130,8 @@ std::istream& operator>>(std::istream& cin, Complete<Z>& num) { template<typename Z> std::ostream& operator<<(std::ostream& cout, const Complete<Z>& num) { + if (num._unknown) + cout << "(unknown)"; if (num._infinity) { cout << (num._value > 0 ? "inf" : "-inf"); } else { @@ -126,5 +144,9 @@ template<> Complete<int> infinity() { return Complete<int>(1, true); } +template<> +Complete<int> unknown(const Complete<int>& x) { + return Complete<int>(x, true); +} #endif diff --git a/impl/EquationSystem.hpp b/impl/EquationSystem.hpp index 2fd24bd..a0ba8a1 100644 --- a/impl/EquationSystem.hpp +++ b/impl/EquationSystem.hpp @@ -31,7 +31,7 @@ struct EquationSystem { delete _expr_to_var; } - MaxExpression<Domain>& maxExpression(const std::vector<Expression<Domain>*>& arguments) { + MaxExpression<Domain>& maxExpression(const std::vector<Expression<Domain>*> arguments) { unsigned int id = _max_expressions.size(); Maximum<Domain>* max = new Maximum<Domain>(); MaxExpression<Domain>* expr = new MaxExpression<Domain>(id, *max, arguments); diff --git a/impl/Expression.hpp b/impl/Expression.hpp index 9c4ac9f..cba9582 100644 --- a/impl/Expression.hpp +++ b/impl/Expression.hpp @@ -151,7 +151,7 @@ struct OperatorExpression : public Expression<Domain> { template<typename Domain> struct MaxExpression : public OperatorExpression<Domain> { MaxExpression(const unsigned int& id, const Maximum<Domain>& op, const std::vector<Expression<Domain>*>& arguments) - : OperatorExpression<Domain>(op, arguments), _id(id) { } + : OperatorExpression<Domain>(op, arguments), _id(id) {} MaxExpression* toMaxExpression() { return this; @@ -173,9 +173,11 @@ struct MaxExpression : public OperatorExpression<Domain> { i < length; ++i) { const Domain value = this->_arguments[i]->eval(rho, strat); - if (bestValue < value) { - bestValue = value; - bestIndex = i; + if (!value.isUnknown()) { + if (bestValue < value) { + bestValue = value; + bestIndex = i; + } } } return bestIndex; diff --git a/impl/MaxStrategy.hpp b/impl/MaxStrategy.hpp index f4026dd..ba7cc11 100644 --- a/impl/MaxStrategy.hpp +++ b/impl/MaxStrategy.hpp @@ -34,7 +34,8 @@ template<typename Domain> struct DynamicMaxStrategy : public MaxStrategy<Domain> { DynamicMaxStrategy( const EquationSystem<Domain>& system - ) : _system(system), + ) : _frozen(false), + _system(system), _rho(NULL), _values(system.maxExpressionCount(), 0), _stable(system.maxExpressionCount()), @@ -62,28 +63,26 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> { } unsigned int get(const MaxExpression<Domain>& e) const { - return _values[e]; - } - - 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]; - _var_influence[v].clear(); - - for (typename IdSet<MaxExpression<Domain> >::iterator - it = infl.begin(), - end = infl.end(); - it != end; - ++it) { - solve(_system.maxExpression(*it)); + void invalidate(const Variable<Domain>& v) const { + 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)); + } } } @@ -99,6 +98,7 @@ private: stack_depth--; if (val != _values[x]) { + log::strategy << x << " => " << *x.arguments()[val] << std::endl; IdSet<MaxExpression<Domain> > oldInfluence = _influence[x]; @@ -126,6 +126,16 @@ 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, @@ -144,6 +154,30 @@ private: 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; + }; + struct DependencyStrategy : public MaxStrategy<Domain> { DependencyStrategy(DynamicMaxStrategy& strat, const MaxExpression<Domain>& expr) : _strat(strat), @@ -161,7 +195,8 @@ private: const MaxExpression<Domain>& _expr; }; -private: +private: + mutable bool _frozen; const EquationSystem<Domain>& _system; DynamicVariableAssignment<Domain>* _rho; IdMap<MaxExpression<Domain>,unsigned int> _values; diff --git a/impl/VariableAssignment.hpp b/impl/VariableAssignment.hpp index 2a63756..cfce925 100644 --- a/impl/VariableAssignment.hpp +++ b/impl/VariableAssignment.hpp @@ -26,7 +26,7 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> { const Domain& value=infinity<Domain>() ) : _system(system), _strategy(strat), - _values(system.variableCount(), value), + _values(system.variableCount(), unknown(infinity<Domain>())), _stable(system.variableCount()), _influence(system.variableCount(), IdSet<Variable<Domain> >(system.variableCount())), @@ -59,17 +59,20 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> { log::fixpoint << indent() << "Invalidating " << x << std::endl; if (_stable.contains(x)) { _stable.remove(x); - _values[x] = infinity<Domain>(); - + _values[x] = unknown(infinity<Domain>()); + + solve(x); + /* 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)); + it = infl.begin(), + ei = infl.end(); + it != ei; + ++it) { + invalidate(_system.variable(*it)); } + */ } } @@ -125,11 +128,12 @@ private: }; const EquationSystem<Domain>& _system; - DynamicMaxStrategy<Domain>& _strategy; - IdMap<Variable<Domain>, Domain> _values; - IdSet<Variable<Domain> > _stable; - IdMap<Variable<Domain>,IdSet<Variable<Domain> > > _influence; - bool _frozen; + const DynamicMaxStrategy<Domain>& _strategy; + mutable IdMap<Variable<Domain>, Domain> _values; +public: + mutable IdSet<Variable<Domain> > _stable; +private: + mutable IdMap<Variable<Domain>,IdSet<Variable<Domain> > > _influence; }; #endif diff --git a/impl/main.cpp b/impl/main.cpp index 84f17dd..02faca5 100644 --- a/impl/main.cpp +++ b/impl/main.cpp @@ -161,13 +161,14 @@ int main (int argc, char* argv[]) { if (variables.size() > 0) { for (unsigned int i = 0, size = system.variableCount(); i < size; ++i) { Variable<ZBar>& var = system.variable(i); - if (variables.find(var.name()) != variables.end()) - cout << var.name() << " = " << rho[var] << endl; + if (variables.find(var.name()) != variables.end()) { + cout << var.name() << " = " << rho[var].asKnown() << endl; + } } } else { for (unsigned int i = 0, size = system.variableCount(); i < size; ++i) { Variable<ZBar>& var = system.variable(i); - cout << var.name() << " = " << rho[var] << endl; + cout << var.name() << " = " << rho[var].asKnown() << endl; } } */ diff --git a/impl/test/10.eqns b/impl/test/10.eqns new file mode 100644 index 0000000..39598f4 --- /dev/null +++ b/impl/test/10.eqns @@ -0,0 +1,9 @@ +x = 0 +w = max(x,y,z,u,w) +y = w +z = w +u = a +a = b +b = c +c = d +d = w diff --git a/impl/test/10.soln b/impl/test/10.soln new file mode 100644 index 0000000..20a47ca --- /dev/null +++ b/impl/test/10.soln @@ -0,0 +1,9 @@ +x = 0 +w = 0 +y = 0 +z = 0 +u = 0 +a = 0 +b = 0 +c = 0 +d = 0 diff --git a/impl/test/7.eqns b/impl/test/7.eqns index 2789f0e..1f69268 100644 --- a/impl/test/7.eqns +++ b/impl/test/7.eqns @@ -1,5 +1,5 @@ x = 0 -y = max(-inf, x, a) +y = max(x,a) a = b b = c c = d diff --git a/impl/test/8.eqns b/impl/test/8.eqns new file mode 100644 index 0000000..c9e9c4e --- /dev/null +++ b/impl/test/8.eqns @@ -0,0 +1,4 @@ +x = 0 +w = max(x,y,z) +y = w +z = w diff --git a/impl/test/8.soln b/impl/test/8.soln new file mode 100644 index 0000000..1945057 --- /dev/null +++ b/impl/test/8.soln @@ -0,0 +1,4 @@ +x = 0 +w = 0 +y = 0 +z = 0 diff --git a/impl/test/9.eqns b/impl/test/9.eqns new file mode 100644 index 0000000..b85e118 --- /dev/null +++ b/impl/test/9.eqns @@ -0,0 +1,5 @@ +x = 0 +w = max(x,y,z,u) +y = w +z = w +u = w diff --git a/impl/test/9.soln b/impl/test/9.soln new file mode 100644 index 0000000..616c5e5 --- /dev/null +++ b/impl/test/9.soln @@ -0,0 +1,5 @@ +x = 0 +w = 0 +y = 0 +z = 0 +u = 0 |