Skip to content

Commit b4862bd

Browse files
committed
Add SMT bit vector theory extract function
1 parent 79618ce commit b4862bd

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@
44

55
#include <util/invariant.h>
66

7+
const char *smt_bit_vector_theoryt::extractt::identifier()
8+
{
9+
return "extract";
10+
}
11+
12+
smt_sortt
13+
smt_bit_vector_theoryt::extractt::return_sort(const smt_termt &operand) const
14+
{
15+
return smt_bit_vector_sortt{i - j + 1};
16+
}
17+
18+
std::vector<smt_indext> smt_bit_vector_theoryt::extractt::indices() const
19+
{
20+
return {smt_numeral_indext{i}, smt_numeral_indext{j}};
21+
}
22+
23+
void smt_bit_vector_theoryt::extractt::validate(const smt_termt &operand) const
24+
{
25+
PRECONDITION(i >= j);
26+
const auto bit_vector_sort = operand.get_sort().cast<smt_bit_vector_sortt>();
27+
PRECONDITION(bit_vector_sort);
28+
PRECONDITION(i < bit_vector_sort->bit_width());
29+
}
30+
31+
smt_function_application_termt::factoryt<smt_bit_vector_theoryt::extractt>
32+
smt_bit_vector_theoryt::extract(std::size_t i, std::size_t j)
33+
{
34+
PRECONDITION(i >= j);
35+
return smt_function_application_termt::factoryt<extractt>(i, j);
36+
}
37+
738
static void validate_bit_vector_operator_arguments(
839
const smt_termt &left,
940
const smt_termt &right)

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88
class smt_bit_vector_theoryt
99
{
1010
public:
11+
struct extractt final
12+
{
13+
std::size_t i;
14+
std::size_t j;
15+
static const char *identifier();
16+
smt_sortt return_sort(const smt_termt &operand) const;
17+
std::vector<smt_indext> indices() const;
18+
void validate(const smt_termt &operand) const;
19+
};
20+
static smt_function_application_termt::factoryt<extractt>
21+
extract(std::size_t i, std::size_t j);
22+
1123
// Relational operator class declarations
1224
struct unsigned_less_thant final
1325
{

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@
77

88
#include <util/mp_arith.h>
99

10+
TEST_CASE("SMT bit vector extract", "[core][smt2_incremental]")
11+
{
12+
const smt_bit_vector_constant_termt operand{42, 8};
13+
const auto extract_4_3 = smt_bit_vector_theoryt::extract(4, 3);
14+
SECTION("Valid construction")
15+
{
16+
const auto extraction = extract_4_3(operand);
17+
const auto expected_return_sort = smt_bit_vector_sortt{2};
18+
REQUIRE(
19+
extraction.function_identifier() ==
20+
smt_identifier_termt(
21+
"extract",
22+
expected_return_sort,
23+
{smt_numeral_indext{4}, smt_numeral_indext{3}}));
24+
REQUIRE(extraction.get_sort() == expected_return_sort);
25+
REQUIRE(extraction.arguments().size() == 1);
26+
REQUIRE(extraction.arguments()[0].get() == operand);
27+
}
28+
SECTION("Invalid constructions")
29+
{
30+
cbmc_invariants_should_throwt invariants_throw;
31+
REQUIRE_THROWS(smt_bit_vector_theoryt::extract(3, 4));
32+
REQUIRE_THROWS(extract_4_3(smt_bool_literal_termt{true}));
33+
REQUIRE_THROWS(extract_4_3(smt_bit_vector_constant_termt{8, 4}));
34+
}
35+
}
36+
1037
TEST_CASE("SMT bit vector predicates", "[core][smt2_incremental]")
1138
{
1239
const smt_bit_vector_constant_termt two{2, 8};

0 commit comments

Comments
 (0)