Theory of Bit-Vectors and Arrays

examples/api/cpp/bitvectors_and_arrays.cpp

 1/******************************************************************************
 2 * Top contributors (to current version):
 3 *   Aina Niemetz, Liana Hadarean, Mathias Preiner
 4 *
 5 * This file is part of the cvc5 project.
 6 *
 7 * Copyright (c) 2009-2024 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 <iostream>
21
22using namespace std;
23using namespace cvc5;
24
25int main()
26{
27  TermManager tm;
28  Solver slv(tm);
29  slv.setOption("produce-models", "true");    // Produce Models
30  slv.setLogic("QF_ABV");                     // Set the logic
31
32  // Consider the following code (where size is some previously defined constant):
33  //
34  //
35  //   Assert (current_array[0] > 0);
36  //   for (unsigned i = 1; i < k; ++i) {
37  //     current_array[i] = 2 * current_array[i - 1];
38  //     Assert (current_array[i-1] < current_array[i]);
39  //     }
40  //
41  // We want to check whether the assertion in the body of the for loop holds
42  // throughout the loop.
43
44  // Setting up the problem parameters
45  uint32_t k = 4;           // number of unrollings (should be a power of 2)
46  uint32_t index_size = 2;  // size of the index, must be log2(k)
47
48  // Sorts
49  Sort elementSort = tm.mkBitVectorSort(32);
50  Sort indexSort = tm.mkBitVectorSort(index_size);
51  Sort arraySort = tm.mkArraySort(indexSort, elementSort);
52
53  // Variables
54  Term current_array = tm.mkConst(arraySort, "current_array");
55
56  // Making a bit-vector constant
57  Term zero = tm.mkBitVector(index_size, 0u);
58
59  // Asserting that current_array[0] > 0
60  Term current_array0 = tm.mkTerm(Kind::SELECT, {current_array, zero});
61  Term current_array0_gt_0 = tm.mkTerm(
62      Kind::BITVECTOR_SGT, {current_array0, tm.mkBitVector(32, 0u)});
63  slv.assertFormula(current_array0_gt_0);
64
65  // Building the assertions in the loop unrolling
66  Term index = tm.mkBitVector(index_size, 0u);
67  Term old_current = tm.mkTerm(Kind::SELECT, {current_array, index});
68  Term two = tm.mkBitVector(32, 2u);
69
70  std::vector<Term> assertions;
71  for (uint32_t i = 1; i < k; ++i)
72  {
73    index = tm.mkBitVector(index_size, i);
74    Term new_current = tm.mkTerm(Kind::BITVECTOR_MULT, {two, old_current});
75    // current[i] = 2 * current[i-1]
76    current_array =
77        tm.mkTerm(Kind::STORE, {current_array, index, new_current});
78    // current[i-1] < current [i]
79    Term current_slt_new_current =
80        tm.mkTerm(Kind::BITVECTOR_SLT, {old_current, new_current});
81    assertions.push_back(current_slt_new_current);
82
83    old_current = tm.mkTerm(Kind::SELECT, {current_array, index});
84  }
85
86  Term query = tm.mkTerm(Kind::NOT, {tm.mkTerm(Kind::AND, assertions)});
87
88  cout << "Asserting " << query << " to cvc5" << endl;
89  slv.assertFormula(query);
90  cout << "Expect sat." << endl;
91  cout << "cvc5: " << slv.checkSat() << 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}