Skip to content

Commit 5f313cd

Browse files
committed
Add remainder (modulus) arithmetic operator bvurem.
Along with tests of its conversion and the function application factory integrity.
1 parent 6aadc83 commit 5f313cd

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,11 @@ static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
380380

381381
static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
382382
{
383-
UNIMPLEMENTED_FEATURE(
384-
"Generation of SMT formula for truncation modulo expression: " +
385-
truncation_modulo.pretty());
383+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.lhs().type()));
384+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.rhs().type()));
385+
return smt_bit_vector_theoryt::remainder(
386+
convert_expr_to_smt(truncation_modulo.lhs()),
387+
convert_expr_to_smt(truncation_modulo.rhs()));
386388
}
387389

388390
static smt_termt

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,29 @@ void smt_bit_vector_theoryt::divisiont::validate(
140140
const smt_function_application_termt::factoryt<
141141
smt_bit_vector_theoryt::divisiont>
142142
smt_bit_vector_theoryt::division{};
143+
144+
const char *smt_bit_vector_theoryt::remaindert::identifier()
145+
{
146+
return "bvurem";
147+
}
148+
149+
smt_sortt smt_bit_vector_theoryt::remaindert::return_sort(
150+
const smt_termt &lhs,
151+
const smt_termt &rhs)
152+
{
153+
// For now, make sure that they have the same bit-width
154+
remaindert::validate(lhs, rhs);
155+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
156+
return smt_bit_vector_sortt{width};
157+
}
158+
159+
void smt_bit_vector_theoryt::remaindert::validate(
160+
const smt_termt &lhs,
161+
const smt_termt &rhs)
162+
{
163+
validate_bit_vector_predicate_arguments(lhs, rhs);
164+
}
165+
166+
const smt_function_application_termt::factoryt<
167+
smt_bit_vector_theoryt::remaindert>
168+
smt_bit_vector_theoryt::remainder{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ class smt_bit_vector_theoryt
5353
static void validate(const smt_termt &lhs, const smt_termt &rhs);
5454
};
5555
static const smt_function_application_termt::factoryt<divisiont> division;
56+
57+
struct remaindert final
58+
{
59+
static const char *identifier();
60+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
61+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
62+
};
63+
static const smt_function_application_termt::factoryt<remaindert> remainder;
5664
};
5765

5866
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,4 +357,23 @@ TEST_CASE(
357357
const cbmc_invariants_should_throwt invariants_throw;
358358
REQUIRE_THROWS(convert_expr_to_smt(div_exprt{one_bvint, false_exprt{}}));
359359
}
360+
361+
SECTION(
362+
"Unsigned remainder (modulus) from truncating division of two constant "
363+
"size bit-vectors")
364+
{
365+
const auto constructed_term =
366+
convert_expr_to_smt(mod_exprt{one_bvint_unsigned, two_bvint_unsigned});
367+
const auto expected_term =
368+
smt_bit_vector_theoryt::remainder(smt_term_one, smt_term_two);
369+
CHECK(constructed_term == expected_term);
370+
}
371+
372+
SECTION(
373+
"Ensure that remainder (truncated modulo) node conversion fails if the "
374+
"operands are not bit-vector based")
375+
{
376+
const cbmc_invariants_should_throwt invariants_throw;
377+
REQUIRE_THROWS(convert_expr_to_smt(mod_exprt{one_bvint, false_exprt{}}));
378+
}
360379
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,17 @@ TEST_CASE(
238238
REQUIRE(function_application.arguments()[0].get() == two);
239239
REQUIRE(function_application.arguments()[1].get() == three);
240240
}
241+
242+
SECTION("Remainder")
243+
{
244+
const auto function_application =
245+
smt_bit_vector_theoryt::remainder(two, three);
246+
REQUIRE(
247+
function_application.function_identifier() ==
248+
smt_identifier_termt("bvurem", smt_bit_vector_sortt{8}));
249+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
250+
REQUIRE(function_application.arguments().size() == 2);
251+
REQUIRE(function_application.arguments()[0].get() == two);
252+
REQUIRE(function_application.arguments()[1].get() == three);
253+
}
241254
}

0 commit comments

Comments
 (0)