Skip to content

Commit e59a77c

Browse files
committed
Add SMT bit vector rotate operations
1 parent 05e2b09 commit e59a77c

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,3 +789,57 @@ smt_bit_vector_theoryt::sign_extend(std::size_t i)
789789
{
790790
return smt_function_application_termt::factoryt<sign_extendt>(i);
791791
}
792+
793+
const char *smt_bit_vector_theoryt::rotate_leftt::identifier()
794+
{
795+
return "rotate_left";
796+
}
797+
798+
smt_sortt
799+
smt_bit_vector_theoryt::rotate_leftt::return_sort(const smt_termt &operand)
800+
{
801+
return operand.get_sort();
802+
}
803+
804+
std::vector<smt_indext> smt_bit_vector_theoryt::rotate_leftt::indices() const
805+
{
806+
return {smt_numeral_indext{i}};
807+
}
808+
809+
void smt_bit_vector_theoryt::rotate_leftt::validate(const smt_termt &operand)
810+
{
811+
PRECONDITION(operand.get_sort().cast<smt_bit_vector_sortt>());
812+
}
813+
814+
smt_function_application_termt::factoryt<smt_bit_vector_theoryt::rotate_leftt>
815+
smt_bit_vector_theoryt::rotate_left(std::size_t i)
816+
{
817+
return smt_function_application_termt::factoryt<rotate_leftt>(i);
818+
}
819+
820+
const char *smt_bit_vector_theoryt::rotate_rightt::identifier()
821+
{
822+
return "rotate_right";
823+
}
824+
825+
smt_sortt
826+
smt_bit_vector_theoryt::rotate_rightt::return_sort(const smt_termt &operand)
827+
{
828+
return operand.get_sort();
829+
}
830+
831+
std::vector<smt_indext> smt_bit_vector_theoryt::rotate_rightt::indices() const
832+
{
833+
return {smt_numeral_indext{i}};
834+
}
835+
836+
void smt_bit_vector_theoryt::rotate_rightt::validate(const smt_termt &operand)
837+
{
838+
PRECONDITION(operand.get_sort().cast<smt_bit_vector_sortt>());
839+
}
840+
841+
smt_function_application_termt::factoryt<smt_bit_vector_theoryt::rotate_rightt>
842+
smt_bit_vector_theoryt::rotate_right(std::size_t i)
843+
{
844+
return smt_function_application_termt::factoryt<rotate_rightt>(i);
845+
}

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,28 @@ class smt_bit_vector_theoryt
297297
};
298298
static smt_function_application_termt::factoryt<sign_extendt>
299299
sign_extend(std::size_t i);
300+
301+
struct rotate_leftt final
302+
{
303+
std::size_t i;
304+
static const char *identifier();
305+
static smt_sortt return_sort(const smt_termt &operand);
306+
std::vector<smt_indext> indices() const;
307+
static void validate(const smt_termt &operand);
308+
};
309+
static smt_function_application_termt::factoryt<rotate_leftt>
310+
rotate_left(std::size_t i);
311+
312+
struct rotate_rightt final
313+
{
314+
std::size_t i;
315+
static const char *identifier();
316+
static smt_sortt return_sort(const smt_termt &operand);
317+
std::vector<smt_indext> indices() const;
318+
static void validate(const smt_termt &operand);
319+
};
320+
static smt_function_application_termt::factoryt<rotate_rightt>
321+
rotate_right(std::size_t i);
300322
};
301323

302324
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,40 @@ TEST_CASE("SMT bit vector extend", "[core][smt2_incremental]")
633633
REQUIRE_THROWS(smt_bit_vector_theoryt::sign_extend(1)(true_val));
634634
}
635635
}
636+
637+
TEST_CASE("SMT bit vector rotation", "[core][smt2_incremental]")
638+
{
639+
const smt_bit_vector_constant_termt two{2, 8};
640+
const smt_bool_literal_termt true_val{true};
641+
const auto expected_return_sort = smt_bit_vector_sortt{8};
642+
SECTION("Left rotation")
643+
{
644+
const auto function_application =
645+
smt_bit_vector_theoryt::rotate_left(4)(two);
646+
REQUIRE(
647+
function_application.function_identifier() ==
648+
smt_identifier_termt(
649+
"rotate_left", expected_return_sort, {smt_numeral_indext{4}}));
650+
REQUIRE(function_application.get_sort() == expected_return_sort);
651+
REQUIRE(function_application.arguments().size() == 1);
652+
REQUIRE(function_application.arguments()[0].get() == two);
653+
cbmc_invariants_should_throwt invariants_throw;
654+
REQUIRE_NOTHROW(smt_bit_vector_theoryt::rotate_left(0));
655+
REQUIRE_THROWS(smt_bit_vector_theoryt::rotate_left(1)(true_val));
656+
}
657+
SECTION("Right rotation")
658+
{
659+
const auto function_application =
660+
smt_bit_vector_theoryt::rotate_right(4)(two);
661+
REQUIRE(
662+
function_application.function_identifier() ==
663+
smt_identifier_termt(
664+
"rotate_right", expected_return_sort, {smt_numeral_indext{4}}));
665+
REQUIRE(function_application.get_sort() == expected_return_sort);
666+
REQUIRE(function_application.arguments().size() == 1);
667+
REQUIRE(function_application.arguments()[0].get() == two);
668+
cbmc_invariants_should_throwt invariants_throw;
669+
REQUIRE_NOTHROW(smt_bit_vector_theoryt::rotate_right(0));
670+
REQUIRE_THROWS(smt_bit_vector_theoryt::rotate_right(1)(true_val));
671+
}
672+
}

0 commit comments

Comments
 (0)