[unconstrained] Fix gathering of visited-once vars (#4652)
authorAndres Noetzli <andres.noetzli@gmail.com>
Wed, 24 Jun 2020 17:41:03 +0000 (10:41 -0700)
committerGitHub <noreply@github.com>
Wed, 24 Jun 2020 17:41:03 +0000 (12:41 -0500)
commitbe607a9d420f79fa3e6a1f2c9b8c0e1b49cd34ee
tree415a032372b68c4de093a5b493ed71b8a7fc6d3d
parentfeea2d248ebe0c024c9c5ed14a9f0bf34b06c146
[unconstrained] Fix gathering of visited-once vars (#4652)

Fixes #4644. This commit fixes an issue where the set `d_unconstrained`
in the unconstrained simplification pass was not computed correctly. The
problem was that visiting the same term multiple times did not remove
the variables appearing in that term from the visited-once set. A simple
example that triggers the issue is the following:

```
(set-logic ALL)
(declare-fun a () Bool)
(declare-fun b () Bool)
(assert (not (= a b)))
(assert (= a (= a b)))
(check-sat)
```

After running `UnconstrainedSimplifier::visitAll()` on both assertions,
we end up with `[b]` as our `d_unconstrained` set. We end up inferring
the substitution `(= a b) --> b` and get `(not b)` and `b`, which is
unsat even though the original problem is sat.

This commit fixes the issue by visiting all the children of a node if we
visit a node for a second time. This makes sure that we remove any
children from the visisted-once set.
src/preprocessing/passes/unconstrained_simplifier.cpp
test/regress/CMakeLists.txt
test/regress/regress0/unconstrained/issue4644.smt2 [new file with mode: 0644]