Theory of Bit-Vectors and Arrays 
examples/api/cpp/bitvectors_and_arrays.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 and array solvers.
15  *
16  */
17 
18 #include <cvc5/cvc5.h>
19 
20 #include <cmath>
21 #include <iostream>
22 
23 using namespace std;
24 using namespace cvc5;
25 
26 int main()
27 {
28   Solver slv;
29   slv.setOption("produce-models", "true");      // Produce Models
30   slv.setOption("output-language", "smtlib"); // output-language
31   slv.setLogic("QF_AUFBV");                   // Set the logic
32 
33   // Consider the following code (where size is some previously defined constant):
34   //
35   //
36   //   Assert (current_array[0] > 0);
37   //   for (unsigned i = 1; i < k; ++i) {
38   //     current_array[i] = 2 * current_array[i - 1];
39   //     Assert (current_array[i-1] < current_array[i]);
40   //     }
41   //
42   // We want to check whether the assertion in the body of the for loop holds
43   // throughout the loop.
44 
45   // Setting up the problem parameters
46   unsigned k = 4;                // number of unrollings (should be a power of 2)
47   unsigned index_size = log2(k); // size of the index
48 
49 
50   // Sorts
51   Sort elementSort = slv.mkBitVectorSort(32);
52   Sort indexSort = slv.mkBitVectorSort(index_size);
53   Sort arraySort = slv.mkArraySort(indexSort, elementSort);
54 
55   // Variables
56   Term current_array = slv.mkConst(arraySort, "current_array");
57 
58   // Making a bit-vector constant
59   Term zero = slv.mkBitVector(index_size, 0u);
60 
61   // Asserting that current_array[0] > 0
62   Term current_array0 = slv.mkTerm(SELECT, {current_array, zero});
63   Term current_array0_gt_0 =
64       slv.mkTerm(BITVECTOR_SGT, {current_array0, slv.mkBitVector(32, 0u)});
65   slv.assertFormula(current_array0_gt_0);
66 
67   // Building the assertions in the loop unrolling
68   Term index = slv.mkBitVector(index_size, 0u);
69   Term old_current = slv.mkTerm(SELECT, {current_array, index});
70   Term two = slv.mkBitVector(32, 2u);
71 
72   std::vector<Term> assertions;
73   for (unsigned i = 1; i < k; ++i) {
74     index = slv.mkBitVector(index_size, i);
75     Term new_current = slv.mkTerm(BITVECTOR_MULT, {two, old_current});
76     // current[i] = 2 * current[i-1]
77     current_array = slv.mkTerm(STORE, {current_array, index, new_current});
78     // current[i-1] < current [i]
79     Term current_slt_new_current =
80         slv.mkTerm(BITVECTOR_SLT, {old_current, new_current});
81     assertions.push_back(current_slt_new_current);
82 
83     old_current = slv.mkTerm(SELECT, {current_array, index});
84   }
85 
86   Term query = slv.mkTerm(NOT, {slv.mkTerm(AND, assertions)});
87 
88   cout << "Asserting " << query << " to cvc5 " << endl;
89   slv.assertFormula(query);
90   cout << "Expect sat. " << endl;
91   cout << "cvc5: " << slv.checkSatAssuming(slv.mkTrue()) << endl;
92 
93   // Getting the model
94   cout << "The satisfying model is: " << endl;
95   cout << "  current_array = " << slv.getValue(current_array) << endl;
96   cout << "  current_array[0] = " << slv.getValue(current_array0) << endl;
97   return 0;
98 }
            examples/api/java/BitVectorsAndArrays.java
  1 /******************************************************************************
  2  * Top contributors (to current version):
  3  *   Mudathir Mohamed, Morgan Deters, Liana Hadarean
  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 BitVectorsAndArrays
 22 {
 23   private static int log2(int n)
 24   {
 25     return (int) Math.round(Math.log(n) / Math.log(2));
 26   }
 27 
 28   public static void main(String[] args) throws CVC5ApiException
 29   {
 30     try (Solver slv = new Solver())
 31     {
 32       slv.setOption("produce-models", "true"); // Produce Models
 33       slv.setOption("output-language", "smtlib"); // output-language
 34       slv.setLogic("QF_AUFBV"); // Set the logic
 35 
 36       // Consider the following code (where size is some previously defined constant):
 37       //
 38       //
 39       //   Assert (current_array[0] > 0);
 40       //   for (unsigned i = 1; i < k; ++i) {
 41       //     current_array[i] = 2 * current_array[i - 1];
 42       //     Assert (current_array[i-1] < current_array[i]);
 43       //     }
 44       //
 45       // We want to check whether the assertion in the body of the for loop holds
 46       // throughout the loop.
 47 
 48       // Setting up the problem parameters
 49       int k = 4; // number of unrollings (should be a power of 2)
 50       int index_size = log2(k); // size of the index
 51 
 52       // Sorts
 53       Sort elementSort = slv.mkBitVectorSort(32);
 54       Sort indexSort = slv.mkBitVectorSort(index_size);
 55       Sort arraySort = slv.mkArraySort(indexSort, elementSort);
 56 
 57       // Variables
 58       Term current_array = slv.mkConst(arraySort, "current_array");
 59 
 60       // Making a bit-vector constant
 61       Term zero = slv.mkBitVector(index_size, 0);
 62 
 63       // Asserting that current_array[0] > 0
 64       Term current_array0 = slv.mkTerm(Kind.SELECT, current_array, zero);
 65       Term current_array0_gt_0 =
 66           slv.mkTerm(Kind.BITVECTOR_SGT, current_array0, slv.mkBitVector(32, 0));
 67       slv.assertFormula(current_array0_gt_0);
 68 
 69       // Building the assertions in the loop unrolling
 70       Term index = slv.mkBitVector(index_size, 0);
 71       Term old_current = slv.mkTerm(Kind.SELECT, current_array, index);
 72       Term two = slv.mkBitVector(32, 2);
 73 
 74       List<Term> assertions = new ArrayList<Term>();
 75       for (int i = 1; i < k; ++i)
 76       {
 77         index = slv.mkBitVector(index_size, i);
 78         Term new_current = slv.mkTerm(Kind.BITVECTOR_MULT, two, old_current);
 79         // current[i] = 2 * current[i-1]
 80         current_array = slv.mkTerm(Kind.STORE, current_array, index, new_current);
 81         // current[i-1] < current [i]
 82         Term current_slt_new_current = slv.mkTerm(Kind.BITVECTOR_SLT, old_current, new_current);
 83         assertions.add(current_slt_new_current);
 84 
 85         old_current = slv.mkTerm(Kind.SELECT, current_array, index);
 86       }
 87 
 88       Term query = slv.mkTerm(Kind.NOT, slv.mkTerm(Kind.AND, assertions.toArray(new Term[0])));
 89 
 90       System.out.println("Asserting " + query + " to cvc5 ");
 91       slv.assertFormula(query);
 92       System.out.println("Expect sat. ");
 93       System.out.println("cvc5: " + slv.checkSatAssuming(slv.mkTrue()));
 94 
 95       // Getting the model
 96       System.out.println("The satisfying model is: ");
 97       System.out.println("  current_array = " + slv.getValue(current_array));
 98       System.out.println("  current_array[0] = " + slv.getValue(current_array0));
 99     }
100   }
101 }
            examples/api/python/pythonic/bitvectors_and_arrays.py
 1 from cvc5.pythonic import *
 2 
 3 if __name__ == '__main__':
 4     # Consider the following (where k is some previously defined constant):
 5     #
 6     #
 7     #   Assert (current_array[0] > 0);
 8     #   for (unsigned i = 1; i < k; ++i) {
 9     #     current_array[i] = 2 * current_array[i - 1];
10     #     Assert (current_array[i-1] < current_array[i]);
11     #   }
12     #
13     # We want to check whether the assertion in the body of the for loop holds
14     # throughout the loop.
15     k = 4
16     idx_bits = int(math.ceil(math.log(k, 2)))
17 
18     init_array = Array('init_arr', BitVecSort(idx_bits), BitVecSort(32))
19     array = init_array
20     assertions = []
21     for i in range(1, k):
22         array = Store(array, i, 2 * Select(array, i - 1))
23         assertions.append(Select(array, i - 1) < Select(array, i))
24     # Does *not* hold.
25     # If the first element is large enough, the multiplication overflows.
26     prove(Implies(Select(init_array, 0) > 0, And(*assertions)))
            examples/api/python/bitvectors_and_arrays.py
 1 #!/usr/bin/env python
 2 ###############################################################################
 3 # Top contributors (to current version):
 4 #   Makai Mann, Aina Niemetz, Alex Ozdemir
 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
15 # bit-vector and array solvers through the Python API. This is a direct
16 # translation of bitvectors_and_arrays-new.cpp.
17 ##
18 
19 import cvc5
20 from cvc5 import Kind
21 
22 import math
23 
24 if __name__ == "__main__":
25     slv = cvc5.Solver()
26     slv.setOption("produce-models", "true")
27     slv.setOption("output-language", "smtlib")
28     slv.setLogic("QF_AUFBV")
29 
30     # Consider the following code (where size is some previously defined constant):
31     #
32     #
33     #   Assert (current_array[0] > 0);
34     #   for (unsigned i = 1; i < k; ++i) {
35     #     current_array[i] = 2 * current_array[i - 1];
36     #     Assert (current_array[i-1] < current_array[i]);
37     #     }
38     #
39     # We want to check whether the assertion in the body of the for loop holds
40     # throughout the loop.
41 
42     # Setting up the problem parameters
43     k = 4
44     index_size = int(math.ceil(math.log(k, 2)))
45 
46     # Sorts
47     elementSort = slv.mkBitVectorSort(32)
48     indexSort = slv.mkBitVectorSort(index_size)
49     arraySort = slv.mkArraySort(indexSort, elementSort)
50 
51     # Variables
52     current_array = slv.mkConst(arraySort, "current_array")
53 
54     # Making a bit-vector constant
55     zero = slv.mkBitVector(index_size, 0)
56 
57     # Test making a constant array
58     constarr0 = slv.mkConstArray(arraySort, slv.mkBitVector(32, 0))
59 
60     # Asserting that current_array[0] > 0
61     current_array0 = slv.mkTerm(Kind.SELECT, current_array, zero)
62     current_array0_gt_0 = slv.mkTerm(Kind.BITVECTOR_SGT,
63                                      current_array0,
64                                      slv.mkBitVector(32, 0))
65     slv.assertFormula(current_array0_gt_0)
66 
67     # Building the assertions in the loop unrolling
68     index = slv.mkBitVector(index_size, 0)
69     old_current = slv.mkTerm(Kind.SELECT, current_array, index)
70     two = slv.mkBitVector(32, 2)
71 
72     assertions = []
73     for i in range(1, k):
74         index = slv.mkBitVector(index_size, i)
75         new_current = slv.mkTerm(Kind.BITVECTOR_MULT, two, old_current)
76         # current[i] = 2*current[i-1]
77         current_array = \
78                 slv.mkTerm(Kind.STORE, current_array, index, new_current)
79         # current[i-1] < current[i]
80         current_slt_new_current = \
81                 slv.mkTerm(Kind.BITVECTOR_SLT, old_current, new_current)
82         assertions.append(current_slt_new_current)
83         old_current = slv.mkTerm(Kind.SELECT, current_array, index)
84 
85     query = slv.mkTerm(Kind.NOT, slv.mkTerm(Kind.AND, *assertions))
86 
87     print("Asserting {} to cvc5".format(query))
88     slv.assertFormula(query)
89     print("Expect sat.")
90     print("cvc5:", slv.checkSatAssuming(slv.mkTrue()))
91 
92     # Getting the model
93     print("The satisfying model is: ")
94     print(" current_array =", slv.getValue(current_array))
95     print(" current_array[0]", slv.getValue(current_array0))
            examples/api/smtlib/bitvectors_and_arrays.smt2
 1 (set-logic QF_AUFBV)
 2 (set-option :produce-models true)
 3 
 4 ; Consider the following code (where size is some previously defined constant):
 5 
 6 
 7 ;   Assert (current_array[0] > 0);
 8 ;   for (unsigned i = 1; i < k; ++i) {
 9 ;     current_array[i] = 2 * current_array[i - 1];
10 ;     Assert (current_array[i-1] < current_array[i]);
11 ;     }
12 
13 ; We want to check whether the assertion in the body of the for loop holds
14 ; throughout the loop. We will do so for k = 4.
15 
16 
17 (define-sort Index () (_ BitVec 2))
18 (define-sort Element () (_ BitVec 32))
19 (define-sort ArraySort () (Array Index Element))
20 
21 ; Declaring the array
22 (declare-const current_array ArraySort)
23 
24 ; Making utility bit-vector constants
25 (define-const zeroI Index (_ bv0 2))
26 (define-const oneI Index (_ bv1 2))
27 (define-const twoI Index (_ bv2 2))
28 (define-const threeI Index (_ bv3 2))
29 
30 (define-const zeroE Element (_ bv0 32))
31 (define-const twoE Element (_ bv2 32))
32 
33 ; Asserting that current_array[0] > 0
34 (assert (bvsgt (select current_array zeroI) zeroE))
35 
36 ; Building the formulas representing loop unrolling
37 
38 ; current_array[0] < array [1]
39 (define-const unroll1 Bool (bvslt (select current_array zeroI) (bvmul twoE (select current_array zeroI))))
40 ; current_array[1] = 2 * current_array[0]
41 (define-const current_array_ ArraySort (store current_array oneI (bvmul twoE (select current_array zeroI))))
42 
43 ; current_array[1] < array [2]
44 (define-const unroll2 Bool (bvslt (select current_array_ oneI) (bvmul twoE (select current_array_ oneI))))
45 ; current_array[2] = 2 * current_array[1]
46 (define-const current_array__ ArraySort (store current_array_ twoI (bvmul twoE (select current_array_ oneI))))
47 
48 ; current_array[2] < array [3]
49 (define-const unroll3 Bool (bvslt (select current_array_ twoI) (bvmul twoE (select current_array_ twoI))))
50 ; current_array[3] = 2 * current_array[2]
51 (define-const current_array___ ArraySort (store current_array_ threeI (bvmul twoE (select current_array_ twoI))))
52 
53 (assert (not (and unroll1 unroll2 unroll3)))
54 
55 (check-sat)
56 (get-value (current_array___ (select current_array___ zeroI)))