Theory of Bit-Vectors 
examples/api/cpp/bitvectors.cpp
  1 /******************************************************************************
  2  * Top contributors (to current version):
  3  *   Liana Hadarean, Aina Niemetz, Mathias Preiner
  4  *
  5  * This file is part of the cvc5 project.
  6  *
  7  * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  8  * in the top-level source directory and their institutional affiliations.
  9  * All rights reserved.  See the file COPYING in the top-level source
 10  * directory for licensing information.
 11  * ****************************************************************************
 12  *
 13  * A simple demonstration of the solving capabilities of the cvc5
 14  * bit-vector solver.
 15  *
 16  */
 17 
 18 #include <cvc5/cvc5.h>
 19 
 20 #include <iostream>
 21 
 22 using namespace std;
 23 using namespace cvc5;
 24 
 25 int main()
 26 {
 27   Solver slv;
 28   slv.setLogic("QF_BV");  // Set the logic
 29 
 30   // The following example has been adapted from the book A Hacker's Delight by
 31   // Henry S. Warren.
 32   //
 33   // Given a variable x that can only have two values, a or b. We want to
 34   // assign to x a value other than the current one. The straightforward code
 35   // to do that is:
 36   //
 37   //(0) if (x == a ) x = b;
 38   //    else x = a;
 39   //
 40   // Two more efficient yet equivalent methods are:
 41   //
 42   //(1) x = a ⊕ b ⊕ x;
 43   //
 44   //(2) x = a + b - x;
 45   //
 46   // We will use cvc5 to prove that the three pieces of code above are all
 47   // equivalent by encoding the problem in the bit-vector theory.
 48 
 49   // Creating a bit-vector type of width 32
 50   Sort bitvector32 = slv.mkBitVectorSort(32);
 51 
 52   // Variables
 53   Term x = slv.mkConst(bitvector32, "x");
 54   Term a = slv.mkConst(bitvector32, "a");
 55   Term b = slv.mkConst(bitvector32, "b");
 56 
 57   // First encode the assumption that x must be equal to a or b
 58   Term x_eq_a = slv.mkTerm(EQUAL, {x, a});
 59   Term x_eq_b = slv.mkTerm(EQUAL, {x, b});
 60   Term assumption = slv.mkTerm(OR, {x_eq_a, x_eq_b});
 61 
 62   // Assert the assumption
 63   slv.assertFormula(assumption);
 64 
 65   // Introduce a new variable for the new value of x after assignment.
 66   Term new_x = slv.mkConst(bitvector32, "new_x");  // x after executing code (0)
 67   Term new_x_ =
 68       slv.mkConst(bitvector32, "new_x_");  // x after executing code (1) or (2)
 69 
 70   // Encoding code (0)
 71   // new_x = x == a ? b : a;
 72   Term ite = slv.mkTerm(ITE, {x_eq_a, b, a});
 73   Term assignment0 = slv.mkTerm(EQUAL, {new_x, ite});
 74 
 75   // Assert the encoding of code (0)
 76   cout << "Asserting " << assignment0 << " to cvc5 " << endl;
 77   slv.assertFormula(assignment0);
 78   cout << "Pushing a new context." << endl;
 79   slv.push();
 80 
 81   // Encoding code (1)
 82   // new_x_ = a xor b xor x
 83   Term a_xor_b_xor_x = slv.mkTerm(BITVECTOR_XOR, {a, b, x});
 84   Term assignment1 = slv.mkTerm(EQUAL, {new_x_, a_xor_b_xor_x});
 85 
 86   // Assert encoding to cvc5 in current context;
 87   cout << "Asserting " << assignment1 << " to cvc5 " << endl;
 88   slv.assertFormula(assignment1);
 89   Term new_x_eq_new_x_ = slv.mkTerm(EQUAL, {new_x, new_x_});
 90 
 91   cout << " Check sat assuming: " << new_x_eq_new_x_.notTerm() << endl;
 92   cout << " Expect UNSAT. " << endl;
 93   cout << " cvc5: " << slv.checkSatAssuming(new_x_eq_new_x_.notTerm()) << endl;
 94   cout << " Popping context. " << endl;
 95   slv.pop();
 96 
 97   // Encoding code (2)
 98   // new_x_ = a + b - x
 99   Term a_plus_b = slv.mkTerm(BITVECTOR_ADD, {a, b});
100   Term a_plus_b_minus_x = slv.mkTerm(BITVECTOR_SUB, {a_plus_b, x});
101   Term assignment2 = slv.mkTerm(EQUAL, {new_x_, a_plus_b_minus_x});
102 
103   // Assert encoding to cvc5 in current context;
104   cout << "Asserting " << assignment2 << " to cvc5 " << endl;
105   slv.assertFormula(assignment2);
106 
107   cout << " Check sat assuming: " << new_x_eq_new_x_.notTerm() << endl;
108   cout << " Expect UNSAT. " << endl;
109   cout << " cvc5: " << slv.checkSatAssuming(new_x_eq_new_x_.notTerm()) << endl;
110 
111   Term x_neq_x = slv.mkTerm(EQUAL, {x, x}).notTerm();
112   std::vector<Term> v{new_x_eq_new_x_, x_neq_x};
113   Term query = slv.mkTerm(AND, {v});
114   cout << " Check sat assuming: " << query.notTerm() << endl;
115   cout << " Expect SAT. " << endl;
116   cout << " cvc5: " << slv.checkSatAssuming(query.notTerm()) << endl;
117 
118   // Assert that a is odd
119   Op extract_op = slv.mkOp(BITVECTOR_EXTRACT, {0, 0});
120   Term lsb_of_a = slv.mkTerm(extract_op, {a});
121   cout << "Sort of " << lsb_of_a << " is " << lsb_of_a.getSort() << endl;
122   Term a_odd = slv.mkTerm(EQUAL, {lsb_of_a, slv.mkBitVector(1u, 1u)});
123   cout << "Assert " << a_odd << endl;
124   cout << "Check satisfiability." << endl;
125   slv.assertFormula(a_odd);
126   cout << " Expect sat. " << endl;
127   cout << " cvc5: " << slv.checkSat() << endl;
128   return 0;
129 }
            examples/api/java/BitVectors.java
  1 /******************************************************************************
  2  * Top contributors (to current version):
  3  *   Mudathir Mohamed, Liana Hadarean, Morgan Deters
  4  *
  5  * This file is part of the cvc5 project.
  6  *
  7  * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  8  * in the top-level source directory and their institutional affiliations.
  9  * All rights reserved.  See the file COPYING in the top-level source
 10  * directory for licensing information.
 11  * ****************************************************************************
 12  *
 13  * A simple demonstration of the solving capabilities of the cvc5
 14  * bit-vector solver.
 15  *
 16  */
 17 
 18 import io.github.cvc5.*;
 19 import java.util.*;
 20 
 21 public class BitVectors
 22 {
 23   public static void main(String args[]) throws CVC5ApiException
 24   {
 25     try (Solver slv = new Solver())
 26     {
 27       slv.setLogic("QF_BV"); // Set the logic
 28 
 29       // The following example has been adapted from the book A Hacker's Delight by
 30       // Henry S. Warren.
 31       //
 32       // Given a variable x that can only have two values, a or b. We want to
 33       // assign to x a value other than the current one. The straightforward code
 34       // to do that is:
 35       //
 36       //(0) if (x == a ) x = b;
 37       //    else x = a;
 38       //
 39       // Two more efficient yet equivalent methods are:
 40       //
 41       //(1) x = a ⊕ b ⊕ x;
 42       //
 43       //(2) x = a + b - x;
 44       //
 45       // We will use cvc5 to prove that the three pieces of code above are all
 46       // equivalent by encoding the problem in the bit-vector theory.
 47 
 48       // Creating a bit-vector type of width 32
 49       Sort bitvector32 = slv.mkBitVectorSort(32);
 50 
 51       // Variables
 52       Term x = slv.mkConst(bitvector32, "x");
 53       Term a = slv.mkConst(bitvector32, "a");
 54       Term b = slv.mkConst(bitvector32, "b");
 55 
 56       // First encode the assumption that x must be Kind.EQUAL to a or b
 57       Term x_eq_a = slv.mkTerm(Kind.EQUAL, x, a);
 58       Term x_eq_b = slv.mkTerm(Kind.EQUAL, x, b);
 59       Term assumption = slv.mkTerm(Kind.OR, x_eq_a, x_eq_b);
 60 
 61       // Assert the assumption
 62       slv.assertFormula(assumption);
 63 
 64       // Introduce a new variable for the new value of x after assignment.
 65       Term new_x = slv.mkConst(bitvector32, "new_x"); // x after executing code (0)
 66       Term new_x_ = slv.mkConst(bitvector32, "new_x_"); // x after executing code (1) or (2)
 67 
 68       // Encoding code (0)
 69       // new_x = x == a ? b : a;
 70       Term ite = slv.mkTerm(Kind.ITE, x_eq_a, b, a);
 71       Term assignment0 = slv.mkTerm(Kind.EQUAL, new_x, ite);
 72 
 73       // Assert the encoding of code (0)
 74       System.out.println("Asserting " + assignment0 + " to cvc5 ");
 75       slv.assertFormula(assignment0);
 76       System.out.println("Pushing a new context.");
 77       slv.push();
 78 
 79       // Encoding code (1)
 80       // new_x_ = a xor b xor x
 81       Term a_xor_b_xor_x = slv.mkTerm(Kind.BITVECTOR_XOR, a, b, x);
 82       Term assignment1 = slv.mkTerm(Kind.EQUAL, new_x_, a_xor_b_xor_x);
 83 
 84       // Assert encoding to cvc5 in current context;
 85       System.out.println("Asserting " + assignment1 + " to cvc5 ");
 86       slv.assertFormula(assignment1);
 87       Term new_x_eq_new_x_ = slv.mkTerm(Kind.EQUAL, new_x, new_x_);
 88 
 89       System.out.println(" Check sat assuming: " + new_x_eq_new_x_.notTerm());
 90       System.out.println(" Expect UNSAT. ");
 91       System.out.println(" cvc5: " + slv.checkSatAssuming(new_x_eq_new_x_.notTerm()));
 92       System.out.println(" Popping context. ");
 93       slv.pop();
 94 
 95       // Encoding code (2)
 96       // new_x_ = a + b - x
 97       Term a_plus_b = slv.mkTerm(Kind.BITVECTOR_ADD, a, b);
 98       Term a_plus_b_minus_x = slv.mkTerm(Kind.BITVECTOR_SUB, a_plus_b, x);
 99       Term assignment2 = slv.mkTerm(Kind.EQUAL, new_x_, a_plus_b_minus_x);
100 
101       // Assert encoding to cvc5 in current context;
102       System.out.println("Asserting " + assignment2 + " to cvc5 ");
103       slv.assertFormula(assignment2);
104 
105       System.out.println(" Check sat assuming: " + new_x_eq_new_x_.notTerm());
106       System.out.println(" Expect UNSAT. ");
107       System.out.println(" cvc5: " + slv.checkSatAssuming(new_x_eq_new_x_.notTerm()));
108 
109       Term x_neq_x = slv.mkTerm(Kind.EQUAL, x, x).notTerm();
110       Term[] v = new Term[] {new_x_eq_new_x_, x_neq_x};
111       Term query = slv.mkTerm(Kind.AND, v);
112       System.out.println(" Check sat assuming: " + query.notTerm());
113       System.out.println(" Expect SAT. ");
114       System.out.println(" cvc5: " + slv.checkSatAssuming(query.notTerm()));
115 
116       // Assert that a is odd
117       Op extract_op = slv.mkOp(Kind.BITVECTOR_EXTRACT, 0, 0);
118       Term lsb_of_a = slv.mkTerm(extract_op, a);
119       System.out.println("Sort of " + lsb_of_a + " is " + lsb_of_a.getSort());
120       Term a_odd = slv.mkTerm(Kind.EQUAL, lsb_of_a, slv.mkBitVector(1, 1));
121       System.out.println("Assert " + a_odd);
122       System.out.println("Check satisfiability.");
123       slv.assertFormula(a_odd);
124       System.out.println(" Expect sat. ");
125       System.out.println(" cvc5: " + slv.checkSat());
126     }
127   }
128 }
            examples/api/python/pythonic/bitvectors.py
 1 from cvc5.pythonic import *
 2 
 3 if __name__ == '__main__':
 4     # The following example has been adapted from the book A Hacker's Delight
 5     # by Henry S. Warren.
 6     #
 7     # Given a variable x that can only have two values, a or b. We want to
 8     # assign to x a value other than the current one. The straightforward code
 9     # to do that is:
10     #
11     # (0) if (x == a ) x = b;
12     #     else x = a;
13     #
14     # Two more efficient yet equivalent methods are:
15     #
16     # (1) x = a xor b xor x;
17     #
18     # (2) x = a + b - x;
19     #
20     # We will use cvc5 to prove that the three pieces of code above are all
21     # equivalent by encoding the problem in the bit-vector theory.
22 
23     x, a, b = BitVecs('x a b', 32)
24     x_is_a_or_b = Or(x == a, x == b)
25 
26     # new_x0 set per (0)
27     new_x0 = If(x == a, b, a)
28     # new_x1 set per (1)
29     new_x1 = a ^ b ^ x
30     # new_x2 set per (2)
31     new_x2 = a + b - x
32 
33     prove(Implies(x_is_a_or_b, new_x0 == new_x1))
34 
35     prove(Implies(x_is_a_or_b, new_x0 == new_x2))
            examples/api/python/bitvectors.py
  1 #!/usr/bin/env python
  2 ###############################################################################
  3 # Top contributors (to current version):
  4 #   Makai Mann, Aina Niemetz, Andrew Reynolds
  5 #
  6 # This file is part of the cvc5 project.
  7 #
  8 # Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  9 # in the top-level source directory and their institutional affiliations.
 10 # All rights reserved.  See the file COPYING in the top-level source
 11 # directory for licensing information.
 12 # #############################################################################
 13 #
 14 # A simple demonstration of the solving capabilities of the cvc5 bit-vector
 15 # solver through the Python API. This is a direct translation of
 16 # bitvectors-new.cpp.
 17 ##
 18 
 19 import cvc5
 20 from cvc5 import Kind
 21 
 22 if __name__ == "__main__":
 23     slv = cvc5.Solver()
 24     slv.setLogic("QF_BV") # Set the logic
 25     # The following example has been adapted from the book A Hacker's Delight by
 26     # Henry S. Warren.
 27     #
 28     # Given a variable x that can only have two values, a or b. We want to
 29     # assign to x a value other than the current one. The straightforward code
 30     # to do that is:
 31     #
 32     #(0) if (x == a ) x = b;
 33     #    else x = a;
 34     #
 35     # Two more efficient yet equivalent methods are:
 36     #
 37     #(1) x = a xor b xor x;
 38     #
 39     #(2) x = a + b - x;
 40     #
 41     # We will use cvc5 to prove that the three pieces of code above are all
 42     # equivalent by encoding the problem in the bit-vector theory.
 43 
 44     # Creating a bit-vector type of width 32
 45     bitvector32 = slv.mkBitVectorSort(32)
 46 
 47     # Variables
 48     x = slv.mkConst(bitvector32, "x")
 49     a = slv.mkConst(bitvector32, "a")
 50     b = slv.mkConst(bitvector32, "b")
 51 
 52     # First encode the assumption that x must be equal to a or b
 53     x_eq_a = slv.mkTerm(Kind.EQUAL, x, a)
 54     x_eq_b = slv.mkTerm(Kind.EQUAL, x, b)
 55     assumption = slv.mkTerm(Kind.OR, x_eq_a, x_eq_b)
 56 
 57     # Assert the assumption
 58     slv.assertFormula(assumption)
 59 
 60     # Introduce a new variable for the new value of x after assignment.
 61     # x after executing code (0)
 62     new_x = slv.mkConst(bitvector32, "new_x")
 63     # x after executing code (1) or (2)
 64     new_x_ = slv.mkConst(bitvector32, "new_x_")
 65 
 66     # Encoding code (0)
 67     # new_x = x == a ? b : a
 68     ite = slv.mkTerm(Kind.ITE, x_eq_a, b, a)
 69     assignment0 = slv.mkTerm(Kind.EQUAL, new_x, ite)
 70 
 71     # Assert the encoding of code (0)
 72     print("Asserting {} to cvc5".format(assignment0))
 73     slv.assertFormula(assignment0)
 74     print("Pushing a new context.")
 75     slv.push()
 76 
 77     # Encoding code (1)
 78     # new_x_ = a xor b xor x
 79     a_xor_b_xor_x = slv.mkTerm(Kind.BITVECTOR_XOR, a, b, x)
 80     assignment1 = slv.mkTerm(Kind.EQUAL, new_x_, a_xor_b_xor_x)
 81 
 82     # Assert encoding to cvc5 in current context
 83     print("Asserting {} to cvc5".format(assignment1))
 84     slv.assertFormula(assignment1)
 85     new_x_eq_new_x_ = slv.mkTerm(Kind.EQUAL, new_x, new_x_)
 86 
 87     print("Checking sat assuming:", new_x_eq_new_x_.notTerm())
 88     print("Expect UNSAT.")
 89     print("cvc5:", slv.checkSatAssuming(new_x_eq_new_x_.notTerm()))
 90     print("Popping context.")
 91     slv.pop()
 92 
 93     # Encoding code (2)
 94     # new_x_ = a + b - x
 95     a_plus_b = slv.mkTerm(Kind.BITVECTOR_ADD, a, b)
 96     a_plus_b_minus_x = slv.mkTerm(Kind.BITVECTOR_SUB, a_plus_b, x)
 97     assignment2 = slv.mkTerm(Kind.EQUAL, new_x_, a_plus_b_minus_x)
 98 
 99     # Assert encoding to cvc5 in current context
100     print("Asserting {} to cvc5".format(assignment2))
101     slv.assertFormula(assignment2)
102 
103     print("Checking sat assuming:", new_x_eq_new_x_.notTerm())
104     print("Expect UNSAT.")
105     print("cvc5:", slv.checkSatAssuming(new_x_eq_new_x_.notTerm()))
106 
107 
108     x_neq_x = slv.mkTerm(Kind.EQUAL, x, x).notTerm()
109     query = slv.mkTerm(Kind.AND, new_x_eq_new_x_, x_neq_x)
110     print("Check sat assuming: ", query.notTerm())
111     print("Expect SAT.")
112     print("cvc5:", slv.checkSatAssuming(query.notTerm()))
113 
114     # Assert that a is odd
115     extract_op = slv.mkOp(Kind.BITVECTOR_EXTRACT, 0, 0)
116     lsb_of_a = slv.mkTerm(extract_op, a)
117     print("Sort of {} is {}".format(lsb_of_a, lsb_of_a.getSort()))
118     a_odd = slv.mkTerm(Kind.EQUAL, lsb_of_a, slv.mkBitVector(1, 1))
119     print("Assert", a_odd)
120     print("Check satisifiability")
121     slv.assertFormula(a_odd)
122     print("Expect sat")
123     print("cvc5:", slv.checkSat())
            examples/api/smtlib/bitvectors.smt2
 1 (set-logic QF_BV)
 2 (set-option :incremental true)
 3 
 4 (declare-const x (_ BitVec 32))
 5 (declare-const a (_ BitVec 32))
 6 (declare-const b (_ BitVec 32))
 7 (declare-const new_x (_ BitVec 32))
 8 (declare-const new_x_ (_ BitVec 32))
 9 
10 (echo "Assert the assumption.")
11 (assert (or (= x a) (= x b)))
12 
13 (echo "Asserting assignment to cvc5.")
14 (assert (= new_x (ite (= x a) b a)))
15 
16 (echo "Pushing a new context.")
17 (push 1)
18 
19 (echo "Asserting another assignment to cvc5.")
20 (assert (= new_x_ (bvxor a b x)))
21 
22 (echo "Check entailment assuming new_x = new_x_.")
23 (echo "UNSAT (of negation) == ENTAILED")
24 (check-sat-assuming ((not (= new_x new_x_))))
25 (echo "Popping context.")
26 (pop 1)
27 
28 (echo "Asserting another assignment to cvc5.")
29 (assert (= new_x_ (bvsub (bvadd a b) x)))
30 
31 (echo "Check entailment assuming new_x = new_x_.")
32 (echo "UNSAT (of negation) == ENTAILED")
33 (check-sat-assuming ((not (= new_x new_x_))))
34 
35 (echo "Check entailment assuming [new_x = new_x_, x != x.")
36 (echo "UNSAT (of negation) == ENTAILED")
37 (check-sat-assuming ((not (= new_x new_x_)) (not (= x x))))
38 
39 (echo "Assert that a is odd, i.e. lsb is one.")
40 (assert (= ((_ extract 0 0) a) (_ bv1 1)))
41 (echo "Check satisfiability, expecting sat.")
42 (check-sat)