Enable eager bitblasting for QF_ABV when no stores are present.
authorClark Barrett <barrett@cs.stanford.edu>
Fri, 11 Nov 2016 22:41:51 +0000 (14:41 -0800)
committerClark Barrett <barrett@cs.stanford.edu>
Fri, 11 Nov 2016 22:41:51 +0000 (14:41 -0800)
src/smt/smt_engine.cpp
src/theory/bv/theory_bv.cpp

index e46511e59e863ffbe810b2b98c916247f3494ec8..38347508cabc7860e9eda2b6bfbec6bbda39dba6 100644 (file)
@@ -1291,7 +1291,8 @@ void SmtEngine::setDefaults() {
   }
   else if (options::solveIntAsBV() > 0) {
     d_logic = LogicInfo("QF_BV");
-  } else if (d_logic.getLogicString() == "QF_UFBV" &&
+  } else if ((d_logic.getLogicString() == "QF_UFBV" ||
+              d_logic.getLogicString() == "QF_ABV") &&
              options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER) {
     d_logic = LogicInfo("QF_BV");
   }
@@ -3871,7 +3872,8 @@ void SmtEnginePrivate::processAssertions() {
 
   if (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER &&
       !d_smt.d_logic.isPure(THEORY_BV) &&
-      d_smt.d_logic.getLogicString() != "QF_UFBV") {
+      d_smt.d_logic.getLogicString() != "QF_UFBV" &&
+      d_smt.d_logic.getLogicString() != "QF_ABV") {
     throw ModalException("Eager bit-blasting does not currently support theory combination. "
                          "Note that in a QF_BV problem UF symbols can be introduced for division. "
                          "Try --bv-div-zero-const to interpret division by zero as a constant.");
index 869e59502a6dbbeb2ddb652b14736fd12f6239a4..139559125e8ca3a3945a6f73460db625bf9e384c 100644 (file)
@@ -194,6 +194,11 @@ void TheoryBV::collectFunctionSymbols(TNode term, TNodeSet& seen) {
   if (term.getKind() == kind::APPLY_UF) {
     TNode func = term.getOperator();
     storeFunction(func, term);
+  } else if (term.getKind() == kind::SELECT) {
+    TNode func = term[0];
+    storeFunction(func, term);
+  } else if (term.getKind() == kind::STORE) {
+    AlwaysAssert(false, "Cannot use eager bitblasting on QF_ABV formula with stores");
   }
   for (unsigned i = 0; i < term.getNumChildren(); ++i) {
     collectFunctionSymbols(term[i], seen);
@@ -233,20 +238,30 @@ void TheoryBV::mkAckermanizationAsssertions(std::vector<Node>& assertions) {
       for(NodeSet::const_iterator it2 = it1; it2 != args.end(); ++it2) {
         TNode args1 = *it1;
         TNode args2 = *it2;
+        Node args_eq;
+        
+        if (args1.getKind() == kind::APPLY_UF) {
+          AlwaysAssert (args1.getKind() == kind::APPLY_UF &&
+                        args1.getOperator() == func);
+          AlwaysAssert (args2.getKind() == kind::APPLY_UF &&
+                        args2.getOperator() == func);
+          AlwaysAssert (args1.getNumChildren() == args2.getNumChildren());
 
-        AlwaysAssert (args1.getKind() == kind::APPLY_UF &&
-                args1.getOperator() == func);
-        AlwaysAssert (args2.getKind() == kind::APPLY_UF &&
-                args2.getOperator() == func);
-        AlwaysAssert (args1.getNumChildren() == args2.getNumChildren());
-
-        std::vector<Node> eqs(args1.getNumChildren());
+          std::vector<Node> eqs(args1.getNumChildren());
 
-        for (unsigned i = 0; i < args1.getNumChildren(); ++i) {
-          eqs[i] = nm->mkNode(kind::EQUAL, args1[i], args2[i]);
+          for (unsigned i = 0; i < args1.getNumChildren(); ++i) {
+            eqs[i] = nm->mkNode(kind::EQUAL, args1[i], args2[i]);
+          }
+          args_eq = eqs.size() == 1 ? eqs[0] : nm->mkNode(kind::AND, eqs);
+        } else {
+          AlwaysAssert (args1.getKind() == kind::SELECT &&
+                        args1[0] == func);
+          AlwaysAssert (args2.getKind() == kind::SELECT &&
+                        args2[0] == func);
+          AlwaysAssert (args1.getNumChildren() == 2);
+          AlwaysAssert (args2.getNumChildren() == 2);
+          args_eq = nm->mkNode(kind::EQUAL, args1[1], args2[1]);
         }
-
-        Node args_eq = eqs.size() == 1 ? eqs[0] : nm->mkNode(kind::AND, eqs);
         Node func_eq = nm->mkNode(kind::EQUAL, args1, args2);
         Node lemma = nm->mkNode(kind::IMPLIES, args_eq, func_eq);
         assertions.push_back(lemma);