Do not apply unconstrained simplification when quantifiers are present (#4532)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Wed, 3 Jun 2020 13:47:46 +0000 (08:47 -0500)
committerGitHub <noreply@github.com>
Wed, 3 Jun 2020 13:47:46 +0000 (08:47 -0500)
Fixes #4437.

This is a simpler fix that aborts the preprocessing pass when a quantifier is encountered.

It also updates our smt2 parser to throw a logic exception when forall/exists is used in non-quantified logics. This is required to ensure that unconstrained simplification does not throw an exception to a user as a result of accidentally setting the wrong logic.

src/options/smt_options.toml
src/parser/smt2/Smt2.g
src/preprocessing/passes/unconstrained_simplifier.cpp
src/preprocessing/passes/unconstrained_simplifier.h
test/regress/CMakeLists.txt
test/regress/regress0/quantifiers/issue4437-unc-quant.smt2 [new file with mode: 0644]
test/regress/regress0/unconstrained/4481.smt2
test/regress/regress0/unconstrained/4484.smt2 [deleted file]
test/regress/regress0/unconstrained/4486.smt2 [deleted file]
test/regress/regress1/strings/norn-ab.smt2

index 08e6f317c6898e8c4fac1a859f5a8f9b63717c9a..449c0c31ecc1785055f5b180d3290d1c4edd8391 100644 (file)
@@ -346,7 +346,7 @@ header = "options/smt_options.h"
   long       = "unconstrained-simp"
   type       = "bool"
   default    = "false"
-  help       = "turn on unconstrained simplification (see Bruttomesso/Brummayer PhD thesis)"
+  help       = "turn on unconstrained simplification (see Bruttomesso/Brummayer PhD thesis). Fully supported only in (subsets of) the logic QF_ABV."
 
 [[option]]
   name       = "repeatSimp"
index 081990a45120bdd0f76b34dc44cc9391427cd5e2..f29e033803965a4e84299ec9bbba4150e84761b7 100644 (file)
@@ -1692,7 +1692,13 @@ termNonVariable[CVC4::api::Term& expr, CVC4::api::Term& expr2]
   std::vector<api::Sort> argTypes;
 }
   : LPAREN_TOK quantOp[kind]
-    { PARSER_STATE->pushScope(true); }
+    {
+      if (!PARSER_STATE->isTheoryEnabled(theory::THEORY_QUANTIFIERS))
+      {
+        PARSER_STATE->parseError("Quantifier used in non-quantified logic.");
+      }
+      PARSER_STATE->pushScope(true);
+    }
     boundVarList[bvl]
     term[f, f2] RPAREN_TOK
     {
index 5d544ae57284a1b5fc45820148daf6dacd749ef5..b7490982444d7b41b540d99a6caa8213c6aefbaa 100644 (file)
@@ -91,6 +91,15 @@ void UnconstrainedSimplifier::visitAll(TNode assertion)
         d_unconstrained.insert(current);
       }
     }
+    else if (current.isClosure())
+    {
+      // Throw an exception. This should never happen in practice unless the
+      // user specifically enabled unconstrained simplification in an illegal
+      // logic.
+      throw LogicException(
+          "Cannot use unconstrained simplification in this logic, due to "
+          "(possibly internally introduced) quantified formula.");
+    }
     else
     {
       for (TNode childNode : current)
index ac4fd0a036f78b2980033b3ec7a1b5d6fe0b3ba5..7fc13e17d515f871dd911933e388649773a3743c 100644 (file)
@@ -62,7 +62,11 @@ class UnconstrainedSimplifier : public PreprocessingPass
   theory::SubstitutionMap d_substitutions;
 
   const LogicInfo& d_logicInfo;
-
+  /**
+   * Visit all subterms in assertion. This method throws a LogicException if
+   * there is a subterm that is unhandled by this preprocessing pass (e.g. a
+   * quantified formula).
+   */
   void visitAll(TNode assertion);
   Node newUnconstrainedVar(TypeNode t, TNode var);
   void processUnconstrained();
index b66d4e973ca678c0636b2e08cd4392aea902dea6..801f38b294e17d906c91fdf9e28c37ece557fd34 100644 (file)
@@ -740,6 +740,7 @@ set(regress_0_tests
   regress0/quantifiers/issue3655.smt2
   regress0/quantifiers/issue4086-infs.smt2
   regress0/quantifiers/issue4275-qcf-cegqi-rep.smt2
+  regress0/quantifiers/issue4437-unc-quant.smt2
   regress0/quantifiers/issue4476-ext-rew.smt2
   regress0/quantifiers/lra-triv-gn.smt2
   regress0/quantifiers/macros-int-real.smt2
@@ -1127,8 +1128,6 @@ set(regress_0_tests
   regress0/uflra/simple.03.cvc
   regress0/uflra/simple.04.cvc
   regress0/unconstrained/4481.smt2
-  regress0/unconstrained/4484.smt2
-  regress0/unconstrained/4486.smt2
   regress0/unconstrained/arith.smt2
   regress0/unconstrained/arith3.smt2
   regress0/unconstrained/arith4.smt2
diff --git a/test/regress/regress0/quantifiers/issue4437-unc-quant.smt2 b/test/regress/regress0/quantifiers/issue4437-unc-quant.smt2
new file mode 100644 (file)
index 0000000..61f7929
--- /dev/null
@@ -0,0 +1,7 @@
+; EXPECT: (error "Parse Error: issue4437-unc-quant.smt2:6.15: Quantifier used in non-quantified logic.")
+; EXIT: 1
+(set-logic QF_AUFBVLIA)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+(assert (forall ((c (_ BitVec 8))) (= (bvashr c a) b)))
+(check-sat)
index 0286070938886d64b503c2d68180ecb59e4318af..19179f4d70592ba19408f9c6cebaf5d6a4741978 100644 (file)
@@ -1,5 +1,6 @@
 ; COMMAND-LINE: --unconstrained-simp
-; EXPECT: unsat
+; EXPECT: (error "Cannot use unconstrained simplification in this logic, due to (possibly internally introduced) quantified formula.")
+; EXIT: 1
 (set-logic ALL)
 (set-info :status unsat)
 (declare-fun a () Int)
diff --git a/test/regress/regress0/unconstrained/4484.smt2 b/test/regress/regress0/unconstrained/4484.smt2
deleted file mode 100644 (file)
index f2f1129..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-; COMMAND-LINE: --unconstrained-simp
-; EXPECT: unsat
-(set-logic QF_NIRA)
-(set-info :status unsat)
-(declare-fun a () Real)
-(assert (= (to_int a) 2))
-(assert (= (to_int (/ a 2.0)) 2))
-(check-sat)
diff --git a/test/regress/regress0/unconstrained/4486.smt2 b/test/regress/regress0/unconstrained/4486.smt2
deleted file mode 100644 (file)
index 01771ce..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-; COMMAND-LINE: --unconstrained-simp
-; EXPECT: sat
-(set-logic ALL)
-(set-info :status sat)
-(declare-fun x () Real)
-(assert (is_int x))
-(assert (is_int (+ x 1)))
-(check-sat)
index 63a95bb78ea8f4de4207cb6f9589f617c648bf46..6109a01dd66bf799cdc326f3fa4c60721f7339ed 100644 (file)
@@ -1,5 +1,5 @@
 (set-info :smt-lib-version 2.6)
-(set-logic QF_SLIA)
+(set-logic SLIA)
 (set-info :status unsat)
 (set-option :strings-exp true)