bv2int: implementing the iand-sum mode (#5265)
authoryoni206 <yoni206@users.noreply.github.com>
Wed, 14 Oct 2020 19:40:13 +0000 (12:40 -0700)
committerGitHub <noreply@github.com>
Wed, 14 Oct 2020 19:40:13 +0000 (14:40 -0500)
There are 3 potential modes to lazily treat the iand operator:
(1) by value (typical CEGAR loop)
(2) by sum (lazily expanding each iand node into a sum of ITEs)
(3) by bit-wise equalities (lazily expanding each iand node into bit-wise equalities)

This PR implements (2).

The relevant option is added to existing tests, and a new test is added. In a few other tests, some options are removed to make them run faster.

18 files changed:
src/theory/arith/inference_id.cpp
src/theory/arith/inference_id.h
src/theory/arith/nl/iand_solver.cpp
src/theory/arith/nl/iand_solver.h
src/theory/arith/nl/iand_table.cpp
test/regress/CMakeLists.txt
test/regress/regress0/bv/bv_to_int1.smt2
test/regress/regress1/nl/iand-native-1.smt2
test/regress/regress1/nl/iand-native-2.smt2 [new file with mode: 0644]
test/regress/regress2/bv_to_int2.smt2
test/regress/regress2/bv_to_int_ashr.smt2
test/regress/regress2/bv_to_int_bitwise.smt2
test/regress/regress2/bv_to_int_bvmul1.smt2
test/regress/regress2/bv_to_int_mask_array_1.smt2
test/regress/regress2/bv_to_int_mask_array_2.smt2
test/regress/regress3/bv_to_int_check_bvsge_bvashr0_4bit.smt2.minimized.smt2
test/regress/regress3/bv_to_int_check_bvsgt_bvlshr0_4bit.smt2.minimized.smt2
test/regress/regress3/bv_to_int_input_mouser_detect.c.smt2.minimized.smt2

index a0dc19d81f6216b6d8ff30ae57d898712fe5039d..a93a980ba7fb120ebb31700e083107ac4e77a6f9 100644 (file)
@@ -40,6 +40,7 @@ const char* toString(InferenceId i)
     case InferenceId::NL_T_TANGENT: return "T_TANGENT";
     case InferenceId::NL_IAND_INIT_REFINE: return "IAND_INIT_REFINE";
     case InferenceId::NL_IAND_VALUE_REFINE: return "IAND_VALUE_REFINE";
+    case InferenceId::NL_IAND_SUM_REFINE: return "IAND_SUM_REFINE";
     case InferenceId::NL_CAD_CONFLICT: return "CAD_CONFLICT";
     case InferenceId::NL_CAD_EXCLUDED_INTERVAL: return "CAD_EXCLUDED_INTERVAL";
     case InferenceId::NL_ICP_CONFLICT: return "ICP_CONFLICT";
index 1940e2ef3e86107b9f6a342de6075f74d0822bc8..c01cd2c8e78d2600cfa30ad1be5fcbacaa1099d1 100644 (file)
@@ -71,6 +71,8 @@ enum class InferenceId : uint32_t
   NL_IAND_INIT_REFINE,
   // value refinements (IAndSolver::checkFullRefine)
   NL_IAND_VALUE_REFINE,
+  // sum refinements (IAndSulver::checkFullRefine)
+  NL_IAND_SUM_REFINE,
   //-------------------- cad solver
   // conflict / infeasible subset obtained from cad
   NL_CAD_CONFLICT,
index 954f921ce1749311b1155a3921624a6c5c118d91..30441a8f48faa14ba3a7f562de1e90b8fa93d1f4 100644 (file)
@@ -148,7 +148,10 @@ void IAndSolver::checkFullRefine()
       // ************* additional lemma schemas go here
       if (options::iandMode() == options::IandMode::SUM)
       {
-        // add lemmas based on sum mode
+        Node lem = sumBasedLemma(i);  // add lemmas based on sum mode
+        Trace("iand-lemma")
+            << "IAndSolver::Lemma: " << lem << " ; SUM_REFINE" << std::endl;
+        d_im.addPendingArithLemma(lem, InferenceId::NL_IAND_SUM_REFINE, true);
       }
       else if (options::iandMode() == options::IandMode::BITWISE)
       {
@@ -245,6 +248,18 @@ Node IAndSolver::valueBasedLemma(Node i)
   return lem;
 }
 
+Node IAndSolver::sumBasedLemma(Node i)
+{
+  Assert(i.getKind() == IAND);
+  Node x = i[0];
+  Node y = i[1];
+  size_t bvsize = i.getOperator().getConst<IntAnd>().d_size;
+  uint64_t granularity = options::BVAndIntegerGranularity();
+  NodeManager* nm = NodeManager::currentNM();
+  Node lem = nm->mkNode(
+      EQUAL, i, d_iandTable.createBitwiseNode(x, y, bvsize, granularity));
+  return lem;
+}
 
 }  // namespace nl
 }  // namespace arith
index d743657848847541fdcd63a887f2b2b3c7bd41b9..e00cb92a9b483a81789c302d874019a4cc9d1088 100644 (file)
@@ -22,6 +22,7 @@
 #include "expr/node.h"
 #include "theory/arith/arith_state.h"
 #include "theory/arith/inference_manager.h"
+#include "theory/arith/nl/iand_table.h"
 #include "theory/arith/nl/nl_lemma_utils.h"
 #include "theory/arith/nl/nl_model.h"
 
@@ -88,6 +89,7 @@ class IAndSolver
   Node d_two;
   Node d_true;
   Node d_false;
+  IAndTable d_iandTable;
   /** IAND terms that have been given initial refinement lemmas */
   NodeSet d_initRefine;
   /** all IAND terms, for each bit-width */
@@ -118,6 +120,13 @@ class IAndSolver
    *     ((_ iand k) x y) = Rewriter::rewrite(((_ iand k) M(x) M(y)))
    */
   Node valueBasedLemma(Node i);
+  /**
+   * Sum-based refinement lemma for i of the form ((_ iand k) x y). Returns:
+   * i = 2^0*min(x[0],y[0])+...2^{k-1}*min(x[k-1],y[k-1])
+   * where x[i] is x div i mod 2
+   * and min is defined with an ite.
+   */
+  Node sumBasedLemma(Node i);
 }; /* class IAndSolver */
 
 }  // namespace nl
index 12e06ed58e4ae4d8cf0da09b7e902c7f8a106d0f..050e6baed305c5135d696b645eb2b11ba68de639 100644 (file)
@@ -198,7 +198,7 @@ void IAndTable::addDefaultValue(
   }
 
   // compute the most common result
-  uint64_t most_common_result;
+  uint64_t most_common_result = 0;
   uint64_t max_num_of_occ = 0;
   for (uint64_t i = 0; i <= num_of_values; i++)
   {
@@ -208,6 +208,9 @@ void IAndTable::addDefaultValue(
       most_common_result = i;
     }
   }
+  // sanity check: some value appears at least once.
+  Assert(max_num_of_occ != 0);
+
   // -1 is the default case of the table.
   // add it to the table
   table[std::make_pair(-1, -1)] = most_common_result;
index aedc27924aacf4fc9f45891f1947ba957dedec05..428d35f8d8281aefc3912b05b9f7a5388d35e94d 100644 (file)
@@ -1433,6 +1433,7 @@ set(regress_1_tests
   regress1/nl/exp_monotone.smt2
   regress1/nl/factor_agg_s.smt2
   regress1/nl/iand-native-1.smt2
+  regress1/nl/iand-native-2.smt2
   regress1/nl/issue3300-approx-sqrt-witness.smt2
   regress1/nl/issue3441.smt2
   regress1/nl/issue3617.smt2
index 8410d04b9de7c80c894ab38b364486667cc531d9..3908cdb162801e8213aae257ba0cd2d598e68737 100644 (file)
@@ -1,7 +1,4 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=2
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=3
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=4
 ; EXPECT: unsat
 (set-logic QF_BV)
 (declare-fun x () (_ BitVec 4))
index 685922f8802e3792e630886549270fc453c457ac..e6a25bcc47f673835927d2214728ef66e4138019 100644 (file)
@@ -1,4 +1,5 @@
 ; COMMAND-LINE: --iand-mode=value
+; COMMAND-LINE: --iand-mode=sum --bvand-integer-granularity=1 --finite-model-find
 ; EXPECT: sat
 (set-logic QF_NIA)
 (set-info :status sat)
diff --git a/test/regress/regress1/nl/iand-native-2.smt2 b/test/regress/regress1/nl/iand-native-2.smt2
new file mode 100644 (file)
index 0000000..6b39598
--- /dev/null
@@ -0,0 +1,15 @@
+; COMMAND-LINE: --iand-mode=value
+; COMMAND-LINE: --iand-mode=sum --bvand-integer-granularity=1
+; EXPECT: unsat
+(set-logic QF_NIA)
+(set-info :status unsat)
+(declare-fun x () Int)
+(declare-fun y () Int)
+
+(assert (and (<= 0 x) (< x 16)))
+(assert (and (<= 0 y) (< y 16)))
+(assert (> ((_ iand 4) x y) 0))
+(assert (= (* x y) 0))
+(assert (= (+ x y) 15))
+
+(check-sat)
index 4c1ca0c002c25356b14031266cbcca5f7a447f34..424e95b27b9550f18ad227a77d4339970fbd1e81 100644 (file)
@@ -1,6 +1,4 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=5
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=8
 ; EXPECT: sat
 (set-logic QF_BV)
 (declare-fun a () (_ BitVec 8))
index b95dc6b7f6600109c07b73c0856c68ee6b3a5b2c..0c67685464608080ecc0acd15f562e90672c7d66 100644 (file)
@@ -1,5 +1,4 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=8
 ; EXPECT: unsat
 (set-logic QF_BV)
 (declare-fun a () (_ BitVec 8))
index 373f9c323910b41260606fcef6c06c9854d63c7e..66d9e237917e63d74e7dc1e22b93a9bf208d2e39 100644 (file)
@@ -1,6 +1,7 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1 --no-check-unsat-cores
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=5 --no-check-unsat-cores
-; COMMAND-LINE: --solve-bv-as-int=iand --no-check-unsat-cores
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=value --no-check-unsat-cores
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=sum --no-check-unsat-cores
 ; COMMAND-LINE: --solve-bv-as-int=bv --no-check-unsat-cores
 ; EXPECT: unsat
 (set-logic QF_BV)
index cfd5c4b9a39e5c307ff40c726d8c264eb5102bd0..232959f33322404d1c1ae8e8bfc72d50f9494120 100644 (file)
@@ -1,6 +1,4 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=4
-; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=8
 ; EXPECT: sat
 (set-logic QF_BV)
 (declare-fun a () (_ BitVec 8))
index b1c8b95096b6cc231b83d76638e3223a9edb719d..d587735e57ac0777c476a54ef7461be7d339bc76 100644 (file)
@@ -1,5 +1,6 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1 --no-check-unsat-cores
-; COMMAND-LINE: --solve-bv-as-int=iand --no-check-unsat-cores
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=value --no-check-unsat-cores
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=sum --no-check-unsat-cores
 ; COMMAND-LINE: --solve-bv-as-int=bv --no-check-unsat-cores
 ; EXPECT: unsat
 (set-logic ALL)
index c054f9693bfd86d36ef10f46d86eb4a40caaefeb..edcc14149b8f22e88259b8bc84d199c915cfb1d1 100644 (file)
@@ -1,5 +1,6 @@
 ; COMMAND-LINE: --solve-bv-as-int=sum --bvand-integer-granularity=1
-; COMMAND-LINE: --solve-bv-as-int=iand
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=value
+; COMMAND-LINE: --solve-bv-as-int=iand --iand-mode=sum
 ; COMMAND-LINE: --solve-bv-as-int=bv
 ; EXPECT: sat
 (set-logic ALL)
index 67f8f69ad4ce5ace6f8df1103469c11e36b23a07..5c96417d5dc3d2f1665339b9d96e5504f7255ddb 100644 (file)
@@ -1,5 +1,4 @@
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=1 --solve-bv-as-int=sum      --no-check-models
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=2 --solve-bv-as-int=sum      --no-check-models
+; COMMAND-LINE:  --solve-bv-as-int=sum  --no-check-models
 ; EXPECT: sat
 (set-logic BV)
 (declare-fun s () (_ BitVec 3))
index 30088388230e82d40170779b0f1fdb87e5bab1f0..ed8543050073b28b1c6b2c200d569c42e7942435 100644 (file)
@@ -1,9 +1,7 @@
 ; COMMAND-LINE:  --solve-bv-as-int=bv 
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=1 --solve-bv-as-int=sum     
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=1 --solve-bv-as-int=iand --iand-mode=sum    
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=1 --solve-bv-as-int=iand --iand-mode=bitwise    
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=1 --solve-bv-as-int=iand    
-; COMMAND-LINE:  --cegqi-all --full-saturate-quant --bvand-integer-granularity=2 --solve-bv-as-int=sum     
+; COMMAND-LINE:  --solve-bv-as-int=sum     
+; COMMAND-LINE:  --solve-bv-as-int=iand --iand-mode=sum    
+; COMMAND-LINE:  --solve-bv-as-int=iand --iand-mode=value
 ; EXPECT: unsat
 (set-logic ALL)
 (declare-fun t () (_ BitVec 4))
index 576ebf9627f21371f9958004cbcafef0f4ebcb2e..dd7e11a5097364b2992e7a7d9ada3451f9511c88 100644 (file)
@@ -1,3 +1,4 @@
+; COMMAND-LINE:  --solve-bv-as-int=bv  --no-check-models
 ; COMMAND-LINE:  --bvand-integer-granularity=1 --solve-bv-as-int=sum --full-saturate-quant --cegqi-all  --no-check-models  
 ;EXPECT: sat
 (set-logic BV)