Skip to content

Commit 4db734d

Browse files
committed
Add bit vector theory shift operations
1 parent a5e1208 commit 4db734d

File tree

3 files changed

+155
-0
lines changed

3 files changed

+155
-0
lines changed

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,72 @@ void smt_bit_vector_theoryt::negatet::validate(const smt_termt &operand)
508508

509509
const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::negatet>
510510
smt_bit_vector_theoryt::negate{};
511+
512+
const char *smt_bit_vector_theoryt::shift_leftt::identifier()
513+
{
514+
return "bvshl";
515+
}
516+
517+
smt_sortt smt_bit_vector_theoryt::shift_leftt::return_sort(
518+
const smt_termt &lhs,
519+
const smt_termt &rhs)
520+
{
521+
return lhs.get_sort();
522+
}
523+
524+
void smt_bit_vector_theoryt::shift_leftt::validate(
525+
const smt_termt &lhs,
526+
const smt_termt &rhs)
527+
{
528+
validate_bit_vector_operator_arguments(lhs, rhs);
529+
}
530+
531+
const smt_function_application_termt::factoryt<
532+
smt_bit_vector_theoryt::shift_leftt>
533+
smt_bit_vector_theoryt::shift_left{};
534+
535+
const char *smt_bit_vector_theoryt::logical_shift_rightt::identifier()
536+
{
537+
return "bvlshr";
538+
}
539+
540+
smt_sortt smt_bit_vector_theoryt::logical_shift_rightt::return_sort(
541+
const smt_termt &lhs,
542+
const smt_termt &rhs)
543+
{
544+
return lhs.get_sort();
545+
}
546+
547+
void smt_bit_vector_theoryt::logical_shift_rightt::validate(
548+
const smt_termt &lhs,
549+
const smt_termt &rhs)
550+
{
551+
validate_bit_vector_operator_arguments(lhs, rhs);
552+
}
553+
554+
const smt_function_application_termt::factoryt<
555+
smt_bit_vector_theoryt::logical_shift_rightt>
556+
smt_bit_vector_theoryt::logical_shift_right{};
557+
558+
const char *smt_bit_vector_theoryt::arithmetic_shift_rightt::identifier()
559+
{
560+
return "bvashr";
561+
}
562+
563+
smt_sortt smt_bit_vector_theoryt::arithmetic_shift_rightt::return_sort(
564+
const smt_termt &lhs,
565+
const smt_termt &rhs)
566+
{
567+
return lhs.get_sort();
568+
}
569+
570+
void smt_bit_vector_theoryt::arithmetic_shift_rightt::validate(
571+
const smt_termt &lhs,
572+
const smt_termt &rhs)
573+
{
574+
validate_bit_vector_operator_arguments(lhs, rhs);
575+
}
576+
577+
const smt_function_application_termt::factoryt<
578+
smt_bit_vector_theoryt::arithmetic_shift_rightt>
579+
smt_bit_vector_theoryt::arithmetic_shift_right{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,33 @@ class smt_bit_vector_theoryt
197197
static void validate(const smt_termt &operand);
198198
};
199199
static const smt_function_application_termt::factoryt<negatet> negate;
200+
201+
// Shift operations
202+
struct shift_leftt final
203+
{
204+
static const char *identifier();
205+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
206+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
207+
};
208+
static const smt_function_application_termt::factoryt<shift_leftt> shift_left;
209+
210+
struct logical_shift_rightt final
211+
{
212+
static const char *identifier();
213+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
214+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
215+
};
216+
static const smt_function_application_termt::factoryt<logical_shift_rightt>
217+
logical_shift_right;
218+
219+
struct arithmetic_shift_rightt final
220+
{
221+
static const char *identifier();
222+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
223+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
224+
};
225+
static const smt_function_application_termt::factoryt<arithmetic_shift_rightt>
226+
arithmetic_shift_right;
200227
};
201228

202229
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,62 @@ TEST_CASE(
431431
REQUIRE_THROWS(smt_bit_vector_theoryt::negate(true_val));
432432
}
433433
}
434+
435+
TEST_CASE("SMT bit vector shifts", "[core][smt2_incremental]")
436+
{
437+
const smt_bit_vector_constant_termt two{2, 8};
438+
const smt_bit_vector_constant_termt three{3, 8};
439+
const smt_bit_vector_constant_termt wider{4, 16};
440+
const smt_bool_literal_termt true_val{true};
441+
SECTION("shift left")
442+
{
443+
const auto function_application =
444+
smt_bit_vector_theoryt::shift_left(two, three);
445+
REQUIRE(
446+
function_application.function_identifier() ==
447+
smt_identifier_termt("bvshl", smt_bit_vector_sortt{8}));
448+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
449+
REQUIRE(function_application.arguments().size() == 2);
450+
REQUIRE(function_application.arguments()[0].get() == two);
451+
REQUIRE(function_application.arguments()[1].get() == three);
452+
453+
cbmc_invariants_should_throwt invariants_throw;
454+
REQUIRE_THROWS(smt_bit_vector_theoryt::shift_left(three, wider));
455+
REQUIRE_THROWS(smt_bit_vector_theoryt::shift_left(true_val, three));
456+
}
457+
SECTION("logical shift right")
458+
{
459+
const auto function_application =
460+
smt_bit_vector_theoryt::logical_shift_right(two, three);
461+
REQUIRE(
462+
function_application.function_identifier() ==
463+
smt_identifier_termt("bvlshr", smt_bit_vector_sortt{8}));
464+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
465+
REQUIRE(function_application.arguments().size() == 2);
466+
REQUIRE(function_application.arguments()[0].get() == two);
467+
REQUIRE(function_application.arguments()[1].get() == three);
468+
469+
cbmc_invariants_should_throwt invariants_throw;
470+
REQUIRE_THROWS(smt_bit_vector_theoryt::logical_shift_right(three, wider));
471+
REQUIRE_THROWS(
472+
smt_bit_vector_theoryt::logical_shift_right(true_val, three));
473+
}
474+
SECTION("arithmetic shift right")
475+
{
476+
const auto function_application =
477+
smt_bit_vector_theoryt::arithmetic_shift_right(two, three);
478+
REQUIRE(
479+
function_application.function_identifier() ==
480+
smt_identifier_termt("bvashr", smt_bit_vector_sortt{8}));
481+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
482+
REQUIRE(function_application.arguments().size() == 2);
483+
REQUIRE(function_application.arguments()[0].get() == two);
484+
REQUIRE(function_application.arguments()[1].get() == three);
485+
486+
cbmc_invariants_should_throwt invariants_throw;
487+
REQUIRE_THROWS(
488+
smt_bit_vector_theoryt::arithmetic_shift_right(three, wider));
489+
REQUIRE_THROWS(
490+
smt_bit_vector_theoryt::arithmetic_shift_right(true_val, three));
491+
}
492+
}

0 commit comments

Comments
 (0)