Skip to content

Commit 1f3801c

Browse files
authored
Merge pull request #6614 from NlightNFotis/newsmt_additional_operators
New SMT2 backend: arithmetic operators implementation for fixed size bit vectors
2 parents 3c0d865 + b11a3b2 commit 1f3801c

File tree

5 files changed

+703
-23
lines changed

5 files changed

+703
-23
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,19 @@ static smt_termt convert_expr_to_smt(const bitnot_exprt &bitwise_not)
154154

155155
static smt_termt convert_expr_to_smt(const unary_minus_exprt &unary_minus)
156156
{
157-
UNIMPLEMENTED_FEATURE(
158-
"Generation of SMT formula for unary minus expression: " +
159-
unary_minus.pretty());
157+
const bool operand_is_bitvector =
158+
can_cast_type<integer_bitvector_typet>(unary_minus.op().type());
159+
if(operand_is_bitvector)
160+
{
161+
return smt_bit_vector_theoryt::negate(
162+
convert_expr_to_smt(unary_minus.op()));
163+
}
164+
else
165+
{
166+
UNIMPLEMENTED_FEATURE(
167+
"Generation of SMT formula for unary minus expression: " +
168+
unary_minus.pretty());
169+
}
160170
}
161171

162172
static smt_termt convert_expr_to_smt(const unary_plus_exprt &unary_plus)
@@ -326,20 +336,67 @@ static optionalt<smt_termt> try_relational_conversion(const exprt &expr)
326336

327337
static smt_termt convert_expr_to_smt(const plus_exprt &plus)
328338
{
329-
UNIMPLEMENTED_FEATURE(
330-
"Generation of SMT formula for plus expression: " + plus.pretty());
339+
if(std::all_of(
340+
plus.operands().cbegin(), plus.operands().cend(), [](exprt operand) {
341+
return can_cast_type<integer_bitvector_typet>(operand.type());
342+
}))
343+
{
344+
return convert_multiary_operator_to_terms(
345+
plus, smt_bit_vector_theoryt::add);
346+
}
347+
else
348+
{
349+
UNIMPLEMENTED_FEATURE(
350+
"Generation of SMT formula for plus expression: " + plus.pretty());
351+
}
331352
}
332353

333354
static smt_termt convert_expr_to_smt(const minus_exprt &minus)
334355
{
335-
UNIMPLEMENTED_FEATURE(
336-
"Generation of SMT formula for minus expression: " + minus.pretty());
356+
const bool both_operands_bitvector =
357+
can_cast_type<integer_bitvector_typet>(minus.lhs().type()) &&
358+
can_cast_type<integer_bitvector_typet>(minus.rhs().type());
359+
360+
if(both_operands_bitvector)
361+
{
362+
return smt_bit_vector_theoryt::subtract(
363+
convert_expr_to_smt(minus.lhs()), convert_expr_to_smt(minus.rhs()));
364+
}
365+
else
366+
{
367+
UNIMPLEMENTED_FEATURE(
368+
"Generation of SMT formula for minus expression: " + minus.pretty());
369+
}
337370
}
338371

339372
static smt_termt convert_expr_to_smt(const div_exprt &divide)
340373
{
341-
UNIMPLEMENTED_FEATURE(
342-
"Generation of SMT formula for divide expression: " + divide.pretty());
374+
const bool both_operands_bitvector =
375+
can_cast_type<integer_bitvector_typet>(divide.lhs().type()) &&
376+
can_cast_type<integer_bitvector_typet>(divide.rhs().type());
377+
378+
const bool both_operands_unsigned =
379+
can_cast_type<unsignedbv_typet>(divide.lhs().type()) &&
380+
can_cast_type<unsignedbv_typet>(divide.rhs().type());
381+
382+
if(both_operands_bitvector)
383+
{
384+
if(both_operands_unsigned)
385+
{
386+
return smt_bit_vector_theoryt::unsigned_divide(
387+
convert_expr_to_smt(divide.lhs()), convert_expr_to_smt(divide.rhs()));
388+
}
389+
else
390+
{
391+
return smt_bit_vector_theoryt::signed_divide(
392+
convert_expr_to_smt(divide.lhs()), convert_expr_to_smt(divide.rhs()));
393+
}
394+
}
395+
else
396+
{
397+
UNIMPLEMENTED_FEATURE(
398+
"Generation of SMT formula for divide expression: " + divide.pretty());
399+
}
343400
}
344401

345402
static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
@@ -353,9 +410,35 @@ static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
353410

354411
static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
355412
{
356-
UNIMPLEMENTED_FEATURE(
357-
"Generation of SMT formula for truncation modulo expression: " +
358-
truncation_modulo.pretty());
413+
const bool both_operands_bitvector =
414+
can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs().type()) &&
415+
can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs().type());
416+
417+
const bool both_operands_unsigned =
418+
can_cast_type<unsignedbv_typet>(truncation_modulo.lhs().type()) &&
419+
can_cast_type<unsignedbv_typet>(truncation_modulo.rhs().type());
420+
421+
if(both_operands_bitvector)
422+
{
423+
if(both_operands_unsigned)
424+
{
425+
return smt_bit_vector_theoryt::unsigned_remainder(
426+
convert_expr_to_smt(truncation_modulo.lhs()),
427+
convert_expr_to_smt(truncation_modulo.rhs()));
428+
}
429+
else
430+
{
431+
return smt_bit_vector_theoryt::signed_remainder(
432+
convert_expr_to_smt(truncation_modulo.lhs()),
433+
convert_expr_to_smt(truncation_modulo.rhs()));
434+
}
435+
}
436+
else
437+
{
438+
UNIMPLEMENTED_FEATURE(
439+
"Generation of SMT formula for remainder (modulus) expression: " +
440+
truncation_modulo.pretty());
441+
}
359442
}
360443

361444
static smt_termt
@@ -368,8 +451,22 @@ convert_expr_to_smt(const euclidean_mod_exprt &euclidean_modulo)
368451

369452
static smt_termt convert_expr_to_smt(const mult_exprt &multiply)
370453
{
371-
UNIMPLEMENTED_FEATURE(
372-
"Generation of SMT formula for multiply expression: " + multiply.pretty());
454+
if(std::all_of(
455+
multiply.operands().cbegin(),
456+
multiply.operands().cend(),
457+
[](exprt operand) {
458+
return can_cast_type<integer_bitvector_typet>(operand.type());
459+
}))
460+
{
461+
return convert_multiary_operator_to_terms(
462+
multiply, smt_bit_vector_theoryt::multiply);
463+
}
464+
else
465+
{
466+
UNIMPLEMENTED_FEATURE(
467+
"Generation of SMT formula for multiply expression: " +
468+
multiply.pretty());
469+
}
373470
}
374471

375472
static smt_termt convert_expr_to_smt(const address_of_exprt &address_of)

0 commit comments

Comments
 (0)