38 std::unordered_map<exprt, smt_termt, irep_full_hash>;
52 template <
typename factoryt>
56 const factoryt &factory)
59 const auto operand_terms =
61 return converted.at(expr);
63 return std::accumulate(
64 ++operand_terms.begin(),
66 *operand_terms.begin(),
74 template <
typename target_typet>
79 return can_cast_type<target_typet>(operand.type());
102 if(
const auto bool_type = type_try_dynamic_cast<bool_typet>(type))
106 if(
const auto bitvector_type = type_try_dynamic_cast<bitvector_typet>(type))
110 if(
const auto array_type = type_try_dynamic_cast<array_typet>(type))
153 const std::size_t c_bool_width = to_type.
get_width();
160 static std::function<std::function<smt_termt(smt_termt)>(std::size_t)>
175 if(
const auto to_fixedbv_type = type_try_dynamic_cast<fixedbv_typet>(to_type))
178 "Generation of SMT formula for type cast to fixed-point bitvector "
182 if(
const auto to_floatbv_type = type_try_dynamic_cast<floatbv_typet>(to_type))
185 "Generation of SMT formula for type cast to floating-point bitvector "
189 const std::size_t from_width =
from_type.get_width();
190 const std::size_t to_width = to_type.
get_width();
191 if(to_width == from_width)
193 if(to_width < from_width)
195 const std::size_t extension_size = to_width - from_width;
223 if(
const auto bitvector = type_try_dynamic_cast<bitvector_typet>(
from_type))
227 "Generation of SMT formula for type cast to bit vector from type: " +
234 "Generation of SMT formula for type cast to bit vector from type: " +
248 return *converter.result;
255 const auto &from_term = converted.at(cast.
op());
258 if(
const auto bool_type = type_try_dynamic_cast<bool_typet>(to_type))
260 if(
const auto c_bool_type = type_try_dynamic_cast<c_bool_typet>(to_type))
262 if(
const auto bit_vector = type_try_dynamic_cast<bitvector_typet>(to_type))
265 "Generation of SMT formula for type cast expression: " + cast.
pretty());
273 "Generation of SMT formula for floating point type cast expression: " +
282 "Generation of SMT formula for struct construction expression: " +
283 struct_construction.
pretty());
291 "Generation of SMT formula for union construction expression: " +
292 union_construction.
pretty());
312 const auto &width = bit_vector_sort.
bit_width();
322 "Conversion of array SMT literal " + array_sort.
pretty());
330 const size_t bit_width =
331 type_checked_cast<pointer_typet>(constant_literal.
type()).get_width();
334 const auto address = 0;
343 const auto value = numeric_cast_v<mp_integer>(constant_literal);
348 sort.accept(converter);
357 "Generation of SMT formula for concatenation expression: " +
365 if(operands_are_of_type<integer_bitvector_typet>(bitwise_and_expr))
373 "Generation of SMT formula for bitwise and expression: " +
374 bitwise_and_expr.
pretty());
382 if(operands_are_of_type<integer_bitvector_typet>(bitwise_or_expr))
390 "Generation of SMT formula for bitwise or expression: " +
391 bitwise_or_expr.
pretty());
399 if(operands_are_of_type<integer_bitvector_typet>(
bitwise_xor))
407 "Generation of SMT formula for bitwise xor expression: " +
416 const bool operand_is_bitvector =
419 if(operand_is_bitvector)
426 "Generation of SMT formula for bitnot_exprt: " + bitwise_not.
pretty());
434 const bool operand_is_bitvector =
436 if(operand_is_bitvector)
443 "Generation of SMT formula for unary minus expression: " +
453 "Generation of SMT formula for unary plus expression: " +
462 "Generation of SMT formula for \"is negative\" expression: " +
471 converted.at(if_expression.
cond()),
505 converted.at(implies.
op0()), converted.at(implies.
op1()));
520 converted.at(equal.
op0()), converted.at(equal.
op1()));
528 converted.at(not_equal.
op0()), converted.at(not_equal.
op1()));
536 "Generation of SMT formula for floating point equality expression: " +
545 "Generation of SMT formula for floating point not equal expression: " +
546 float_not_equal.
pretty());
549 template <
typename unsigned_factory_typet,
typename signed_factory_typet>
552 const unsigned_factory_typet &unsigned_factory,
553 const signed_factory_typet &signed_factory,
557 const auto &lhs = converted.at(binary_relation.
lhs());
558 const auto &rhs = converted.at(binary_relation.
rhs());
559 const typet operand_type = binary_relation.
lhs().
type();
568 const auto lhs_type_is_pointer =
570 const auto rhs_type_is_pointer =
573 lhs_type_is_pointer && rhs_type_is_pointer,
574 "pointer comparison requires that both operand types are pointers.");
575 return unsigned_factory(lhs, rhs);
580 return unsigned_factory(lhs, rhs);
582 return signed_factory(lhs, rhs);
586 "Generation of SMT formula for relational expression: " +
587 binary_relation.
pretty());
594 if(
const auto greater_than = expr_try_dynamic_cast<greater_than_exprt>(expr))
603 const auto greater_than_or_equal =
604 expr_try_dynamic_cast<greater_than_or_equal_exprt>(expr))
607 *greater_than_or_equal,
612 if(
const auto less_than = expr_try_dynamic_cast<less_than_exprt>(expr))
621 const auto less_than_or_equal =
622 expr_try_dynamic_cast<less_than_or_equal_exprt>(expr))
640 return can_cast_type<integer_bitvector_typet>(operand.type());
650 "We are only handling a binary version of plus when it has a pointer "
655 for(
auto &operand : plus.
operands())
671 "An addition expression with both operands being pointers when they are "
672 "not dereferenced is malformed");
675 *type_try_dynamic_cast<pointer_typet>(pointer.
type());
677 const auto pointer_size = pointer_sizes.at(base_type);
680 converted.at(pointer),
686 "Generation of SMT formula for plus expression: " + plus.
pretty());
695 const bool both_operands_bitvector =
702 const bool both_operands_pointers = lhs_is_pointer && rhs_is_pointer;
706 const bool one_operand_pointer = lhs_is_pointer || rhs_is_pointer;
708 if(both_operands_bitvector)
711 converted.at(minus.
lhs()), converted.at(minus.
rhs()));
713 else if(both_operands_pointers)
718 lhs_base_type == rhs_base_type,
719 "only pointers of the same object type can be subtracted.");
722 converted.at(minus.
lhs()), converted.at(minus.
rhs())),
723 pointer_sizes.at(lhs_base_type));
725 else if(one_operand_pointer)
731 "minus expressions of pointer and integer expect lhs to be the pointer");
735 converted.at(minus.
lhs()),
737 converted.at(minus.
rhs()), pointer_sizes.at(lhs_base_type)));
742 "Generation of SMT formula for minus expression: " + minus.
pretty());
753 const bool both_operands_bitvector =
757 const bool both_operands_unsigned =
761 if(both_operands_bitvector)
763 if(both_operands_unsigned)
775 "Generation of SMT formula for divide expression: " + divide.
pretty());
786 "Generation of SMT formula for floating point operation expression: " +
787 float_operation.
pretty());
794 const smt_termt &lhs = converted.at(truncation_modulo.
lhs());
795 const smt_termt &rhs = converted.at(truncation_modulo.
rhs());
797 const bool both_operands_bitvector =
801 const bool both_operands_unsigned =
805 if(both_operands_bitvector)
807 if(both_operands_unsigned)
819 "Generation of SMT formula for remainder (modulus) expression: " +
820 truncation_modulo.
pretty());
829 "Generation of SMT formula for euclidean modulo expression: " +
830 euclidean_modulo.
pretty());
841 return can_cast_type<integer_bitvector_typet>(operand.type());
850 "Generation of SMT formula for multiply expression: " +
855 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
859 result.setPower2(exponent);
876 const auto type = type_try_dynamic_cast<pointer_typet>(address_of.
type());
878 type,
"Result of the address_of operator should have pointer type.");
880 const auto object = object_map.find(base);
882 object != object_map.end(),
883 "Objects should be tracked before converting their address to SMT terms");
884 const std::size_t object_id =
object->second.unique_id;
887 "There should be sufficient bits to encode unique object identifier.");
892 "Pointer should be wider than object_bits in order to allow for offset "
897 expr_try_dynamic_cast<symbol_exprt>(address_of.
object()))
903 "Generation of SMT formula for address of expression: " +
922 "Generation of SMT formula for array comprehension expression: " +
923 array_comprehension.
pretty());
935 template <
typename factoryt,
typename shiftt>
937 const factoryt &factory,
941 const smt_termt &first_operand = converted.at(shift.op0());
942 const smt_termt &second_operand = converted.at(shift.op1());
943 const auto first_bit_vector_sort =
945 const auto second_bit_vector_sort =
948 first_bit_vector_sort && second_bit_vector_sort,
949 "Shift expressions are expected to have bit vector operands.");
950 const std::size_t first_width = first_bit_vector_sort->bit_width();
951 const std::size_t second_width = second_bit_vector_sort->
bit_width();
952 if(first_width > second_width)
959 else if(first_width < second_width)
968 return factory(first_operand, second_operand);
977 if(
const auto left_shift = expr_try_dynamic_cast<shl_exprt>(shift))
982 if(
const auto right_logical_shift = expr_try_dynamic_cast<lshr_exprt>(shift))
986 *right_logical_shift,
989 if(
const auto right_arith_shift = expr_try_dynamic_cast<ashr_exprt>(shift))
997 "Generation of SMT formula for shift expression: " + shift.
pretty());
1003 const exprt &new_value,
1006 const smt_termt &old_array_term = converted.at(old);
1007 const smt_termt &index_term = converted.at(index);
1008 const smt_termt &value_term = converted.at(new_value);
1016 if(
const auto array_type = type_try_dynamic_cast<array_typet>(with.
type()))
1024 "Generation of SMT formula for with expression: " + with.
pretty());
1032 "Generation of SMT formula for update expression: " + update.
pretty());
1040 "Generation of SMT formula for member extraction expression: " +
1041 member_extraction.
pretty());
1049 "Generation of SMT formula for is dynamic object expression: " +
1050 is_dynamic_object.
pretty());
1060 type_try_dynamic_cast<bitvector_typet>(pointer_expr.
type());
1065 width >= object_bits,
1066 "Width should be at least as big as the number of object bits.");
1069 width - 1, width - object_bits)(converted.at(pointer_expr));
1084 "Generation of SMT formula for string constant expression: " +
1085 string_constant.
pretty());
1093 "Generation of SMT formula for extract bit expression: " +
1101 const smt_termt &from = converted.at(extract_bits.
src());
1102 const auto upper_value = numeric_cast<std::size_t>(extract_bits.
upper());
1103 const auto lower_value = numeric_cast<std::size_t>(extract_bits.
lower());
1104 if(upper_value && lower_value)
1107 "Generation of SMT formula for extract bits expression: " +
1116 "Generation of SMT formula for bit vector replication expression: " +
1125 "Generation of SMT formula for byte extract expression: " +
1126 byte_extraction.
pretty());
1134 "Generation of SMT formula for byte update expression: " +
1143 "Generation of SMT formula for absolute value of expression: " +
1144 absolute_value_of.
pretty());
1152 "Generation of SMT formula for is not a number expression: " +
1161 "Generation of SMT formula for is finite expression: " +
1162 is_finite_expr.
pretty());
1170 "Generation of SMT formula for is infinite expression: " +
1171 is_infinite_expr.
pretty());
1179 "Generation of SMT formula for is infinite expression: " +
1180 is_normal_expr.
pretty());
1191 "Most significant bit can only be extracted from bit vector terms.");
1192 const size_t most_significant_bit_index = bit_vector_sort->bit_width() - 1;
1194 most_significant_bit_index, most_significant_bit_index);
1203 const smt_termt &left = converted.at(plus_overflow.
lhs());
1204 const smt_termt &right = converted.at(plus_overflow.
rhs());
1205 if(operands_are_of_type<unsignedbv_typet>(plus_overflow))
1211 if(operands_are_of_type<signedbv_typet>(plus_overflow))
1224 "Generation of SMT formula for plus overflow expression: " +
1232 const smt_termt &left = converted.at(minus_overflow.
lhs());
1233 const smt_termt &right = converted.at(minus_overflow.
rhs());
1234 if(operands_are_of_type<unsignedbv_typet>(minus_overflow))
1238 if(operands_are_of_type<signedbv_typet>(minus_overflow))
1256 "Generation of SMT formula for minus overflow expression: " +
1257 minus_overflow.
pretty());
1265 const auto &operand_type = mult_overflow.
lhs().
type();
1266 const smt_termt &left = converted.at(mult_overflow.
lhs());
1267 const smt_termt &right = converted.at(mult_overflow.
rhs());
1269 const auto unsigned_type =
1270 type_try_dynamic_cast<unsignedbv_typet>(operand_type))
1272 const std::size_t width = unsigned_type->get_width();
1279 const auto signed_type =
1280 type_try_dynamic_cast<signedbv_typet>(operand_type))
1284 const std::size_t width = signed_type->get_width();
1286 const auto multiplication =
1299 "Generation of SMT formula for multiply overflow expression: " +
1309 INVARIANT(type,
"Pointer object should have a bitvector-based type.");
1310 const auto converted_expr = converted.at(
pointer_object.pointer());
1311 const std::size_t width = type->get_width();
1314 width >= object_bits,
1315 "Width should be at least as big as the number of object bits.");
1316 const std::size_t ext = width - object_bits;
1318 width - 1, width - object_bits)(converted_expr);
1332 INVARIANT(type,
"Pointer offset should have a bitvector-based type.");
1333 const auto converted_expr = converted.at(
pointer_offset.pointer());
1334 const std::size_t width = type->get_width();
1336 if(offset_bits > width)
1337 offset_bits = width;
1338 const auto extract_op =
1340 if(width > offset_bits)
1352 "Generation of SMT formula for shift left overflow expression: " +
1371 "Generation of SMT formula for literal expression: " + literal.
pretty());
1379 "Generation of SMT formula for for all expression: " + for_all.
pretty());
1387 "Generation of SMT formula for exists expression: " +
exists.pretty());
1395 "Generation of SMT formula for vector expression: " + vector.
pretty());
1406 pointer_sort,
"Pointers should be encoded as bit vector sorted terms.");
1407 const std::size_t pointer_width = pointer_sort->bit_width();
1408 return call_object_size(
1418 "Generation of SMT formula for let expression: " + let.
pretty());
1426 "Generation of SMT formula for byte swap expression: " +
1435 "Generation of SMT formula for population count expression: " +
1436 population_count.
pretty());
1444 "Generation of SMT formula for count leading zeros expression: " +
1445 count_leading_zeros.
pretty());
1453 "Generation of SMT formula for byte swap expression: " +
1454 count_trailing_zeros.
pretty());
1464 if(
const auto symbol = expr_try_dynamic_cast<symbol_exprt>(expr))
1468 if(
const auto nondet = expr_try_dynamic_cast<nondet_symbol_exprt>(expr))
1472 if(
const auto cast = expr_try_dynamic_cast<typecast_exprt>(expr))
1477 const auto float_cast = expr_try_dynamic_cast<floatbv_typecast_exprt>(expr))
1481 if(
const auto struct_construction = expr_try_dynamic_cast<struct_exprt>(expr))
1485 if(
const auto union_construction = expr_try_dynamic_cast<union_exprt>(expr))
1489 if(
const auto constant_literal = expr_try_dynamic_cast<constant_exprt>(expr))
1494 const auto concatenation = expr_try_dynamic_cast<concatenation_exprt>(expr))
1498 if(
const auto bitwise_and_expr = expr_try_dynamic_cast<bitand_exprt>(expr))
1502 if(
const auto bitwise_or_expr = expr_try_dynamic_cast<bitor_exprt>(expr))
1506 if(
const auto bitwise_xor = expr_try_dynamic_cast<bitxor_exprt>(expr))
1510 if(
const auto bitwise_not = expr_try_dynamic_cast<bitnot_exprt>(expr))
1514 if(
const auto unary_minus = expr_try_dynamic_cast<unary_minus_exprt>(expr))
1518 if(
const auto unary_plus = expr_try_dynamic_cast<unary_plus_exprt>(expr))
1522 if(
const auto is_negative = expr_try_dynamic_cast<sign_exprt>(expr))
1526 if(
const auto if_expression = expr_try_dynamic_cast<if_exprt>(expr))
1530 if(
const auto and_expression = expr_try_dynamic_cast<and_exprt>(expr))
1534 if(
const auto or_expression = expr_try_dynamic_cast<or_exprt>(expr))
1538 if(
const auto xor_expression = expr_try_dynamic_cast<xor_exprt>(expr))
1542 if(
const auto implies = expr_try_dynamic_cast<implies_exprt>(expr))
1546 if(
const auto logical_not = expr_try_dynamic_cast<not_exprt>(expr))
1550 if(
const auto equal = expr_try_dynamic_cast<equal_exprt>(expr))
1554 if(
const auto not_equal = expr_try_dynamic_cast<notequal_exprt>(expr))
1559 const auto float_equal =
1560 expr_try_dynamic_cast<ieee_float_equal_exprt>(expr))
1565 const auto float_not_equal =
1566 expr_try_dynamic_cast<ieee_float_notequal_exprt>(expr))
1571 const auto converted_relational =
1574 return *converted_relational;
1576 if(
const auto plus = expr_try_dynamic_cast<plus_exprt>(expr))
1580 if(
const auto minus = expr_try_dynamic_cast<minus_exprt>(expr))
1584 if(
const auto divide = expr_try_dynamic_cast<div_exprt>(expr))
1589 const auto float_operation =
1590 expr_try_dynamic_cast<ieee_float_op_exprt>(expr))
1594 if(
const auto truncation_modulo = expr_try_dynamic_cast<mod_exprt>(expr))
1599 const auto euclidean_modulo =
1600 expr_try_dynamic_cast<euclidean_mod_exprt>(expr))
1604 if(
const auto multiply = expr_try_dynamic_cast<mult_exprt>(expr))
1609 else if(expr.
id() == ID_floatbv_rem)
1614 if(
const auto address_of = expr_try_dynamic_cast<address_of_exprt>(expr))
1618 if(
const auto array_of = expr_try_dynamic_cast<array_of_exprt>(expr))
1623 const auto array_comprehension =
1624 expr_try_dynamic_cast<array_comprehension_exprt>(expr))
1628 if(
const auto index = expr_try_dynamic_cast<index_exprt>(expr))
1632 if(
const auto shift = expr_try_dynamic_cast<shift_exprt>(expr))
1636 if(
const auto with = expr_try_dynamic_cast<with_exprt>(expr))
1640 if(
const auto update = expr_try_dynamic_cast<update_exprt>(expr))
1644 if(
const auto member_extraction = expr_try_dynamic_cast<member_exprt>(expr))
1650 expr_try_dynamic_cast<pointer_offset_exprt>(expr))
1656 expr_try_dynamic_cast<pointer_object_exprt>(expr))
1661 const auto is_dynamic_object =
1662 expr_try_dynamic_cast<is_dynamic_object_exprt>(expr))
1667 const auto is_invalid_pointer =
1668 expr_try_dynamic_cast<is_invalid_pointer_exprt>(expr))
1672 if(
const auto string_constant = expr_try_dynamic_cast<string_constantt>(expr))
1676 if(
const auto extract_bit = expr_try_dynamic_cast<extractbit_exprt>(expr))
1680 if(
const auto extract_bits = expr_try_dynamic_cast<extractbits_exprt>(expr))
1684 if(
const auto replication = expr_try_dynamic_cast<replication_exprt>(expr))
1689 const auto byte_extraction =
1690 expr_try_dynamic_cast<byte_extract_exprt>(expr))
1694 if(
const auto byte_update = expr_try_dynamic_cast<byte_update_exprt>(expr))
1698 if(
const auto absolute_value_of = expr_try_dynamic_cast<abs_exprt>(expr))
1702 if(
const auto is_nan_expr = expr_try_dynamic_cast<isnan_exprt>(expr))
1706 if(
const auto is_finite_expr = expr_try_dynamic_cast<isfinite_exprt>(expr))
1710 if(
const auto is_infinite_expr = expr_try_dynamic_cast<isinf_exprt>(expr))
1714 if(
const auto is_normal_expr = expr_try_dynamic_cast<isnormal_exprt>(expr))
1719 const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
1724 const auto minus_overflow =
1725 expr_try_dynamic_cast<minus_overflow_exprt>(expr))
1730 const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
1734 if(
const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
1738 if(
const auto array_construction = expr_try_dynamic_cast<array_exprt>(expr))
1742 if(
const auto literal = expr_try_dynamic_cast<literal_exprt>(expr))
1746 if(
const auto for_all = expr_try_dynamic_cast<forall_exprt>(expr))
1750 if(
const auto exists = expr_try_dynamic_cast<exists_exprt>(expr))
1754 if(
const auto vector = expr_try_dynamic_cast<vector_exprt>(expr))
1758 if(
const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
1762 if(
const auto let = expr_try_dynamic_cast<let_exprt>(expr))
1767 expr.
id() != ID_constraint_select_one,
1768 "constraint_select_one is not expected in smt conversion: " +
1770 if(
const auto byte_swap = expr_try_dynamic_cast<bswap_exprt>(expr))
1774 if(
const auto population_count = expr_try_dynamic_cast<popcount_exprt>(expr))
1779 const auto count_leading_zeros =
1780 expr_try_dynamic_cast<count_leading_zeros_exprt>(expr))
1785 const auto count_trailing_zeros =
1786 expr_try_dynamic_cast<count_trailing_zeros_exprt>(expr))
1792 "Generation of SMT formula for unknown kind of expression: " +
1796 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1797 template <
typename functiont>
1811 template <
typename functiont>
1821 const auto address_of_expr = expr_try_dynamic_cast<address_of_exprt>(expr);
1822 if(!address_of_expr)
1824 const auto array_index_expr =
1825 expr_try_dynamic_cast<index_exprt>(address_of_expr->object());
1826 if(!array_index_expr)
1830 array_index_expr->array(),
1831 type_checked_cast<pointer_typet>(address_of_expr->type())},
1832 array_index_expr->index()};
1843 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1844 static bool in_conversion =
false;
1847 "Conversion of expr to smt should be non-recursive. "
1848 "Re-entrance found in conversion of " +
1850 in_conversion =
true;
1851 const auto end_conversion =
at_scope_exit([&]() { in_conversion =
false; });
1855 lowered_expr.visit_post([&](
const exprt &expr) {
1856 const auto find_result = sub_expression_map.find(expr);
1857 if(find_result != sub_expression_map.cend())
1860 expr, sub_expression_map, object_map, pointer_sizes,
object_size);
1861 sub_expression_map.emplace_hint(find_result, expr, std::move(term));
1863 return std::move(sub_expression_map.at(lowered_expr));