Add explicit disequality handling when generating side condition for CBQI BV. (#1447)
authorAina Niemetz <aina.niemetz@gmail.com>
Thu, 21 Dec 2017 02:27:39 +0000 (18:27 -0800)
committerGitHub <noreply@github.com>
Thu, 21 Dec 2017 02:27:39 +0000 (18:27 -0800)
This refactors solveBvLit to support explicit handling of disequalities (and, in the next step, inequalities) when generating side conditions.

49 files changed:
src/theory/quantifiers/bv_inverter.cpp
src/theory/quantifiers/bv_inverter.h
src/theory/quantifiers/ceg_t_instantiator.cpp
src/theory/quantifiers/ceg_t_instantiator.h
test/regress/regress0/quantifiers/Makefile.am
test/regress/regress0/quantifiers/qbv-disequality3.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-inequality2.smt2
test/regress/regress0/quantifiers/qbv-multi-lit-uge.smt2
test/regress/regress0/quantifiers/qbv-simp.smt2
test/regress/regress0/quantifiers/qbv-simple-2vars-vo.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvadd-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvand-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvand.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvashr-0-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvashr-0.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvcomp.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-0-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-0.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvmul-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvmul.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvor-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvor.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvult-1.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvurem-1-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvurem-1.smt2
test/regress/regress0/quantifiers/qbv-test-invert-bvxor-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-bvxor.smt2
test/regress/regress0/quantifiers/qbv-test-invert-concat-0-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-concat-0.smt2
test/regress/regress0/quantifiers/qbv-test-invert-concat-1-neq.smt2 [new file with mode: 0644]
test/regress/regress0/quantifiers/qbv-test-invert-concat-1.smt2
test/regress/regress0/quantifiers/qbv-test-invert-disequality.smt2 [deleted file]
test/regress/regress0/quantifiers/qbv-test-invert-mul.smt2 [deleted file]
test/regress/regress0/quantifiers/qbv-test-invert-shl.smt2 [deleted file]
test/regress/regress0/quantifiers/qbv-test-invert-sign-extend.smt2
test/regress/regress0/quantifiers/qbv-test-invert-udiv-0.smt2 [deleted file]
test/regress/regress0/quantifiers/qbv-test-invert-udiv-1.smt2 [deleted file]
test/regress/regress0/quantifiers/qbv-test-urem-rewrite.smt2
test/unit/theory/theory_quantifiers_bv_inverter_white.h

index 0ac22a3e4db04576847d7017ec3db58383a9fe10..11d6ba85d4a6f9383f7d080945431fbba70c39ec 100644 (file)
@@ -50,6 +50,8 @@ Node BvInverter::getSolveVariable(TypeNode tn)
 
 Node BvInverter::getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m)
 {
+  TNode solve_var = getSolveVariable(tn);
+
   // condition should be rewritten
   Node new_cond = Rewriter::rewrite(cond);
   if (new_cond != cond)
@@ -58,11 +60,10 @@ Node BvInverter::getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m)
                                    << " was rewritten to " << new_cond
                                    << std::endl;
   }
+  // optimization : if condition is ( x = solve_var ) should just return
+  // solve_var and not introduce a Skolem this can happen when we ask for
+  // the multiplicative inversion with bv1
   Node c;
-  // optimization : if condition is ( x = v ) should just return v and not
-  // introduce a Skolem this can happen when we ask for the multiplicative
-  // inversion with bv1
-  TNode solve_var = getSolveVariable(tn);
   if (new_cond.getKind() == EQUAL)
   {
     for (unsigned i = 0; i < 2; i++)
@@ -225,6 +226,8 @@ static Node getScBvUlt(bool pol, Kind k, unsigned idx, Node x, Node t)
     }
     else
     {
+      /* x >= t
+       * no side condition  */
       sc = nm->mkNode(NOT, nm->mkNode(k, x, t));
     }
   }
@@ -241,6 +244,8 @@ static Node getScBvUlt(bool pol, Kind k, unsigned idx, Node x, Node t)
     }
     else
     {
+      /* t >= x
+       * no side condition */
       sc = nm->mkNode(NOT, nm->mkNode(k, t, x));
     }
   }
@@ -270,6 +275,8 @@ static Node getScBvSlt(bool pol, Kind k, unsigned idx, Node x, Node t)
     }
     else
     {
+      /* x >= t
+       * no side condition */
       sc = nm->mkNode(NOT, nm->mkNode(k, x, t));
     }
   }
@@ -288,6 +295,8 @@ static Node getScBvSlt(bool pol, Kind k, unsigned idx, Node x, Node t)
     }
     else
     {
+      /* t >= x
+       * no side condition */
       sc = nm->mkNode(NOT, nm->mkNode(k, t, x));
     }
   }
@@ -295,392 +304,617 @@ static Node getScBvSlt(bool pol, Kind k, unsigned idx, Node x, Node t)
   return sc;
 }
 
-static Node getScBvEq(bool pol, Kind k, unsigned idx, Node x, Node t)
-{
-  Assert(k == EQUAL);
-  Assert(pol == false);
-
-  NodeManager* nm = NodeManager::currentNM();
-  unsigned w = bv::utils::getSize(t);
-
-  /* x != t
-   * <->
-   * x < t || x > t  (ULT)
-   * with side condition:
-   * t != 0 || t != ~0  */
-  Node scl = nm->mkNode(OR,
-      nm->mkNode(DISTINCT, t, bv::utils::mkZero(w)),
-      nm->mkNode(DISTINCT, t, bv::utils::mkOnes(w)));
-  Node scr = nm->mkNode(DISTINCT, x, t);
-  Node sc = nm->mkNode(IMPLIES, scl, scr);
-  Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
-  return sc;
-}
-
-static Node getScBvMult(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvMult(bool pol,
+                        Kind litk,
+                        Kind k,
+                        unsigned idx,
+                        Node x,
+                        Node s,
+                        Node t)
 {
   Assert(k == BITVECTOR_MULT);
 
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
+  Node scl, scr;
+  Node z = bv::utils::mkZero(bv::utils::getSize(s));
+
+  if (pol)
+  {
+    /* x * s = t
+     * with side condition:
+     * ctz(t) >= ctz(s) <-> x * s = t
+     * where
+     * ctz(t) >= ctz(s) -> t = 0 \/ ((t & -t) >= (s & -s) /\ s != 0) */
+    Node t_uge_s = nm->mkNode(BITVECTOR_UGE,
+        nm->mkNode(BITVECTOR_AND, t, nm->mkNode(BITVECTOR_NEG, t)),
+        nm->mkNode(BITVECTOR_AND, s, nm->mkNode(BITVECTOR_NEG, s)));
+    scl = nm->mkNode(OR,
+        t.eqNode(z),
+        nm->mkNode(AND, t_uge_s, s.eqNode(z).notNode()));
+    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+  }
+  else
+  {
+    /* x * s != t
+     * with side condition:
+     * t != 0 || s != 0 */
+    scl = nm->mkNode(OR, t.eqNode(z).notNode(), s.eqNode(z).notNode());
+    scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+  }
 
-  /* x * s = t
-   * with side condition:
-   * ctz(t) >= ctz(s) <-> x * s = t
-   * where
-   * ctz(t) >= ctz(s) -> t = 0 \/ ((t & -t) >= (s & -s) /\ s != 0) */
-  Node zero = bv::utils::mkZero(bv::utils::getSize(s));
-  Node t_uge_s = nm->mkNode(BITVECTOR_UGE,
-      nm->mkNode(BITVECTOR_AND, t, nm->mkNode(BITVECTOR_NEG, t)),
-      nm->mkNode(BITVECTOR_AND, s, nm->mkNode(BITVECTOR_NEG, s)));
-  Node scl = nm->mkNode(OR,
-      t.eqNode(zero),
-      nm->mkNode(AND, t_uge_s, s.eqNode(zero).notNode()));
-  Node scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
   Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvUrem(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvUrem(bool pol,
+                        Kind litk,
+                        Kind k,
+                        unsigned idx,
+                        Node x,
+                        Node s,
+                        Node t)
 {
   Assert(k == BITVECTOR_UREM_TOTAL);
-  Assert(idx == 1);
+  Assert(pol == false || idx == 1);
+
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
 
   NodeManager* nm = NodeManager::currentNM();
+  Node scl, scr;
+  unsigned w = bv::utils::getSize(s);
+  Assert (w == bv::utils::getSize(t));
+  Node z = bv::utils::mkZero(w);
 
-  /* s % x = t
-   * with side condition:
-   * s = t
-   * ||
-   * ( s > t
-   *   && s-t > t
-   *   && (t = 0 || t != s-1) )  */
-
-  Node a1 =  // s > t
-    nm->mkNode(BITVECTOR_UGT, s, t);
-  Node a2 =  // s-t > t
-    nm->mkNode(BITVECTOR_UGT, nm->mkNode(BITVECTOR_SUB, s, t), t);
-  Node a3 =  // (t = 0 || t != s-1)
-    nm->mkNode(OR,
-        t.eqNode(bv::utils::mkZero(bv::utils::getSize(t))),
-        t.eqNode(bv::utils::mkDec(s)).notNode());
-
-  Node scl = nm->mkNode(OR,
-        t.eqNode(s),
-        nm->mkNode(AND, a1, nm->mkNode(AND, a2, a3)));
-  Node scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
-  Node sc = nm->mkNode(IMPLIES, scl, scr);
+  if (idx == 0)
+  {
+    Assert (pol == false);
+    /* x % s != t
+     * with side condition:
+     * s != 1 || t != 0  */
+    scl = nm->mkNode(OR,
+        s.eqNode(bv::utils::mkOne(w)).notNode(),
+        t.eqNode(z).notNode());
+    scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+  }
+  else
+  {
+    if (pol)
+    {
+      /* s % x = t
+       * with side condition:
+       * s = t
+       * ||
+       * ( s > t
+       *   && s-t > t
+       *   && (t = 0 || t != s-1) )  */
+
+      Node a1 = nm->mkNode(BITVECTOR_UGT, s, t);
+      Node a2 = nm->mkNode(BITVECTOR_UGT, nm->mkNode(BITVECTOR_SUB, s, t), t);
+      Node a3 = nm->mkNode(OR,
+          t.eqNode(z),
+          t.eqNode(bv::utils::mkDec(s)).notNode());
+
+      scl = nm->mkNode(OR,
+            t.eqNode(s),
+            nm->mkNode(AND, a1, nm->mkNode(AND, a2, a3)));
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    }
+    else
+    {
+      /* s % x != t
+       * with side condition:
+       * s != 0 || t != 0  */
+      scl = nm->mkNode(OR, s.eqNode(z).notNode(), t.eqNode(z).notNode());
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, s, x), t);
+    }
+  }
 
+  Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvUdiv(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvUdiv(bool pol,
+                        Kind litk,
+                        Kind k,
+                        unsigned idx,
+                        Node x,
+                        Node s,
+                        Node t)
 {
   Assert(k == BITVECTOR_UDIV_TOTAL);
 
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
   unsigned w = bv::utils::getSize(s);
   Assert (w == bv::utils::getSize(t));
-  Node scl, scr;
-  Node zero = bv::utils::mkZero(w);
+  Node sc, scl, scr;
+  Node z = bv::utils::mkZero(w);
+  Node n = bv::utils::mkOnes(w);
 
   if (idx == 0)
   {
-    /* x udiv s = t
-     * with side condition:
-     * t = ~0 && (s = 0 || s = 1)
-     * ||
-     * (t != ~0 && s != 0 && !umulo(s * t)) */
-    Node o1 = nm->mkNode(AND,
-        t.eqNode(bv::utils::mkOnes(w)),
-        nm->mkNode(OR,
-          s.eqNode(bv::utils::mkZero(w)),
-          s.eqNode(bv::utils::mkOne(w))));
-    Node o2 = nm->mkNode(AND,
-        t.eqNode(bv::utils::mkOnes(w)).notNode(),
-        s.eqNode(bv::utils::mkZero(w)).notNode(),
-        nm->mkNode(NOT, bv::utils::mkUmulo(s, t)));
-
-    scl = nm->mkNode(OR, o1, o2);
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    if (pol)
+    {
+      /* x udiv s = t
+       * with side condition:
+       * t = ~0 && (s = 0 || s = 1)
+       * ||
+       * (t != ~0 && s != 0 && !umulo(s * t)) */
+      Node one = bv::utils::mkOne(w);
+      Node o1 = nm->mkNode(AND,
+          t.eqNode(n),
+          nm->mkNode(OR, s.eqNode(z), s.eqNode(one)));
+      Node o2 = nm->mkNode(AND,
+          t.eqNode(n).notNode(),
+          s.eqNode(z).notNode(),
+          nm->mkNode(NOT, bv::utils::mkUmulo(s, t)));
+
+      scl = nm->mkNode(OR, o1, o2);
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    }
+    else
+    {
+      /* x udiv s != t
+       * with side condition:
+       * s != 0 || t != ~0  */
+      scl = nm->mkNode(OR, s.eqNode(z).notNode(), t.eqNode(n).notNode());
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+    }
+    sc = nm->mkNode(IMPLIES, scl, scr);
   }
   else
   {
-    /* s udiv x = t
-     * with side condition:
-     * s = t
-     * ||
-     * t = ~0
-     * ||
-     * (s >= t
-     *  && (s % t = 0 || (s / (t+1) +1) <= s / t)
-     *  && (s = ~0 => t != 0))  */
-
-    Node oo1 = nm->mkNode(EQUAL,
-        nm->mkNode(BITVECTOR_UREM_TOTAL, s, t),
-        bv::utils::mkZero(w));
-
-    Node ule1 = nm->mkNode(BITVECTOR_PLUS,
-        bv::utils::mkOne(w),
-        nm->mkNode(BITVECTOR_UDIV_TOTAL,
-          s, nm->mkNode(BITVECTOR_PLUS, t, bv::utils::mkOne(w))));
-    Node ule2 = nm->mkNode(BITVECTOR_UDIV_TOTAL, s, t);
-    Node oo2 = nm->mkNode(BITVECTOR_ULE, ule1, ule2);
-
-    Node a1 = nm->mkNode(BITVECTOR_UGE, s, t);
-    Node a2 = nm->mkNode(OR, oo1, oo2);
-    Node a3 = nm->mkNode(IMPLIES,
-        s.eqNode(bv::utils::mkOnes(w)),
-        t.eqNode(bv::utils::mkZero(w)).notNode());
-
-    Node o1 = s.eqNode(t);
-    Node o2 = t.eqNode(bv::utils::mkOnes(w));
-    Node o3 = nm->mkNode(AND, a1, a2, a3);
-
-    scl = nm->mkNode(OR, o1, o2, o3);
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    if (pol)
+    {
+      /* s udiv x = t
+       * with side condition:
+       * s = t
+       * ||
+       * t = ~0
+       * ||
+       * (s >= t
+       *  && (s % t = 0 || (s / (t+1) +1) <= s / t)
+       *  && (s = ~0 => t != 0))  */
+      Node oo1 = nm->mkNode(EQUAL, nm->mkNode(BITVECTOR_UREM_TOTAL, s, t), z); 
+      Node udiv = nm->mkNode(BITVECTOR_UDIV_TOTAL, s, bv::utils::mkInc(t));
+      Node ule1 = bv::utils::mkInc(udiv);
+      Node ule2 = nm->mkNode(BITVECTOR_UDIV_TOTAL, s, t);
+      Node oo2 = nm->mkNode(BITVECTOR_ULE, ule1, ule2);
+
+      Node a1 = nm->mkNode(BITVECTOR_UGE, s, t);
+      Node a2 = nm->mkNode(OR, oo1, oo2);
+      Node a3 = nm->mkNode(IMPLIES, s.eqNode(n), t.eqNode(z).notNode());
+
+      Node o1 = s.eqNode(t);
+      Node o2 = t.eqNode(n);
+      Node o3 = nm->mkNode(AND, a1, a2, a3);
+
+      scl = nm->mkNode(OR, o1, o2, o3);
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+      sc = nm->mkNode(IMPLIES, scl, scr);
+    }
+    else
+    {
+      sc = nm->mkNode(DISTINCT, nm->mkNode(k, s, x), t);
+    }
   }
 
-  Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvAndOr(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvAndOr(bool pol,
+                         Kind litk,
+                         Kind k,
+                         unsigned idx,
+                         Node x,
+                         Node s,
+                         Node t)
 {
+  Assert (k == BITVECTOR_AND || k == BITVECTOR_OR);
+
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
-  /* with side condition:
-   * t & s = t
-   * t | s = t */
-  Node scl = nm->mkNode(EQUAL, t, nm->mkNode(k, t, s));
-  Node scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+  Node scl, scr;
+
+  if (pol)
+  {
+    /* x & s = t
+     * x | s = t
+     * with side condition:
+     * t & s = t
+     * t | s = t */
+    scl = nm->mkNode(EQUAL, t, nm->mkNode(k, t, s));
+    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+  }
+  else
+  {
+    unsigned w = bv::utils::getSize(s);
+    Assert (w == bv::utils::getSize(t));
+
+    if (k == BITVECTOR_AND)
+    {
+      /* x & s = t
+       * with side condition:
+       * s != 0 || t != 0  */
+      Node z = bv::utils::mkZero(w);
+      scl = nm->mkNode(OR, s.eqNode(z).notNode(), t.eqNode(z).notNode());
+    }
+    else
+    {
+      /* x | s = t
+       * with side condition:
+       * s != ~0 || t != ~0  */
+      Node n = bv::utils::mkOnes(w);
+      scl = nm->mkNode(OR, s.eqNode(n).notNode(), t.eqNode(n).notNode());
+    }
+    scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+  }
+
   Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvLshr(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvLshr(bool pol,
+                        Kind litk,
+                        Kind k,
+                        unsigned idx,
+                        Node x,
+                        Node s,
+                        Node t)
 {
   Assert(k == BITVECTOR_LSHR);
 
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
   Node scl, scr;
   unsigned w = bv::utils::getSize(s);
   Assert(w == bv::utils::getSize(t));
   Node z = bv::utils::mkZero(w);
-  
+
   if (idx == 0)
   {
-    /* x >> s = t
-     * with side condition:
-     * s = 0 || (s < w && clz(t) >=s) || (s >= w && t = 0)
-     * ->
-     * s = 0 || (s < w && ((z o t) << (z o s))[2w-1 : w] = z) || (s >= w && t = 0)
-     * with w = getSize(t) = getSize(s)
-     * and z = 0 with getSize(z) = w  */
-
     Node ww = bv::utils::mkConst(w, w);
 
-    Node z_o_t = nm->mkNode(BITVECTOR_CONCAT, z, t);
-    Node z_o_s = nm->mkNode(BITVECTOR_CONCAT, z, s);
-    Node shl = nm->mkNode(BITVECTOR_SHL, z_o_t, z_o_s);
-    Node ext = bv::utils::mkExtract(shl, 2*w-1, w);
-
-    Node o1 = s.eqNode(z);
-    Node o2 = nm->mkNode(AND, nm->mkNode(BITVECTOR_ULT, s, ww), ext.eqNode(z));
-    Node o3 = nm->mkNode(AND, nm->mkNode(BITVECTOR_UGE, s, ww), t.eqNode(z));
-
-    scl = nm->mkNode(OR, o1, o2, o3);
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    if (pol)
+    {
+      /* x >> s = t
+       * with side condition:
+       * s = 0 || (s < w && clz(t) >=s) || (s >= w && t = 0)
+       * ->
+       * s = 0
+       * || (s < w && ((z o t) << (z o s))[2w-1 : w] = z)
+       * || (s >= w && t = 0)
+       * with w = getSize(t) = getSize(s)
+       * and z = 0 with getSize(z) = w  */
+      Node z_o_t = nm->mkNode(BITVECTOR_CONCAT, z, t);
+      Node z_o_s = nm->mkNode(BITVECTOR_CONCAT, z, s);
+      Node shl = nm->mkNode(BITVECTOR_SHL, z_o_t, z_o_s);
+      Node ext = bv::utils::mkExtract(shl, 2*w-1, w);
+
+      Node o1 = s.eqNode(z);
+      Node o2 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_ULT, s, ww), ext.eqNode(z));
+      Node o3 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_UGE, s, ww), t.eqNode(z));
+
+      scl = nm->mkNode(OR, o1, o2, o3);
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    }
+    else
+    {
+      /* x >> s != t
+       * with side condition:
+       * t != 0 || s < w
+       * with
+       * w = getSize(s) = getSize(t)
+       */
+      scl = nm->mkNode(OR,
+          t.eqNode(z).notNode(),
+          nm->mkNode(BITVECTOR_ULT, s, ww));
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+    }
   }
   else
   {
-    /* s >> x = t
-     * with side condition:
-     * t = 0
-     * ||
-     * s = t
-     * || 
-     * \/ (t[w-1-i:0] = s[w-1:i] && t[w-1:w-i] = 0) for 0 < i < w
-     * where
-     * w = getSize(s) = getSize(t)
-     */
-    NodeBuilder<> nb(nm, OR);
-    nb << nm->mkNode(EQUAL, t, s);
-    for (unsigned i = 1; i < w; ++i)
-    {
-      nb << nm->mkNode(AND,
-          nm->mkNode(EQUAL,
-            bv::utils::mkExtract(t, w-1-i, 0), bv::utils::mkExtract(s, w-1, i)),
-          nm->mkNode(EQUAL,
-            bv::utils::mkExtract(t, w-1, w-i), bv::utils::mkZero(i)));
-    }
-    nb << t.eqNode(z);
-    scl = nb.constructNode();
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    if (pol)
+    {
+      /* s >> x = t
+       * with side condition:
+       * t = 0
+       * ||
+       * s = t
+       * || 
+       * \/ (t[w-1-i:0] = s[w-1:i] && t[w-1:w-i] = 0) for 0 < i < w
+       * where
+       * w = getSize(s) = getSize(t)
+       */
+      NodeBuilder<> nb(nm, OR);
+      nb << nm->mkNode(EQUAL, t, s);
+      for (unsigned i = 1; i < w; ++i)
+      {
+        nb << nm->mkNode(AND,
+            nm->mkNode(EQUAL,
+              bv::utils::mkExtract(t, w - 1 - i, 0),
+              bv::utils::mkExtract(s, w - 1, i)),
+            nm->mkNode(EQUAL,
+              bv::utils::mkExtract(t, w - 1, w - i),
+              bv::utils::mkZero(i)));
+      }
+      nb << t.eqNode(z);
+      scl = nb.constructNode();
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    }
+    else
+    {
+      /* s >> x != t
+       * with side condition:
+       * s != 0 || t != 0  */
+      scl = nm->mkNode(OR, s.eqNode(z).notNode(), t.eqNode(z).notNode());
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, s, x), t);
+    }
   }
   Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvAshr(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvAshr(bool pol,
+                        Kind litk,
+                        Kind k,
+                        unsigned idx,
+                        Node x,
+                        Node s,
+                        Node t)
 {
   Assert(k == BITVECTOR_ASHR);
 
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
   Node scl, scr;
   unsigned w = bv::utils::getSize(s);
   Assert(w == bv::utils::getSize(t));
   Node z = bv::utils::mkZero(w);
   Node n = bv::utils::mkOnes(w);
-  
+
   if (idx == 0)
   {
-    /* x >> s = t
-     * with side condition:
-     * s = 0
-     * ||
-     * (s < w && (((z o t) << (z o s))[2w-1:w-1] = z
-     *            ||
-     *            ((~z o t) << (z o s))[2w-1:w-1] = ~z))
-     * ||
-     * (s >= w && (t = 0 || t = ~0))
-     * with w = getSize(t) = getSize(s)
-     * and z = 0 with getSize(z) = w  */
-    
-    Node zz = bv::utils::mkZero(w+1);
-    Node nn = bv::utils::mkOnes(w+1);
-    Node ww = bv::utils::mkConst(w, w);
-
-    Node z_o_t = bv::utils::mkConcat(z, t);
-    Node z_o_s = bv::utils::mkConcat(z, s);
-    Node n_o_t = bv::utils::mkConcat(n, t);
-
-    Node shlz = nm->mkNode(BITVECTOR_SHL, z_o_t, z_o_s);
-    Node shln = nm->mkNode(BITVECTOR_SHL, n_o_t, z_o_s);
-    Node extz = bv::utils::mkExtract(shlz, 2*w-1, w-1);
-    Node extn = bv::utils::mkExtract(shln, 2*w-1, w-1);
-
-    Node o1 = s.eqNode(z);
-    Node o2 = nm->mkNode(AND,
-        nm->mkNode(BITVECTOR_ULT, s, ww),
-        nm->mkNode(OR, extz.eqNode(zz), extn.eqNode(nn)));
-    Node o3 = nm->mkNode(AND,
-        nm->mkNode(BITVECTOR_UGE, s, ww),
-        nm->mkNode(OR, t.eqNode(z), t.eqNode(n)));
-
-    scl = nm->mkNode(OR, o1, o2, o3);
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    if (pol)
+    {
+      /* x >> s = t
+       * with side condition:
+       * s = 0
+       * ||
+       * (s < w && (((z o t) << (z o s))[2w-1:w-1] = z
+       *            ||
+       *            ((~z o t) << (z o s))[2w-1:w-1] = ~z))
+       * ||
+       * (s >= w && (t = 0 || t = ~0))
+       * with w = getSize(t) = getSize(s)
+       * and z = 0 with getSize(z) = w  */
+
+      Node zz = bv::utils::mkZero(w+1);
+      Node nn = bv::utils::mkOnes(w+1);
+      Node ww = bv::utils::mkConst(w, w);
+
+      Node z_o_t = bv::utils::mkConcat(z, t);
+      Node z_o_s = bv::utils::mkConcat(z, s);
+      Node n_o_t = bv::utils::mkConcat(n, t);
+
+      Node shlz = nm->mkNode(BITVECTOR_SHL, z_o_t, z_o_s);
+      Node shln = nm->mkNode(BITVECTOR_SHL, n_o_t, z_o_s);
+      Node extz = bv::utils::mkExtract(shlz, 2*w-1, w-1);
+      Node extn = bv::utils::mkExtract(shln, 2*w-1, w-1);
+
+      Node o1 = s.eqNode(z);
+      Node o2 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_ULT, s, ww),
+          nm->mkNode(OR, extz.eqNode(zz), extn.eqNode(nn)));
+      Node o3 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_UGE, s, ww),
+          nm->mkNode(OR, t.eqNode(z), t.eqNode(n)));
+
+      scl = nm->mkNode(OR, o1, o2, o3);
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    }
+    else
+    {
+      /* x >> s != t
+       * no side condition */
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+    }
   }
   else
   {
-    /* s >> x = t
-     * with side condition:
-     * (s[w-1:w-1] = 0 && t = 0)
-     * ||
-     * (s[w-1:w-1] = 1 && t == ~0)
-     * ||
-     * s = t
-     * || 
-     * \/ (t[w-1-i:0] = s[w-1:i]
-     *     && ((s[w-1:w-1] = 0 && t[w-1:w-i] = 0)
-     *         ||
-     *         (s[w-1:w-1] = 1 &&  t[w-1:w-i] = ~0)))
-     * for 0 < i < w
-     * where
-     * w = getSize(s) = getSize(t)
-     */
-    Node msbz = bv::utils::mkExtract(s, w-1, w-1).eqNode(bv::utils::mkZero(1));
-    Node msbn = bv::utils::mkExtract(s, w-1, w-1).eqNode(bv::utils::mkOnes(1));
-    NodeBuilder<> nb(nm, OR);
-    nb << nm->mkNode(EQUAL, t, s);
-    for (unsigned i = 1; i < w; ++i)
+    if (pol)
     {
+      /* s >> x = t
+       * with side condition:
+       * (s[w-1:w-1] = 0 && t = 0)
+       * ||
+       * (s[w-1:w-1] = 1 && t == ~0)
+       * ||
+       * s = t
+       * || 
+       * \/ (t[w-1-i:0] = s[w-1:i]
+       *     && ((s[w-1:w-1] = 0 && t[w-1:w-i] = 0)
+       *         ||
+       *         (s[w-1:w-1] = 1 &&  t[w-1:w-i] = ~0)))
+       * for 0 < i < w
+       * where
+       * w = getSize(s) = getSize(t)
+       */
+      Node msbz = bv::utils::mkExtract(
+          s, w-1, w-1).eqNode(bv::utils::mkZero(1));
+      Node msbn = bv::utils::mkExtract(
+          s, w-1, w-1).eqNode(bv::utils::mkOnes(1));
+      NodeBuilder<> nb(nm, OR);
+      nb << nm->mkNode(EQUAL, t, s);
+      for (unsigned i = 1; i < w; ++i)
+      {
+        Node ext = bv::utils::mkExtract(t, w-1, w-i);
 
-      Node ext = bv::utils::mkExtract(t, w-1, w-i);
-
-      Node o1 = nm->mkNode(AND, msbz, ext.eqNode(bv::utils::mkZero(i)));
-      Node o2 = nm->mkNode(AND, msbn, ext.eqNode(bv::utils::mkOnes(i)));
-      Node o = nm->mkNode(OR, o1, o2);
+        Node o1 = nm->mkNode(AND, msbz, ext.eqNode(bv::utils::mkZero(i)));
+        Node o2 = nm->mkNode(AND, msbn, ext.eqNode(bv::utils::mkOnes(i)));
+        Node o = nm->mkNode(OR, o1, o2);
 
-      Node e = nm->mkNode(EQUAL,
-          bv::utils::mkExtract(t, w-1-i, 0), bv::utils::mkExtract(s, w-1, i));
+        Node e = nm->mkNode(EQUAL,
+            bv::utils::mkExtract(t, w-1-i, 0), bv::utils::mkExtract(s, w-1, i));
 
-      nb << nm->mkNode(AND, e, o);
+        nb << nm->mkNode(AND, e, o);
+      }
+      nb << nm->mkNode(AND, msbz, t.eqNode(z));
+      nb << nm->mkNode(AND, msbn, t.eqNode(n));
+      scl = nb.constructNode();
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    }
+    else
+    {
+      /* s >> x != t
+       * with side condition:
+       * (t != 0 || s != 0) && (t != ~0 || s != ~0)  */
+      scl = nm->mkNode(AND,
+          nm->mkNode(OR, t.eqNode(z).notNode(), s.eqNode(z).notNode()),
+          nm->mkNode(OR, t.eqNode(n).notNode(), s.eqNode(n).notNode()));
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, s, x), t);
     }
-    nb << nm->mkNode(AND, msbz, t.eqNode(z));
-    nb << nm->mkNode(AND, msbn, t.eqNode(n));
-    scl = nb.constructNode();
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
   }
-  Node sc = nm->mkNode(IMPLIES, scl, scr);
+  Node sc = scl.isNull() ? scr : nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
   return sc;
 }
 
-static Node getScBvShl(Kind k, unsigned idx, Node x, Node s, Node t)
+static Node getScBvShl(bool pol,
+                       Kind litk,
+                       Kind k,
+                       unsigned idx,
+                       Node x,
+                       Node s,
+                       Node t)
 {
   Assert(k == BITVECTOR_SHL);
 
+  if (litk != EQUAL)
+  {
+    return Node::null();
+  }
+
   NodeManager* nm = NodeManager::currentNM();
   Node scl, scr;
   unsigned w = bv::utils::getSize(s);
   Assert(w == bv::utils::getSize(t));
-  Node z = bv::utils::mkConst(w, 0u);
+  Node z = bv::utils::mkZero(w);
 
   if (idx == 0)
   {
-    /* x << s = t
-     * with side condition:
-     * (s = 0 || ctz(t) >= s)
-     * <->
-     * (s = 0 || (s < w && ((t o z) >> (z o s))[w-1:0] = z) || (s >= w && t = 0)
-     *
-     * where
-     * w = getSize(s) = getSize(t) = getSize (z) && z = 0
-     */
-
     Node ww = bv::utils::mkConst(w, w);
 
-    Node shr = nm->mkNode(BITVECTOR_LSHR,
-        bv::utils::mkConcat(t, z),
-        bv::utils::mkConcat(z, s));
-    Node ext = bv::utils::mkExtract(shr, w - 1, 0);
-
-    Node o1 = nm->mkNode(EQUAL, s, z);
-    Node o2 = nm->mkNode(AND, nm->mkNode(BITVECTOR_ULT, s, ww), ext.eqNode(z));
-    Node o3 = nm->mkNode(AND, nm->mkNode(BITVECTOR_UGE, s, ww), t.eqNode(z));
-
-    scl = nm->mkNode(OR, o1, o2, o3);
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    if (pol)
+    {
+      /* x << s = t
+       * with side condition:
+       * (s = 0 || ctz(t) >= s)
+       * <->
+       * s = 0
+       * ||
+       * (s < w && ((t o z) >> (z o s))[w-1:0] = z)
+       * ||
+       * (s >= w && t = 0)
+       *
+       * where
+       * w = getSize(s) = getSize(t) = getSize (z) && z = 0
+       */
+      Node shr = nm->mkNode(BITVECTOR_LSHR,
+          bv::utils::mkConcat(t, z),
+          bv::utils::mkConcat(z, s));
+      Node ext = bv::utils::mkExtract(shr, w - 1, 0);
+
+      Node o1 = nm->mkNode(EQUAL, s, z);
+      Node o2 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_ULT, s, ww), ext.eqNode(z));
+      Node o3 = nm->mkNode(AND,
+          nm->mkNode(BITVECTOR_UGE, s, ww), t.eqNode(z));
+
+      scl = nm->mkNode(OR, o1, o2, o3);
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, x, s), t);
+    }
+    else
+    {
+      /* x << s != t
+       * with side condition:
+       * t != 0 || s < w
+       * with
+       * w = getSize(s) = getSize(t)
+       */
+      scl = nm->mkNode(OR,
+          t.eqNode(z).notNode(),
+          nm->mkNode(BITVECTOR_ULT, s, ww));
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, x, s), t);
+    }
   }
   else
   {
-    /* s << x = t
-     * with side condition:
-     * t = 0
-     * ||
-     * s = t
-     * || 
-     * \/ (t[w-1:i] = s[w-1-i:0] && t[i-1:0] = 0) for 0 < i < w
-     * where
-     * w = getSize(s) = getSize(t)
-     */
-    NodeBuilder<> nb(nm, OR);
-    nb << nm->mkNode(EQUAL, t, s);
-    for (unsigned i = 1; i < w; ++i)
-    {
-      nb << nm->mkNode(AND,
-          nm->mkNode(EQUAL,
-            bv::utils::mkExtract(t, w-1, i), bv::utils::mkExtract(s, w-1-i, 0)),
-          nm->mkNode(EQUAL,
-            bv::utils::mkExtract(t, i-1, 0), bv::utils::mkZero(i)));
-    }
-    nb << t.eqNode(z);
-    scl = nb.constructNode();
-    scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    if (pol)
+    {
+      /* s << x = t
+       * with side condition:
+       * t = 0
+       * ||
+       * s = t
+       * || 
+       * \/ (t[w-1:i] = s[w-1-i:0] && t[i-1:0] = 0) for 0 < i < w
+       * where
+       * w = getSize(s) = getSize(t)
+       */
+      NodeBuilder<> nb(nm, OR);
+      nb << nm->mkNode(EQUAL, t, s);
+      for (unsigned i = 1; i < w; ++i)
+      {
+        nb << nm->mkNode(AND,
+            nm->mkNode(EQUAL,
+              bv::utils::mkExtract(t, w-1, i), bv::utils::mkExtract(s, w-1-i, 0)),
+            nm->mkNode(EQUAL,
+              bv::utils::mkExtract(t, i-1, 0), bv::utils::mkZero(i)));
+      }
+      nb << t.eqNode(z);
+      scl = nb.constructNode();
+      scr = nm->mkNode(EQUAL, nm->mkNode(k, s, x), t);
+    }
+    else
+    {
+      /* s << x != t
+       * with side condition:
+       * s != 0 || t != 0  */
+      scl = nm->mkNode(OR, s.eqNode(z).notNode(), t.eqNode(z).notNode());
+      scr = nm->mkNode(DISTINCT, nm->mkNode(k, s, x), t);
+    }
   }
   Node sc = nm->mkNode(IMPLIES, scl, scr);
   Trace("bv-invert") << "Add SC_" << k << "(" << x << "): " << sc << std::endl;
@@ -690,28 +924,27 @@ static Node getScBvShl(Kind k, unsigned idx, Node x, Node s, Node t)
 Node BvInverter::solveBvLit(Node sv,
                             Node lit,
                             std::vector<unsigned>& path,
-                            BvInverterQuery* m,
-                            BvInverterStatus& status)
+                            BvInverterQuery* m)
 {
   Assert(!path.empty());
 
   bool pol = true;
   unsigned index, nchildren;
   NodeManager* nm = NodeManager::currentNM();
-  Kind k;
+  Kind k, litk;
 
   Assert(!path.empty());
   index = path.back();
   Assert(index < lit.getNumChildren());
   path.pop_back();
-  k = lit.getKind();
-  
+  litk = k = lit.getKind();
+
   /* Note: option --bool-to-bv is currently disabled when CBQI BV
    *       is enabled. We currently do not support Boolean operators
    *       that are interpreted as bit-vector operators of width 1.  */
 
   /* Boolean layer ----------------------------------------------- */
-  
+
   if (k == NOT)
   {
     pol = !pol;
@@ -720,72 +953,16 @@ Node BvInverter::solveBvLit(Node sv,
     index = path.back();
     Assert(index < lit.getNumChildren());
     path.pop_back();
-    k = lit.getKind();
+    litk = k = lit.getKind();
   }
 
   Assert(k == EQUAL
       || k == BITVECTOR_ULT
-      || k == BITVECTOR_SLT
-      || k == BITVECTOR_COMP);
+      || k == BITVECTOR_SLT);
 
   Node sv_t = lit[index];
   Node t = lit[1-index];
 
-  switch (k)
-  {
-    case BITVECTOR_ULT:
-    {
-      TypeNode solve_tn = sv_t.getType();
-      Node sc = getScBvUlt(pol, k, index, getSolveVariable(solve_tn), t);
-      /* t = fresh skolem constant  */
-      t = getInversionNode(sc, solve_tn, m);
-      if (!path.empty())
-      {
-        index = path.back();
-        Assert(index < sv_t.getNumChildren());
-        path.pop_back();
-        sv_t = sv_t[index];
-        k = sv_t.getKind();
-      }
-      break;
-    }
-
-    case BITVECTOR_SLT:
-    {
-      TypeNode solve_tn = sv_t.getType();
-      Node sc = getScBvSlt(pol, k, index, getSolveVariable(solve_tn), t);
-      /* t = fresh skolem constant  */
-      t = getInversionNode(sc, solve_tn, m);
-      if (!path.empty())
-      {
-        index = path.back();
-        Assert(index < sv_t.getNumChildren());
-        path.pop_back();
-        sv_t = sv_t[index];
-        k = sv_t.getKind();
-      }
-      break;
-    }
-
-    default:
-      Assert(k == EQUAL);
-      if (pol == false)
-      {
-        TypeNode solve_tn = sv_t.getType();
-        Node sc = getScBvEq(pol, k, index, getSolveVariable(solve_tn), t);
-        /* t = fresh skolem constant  */
-        t = getInversionNode(sc, solve_tn, m);
-        if (!path.empty())
-        {
-          index = path.back();
-          Assert(index < sv_t.getNumChildren());
-          path.pop_back();
-          sv_t = sv_t[index];
-          k = sv_t.getKind();
-        }
-      }
-  }
-
   /* Bit-vector layer -------------------------------------------- */
 
   while (!path.empty())
@@ -822,7 +999,7 @@ Node BvInverter::solveBvLit(Node sv,
     {
       t = bv::utils::mkExtract(t, bv::utils::getSize(sv_t[index]) - 1, 0);
     }
-    else if (k == BITVECTOR_EXTRACT)
+    else if (k == BITVECTOR_EXTRACT || k == BITVECTOR_COMP)
     {
       Trace("bv-invert") << "bv-invert : Unsupported for index " << index
                          << ", from " << sv_t << std::endl;
@@ -834,107 +1011,126 @@ Node BvInverter::solveBvLit(Node sv,
       Node s = nchildren == 2 ? sv_t[1 - index] : dropChild(sv_t, index);
       /* Note: All n-ary kinds except for CONCAT (i.e., AND, OR, MULT, PLUS)
        *       are commutative (no case split based on index). */
-      switch (k)
+      if (k == BITVECTOR_PLUS)
       {
-        case BITVECTOR_COMP:
-          t = s;
-          break;
-
-        case BITVECTOR_PLUS:
-          t = nm->mkNode(BITVECTOR_SUB, t, s);
-          break;
-
-        case BITVECTOR_SUB:
-          t = nm->mkNode(BITVECTOR_PLUS, t, s);
-          break;
+        t = nm->mkNode(BITVECTOR_SUB, t, s);
+      }
+      else if (k == BITVECTOR_SUB)
+      {
+        t = nm->mkNode(BITVECTOR_PLUS, t, s);
+      }
+      else if (k == BITVECTOR_XOR)
+      {
+        t = nm->mkNode(BITVECTOR_XOR, t, s);
+      }
+      else
+      {
+        TypeNode solve_tn = sv_t[index].getType();
+        Node sc;
 
-        case BITVECTOR_MULT:
+        switch (k)
         {
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvMult(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
+          case BITVECTOR_MULT:
+            sc = getScBvMult(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_SHL:
+            sc = getScBvShl(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_UREM_TOTAL:
+            if (index == 0)
+            {
+              /* x % s = t is rewritten to x - x / y * y */
+              Trace("bv-invert") << "bv-invert : Unsupported for index "
+                                 << index << ", from " << sv_t << std::endl;
+              return Node::null();
+            }
+            sc = getScBvUrem(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_UDIV_TOTAL:
+            sc = getScBvUdiv(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_AND:
+          case BITVECTOR_OR:
+            sc = getScBvAndOr(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_LSHR:
+            sc = getScBvLshr(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          case BITVECTOR_ASHR:
+            sc = getScBvAshr(
+                pol, litk, k, index, getSolveVariable(solve_tn), s, t);
+            break;
+
+          default:
+            Trace("bv-invert") << "bv-invert : Unknown kind " << k
+                               << " for bit-vector term " << sv_t << std::endl;
+            return Node::null();
         }
-
-        case BITVECTOR_UREM_TOTAL:
+        Assert (litk != EQUAL || !sc.isNull());
+        /* No specific handling for litk and operator k, generate generic
+         * side condition. */
+        if (sc.isNull())
         {
-          if (index == 0)
+          solve_tn = sv_t.getType();
+          if (litk == BITVECTOR_ULT)
           {
-            /* x % s = t is rewritten to x - x / y * y */
-            Trace("bv-invert") << "bv-invert : Unsupported for index " << index
-                               << ", from " << sv_t << std::endl;
-            return Node::null();
+            sc = getScBvUlt(
+                pol, litk, index, getSolveVariable(solve_tn), t);
+          }
+          else
+          {
+            Assert (litk == BITVECTOR_SLT);
+            sc = getScBvSlt(
+                pol, litk, index, getSolveVariable(solve_tn), t);
           }
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvUrem(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = skv (fresh skolem constant)  */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
-        }
-
-        case BITVECTOR_UDIV_TOTAL:
-        {
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvUdiv(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
-        }
-
-        case BITVECTOR_AND:
-        case BITVECTOR_OR:
-        {
-          /* with side condition:
-           * t & s = t
-           * t | s = t */
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvAndOr(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant  */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
-        }
-
-        case BITVECTOR_XOR:
-          t = nm->mkNode(BITVECTOR_XOR, t, s);
-          break;
-
-        case BITVECTOR_LSHR:
-        {
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvLshr(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant  */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
-        }
-
-        case BITVECTOR_ASHR:
-        {
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvAshr(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant  */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
-        }
-
-        case BITVECTOR_SHL:
-        {
-          TypeNode solve_tn = sv_t[index].getType();
-          Node sc = getScBvShl(k, index, getSolveVariable(solve_tn), s, t);
-          /* t = fresh skolem constant */
-          t = getInversionNode(sc, solve_tn, m);
-          break;
         }
-
-        default:
-          Trace("bv-invert") << "bv-invert : Unknown kind " << k
-                             << " for bit-vector term " << sv_t << std::endl;
-          return Node::null();
+        /* We generate a choice term (choice x0. SC => x0 <k> s <litk> t) for
+         * x <k> s <litk> t. When traversing down, this choice term determines
+         * the value for x <k> s = (choice x0. SC => x0 <k> s <litk> t), i.e.,
+         * from here on, the propagated literal is a positive equality. */
+        litk = EQUAL;
+        pol = true;
+        /* t = fresh skolem constant */
+        t = getInversionNode(sc, solve_tn, m);
       }
     }
     sv_t = sv_t[index];
   }
   Assert(sv_t == sv);
+  if (litk == BITVECTOR_ULT)
+  {
+    TypeNode solve_tn = sv_t.getType();
+    Node sc = getScBvUlt(pol, litk, index, getSolveVariable(solve_tn), t);
+    t = getInversionNode(sc, solve_tn, m);
+  }
+  else if (litk == BITVECTOR_SLT)
+  {
+    TypeNode solve_tn = sv_t.getType();
+    Node sc = getScBvSlt(pol, litk, index, getSolveVariable(solve_tn), t);
+    t = getInversionNode(sc, solve_tn, m);
+  }
+  else if (pol == false)
+  {
+    Assert (litk == EQUAL);
+    TypeNode solve_tn = sv_t.getType();
+    Node x = getSolveVariable(solve_tn);
+    Node sc = nm->mkNode(DISTINCT, x, t);
+    Trace("bv-invert") << "Add SC_" << litk << "(" << x << "): " << sc
+                       << std::endl;
+    t = getInversionNode(sc, solve_tn, m);
+  }
   return t;
 }
 
index a44d64904e7fe415e0594f725adc266ce9fd44e6..ce2a58695f05f5bad75331732ba44d3df4a464c2 100644 (file)
@@ -44,47 +44,22 @@ class BvInverterQuery
   virtual Node getBoundVariable(TypeNode tn) = 0;
 };
 
-// class for storing information about the solved status
-class BvInverterStatus {
- public:
-  BvInverterStatus() : d_status(0) {}
-  ~BvInverterStatus() {}
-  int d_status;
-};
-
 // inverter class
 // TODO : move to theory/bv/ if generally useful?
-class BvInverter {
+class BvInverter
+{
  public:
   BvInverter() {}
   ~BvInverter() {}
   /** get dummy fresh variable of type tn, used as argument for sv */
   Node getSolveVariable(TypeNode tn);
 
-  /** get inversion node
-   *
-   * This expects a condition cond where:
-   *   (exists x. cond)
-   * is a BV tautology where x is getSolveVariable( tn ).
-   *
-   * It returns a term of the form:
-   *   (choice y. cond { x -> y })
-   * where y is a bound variable and x is getSolveVariable( tn ).
-   *
-   * In some cases, we may return a term t
-   * if cond implies an equality on the solve variable.
-   * For example, if cond is x = t where x is
-   * getSolveVariable( tn ), then we return t
-   * instead of introducing the choice function.
-   */
-  Node getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m);
-
   /** Get path to pv in lit, replace that occurrence by sv and all others by
    * pvs. If return value R is non-null, then : lit.path = pv R.path = sv
    *   R.path' = pvs for all lit.path' = pv, where path' != path
    */
-  Node getPathToPv(Node lit, Node pv, Node sv, Node pvs,
-                   std::vector<unsigned>& path);
+  Node getPathToPv(
+      Node lit, Node pv, Node sv, Node pvs, std::vector<unsigned>& path);
 
   /** solveBvLit
    * solve for sv in lit, where lit.path = sv
@@ -93,16 +68,35 @@ class BvInverter {
   Node solveBvLit(Node sv,
                   Node lit,
                   std::vector<unsigned>& path,
-                  BvInverterQuery* m,
-                  BvInverterStatus& status);
+                  BvInverterQuery* m);
 
  private:
-  /** dummy variables for each type */
+  /** Dummy variables for each type */
   std::map<TypeNode, Node> d_solve_var;
 
-  /** helper function for getPathToPv */
-  Node getPathToPv(Node lit, Node pv, Node sv, std::vector<unsigned>& path,
+  /** Helper function for getPathToPv */
+  Node getPathToPv(Node lit,
+                   Node pv,
+                   Node sv,
+                   std::vector<unsigned>& path,
                    std::unordered_set<TNode, TNodeHashFunction>& visited);
+
+  /** Helper function for getInv.
+   *
+   * This expects a condition cond where:
+   *   (exists x. cond)
+   * is a BV tautology where x is getSolveVariable( tn ).
+   *
+   * It returns a term of the form:
+   *   (choice y. cond { x -> y })
+   * where y is a bound variable and x is getSolveVariable( tn ).
+   *
+   * In some cases, we may return a term t if cond implies an equality on
+   * the solve variable. For example, if cond is x = t where x is
+   * getSolveVariable(tn), then we return t instead of introducing the choice
+   * function.
+   */
+  Node getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m);
 };
 
 }  // namespace quantifiers
index 55cc59c51dc3c8d3e762aab4d3c53b2da253371c..e4bc9adb84817937d999437c2372364a4e89bdd9 100644 (file)
@@ -965,7 +965,6 @@ void BvInstantiator::reset(CegInstantiator* ci,
   d_inst_id_counter = 0;
   d_var_to_inst_id.clear();
   d_inst_id_to_term.clear();
-  d_inst_id_to_status.clear();
   d_inst_id_to_alit.clear();
   d_var_to_curr_inst_id.clear();
   d_alit_to_model_slack.clear();
@@ -979,31 +978,32 @@ void BvInstantiator::processLiteral(CegInstantiator* ci,
                                     Node alit,
                                     CegInstEffort effort)
 {
-  Assert( d_inverter!=NULL );
+  Assert(d_inverter != NULL);
   // find path to pv
-  std::vector< unsigned > path;
-  Node sv = d_inverter->getSolveVariable( pv.getType() );
-  Node pvs = ci->getModelValue( pv );
+  std::vector<unsigned> path;
+  Node sv = d_inverter->getSolveVariable(pv.getType());
+  Node pvs = ci->getModelValue(pv);
   Trace("cegqi-bv") << "Get path to pv : " << lit << std::endl;
-  Node slit = d_inverter->getPathToPv( lit, pv, sv, pvs, path );
-  if( !slit.isNull() ){
+  Node slit = d_inverter->getPathToPv(lit, pv, sv, pvs, path);
+  if (!slit.isNull())
+  {
     CegInstantiatorBvInverterQuery m(ci);
     unsigned iid = d_inst_id_counter;
     Trace("cegqi-bv") << "Solve lit to bv inverter : " << slit << std::endl;
-    Node inst =
-        d_inverter->solveBvLit(sv, slit, path, &m, d_inst_id_to_status[iid]);
-    if( !inst.isNull() ){
+    Node inst = d_inverter->solveBvLit(sv, slit, path, &m);
+    if (!inst.isNull())
+    {
       inst = Rewriter::rewrite(inst);
       Trace("cegqi-bv") << "...solved form is " << inst << std::endl;
       // store information for id and increment
-      d_var_to_inst_id[pv].push_back( iid );
+      d_var_to_inst_id[pv].push_back(iid);
       d_inst_id_to_term[iid] = inst;
       d_inst_id_to_alit[iid] = alit;
       d_inst_id_counter++;
-    }else{
+    }
+    else
+    {
       Trace("cegqi-bv") << "...failed to solve." << std::endl;
-      // cleanup information if we failed to solve
-      d_inst_id_to_status.erase( iid );
     }
   }
 }
index c2864acc5817166dde015c93b143078b75714cac..0648942e8844f574e658229ac2c2f9fffb888480 100644 (file)
@@ -231,7 +231,6 @@ class BvInstantiator : public Instantiator {
   /** information about solved forms */
   std::unordered_map< Node, std::vector< unsigned >, NodeHashFunction > d_var_to_inst_id;
   std::unordered_map< unsigned, Node > d_inst_id_to_term;
-  std::unordered_map< unsigned, BvInverterStatus > d_inst_id_to_status;
   std::unordered_map<unsigned, Node> d_inst_id_to_alit;
   // variable to current id we are processing
   std::unordered_map< Node, unsigned, NodeHashFunction > d_var_to_curr_inst_id;
index c59570651700632543f7a1ee61e7e9eea461fd03..bb43d6c1c6eea141c9f94d8f1d7ec044738ac76f 100644 (file)
@@ -90,25 +90,38 @@ TESTS =     \
        qbv-simp.smt2 \
        psyco-001-bv.smt2 \
        bug822.smt2 \
-       qbv-test-invert-mul.smt2 \
+       qbv-disequality3.smt2 \
+       qbv-inequality2.smt2 \
+       qbv-simple-2vars-vo.smt2 \
+       qbv-test-invert-bvadd-neq.smt2 \
        qbv-test-invert-bvand.smt2 \
-       qbv-test-invert-bvcomp.smt2 \
-       qbv-test-invert-bvor.smt2 \
-       qbv-test-invert-bvlshr-0.smt2 \
+       qbv-test-invert-bvand-neq.smt2 \
        qbv-test-invert-bvashr-0.smt2 \
+       qbv-test-invert-bvashr-0-neq.smt2 \
+       qbv-test-invert-bvashr-1.smt2 \
+       qbv-test-invert-bvashr-1-neq.smt2 \
+       qbv-test-invert-bvlshr-0.smt2 \
+       qbv-test-invert-bvlshr-0-neq.smt2 \
+       qbv-test-invert-bvlshr-1.smt2 \
+       qbv-test-invert-bvlshr-1-neq.smt2 \
+       qbv-test-invert-bvmul.smt2 \
+       qbv-test-invert-bvmul-neq.smt2 \
+       qbv-test-invert-bvor.smt2 \
+       qbv-test-invert-bvor-neq.smt2 \
+       qbv-test-invert-bvshl-0.smt2 \
+       qbv-test-invert-bvudiv-0.smt2 \
+       qbv-test-invert-bvudiv-0-neq.smt2 \
+       qbv-test-invert-bvudiv-1.smt2 \
+       qbv-test-invert-bvudiv-1-neq.smt2 \
+       qbv-test-invert-bvult-1.smt2 \
        qbv-test-invert-bvurem-1.smt2 \
+       qbv-test-invert-bvurem-1-neq.smt2 \
+       qbv-test-invert-bvxor.smt2 \
+       qbv-test-invert-bvxor-neq.smt2 \
        qbv-test-invert-concat-0.smt2 \
        qbv-test-invert-concat-1.smt2 \
-       qbv-test-invert-disequality.smt2 \
-       qbv-test-invert-shl.smt2 \
-       qbv-test-invert-udiv-0.smt2 \
-       qbv-test-invert-udiv-1.smt2 \
        qbv-test-invert-sign-extend.smt2 \
-       qbv-test-invert-bvxor.smt2 \
-       qbv-simple-2vars-vo.smt2 \
        qbv-test-urem-rewrite.smt2 \
-       qbv-inequality2.smt2 \
-       qbv-test-invert-bvult-1.smt2 \
        intersection-example-onelane.proof-node22337.smt2 \
        nested9_true-unreach-call.i_575.smt2 \
        small-pipeline-fixpoint-3.smt2 \
@@ -127,6 +140,8 @@ TESTS =     \
 # regression can be solved with --finite-model-find --fmf-inst-engine
 # set3.smt2
 
+# disabled since bvcomp handling is currently disabled
+# qbv-test-invert-bvcomp.smt2
 
 # removed because they take more than 20s
 #              javafe.ast.ArrayInit.35.smt2
diff --git a/test/regress/regress0/quantifiers/qbv-disequality3.smt2 b/test/regress/regress0/quantifiers/qbv-disequality3.smt2
new file mode 100644 (file)
index 0000000..d161575
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvmul (bvadd x b) a)  b)))
+
+(check-sat)
index d53715a2d5064cd9259bda6b4f8d430ad8873fa0..1486e176d235c067c9fa2738afb0bcb2e0f9cd1e 100644 (file)
@@ -1,11 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-
-(assert (forall ((x (_ BitVec 32))) (or (bvuge x (bvadd a b)) (bvule x b))))
+(assert (forall ((x (_ BitVec 8))) (or (bvuge x (bvadd a b)) (bvule x b))))
 
 (check-sat)
index d74a6cfeac462c973ffbf4291a2e0ac84a27e8ac..3c4f932434422dc137fc1d6fb6af3f281d7a8b26 100644 (file)
@@ -1,4 +1,4 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
index 1f72d44e40bca40a5772bf7e8f65b534f6d44d55..ec4626f52a579b99569ee1ff15dcf22ac0d0b4e6 100644 (file)
@@ -1,9 +1,11 @@
+; COMMAND-LINE: --cbqi-bv --no-cbqi-full
+; EXPECT: unsat
 (set-logic BV)
 (set-info :status unsat)
 (assert
    (forall
-    ((A (_ BitVec 32)) (B (_ BitVec 32)) (C (_ BitVec 32)) (D (_ BitVec 32)))
+    ((A (_ BitVec 8)) (B (_ BitVec 8)) (C (_ BitVec 8)) (D (_ BitVec 8)))
       (or (and (= A B) (= C D)) (and (= A C) (= B D)))))
-      
+
 (check-sat)
-      
+
index b6ae95fec475824ef146cb617054c301940661ae..c36322aaccc11f5ee669f9256e4cb4efbfc736ce 100644 (file)
@@ -1,16 +1,16 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
-(declare-fun c () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+(declare-fun c () (_ BitVec 8))
 
-(assert (not (= a #x00000000)))
+(assert (not (= a #x00)))
 
-(assert (forall ((x (_ BitVec 32)) (y (_ BitVec 32))) (or 
-(not (= (bvmul x y) #x0000000A))
-(not (= (bvadd y a) #x00000010))
+(assert (forall ((x (_ BitVec 8)) (y (_ BitVec 8))) (or 
+(not (= (bvmul x y) #x0A))
+(not (= (bvadd y a) #x10))
 )))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvadd-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvadd-neq.smt2
new file mode 100644 (file)
index 0000000..216a985
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvadd x a) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvand-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvand-neq.smt2
new file mode 100644 (file)
index 0000000..ad3b9a9
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvand x a) b)))
+
+(check-sat)
index d611fcd6869fd390c1adb95d33fb19d390087790..8dd50b1beaeaee9f33b9ec11c343bc481cbbec2b 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvand x a) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvand x a) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-0-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-0-neq.smt2
new file mode 100644 (file)
index 0000000..e05c344
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvashr x a) b)))
+
+(check-sat)
index db772589603f8d87ebbaa49dbab003f4e33c9566..30e7c2f8bf6a01b25eae3f2ea3824f6933a98525 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvashr x a) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvashr x a) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1-neq.smt2
new file mode 100644 (file)
index 0000000..2835e59
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvashr a x) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvashr-1.smt2
new file mode 100644 (file)
index 0000000..c3de64c
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (not (= (bvashr a x) b))))
+
+(check-sat)
index e8f7c25dbf931177f5d044b1cabb88dc1ed79cef..3b55c0b9aa64f647b7750fa147a729767fce68d7 100644 (file)
@@ -1,11 +1,11 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: unsat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 (declare-fun c () (_ BitVec 1))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvcomp x a) (bvcomp x b)))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvcomp x a) ((_ extract 7 7) (bvmul a b))))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-0-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-0-neq.smt2
new file mode 100644 (file)
index 0000000..e05c344
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvashr x a) b)))
+
+(check-sat)
index db772589603f8d87ebbaa49dbab003f4e33c9566..1018ce72cbab6a991949a0d2963f8bf64ce0280d 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvashr x a) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvlshr x a) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1-neq.smt2
new file mode 100644 (file)
index 0000000..503bc98
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvlshr a x) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvlshr-1.smt2
new file mode 100644 (file)
index 0000000..08479d9
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (not (= (bvlshr a x) b))))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvmul-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvmul-neq.smt2
new file mode 100644 (file)
index 0000000..9dc9f98
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvmul x a) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvmul.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvmul.smt2
new file mode 100644 (file)
index 0000000..f3dad67
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (not (= (bvmul x a) b))))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvor-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvor-neq.smt2
new file mode 100644 (file)
index 0000000..74c2891
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvor x a) b)))
+
+(check-sat)
index 287da08c72919508d998890b63c2f3e729151766..4145c68b1d93e2ac73c846e945be41660d3656a4 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvor x a) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvor x a) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0-neq.smt2
new file mode 100644 (file)
index 0000000..e85ecc7
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvshl x a) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvshl-0.smt2
new file mode 100644 (file)
index 0000000..abef84d
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (not (= (bvshl x a) b))))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0-neq.smt2
new file mode 100644 (file)
index 0000000..3748eca
--- /dev/null
@@ -0,0 +1,11 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (distinct a b (_ bv0 8)))
+(assert (forall ((x (_ BitVec 8))) (= (bvudiv x a) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-0.smt2
new file mode 100644 (file)
index 0000000..2cabb50
--- /dev/null
@@ -0,0 +1,11 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (distinct a b (_ bv0 8)))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvudiv x a) b))))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1-neq.smt2
new file mode 100644 (file)
index 0000000..a0e1b62
--- /dev/null
@@ -0,0 +1,11 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full --bv-div-zero-const
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (distinct a b (_ bv0 8)))
+(assert (forall ((x (_ BitVec 8))) (= (bvudiv a x) b)))
+
+(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvudiv-1.smt2
new file mode 100644 (file)
index 0000000..2690a0a
--- /dev/null
@@ -0,0 +1,11 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full --bv-div-zero-const
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (distinct a b (_ bv0 8)))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvudiv a x) b))))
+
+(check-sat)
index 13c1bf10a3b92772694c82e0053936340802a733..a1dca469a25114506efcab74de22679f41e028ec 100644 (file)
@@ -1,9 +1,9 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (bvult a x))))
+(assert (forall ((x (_ BitVec 8))) (not (bvult a x))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvurem-1-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvurem-1-neq.smt2
new file mode 100644 (file)
index 0000000..871df48
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: sat
+(set-logic BV)
+(set-info :status sat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (= (bvurem a x) b)))
+
+(check-sat)
index f7fe54e3e2486c9dad1e71b9e8f60fe985d58c98..22bd306eecf5810a11cf3fb78ab57c92bb0895e1 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv --bv-div-zero-const
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvurem a x) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvurem a x) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-bvxor-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-bvxor-neq.smt2
new file mode 100644 (file)
index 0000000..4f9c6ed
--- /dev/null
@@ -0,0 +1,9 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+
+(assert (forall ((x (_ BitVec 8))) (not (= (bvxor x a) (bvmul a a)))))
+
+(check-sat)
index eec40a4255a909f35320579b70bae24375f704b8..ef41eecdd6a02288c30ad77c337b0b510bc77f2b 100644 (file)
@@ -1,9 +1,9 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: unsat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
+(declare-fun a () (_ BitVec 8))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (bvxor x a) (bvmul a a)))))
+(assert (forall ((x (_ BitVec 8))) (not (= (bvxor x a) (bvmul a a)))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-concat-0-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-concat-0-neq.smt2
new file mode 100644 (file)
index 0000000..769854f
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 16))
+
+(assert (forall ((x (_ BitVec 8))) (= (concat x a) b)))
+
+(check-sat)
index f4e19fc5204f9c3cec325092d14a52019fda515d..7b66bd859ffc0e2dd07b544c052036a4cfea4eeb 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 64))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 16))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (concat x a) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (concat x a) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-concat-1-neq.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-concat-1-neq.smt2
new file mode 100644 (file)
index 0000000..7dab563
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
+; EXPECT: unsat
+(set-logic BV)
+(set-info :status unsat)
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 16))
+
+(assert (forall ((x (_ BitVec 8))) (= (concat a x) b)))
+
+(check-sat)
index 827e746050fea5d9fc249d2ce344b6fd3b5ef4a0..13fb3e1c2e3ec20785218d300b6aff7c25031d1e 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 64))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 16))
 
-(assert (forall ((x (_ BitVec 32))) (not (= (concat a x) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= (concat a x) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-disequality.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-disequality.smt2
deleted file mode 100644 (file)
index 6ba7825..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep
-; EXPECT: sat
-(set-logic BV)
-(set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
-
-(assert (forall ((x (_ BitVec 32))) (= (bvand x a) b)))
-
-(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-mul.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-mul.smt2
deleted file mode 100644 (file)
index 84e9fa7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-; COMMAND-LINE: --cbqi-bv
-; EXPECT: sat
-(set-logic BV)
-(set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
-
-(assert (forall ((x (_ BitVec 32))) (not (= (bvmul x a) b))))
-
-(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-shl.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-shl.smt2
deleted file mode 100644 (file)
index 97a0662..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-; COMMAND-LINE: --cbqi-bv
-; EXPECT: sat
-(set-logic BV)
-(set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 32))
-
-(assert (forall ((x (_ BitVec 32))) (not (= (bvshl x a) b))))
-
-(check-sat)
index 21aa519ada314b1f645c2d41675639461c48466a..43019c4cb888977408f130ef72b42c0bd909b0c4 100644 (file)
@@ -1,10 +1,10 @@
-; COMMAND-LINE: --cbqi-bv
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
-(declare-fun a () (_ BitVec 32))
-(declare-fun b () (_ BitVec 64))
+(declare-fun a () (_ BitVec 8))
+(declare-fun b () (_ BitVec 16))
 
-(assert (forall ((x (_ BitVec 32))) (not (= ((_ sign_extend 32) x) b))))
+(assert (forall ((x (_ BitVec 8))) (not (= ((_ sign_extend 8) x) b))))
 
 (check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-udiv-0.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-udiv-0.smt2
deleted file mode 100644 (file)
index becfc53..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-; COMMAND-LINE: --cbqi-bv --bv-div-zero-const
-; EXPECT: sat
-(set-logic BV)
-(set-info :status sat)
-(declare-fun a () (_ BitVec 16))
-(declare-fun b () (_ BitVec 16))
-
-(assert (distinct a b (_ bv0 16)))
-(assert (forall ((x (_ BitVec 16))) (not (= (bvudiv x a) b))))
-
-(check-sat)
diff --git a/test/regress/regress0/quantifiers/qbv-test-invert-udiv-1.smt2 b/test/regress/regress0/quantifiers/qbv-test-invert-udiv-1.smt2
deleted file mode 100644 (file)
index bf69a8b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-; COMMAND-LINE: --cbqi-bv --bv-div-zero-const
-; EXPECT: sat
-(set-logic BV)
-(set-info :status sat)
-(declare-fun a () (_ BitVec 8))
-(declare-fun b () (_ BitVec 8))
-
-(assert (distinct a b (_ bv0 8)))
-(assert (forall ((x (_ BitVec 8))) (not (= (bvudiv a x) b))))
-
-(check-sat)
index 6df69d80b9e3db08eb86159962766f6af77ea26b..e57352b8f1a44ff83bcd434a1d9009d83db5680d 100644 (file)
@@ -1,4 +1,4 @@
-; COMMAND-LINE: --cbqi-bv --bv-div-zero-const
+; COMMAND-LINE: --cbqi-bv --cbqi-bv-ineq=keep --no-cbqi-full
 ; EXPECT: sat
 (set-logic BV)
 (set-info :status sat)
index ce01c17e40937fdda010da9c8678d5c652c4566a..5e1d404dc189ade49e672c6a61df4d133901c37b 100644 (file)
@@ -23,6 +23,7 @@
 #include "util/result.h"
 
 using namespace CVC4;
+using namespace CVC4::kind;
 using namespace CVC4::theory;
 using namespace CVC4::theory::quantifiers;
 using namespace CVC4::smt;
@@ -45,58 +46,63 @@ class TheoryQuantifiersBvInverter : public CxxTest::TestSuite
                    unsigned idx,
                    Node (*getsc)(bool, Kind, unsigned, Node, Node))
   {
-    Assert(k == kind::BITVECTOR_ULT
-        || k == kind::BITVECTOR_SLT
-        || k == kind::EQUAL);
-    Assert(k != kind::EQUAL || pol == false);
+    Assert(k == BITVECTOR_ULT || k == BITVECTOR_SLT || k == EQUAL);
+    Assert(k != EQUAL || pol == false);
 
     Node sc = getsc(pol, k, idx, d_sk, d_t);
     Kind ksc = sc.getKind();
-    TS_ASSERT((k == kind::BITVECTOR_ULT && pol == false)
-           || (k == kind::BITVECTOR_SLT && pol == false)
-           || ksc == kind::IMPLIES);
-    Node scl = ksc == kind::IMPLIES ? sc[0] : bv::utils::mkTrue();
+    TS_ASSERT((k == BITVECTOR_ULT && pol == false)
+           || (k == BITVECTOR_SLT && pol == false)
+           || ksc == IMPLIES);
+    Node scl = ksc == IMPLIES ? sc[0] : bv::utils::mkTrue();
     if (!pol)
     {
-      k = k == kind::BITVECTOR_ULT
-        ? kind::BITVECTOR_UGE
-        : (k == kind::BITVECTOR_SLT ? kind::BITVECTOR_SGE : kind::DISTINCT);
+      k = k == BITVECTOR_ULT
+        ? BITVECTOR_UGE
+        : (k == BITVECTOR_SLT ? BITVECTOR_SGE : DISTINCT);
     }
     Node body = idx == 0
       ? d_nm->mkNode(k, d_x, d_t)
       : d_nm->mkNode(k, d_t, d_x);
-    Node scr = d_nm->mkNode(kind::EXISTS, d_bvarlist, body);
-    Expr a = d_nm->mkNode(kind::DISTINCT, scl, scr).toExpr();
+    Node scr = d_nm->mkNode(EXISTS, d_bvarlist, body);
+    Expr a = d_nm->mkNode(DISTINCT, scl, scr).toExpr();
     Result res = d_smt->checkSat(a);
     TS_ASSERT(res.d_sat == Result::UNSAT);
   }
 
-  void runTest(Kind k,
+  void runTest(bool pol,
+               Kind litk,
+               Kind k,
                unsigned idx,
-               Node (*getsc)(Kind, unsigned, Node, Node, Node))
-  {
-    Assert(k == kind::BITVECTOR_MULT
-           || k == kind::BITVECTOR_UREM_TOTAL
-           || k == kind::BITVECTOR_UDIV_TOTAL
-           || k == kind::BITVECTOR_AND
-           || k == kind::BITVECTOR_OR
-           || k == kind::BITVECTOR_LSHR
-           || k == kind::BITVECTOR_ASHR
-           || k == kind::BITVECTOR_SHL);
-    Assert(k != kind::BITVECTOR_UREM_TOTAL || idx == 1);
-
-    Node sc = getsc(k, idx, d_sk, d_s, d_t);
+               Node (*getsc)(bool, Kind, Kind, unsigned, Node, Node, Node))
+  {
+    Assert(k == BITVECTOR_MULT
+           || k == BITVECTOR_UREM_TOTAL
+           || k == BITVECTOR_UDIV_TOTAL
+           || k == BITVECTOR_AND
+           || k == BITVECTOR_OR
+           || k == BITVECTOR_LSHR
+           || k == BITVECTOR_ASHR
+           || k == BITVECTOR_SHL);
+    Assert(k != BITVECTOR_UREM_TOTAL || pol == false || idx == 1);
+
+    Node sc = getsc(pol, litk, k, idx, d_sk, d_s, d_t);
+    TS_ASSERT (litk != EQUAL || sc != Node::null());
     Kind ksc = sc.getKind();
-    TS_ASSERT(ksc == kind::IMPLIES);
+    TS_ASSERT((k == BITVECTOR_UDIV_TOTAL && idx == 1 && pol == false)
+              || (k == BITVECTOR_ASHR && idx == 0 && pol == false)
+              || ksc == IMPLIES);
+    Node scl = ksc == IMPLIES ? sc[0] : bv::utils::mkTrue();
     Node body = idx == 0
-      ? d_nm->mkNode(k, d_x, d_s).eqNode(d_t)
-      : d_nm->mkNode(k, d_s, d_x).eqNode(d_t);
-    Node scr = d_nm->mkNode(kind::EXISTS, d_bvarlist, body);
-    Expr a = d_nm->mkNode(kind::DISTINCT, sc[0], scr).toExpr();
+      ? d_nm->mkNode(pol ? EQUAL : DISTINCT, d_nm->mkNode(k, d_x, d_s), d_t)
+      : d_nm->mkNode(pol ? EQUAL : DISTINCT, d_nm->mkNode(k, d_s, d_x), d_t);
+    Node scr = d_nm->mkNode(EXISTS, d_bvarlist, body);
+    Expr a = d_nm->mkNode(DISTINCT, scl, scr).toExpr();
     Result res = d_smt->checkSat(a);
     if (res.d_sat == Result::SAT)
     {
-      std::cout << std::endl << "s " << d_smt->getValue(d_s.toExpr()) << std::endl;
+      std::cout << std::endl;
+      std::cout << "s " << d_smt->getValue(d_s.toExpr()) << std::endl;
       std::cout << "t " << d_smt->getValue(d_t.toExpr()) << std::endl;
       std::cout << "x " << d_smt->getValue(d_x.toExpr()) << std::endl;
     }
@@ -119,7 +125,7 @@ class TheoryQuantifiersBvInverter : public CxxTest::TestSuite
     d_t = d_nm->mkVar("t", d_nm->mkBitVectorType(4));
     d_sk = d_nm->mkSkolem("sk", d_t.getType());
     d_x = d_nm->mkBoundVar(d_t.getType());
-    d_bvarlist = d_nm->mkNode(kind::BOUND_VAR_LIST, { d_x });
+    d_bvarlist = d_nm->mkNode(BOUND_VAR_LIST, { d_x });
   }
 
   void tearDown()
@@ -174,99 +180,163 @@ class TheoryQuantifiersBvInverter : public CxxTest::TestSuite
     runTestPred(false, BITVECTOR_SLT, 1, getScBvSlt);
   }
 
-  void testGetScBvEq0()
+  void testGetScBvMultEqTrue0()
   {
-    runTestPred(false, EQUAL, 0, getScBvEq);
-    TS_ASSERT_THROWS(runTestPred(true, EQUAL, 0, getScBvEq),
-                     AssertionException);
+    runTest(true, EQUAL, BITVECTOR_MULT, 0, getScBvMult);
   }
 
-  void testGetScBvEq1()
+  void testGetScBvMultEqTrue1()
   {
-    runTestPred(false, EQUAL, 1, getScBvEq);
-    TS_ASSERT_THROWS(runTestPred(true, EQUAL, 1, getScBvEq),
-                     AssertionException);
+    runTest(true, EQUAL, BITVECTOR_MULT, 1, getScBvMult);
   }
 
-  void testGetScBvMult0()
+  void testGetScBvMultEqFalse0()
   {
-    runTest(BITVECTOR_MULT, 0, getScBvMult);
+    runTest(false, EQUAL, BITVECTOR_MULT, 0, getScBvMult);
   }
 
-  void testGetScBvMult1()
+  void testGetScBvMultEqFalse1()
   {
-    runTest(BITVECTOR_MULT, 1, getScBvMult);
+    runTest(false, EQUAL, BITVECTOR_MULT, 1, getScBvMult);
   }
 
-  void testGetScBvUrem0()
+  void testGetScBvUremEqTrue0()
   {
-    TS_ASSERT_THROWS(runTest(BITVECTOR_UREM_TOTAL, 0, getScBvUrem),
+    TS_ASSERT_THROWS(runTest(true, EQUAL, BITVECTOR_UREM_TOTAL, 0, getScBvUrem),
                      AssertionException);
   }
 
-  void testGetScBvUrem1()
+  void testGetScBvUremEqTrue1()
+  {
+    runTest(true, EQUAL, BITVECTOR_UREM_TOTAL, 1, getScBvUrem);
+  }
+
+  void testGetScBvUremEqFalse0()
+  {
+    runTest(false, EQUAL, BITVECTOR_UREM_TOTAL, 0, getScBvUrem);
+  }
+
+  void testGetScBvUremEqFalse1()
+  {
+    runTest(false, EQUAL, BITVECTOR_UREM_TOTAL, 1, getScBvUrem);
+  }
+  void testGetScBvUdivEqTrue0()
+  {
+    runTest(true, EQUAL, BITVECTOR_UDIV_TOTAL, 0, getScBvUdiv);
+  }
+
+  void testGetScBvUdivEqTrue1()
+  {
+    runTest(true, EQUAL, BITVECTOR_UDIV_TOTAL, 1, getScBvUdiv);
+  }
+
+  void testGetScBvUdivFalse0()
   {
-    runTest(BITVECTOR_UREM_TOTAL, 1, getScBvUrem);
+    runTest(false, EQUAL, BITVECTOR_UDIV_TOTAL, 0, getScBvUdiv);
   }
 
-  void testGetScBvUdiv0()
+  void testGetScBvUdivFalse1()
   {
-    runTest(BITVECTOR_UDIV_TOTAL, 0, getScBvUdiv);
+    runTest(false, EQUAL, BITVECTOR_UDIV_TOTAL, 1, getScBvUdiv);
   }
 
-  void testGetScBvUdiv1()
+  void testGetScBvAndEqTrue0()
   {
-    runTest(BITVECTOR_UDIV_TOTAL, 1, getScBvUdiv);
+    runTest(true, EQUAL, BITVECTOR_AND, 0, getScBvAndOr);
   }
 
-  void testGetScBvAnd0()
+  void testGetScBvAndEqTrue1()
   {
-    runTest(BITVECTOR_AND, 0, getScBvAndOr);
+    runTest(true, EQUAL, BITVECTOR_AND, 1, getScBvAndOr);
   }
 
-  void testGetScBvAnd1()
+  void testGetScBvAndEqFalse0()
   {
-    runTest(BITVECTOR_AND, 1, getScBvAndOr);
+    runTest(false, EQUAL, BITVECTOR_AND, 0, getScBvAndOr);
   }
 
-  void testGetScBvOr0()
+  void testGetScBvAndEqFalse1()
   {
-    runTest(BITVECTOR_OR, 0, getScBvAndOr);
+    runTest(false, EQUAL, BITVECTOR_AND, 1, getScBvAndOr);
   }
 
-  void testGetScBvOr1()
+  void testGetScBvOrEqTrue0()
   {
-    runTest(BITVECTOR_OR, 1, getScBvAndOr);
+    runTest(true, EQUAL, BITVECTOR_OR, 0, getScBvAndOr);
   }
 
-  void testGetScBvLshr0()
+  void testGetScBvOrEqTrue1()
   {
-    runTest(BITVECTOR_LSHR, 0, getScBvLshr);
+    runTest(true, EQUAL, BITVECTOR_OR, 1, getScBvAndOr);
   }
 
-  void testGetScBvLshr1()
+  void testGetScBvOrEqFalse0()
   {
-    runTest(BITVECTOR_LSHR, 1, getScBvLshr);
+    runTest(false, EQUAL, BITVECTOR_OR, 0, getScBvAndOr);
   }
 
-  void testGetScBvAshr0()
+  void testGetScBvOrEqFalse1()
   {
-    runTest(BITVECTOR_ASHR, 0, getScBvAshr);
+    runTest(false, EQUAL, BITVECTOR_OR, 1, getScBvAndOr);
   }
 
-  void testGetScBvAshr1()
+  void testGetScBvLshrEqTrue0()
   {
-    runTest(BITVECTOR_ASHR, 1, getScBvAshr);
+    runTest(true, EQUAL, BITVECTOR_LSHR, 0, getScBvLshr);
   }
 
-  void testGetScBvShl0()
+  void testGetScBvLshrEqTrue1()
   {
-    runTest(BITVECTOR_SHL, 0, getScBvShl);
+    runTest(true, EQUAL, BITVECTOR_LSHR, 1, getScBvLshr);
   }
 
-  void testGetScBvShl1()
+  void testGetScBvLshrEqFalse0()
   {
-    runTest(BITVECTOR_SHL, 1, getScBvShl);
+    runTest(false, EQUAL, BITVECTOR_LSHR, 0, getScBvLshr);
   }
 
+  void testGetScBvLshrEqFalse1()
+  {
+    runTest(false, EQUAL, BITVECTOR_LSHR, 1, getScBvLshr);
+  }
+
+  void testGetScBvAshrEqTrue0()
+  {
+    runTest(true, EQUAL, BITVECTOR_ASHR, 0, getScBvAshr);
+  }
+
+  void testGetScBvAshrEqTrue1()
+  {
+    runTest(true, EQUAL, BITVECTOR_ASHR, 1, getScBvAshr);
+  }
+
+  void testGetScBvAshrEqFalse0()
+  {
+    runTest(false, EQUAL, BITVECTOR_ASHR, 0, getScBvAshr);
+  }
+
+  void testGetScBvAshrEqFalse1()
+  {
+    runTest(false, EQUAL, BITVECTOR_ASHR, 1, getScBvAshr);
+  }
+
+  void testGetScBvShlEqTrue0()
+  {
+    runTest(true, EQUAL, BITVECTOR_SHL, 0, getScBvShl);
+  }
+
+  void testGetScBvShlEqTrue1()
+  {
+    runTest(true, EQUAL, BITVECTOR_SHL, 1, getScBvShl);
+  }
+
+  void testGetScBvShlEqFalse0()
+  {
+    runTest(false, EQUAL, BITVECTOR_SHL, 0, getScBvShl);
+  }
+
+  void testGetScBvShlEqFalse1()
+  {
+    runTest(false, EQUAL, BITVECTOR_SHL, 1, getScBvShl);
+  }
 };