summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2018-06-08 21:05:01 -0700
committerGitHub <noreply@github.com>2018-06-08 21:05:01 -0700
commit6104c154e07b6d343b4d08c7bd185f6d74c89da8 (patch)
tree7950939d64841bb004ae1f8e7eaa27cc06b99d70 /test
parentdcbd349c069a423dd631d4a5bc049f3721d5cc83 (diff)
Reset decisions at SAT level after solving (#2059)
Some quick background: CVC4 has two primary contexts: the assertion context (which corresponds to the push/pops issued by the user) and the decision/SAT context (which corresponds to the push/pops done by the user and each decision made by MiniSat. Before 2cc0e2c6a691fb6d30ed8879832b49bc1f277d77, we had an additonal push/pop when doing the actual solving. With these removed, it could happen that we get a wrong result when doing incremental solving: ``` ... ; check-sat call returns sat, the decision level in the SAT solver is ; non-zero at this point (check-sat) ; Solver::addClause_() determines that we cannot add the clause to the ; SAT solver directly because the decision level is non-zero (i.e. the ; clause is treated like a theory lemma), thus it is added to the lemmas ; list. (assert false) ; The solver stores some information about the current state, including ; the value of the "ok" flag in Solver, which indicates whether the ; current constraints are unsatisfiable. Note that "ok" is true at this ; point. (push) ; Now, in Solver::updateLemmas(), we add clauses from the lemmas list. ; The problem is that empty clauses (which "false" is after removing "false" ; literals) and unit clauses are not added like normal clauses. Instead, ; the empty clause, essentially just results in the "ok" flag being set to ; false (unit clauses are added to the decision trail). (check-sat) ; Here, the solver restores the information stored during ; (push), including the "ok" flag, which is now true again. (pop) ; At this point, the solver has "forgotten" about (assert false) since ; the "ok" flag is back to true and it answers sat. (check-sat) ``` There are multiple ways to look at the problem and to fix it: - One could argue that an input assertion should always be added directly to the clauses in the SAT solver, i.e. the solver should always be at decision level 0 when we are adding input clauses. The advantage of this is that it is relatively easy to implement, corresponds to what the original MiniSat code does (it calls Solver::cancelUntil(0) after solving), and is no worse than what we had before commit 2cc0e2c6a691fb6d30ed8879832b49bc1f277d77 (push/pop do a strict superset of what resetting the decision at the current assertion level does). The disadvantage is that we might throw away some useful work. - One could argue that is fine that (assert false) is treated like a theory lemma. The advantage being that it might result in more efficient solving and the disadvantage being that it is much trickier to implement. Unfortunately, it is not quite clear from the code what the original intention was but we decided to implement the first solution. This commit exposes a method in MiniSat to reset the decisions at the current assertion level. We call this method from SmtEngine after solving. Resetting the decisions directly after solving while we are still in MiniSat does not work because it causes issues with datastructures in the SMT solver that use the decision context (e.g. TheoryEngine::d_incomplete seems to be reset too early, resulting in us answering sat instead of unknown).
Diffstat (limited to 'test')
-rw-r--r--test/regress/Makefile.tests1
-rw-r--r--test/regress/regress0/push-pop/bug1990.smt214
2 files changed, 15 insertions, 0 deletions
diff --git a/test/regress/Makefile.tests b/test/regress/Makefile.tests
index 4a7267a60..d25da1b62 100644
--- a/test/regress/Makefile.tests
+++ b/test/regress/Makefile.tests
@@ -570,6 +570,7 @@ REG0_TESTS = \
regress0/push-pop/boolean/fuzz_48.smt2 \
regress0/push-pop/boolean/fuzz_49.smt2 \
regress0/push-pop/boolean/fuzz_50.smt2 \
+ regress0/push-pop/bug1990.smt2 \
regress0/push-pop/bug233.cvc \
regress0/push-pop/bug654-dd.smt2 \
regress0/push-pop/bug691.smt2 \
diff --git a/test/regress/regress0/push-pop/bug1990.smt2 b/test/regress/regress0/push-pop/bug1990.smt2
new file mode 100644
index 000000000..f0cde3113
--- /dev/null
+++ b/test/regress/regress0/push-pop/bug1990.smt2
@@ -0,0 +1,14 @@
+; COMMAND-LINE: --incremental
+; EXPECT: sat
+; EXPECT: unsat
+; EXPECT: unsat
+(set-logic QF_SAT)
+(declare-fun v1 () Bool)
+(declare-fun v2 () Bool)
+(assert (or v1 v2))
+(check-sat)
+(assert false)
+(push)
+(check-sat)
+(pop)
+(check-sat)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback