54#define UNEXPECTEDCASE(S) PRECONDITION_WITH_DIAGNOSTICS(false, S);
57#define SMT2_TODO(S) PRECONDITION_WITH_DIAGNOSTICS(false, "TODO: " S)
61 const std::string &_benchmark,
62 const std::string &_notes,
63 const std::string &_logic,
172 "variable number shall be within bounds");
178 out <<
"; SMT 2" <<
"\n";
187 out <<
"; Generated for the CPROVER SMT2 solver\n";
break;
197 out <<
"(set-info :source \"" <<
notes <<
"\")" <<
"\n";
199 out <<
"(set-option :produce-models true)" <<
"\n";
205 out <<
"(set-logic " <<
logic <<
")" <<
"\n";
220 out <<
"(check-sat-assuming (";
230 out <<
"; assumptions\n";
241 out <<
"(check-sat)\n";
252 out <<
"(get-value (" <<
id <<
"))"
260 out <<
"; end of SMT2 file"
267 if(type.
id() == ID_empty)
269 else if(type.
id() == ID_struct_tag)
271 else if(type.
id() == ID_union_tag)
273 else if(type.
id() == ID_struct || type.
id() == ID_union)
298 std::size_t number = 0;
299 std::size_t h=pointer_width-1;
300 std::size_t l=pointer_width-
config.bv_encoding.object_bits;
304 const typet &type = o.type();
308 (o.id() != ID_symbol && o.id() != ID_string_constant) ||
309 !size_expr.has_value())
316 out <<
"(assert (=> (= "
317 <<
"((_ extract " << h <<
" " << l <<
") ";
319 out <<
") (_ bv" << number <<
" " <<
config.bv_encoding.object_bits <<
"))"
320 <<
"(= " <<
id <<
" ";
345 if(expr.
id()==ID_symbol)
352 return it->second.value;
355 else if(expr.
id()==ID_nondet_symbol)
362 return it->second.value;
364 else if(expr.
id() == ID_literal)
372 else if(expr.
id() == ID_not)
382 (!expr.
has_operands() && (expr.
id() == ID_struct || expr.
id() == ID_array)))
394 op = std::move(eval_op);
429 if(s.size()>=2 && s[0]==
'#' && s[1]==
'b')
434 else if(s.size()>=2 && s[0]==
'#' && s[1]==
'x')
441 std::size_t
pos = s.find(
".");
442 if(
pos != std::string::npos)
445 if(type.
id() == ID_rational)
453 else if(type.
id() == ID_real)
464 "smt2_convt::parse_literal parsed a number with a decimal point "
473 else if(src.
get_sub().size()==2 &&
478 else if(src.
get_sub().size()==3 &&
481 src.
get_sub()[1].id_string().substr(0, 2)==
"bv")
486 type.
id() == ID_rational && src.
get_sub().size() == 3 &&
497 else if(src.
get_sub().size()==4 &&
500 if(type.
id()==ID_floatbv)
515 s1_int << (floatbv_type.
get_e() + floatbv_type.
get_f()),
521 else if(src.
get_sub().size()==4 &&
530 else if(src.
get_sub().size()==4 &&
539 else if(src.
get_sub().size()==4 &&
549 src.
get_sub()[0].id() ==
"root-obj")
557 src.
get_sub()[1].id().empty() && src.
get_sub()[1].get_sub().size() == 3 &&
558 src.
get_sub()[1].get_sub()[0].id() ==
"+" &&
560 "unexpected root-obj expression",
567 !
failed,
"failed to parse rational constant coefficient", src.
pretty());
571 sum_lhs.
get_sub()[0].id() ==
"^" && sum_lhs.
get_sub()[1].id() ==
"x",
572 "unexpected first operand to root-obj",
576 degree > 0,
"polynomial degree must be positive", src.
pretty());
577 std::vector<rationalt> coefficients{degree + 1,
rationalt{}};
578 coefficients.front() = constant_coeff;
584 if(type.
id()==ID_signedbv ||
585 type.
id()==ID_unsignedbv ||
586 type.
id()==ID_c_enum ||
587 type.
id()==ID_c_bool)
591 else if(type.
id()==ID_c_enum_tag)
597 result.
type() = type;
600 else if(type.
id()==ID_fixedbv ||
601 type.
id()==ID_floatbv)
607 type.
id() == ID_integer || type.
id() == ID_natural ||
608 type.
id() == ID_rational || type.
id() == ID_real)
612 else if(type.
id() == ID_range)
618 "smt2_convt::parse_literal should not be of unsupported type " +
626 std::unordered_map<int64_t, exprt> operands_map;
630 auto maybe_default_op = operands_map.find(-1);
632 if(maybe_default_op == operands_map.end())
635 default_op = maybe_default_op->second;
638 if(maybe_size.has_value())
640 while(i < maybe_size.value())
642 auto found_op = operands_map.find(i);
643 if(found_op != operands_map.end())
644 operands.emplace_back(found_op->second);
646 operands.emplace_back(default_op);
654 auto found_op = operands_map.find(i);
655 while(found_op != operands_map.end())
657 operands.emplace_back(found_op->second);
659 found_op = operands_map.find(i);
661 operands.emplace_back(default_op);
667 std::unordered_map<int64_t, exprt> *operands_map,
680 bool failure =
to_integer(index_constant, tempint);
683 long index = tempint.to_long();
685 operands_map->emplace(index, value);
687 else if(src.
get_sub().size()==2 &&
688 src.
get_sub()[0].get_sub().size()==3 &&
689 src.
get_sub()[0].get_sub()[0].id()==
"as" &&
690 src.
get_sub()[0].get_sub()[1].id()==
"const")
694 operands_map->emplace(-1, default_value);
727 if(components.empty())
735 for(std::size_t i=0; i<components.size(); i++)
745 src.
get_sub().size() > j,
"insufficient number of component values");
762 std::size_t offset=0;
764 for(std::size_t i=0; i<components.size(); i++)
769 std::size_t component_width=
boolbv_width(components[i].type());
772 offset + component_width <= total_width,
773 "struct component bits shall be within struct bit vector");
775 std::string component_binary=
777 total_width-offset-component_width, component_width);
782 offset+=component_width;
796 for(
const auto &binding : src.
get_sub()[1].get_sub())
798 const irep_idt &name = binding.get_sub()[0].id();
809 return parse_rec(bindings_it->second, type);
813 type.
id() == ID_signedbv || type.
id() == ID_unsignedbv ||
814 type.
id() == ID_integer || type.
id() == ID_rational ||
815 type.
id() == ID_natural || type.
id() == ID_real || type.
id() == ID_c_enum ||
816 type.
id() == ID_c_enum_tag || type.
id() == ID_fixedbv ||
817 type.
id() == ID_floatbv || type.
id() == ID_c_bool || type.
id() == ID_range)
821 else if(type.
id()==ID_bool)
823 if(src.
id()==ID_1 || src.
id()==ID_true)
825 else if(src.
id()==ID_0 || src.
id()==ID_false)
828 else if(type.
id()==ID_pointer)
843 else if(type.
id()==ID_struct)
847 else if(type.
id() == ID_struct_tag)
852 struct_expr.type() = type;
853 return std::move(struct_expr);
855 else if(type.
id()==ID_union)
859 else if(type.
id() == ID_union_tag)
863 union_expr.type() = type;
866 else if(type.
id()==ID_array)
880 expr.
id() == ID_string_constant || expr.
id() == ID_label)
882 const std::size_t object_bits =
config.bv_encoding.object_bits;
883 const std::size_t max_objects = std::size_t(1) << object_bits;
886 if(object_id >= max_objects)
889 "too many addressed objects: maximum number of objects is set to 2^n=" +
890 std::to_string(max_objects) +
891 " (with n=" + std::to_string(object_bits) +
"); " +
892 "use the `--object-bits n` option to increase the maximum number"};
895 out <<
"(concat (_ bv" << object_id <<
" " << object_bits <<
")"
896 <<
" (_ bv0 " <<
boolbv_width(result_type) - object_bits <<
"))";
898 else if(expr.
id()==ID_index)
907 if(array.
type().
id()==ID_pointer)
909 else if(array.
type().
id()==ID_array)
929 else if(expr.
id()==ID_member)
934 const typet &struct_op_type = struct_op.
type();
937 struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag,
938 "member expression operand shall have struct type");
941 struct_op_type.
id() == ID_struct_tag
958 else if(expr.
id()==ID_if)
973 "operand of address of expression should not be of kind " +
981 if(node.
id() == ID_exists || node.
id() == ID_forall)
995 else if(expr ==
false)
997 else if(expr.
id()==ID_literal)
1009 out <<
"; convert\n";
1010 out <<
"; Converting var_no " << l.
var_no() <<
" with expr ID of "
1020 out <<
"(declare-fun ";
1022 out <<
" () Bool)\n";
1023 out <<
"(assert (= ";
1035 out <<
"(define-fun " << identifier <<
" () Bool ";
1063 const auto identifier =
1085 for(
auto &assumption : _assumptions)
1096 if(identifier.empty())
1099 if(isdigit(identifier[0]))
1121 std::string result =
"|";
1123 for(
auto ch : identifier)
1131 result+=std::to_string(ch);
1148 if(type.
id()==ID_floatbv)
1151 return "f"+std::to_string(spec.
width())+
"_"+std::to_string(spec.
f);
1153 else if(type.
id() == ID_bv)
1157 else if(type.
id()==ID_unsignedbv)
1161 else if(type.
id()==ID_c_bool)
1165 else if(type.
id()==ID_signedbv)
1169 else if(type.
id()==ID_bool)
1173 else if(type.
id()==ID_c_enum_tag)
1177 else if(type.
id() == ID_pointer)
1181 else if(type.
id() == ID_struct_tag)
1188 else if(type.
id() == ID_union_tag)
1192 else if(type.
id() == ID_array)
1213 if(expr.
id()==ID_symbol)
1220 if(expr.
id()==ID_smt2_symbol)
1228 !expr.
operands().empty(),
"non-symbol expressions shall have operands");
1234 for(
const auto &op : expr.
operands())
1262 converter_result->second(expr);
1267 if(expr.
id()==ID_symbol)
1273 else if(expr.
id()==ID_nondet_symbol)
1276 DATA_INVARIANT(!
id.empty(),
"nondet symbol must have identifier");
1279 else if(expr.
id()==ID_smt2_symbol)
1285 else if(expr.
id()==ID_typecast)
1289 else if(expr.
id()==ID_floatbv_typecast)
1293 else if(expr.
id() == ID_floatbv_round_to_integral)
1297 else if(expr.
id()==ID_struct)
1301 else if(expr.
id()==ID_union)
1309 else if(expr.
id() == ID_concatenation)
1313 "concatenation expression should have at least one operand",
1324 for(
const auto &op : expr.
operands())
1338 expr.
id() == ID_bitand || expr.
id() == ID_bitor || expr.
id() == ID_bitxor)
1342 "given expression should have at least one operand",
1353 if(expr.
id() == ID_concatenation)
1355 else if(expr.
id() == ID_bitand)
1357 else if(expr.
id() == ID_bitor)
1359 else if(expr.
id() == ID_bitxor)
1362 for(
const auto &op : expr.
operands())
1372 expr.
id() == ID_bitxnor || expr.
id() == ID_bitnand ||
1373 expr.
id() == ID_bitnor)
1382 if(binary_expr.id() == ID_bitxnor)
1384 else if(binary_expr.id() == ID_bitnand)
1386 else if(binary_expr.id() == ID_bitnor)
1394 else if(expr.
operands().size() == 1)
1400 else if(expr.
operands().size() >= 3)
1403 if(expr.
id() == ID_bitxnor)
1405 else if(expr.
id() == ID_bitnand)
1407 else if(expr.
id() == ID_bitnor)
1410 for(
const auto &op : expr.
operands())
1422 expr.
id_string() +
" should have at least one operand");
1425 else if(expr.
id()==ID_bitnot)
1433 else if(expr.
id()==ID_unary_minus)
1436 const auto &type = expr.
type();
1439 type.id() == ID_rational || type.id() == ID_integer ||
1440 type.id() == ID_real)
1446 else if(type.id() == ID_range)
1455 else if(type.id() == ID_floatbv)
1475 else if(expr.
id()==ID_unary_plus)
1480 else if(expr.
id()==ID_sign)
1486 if(op_type.
id()==ID_floatbv)
1490 out <<
"(fp.isNegative ";
1497 else if(op_type.
id()==ID_signedbv)
1503 out <<
" (_ bv0 " << op_width <<
"))";
1508 "sign should not be applied to unsupported type",
1511 else if(expr.
id()==ID_if)
1549 else if(expr.
id()==ID_and ||
1555 "logical and, or, and xor expressions should have Boolean type");
1558 "logical and, or, and xor expressions should have at least two operands");
1560 out <<
"(" << expr.
id();
1561 for(
const auto &op : expr.
operands())
1568 else if(expr.
id() == ID_nand || expr.
id() == ID_nor || expr.
id() == ID_xnor)
1572 "logical nand, nor, xnor expressions should have Boolean type");
1575 "logical nand, nor, xnor expressions should have at least one operand");
1583 if(expr.
id() == ID_nand)
1585 else if(expr.
id() == ID_nor)
1587 else if(expr.
id() == ID_xnor)
1591 for(
const auto &op : expr.
operands())
1600 else if(expr.
id()==ID_implies)
1605 implies_expr.
is_boolean(),
"implies expression should have Boolean type");
1613 else if(expr.
id()==ID_not)
1618 not_expr.
is_boolean(),
"not expression should have Boolean type");
1624 else if(expr.
id() == ID_equal)
1630 "operands of equal expression shall have same type");
1645 else if(expr.
id() == ID_notequal)
1651 "operands of not equal expression shall have same type");
1659 else if(expr.
id()==ID_ieee_float_equal ||
1660 expr.
id()==ID_ieee_float_notequal)
1667 rel_expr.lhs().type() == rel_expr.rhs().type(),
1668 "operands of float equal and not equal expressions shall have same type");
1673 if(rel_expr.id() == ID_ieee_float_notequal)
1682 if(rel_expr.id() == ID_ieee_float_notequal)
1688 else if(expr.
id()==ID_le ||
1695 else if(expr.
id()==ID_plus)
1699 else if(expr.
id()==ID_floatbv_plus)
1703 else if(expr.
id()==ID_minus)
1707 else if(expr.
id()==ID_floatbv_minus)
1711 else if(expr.
id()==ID_div)
1715 else if(expr.
id()==ID_floatbv_div)
1719 else if(expr.
id()==ID_mod)
1723 else if(expr.
id() == ID_euclidean_mod)
1727 else if(expr.
id()==ID_mult)
1731 else if(expr.
id()==ID_floatbv_mult)
1735 else if(expr.
id() == ID_floatbv_rem)
1739 else if(expr.
id() == ID_floatbv_fma)
1743 else if(expr.
id()==ID_address_of)
1749 else if(expr.
id() == ID_array_of)
1754 array_of_expr.type().id() == ID_array,
1755 "array of expression shall have array type");
1759 out <<
"((as const ";
1767 defined_expressionst::const_iterator it =
1773 else if(expr.
id() == ID_array_comprehension)
1778 array_comprehension.type().id() == ID_array,
1779 "array_comprehension expression shall have array type");
1783 out <<
"(lambda ((";
1786 convert_type(array_comprehension.type().size().type());
1798 else if(expr.
id()==ID_index)
1802 else if(expr.
id()==ID_ashr ||
1803 expr.
id()==ID_lshr ||
1809 if(type.
id()==ID_unsignedbv ||
1810 type.
id()==ID_signedbv ||
1813 if(shift_expr.
id() == ID_ashr)
1815 else if(shift_expr.
id() == ID_lshr)
1817 else if(shift_expr.
id() == ID_shl)
1828 const auto &distance_type = shift_expr.
distance().
type();
1829 if(distance_type.id() == ID_integer || distance_type.id() == ID_natural)
1840 distance_type.id() == ID_signedbv ||
1841 distance_type.id() == ID_unsignedbv ||
1842 distance_type.id() == ID_c_enum || distance_type.id() == ID_c_bool)
1847 if(width_op0==width_op1)
1849 else if(width_op0>width_op1)
1851 out <<
"((_ zero_extend " << width_op0-width_op1 <<
") ";
1857 out <<
"((_ extract " << width_op0-1 <<
" 0) ";
1865 "unsupported distance type for " + shift_expr.
id_string() +
": " +
1866 distance_type.id_string());
1873 "unsupported type for " + shift_expr.
id_string() +
": " +
1876 else if(expr.
id() == ID_rol || expr.
id() == ID_ror)
1882 type.
id() == ID_unsignedbv || type.
id() == ID_signedbv ||
1887 if(shift_expr.
id() == ID_rol)
1888 out <<
"((_ rotate_left";
1889 else if(shift_expr.
id() == ID_ror)
1890 out <<
"((_ rotate_right";
1898 if(distance_int_op.has_value())
1900 out << distance_int_op.value();
1904 "distance type for " + shift_expr.
id_string() +
"must be constant");
1913 "unsupported type for " + shift_expr.
id_string() +
": " +
1916 else if(expr.
id() == ID_named_term)
1920 convert(named_term_expr.value());
1924 else if(expr.
id()==ID_with)
1928 else if(expr.
id()==ID_update)
1932 else if(expr.
id() == ID_update_bit)
1936 else if(expr.
id() == ID_update_bits)
1940 else if(expr.
id() == ID_object_address)
1942 out <<
"(object-address ";
1947 else if(expr.
id() == ID_element_address)
1953 auto element_size_expr_opt =
1963 *element_size_expr_opt, element_address_expr.index().type()));
1966 else if(expr.
id() == ID_field_address)
1975 else if(expr.
id()==ID_member)
1979 else if(expr.
id()==ID_pointer_offset)
1984 op.type().id() == ID_pointer,
1985 "operand of pointer offset expression shall be of pointer type");
1987 std::size_t offset_bits =
1992 if(offset_bits>result_width)
1993 offset_bits=result_width;
1996 if(result_width>offset_bits)
1997 out <<
"((_ zero_extend " << result_width-offset_bits <<
") ";
1999 out <<
"((_ extract " << offset_bits-1 <<
" 0) ";
2003 if(result_width>offset_bits)
2006 else if(expr.
id()==ID_pointer_object)
2011 op.type().id() == ID_pointer,
2012 "pointer object expressions should be of pointer type");
2018 out <<
"((_ zero_extend " << ext <<
") ";
2020 out <<
"((_ extract "
2021 << pointer_width-1 <<
" "
2022 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2029 else if(expr.
id() == ID_is_dynamic_object)
2033 else if(expr.
id() == ID_is_invalid_pointer)
2037 out <<
"(= ((_ extract "
2038 << pointer_width-1 <<
" "
2039 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2042 <<
" " <<
config.bv_encoding.object_bits <<
"))";
2044 else if(expr.
id()==ID_string_constant)
2050 else if(expr.
id()==ID_extractbit)
2059 out <<
"(= ((_ extract " << i <<
" " << i <<
") ";
2065 out <<
"(= ((_ extract 0 0) ";
2075 else if(expr.
id() == ID_onehot)
2079 else if(expr.
id() == ID_onehot0)
2083 else if(expr.
id()==ID_extractbits)
2093 out <<
"((_ extract " << (width + index_i - 1) <<
" " << index_i <<
") ";
2100 out <<
"(= ((_ extract 0 0) ";
2109 SMT2_TODO(
"smt2: extractbits with non-constant index");
2112 else if(expr.
id()==ID_replication)
2122 out <<
"((_ repeat " << times <<
") ";
2126 else if(expr.
id()==ID_byte_extract_little_endian ||
2127 expr.
id()==ID_byte_extract_big_endian)
2130 false,
"byte_extract ops should be lowered in prepare_for_convert_expr");
2132 else if(expr.
id()==ID_byte_update_little_endian ||
2133 expr.
id()==ID_byte_update_big_endian)
2136 false,
"byte_update ops should be lowered in prepare_for_convert_expr");
2138 else if(expr.
id()==ID_abs)
2144 if(type.
id()==ID_signedbv)
2148 out <<
"(ite (bvslt ";
2150 out <<
" (_ bv0 " << result_width <<
")) ";
2157 else if(type.
id()==ID_fixedbv)
2161 out <<
"(ite (bvslt ";
2163 out <<
" (_ bv0 " << result_width <<
")) ";
2170 else if(type.
id()==ID_floatbv)
2184 else if(expr.
id()==ID_isnan)
2190 if(op_type.
id()==ID_fixedbv)
2192 else if(op_type.
id()==ID_floatbv)
2196 out <<
"(fp.isNaN ";
2206 else if(expr.
id()==ID_isfinite)
2212 if(op_type.
id()==ID_fixedbv)
2214 else if(op_type.
id()==ID_floatbv)
2220 out <<
"(not (fp.isNaN ";
2224 out <<
"(not (fp.isInfinite ";
2236 else if(expr.
id()==ID_isinf)
2242 if(op_type.
id()==ID_fixedbv)
2244 else if(op_type.
id()==ID_floatbv)
2248 out <<
"(fp.isInfinite ";
2258 else if(expr.
id()==ID_isnormal)
2264 if(op_type.
id()==ID_fixedbv)
2266 else if(op_type.
id()==ID_floatbv)
2270 out <<
"(fp.isNormal ";
2283 expr.
id() == ID_overflow_result_plus ||
2284 expr.
id() == ID_overflow_result_minus)
2293 "overflow plus and overflow minus expressions shall be of Boolean type");
2296 expr.
id() == ID_overflow_result_minus;
2297 const typet &op_type = op0.type();
2300 if(op_type.
id()==ID_signedbv)
2303 out <<
"(let ((?sum (";
2304 out << (subtract?
"bvsub":
"bvadd");
2305 out <<
" ((_ sign_extend 1) ";
2308 out <<
" ((_ sign_extend 1) ";
2318 out <<
"(mk-" << smt_typename;
2323 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2328 "((_ extract " << width <<
" " << width <<
") ?sum) "
2329 "((_ extract " << (width-1) <<
" " << (width-1) <<
") ?sum)";
2339 else if(op_type.
id()==ID_unsignedbv ||
2340 op_type.
id()==ID_pointer)
2343 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2344 out <<
" ((_ zero_extend 1) ";
2347 out <<
" ((_ zero_extend 1) ";
2359 out <<
"(mk-" << smt_typename;
2360 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2364 out <<
"((_ extract " << width <<
" " << width <<
") ?sum)";
2375 "overflow check should not be performed on unsupported type",
2380 expr.
id() == ID_overflow_result_mult)
2389 "overflow mult expression shall be of Boolean type");
2394 const typet &op_type = op0.type();
2397 if(op_type.
id()==ID_signedbv)
2399 out <<
"(let ( (prod (bvmul ((_ sign_extend " << width <<
") ";
2401 out <<
") ((_ sign_extend " << width <<
") ";
2411 out <<
"(mk-" << smt_typename;
2416 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2420 out <<
"(or (bvsge prod (_ bv" <<
power(2, width-1) <<
" "
2422 out <<
" (bvslt prod (bvneg (_ bv" <<
power(2, width - 1) <<
" "
2423 << width * 2 <<
"))))";
2432 else if(op_type.
id()==ID_unsignedbv)
2434 out <<
"(let ((prod (bvmul ((_ zero_extend " << width <<
") ";
2436 out <<
") ((_ zero_extend " << width <<
") ";
2446 out <<
"(mk-" << smt_typename;
2451 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2455 out <<
"(bvuge prod (_ bv" <<
power(2, width) <<
" " << width * 2 <<
"))";
2467 "overflow check should not be performed on unsupported type",
2470 else if(expr.
id() == ID_saturating_plus || expr.
id() == ID_saturating_minus)
2472 const bool subtract = expr.
id() == ID_saturating_minus;
2473 const auto &op_type = expr.
type();
2477 if(op_type.id() == ID_signedbv)
2482 out <<
"(let ((?sum (";
2483 out << (subtract ?
"bvsub" :
"bvadd");
2484 out <<
" ((_ sign_extend 1) ";
2487 out <<
" ((_ sign_extend 1) ";
2494 << width <<
" " << width
2497 << (width - 1) <<
" " << (width - 1) <<
") ?sum)";
2501 out <<
"((_ extract " << width - 1 <<
" 0) ?sum) ";
2504 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2511 else if(op_type.id() == ID_unsignedbv)
2516 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2517 out <<
" ((_ zero_extend 1) ";
2520 out <<
" ((_ zero_extend 1) ";
2525 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2528 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2542 "saturating_plus/minus on unsupported type",
2543 op_type.id_string());
2545 else if(expr.
id()==ID_array)
2551 else if(expr.
id()==ID_literal)
2555 else if(expr.
id()==ID_forall ||
2556 expr.
id()==ID_exists)
2562 throw "MathSAT does not support quantifiers";
2564 if(quantifier_expr.
id() == ID_forall)
2566 else if(quantifier_expr.
id() == ID_exists)
2571 for(
const auto &bound : quantifier_expr.
variables())
2594 else if(expr.
id()==ID_let)
2597 const auto &variables = let_expr.
variables();
2598 const auto &values = let_expr.
values();
2603 for(
auto &binding :
make_range(variables).zip(values))
2622 else if(expr.
id()==ID_constraint_select_one)
2625 "smt2_convt::convert_expr: '" + expr.
id_string() +
2626 "' is not yet supported");
2628 else if(expr.
id() == ID_bswap)
2634 "operand of byte swap expression shall have same type as the expression");
2637 out <<
"(let ((bswap_op ";
2642 bswap_expr.
type().
id() == ID_signedbv ||
2643 bswap_expr.
type().
id() == ID_unsignedbv)
2645 const std::size_t width =
2652 width % bits_per_byte == 0,
2653 "bit width indicated by type of bswap expression should be a multiple "
2654 "of the number of bits per byte");
2656 const std::size_t bytes = width / bits_per_byte;
2665 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2669 out <<
"(bswap_byte_" <<
byte <<
' ';
2670 out <<
"((_ extract " << (
byte * bits_per_byte + (bits_per_byte - 1))
2671 <<
" " << (
byte * bits_per_byte) <<
") bswap_op)";
2680 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2681 out <<
" bswap_byte_" <<
byte;
2692 else if(expr.
id() == ID_popcount)
2696 else if(expr.
id() == ID_count_leading_zeros)
2700 else if(expr.
id() == ID_count_trailing_zeros)
2704 else if(expr.
id() == ID_find_first_set)
2708 else if(expr.
id() == ID_bitreverse)
2712 else if(expr.
id() == ID_zero_extend)
2716 else if(expr.
id() == ID_function_application)
2720 if(function_application_expr.arguments().empty())
2728 for(
auto &op : function_application_expr.arguments())
2736 else if(expr.
id() == ID_cond)
2744 "smt2_convt::convert_expr should not be applied to unsupported "
2755 if(dest_type == src.
type())
2761 if(dest_type.
id()==ID_c_enum_tag)
2765 if(src_type.
id()==ID_c_enum_tag)
2768 if(dest_type.
id()==ID_bool)
2772 src_type.
id() == ID_signedbv || src_type.
id() == ID_unsignedbv ||
2773 src_type.
id() == ID_c_bool || src_type.
id() == ID_fixedbv ||
2774 src_type.
id() == ID_pointer || src_type.
id() == ID_integer ||
2775 src_type.
id() == ID_natural || src_type.
id() == ID_rational ||
2776 src_type.
id() == ID_real)
2784 else if(src_type.
id()==ID_floatbv)
2788 out <<
"(not (fp.isZero ";
2800 else if(dest_type.
id()==ID_c_bool)
2809 out <<
" (_ bv1 " << to_width <<
")";
2810 out <<
" (_ bv0 " << to_width <<
")";
2813 else if(dest_type.
id()==ID_signedbv ||
2814 dest_type.
id()==ID_unsignedbv ||
2815 dest_type.
id()==ID_c_enum ||
2816 dest_type.
id()==ID_bv)
2820 if(src_type.
id()==ID_signedbv ||
2821 src_type.
id()==ID_unsignedbv ||
2822 src_type.
id()==ID_c_bool ||
2823 src_type.
id()==ID_c_enum ||
2824 src_type.
id()==ID_bv)
2828 if(from_width==to_width)
2830 else if(from_width<to_width)
2832 if(src_type.
id()==ID_signedbv)
2833 out <<
"((_ sign_extend ";
2835 out <<
"((_ zero_extend ";
2837 out << (to_width-from_width)
2844 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2849 else if(src_type.
id()==ID_fixedbv)
2853 std::size_t from_width=fixedbv_type.
get_width();
2860 out <<
"(let ((?tcop ";
2866 if(to_width>from_integer_bits)
2868 out <<
"((_ sign_extend "
2869 << (to_width-from_integer_bits) <<
") ";
2870 out <<
"((_ extract " << (from_width-1) <<
" "
2871 << from_fraction_bits <<
") ";
2877 out <<
"((_ extract " << (from_fraction_bits+to_width-1)
2878 <<
" " << from_fraction_bits <<
") ";
2883 out <<
" (ite (and ";
2886 out <<
"(not (= ((_ extract " << (from_fraction_bits-1) <<
" 0) ?tcop) "
2887 "(_ bv0 " << from_fraction_bits <<
")))";
2890 out <<
" (= ((_ extract " << (from_width-1) <<
" " << (from_width-1)
2895 out <<
" (_ bv1 " << to_width <<
") (_ bv0 " << to_width <<
"))";
2899 else if(src_type.
id()==ID_floatbv)
2901 if(dest_type.
id()==ID_bv)
2907 defined_expressionst::const_iterator it =
2918 else if(dest_type.
id()==ID_signedbv)
2922 "typecast unexpected "+src_type.
id_string()+
" -> "+
2925 else if(dest_type.
id()==ID_unsignedbv)
2929 "typecast unexpected "+src_type.
id_string()+
" -> "+
2933 else if(src_type.
id()==ID_bool)
2938 if(dest_type.
id()==ID_fixedbv)
2941 out <<
" (concat (_ bv1 "
2944 "(_ bv0 " << spec.
width <<
")";
2948 out <<
" (_ bv1 " << to_width <<
")";
2949 out <<
" (_ bv0 " << to_width <<
")";
2954 else if(src_type.
id()==ID_pointer)
2958 if(from_width<to_width)
2960 out <<
"((_ sign_extend ";
2961 out << (to_width-from_width)
2968 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2973 else if(src_type.
id() == ID_integer || src_type.
id() == ID_natural)
2979 out <<
"(_ bv" << i <<
" " << to_width <<
")";
2982 SMT2_TODO(
"can't convert non-constant integer to bitvector");
2985 src_type.
id() == ID_struct ||
2986 src_type.
id() == ID_struct_tag)
2992 "bit vector with of source and destination type shall be equal");
2999 "bit vector with of source and destination type shall be equal");
3004 src_type.
id() == ID_union ||
3005 src_type.
id() == ID_union_tag)
3009 "bit vector with of source and destination type shall be equal");
3012 else if(src_type.
id()==ID_c_bit_field)
3016 if(from_width==to_width)
3027 std::ostringstream e_str;
3028 e_str << src_type.
id() <<
" -> " << dest_type.
id()
3029 <<
" src == " <<
format(src);
3033 else if(dest_type.
id()==ID_fixedbv)
3039 if(src_type.
id()==ID_unsignedbv ||
3040 src_type.
id()==ID_signedbv ||
3041 src_type.
id()==ID_c_enum)
3048 if(from_width==to_integer_bits)
3050 else if(from_width>to_integer_bits)
3053 out <<
"((_ extract " << (to_integer_bits-1) <<
" 0) ";
3061 from_width < to_integer_bits,
3062 "from_width should be smaller than to_integer_bits as other case "
3063 "have been handled above");
3064 if(dest_type.
id()==ID_unsignedbv)
3066 out <<
"(_ zero_extend "
3067 << (to_integer_bits-from_width) <<
") ";
3073 out <<
"((_ sign_extend "
3074 << (to_integer_bits-from_width) <<
") ";
3080 out <<
"(_ bv0 " << to_fraction_bits <<
")";
3083 else if(src_type.
id()==ID_bool)
3085 out <<
"(concat (concat"
3086 <<
" (_ bv0 " << (to_integer_bits-1) <<
") ";
3092 else if(src_type.
id()==ID_fixedbv)
3097 std::size_t from_width=from_fixedbv_type.
get_width();
3099 out <<
"(let ((?tcop ";
3105 if(to_integer_bits<=from_integer_bits)
3107 out <<
"((_ extract "
3108 << (from_fraction_bits+to_integer_bits-1) <<
" "
3109 << from_fraction_bits
3115 to_integer_bits > from_integer_bits,
3116 "to_integer_bits should be greater than from_integer_bits as the"
3117 "other case has been handled above");
3118 out <<
"((_ sign_extend "
3119 << (to_integer_bits-from_integer_bits)
3121 << (from_width-1) <<
" "
3122 << from_fraction_bits
3128 if(to_fraction_bits<=from_fraction_bits)
3130 out <<
"((_ extract "
3131 << (from_fraction_bits-1) <<
" "
3132 << (from_fraction_bits-to_fraction_bits)
3138 to_fraction_bits > from_fraction_bits,
3139 "to_fraction_bits should be greater than from_fraction_bits as the"
3140 "other case has been handled above");
3141 out <<
"(concat ((_ extract "
3142 << (from_fraction_bits-1) <<
" 0) ";
3145 <<
" (_ bv0 " << to_fraction_bits-from_fraction_bits
3154 else if(dest_type.
id()==ID_pointer)
3158 if(src_type.
id()==ID_pointer)
3164 src_type.
id() == ID_unsignedbv || src_type.
id() == ID_signedbv ||
3165 src_type.
id() == ID_bv)
3171 if(from_width==to_width)
3173 else if(from_width<to_width)
3175 out <<
"((_ sign_extend "
3176 << (to_width-from_width)
3183 out <<
"((_ extract " << to_width <<
" 0) ";
3191 else if(dest_type.
id()==ID_range)
3194 const auto dest_size =
3195 dest_range_type.get_to() - dest_range_type.get_from() + 1;
3197 if(src_type.
id() == ID_range)
3200 const auto src_size =
3201 src_range_type.get_to() - src_range_type.get_from() + 1;
3203 if(src_width < dest_width)
3205 out <<
"((_ zero_extend " << dest_width - src_width <<
") ";
3209 else if(src_width > dest_width)
3211 out <<
"((_ extract " << dest_width - 1 <<
" 0) ";
3223 else if(dest_type.
id()==ID_floatbv)
3232 if(src_type.
id()==ID_bool)
3242 else if(src_type.
id()==ID_c_bool)
3248 else if(src_type.
id() == ID_bv)
3257 out <<
"((_ to_fp " << dest_floatbv_type.get_e() <<
" "
3258 << dest_floatbv_type.get_f() + 1 <<
") ";
3268 else if(dest_type.
id() == ID_integer || dest_type.
id() == ID_natural)
3270 if(src_type.
id()==ID_bool)
3279 else if(dest_type.
id()==ID_c_bit_field)
3284 if(from_width==to_width)
3293 else if(dest_type.
id() == ID_rational)
3295 if(src_type.
id() == ID_signedbv)
3304 "Unknown typecast " + src_type.
id_string() +
" -> rational");
3318 if(dest_type.
id()==ID_floatbv)
3320 if(src_type.
id()==ID_floatbv)
3347 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3348 << dst.
get_f() + 1 <<
") ";
3357 else if(src_type.
id()==ID_unsignedbv)
3378 out <<
"((_ to_fp_unsigned " << dst.
get_e() <<
" "
3379 << dst.
get_f() + 1 <<
") ";
3388 else if(src_type.
id()==ID_signedbv)
3396 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3397 << dst.
get_f() + 1 <<
") ";
3406 else if(src_type.
id()==ID_c_enum_tag)
3420 else if(dest_type.
id()==ID_signedbv)
3425 out <<
"((_ fp.to_sbv " << dest_width <<
") ";
3434 else if(dest_type.
id()==ID_unsignedbv)
3439 out <<
"((_ fp.to_ubv " << dest_width <<
") ";
3462 out <<
"(fp.roundToIntegral ";
3475 expr.
type().
id() == ID_struct_tag
3483 components.size() == expr.
operands().size(),
3484 "number of struct components as indicated by the struct type shall be equal"
3485 "to the number of operands of the struct expression");
3487 DATA_INVARIANT(!components.empty(),
"struct shall have struct components");
3491 const std::string &smt_typename =
datatype_map.at(struct_type);
3494 out <<
"(mk-" << smt_typename;
3497 for(struct_typet::componentst::const_iterator
3498 it=components.begin();
3499 it!=components.end();
3512 auto convert_operand = [
this](
const exprt &op) {
3516 else if(op.type().id() == ID_bool)
3523 std::size_t n_concat = 0;
3524 for(std::size_t i = components.size(); i > 1; i--)
3534 convert_operand(expr.
operands()[i - 1]);
3540 convert_operand(expr.
op0());
3542 out << std::string(n_concat,
')');
3550 const auto &size_expr = array_type.
size();
3556 out <<
"(let ((?far ";
3564 out <<
"(select ?far ";
3586 if(total_width==member_width)
3594 total_width > member_width,
3595 "total_width should be greater than member_width as member_width can be"
3596 "at most as large as total_width and the other case has been handled "
3600 << (total_width-member_width) <<
") ";
3610 if(expr_type.
id()==ID_unsignedbv ||
3611 expr_type.
id()==ID_signedbv ||
3612 expr_type.
id()==ID_bv ||
3613 expr_type.
id()==ID_c_enum ||
3614 expr_type.
id()==ID_c_enum_tag ||
3615 expr_type.
id()==ID_c_bool ||
3616 expr_type.
id()==ID_c_bit_field)
3622 out <<
"(_ bv" << value
3623 <<
" " << width <<
")";
3625 else if(expr_type.
id()==ID_fixedbv)
3631 out <<
"(_ bv" << v <<
" " << spec.
width <<
")";
3633 else if(expr_type.
id()==ID_floatbv)
3646 size_t e=floatbv_type.
get_e();
3647 size_t f=floatbv_type.
get_f()+1;
3653 out <<
"((_ to_fp " << e <<
" " << f <<
")"
3659 out <<
"(_ NaN " << e <<
" " << f <<
")";
3664 out <<
"(_ -oo " << e <<
" " << f <<
")";
3666 out <<
"(_ +oo " << e <<
" " << f <<
")";
3676 <<
"#b" << binaryString.substr(0, 1) <<
" "
3677 <<
"#b" << binaryString.substr(1, e) <<
" "
3678 <<
"#b" << binaryString.substr(1+e, f-1) <<
")";
3686 out <<
"(_ bv" << v <<
" " << spec.
width() <<
")";
3689 else if(expr_type.
id()==ID_pointer)
3703 out <<
"(_ bv" << value <<
" " << width <<
")";
3706 else if(expr_type.
id()==ID_bool)
3710 else if(expr ==
false)
3715 else if(expr_type.
id()==ID_array)
3721 else if(expr_type.
id()==ID_rational)
3724 const bool negative =
has_prefix(value,
"-");
3729 value = value.substr(1);
3732 size_t pos=value.find(
"/");
3734 if(
pos==std::string::npos)
3735 out << value <<
".0";
3738 out <<
"(/ " << value.substr(0,
pos) <<
".0 "
3739 << value.substr(
pos+1) <<
".0)";
3745 else if(expr_type.
id() == ID_real)
3749 if(value.find(
'.') == std::string::npos)
3752 else if(expr_type.
id()==ID_integer)
3758 out <<
"(- " << value.substr(1, std::string::npos) <<
')';
3762 else if(expr_type.
id() == ID_natural)
3766 else if(expr_type.
id() == ID_range)
3769 const auto size = range_type.get_to() - range_type.get_from() + 1;
3772 out <<
"(_ bv" << (value_int - range_type.get_from()) <<
" " << width
3781 if(expr.
type().
id() == ID_integer)
3791 "unsupported type for euclidean_mod: " + expr.
type().
id_string());
3796 if(expr.
type().
id()==ID_unsignedbv ||
3797 expr.
type().
id()==ID_signedbv)
3799 if(expr.
type().
id()==ID_unsignedbv)
3815 std::vector<mp_integer> dynamic_objects;
3818 if(dynamic_objects.empty())
3824 out <<
"(let ((?obj ((_ extract "
3825 << pointer_width-1 <<
" "
3826 << pointer_width-
config.bv_encoding.object_bits <<
") ";
3830 if(dynamic_objects.size()==1)
3832 out <<
"(= (_ bv" << dynamic_objects.front()
3833 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3839 for(
const auto &
object : dynamic_objects)
3840 out <<
" (= (_ bv" <<
object
3841 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3855 op_type.
id() == ID_unsignedbv || op_type.
id() == ID_bv ||
3856 op_type.
id() == ID_range)
3860 if(expr.
id()==ID_le)
3862 else if(expr.
id()==ID_lt)
3864 else if(expr.
id()==ID_ge)
3866 else if(expr.
id()==ID_gt)
3875 else if(op_type.
id()==ID_signedbv ||
3876 op_type.
id()==ID_fixedbv)
3879 if(expr.
id()==ID_le)
3881 else if(expr.
id()==ID_lt)
3883 else if(expr.
id()==ID_ge)
3885 else if(expr.
id()==ID_gt)
3894 else if(op_type.
id()==ID_floatbv)
3899 if(expr.
id()==ID_le)
3901 else if(expr.
id()==ID_lt)
3903 else if(expr.
id()==ID_ge)
3905 else if(expr.
id()==ID_gt)
3918 op_type.
id() == ID_rational || op_type.
id() == ID_integer ||
3919 op_type.
id() == ID_natural || op_type.
id() == ID_real)
3930 else if(op_type.
id() == ID_pointer)
3938 if(expr.
id() == ID_le)
3940 else if(expr.
id() == ID_lt)
3942 else if(expr.
id() == ID_ge)
3944 else if(expr.
id() == ID_gt)
3963 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
3964 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
3969 for(
const auto &op : expr.
operands())
3978 expr.
type().
id() == ID_unsignedbv || expr.
type().
id() == ID_signedbv ||
3979 expr.
type().
id() == ID_fixedbv)
3996 else if(expr.
type().
id() == ID_range)
4006 const auto size = range_type.get_to() - range_type.get_from() + 1;
4013 out <<
" (_ bv" << range_type.get_from() <<
' ' << width
4021 else if(expr.
type().
id() == ID_floatbv)
4028 else if(expr.
type().
id() == ID_pointer)
4034 if(p.
type().
id() != ID_pointer)
4038 p.
type().
id() == ID_pointer,
4039 "one of the operands should have pointer type");
4043 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4046 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
4050 out <<
"(let ((?pointerop ";
4056 const std::size_t offset_bits =
4057 pointer_width -
config.bv_encoding.object_bits;
4060 out <<
"((_ extract " << pointer_width - 1 <<
' ' << offset_bits
4061 <<
") ?pointerop) ";
4062 out <<
"(bvadd ((_ extract " << offset_bits - 1 <<
" 0) ?pointerop) ";
4064 if(element_size >= 2)
4066 out <<
"(bvmul ((_ extract " << offset_bits - 1 <<
" 0) ";
4068 out <<
") (_ bv" << element_size <<
" " << offset_bits <<
"))";
4072 out <<
"((_ extract " << offset_bits - 1 <<
" 0) ";
4111 out <<
"roundNearestTiesToEven";
4113 out <<
"roundTowardNegative";
4115 out <<
"roundTowardPositive";
4117 out <<
"roundTowardZero";
4119 out <<
"roundNearestTiesToAway";
4123 "Rounding mode should have value 0, 1, 2, 3, or 4",
4131 out <<
"(ite (= (_ bv0 " << width <<
") ";
4133 out <<
") roundNearestTiesToEven ";
4135 out <<
"(ite (= (_ bv1 " << width <<
") ";
4137 out <<
") roundTowardNegative ";
4139 out <<
"(ite (= (_ bv2 " << width <<
") ";
4141 out <<
") roundTowardPositive ";
4143 out <<
"(ite (= (_ bv3 " << width <<
") ";
4145 out <<
") roundTowardZero ";
4148 out <<
"roundNearestTiesToAway";
4159 type.
id() == ID_floatbv ||
4160 (type.
id() == ID_complex &&
4165 if(type.
id()==ID_floatbv)
4175 else if(type.
id()==ID_complex)
4182 "type should not be one of the unsupported types",
4192 expr.
type().
id() == ID_integer || expr.
type().
id() == ID_natural ||
4193 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_real)
4201 else if(expr.
type().
id()==ID_unsignedbv ||
4202 expr.
type().
id()==ID_signedbv ||
4203 expr.
type().
id()==ID_fixedbv)
4205 if(expr.
op0().
type().
id()==ID_pointer &&
4211 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4213 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
4216 if(element_size >= 2)
4221 "bitvector width of operand shall be equal to the bitvector width of "
4230 if(element_size >= 2)
4243 else if(expr.
type().
id()==ID_floatbv)
4250 else if(expr.
type().
id()==ID_pointer)
4254 (expr.
op1().
type().
id() == ID_unsignedbv ||
4266 else if(expr.
type().
id() == ID_range)
4272 const auto size = range_type.get_to() - range_type.get_from() + 1;
4275 out <<
"(bvsub (bvsub ";
4279 out <<
") (_ bv" << range_type.get_from() <<
' ' << width
4289 expr.
type().
id() == ID_floatbv,
4290 "type of ieee floating point expression shall be floatbv");
4308 if(expr.
type().
id()==ID_unsignedbv ||
4309 expr.
type().
id()==ID_signedbv)
4311 if(expr.
type().
id()==ID_unsignedbv)
4321 else if(expr.
type().
id()==ID_fixedbv)
4326 out <<
"((_ extract " << spec.
width-1 <<
" 0) ";
4331 out <<
" (_ bv0 " << fraction_bits <<
")) ";
4333 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4339 else if(expr.
type().
id()==ID_floatbv)
4347 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4348 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4363 expr.
type().
id() == ID_floatbv,
4364 "type of ieee floating point expression shall be floatbv");
4395 "expression should have been converted to a variant with two operands");
4397 if(expr.
type().
id()==ID_unsignedbv ||
4398 expr.
type().
id()==ID_signedbv)
4409 else if(expr.
type().
id()==ID_floatbv)
4416 else if(expr.
type().
id()==ID_fixedbv)
4421 out <<
"((_ extract "
4422 << spec.
width+fraction_bits-1 <<
" "
4423 << fraction_bits <<
") ";
4427 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4431 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4438 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4439 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4443 for(
const auto &op : expr.
operands())
4458 expr.
type().
id() == ID_floatbv,
4459 "type of ieee floating point expression shall be floatbv");
4478 expr.
type().
id() == ID_floatbv,
4479 "type of ieee floating point expression shall be floatbv");
4493 "smt2_convt::convert_floatbv_rem to be implemented when not using "
4501 expr.
type().
id() == ID_floatbv,
4502 "type of ieee floating point expression shall be floatbv");
4524 "with expression should have exactly three operands");
4528 if(expr_type.
id()==ID_array)
4552 out <<
"(let ((distance? ";
4553 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4557 if(array_width>index_width)
4559 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4565 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4575 out <<
"(bvshl (_ bv" <<
power(2, sub_width) - 1 <<
" " << array_width
4577 out <<
"distance?)) ";
4581 out <<
"((_ zero_extend " << array_width-sub_width <<
") ";
4583 out <<
") distance?)))";
4586 else if(expr_type.
id() == ID_struct || expr_type.
id() == ID_struct_tag)
4589 expr_type.
id() == ID_struct_tag
4596 const irep_idt &component_name=index.
get(ID_component_name);
4600 "struct should have accessed component");
4604 const std::string &smt_typename =
datatype_map.at(expr_type);
4606 out <<
"(update-" << smt_typename <<
"." << component_name <<
" ";
4614 auto convert_operand = [
this](
const exprt &op)
4619 else if(op.type().id() == ID_bool)
4631 if(m.
width==struct_width)
4634 convert_operand(value);
4638 out <<
"(let ((?withop ";
4639 convert_operand(expr.
old());
4646 <<
"((_ extract " << (struct_width - 1) <<
" " << m.
width
4648 convert_operand(value);
4655 convert_operand(value);
4656 out <<
" ((_ extract " << (m.
offset - 1) <<
" 0) ?withop))";
4661 out <<
"(concat (concat "
4662 <<
"((_ extract " << (struct_width - 1) <<
" "
4664 convert_operand(value);
4665 out <<
") ((_ extract " << (m.
offset - 1) <<
" 0) ?withop)";
4673 else if(expr_type.
id() == ID_union || expr_type.
id() == ID_union_tag)
4681 if(total_width==member_width)
4688 total_width > member_width,
4689 "total width should be greater than member_width as member_width is at "
4690 "most as large as total_width and the other case has been handled "
4693 out <<
"((_ extract "
4695 <<
" " << member_width <<
") ";
4702 else if(expr_type.
id()==ID_bv ||
4703 expr_type.
id()==ID_unsignedbv ||
4704 expr_type.
id()==ID_signedbv)
4719 "with expects struct, union, or array type, but got "+
4727 SMT2_TODO(
"smt2_convt::convert_update to be implemented");
4744 if(array_op_type.
id()==ID_array)
4779 out <<
"((_ extract " << sub_width-1 <<
" 0) ";
4783 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4787 if(array_width>index_width)
4789 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4795 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4807 false,
"index with unsupported array type: " + array_op_type.
id_string());
4814 const typet &struct_op_type = struct_op.
type();
4817 if(struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag)
4820 struct_op_type.
id() == ID_struct_tag
4825 struct_type.
has_component(name),
"struct should have accessed component");
4829 const std::string &smt_typename =
datatype_map.at(struct_type);
4831 out <<
"(" << smt_typename <<
"."
4842 if(expr.
type().
id() == ID_bool)
4848 if(expr.
type().
id() == ID_bool)
4853 struct_op_type.
id() == ID_union || struct_op_type.
id() == ID_union_tag)
4857 width != 0,
"failed to get union member width");
4863 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4871 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4878 "convert_member on an unexpected type "+struct_op_type.
id_string());
4885 if(type.
id()==ID_bool)
4891 else if(type.
id()==ID_array)
4902 std::size_t n_concat = 0;
4916 out << std::string(n_concat,
')');
4921 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4934 std::size_t n_concat = 0;
4935 for(std::size_t i=components.size(); i>1; i--)
4955 out << std::string(n_concat,
')');
4960 else if(type.
id()==ID_floatbv)
4964 "floatbv expressions should be flattened when using FPA theory");
4977 if(type.
id()==ID_bool)
4984 else if(type.
id() == ID_array)
4989 out <<
"(let ((?ufop" << nesting <<
" ";
5000 "cannot unflatten arrays of non-constant size");
5007 out <<
"((as const ";
5012 out <<
"((_ extract " << subtype_width - 1 <<
" "
5013 <<
"0) ?ufop" << nesting <<
")";
5017 std::size_t offset = subtype_width;
5018 for(
mp_integer i = 1; i < size; ++i, offset += subtype_width)
5023 out <<
"((_ extract " << offset + subtype_width - 1 <<
" " << offset
5024 <<
") ?ufop" << nesting <<
")";
5032 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5038 out <<
"(let ((?ufop" << nesting <<
" ";
5043 const std::string &smt_typename =
datatype_map.at(type);
5045 out <<
"(mk-" << smt_typename;
5054 std::size_t offset=0;
5057 for(struct_typet::componentst::const_iterator
5058 it=components.begin();
5059 it!=components.end();
5069 out <<
"((_ extract " << offset+member_width-1 <<
" "
5070 << offset <<
") ?ufop" << nesting <<
")";
5072 offset+=member_width;
5093 if(expr.
id()==ID_and && value)
5095 for(
const auto &op : expr.
operands())
5100 if(expr.
id()==ID_or && !value)
5102 for(
const auto &op : expr.
operands())
5107 if(expr.
id()==ID_not)
5117 if(expr.
id() == ID_equal && value)
5126 if(equal_expr.
lhs().
id()==ID_symbol)
5133 equal_expr.
lhs() != equal_expr.
rhs())
5145 out <<
"; set_to true (equal)\n";
5147 if(equal_expr.
lhs().
type().
id() == ID_mathematical_function)
5151 out <<
"(declare-fun " << smt2_identifier;
5153 auto &mathematical_function_type =
5159 for(
auto &t : mathematical_function_type.domain())
5173 out <<
"(assert (= " << smt2_identifier <<
' ';
5175 out <<
')' <<
')' <<
'\n';
5179 out <<
"(define-fun " << smt2_identifier;
5184 equal_expr.
lhs().
type().
id() != ID_array ||
5212 out <<
"; set_to " << (value?
"true":
"false") <<
"\n"
5223 out << found_literal->second;
5246 exprt lowered_expr = expr;
5253 it->id() == ID_byte_extract_little_endian ||
5254 it->id() == ID_byte_extract_big_endian)
5259 it->id() == ID_byte_update_little_endian ||
5260 it->id() == ID_byte_update_big_endian)
5266 return lowered_expr;
5283 "lower_byte_operators should remove all byte operators");
5290 auto prophecy_r_or_w_ok =
5294 it.mutate() = lowered;
5295 it.next_sibling_or_parent();
5298 auto prophecy_pointer_in_range =
5302 it.mutate() = lowered;
5303 it.next_sibling_or_parent();
5312 return lowered_expr;
5332 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
5334 std::unordered_map<irep_idt, std::optional<identifiert>> shadowed_syms;
5339 for(
const auto &symbol : q_expr.variables())
5341 const auto identifier = symbol.get_identifier();
5344 shadowed_syms.insert(
5346 id_entry.second ? std::nullopt
5347 : std::optional{id_entry.first->second}});
5350 for(
const auto &[
id, shadowed_val] : shadowed_syms)
5353 if(!shadowed_val.has_value())
5356 previous_entry->second = std::move(*shadowed_val);
5362 for(
const auto &op : expr.
operands())
5365 if(expr.
id()==ID_symbol ||
5366 expr.
id()==ID_nondet_symbol)
5369 if(expr.
type().
id()==ID_code)
5374 if(expr.
id()==ID_symbol)
5377 identifier=
"nondet_"+
5388 out <<
"; find_symbols\n";
5389 out <<
"(declare-fun " << smt2_identifier;
5391 if(expr.
type().
id() == ID_mathematical_function)
5393 auto &mathematical_function_type =
5398 for(
auto &type : mathematical_function_type.domain())
5419 else if(expr.
id() == ID_array_of)
5426 const auto &array_type = array_of.type();
5430 out <<
"; the following is a substitute for lambda i. x\n";
5431 out <<
"(declare-fun " <<
id <<
" () ";
5438 out <<
"(assert (forall ((i ";
5440 out <<
")) (= (select " <<
id <<
" i) ";
5458 else if(expr.
id() == ID_array_comprehension)
5465 const auto &array_type = array_comprehension.type();
5466 const auto &array_size = array_type.size();
5470 out <<
"(declare-fun " <<
id <<
" () ";
5474 out <<
"; the following is a substitute for lambda i . x(i)\n";
5475 out <<
"; universally quantified initialization of the array\n";
5476 out <<
"(assert (forall ((";
5480 out <<
")) (=> (and (bvule (_ bv0 " <<
boolbv_width(array_size.type())
5487 out <<
")) (= (select " <<
id <<
" ";
5506 else if(expr.
id()==ID_array)
5513 out <<
"; the following is a substitute for an array constructor" <<
"\n";
5514 out <<
"(declare-fun " <<
id <<
" () ";
5520 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5522 out <<
"(assert (= (select " <<
id <<
" ";
5543 else if(expr.
id()==ID_string_constant)
5553 out <<
"; the following is a substitute for a string" <<
"\n";
5554 out <<
"(declare-fun " <<
id <<
" () ";
5558 for(std::size_t i=0; i<tmp.
operands().size(); i++)
5560 out <<
"(assert (= (select " <<
id <<
' ';
5564 out <<
"))" <<
"\n";
5577 out <<
"(declare-fun " <<
id <<
" () ";
5588 (expr.
id() == ID_floatbv_plus ||
5589 expr.
id() == ID_floatbv_minus ||
5590 expr.
id() == ID_floatbv_mult ||
5591 expr.
id() == ID_floatbv_div ||
5592 expr.
id() == ID_floatbv_fma ||
5593 expr.
id() == ID_floatbv_typecast ||
5594 expr.
id() == ID_ieee_float_equal ||
5595 expr.
id() == ID_ieee_float_notequal ||
5596 ((expr.
id() == ID_lt ||
5597 expr.
id() == ID_gt ||
5598 expr.
id() == ID_le ||
5599 expr.
id() == ID_ge ||
5600 expr.
id() == ID_isnan ||
5601 expr.
id() == ID_isnormal ||
5602 expr.
id() == ID_isfinite ||
5603 expr.
id() == ID_isinf ||
5604 expr.
id() == ID_sign ||
5605 expr.
id() == ID_unary_minus ||
5606 expr.
id() == ID_typecast ||
5607 expr.
id() == ID_abs) &&
5614 if(
bvfp_set.insert(function).second)
5616 out <<
"; this is a model for " << expr.
id() <<
" : "
5619 <<
"(define-fun " << function <<
" (";
5621 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5625 out <<
"(op" << i <<
' ';
5635 for(std::size_t i = 0; i < tmp1.
operands().size(); i++)
5651 expr.
type().
id() == ID_bv)
5661 out <<
"(declare-fun " <<
id <<
" () ";
5667 out <<
"(assert (= ";
5668 out <<
"((_ to_fp " << floatbv_type.get_e() <<
" "
5669 << floatbv_type.get_f() + 1 <<
") " <<
id <<
')';
5677 else if(expr.
id() == ID_initial_state)
5679 irep_idt function =
"initial-state";
5683 out <<
"(declare-fun " << function <<
" (";
5690 else if(expr.
id() == ID_evaluate)
5696 out <<
"(declare-fun " << function <<
" (";
5706 expr.
id() == ID_state_is_cstring ||
5707 expr.
id() == ID_state_is_dynamic_object ||
5708 expr.
id() == ID_state_live_object || expr.
id() == ID_state_writeable_object)
5711 expr.
id() == ID_state_is_cstring ?
"state-is-cstring"
5712 : expr.
id() == ID_state_is_dynamic_object ?
"state-is-dynamic-object"
5713 : expr.
id() == ID_state_live_object ?
"state-live-object"
5714 :
"state-writeable-object";
5718 out <<
"(declare-fun " << function <<
" (";
5728 expr.
id() == ID_state_r_ok || expr.
id() == ID_state_w_ok ||
5729 expr.
id() == ID_state_rw_ok)
5731 irep_idt function = expr.
id() == ID_state_r_ok ?
"state-r-ok"
5732 : expr.
id() == ID_state_w_ok ?
"state-w-ok"
5737 out <<
"(declare-fun " << function <<
" (";
5748 else if(expr.
id() == ID_update_state)
5755 out <<
"(declare-fun " << function <<
" (";
5766 else if(expr.
id() == ID_enter_scope_state)
5773 out <<
"(declare-fun " << function <<
" (";
5784 else if(expr.
id() == ID_exit_scope_state)
5791 out <<
"(declare-fun " << function <<
" (";
5800 else if(expr.
id() == ID_allocate)
5806 out <<
"(declare-fun " << function <<
" (";
5815 else if(expr.
id() == ID_reallocate)
5821 out <<
"(declare-fun " << function <<
" (";
5832 else if(expr.
id() == ID_deallocate_state)
5838 out <<
"(declare-fun " << function <<
" (";
5847 else if(expr.
id() == ID_object_address)
5849 irep_idt function =
"object-address";
5853 out <<
"(declare-fun " << function <<
" (String) ";
5858 else if(expr.
id() == ID_field_address)
5864 out <<
"(declare-fun " << function <<
" (";
5873 else if(expr.
id() == ID_element_address)
5879 out <<
"(declare-fun " << function <<
" (";
5898 if(expr.
id() == ID_with)
5906 if(type.
id()==ID_array)
5920 out <<
"(_ BitVec 1)";
5926 else if(type.
id()==ID_bool)
5930 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5940 out <<
"(_ BitVec " << width <<
")";
5943 else if(type.
id()==ID_code)
5950 else if(type.
id() == ID_union || type.
id() == ID_union_tag)
5957 union_type.
components().empty() || width != 0,
5958 "failed to get width of union");
5960 out <<
"(_ BitVec " << width <<
")";
5962 else if(type.
id()==ID_pointer)
5967 else if(type.
id()==ID_bv ||
5968 type.
id()==ID_fixedbv ||
5969 type.
id()==ID_unsignedbv ||
5970 type.
id()==ID_signedbv ||
5971 type.
id()==ID_c_bool)
5976 else if(type.
id()==ID_c_enum)
5983 else if(type.
id()==ID_c_enum_tag)
5987 else if(type.
id()==ID_floatbv)
5992 out <<
"(_ FloatingPoint "
5993 << floatbv_type.
get_e() <<
" "
5994 << floatbv_type.
get_f() + 1 <<
")";
5999 else if(type.
id()==ID_rational ||
6002 else if(type.
id()==ID_integer)
6004 else if(type.
id() == ID_natural)
6006 else if(type.
id()==ID_complex)
6016 out <<
"(_ BitVec " << width <<
")";
6019 else if(type.
id()==ID_c_bit_field)
6023 else if(type.
id() == ID_state)
6027 else if(type.
id() == ID_range)
6030 mp_integer size = range_type.get_to() - range_type.get_from() + 1;
6043 std::set<irep_idt> recstack;
6049 std::set<irep_idt> &recstack)
6051 if(type.
id()==ID_array)
6057 else if(type.
id()==ID_complex)
6064 const std::string smt_typename =
6068 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6069 <<
"(((mk-" << smt_typename;
6071 out <<
" (" << smt_typename <<
".imag ";
6075 out <<
" (" << smt_typename <<
".real ";
6082 else if(type.
id() == ID_struct)
6085 bool need_decl=
false;
6089 const std::string smt_typename =
6104 const std::string &smt_typename =
datatype_map.at(type);
6115 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6116 <<
"(((mk-" << smt_typename <<
" ";
6123 out <<
"(" << smt_typename <<
"." <<
component.get_name()
6129 out <<
"))))" <<
"\n";
6146 for(struct_union_typet::componentst::const_iterator
6147 it=components.begin();
6148 it!=components.end();
6155 out <<
"(define-fun update-" << smt_typename <<
"."
6157 <<
"((s " << smt_typename <<
") "
6160 out <<
")) " << smt_typename <<
" "
6161 <<
"(mk-" << smt_typename
6164 for(struct_union_typet::componentst::const_iterator
6165 it2=components.begin();
6166 it2!=components.end();
6173 out <<
"(" << smt_typename <<
"."
6174 << it2->get_name() <<
" s) ";
6178 out <<
"))" <<
"\n";
6184 else if(type.
id() == ID_union)
6192 else if(type.
id()==ID_code)
6196 for(
const auto ¶m : parameters)
6201 else if(type.
id()==ID_pointer)
6205 else if(type.
id() == ID_struct_tag)
6208 const irep_idt &
id = struct_tag.get_identifier();
6210 if(recstack.find(
id) == recstack.end())
6212 const auto &base_struct =
ns.follow_tag(struct_tag);
6213 recstack.insert(
id);
6218 else if(type.
id() == ID_union_tag)
6221 const irep_idt &
id = union_tag.get_identifier();
6223 if(recstack.find(
id) == recstack.end())
6225 recstack.insert(
id);
6229 else if(type.
id() == ID_state)
6234 out <<
"(declare-sort state 0)\n";
6237 else if(type.
id() == ID_mathematical_function)
6239 const auto &mathematical_function_type =
6241 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 shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_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 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 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.
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.
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
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.
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
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.
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 type_try_dynamic_cast(TType &base) -> typename detail::expr_try_dynamic_cast_return_typet< T, TType >::type
Try to cast a reference to a generic typet to 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 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.
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_zero_width(const typet &type, const namespacet &ns)
Returns true iff type has effective width of zero bits.
static bool is_smt2_simple_identifier(const std::string &identifier)
#define UNEXPECTEDCASE(S)
bool is_smt2_simple_symbol_character(char ch)
#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 range_typet & to_range_type(const typet &type)
Cast a typet to a range_typet.
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.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_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)