Skip to content

Commit 1450583

Browse files
committed
Add remainder (modulus) arithmetic operator bvurem.
Along with tests of its conversion and the function application factory integrity.
1 parent 391fd95 commit 1450583

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
@@ -360,9 +360,11 @@ static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
360360

361361
static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
362362
{
363-
UNIMPLEMENTED_FEATURE(
364-
"Generation of SMT formula for truncation modulo expression: " +
365-
truncation_modulo.pretty());
363+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.lhs().type()));
364+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.rhs().type()));
365+
return smt_bit_vector_theoryt::remainder(
366+
convert_expr_to_smt(truncation_modulo.lhs()),
367+
convert_expr_to_smt(truncation_modulo.rhs()));
366368
}
367369

368370
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
@@ -146,3 +146,29 @@ void smt_bit_vector_theoryt::divisiont::validate(
146146
const smt_function_application_termt::factoryt<
147147
smt_bit_vector_theoryt::divisiont>
148148
smt_bit_vector_theoryt::division{};
149+
150+
const char *smt_bit_vector_theoryt::remaindert::identifier()
151+
{
152+
return "bvurem";
153+
}
154+
155+
smt_sortt smt_bit_vector_theoryt::remaindert::return_sort(
156+
const smt_termt &lhs,
157+
const smt_termt &rhs)
158+
{
159+
// For now, make sure that they have the same bit-width
160+
remaindert::validate(lhs, rhs);
161+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
162+
return smt_bit_vector_sortt{width};
163+
}
164+
165+
void smt_bit_vector_theoryt::remaindert::validate(
166+
const smt_termt &lhs,
167+
const smt_termt &rhs)
168+
{
169+
validate_bit_vector_predicate_arguments(lhs, rhs);
170+
}
171+
172+
const smt_function_application_termt::factoryt<
173+
smt_bit_vector_theoryt::remaindert>
174+
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
@@ -54,6 +54,14 @@ class smt_bit_vector_theoryt
5454
static void validate(const smt_termt &lhs, const smt_termt &rhs);
5555
};
5656
static const smt_function_application_termt::factoryt<divisiont> division;
57+
58+
struct remaindert final
59+
{
60+
static const char *identifier();
61+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
62+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
63+
};
64+
static const smt_function_application_termt::factoryt<remaindert> remainder;
5765
};
5866

5967
#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
@@ -347,4 +347,23 @@ TEST_CASE(
347347
const cbmc_invariants_should_throwt invariants_throw;
348348
REQUIRE_THROWS(convert_expr_to_smt(div_exprt{one_bvint, false_exprt{}}));
349349
}
350+
351+
SECTION(
352+
"Unsigned remainder (modulus) from truncating division of two constant "
353+
"size bit-vectors")
354+
{
355+
const auto constructed_term =
356+
convert_expr_to_smt(mod_exprt{one_bvint_unsigned, two_bvint_unsigned});
357+
const auto expected_term =
358+
smt_bit_vector_theoryt::remainder(smt_term_one, smt_term_two);
359+
CHECK(constructed_term == expected_term);
360+
}
361+
362+
SECTION(
363+
"Ensure that remainder (truncated modulo) node conversion fails if the "
364+
"operands are not bit-vector based")
365+
{
366+
const cbmc_invariants_should_throwt invariants_throw;
367+
REQUIRE_THROWS(convert_expr_to_smt(mod_exprt{one_bvint, false_exprt{}}));
368+
}
350369
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,17 @@ TEST_CASE(
225225
REQUIRE(function_application.arguments()[0].get() == two);
226226
REQUIRE(function_application.arguments()[1].get() == three);
227227
}
228+
229+
SECTION("Remainder")
230+
{
231+
const auto function_application =
232+
smt_bit_vector_theoryt::remainder(two, three);
233+
REQUIRE(
234+
function_application.function_identifier() ==
235+
smt_identifier_termt("bvurem", smt_bit_vector_sortt{8}));
236+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
237+
REQUIRE(function_application.arguments().size() == 2);
238+
REQUIRE(function_application.arguments()[0].get() == two);
239+
REQUIRE(function_application.arguments()[1].get() == three);
240+
}
228241
}

0 commit comments

Comments
 (0)