Skip to content

Commit a5e1208

Browse files
committed
Add bitvector theory bitwise operators
1 parent 1926470 commit a5e1208

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,71 @@ static void validate_bit_vector_operator_arguments(
7878
"Left and right operands must have the same bit width.");
7979
}
8080

81+
// Bitwise operator definitions
82+
83+
const char *smt_bit_vector_theoryt::nott::identifier()
84+
{
85+
return "bvnot";
86+
}
87+
88+
smt_sortt smt_bit_vector_theoryt::nott::return_sort(const smt_termt &operand)
89+
{
90+
return operand.get_sort();
91+
}
92+
93+
void smt_bit_vector_theoryt::nott::validate(const smt_termt &operand)
94+
{
95+
const auto operand_sort = operand.get_sort().cast<smt_bit_vector_sortt>();
96+
INVARIANT(operand_sort, "The operand is expected to have a bit-vector sort.");
97+
}
98+
99+
const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::nott>
100+
smt_bit_vector_theoryt::make_not{};
101+
102+
const char *smt_bit_vector_theoryt::andt::identifier()
103+
{
104+
return "bvand";
105+
}
106+
107+
smt_sortt smt_bit_vector_theoryt::andt::return_sort(
108+
const smt_termt &lhs,
109+
const smt_termt &rhs)
110+
{
111+
return lhs.get_sort();
112+
}
113+
114+
void smt_bit_vector_theoryt::andt::validate(
115+
const smt_termt &lhs,
116+
const smt_termt &rhs)
117+
{
118+
validate_bit_vector_operator_arguments(lhs, rhs);
119+
}
120+
121+
const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::andt>
122+
smt_bit_vector_theoryt::make_and{};
123+
124+
const char *smt_bit_vector_theoryt::ort::identifier()
125+
{
126+
return "bvor";
127+
}
128+
129+
smt_sortt smt_bit_vector_theoryt::ort::return_sort(
130+
const smt_termt &lhs,
131+
const smt_termt &rhs)
132+
{
133+
return lhs.get_sort();
134+
}
135+
136+
void smt_bit_vector_theoryt::ort::validate(
137+
const smt_termt &lhs,
138+
const smt_termt &rhs)
139+
{
140+
validate_bit_vector_operator_arguments(lhs, rhs);
141+
}
142+
143+
const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::ort>
144+
smt_bit_vector_theoryt::make_or{};
145+
81146
// Relational operator definitions
82147

83148
const char *smt_bit_vector_theoryt::unsigned_less_thant::identifier()

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ class smt_bit_vector_theoryt
2828
static smt_function_application_termt::factoryt<extractt>
2929
extract(std::size_t i, std::size_t j);
3030

31+
// Bitwise operators
32+
struct nott final
33+
{
34+
static const char *identifier();
35+
static smt_sortt return_sort(const smt_termt &operand);
36+
static void validate(const smt_termt &operand);
37+
};
38+
static const smt_function_application_termt::factoryt<nott> make_not;
39+
40+
struct andt final
41+
{
42+
static const char *identifier();
43+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
44+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
45+
};
46+
static const smt_function_application_termt::factoryt<andt> make_and;
47+
48+
struct ort final
49+
{
50+
static const char *identifier();
51+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
52+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
53+
};
54+
static const smt_function_application_termt::factoryt<ort> make_or;
55+
3156
// Relational operator class declarations
3257
struct unsigned_less_thant final
3358
{

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,59 @@ TEST_CASE("SMT bit vector extract", "[core][smt2_incremental]")
6060
}
6161
}
6262

63+
TEST_CASE("SMT bit vector bitwise operators", "[core][smt2_incremental]")
64+
{
65+
const smt_bit_vector_constant_termt two{2, 8};
66+
const smt_bit_vector_constant_termt three{3, 8};
67+
const smt_bit_vector_constant_termt wider{4, 16};
68+
const smt_bool_literal_termt true_val{true};
69+
SECTION("not")
70+
{
71+
const auto function_application = smt_bit_vector_theoryt::make_not(two);
72+
REQUIRE(
73+
function_application.function_identifier() ==
74+
smt_identifier_termt("bvnot", smt_bit_vector_sortt{8}));
75+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
76+
REQUIRE(function_application.arguments().size() == 1);
77+
REQUIRE(function_application.arguments()[0].get() == two);
78+
79+
cbmc_invariants_should_throwt invariants_throw;
80+
REQUIRE_THROWS(smt_bit_vector_theoryt::make_not(true_val));
81+
}
82+
SECTION("or")
83+
{
84+
const auto function_application =
85+
smt_bit_vector_theoryt::make_or(two, three);
86+
REQUIRE(
87+
function_application.function_identifier() ==
88+
smt_identifier_termt("bvor", smt_bit_vector_sortt{8}));
89+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
90+
REQUIRE(function_application.arguments().size() == 2);
91+
REQUIRE(function_application.arguments()[0].get() == two);
92+
REQUIRE(function_application.arguments()[1].get() == three);
93+
94+
cbmc_invariants_should_throwt invariants_throw;
95+
REQUIRE_THROWS(smt_bit_vector_theoryt::make_or(three, wider));
96+
REQUIRE_THROWS(smt_bit_vector_theoryt::make_or(true_val, three));
97+
}
98+
SECTION("and")
99+
{
100+
const auto function_application =
101+
smt_bit_vector_theoryt::make_and(two, three);
102+
REQUIRE(
103+
function_application.function_identifier() ==
104+
smt_identifier_termt("bvand", smt_bit_vector_sortt{8}));
105+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
106+
REQUIRE(function_application.arguments().size() == 2);
107+
REQUIRE(function_application.arguments()[0].get() == two);
108+
REQUIRE(function_application.arguments()[1].get() == three);
109+
110+
cbmc_invariants_should_throwt invariants_throw;
111+
REQUIRE_THROWS(smt_bit_vector_theoryt::make_and(three, wider));
112+
REQUIRE_THROWS(smt_bit_vector_theoryt::make_and(true_val, three));
113+
}
114+
}
115+
63116
TEST_CASE("SMT bit vector predicates", "[core][smt2_incremental]")
64117
{
65118
const smt_bit_vector_constant_termt two{2, 8};

0 commit comments

Comments
 (0)