summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@carlo-laptop>2012-10-24 10:34:15 +1100
committerCarlo Zancanaro <carlo@carlo-laptop>2012-10-24 10:34:15 +1100
commita3860a4cd6ca6a1ee664634ea472b5487535b2b5 (patch)
tree894e638faf1141a63c9159785779193c8546a852
parent8253e957e54d31699b4bd827300bc1fa794c4660 (diff)
Add a fix for mutually-recursive infinite things
So now it will solve correctly for x = y + 1 y = max(0, x + 1) I also added in tests for this (and a slightly different form with `x` going through another variable, `z`, for indirection). The tests will also stop now after five seconds of execution. If they can't be solved in five seconds then they're considered a failure.
-rw-r--r--impl/VariableAssignment.hpp19
-rw-r--r--impl/test/12.eqns2
-rw-r--r--impl/test/12.soln2
-rw-r--r--impl/test/13.eqns3
-rw-r--r--impl/test/13.soln3
-rw-r--r--impl/test/run5
6 files changed, 29 insertions, 5 deletions
diff --git a/impl/VariableAssignment.hpp b/impl/VariableAssignment.hpp
index 21226ac..19403a8 100644
--- a/impl/VariableAssignment.hpp
+++ b/impl/VariableAssignment.hpp
@@ -55,15 +55,26 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> {
return _values[var];
}
- void invalidate(const Variable<Domain>& x) {
+ 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>());
- solve(x);
- if (_values[x] == infinity<Domain>())
- _values[x] = _values[x].asKnown();
+ IdSet<Variable<Domain> > infl = _influence[x];
+ 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();
+ }
}
}
diff --git a/impl/test/12.eqns b/impl/test/12.eqns
new file mode 100644
index 0000000..91be47b
--- /dev/null
+++ b/impl/test/12.eqns
@@ -0,0 +1,2 @@
+x = y + 1
+y = max(0, x + 1)
diff --git a/impl/test/12.soln b/impl/test/12.soln
new file mode 100644
index 0000000..cdfcb1f
--- /dev/null
+++ b/impl/test/12.soln
@@ -0,0 +1,2 @@
+x = inf
+y = inf
diff --git a/impl/test/13.eqns b/impl/test/13.eqns
new file mode 100644
index 0000000..ce399ef
--- /dev/null
+++ b/impl/test/13.eqns
@@ -0,0 +1,3 @@
+x = y + 1
+y = max(0, z)
+z = x
diff --git a/impl/test/13.soln b/impl/test/13.soln
new file mode 100644
index 0000000..ff37347
--- /dev/null
+++ b/impl/test/13.soln
@@ -0,0 +1,3 @@
+x = inf
+y = inf
+z = inf
diff --git a/impl/test/run b/impl/test/run
index 0c1886d..826bbde 100644
--- a/impl/test/run
+++ b/impl/test/run
@@ -7,7 +7,10 @@ FAILED=0
echo "Testing binary: $1 in directory $DIR"
while [ -f "$DIR/$NUM.eqns" ]
do
- OUTPUT=$($1 "$DIR/$NUM.eqns")
+ OUTPUT=$(timeout 5s $1 "$DIR/$NUM.eqns")
+ if [ $? -eq 124 ]; then
+ OUTPUT="did not terminate"
+ fi
DIFF=$(echo "$OUTPUT" | diff - "$DIR/$NUM.soln")
if [ ! -z "$DIFF" ]; then
echo "=================="