int2bv: Fix conversion of signed bit-vector values. (#7061)
authorMathias Preiner <mathias.preiner@gmail.com>
Thu, 26 Aug 2021 00:50:53 +0000 (17:50 -0700)
committerGitHub <noreply@github.com>
Thu, 26 Aug 2021 00:50:53 +0000 (00:50 +0000)
This commit fixes the conversion of signed bit-vector values to integers in the int-to-bv preprocessing pass.

src/preprocessing/passes/int_to_bv.cpp
test/regress/CMakeLists.txt
test/regress/regress0/bv/int_to_bv_model2.smt2 [new file with mode: 0644]

index 8c18ccf541af1edf1560ed220a093fdd24673774..41d52d1ae9637eb0b07ec4d345fcff7dad5c8070 100644 (file)
@@ -217,8 +217,20 @@ Node IntToBV::intToBV(TNode n, NodeMap& cache)
           result = sm->mkDummySkolem("__intToBV_var",
                                      nm->mkBitVectorType(size),
                                      "Variable introduced in intToBV pass");
-          Node bv2nat = nm->mkNode(kind::BITVECTOR_TO_NAT, result);
-          d_preprocContext->addSubstitution(current, bv2nat);
+          /**
+           * Correctly convert signed/unsigned BV values to Integers as follows
+           * x < 0 ? -nat(-x) : nat(x)
+           * where x refers to the bit-vector term `result`.
+           */
+          BitVector bvzero(size, Integer(0));
+          Node negResult = nm->mkNode(kind::BITVECTOR_TO_NAT,
+                                      nm->mkNode(kind::BITVECTOR_NEG, result));
+          Node bv2int = nm->mkNode(
+              kind::ITE,
+              nm->mkNode(kind::BITVECTOR_SLT, result, nm->mkConst(bvzero)),
+              nm->mkNode(kind::UMINUS, negResult),
+              nm->mkNode(kind::BITVECTOR_TO_NAT, result));
+          d_preprocContext->addSubstitution(current, bv2int);
         }
       }
       else if (current.isConst())
index ce047c877a453f2970bf9492b348583038f55da9..ec6d04c1db3090ebade4689a64decdc67185afc5 100644 (file)
@@ -420,6 +420,7 @@ set(regress_0_tests
   regress0/bv/inequality05.smt2
   regress0/bv/int_to_bv_err_on_demand_1.smt2
   regress0/bv/int_to_bv_model.smt2
+  regress0/bv/int_to_bv_model2.smt2
   regress0/bv/issue-4075.smt2
   regress0/bv/issue-4076.smt2
   regress0/bv/issue-4130.smt2
diff --git a/test/regress/regress0/bv/int_to_bv_model2.smt2 b/test/regress/regress0/bv/int_to_bv_model2.smt2
new file mode 100644 (file)
index 0000000..d4ad969
--- /dev/null
@@ -0,0 +1,6 @@
+; COMMAND-LINE: --solve-int-as-bv=5 --check-models
+(set-logic QF_NIA)
+(set-info :status sat)
+(declare-const x Int)
+(assert (< x 0))
+(check-sat)