Skip to content

Commit ac69bf3

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

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

371371
static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
372372
{
373-
UNIMPLEMENTED_FEATURE(
374-
"Generation of SMT formula for truncation modulo expression: " +
375-
truncation_modulo.pretty());
373+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.lhs().type()));
374+
PRECONDITION(can_cast_type<bitvector_typet>(truncation_modulo.rhs().type()));
375+
return smt_bit_vector_theoryt::remainder(
376+
convert_expr_to_smt(truncation_modulo.lhs()),
377+
convert_expr_to_smt(truncation_modulo.rhs()));
376378
}
377379

378380
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
@@ -143,3 +143,29 @@ void smt_bit_vector_theoryt::divisiont::validate(
143143
const smt_function_application_termt::factoryt<
144144
smt_bit_vector_theoryt::divisiont>
145145
smt_bit_vector_theoryt::division{};
146+
147+
const char *smt_bit_vector_theoryt::remaindert::identifier()
148+
{
149+
return "bvurem";
150+
}
151+
152+
smt_sortt smt_bit_vector_theoryt::remaindert::return_sort(
153+
const smt_termt &lhs,
154+
const smt_termt &rhs)
155+
{
156+
// For now, make sure that they have the same bit-width
157+
remaindert::validate(lhs, rhs);
158+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
159+
return smt_bit_vector_sortt{width};
160+
}
161+
162+
void smt_bit_vector_theoryt::remaindert::validate(
163+
const smt_termt &lhs,
164+
const smt_termt &rhs)
165+
{
166+
validate_bit_vector_predicate_arguments(lhs, rhs);
167+
}
168+
169+
const smt_function_application_termt::factoryt<
170+
smt_bit_vector_theoryt::remaindert>
171+
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
@@ -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
@@ -232,4 +232,17 @@ TEST_CASE(
232232
REQUIRE(function_application.arguments()[0].get() == two);
233233
REQUIRE(function_application.arguments()[1].get() == three);
234234
}
235+
236+
SECTION("Remainder")
237+
{
238+
const auto function_application =
239+
smt_bit_vector_theoryt::remainder(two, three);
240+
REQUIRE(
241+
function_application.function_identifier() ==
242+
smt_identifier_termt("bvurem", smt_bit_vector_sortt{8}));
243+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
244+
REQUIRE(function_application.arguments().size() == 2);
245+
REQUIRE(function_application.arguments()[0].get() == two);
246+
REQUIRE(function_application.arguments()[1].get() == three);
247+
}
235248
}

0 commit comments

Comments
 (0)