56#define UNEXPECTEDCASE(S) PRECONDITION_WITH_DIAGNOSTICS(false, S);
59#define SMT2_TODO(S) PRECONDITION_WITH_DIAGNOSTICS(false, "TODO: " S)
63 const std::string &_benchmark,
64 const std::string &_notes,
65 const std::string &_logic,
162 "variable number shall be within bounds");
168 out <<
"; SMT 2" <<
"\n";
177 out <<
"; Generated for the CPROVER SMT2 solver\n";
break;
185 out <<
"(set-info :source \"" <<
notes <<
"\")" <<
"\n";
187 out <<
"(set-option :produce-models true)" <<
"\n";
193 out <<
"(set-logic " <<
logic <<
")" <<
"\n";
208 out <<
"(check-sat-assuming (";
218 out <<
"; assumptions\n";
229 out <<
"(check-sat)\n";
240 out <<
"(get-value (" <<
id <<
"))"
248 out <<
"; end of SMT2 file"
258 std::size_t number = 0;
259 std::size_t h=pointer_width-1;
260 std::size_t l=pointer_width-
config.bv_encoding.object_bits;
264 const typet &type = o.type();
268 (o.id() != ID_symbol && o.id() != ID_string_constant) ||
269 !size_expr.has_value())
276 out <<
"(assert (=> (= "
277 <<
"((_ extract " << h <<
" " << l <<
") ";
279 out <<
") (_ bv" << number <<
" " <<
config.bv_encoding.object_bits <<
"))"
280 <<
"(= " <<
id <<
" ";
305 if(expr.
id()==ID_symbol)
312 return it->second.value;
315 else if(expr.
id()==ID_nondet_symbol)
322 return it->second.value;
324 else if(expr.
id() == ID_literal)
332 else if(expr.
id() == ID_not)
342 (!expr.
has_operands() && (expr.
id() == ID_struct || expr.
id() == ID_array)))
354 op = std::move(eval_op);
389 if(s.size()>=2 && s[0]==
'#' && s[1]==
'b')
394 else if(s.size()>=2 && s[0]==
'#' && s[1]==
'x')
401 std::size_t
pos = s.find(
".");
402 if(
pos != std::string::npos)
405 if(type.
id() == ID_rational)
413 else if(type.
id() == ID_real)
424 "smt2_convt::parse_literal parsed a number with a decimal point "
433 else if(src.
get_sub().size()==2 &&
438 else if(src.
get_sub().size()==3 &&
441 src.
get_sub()[1].id_string().substr(0, 2)==
"bv")
446 type.
id() == ID_rational && src.
get_sub().size() == 3 &&
457 else if(src.
get_sub().size()==4 &&
460 if(type.
id()==ID_floatbv)
475 s1_int << (floatbv_type.
get_e() + floatbv_type.
get_f()),
481 else if(src.
get_sub().size()==4 &&
490 else if(src.
get_sub().size()==4 &&
499 else if(src.
get_sub().size()==4 &&
509 src.
get_sub()[0].id() ==
"root-obj")
522 src.
get_sub()[1].id().empty() && src.
get_sub()[1].get_sub().size() == 3 &&
523 src.
get_sub()[1].get_sub()[0].id() ==
"+",
524 "unexpected root-obj expression",
531 !
failed,
"failed to parse rational constant coefficient", src.
pretty());
535 sum_lhs.
get_sub()[0].id() ==
"^" && sum_lhs.
get_sub()[1].id() ==
"x",
536 "unexpected first operand to root-obj",
540 degree > 0,
"polynomial degree must be positive", src.
pretty());
541 std::vector<rationalt> coefficients{degree + 1,
rationalt{}};
542 coefficients.front() = constant_coeff;
548 if(type.
id()==ID_signedbv ||
549 type.
id()==ID_unsignedbv ||
550 type.
id()==ID_c_enum ||
551 type.
id()==ID_c_bool)
555 else if(type.
id()==ID_c_enum_tag)
561 result.
type() = type;
564 else if(type.
id()==ID_fixedbv ||
565 type.
id()==ID_floatbv)
571 type.
id() == ID_integer || type.
id() == ID_natural ||
572 type.
id() == ID_rational || type.
id() == ID_real)
576 else if(type.
id() == ID_range)
582 "smt2_convt::parse_literal should not be of unsupported type " +
590 std::unordered_map<int64_t, exprt> operands_map;
594 auto maybe_default_op = operands_map.find(-1);
596 if(maybe_default_op == operands_map.end())
599 default_op = maybe_default_op->second;
602 if(maybe_size.has_value())
604 while(i < maybe_size.value())
606 auto found_op = operands_map.find(i);
607 if(found_op != operands_map.end())
608 operands.emplace_back(found_op->second);
610 operands.emplace_back(default_op);
618 auto found_op = operands_map.find(i);
619 while(found_op != operands_map.end())
621 operands.emplace_back(found_op->second);
623 found_op = operands_map.find(i);
625 operands.emplace_back(default_op);
631 std::unordered_map<int64_t, exprt> *operands_map,
642 if(!index_expr.is_constant())
650 bool failure =
to_integer(index_constant, tempint);
653 long index = tempint.to_long();
655 operands_map->emplace(index, value);
657 else if(src.
get_sub().size()==2 &&
658 src.
get_sub()[0].get_sub().size()==3 &&
659 src.
get_sub()[0].get_sub()[0].id()==
"as" &&
660 src.
get_sub()[0].get_sub()[1].id()==
"const")
664 operands_map->emplace(-1, default_value);
697 if(components.empty())
705 for(std::size_t i=0; i<components.size(); i++)
715 src.
get_sub().size() > j,
"insufficient number of component values");
732 std::size_t offset=0;
734 for(std::size_t i=0; i<components.size(); i++)
739 std::size_t component_width=
boolbv_width(components[i].type());
742 offset + component_width <= total_width,
743 "struct component bits shall be within struct bit vector");
745 std::string component_binary=
747 total_width-offset-component_width, component_width);
752 offset+=component_width;
766 for(
const auto &binding : src.
get_sub()[1].get_sub())
768 const irep_idt &name = binding.get_sub()[0].id();
779 return parse_rec(bindings_it->second, type);
783 type.
id() == ID_signedbv || type.
id() == ID_unsignedbv ||
784 type.
id() == ID_integer || type.
id() == ID_rational ||
785 type.
id() == ID_natural || type.
id() == ID_real || type.
id() == ID_c_enum ||
786 type.
id() == ID_c_enum_tag || type.
id() == ID_fixedbv ||
787 type.
id() == ID_floatbv || type.
id() == ID_c_bool || type.
id() == ID_range)
791 else if(type.
id()==ID_bool)
793 if(src.
id()==ID_1 || src.
id()==ID_true)
795 else if(src.
id()==ID_0 || src.
id()==ID_false)
798 else if(type.
id()==ID_pointer)
813 else if(type.
id()==ID_struct)
817 else if(type.
id() == ID_struct_tag)
822 struct_expr.type() = type;
823 return std::move(struct_expr);
825 else if(type.
id()==ID_union)
829 else if(type.
id() == ID_union_tag)
833 union_expr.type() = type;
836 else if(type.
id()==ID_array)
850 expr.
id() == ID_string_constant || expr.
id() == ID_label)
852 const std::size_t object_bits =
config.bv_encoding.object_bits;
853 const std::size_t max_objects = std::size_t(1) << object_bits;
856 if(object_id >= max_objects)
859 "too many addressed objects: maximum number of objects is set to 2^n=" +
860 std::to_string(max_objects) +
861 " (with n=" + std::to_string(object_bits) +
"); " +
862 "use the `--object-bits n` option to increase the maximum number"};
865 out <<
"(concat (_ bv" << object_id <<
" " << object_bits <<
")"
866 <<
" (_ bv0 " <<
boolbv_width(result_type) - object_bits <<
"))";
868 else if(expr.
id()==ID_index)
877 if(array.
type().
id()==ID_pointer)
879 else if(array.
type().
id()==ID_array)
899 else if(expr.
id()==ID_member)
904 const typet &struct_op_type = struct_op.
type();
907 struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag,
908 "member expression operand shall have struct type");
911 struct_op_type.
id() == ID_struct_tag
928 else if(expr.
id()==ID_if)
943 "operand of address of expression should not be of kind " +
951 if(node.
id() == ID_exists || node.
id() == ID_forall)
965 else if(expr ==
false)
967 else if(expr.
id()==ID_literal)
979 out <<
"; convert\n";
980 out <<
"; Converting var_no " << l.
var_no() <<
" with expr ID of "
990 out <<
"(declare-fun ";
992 out <<
" () Bool)\n";
993 out <<
"(assert (= ";
1005 out <<
"(define-fun " << identifier <<
" () Bool ";
1033 const auto identifier =
1055 for(
auto &assumption : _assumptions)
1066 if(identifier.empty())
1069 if(isdigit(identifier[0]))
1091 std::string result =
"|";
1093 for(
auto ch : identifier)
1101 result+=std::to_string(ch);
1118 if(type.
id()==ID_floatbv)
1121 return "f"+std::to_string(spec.
width())+
"_"+std::to_string(spec.
f);
1123 else if(type.
id() == ID_bv)
1127 else if(type.
id()==ID_unsignedbv)
1131 else if(type.
id()==ID_c_bool)
1135 else if(type.
id()==ID_signedbv)
1139 else if(type.
id()==ID_bool)
1143 else if(type.
id()==ID_c_enum_tag)
1147 else if(type.
id() == ID_pointer)
1151 else if(type.
id() == ID_struct_tag)
1158 else if(type.
id() == ID_union_tag)
1162 else if(type.
id() == ID_array)
1166 else if(type.
id() == ID_integer)
1170 else if(type.
id() == ID_real)
1174 else if(type.
id() == ID_string)
1178 else if(type.
id() == ID_regex)
1182 else if(type.
id() == ID_mathematical_function)
1184 std::string result =
"MF";
1186 for(
const auto &d : mf.domain())
1188 result +=
"_" +
type2id(mf.codomain());
1208 if(expr.
id()==ID_symbol)
1215 if(expr.
id()==ID_smt2_symbol)
1223 !expr.
operands().empty(),
"non-symbol expressions shall have operands");
1229 for(
const auto &op : expr.
operands())
1257 converter_result->second(expr);
1262 if(expr.
id()==ID_symbol)
1268 else if(expr.
id()==ID_nondet_symbol)
1271 DATA_INVARIANT(!
id.empty(),
"nondet symbol must have identifier");
1274 else if(expr.
id()==ID_smt2_symbol)
1280 else if(expr.
id()==ID_typecast)
1284 else if(expr.
id()==ID_floatbv_typecast)
1288 else if(expr.
id() == ID_floatbv_round_to_integral)
1292 else if(expr.
id()==ID_struct)
1296 else if(expr.
id()==ID_union)
1304 else if(expr.
id() == ID_concatenation)
1308 "concatenation expression should have at least one operand",
1313 for(
const auto &op : expr.
operands())
1316 non_zero_width_ops.push_back(op);
1320 !non_zero_width_ops.empty(),
1321 "concatenation must have at least one non-zero-width operand");
1323 if(non_zero_width_ops.size() == 1)
1332 for(
const auto &op : non_zero_width_ops)
1342 expr.
id() == ID_bitand || expr.
id() == ID_bitor || expr.
id() == ID_bitxor)
1346 "given expression should have at least one operand",
1357 if(expr.
id() == ID_concatenation)
1359 else if(expr.
id() == ID_bitand)
1361 else if(expr.
id() == ID_bitor)
1363 else if(expr.
id() == ID_bitxor)
1366 for(
const auto &op : expr.
operands())
1376 expr.
id() == ID_bitxnor || expr.
id() == ID_bitnand ||
1377 expr.
id() == ID_bitnor)
1386 if(binary_expr.id() == ID_bitxnor)
1388 else if(binary_expr.id() == ID_bitnand)
1390 else if(binary_expr.id() == ID_bitnor)
1398 else if(expr.
operands().size() == 1)
1404 else if(expr.
operands().size() >= 3)
1407 if(expr.
id() == ID_bitxnor)
1409 else if(expr.
id() == ID_bitnand)
1411 else if(expr.
id() == ID_bitnor)
1414 for(
const auto &op : expr.
operands())
1426 expr.
id_string() +
" should have at least one operand");
1429 else if(expr.
id()==ID_bitnot)
1437 else if(expr.
id()==ID_unary_minus)
1440 const auto &type = expr.
type();
1443 type.id() == ID_rational || type.id() == ID_integer ||
1444 type.id() == ID_real)
1450 else if(type.id() == ID_range)
1459 else if(type.id() == ID_floatbv)
1479 else if(expr.
id()==ID_unary_plus)
1484 else if(expr.
id()==ID_sign)
1490 if(op_type.
id()==ID_floatbv)
1494 out <<
"(fp.isNegative ";
1501 else if(op_type.
id()==ID_signedbv)
1507 out <<
" (_ bv0 " << op_width <<
"))";
1512 "sign should not be applied to unsupported type",
1515 else if(expr.
id()==ID_if)
1553 else if(expr.
id()==ID_and ||
1559 "logical and, or, and xor expressions should have Boolean type");
1562 "logical and, or, and xor expressions should have at least two operands");
1564 out <<
"(" << expr.
id();
1565 for(
const auto &op : expr.
operands())
1572 else if(expr.
id() == ID_nand || expr.
id() == ID_nor || expr.
id() == ID_xnor)
1576 "logical nand, nor, xnor expressions should have Boolean type");
1579 "logical nand, nor, xnor expressions should have at least one operand");
1587 if(expr.
id() == ID_nand)
1589 else if(expr.
id() == ID_nor)
1591 else if(expr.
id() == ID_xnor)
1595 for(
const auto &op : expr.
operands())
1604 else if(expr.
id()==ID_implies)
1609 implies_expr.
is_boolean(),
"implies expression should have Boolean type");
1617 else if(expr.
id()==ID_not)
1622 not_expr.
is_boolean(),
"not expression should have Boolean type");
1628 else if(expr.
id() == ID_equal)
1634 "operands of equal expression shall have same type");
1649 else if(expr.
id() == ID_notequal)
1655 "operands of not equal expression shall have same type");
1663 else if(expr.
id()==ID_ieee_float_equal ||
1664 expr.
id()==ID_ieee_float_notequal)
1671 rel_expr.lhs().type() == rel_expr.rhs().type(),
1672 "operands of float equal and not equal expressions shall have same type");
1677 if(rel_expr.id() == ID_ieee_float_notequal)
1686 if(rel_expr.id() == ID_ieee_float_notequal)
1692 else if(expr.
id()==ID_le ||
1699 else if(expr.
id()==ID_plus)
1703 else if(expr.
id()==ID_floatbv_plus)
1707 else if(expr.
id()==ID_minus)
1711 else if(expr.
id()==ID_floatbv_minus)
1715 else if(expr.
id()==ID_div)
1719 else if(expr.
id()==ID_floatbv_div)
1723 else if(expr.
id()==ID_mod)
1727 else if(expr.
id() == ID_euclidean_mod)
1731 else if(expr.
id()==ID_mult)
1735 else if(expr.
id()==ID_floatbv_mult)
1739 else if(expr.
id() == ID_floatbv_rem)
1743 else if(expr.
id() == ID_floatbv_fma)
1747 else if(expr.
id()==ID_address_of)
1753 else if(expr.
id() == ID_array_of)
1758 array_of_expr.type().id() == ID_array,
1759 "array of expression shall have array type");
1763 out <<
"((as const ";
1771 defined_expressionst::const_iterator it =
1777 else if(expr.
id() == ID_array_comprehension)
1782 array_comprehension.type().id() == ID_array,
1783 "array_comprehension expression shall have array type");
1787 out <<
"(lambda ((";
1790 convert_type(array_comprehension.type().size().type());
1802 else if(expr.
id()==ID_index)
1806 else if(expr.
id()==ID_ashr ||
1807 expr.
id()==ID_lshr ||
1813 if(type.
id()==ID_unsignedbv ||
1814 type.
id()==ID_signedbv ||
1817 if(shift_expr.
id() == ID_ashr)
1819 else if(shift_expr.
id() == ID_lshr)
1821 else if(shift_expr.
id() == ID_shl)
1832 const auto &distance_type = shift_expr.
distance().
type();
1833 if(distance_type.id() == ID_integer || distance_type.id() == ID_natural)
1844 distance_type.id() == ID_signedbv ||
1845 distance_type.id() == ID_unsignedbv ||
1846 distance_type.id() == ID_c_enum || distance_type.id() == ID_c_bool)
1851 if(width_op0==width_op1)
1853 else if(width_op0>width_op1)
1855 out <<
"((_ zero_extend " << width_op0-width_op1 <<
") ";
1861 out <<
"((_ extract " << width_op0-1 <<
" 0) ";
1869 "unsupported distance type for " + shift_expr.
id_string() +
": " +
1870 distance_type.id_string());
1877 "unsupported type for " + shift_expr.
id_string() +
": " +
1880 else if(expr.
id() == ID_rol || expr.
id() == ID_ror)
1886 type.
id() == ID_unsignedbv || type.
id() == ID_signedbv ||
1891 if(shift_expr.
id() == ID_rol)
1892 out <<
"((_ rotate_left";
1893 else if(shift_expr.
id() == ID_ror)
1894 out <<
"((_ rotate_right";
1902 if(distance_int_op.has_value())
1904 out << distance_int_op.value();
1908 "distance type for " + shift_expr.
id_string() +
"must be constant");
1917 "unsupported type for " + shift_expr.
id_string() +
": " +
1920 else if(expr.
id() == ID_named_term)
1924 convert(named_term_expr.value());
1928 else if(expr.
id()==ID_with)
1932 else if(expr.
id()==ID_update)
1936 else if(expr.
id() == ID_update_bit)
1940 else if(expr.
id() == ID_update_bits)
1944 else if(expr.
id() == ID_object_address)
1946 out <<
"(object-address ";
1951 else if(expr.
id() == ID_element_address)
1957 auto element_size_expr_opt =
1967 *element_size_expr_opt, element_address_expr.index().type()));
1970 else if(expr.
id() == ID_field_address)
1979 else if(expr.
id()==ID_member)
1983 else if(expr.
id()==ID_pointer_offset)
1988 op.type().id() == ID_pointer,
1989 "operand of pointer offset expression shall be of pointer type");
1991 std::size_t offset_bits =
1996 if(offset_bits>result_width)
1997 offset_bits=result_width;
2000 if(result_width>offset_bits)
2001 out <<
"((_ zero_extend " << result_width-offset_bits <<
") ";
2003 out <<
"((_ extract " << offset_bits-1 <<
" 0) ";
2007 if(result_width>offset_bits)
2010 else if(expr.
id()==ID_pointer_object)
2015 op.type().id() == ID_pointer,
2016 "pointer object expressions should be of pointer type");
2022 out <<
"((_ zero_extend " << ext <<
") ";
2024 out <<
"((_ extract "
2025 << pointer_width-1 <<
" "
2026 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2033 else if(expr.
id() == ID_is_dynamic_object)
2037 else if(expr.
id() == ID_is_invalid_pointer)
2041 out <<
"(= ((_ extract "
2042 << pointer_width-1 <<
" "
2043 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2046 <<
" " <<
config.bv_encoding.object_bits <<
"))";
2048 else if(expr.
id()==ID_string_constant)
2054 else if(expr.
id()==ID_extractbit)
2063 out <<
"(= ((_ extract " << i <<
" " << i <<
") ";
2069 out <<
"(= ((_ extract 0 0) ";
2079 else if(expr.
id() == ID_onehot)
2083 else if(expr.
id() == ID_onehot0)
2087 else if(expr.
id()==ID_extractbits)
2097 out <<
"((_ extract " << (width + index_i - 1) <<
" " << index_i <<
") ";
2104 out <<
"(= ((_ extract 0 0) ";
2113 SMT2_TODO(
"smt2: extractbits with non-constant index");
2116 else if(expr.
id()==ID_replication)
2126 out <<
"((_ repeat " << times <<
") ";
2130 else if(expr.
id()==ID_byte_extract_little_endian ||
2131 expr.
id()==ID_byte_extract_big_endian)
2134 false,
"byte_extract ops should be lowered in prepare_for_convert_expr");
2136 else if(expr.
id()==ID_byte_update_little_endian ||
2137 expr.
id()==ID_byte_update_big_endian)
2140 false,
"byte_update ops should be lowered in prepare_for_convert_expr");
2142 else if(expr.
id()==ID_abs)
2148 if(type.
id()==ID_signedbv)
2152 out <<
"(ite (bvslt ";
2154 out <<
" (_ bv0 " << result_width <<
")) ";
2161 else if(type.
id()==ID_fixedbv)
2165 out <<
"(ite (bvslt ";
2167 out <<
" (_ bv0 " << result_width <<
")) ";
2174 else if(type.
id()==ID_floatbv)
2188 else if(expr.
id()==ID_isnan)
2194 if(op_type.
id()==ID_fixedbv)
2196 else if(op_type.
id()==ID_floatbv)
2200 out <<
"(fp.isNaN ";
2210 else if(expr.
id()==ID_isfinite)
2216 if(op_type.
id()==ID_fixedbv)
2218 else if(op_type.
id()==ID_floatbv)
2224 out <<
"(not (fp.isNaN ";
2228 out <<
"(not (fp.isInfinite ";
2240 else if(expr.
id()==ID_isinf)
2246 if(op_type.
id()==ID_fixedbv)
2248 else if(op_type.
id()==ID_floatbv)
2252 out <<
"(fp.isInfinite ";
2262 else if(expr.
id()==ID_isnormal)
2268 if(op_type.
id()==ID_fixedbv)
2270 else if(op_type.
id()==ID_floatbv)
2274 out <<
"(fp.isNormal ";
2287 expr.
id() == ID_overflow_result_plus ||
2288 expr.
id() == ID_overflow_result_minus)
2297 "overflow plus and overflow minus expressions shall be of Boolean type");
2300 expr.
id() == ID_overflow_result_minus;
2301 const typet &op_type = op0.type();
2304 if(op_type.
id()==ID_signedbv)
2307 out <<
"(let ((?sum (";
2308 out << (subtract?
"bvsub":
"bvadd");
2309 out <<
" ((_ sign_extend 1) ";
2312 out <<
" ((_ sign_extend 1) ";
2322 out <<
"(mk-" << smt_typename;
2327 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2332 "((_ extract " << width <<
" " << width <<
") ?sum) "
2333 "((_ extract " << (width-1) <<
" " << (width-1) <<
") ?sum)";
2343 else if(op_type.
id()==ID_unsignedbv ||
2344 op_type.
id()==ID_pointer)
2347 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2348 out <<
" ((_ zero_extend 1) ";
2351 out <<
" ((_ zero_extend 1) ";
2363 out <<
"(mk-" << smt_typename;
2364 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2368 out <<
"((_ extract " << width <<
" " << width <<
") ?sum)";
2379 "overflow check should not be performed on unsupported type",
2384 expr.
id() == ID_overflow_result_mult)
2393 "overflow mult expression shall be of Boolean type");
2398 const typet &op_type = op0.type();
2401 if(op_type.
id()==ID_signedbv)
2403 out <<
"(let ( (prod (bvmul ((_ sign_extend " << width <<
") ";
2405 out <<
") ((_ sign_extend " << width <<
") ";
2415 out <<
"(mk-" << smt_typename;
2420 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2424 out <<
"(or (bvsge prod (_ bv" <<
power(2, width-1) <<
" "
2426 out <<
" (bvslt prod (bvneg (_ bv" <<
power(2, width - 1) <<
" "
2427 << width * 2 <<
"))))";
2436 else if(op_type.
id()==ID_unsignedbv)
2438 out <<
"(let ((prod (bvmul ((_ zero_extend " << width <<
") ";
2440 out <<
") ((_ zero_extend " << width <<
") ";
2450 out <<
"(mk-" << smt_typename;
2455 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2459 out <<
"(bvuge prod (_ bv" <<
power(2, width) <<
" " << width * 2 <<
"))";
2471 "overflow check should not be performed on unsupported type",
2474 else if(expr.
id() == ID_saturating_plus || expr.
id() == ID_saturating_minus)
2476 const bool subtract = expr.
id() == ID_saturating_minus;
2477 const auto &op_type = expr.
type();
2481 if(op_type.id() == ID_signedbv)
2486 out <<
"(let ((?sum (";
2487 out << (subtract ?
"bvsub" :
"bvadd");
2488 out <<
" ((_ sign_extend 1) ";
2491 out <<
" ((_ sign_extend 1) ";
2498 << width <<
" " << width
2501 << (width - 1) <<
" " << (width - 1) <<
") ?sum)";
2505 out <<
"((_ extract " << width - 1 <<
" 0) ?sum) ";
2508 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2515 else if(op_type.id() == ID_unsignedbv)
2520 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2521 out <<
" ((_ zero_extend 1) ";
2524 out <<
" ((_ zero_extend 1) ";
2529 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2532 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2546 "saturating_plus/minus on unsupported type",
2547 op_type.id_string());
2549 else if(expr.
id()==ID_array)
2555 else if(expr.
id()==ID_literal)
2559 else if(expr.
id()==ID_forall ||
2560 expr.
id()==ID_exists)
2566 throw "MathSAT does not support quantifiers";
2568 if(quantifier_expr.
id() == ID_forall)
2570 else if(quantifier_expr.
id() == ID_exists)
2575 for(
const auto &bound : quantifier_expr.
variables())
2598 else if(expr.
id()==ID_let)
2601 const auto &variables = let_expr.
variables();
2602 const auto &values = let_expr.
values();
2607 for(
auto &binding :
make_range(variables).zip(values))
2626 else if(expr.
id()==ID_constraint_select_one)
2629 "smt2_convt::convert_expr: '" + expr.
id_string() +
2630 "' is not yet supported");
2632 else if(expr.
id() == ID_bswap)
2638 "operand of byte swap expression shall have same type as the expression");
2641 out <<
"(let ((bswap_op ";
2646 bswap_expr.
type().
id() == ID_signedbv ||
2647 bswap_expr.
type().
id() == ID_unsignedbv)
2649 const std::size_t width =
2656 width % bits_per_byte == 0,
2657 "bit width indicated by type of bswap expression should be a multiple "
2658 "of the number of bits per byte");
2660 const std::size_t bytes = width / bits_per_byte;
2669 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2673 out <<
"(bswap_byte_" <<
byte <<
' ';
2674 out <<
"((_ extract " << (
byte * bits_per_byte + (bits_per_byte - 1))
2675 <<
" " << (
byte * bits_per_byte) <<
") bswap_op)";
2684 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2685 out <<
" bswap_byte_" <<
byte;
2696 else if(expr.
id() == ID_popcount)
2700 else if(expr.
id() == ID_count_leading_zeros)
2704 else if(expr.
id() == ID_count_trailing_zeros)
2708 else if(expr.
id() == ID_find_first_set)
2712 else if(expr.
id() == ID_bitreverse)
2716 else if(expr.
id() == ID_zero_extend)
2720 else if(expr.
id() == ID_function_application)
2760 if(function_application_expr.function().id() == ID_symbol)
2764 const auto &args = function_application_expr.arguments();
2774 static const std::map<irep_idt, std::string> flat_string_ops = {
2776 {ID_cprover_string_concat_func,
"str.++"},
2777 {ID_cprover_string_length_func,
"str.len"},
2778 {ID_cprover_string_substring_func,
"str.substr"},
2779 {ID_cprover_string_char_at_func,
"str.at"},
2780 {ID_cprover_string_contains_func,
"str.contains"},
2781 {ID_cprover_string_is_prefix_func,
"str.prefixof"},
2782 {ID_cprover_string_is_suffix_func,
"str.suffixof"},
2783 {ID_cprover_string_replace_func,
"str.replace"},
2784 {ID_cprover_string_equal_func,
"="},
2786 {ID_cprover_string_to_regex_func,
"str.to_re"},
2787 {ID_cprover_string_in_regex_func,
"str.in_re"},
2788 {ID_cprover_regex_range_func,
"re.range"},
2789 {ID_cprover_regex_concat_func,
"re.++"},
2790 {ID_cprover_regex_star_func,
"re.*"},
2791 {ID_cprover_regex_plus_func,
"re.+"},
2792 {ID_cprover_regex_opt_func,
"re.opt"},
2793 {ID_cprover_regex_union_func,
"re.union"},
2794 {ID_cprover_regex_inter_func,
"re.inter"},
2795 {ID_cprover_regex_comp_func,
"re.comp"},
2796 {ID_cprover_regex_diff_func,
"re.diff"},
2797 {ID_cprover_regex_all_func,
"re.all"},
2798 {ID_cprover_regex_allchar_func,
"re.allchar"},
2799 {ID_cprover_regex_none_func,
"re.none"}};
2801 std::string smt_name;
2802 if(
auto it = flat_string_ops.find(fn_id); it != flat_string_ops.end())
2803 smt_name = it->second;
2806 const bool is_index_of = fn_id == ID_cprover_string_index_of_func;
2807 const bool is_startswith = fn_id == ID_cprover_string_startswith_func;
2808 const bool is_endswith = fn_id == ID_cprover_string_endswith_func;
2809 const bool is_is_empty = fn_id == ID_cprover_string_is_empty_func;
2810 const bool is_regex_loop = fn_id == ID_cprover_regex_loop_func;
2813 !smt_name.empty() || is_index_of || is_startswith || is_endswith ||
2814 is_is_empty || is_regex_loop)
2822 for(
const auto &arg : args)
2824 if(arg.type().id() == ID_array || arg.type().id() == ID_pointer)
2827 "string/regex built-in '" +
id2string(fn_id) +
2828 "' reached the SMT-LIB string lowering with a refined-string "
2829 "(array/pointer) operand; the refined-string representation "
2830 "requires the SAT string solver (--refine-strings)");
2839 out <<
"(str.indexof ";
2844 if(args.size() == 3)
2850 else if(is_startswith || is_endswith)
2855 out << (is_startswith ?
"(str.prefixof " :
"(str.suffixof ");
2861 else if(is_is_empty)
2869 else if(is_regex_loop)
2877 out <<
"((_ re.loop " << lo <<
' ' << hi <<
") ";
2881 else if(args.empty())
2885 out <<
'(' << smt_name;
2886 for(
const auto &arg : args)
2895 else if(function_application_expr.arguments().empty())
2903 for(
auto &op : function_application_expr.arguments())
2911 else if(expr.
id() == ID_cond)
2916 else if(expr.
id() == ID_reduction_and)
2923 else if(expr.
id() == ID_reduction_nand)
2929 else if(expr.
id() == ID_reduction_or)
2936 else if(expr.
id() == ID_reduction_nor)
2942 else if(expr.
id() == ID_reduction_xor)
2958 out <<
"(let ((?rop ";
2964 for(std::size_t i = 0; i < width; i++)
2965 out <<
" ((_ extract " << i <<
" " << i <<
") ?rop)";
2971 else if(expr.
id() == ID_reduction_xnor)
2980 "smt2_convt::convert_expr should not be applied to unsupported "
2991 if(dest_type == src.
type())
2997 if(dest_type.
id()==ID_c_enum_tag)
3001 if(src_type.
id()==ID_c_enum_tag)
3004 if(dest_type.
id()==ID_bool)
3008 src_type.
id() == ID_signedbv || src_type.
id() == ID_unsignedbv ||
3009 src_type.
id() == ID_c_bool || src_type.
id() == ID_fixedbv ||
3010 src_type.
id() == ID_pointer || src_type.
id() == ID_integer ||
3011 src_type.
id() == ID_natural || src_type.
id() == ID_rational ||
3012 src_type.
id() == ID_real)
3020 else if(src_type.
id()==ID_floatbv)
3024 out <<
"(not (fp.isZero ";
3036 else if(dest_type.
id()==ID_c_bool)
3045 out <<
" (_ bv1 " << to_width <<
")";
3046 out <<
" (_ bv0 " << to_width <<
")";
3049 else if(dest_type.
id()==ID_signedbv ||
3050 dest_type.
id()==ID_unsignedbv ||
3051 dest_type.
id()==ID_c_enum ||
3052 dest_type.
id()==ID_bv)
3056 if(src_type.
id()==ID_signedbv ||
3057 src_type.
id()==ID_unsignedbv ||
3058 src_type.
id()==ID_c_bool ||
3059 src_type.
id()==ID_c_enum ||
3060 src_type.
id()==ID_bv)
3064 if(from_width==to_width)
3066 else if(from_width<to_width)
3068 if(src_type.
id()==ID_signedbv)
3069 out <<
"((_ sign_extend ";
3071 out <<
"((_ zero_extend ";
3073 out << (to_width-from_width)
3080 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
3085 else if(src_type.
id()==ID_fixedbv)
3089 std::size_t from_width=fixedbv_type.
get_width();
3096 out <<
"(let ((?tcop ";
3102 if(to_width>from_integer_bits)
3104 out <<
"((_ sign_extend "
3105 << (to_width-from_integer_bits) <<
") ";
3106 out <<
"((_ extract " << (from_width-1) <<
" "
3107 << from_fraction_bits <<
") ";
3113 out <<
"((_ extract " << (from_fraction_bits+to_width-1)
3114 <<
" " << from_fraction_bits <<
") ";
3119 out <<
" (ite (and ";
3122 out <<
"(not (= ((_ extract " << (from_fraction_bits-1) <<
" 0) ?tcop) "
3123 "(_ bv0 " << from_fraction_bits <<
")))";
3126 out <<
" (= ((_ extract " << (from_width-1) <<
" " << (from_width-1)
3131 out <<
" (_ bv1 " << to_width <<
") (_ bv0 " << to_width <<
"))";
3135 else if(src_type.
id()==ID_floatbv)
3137 if(dest_type.
id()==ID_bv)
3143 defined_expressionst::const_iterator it =
3154 else if(dest_type.
id()==ID_signedbv)
3158 "typecast unexpected "+src_type.
id_string()+
" -> "+
3161 else if(dest_type.
id()==ID_unsignedbv)
3165 "typecast unexpected "+src_type.
id_string()+
" -> "+
3169 else if(src_type.
id()==ID_bool)
3174 if(dest_type.
id()==ID_fixedbv)
3177 out <<
" (concat (_ bv1 "
3180 "(_ bv0 " << spec.
width <<
")";
3184 out <<
" (_ bv1 " << to_width <<
")";
3185 out <<
" (_ bv0 " << to_width <<
")";
3190 else if(src_type.
id()==ID_pointer)
3194 if(from_width<to_width)
3196 out <<
"((_ sign_extend ";
3197 out << (to_width-from_width)
3204 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
3209 else if(src_type.
id() == ID_integer || src_type.
id() == ID_natural)
3215 out <<
"(_ bv" << i <<
" " << to_width <<
")";
3218 SMT2_TODO(
"can't convert non-constant integer to bitvector");
3221 src_type.
id() == ID_struct ||
3222 src_type.
id() == ID_struct_tag)
3228 "bit vector with of source and destination type shall be equal");
3235 "bit vector with of source and destination type shall be equal");
3240 src_type.
id() == ID_union ||
3241 src_type.
id() == ID_union_tag)
3245 "bit vector with of source and destination type shall be equal");
3248 else if(src_type.
id()==ID_c_bit_field)
3252 if(from_width==to_width)
3263 std::ostringstream e_str;
3264 e_str << src_type.
id() <<
" -> " << dest_type.
id()
3265 <<
" src == " <<
format(src);
3269 else if(dest_type.
id()==ID_fixedbv)
3275 if(src_type.
id()==ID_unsignedbv ||
3276 src_type.
id()==ID_signedbv ||
3277 src_type.
id()==ID_c_enum)
3284 if(from_width==to_integer_bits)
3286 else if(from_width>to_integer_bits)
3289 out <<
"((_ extract " << (to_integer_bits-1) <<
" 0) ";
3297 from_width < to_integer_bits,
3298 "from_width should be smaller than to_integer_bits as other case "
3299 "have been handled above");
3300 if(dest_type.
id()==ID_unsignedbv)
3302 out <<
"(_ zero_extend "
3303 << (to_integer_bits-from_width) <<
") ";
3309 out <<
"((_ sign_extend "
3310 << (to_integer_bits-from_width) <<
") ";
3316 out <<
"(_ bv0 " << to_fraction_bits <<
")";
3319 else if(src_type.
id()==ID_bool)
3321 out <<
"(concat (concat"
3322 <<
" (_ bv0 " << (to_integer_bits-1) <<
") ";
3328 else if(src_type.
id()==ID_fixedbv)
3333 std::size_t from_width=from_fixedbv_type.
get_width();
3335 out <<
"(let ((?tcop ";
3341 if(to_integer_bits<=from_integer_bits)
3343 out <<
"((_ extract "
3344 << (from_fraction_bits+to_integer_bits-1) <<
" "
3345 << from_fraction_bits
3351 to_integer_bits > from_integer_bits,
3352 "to_integer_bits should be greater than from_integer_bits as the"
3353 "other case has been handled above");
3354 out <<
"((_ sign_extend "
3355 << (to_integer_bits-from_integer_bits)
3357 << (from_width-1) <<
" "
3358 << from_fraction_bits
3364 if(to_fraction_bits<=from_fraction_bits)
3366 out <<
"((_ extract "
3367 << (from_fraction_bits-1) <<
" "
3368 << (from_fraction_bits-to_fraction_bits)
3374 to_fraction_bits > from_fraction_bits,
3375 "to_fraction_bits should be greater than from_fraction_bits as the"
3376 "other case has been handled above");
3377 out <<
"(concat ((_ extract "
3378 << (from_fraction_bits-1) <<
" 0) ";
3381 <<
" (_ bv0 " << to_fraction_bits-from_fraction_bits
3390 else if(dest_type.
id()==ID_pointer)
3394 if(src_type.
id()==ID_pointer)
3400 src_type.
id() == ID_unsignedbv || src_type.
id() == ID_signedbv ||
3401 src_type.
id() == ID_bv)
3407 if(from_width==to_width)
3409 else if(from_width<to_width)
3411 out <<
"((_ sign_extend "
3412 << (to_width-from_width)
3419 out <<
"((_ extract " << to_width <<
" 0) ";
3427 else if(dest_type.
id()==ID_range)
3430 const auto dest_width =
address_bits(dest_range_type.size());
3431 if(src_type.
id() == ID_range)
3434 const auto src_width =
address_bits(src_range_type.size());
3435 if(src_width < dest_width)
3437 out <<
"((_ zero_extend " << dest_width - src_width <<
") ";
3441 else if(src_width > dest_width)
3443 out <<
"((_ extract " << dest_width - 1 <<
" 0) ";
3455 else if(dest_type.
id()==ID_floatbv)
3464 if(src_type.
id()==ID_bool)
3474 else if(src_type.
id()==ID_c_bool)
3480 else if(src_type.
id() == ID_bv)
3489 out <<
"((_ to_fp " << dest_floatbv_type.get_e() <<
" "
3490 << dest_floatbv_type.get_f() + 1 <<
") ";
3500 else if(dest_type.
id() == ID_integer || dest_type.
id() == ID_natural)
3502 if(src_type.
id()==ID_bool)
3511 else if(dest_type.
id()==ID_c_bit_field)
3516 if(from_width==to_width)
3525 else if(dest_type.
id() == ID_rational)
3527 if(src_type.
id() == ID_signedbv)
3536 "Unknown typecast " + src_type.
id_string() +
" -> rational");
3550 if(dest_type.
id()==ID_floatbv)
3552 if(src_type.
id()==ID_floatbv)
3579 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3580 << dst.
get_f() + 1 <<
") ";
3589 else if(src_type.
id()==ID_unsignedbv)
3610 out <<
"((_ to_fp_unsigned " << dst.
get_e() <<
" "
3611 << dst.
get_f() + 1 <<
") ";
3620 else if(src_type.
id()==ID_signedbv)
3628 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3629 << dst.
get_f() + 1 <<
") ";
3638 else if(src_type.
id()==ID_c_enum_tag)
3652 else if(dest_type.
id()==ID_signedbv)
3657 out <<
"((_ fp.to_sbv " << dest_width <<
") ";
3666 else if(dest_type.
id()==ID_unsignedbv)
3671 out <<
"((_ fp.to_ubv " << dest_width <<
") ";
3694 out <<
"(fp.roundToIntegral ";
3707 expr.
type().
id() == ID_struct_tag
3715 components.size() == expr.
operands().size(),
3716 "number of struct components as indicated by the struct type shall be equal"
3717 "to the number of operands of the struct expression");
3719 DATA_INVARIANT(!components.empty(),
"struct shall have struct components");
3723 const std::string &smt_typename =
datatype_map.at(struct_type);
3726 out <<
"(mk-" << smt_typename;
3729 for(struct_typet::componentst::const_iterator
3730 it=components.begin();
3731 it!=components.end();
3744 auto convert_operand = [
this](
const exprt &op) {
3748 else if(op.type().id() == ID_bool)
3755 std::size_t n_concat = 0;
3756 for(std::size_t i = components.size(); i > 1; i--)
3766 convert_operand(expr.
operands()[i - 1]);
3772 convert_operand(expr.
op0());
3774 out << std::string(n_concat,
')');
3782 const auto &size_expr = array_type.
size();
3787 if(!size_expr.is_constant())
3790 "cannot flatten an array of non-constant size to a bit-vector; such an "
3791 "array can only be encoded with the SMT-LIB array theory");
3797 out <<
"(let ((?far ";
3805 out <<
"(select ?far ";
3827 if(total_width==member_width)
3835 total_width > member_width,
3836 "total_width should be greater than member_width as member_width can be"
3837 "at most as large as total_width and the other case has been handled "
3841 << (total_width-member_width) <<
") ";
3851 if(expr_type.
id()==ID_unsignedbv ||
3852 expr_type.
id()==ID_signedbv ||
3853 expr_type.
id()==ID_bv ||
3854 expr_type.
id()==ID_c_enum ||
3855 expr_type.
id()==ID_c_enum_tag ||
3856 expr_type.
id()==ID_c_bool ||
3857 expr_type.
id()==ID_c_bit_field)
3863 out <<
"(_ bv" << value
3864 <<
" " << width <<
")";
3866 else if(expr_type.
id()==ID_fixedbv)
3872 out <<
"(_ bv" << v <<
" " << spec.
width <<
")";
3874 else if(expr_type.
id()==ID_floatbv)
3887 size_t e=floatbv_type.
get_e();
3888 size_t f=floatbv_type.
get_f()+1;
3894 out <<
"((_ to_fp " << e <<
" " << f <<
")"
3900 out <<
"(_ NaN " << e <<
" " << f <<
")";
3905 out <<
"(_ -oo " << e <<
" " << f <<
")";
3907 out <<
"(_ +oo " << e <<
" " << f <<
")";
3917 <<
"#b" << binaryString.substr(0, 1) <<
" "
3918 <<
"#b" << binaryString.substr(1, e) <<
" "
3919 <<
"#b" << binaryString.substr(1+e, f-1) <<
")";
3927 out <<
"(_ bv" << v <<
" " << spec.
width() <<
")";
3930 else if(expr_type.
id()==ID_pointer)
3944 out <<
"(_ bv" << value <<
" " << width <<
")";
3947 else if(expr_type.
id()==ID_bool)
3951 else if(expr ==
false)
3956 else if(expr_type.
id()==ID_array)
3962 else if(expr_type.
id()==ID_rational)
3965 const bool negative =
has_prefix(value,
"-");
3970 value = value.substr(1);
3973 size_t pos=value.find(
"/");
3975 if(
pos==std::string::npos)
3976 out << value <<
".0";
3979 out <<
"(/ " << value.substr(0,
pos) <<
".0 "
3980 << value.substr(
pos+1) <<
".0)";
3986 else if(expr_type.
id() == ID_real)
3990 if(value.find(
'.') == std::string::npos)
3993 else if(expr_type.
id()==ID_integer)
3999 out <<
"(- " << value.substr(1, std::string::npos) <<
')';
4003 else if(expr_type.
id() == ID_natural)
4007 else if(expr_type.
id() == ID_range)
4012 out <<
"(_ bv" << (value_int - range_type.from()) <<
" " << width <<
")";
4014 else if(expr_type.
id() == ID_string)
4021 for(
char ch : value)
4023 const auto c =
static_cast<unsigned char>(ch);
4026 else if(c >= 0x20 && c <= 0x7e)
4029 out <<
"\\u{" << std::hex << static_cast<unsigned>(c) << std::dec
4040 if(expr.
type().
id() == ID_integer)
4050 "unsupported type for euclidean_mod: " + expr.
type().
id_string());
4055 if(expr.
type().
id()==ID_unsignedbv ||
4056 expr.
type().
id()==ID_signedbv)
4058 if(expr.
type().
id()==ID_unsignedbv)
4068 else if(expr.
type().
id() == ID_integer)
4074 out <<
"(let ((?ma ";
4078 out <<
")) (let ((?mr (mod (ite (< ?ma 0) (- ?ma) ?ma)";
4079 out <<
" (ite (< ?mb 0) (- ?mb) ?mb)))) (ite (< ?ma 0) (- ?mr) ?mr)))";
4081 else if(expr.
type().
id() == ID_natural)
4096 std::vector<mp_integer> dynamic_objects;
4099 if(dynamic_objects.empty())
4105 out <<
"(let ((?obj ((_ extract "
4106 << pointer_width-1 <<
" "
4107 << pointer_width-
config.bv_encoding.object_bits <<
") ";
4111 if(dynamic_objects.size()==1)
4113 out <<
"(= (_ bv" << dynamic_objects.front()
4114 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
4120 for(
const auto &
object : dynamic_objects)
4121 out <<
" (= (_ bv" <<
object
4122 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
4136 op_type.
id() == ID_unsignedbv || op_type.
id() == ID_bv ||
4137 op_type.
id() == ID_range)
4141 if(expr.
id()==ID_le)
4143 else if(expr.
id()==ID_lt)
4145 else if(expr.
id()==ID_ge)
4147 else if(expr.
id()==ID_gt)
4156 else if(op_type.
id()==ID_signedbv ||
4157 op_type.
id()==ID_fixedbv)
4160 if(expr.
id()==ID_le)
4162 else if(expr.
id()==ID_lt)
4164 else if(expr.
id()==ID_ge)
4166 else if(expr.
id()==ID_gt)
4175 else if(op_type.
id()==ID_floatbv)
4180 if(expr.
id()==ID_le)
4182 else if(expr.
id()==ID_lt)
4184 else if(expr.
id()==ID_ge)
4186 else if(expr.
id()==ID_gt)
4199 op_type.
id() == ID_rational || op_type.
id() == ID_integer ||
4200 op_type.
id() == ID_natural || op_type.
id() == ID_real)
4211 else if(op_type.
id() == ID_pointer)
4219 if(expr.
id() == ID_le)
4221 else if(expr.
id() == ID_lt)
4223 else if(expr.
id() == ID_ge)
4225 else if(expr.
id() == ID_gt)
4244 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4245 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4250 for(
const auto &op : expr.
operands())
4259 expr.
type().
id() == ID_unsignedbv || expr.
type().
id() == ID_signedbv ||
4260 expr.
type().
id() == ID_fixedbv)
4277 else if(expr.
type().
id() == ID_range)
4292 out <<
" (_ bv" << range_type.from() <<
' ' << width
4300 else if(expr.
type().
id() == ID_floatbv)
4307 else if(expr.
type().
id() == ID_pointer)
4313 if(p.
type().
id() != ID_pointer)
4317 p.
type().
id() == ID_pointer,
4318 "one of the operands should have pointer type");
4322 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4325 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
4329 out <<
"(let ((?pointerop ";
4335 const std::size_t offset_bits =
4336 pointer_width -
config.bv_encoding.object_bits;
4339 out <<
"((_ extract " << pointer_width - 1 <<
' ' << offset_bits
4340 <<
") ?pointerop) ";
4341 out <<
"(bvadd ((_ extract " << offset_bits - 1 <<
" 0) ?pointerop) ";
4343 if(element_size >= 2)
4345 out <<
"(bvmul ((_ extract " << offset_bits - 1 <<
" 0) ";
4347 out <<
") (_ bv" << element_size <<
" " << offset_bits <<
"))";
4351 out <<
"((_ extract " << offset_bits - 1 <<
" 0) ";
4390 out <<
"roundNearestTiesToEven";
4392 out <<
"roundTowardNegative";
4394 out <<
"roundTowardPositive";
4396 out <<
"roundTowardZero";
4398 out <<
"roundNearestTiesToAway";
4402 "Rounding mode should have value 0, 1, 2, 3, or 4",
4410 out <<
"(ite (= (_ bv0 " << width <<
") ";
4412 out <<
") roundNearestTiesToEven ";
4414 out <<
"(ite (= (_ bv1 " << width <<
") ";
4416 out <<
") roundTowardNegative ";
4418 out <<
"(ite (= (_ bv2 " << width <<
") ";
4420 out <<
") roundTowardPositive ";
4422 out <<
"(ite (= (_ bv3 " << width <<
") ";
4424 out <<
") roundTowardZero ";
4427 out <<
"roundNearestTiesToAway";
4438 type.
id() == ID_floatbv ||
4439 (type.
id() == ID_complex &&
4444 if(type.
id()==ID_floatbv)
4454 else if(type.
id()==ID_complex)
4461 "type should not be one of the unsupported types",
4471 expr.
type().
id() == ID_integer || expr.
type().
id() == ID_natural ||
4472 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_real)
4480 else if(expr.
type().
id()==ID_unsignedbv ||
4481 expr.
type().
id()==ID_signedbv ||
4482 expr.
type().
id()==ID_fixedbv)
4484 if(expr.
op0().
type().
id()==ID_pointer &&
4490 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4492 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
4495 if(element_size >= 2)
4500 "bitvector width of operand shall be equal to the bitvector width of "
4509 if(element_size >= 2)
4522 else if(expr.
type().
id()==ID_floatbv)
4529 else if(expr.
type().
id()==ID_pointer)
4533 (expr.
op1().
type().
id() == ID_unsignedbv ||
4545 else if(expr.
type().
id() == ID_range)
4552 out <<
"(bvsub (bvsub ";
4556 out <<
") (_ bv" << range_type.from() <<
' ' << width <<
"))";
4565 expr.
type().
id() == ID_floatbv,
4566 "type of ieee floating point expression shall be floatbv");
4584 if(expr.
type().
id()==ID_unsignedbv ||
4585 expr.
type().
id()==ID_signedbv)
4587 if(expr.
type().
id()==ID_unsignedbv)
4597 else if(expr.
type().
id()==ID_fixedbv)
4602 out <<
"((_ extract " << spec.
width-1 <<
" 0) ";
4607 out <<
" (_ bv0 " << fraction_bits <<
")) ";
4609 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4615 else if(expr.
type().
id()==ID_floatbv)
4623 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4624 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4626 if(expr.
type().
id() == ID_integer)
4631 out <<
"(let ((?da ";
4635 out <<
")) (let ((?dq (div (ite (< ?da 0) (- ?da) ?da)";
4636 out <<
" (ite (< ?db 0) (- ?db) ?db))))";
4637 out <<
" (ite (= (< ?da 0) (< ?db 0)) ?dq (- ?dq))))";
4643 if(expr.
type().
id() == ID_natural)
4660 expr.
type().
id() == ID_floatbv,
4661 "type of ieee floating point expression shall be floatbv");
4692 "expression should have been converted to a variant with two operands");
4694 if(expr.
type().
id()==ID_unsignedbv ||
4695 expr.
type().
id()==ID_signedbv)
4706 else if(expr.
type().
id()==ID_floatbv)
4713 else if(expr.
type().
id()==ID_fixedbv)
4718 out <<
"((_ extract "
4719 << spec.
width+fraction_bits-1 <<
" "
4720 << fraction_bits <<
") ";
4724 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4728 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4735 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4736 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4740 for(
const auto &op : expr.
operands())
4755 expr.
type().
id() == ID_floatbv,
4756 "type of ieee floating point expression shall be floatbv");
4775 expr.
type().
id() == ID_floatbv,
4776 "type of ieee floating point expression shall be floatbv");
4790 "smt2_convt::convert_floatbv_rem to be implemented when not using "
4798 expr.
type().
id() == ID_floatbv,
4799 "type of ieee floating point expression shall be floatbv");
4821 "with expression should have exactly three operands");
4825 if(expr_type.
id()==ID_array)
4849 out <<
"(let ((distance? ";
4850 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4854 if(array_width>index_width)
4856 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4862 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4872 out <<
"(bvshl (_ bv" <<
power(2, sub_width) - 1 <<
" " << array_width
4874 out <<
"distance?)) ";
4878 out <<
"((_ zero_extend " << array_width-sub_width <<
") ";
4880 out <<
") distance?)))";
4883 else if(expr_type.
id() == ID_struct || expr_type.
id() == ID_struct_tag)
4886 expr_type.
id() == ID_struct_tag
4893 const irep_idt &component_name=index.
get(ID_component_name);
4897 "struct should have accessed component");
4901 const std::string &smt_typename =
datatype_map.at(expr_type);
4903 out <<
"(update-" << smt_typename <<
"." << component_name <<
" ";
4911 auto convert_operand = [
this](
const exprt &op)
4916 else if(op.type().id() == ID_bool)
4928 if(m.
width==struct_width)
4931 convert_operand(value);
4935 out <<
"(let ((?withop ";
4936 convert_operand(expr.
old());
4943 <<
"((_ extract " << (struct_width - 1) <<
" " << m.
width
4945 convert_operand(value);
4952 convert_operand(value);
4953 out <<
" ((_ extract " << (m.
offset - 1) <<
" 0) ?withop))";
4958 out <<
"(concat (concat "
4959 <<
"((_ extract " << (struct_width - 1) <<
" "
4961 convert_operand(value);
4962 out <<
") ((_ extract " << (m.
offset - 1) <<
" 0) ?withop)";
4970 else if(expr_type.
id() == ID_union || expr_type.
id() == ID_union_tag)
4978 if(total_width==member_width)
4985 total_width > member_width,
4986 "total width should be greater than member_width as member_width is at "
4987 "most as large as total_width and the other case has been handled "
4990 out <<
"((_ extract "
4992 <<
" " << member_width <<
") ";
4999 else if(expr_type.
id()==ID_bv ||
5000 expr_type.
id()==ID_unsignedbv ||
5001 expr_type.
id()==ID_signedbv)
5016 "with expects struct, union, or array type, but got "+
5024 SMT2_TODO(
"smt2_convt::convert_update to be implemented");
5041 if(array_op_type.
id()==ID_array)
5076 out <<
"((_ extract " << sub_width-1 <<
" 0) ";
5080 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
5084 if(array_width>index_width)
5086 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
5092 out <<
"((_ extract " << array_width-1 <<
" 0) ";
5104 false,
"index with unsupported array type: " + array_op_type.
id_string());
5111 const typet &struct_op_type = struct_op.
type();
5114 if(struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag)
5117 struct_op_type.
id() == ID_struct_tag
5122 struct_type.
has_component(name),
"struct should have accessed component");
5126 const std::string &smt_typename =
datatype_map.at(struct_type);
5128 out <<
"(" << smt_typename <<
"."
5139 if(expr.
type().
id() == ID_bool)
5145 if(expr.
type().
id() == ID_bool)
5150 struct_op_type.
id() == ID_union || struct_op_type.
id() == ID_union_tag)
5154 width != 0,
"failed to get union member width");
5160 out <<
"((_ extract " << (width - 1) <<
" 0) ";
5168 out <<
"((_ extract " << (width - 1) <<
" 0) ";
5175 "convert_member on an unexpected type "+struct_op_type.
id_string());
5182 if(type.
id()==ID_bool)
5188 else if(type.
id()==ID_array)
5199 std::size_t n_concat = 0;
5213 out << std::string(n_concat,
')');
5218 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5231 std::size_t n_concat = 0;
5232 for(std::size_t i=components.size(); i>1; i--)
5252 out << std::string(n_concat,
')');
5257 else if(type.
id()==ID_floatbv)
5272 out <<
"(_ bv" << value <<
" " << spec.
width() <<
")";
5277 "flatten2bv of a non-constant FPA-encoded float is unsupported");
5292 if(type.
id()==ID_bool)
5299 else if(type.
id() == ID_array)
5304 out <<
"(let ((?ufop" << nesting <<
" ";
5315 "cannot unflatten arrays of non-constant size");
5326 out <<
"((as const ";
5334 "unflatten relies on `(lambda ...)` for constant arrays "
5335 "when `(as const ...)` is unavailable");
5341 out <<
"(lambda ((?ufidx" << nesting <<
" ";
5347 out <<
"((_ extract " << subtype_width - 1 <<
" "
5348 <<
"0) ?ufop" << nesting <<
")";
5352 std::size_t offset = subtype_width;
5353 for(
mp_integer i = 1; i < size; ++i, offset += subtype_width)
5358 out <<
"((_ extract " << offset + subtype_width - 1 <<
" " << offset
5359 <<
") ?ufop" << nesting <<
")";
5367 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5373 out <<
"(let ((?ufop" << nesting <<
" ";
5378 const std::string &smt_typename =
datatype_map.at(type);
5380 out <<
"(mk-" << smt_typename;
5389 std::size_t offset=0;
5392 for(struct_typet::componentst::const_iterator
5393 it=components.begin();
5394 it!=components.end();
5404 out <<
"((_ extract " << offset+member_width-1 <<
" "
5405 << offset <<
") ?ufop" << nesting <<
")";
5407 offset+=member_width;
5428 if(expr.
id()==ID_and && value)
5430 for(
const auto &op : expr.
operands())
5435 if(expr.
id()==ID_or && !value)
5437 for(
const auto &op : expr.
operands())
5442 if(expr.
id()==ID_not)
5452 if(expr.
id() == ID_equal && value)
5461 if(equal_expr.
lhs().
id()==ID_symbol)
5468 equal_expr.
lhs() != equal_expr.
rhs())
5480 out <<
"; set_to true (equal)\n";
5488 auto emit_definition_body = [&]()
5491 equal_expr.
lhs().
type().
id() != ID_array ||
5504 if(equal_expr.
lhs().
type().
id() == ID_mathematical_function)
5508 out <<
"(declare-fun " << smt2_identifier;
5510 auto &mathematical_function_type =
5516 for(
auto &t : mathematical_function_type.domain())
5530 out <<
"(assert (= " << smt2_identifier <<
' ';
5532 out <<
')' <<
')' <<
'\n';
5545 out <<
"(declare-fun " << smt2_identifier;
5549 out <<
"(assert (= " << smt2_identifier <<
' ';
5550 emit_definition_body();
5555 out <<
"(define-fun " << smt2_identifier;
5559 emit_definition_body();
5575 out <<
"; set_to " << (value?
"true":
"false") <<
"\n"
5586 out << found_literal->second;
5609 exprt lowered_expr = expr;
5616 it->id() == ID_byte_extract_little_endian ||
5617 it->id() == ID_byte_extract_big_endian)
5622 it->id() == ID_byte_update_little_endian ||
5623 it->id() == ID_byte_update_big_endian)
5629 return lowered_expr;
5646 "lower_byte_operators should remove all byte operators");
5653 auto prophecy_r_or_w_ok =
5657 it.mutate() = lowered;
5658 it.next_sibling_or_parent();
5661 auto prophecy_pointer_in_range =
5665 it.mutate() = lowered;
5666 it.next_sibling_or_parent();
5675 return lowered_expr;
5695 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
5697 std::unordered_map<irep_idt, std::optional<identifiert>> shadowed_syms;
5702 for(
const auto &symbol : q_expr.variables())
5704 const auto identifier = symbol.identifier();
5707 shadowed_syms.insert(
5709 id_entry.second ? std::nullopt
5710 : std::optional{id_entry.first->second}});
5713 for(
const auto &[
id, shadowed_val] : shadowed_syms)
5716 if(!shadowed_val.has_value())
5719 previous_entry->second = std::move(*shadowed_val);
5725 for(
const auto &op : expr.
operands())
5728 if(expr.
id()==ID_symbol ||
5729 expr.
id()==ID_nondet_symbol)
5732 if(expr.
type().
id()==ID_code)
5737 if(expr.
id()==ID_symbol)
5740 identifier=
"nondet_"+
5751 out <<
"; find_symbols\n";
5752 out <<
"(declare-fun " << smt2_identifier;
5754 if(expr.
type().
id() == ID_mathematical_function)
5756 auto &mathematical_function_type =
5761 for(
auto &type : mathematical_function_type.domain())
5785 if(expr.
type().
id() == ID_range)
5790 out <<
"(assert (bvule " << smt2_identifier <<
' ';
5797 else if(expr.
id() == ID_array_of)
5804 const auto &array_type = array_of.type();
5808 out <<
"; the following is a substitute for lambda i. x\n";
5809 out <<
"(declare-fun " <<
id <<
" () ";
5816 out <<
"(assert (forall ((i ";
5818 out <<
")) (= (select " <<
id <<
" i) ";
5836 else if(expr.
id() == ID_array_comprehension)
5843 const auto &array_type = array_comprehension.type();
5844 const auto &array_size = array_type.size();
5848 out <<
"(declare-fun " <<
id <<
" () ";
5852 out <<
"; the following is a substitute for lambda i . x(i)\n";
5853 out <<
"; universally quantified initialization of the array\n";
5854 out <<
"(assert (forall ((";
5858 out <<
")) (=> (and (bvule (_ bv0 " <<
boolbv_width(array_size.type())
5865 out <<
")) (= (select " <<
id <<
" ";
5884 else if(expr.
id()==ID_array)
5891 out <<
"; the following is a substitute for an array constructor" <<
"\n";
5892 out <<
"(declare-fun " <<
id <<
" () ";
5898 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5900 out <<
"(assert (= (select " <<
id <<
" ";
5921 else if(expr.
id()==ID_string_constant)
5931 out <<
"; the following is a substitute for a string" <<
"\n";
5932 out <<
"(declare-fun " <<
id <<
" () ";
5936 for(std::size_t i=0; i<tmp.
operands().size(); i++)
5938 out <<
"(assert (= (select " <<
id <<
' ';
5942 out <<
"))" <<
"\n";
5955 out <<
"(declare-fun " <<
id <<
" () ";
5966 (expr.
id() == ID_floatbv_plus ||
5967 expr.
id() == ID_floatbv_minus ||
5968 expr.
id() == ID_floatbv_mult ||
5969 expr.
id() == ID_floatbv_div ||
5970 expr.
id() == ID_floatbv_fma ||
5971 expr.
id() == ID_floatbv_typecast ||
5972 expr.
id() == ID_ieee_float_equal ||
5973 expr.
id() == ID_ieee_float_notequal ||
5974 ((expr.
id() == ID_lt ||
5975 expr.
id() == ID_gt ||
5976 expr.
id() == ID_le ||
5977 expr.
id() == ID_ge ||
5978 expr.
id() == ID_isnan ||
5979 expr.
id() == ID_isnormal ||
5980 expr.
id() == ID_isfinite ||
5981 expr.
id() == ID_isinf ||
5982 expr.
id() == ID_sign ||
5983 expr.
id() == ID_unary_minus ||
5984 expr.
id() == ID_typecast ||
5985 expr.
id() == ID_abs) &&
5992 if(
bvfp_set.insert(function).second)
5994 out <<
"; this is a model for " << expr.
id() <<
" : "
5997 <<
"(define-fun " << function <<
" (";
5999 for(std::size_t i = 0; i < expr.
operands().size(); i++)
6003 out <<
"(op" << i <<
' ';
6013 for(std::size_t i = 0; i < tmp1.
operands().size(); i++)
6029 expr.
type().
id() == ID_bv)
6039 out <<
"(declare-fun " <<
id <<
" () ";
6045 out <<
"(assert (= ";
6046 out <<
"((_ to_fp " << floatbv_type.get_e() <<
" "
6047 << floatbv_type.get_f() + 1 <<
") " <<
id <<
')';
6055 else if(expr.
id() == ID_initial_state)
6057 irep_idt function =
"initial-state";
6061 out <<
"(declare-fun " << function <<
" (";
6068 else if(expr.
id() == ID_evaluate)
6074 out <<
"(declare-fun " << function <<
" (";
6084 expr.
id() == ID_state_is_cstring ||
6085 expr.
id() == ID_state_is_dynamic_object ||
6086 expr.
id() == ID_state_live_object || expr.
id() == ID_state_writeable_object)
6089 expr.
id() == ID_state_is_cstring ?
"state-is-cstring"
6090 : expr.
id() == ID_state_is_dynamic_object ?
"state-is-dynamic-object"
6091 : expr.
id() == ID_state_live_object ?
"state-live-object"
6092 :
"state-writeable-object";
6096 out <<
"(declare-fun " << function <<
" (";
6106 expr.
id() == ID_state_r_ok || expr.
id() == ID_state_w_ok ||
6107 expr.
id() == ID_state_rw_ok)
6109 irep_idt function = expr.
id() == ID_state_r_ok ?
"state-r-ok"
6110 : expr.
id() == ID_state_w_ok ?
"state-w-ok"
6115 out <<
"(declare-fun " << function <<
" (";
6126 else if(expr.
id() == ID_update_state)
6133 out <<
"(declare-fun " << function <<
" (";
6144 else if(expr.
id() == ID_enter_scope_state)
6151 out <<
"(declare-fun " << function <<
" (";
6162 else if(expr.
id() == ID_exit_scope_state)
6169 out <<
"(declare-fun " << function <<
" (";
6178 else if(expr.
id() == ID_allocate)
6184 out <<
"(declare-fun " << function <<
" (";
6193 else if(expr.
id() == ID_reallocate)
6199 out <<
"(declare-fun " << function <<
" (";
6210 else if(expr.
id() == ID_deallocate_state)
6216 out <<
"(declare-fun " << function <<
" (";
6225 else if(expr.
id() == ID_object_address)
6227 irep_idt function =
"object-address";
6231 out <<
"(declare-fun " << function <<
" (String) ";
6236 else if(expr.
id() == ID_field_address)
6242 out <<
"(declare-fun " << function <<
" (";
6251 else if(expr.
id() == ID_element_address)
6257 out <<
"(declare-fun " << function <<
" (";
6276 if(expr.
id() == ID_with)
6278 else if(expr.
id() == ID_if)
6314 if(type.
id()==ID_array)
6327 out <<
"(_ BitVec 1)";
6333 else if(type.
id()==ID_bool)
6337 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
6347 out <<
"(_ BitVec " << width <<
")";
6350 else if(type.
id()==ID_code)
6357 else if(type.
id() == ID_union || type.
id() == ID_union_tag)
6364 union_type.
components().empty() || width != 0,
6365 "failed to get width of union");
6367 out <<
"(_ BitVec " << width <<
")";
6369 else if(type.
id()==ID_pointer)
6374 else if(type.
id()==ID_bv ||
6375 type.
id()==ID_fixedbv ||
6376 type.
id()==ID_unsignedbv ||
6377 type.
id()==ID_signedbv ||
6378 type.
id()==ID_c_bool)
6383 else if(type.
id()==ID_c_enum)
6390 else if(type.
id()==ID_c_enum_tag)
6394 else if(type.
id()==ID_floatbv)
6399 out <<
"(_ FloatingPoint "
6400 << floatbv_type.
get_e() <<
" "
6401 << floatbv_type.
get_f() + 1 <<
")";
6406 else if(type.
id()==ID_rational ||
6409 else if(type.
id()==ID_integer)
6411 else if(type.
id() == ID_natural)
6413 else if(type.
id()==ID_complex)
6423 out <<
"(_ BitVec " << width <<
")";
6426 else if(type.
id()==ID_c_bit_field)
6430 else if(type.
id() == ID_state)
6434 else if(type.
id() == ID_range)
6437 if(range_type.empty())
6441 else if(type.
id() == ID_string)
6443 else if(type.
id() == ID_regex)
6453 std::set<irep_idt> recstack;
6459 std::set<irep_idt> &recstack)
6461 if(type.
id()==ID_array)
6467 else if(type.
id()==ID_complex)
6474 const std::string smt_typename =
6478 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6479 <<
"(((mk-" << smt_typename;
6481 out <<
" (" << smt_typename <<
".imag ";
6485 out <<
" (" << smt_typename <<
".real ";
6492 else if(type.
id() == ID_struct)
6495 bool need_decl=
false;
6499 const std::string smt_typename =
6514 const std::string &smt_typename =
datatype_map.at(type);
6525 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6526 <<
"(((mk-" << smt_typename <<
" ";
6533 out <<
"(" << smt_typename <<
"." <<
component.get_name()
6539 out <<
"))))" <<
"\n";
6556 for(struct_union_typet::componentst::const_iterator
6557 it=components.begin();
6558 it!=components.end();
6565 out <<
"(define-fun update-" << smt_typename <<
"."
6567 <<
"((s " << smt_typename <<
") "
6570 out <<
")) " << smt_typename <<
" "
6571 <<
"(mk-" << smt_typename
6574 for(struct_union_typet::componentst::const_iterator
6575 it2=components.begin();
6576 it2!=components.end();
6583 out <<
"(" << smt_typename <<
"."
6584 << it2->get_name() <<
" s) ";
6588 out <<
"))" <<
"\n";
6594 else if(type.
id() == ID_union)
6602 else if(type.
id()==ID_code)
6606 for(
const auto ¶m : parameters)
6611 else if(type.
id()==ID_pointer)
6615 else if(type.
id() == ID_struct_tag)
6618 const irep_idt &
id = struct_tag.get_identifier();
6620 if(recstack.find(
id) == recstack.end())
6622 const auto &base_struct =
ns.follow_tag(struct_tag);
6623 recstack.insert(
id);
6628 else if(type.
id() == ID_union_tag)
6631 const irep_idt &
id = union_tag.get_identifier();
6633 if(recstack.find(
id) == recstack.end())
6635 recstack.insert(
id);
6639 else if(type.
id() == ID_state)
6644 out <<
"(declare-sort state 0)\n";
6647 else if(type.
id() == ID_mathematical_function)
6649 const auto &mathematical_function_type =
6651 for(
auto &d_type : mathematical_function_type.domain())
API to expression classes for bitvectors.
const onehot0_exprt & to_onehot0_expr(const exprt &expr)
Cast an exprt to a onehot0_exprt.
const replication_exprt & to_replication_expr(const exprt &expr)
Cast an exprt to a replication_exprt.
const reduction_xnor_exprt & to_reduction_xnor_expr(const exprt &expr)
Cast an exprt to a reduction_xnor_exprt.
const reduction_nand_exprt & to_reduction_nand_expr(const exprt &expr)
Cast an exprt to a reduction_nand_exprt.
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
const reduction_and_exprt & to_reduction_and_expr(const exprt &expr)
Cast an exprt to a reduction_and_exprt.
const reduction_or_exprt & to_reduction_or_expr(const exprt &expr)
Cast an exprt to a reduction_or_exprt.
const popcount_exprt & to_popcount_expr(const exprt &expr)
Cast an exprt to a popcount_exprt.
const update_bits_exprt & to_update_bits_expr(const exprt &expr)
Cast an exprt to an update_bits_exprt.
const extractbits_exprt & to_extractbits_expr(const exprt &expr)
Cast an exprt to an extractbits_exprt.
const onehot_exprt & to_onehot_expr(const exprt &expr)
Cast an exprt to a onehot_exprt.
bool can_cast_expr< minus_overflow_exprt >(const exprt &base)
const find_first_set_exprt & to_find_first_set_expr(const exprt &expr)
Cast an exprt to a find_first_set_exprt.
bool can_cast_expr< overflow_result_exprt >(const exprt &base)
const update_bit_exprt & to_update_bit_expr(const exprt &expr)
Cast an exprt to an update_bit_exprt.
const bitnot_exprt & to_bitnot_expr(const exprt &expr)
Cast an exprt to a bitnot_exprt.
const bswap_exprt & to_bswap_expr(const exprt &expr)
Cast an exprt to a bswap_exprt.
const count_leading_zeros_exprt & to_count_leading_zeros_expr(const exprt &expr)
Cast an exprt to a count_leading_zeros_exprt.
const reduction_xor_exprt & to_reduction_xor_expr(const exprt &expr)
Cast an exprt to a reduction_xor_exprt.
const bitreverse_exprt & to_bitreverse_expr(const exprt &expr)
Cast an exprt to a bitreverse_exprt.
const extractbit_exprt & to_extractbit_expr(const exprt &expr)
Cast an exprt to an extractbit_exprt.
const reduction_nor_exprt & to_reduction_nor_expr(const exprt &expr)
Cast an exprt to a reduction_nor_exprt.
const zero_extend_exprt & to_zero_extend_expr(const exprt &expr)
Cast an exprt to a zero_extend_exprt.
const count_trailing_zeros_exprt & to_count_trailing_zeros_expr(const exprt &expr)
Cast an exprt to a count_trailing_zeros_exprt.
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
bool has_byte_operator(const exprt &src)
Return true iff src or one of its operands contain a byte extract or byte update expression.
Expression classes for byte-level operators.
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
Rewrite a byte extract expression to more fundamental operations.
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
Rewrite a byte update expression to more fundamental operations.
typet c_bit_field_replacement_type(const c_bit_field_typet &src, const namespacet &ns)
unsignedbv_typet size_type()
pointer_typet pointer_type(const typet &subtype)
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const c_bool_typet & to_c_bool_type(const typet &type)
Cast a typet to a c_bool_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Operator to return the address of an object.
Represents real numbers as roots (zeros) of a polynomial with rational coefficients.
constant_exprt as_expr() const
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Pointer-typed bitvector constant annotated with the pointer expression that the bitvector is the nume...
Array constructor from list of elements.
typet index_type() const
The type of the index expressions into any instance of this type.
const exprt & size() const
const typet & element_type() const
The type of the elements of the array.
A base class for binary expressions.
A base class for relations, i.e., binary predicates whose two operands have the same type.
Bit-wise negation of bit-vectors.
constant_exprt all_zeros_expr() const
constant_exprt all_ones_expr() const
std::size_t get_width() const
The byte swap expression.
std::size_t get_bits_per_byte() const
std::vector< parametert > parameterst
const parameterst & parameters() const
A constant literal expression.
const irep_idt & get_value() const
bool is_null_pointer() const
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
resultt
Result of running the decision procedure.
Boute's Euclidean definition of Modulo – to match SMT-LIB2.
Base class for all expressions.
std::vector< exprt > operandst
bool has_operands() const
Return true if there is at least one operand.
depth_iteratort depth_end()
bool is_boolean() const
Return whether the expression represents a Boolean.
depth_iteratort depth_begin()
bool is_constant() const
Return whether the expression is a constant.
typet & type()
Return the type of the expression.
void visit_post(std::function< void(exprt &)>)
These are post-order traversal visitors, i.e., the visitor is executed on a node after its children h...
The Boolean constant false.
std::size_t get_fraction_bits() const
Fixed-width bit-vector with signed fixed-point interpretation.
std::size_t get_fraction_bits() const
std::size_t get_integer_bits() const
Fused multiply-add expression: round(op0 * op1 + op2) with a single rounding.
exprt & op_multiply_lhs()
exprt & op_multiply_rhs()
Round a floating-point number to an integral value considering the given rounding mode.
Semantic type conversion from/to floating-point formats.
Fixed-width bit-vector with IEEE floating-point interpretation.
std::size_t get_f() const
std::size_t get_e() const
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
std::size_t width() const
An IEEE 754 floating-point value, including specificiation.
static ieee_float_valuet minus_infinity(const ieee_float_spect &_spec)
static ieee_float_valuet one(const floatbv_typet &)
constant_exprt to_expr() const
static ieee_float_valuet zero(const floatbv_typet &type)
static ieee_float_valuet NaN(const ieee_float_spect &_spec)
static ieee_float_valuet plus_infinity(const ieee_float_spect &_spec)
The trinary if-then-else operator.
There are a large number of kinds of tree structured or tree-like data in CPROVER.
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const irep_idt & get(const irep_idt &name) const
const std::string & id_string() const
const irep_idt & id() const
Evaluates to true if the operand is finite.
Evaluates to true if the operand is infinite.
Evaluates to true if the operand is NaN.
Evaluates to true if the operand is a normal number.
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
exprt & where()
convenience accessor for binding().where()
literalt get_literal() const
Extract member of struct or union.
const exprt & struct_op() const
irep_idt get_component_name() const
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Binary multiplication Associativity is not specified.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
const irep_idt & get_identifier() const
Expression for finding the size (in bytes) of the object a pointer points to.
The plus expression Associativity is not specified.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
A base class for quantifier expressions.
Unbounded, signed rational numbers.
Boolean reduction: true iff every bit of the operand is 1.
Boolean reduction: true iff any bit of the operand is 1.
Boolean reduction: XOR (parity) of all bits in the operand.
A base class for shift and rotate operators.
Sign of an expression Predicate is true if _op is negative, false otherwise.
const irep_idt & get_identifier() const
void convert_relation(const binary_relation_exprt &)
bool use_lambda_for_array
void convert_type(const typet &)
void unflatten(wheret, const typet &, unsigned nesting=0)
bool use_array_theory(const exprt &)
void find_symbols(const exprt &expr)
Find and declare symbols used in an expression This function traverses the expression tree and create...
std::size_t number_of_solver_calls
void convert_typecast(const typecast_exprt &expr)
void write_footer()
Writes the end of the SMT file to the smt_convt::out stream.
tvt l_get(literalt l) const
void convert_floatbv_rem(const binary_exprt &expr)
std::unordered_map< irep_idt, irept > current_bindings
resultt dec_solve(const exprt &) override
Implementation of the decision procedure.
std::set< irep_idt > bvfp_set
void convert_address_of_rec(const exprt &expr, const pointer_typet &result_type)
void push() override
Unimplemented.
void convert_is_dynamic_object(const unary_exprt &)
void convert_literal(const literalt)
void convert_floatbv_div(const ieee_float_op_exprt &expr)
void convert_string_literal(const std::string &)
std::size_t get_number_of_solver_calls() const override
Return the number of incremental solver calls.
void convert_floatbv_mult(const ieee_float_op_exprt &expr)
boolbv_widtht boolbv_width
void convert_constant(const constant_exprt &expr)
std::string floatbv_suffix(const exprt &) const
void flatten2bv(const exprt &)
void convert_floatbv_fma(const floatbv_fma_exprt &expr)
void convert_div(const div_exprt &expr)
exprt lower_byte_operators(const exprt &expr)
Lower byte_update and byte_extract operations within expr.
std::string type2id(const typet &) const
void convert_rounding_mode_FPA(const exprt &expr)
Converting a constant or symbolic rounding mode to SMT-LIB.
void convert_floatbv_typecast(const floatbv_typecast_exprt &expr)
struct_exprt parse_struct(const irept &s, const struct_typet &type)
void convert_mult(const mult_exprt &expr)
void convert_update_bit(const update_bit_exprt &)
exprt prepare_for_convert_expr(const exprt &expr)
Perform steps necessary before an expression is passed to convert_expr.
exprt get(const exprt &expr) const override
Return expr with variables replaced by values from satisfying assignment if available.
std::string decision_procedure_text() const override
Return a textual description of the decision procedure.
void convert_floatbv_minus(const ieee_float_op_exprt &expr)
bool use_check_sat_assuming
std::map< object_size_exprt, irep_idt > object_sizes
void define_object_size(const irep_idt &id, const object_size_exprt &expr)
datatype_mapt datatype_map
void convert_mod(const mod_exprt &expr)
static std::string convert_identifier(const irep_idt &identifier)
void convert_floatbv_plus(const ieee_float_op_exprt &expr)
void convert_struct(const struct_exprt &expr)
std::unordered_map< irep_idt, bool > set_values
The values which boolean identifiers have been smt2_convt::set_to or in other words those which are a...
smt2_convt(const namespacet &_ns, const std::string &_benchmark, const std::string &_notes, const std::string &_logic, solvert _solver, std::ostream &_out)
void convert_member(const member_exprt &expr)
void convert_euclidean_mod(const euclidean_mod_exprt &expr)
void convert_index(const index_exprt &expr)
pointer_logict pointer_logic
exprt handle(const exprt &expr) override
Generate a handle, which is an expression that has the same value as the argument in any model that i...
void print_assignment(std::ostream &out) const override
Print satisfying assignment to out.
void walk_array_tree(std::unordered_map< int64_t, exprt > *operands_map, const irept &src, const array_typet &type)
This function walks the SMT output and populates a map with index/value pairs for the array.
void convert_floatbv_round_to_integral(const floatbv_round_to_integral_exprt &)
void set_to(const exprt &expr, bool value) override
For a Boolean expression expr, add the constraint 'expr' if value is true, otherwise add 'not expr'.
exprt parse_rec(const irept &s, const typet &type)
void convert_union(const union_exprt &expr)
exprt parse_union(const irept &s, const union_typet &type)
exprt parse_array(const irept &s, const array_typet &type)
This function is for parsing array output from SMT solvers when "(get-value |???|)" returns an array ...
std::vector< bool > boolean_assignment
void flatten_array(const exprt &)
produce a flat bit-vector for a given array of fixed size
void convert_with(const with_exprt &expr)
std::vector< literalt > assumptions
void convert_plus(const plus_exprt &expr)
defined_expressionst defined_expressions
void pop() override
Currently, only implements a single stack element (no nested contexts).
void convert_update_bits(const update_bits_exprt &)
void find_symbols_rec(const typet &type, std::set< irep_idt > &recstack)
void convert_update(const update_exprt &)
std::set< irep_idt > state_fkt_declared
identifier_mapt identifier_map
void convert_minus(const minus_exprt &expr)
void convert_expr(const exprt &)
constant_exprt parse_literal(const irept &, const typet &type)
const smt2_symbolt & to_smt2_symbol(const exprt &expr)
std::size_t no_boolean_variables
smt2_identifierst smt2_identifiers
void convert_floatbv(const exprt &expr)
literalt convert(const exprt &expr)
array_exprt to_array_expr() const
convert string into array constant
Struct constructor from list of elements.
Structure type, corresponds to C style structs.
const irep_idt & get_name() const
const componentst & components() const
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
bool has_component(const irep_idt &component_name) const
std::vector< componentt > componentst
const irep_idt & get_identifier() const
void identifier(const irep_idt &identifier)
The Boolean constant true.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
Generic base class for unary expressions.
The unary minus expression.
Union constructor from single element.
Fixed-width bit-vector with unsigned binary interpretation.
Thrown when we encounter an instruction, parameters to an instruction etc.
Replaces a sub-range of a bit-vector operand.
exprt lower() const
A lowering to masking, shifting, or.
Replaces a sub-range of a bit-vector operand.
exprt lower() const
A lowering to masking, shifting, or.
Operator to update elements in structs and arrays.
Operator to update elements in structs and arrays.
bool has_prefix(const std::string &s, const std::string &prefix)
bool can_cast_expr(const exprt &base)
Check whether a reference to a generic exprt is of a specific derived class.
auto expr_try_dynamic_cast(TExpr &base) -> typename detail::expr_try_dynamic_cast_return_typet< T, TExpr >::type
Try to cast a reference to a generic exprt to a specific derived class.
Forward depth-first search iterators These iterators' copy operations are expensive,...
exprt make_binary(const exprt &expr)
splits an expression with >=3 operands into nested binary expressions
Deprecated expression utility functions.
exprt float_bv(const exprt &src)
API to expression classes for floating-point arithmetic.
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
const floatbv_fma_exprt & to_floatbv_fma_expr(const exprt &expr)
const floatbv_round_to_integral_exprt & to_floatbv_round_to_integral_expr(const exprt &expr)
Cast an exprt to a floatbv_round_to_integral_exprt.
const isnormal_exprt & to_isnormal_expr(const exprt &expr)
Cast an exprt to a isnormal_exprt.
const isinf_exprt & to_isinf_expr(const exprt &expr)
Cast an exprt to a isinf_exprt.
const isfinite_exprt & to_isfinite_expr(const exprt &expr)
Cast an exprt to a isfinite_exprt.
const isnan_exprt & to_isnan_expr(const exprt &expr)
Cast an exprt to a isnan_exprt.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
const std::string & id2string(const irep_idt &d)
static std::string binary(const constant_exprt &src)
exprt to_expr(const namespacet &ns, const irep_idt &identifier, const std::string &src)
bool is_true(const literalt &l)
literalt const_literal(bool value)
const literal_exprt & to_literal_expr(const exprt &expr)
Cast a generic exprt to a literal_exprt.
API to expression classes for 'mathematical' expressions.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
const integer_range_typet & to_integer_range_type(const typet &type)
Cast a typet to a integer_range_typet.
const mathematical_function_typet & to_mathematical_function_type(const typet &type)
Cast a typet to a mathematical_function_typet.
const mp_integer string2integer(const std::string &n, unsigned base)
mp_integer bitwise_or(const mp_integer &a, const mp_integer &b)
bitwise 'or' of two nonnegative integers
const std::string integer2binary(const mp_integer &n, std::size_t width)
const element_address_exprt & to_element_address_expr(const exprt &expr)
Cast an exprt to an element_address_exprt.
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
bool is_zero_width(const typet &type, const namespacet &ns)
Returns true iff type has effective width of zero bits.
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
exprt pointer_offset(const exprt &pointer)
exprt object_size(const exprt &pointer)
exprt same_object(const exprt &p1, const exprt &p2)
Various predicates over pointers in programs.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
exprt simplify_expr(exprt src, const namespacet &ns)
static bool has_quantifier(const exprt &expr)
static bool is_smt2_simple_identifier(const std::string &identifier)
#define UNEXPECTEDCASE(S)
bool is_smt2_simple_symbol_character(char ch)
Tokenizer for the SMT-LIB v2.6 syntax.
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Same as invariant, with one or more diagnostics attached Diagnostics can be of any type that has a sp...
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
#define CHECK_RETURN_WITH_DIAGNOSTICS(CONDITION,...)
#define DATA_INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
#define UNREACHABLE_BECAUSE(REASON)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
API to expression classes.
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
const array_of_exprt & to_array_of_expr(const exprt &expr)
Cast an exprt to an array_of_exprt.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
const unary_plus_exprt & to_unary_plus_expr(const exprt &expr)
Cast an exprt to a unary_plus_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const mod_exprt & to_mod_expr(const exprt &expr)
Cast an exprt to a mod_exprt.
const mult_exprt & to_mult_expr(const exprt &expr)
Cast an exprt to a mult_exprt.
const array_comprehension_exprt & to_array_comprehension_expr(const exprt &expr)
Cast an exprt to a array_comprehension_exprt.
const ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
const named_term_exprt & to_named_term_expr(const exprt &expr)
Cast an exprt to a named_term_exprt.
const cond_exprt & to_cond_expr(const exprt &expr)
Cast an exprt to a cond_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const div_exprt & to_div_expr(const exprt &expr)
Cast an exprt to a div_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const notequal_exprt & to_notequal_expr(const exprt &expr)
Cast an exprt to an notequal_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const minus_exprt & to_minus_expr(const exprt &expr)
Cast an exprt to a minus_exprt.
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
const update_exprt & to_update_expr(const exprt &expr)
Cast an exprt to an update_exprt.
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
const nondet_symbol_exprt & to_nondet_symbol_expr(const exprt &expr)
Cast an exprt to a nondet_symbol_exprt.
const sign_exprt & to_sign_expr(const exprt &expr)
Cast an exprt to a sign_exprt.
const euclidean_mod_exprt & to_euclidean_mod_expr(const exprt &expr)
Cast an exprt to a euclidean_mod_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
std::size_t unsafe_string2size_t(const std::string &str, int base)
const string_constantt & to_string_constant(const exprt &expr)
static bool failed(bool error_indicator)