Skip to content

Commit 27301a4

Browse files
committed
Add SMT bit vector repeat operation
1 parent bb4f9b7 commit 27301a4

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-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
@@ -700,3 +700,34 @@ void smt_bit_vector_theoryt::arithmetic_shift_rightt::validate(
700700
const smt_function_application_termt::factoryt<
701701
smt_bit_vector_theoryt::arithmetic_shift_rightt>
702702
smt_bit_vector_theoryt::arithmetic_shift_right{};
703+
704+
const char *smt_bit_vector_theoryt::repeatt::identifier()
705+
{
706+
return "repeat";
707+
}
708+
709+
smt_sortt
710+
smt_bit_vector_theoryt::repeatt::return_sort(const smt_termt &operand) const
711+
{
712+
const std::size_t operand_width =
713+
operand.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
714+
return smt_bit_vector_sortt{i * operand_width};
715+
}
716+
717+
std::vector<smt_indext> smt_bit_vector_theoryt::repeatt::indices() const
718+
{
719+
return {smt_numeral_indext{i}};
720+
}
721+
722+
void smt_bit_vector_theoryt::repeatt::validate(const smt_termt &operand) const
723+
{
724+
PRECONDITION(i >= 1);
725+
PRECONDITION(operand.get_sort().cast<smt_bit_vector_sortt>());
726+
}
727+
728+
smt_function_application_termt::factoryt<smt_bit_vector_theoryt::repeatt>
729+
smt_bit_vector_theoryt::repeat(std::size_t i)
730+
{
731+
PRECONDITION(i >= 1);
732+
return smt_function_application_termt::factoryt<repeatt>(i);
733+
}

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ class smt_bit_vector_theoryt
264264
};
265265
static const smt_function_application_termt::factoryt<arithmetic_shift_rightt>
266266
arithmetic_shift_right;
267+
268+
struct repeatt final
269+
{
270+
std::size_t i;
271+
static const char *identifier();
272+
smt_sortt return_sort(const smt_termt &operand) const;
273+
std::vector<smt_indext> indices() const;
274+
void validate(const smt_termt &operand) const;
275+
};
276+
static smt_function_application_termt::factoryt<repeatt>
277+
repeat(std::size_t i);
267278
};
268279

269280
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,21 @@ TEST_CASE("SMT bit vector shifts", "[core][smt2_incremental]")
577577
smt_bit_vector_theoryt::arithmetic_shift_right(true_val, three));
578578
}
579579
}
580+
581+
TEST_CASE("SMT bit vector repeat", "[core][smt2_incremental]")
582+
{
583+
const smt_bit_vector_constant_termt two{2, 8};
584+
const auto expected_return_sort = smt_bit_vector_sortt{32};
585+
const smt_bool_literal_termt true_val{true};
586+
const auto function_application = smt_bit_vector_theoryt::repeat(4)(two);
587+
REQUIRE(
588+
function_application.function_identifier() ==
589+
smt_identifier_termt(
590+
"repeat", expected_return_sort, {smt_numeral_indext{4}}));
591+
REQUIRE(function_application.get_sort() == expected_return_sort);
592+
REQUIRE(function_application.arguments().size() == 1);
593+
REQUIRE(function_application.arguments()[0].get() == two);
594+
cbmc_invariants_should_throwt invariants_throw;
595+
REQUIRE_THROWS(smt_bit_vector_theoryt::repeat(0));
596+
REQUIRE_THROWS(smt_bit_vector_theoryt::repeat(1)(true_val));
597+
}

0 commit comments

Comments
 (0)