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";
218 out <<
"(check-sat-assuming (";
228 out <<
"; assumptions\n";
239 out <<
"(check-sat)\n";
247 out <<
"(get-value (" <<
id <<
"))"
255 out <<
"; end of SMT2 file"
262 if(type.
id() == ID_empty)
264 else if(type.
id() == ID_struct_tag)
266 else if(type.
id() == ID_union_tag)
268 else if(type.
id() == ID_struct || type.
id() == ID_union)
293 std::size_t number = 0;
294 std::size_t h=pointer_width-1;
295 std::size_t l=pointer_width-
config.bv_encoding.object_bits;
299 const typet &type = o.type();
303 (o.id() != ID_symbol && o.id() != ID_string_constant) ||
304 !size_expr.has_value())
311 out <<
"(assert (=> (= "
312 <<
"((_ extract " << h <<
" " << l <<
") ";
314 out <<
") (_ bv" << number <<
" " <<
config.bv_encoding.object_bits <<
"))"
315 <<
"(= " <<
id <<
" ";
340 if(expr.
id()==ID_symbol)
347 return it->second.value;
350 else if(expr.
id()==ID_nondet_symbol)
357 return it->second.value;
359 else if(expr.
id() == ID_literal)
367 else if(expr.
id() == ID_not)
377 (!expr.
has_operands() && (expr.
id() == ID_struct || expr.
id() == ID_array)))
389 op = std::move(eval_op);
424 if(s.size()>=2 && s[0]==
'#' && s[1]==
'b')
429 else if(s.size()>=2 && s[0]==
'#' && s[1]==
'x')
436 std::size_t
pos = s.find(
".");
437 if(
pos != std::string::npos)
440 if(type.
id() == ID_rational)
448 else if(type.
id() == ID_real)
459 "smt2_convt::parse_literal parsed a number with a decimal point "
468 else if(src.
get_sub().size()==2 &&
473 else if(src.
get_sub().size()==3 &&
476 src.
get_sub()[1].id_string().substr(0, 2)==
"bv")
481 type.
id() == ID_rational && src.
get_sub().size() == 3 &&
492 else if(src.
get_sub().size()==4 &&
495 if(type.
id()==ID_floatbv)
510 s1_int << (floatbv_type.
get_e() + floatbv_type.
get_f()),
516 else if(src.
get_sub().size()==4 &&
525 else if(src.
get_sub().size()==4 &&
534 else if(src.
get_sub().size()==4 &&
544 src.
get_sub()[0].id() ==
"root-obj")
552 src.
get_sub()[1].id().empty() && src.
get_sub()[1].get_sub().size() == 3 &&
553 src.
get_sub()[1].get_sub()[0].id() ==
"+" &&
555 "unexpected root-obj expression",
562 !
failed,
"failed to parse rational constant coefficient", src.
pretty());
566 sum_lhs.
get_sub()[0].id() ==
"^" && sum_lhs.
get_sub()[1].id() ==
"x",
567 "unexpected first operand to root-obj",
571 degree > 0,
"polynomial degree must be positive", src.
pretty());
572 std::vector<rationalt> coefficients{degree + 1,
rationalt{}};
573 coefficients.front() = constant_coeff;
579 if(type.
id()==ID_signedbv ||
580 type.
id()==ID_unsignedbv ||
581 type.
id()==ID_c_enum ||
582 type.
id()==ID_c_bool)
586 else if(type.
id()==ID_c_enum_tag)
592 result.
type() = type;
595 else if(type.
id()==ID_fixedbv ||
596 type.
id()==ID_floatbv)
602 type.
id() == ID_integer || type.
id() == ID_natural ||
603 type.
id() == ID_rational || type.
id() == ID_real)
607 else if(type.
id() == ID_range)
613 "smt2_convt::parse_literal should not be of unsupported type " +
621 std::unordered_map<int64_t, exprt> operands_map;
625 auto maybe_default_op = operands_map.find(-1);
627 if(maybe_default_op == operands_map.end())
630 default_op = maybe_default_op->second;
633 if(maybe_size.has_value())
635 while(i < maybe_size.value())
637 auto found_op = operands_map.find(i);
638 if(found_op != operands_map.end())
639 operands.emplace_back(found_op->second);
641 operands.emplace_back(default_op);
649 auto found_op = operands_map.find(i);
650 while(found_op != operands_map.end())
652 operands.emplace_back(found_op->second);
654 found_op = operands_map.find(i);
656 operands.emplace_back(default_op);
662 std::unordered_map<int64_t, exprt> *operands_map,
675 bool failure =
to_integer(index_constant, tempint);
678 long index = tempint.to_long();
680 operands_map->emplace(index, value);
682 else if(src.
get_sub().size()==2 &&
683 src.
get_sub()[0].get_sub().size()==3 &&
684 src.
get_sub()[0].get_sub()[0].id()==
"as" &&
685 src.
get_sub()[0].get_sub()[1].id()==
"const")
689 operands_map->emplace(-1, default_value);
722 if(components.empty())
730 for(std::size_t i=0; i<components.size(); i++)
740 src.
get_sub().size() > j,
"insufficient number of component values");
757 std::size_t offset=0;
759 for(std::size_t i=0; i<components.size(); i++)
764 std::size_t component_width=
boolbv_width(components[i].type());
767 offset + component_width <= total_width,
768 "struct component bits shall be within struct bit vector");
770 std::string component_binary=
772 total_width-offset-component_width, component_width);
777 offset+=component_width;
791 for(
const auto &binding : src.
get_sub()[1].get_sub())
793 const irep_idt &name = binding.get_sub()[0].id();
804 return parse_rec(bindings_it->second, type);
808 type.
id() == ID_signedbv || type.
id() == ID_unsignedbv ||
809 type.
id() == ID_integer || type.
id() == ID_rational ||
810 type.
id() == ID_natural || type.
id() == ID_real || type.
id() == ID_c_enum ||
811 type.
id() == ID_c_enum_tag || type.
id() == ID_fixedbv ||
812 type.
id() == ID_floatbv || type.
id() == ID_c_bool || type.
id() == ID_range)
816 else if(type.
id()==ID_bool)
818 if(src.
id()==ID_1 || src.
id()==ID_true)
820 else if(src.
id()==ID_0 || src.
id()==ID_false)
823 else if(type.
id()==ID_pointer)
838 else if(type.
id()==ID_struct)
842 else if(type.
id() == ID_struct_tag)
847 struct_expr.type() = type;
848 return std::move(struct_expr);
850 else if(type.
id()==ID_union)
854 else if(type.
id() == ID_union_tag)
858 union_expr.type() = type;
861 else if(type.
id()==ID_array)
875 expr.
id() == ID_string_constant || expr.
id() == ID_label)
877 const std::size_t object_bits =
config.bv_encoding.object_bits;
878 const std::size_t max_objects = std::size_t(1) << object_bits;
881 if(object_id >= max_objects)
884 "too many addressed objects: maximum number of objects is set to 2^n=" +
885 std::to_string(max_objects) +
886 " (with n=" + std::to_string(object_bits) +
"); " +
887 "use the `--object-bits n` option to increase the maximum number"};
890 out <<
"(concat (_ bv" << object_id <<
" " << object_bits <<
")"
891 <<
" (_ bv0 " <<
boolbv_width(result_type) - object_bits <<
"))";
893 else if(expr.
id()==ID_index)
902 if(array.
type().
id()==ID_pointer)
904 else if(array.
type().
id()==ID_array)
924 else if(expr.
id()==ID_member)
929 const typet &struct_op_type = struct_op.
type();
932 struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag,
933 "member expression operand shall have struct type");
936 struct_op_type.
id() == ID_struct_tag
953 else if(expr.
id()==ID_if)
968 "operand of address of expression should not be of kind " +
976 if(node.
id() == ID_exists || node.
id() == ID_forall)
990 else if(expr ==
false)
992 else if(expr.
id()==ID_literal)
1004 out <<
"; convert\n";
1005 out <<
"; Converting var_no " << l.
var_no() <<
" with expr ID of "
1015 out <<
"(declare-fun ";
1017 out <<
" () Bool)\n";
1018 out <<
"(assert (= ";
1030 out <<
"(define-fun " << identifier <<
" () Bool ";
1058 const auto identifier =
1080 for(
auto &assumption : _assumptions)
1091 if(identifier.empty())
1094 if(isdigit(identifier[0]))
1116 std::string result =
"|";
1118 for(
auto ch : identifier)
1126 result+=std::to_string(ch);
1143 if(type.
id()==ID_floatbv)
1146 return "f"+std::to_string(spec.
width())+
"_"+std::to_string(spec.
f);
1148 else if(type.
id() == ID_bv)
1152 else if(type.
id()==ID_unsignedbv)
1156 else if(type.
id()==ID_c_bool)
1160 else if(type.
id()==ID_signedbv)
1164 else if(type.
id()==ID_bool)
1168 else if(type.
id()==ID_c_enum_tag)
1172 else if(type.
id() == ID_pointer)
1176 else if(type.
id() == ID_struct_tag)
1183 else if(type.
id() == ID_union_tag)
1187 else if(type.
id() == ID_array)
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 && expr.
operands().size() == 1)
1308 "concatenation over a single operand should have matching types",
1314 expr.
id() == ID_concatenation || expr.
id() == ID_bitand ||
1315 expr.
id() == ID_bitor || expr.
id() == ID_bitxor)
1319 "given expression should have at least two operands",
1324 if(expr.
id()==ID_concatenation)
1326 else if(expr.
id()==ID_bitand)
1328 else if(expr.
id()==ID_bitor)
1330 else if(expr.
id()==ID_bitxor)
1332 else if(expr.
id()==ID_bitnand)
1334 else if(expr.
id()==ID_bitnor)
1337 for(
const auto &op : expr.
operands())
1346 expr.
id() == ID_bitxnor || expr.
id() == ID_bitnand ||
1347 expr.
id() == ID_bitnor)
1356 if(binary_expr.id() == ID_bitxnor)
1358 else if(binary_expr.id() == ID_bitnand)
1360 else if(binary_expr.id() == ID_bitnor)
1368 else if(expr.
operands().size() == 1)
1374 else if(expr.
operands().size() >= 3)
1377 if(expr.
id() == ID_bitxnor)
1379 else if(expr.
id() == ID_bitnand)
1381 else if(expr.
id() == ID_bitnor)
1384 for(
const auto &op : expr.
operands())
1396 expr.
id_string() +
" should have at least one operand");
1399 else if(expr.
id()==ID_bitnot)
1407 else if(expr.
id()==ID_unary_minus)
1410 const auto &type = expr.
type();
1413 type.id() == ID_rational || type.id() == ID_integer ||
1414 type.id() == ID_real)
1420 else if(type.id() == ID_range)
1429 else if(type.id() == ID_floatbv)
1449 else if(expr.
id()==ID_unary_plus)
1454 else if(expr.
id()==ID_sign)
1460 if(op_type.
id()==ID_floatbv)
1464 out <<
"(fp.isNegative ";
1471 else if(op_type.
id()==ID_signedbv)
1477 out <<
" (_ bv0 " << op_width <<
"))";
1482 "sign should not be applied to unsupported type",
1485 else if(expr.
id()==ID_if)
1523 else if(expr.
id()==ID_and ||
1529 "logical and, or, and xor expressions should have Boolean type");
1532 "logical and, or, and xor expressions should have at least two operands");
1534 out <<
"(" << expr.
id();
1535 for(
const auto &op : expr.
operands())
1542 else if(expr.
id() == ID_nand || expr.
id() == ID_nor || expr.
id() == ID_xnor)
1546 "logical nand, nor, xnor expressions should have Boolean type");
1549 "logical nand, nor, xnor expressions should have at least one operand");
1557 if(expr.
id() == ID_nand)
1559 else if(expr.
id() == ID_nor)
1561 else if(expr.
id() == ID_xnor)
1565 for(
const auto &op : expr.
operands())
1574 else if(expr.
id()==ID_implies)
1579 implies_expr.
is_boolean(),
"implies expression should have Boolean type");
1587 else if(expr.
id()==ID_not)
1592 not_expr.
is_boolean(),
"not expression should have Boolean type");
1598 else if(expr.
id() == ID_equal)
1604 "operands of equal expression shall have same type");
1619 else if(expr.
id() == ID_notequal)
1625 "operands of not equal expression shall have same type");
1633 else if(expr.
id()==ID_ieee_float_equal ||
1634 expr.
id()==ID_ieee_float_notequal)
1641 rel_expr.lhs().type() == rel_expr.rhs().type(),
1642 "operands of float equal and not equal expressions shall have same type");
1647 if(rel_expr.id() == ID_ieee_float_notequal)
1656 if(rel_expr.id() == ID_ieee_float_notequal)
1662 else if(expr.
id()==ID_le ||
1669 else if(expr.
id()==ID_plus)
1673 else if(expr.
id()==ID_floatbv_plus)
1677 else if(expr.
id()==ID_minus)
1681 else if(expr.
id()==ID_floatbv_minus)
1685 else if(expr.
id()==ID_div)
1689 else if(expr.
id()==ID_floatbv_div)
1693 else if(expr.
id()==ID_mod)
1697 else if(expr.
id() == ID_euclidean_mod)
1701 else if(expr.
id()==ID_mult)
1705 else if(expr.
id()==ID_floatbv_mult)
1709 else if(expr.
id() == ID_floatbv_rem)
1713 else if(expr.
id()==ID_address_of)
1719 else if(expr.
id() == ID_array_of)
1724 array_of_expr.type().id() == ID_array,
1725 "array of expression shall have array type");
1729 out <<
"((as const ";
1737 defined_expressionst::const_iterator it =
1743 else if(expr.
id() == ID_array_comprehension)
1748 array_comprehension.type().id() == ID_array,
1749 "array_comprehension expression shall have array type");
1753 out <<
"(lambda ((";
1756 convert_type(array_comprehension.type().size().type());
1768 else if(expr.
id()==ID_index)
1772 else if(expr.
id()==ID_ashr ||
1773 expr.
id()==ID_lshr ||
1779 if(type.
id()==ID_unsignedbv ||
1780 type.
id()==ID_signedbv ||
1783 if(shift_expr.
id() == ID_ashr)
1785 else if(shift_expr.
id() == ID_lshr)
1787 else if(shift_expr.
id() == ID_shl)
1798 const auto &distance_type = shift_expr.
distance().
type();
1799 if(distance_type.id() == ID_integer || distance_type.id() == ID_natural)
1810 distance_type.id() == ID_signedbv ||
1811 distance_type.id() == ID_unsignedbv ||
1812 distance_type.id() == ID_c_enum || distance_type.id() == ID_c_bool)
1817 if(width_op0==width_op1)
1819 else if(width_op0>width_op1)
1821 out <<
"((_ zero_extend " << width_op0-width_op1 <<
") ";
1827 out <<
"((_ extract " << width_op0-1 <<
" 0) ";
1835 "unsupported distance type for " + shift_expr.
id_string() +
": " +
1836 distance_type.id_string());
1843 "unsupported type for " + shift_expr.
id_string() +
": " +
1846 else if(expr.
id() == ID_rol || expr.
id() == ID_ror)
1852 type.
id() == ID_unsignedbv || type.
id() == ID_signedbv ||
1857 if(shift_expr.
id() == ID_rol)
1858 out <<
"((_ rotate_left";
1859 else if(shift_expr.
id() == ID_ror)
1860 out <<
"((_ rotate_right";
1868 if(distance_int_op.has_value())
1870 out << distance_int_op.value();
1874 "distance type for " + shift_expr.
id_string() +
"must be constant");
1883 "unsupported type for " + shift_expr.
id_string() +
": " +
1886 else if(expr.
id() == ID_named_term)
1890 convert(named_term_expr.value());
1894 else if(expr.
id()==ID_with)
1898 else if(expr.
id()==ID_update)
1902 else if(expr.
id() == ID_update_bit)
1906 else if(expr.
id() == ID_update_bits)
1910 else if(expr.
id() == ID_object_address)
1912 out <<
"(object-address ";
1917 else if(expr.
id() == ID_element_address)
1923 auto element_size_expr_opt =
1933 *element_size_expr_opt, element_address_expr.index().type()));
1936 else if(expr.
id() == ID_field_address)
1945 else if(expr.
id()==ID_member)
1949 else if(expr.
id()==ID_pointer_offset)
1954 op.type().id() == ID_pointer,
1955 "operand of pointer offset expression shall be of pointer type");
1957 std::size_t offset_bits =
1962 if(offset_bits>result_width)
1963 offset_bits=result_width;
1966 if(result_width>offset_bits)
1967 out <<
"((_ zero_extend " << result_width-offset_bits <<
") ";
1969 out <<
"((_ extract " << offset_bits-1 <<
" 0) ";
1973 if(result_width>offset_bits)
1976 else if(expr.
id()==ID_pointer_object)
1981 op.type().id() == ID_pointer,
1982 "pointer object expressions should be of pointer type");
1988 out <<
"((_ zero_extend " << ext <<
") ";
1990 out <<
"((_ extract "
1991 << pointer_width-1 <<
" "
1992 << pointer_width-
config.bv_encoding.object_bits <<
") ";
1999 else if(expr.
id() == ID_is_dynamic_object)
2003 else if(expr.
id() == ID_is_invalid_pointer)
2007 out <<
"(= ((_ extract "
2008 << pointer_width-1 <<
" "
2009 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2012 <<
" " <<
config.bv_encoding.object_bits <<
"))";
2014 else if(expr.
id()==ID_string_constant)
2020 else if(expr.
id()==ID_extractbit)
2029 out <<
"(= ((_ extract " << i <<
" " << i <<
") ";
2035 out <<
"(= ((_ extract 0 0) ";
2045 else if(expr.
id() == ID_onehot)
2049 else if(expr.
id() == ID_onehot0)
2053 else if(expr.
id()==ID_extractbits)
2063 out <<
"((_ extract " << (width + index_i - 1) <<
" " << index_i <<
") ";
2070 out <<
"(= ((_ extract 0 0) ";
2079 SMT2_TODO(
"smt2: extractbits with non-constant index");
2082 else if(expr.
id()==ID_replication)
2088 out <<
"((_ repeat " << times <<
") ";
2092 else if(expr.
id()==ID_byte_extract_little_endian ||
2093 expr.
id()==ID_byte_extract_big_endian)
2096 false,
"byte_extract ops should be lowered in prepare_for_convert_expr");
2098 else if(expr.
id()==ID_byte_update_little_endian ||
2099 expr.
id()==ID_byte_update_big_endian)
2102 false,
"byte_update ops should be lowered in prepare_for_convert_expr");
2104 else if(expr.
id()==ID_abs)
2110 if(type.
id()==ID_signedbv)
2114 out <<
"(ite (bvslt ";
2116 out <<
" (_ bv0 " << result_width <<
")) ";
2123 else if(type.
id()==ID_fixedbv)
2127 out <<
"(ite (bvslt ";
2129 out <<
" (_ bv0 " << result_width <<
")) ";
2136 else if(type.
id()==ID_floatbv)
2150 else if(expr.
id()==ID_isnan)
2156 if(op_type.
id()==ID_fixedbv)
2158 else if(op_type.
id()==ID_floatbv)
2162 out <<
"(fp.isNaN ";
2172 else if(expr.
id()==ID_isfinite)
2178 if(op_type.
id()==ID_fixedbv)
2180 else if(op_type.
id()==ID_floatbv)
2186 out <<
"(not (fp.isNaN ";
2190 out <<
"(not (fp.isInfinite ";
2202 else if(expr.
id()==ID_isinf)
2208 if(op_type.
id()==ID_fixedbv)
2210 else if(op_type.
id()==ID_floatbv)
2214 out <<
"(fp.isInfinite ";
2224 else if(expr.
id()==ID_isnormal)
2230 if(op_type.
id()==ID_fixedbv)
2232 else if(op_type.
id()==ID_floatbv)
2236 out <<
"(fp.isNormal ";
2249 expr.
id() == ID_overflow_result_plus ||
2250 expr.
id() == ID_overflow_result_minus)
2259 "overflow plus and overflow minus expressions shall be of Boolean type");
2262 expr.
id() == ID_overflow_result_minus;
2263 const typet &op_type = op0.type();
2266 if(op_type.
id()==ID_signedbv)
2269 out <<
"(let ((?sum (";
2270 out << (subtract?
"bvsub":
"bvadd");
2271 out <<
" ((_ sign_extend 1) ";
2274 out <<
" ((_ sign_extend 1) ";
2284 out <<
"(mk-" << smt_typename;
2289 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2294 "((_ extract " << width <<
" " << width <<
") ?sum) "
2295 "((_ extract " << (width-1) <<
" " << (width-1) <<
") ?sum)";
2305 else if(op_type.
id()==ID_unsignedbv ||
2306 op_type.
id()==ID_pointer)
2309 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2310 out <<
" ((_ zero_extend 1) ";
2313 out <<
" ((_ zero_extend 1) ";
2325 out <<
"(mk-" << smt_typename;
2326 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2330 out <<
"((_ extract " << width <<
" " << width <<
") ?sum)";
2341 "overflow check should not be performed on unsupported type",
2346 expr.
id() == ID_overflow_result_mult)
2355 "overflow mult expression shall be of Boolean type");
2360 const typet &op_type = op0.type();
2363 if(op_type.
id()==ID_signedbv)
2365 out <<
"(let ( (prod (bvmul ((_ sign_extend " << width <<
") ";
2367 out <<
") ((_ sign_extend " << width <<
") ";
2377 out <<
"(mk-" << smt_typename;
2382 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2386 out <<
"(or (bvsge prod (_ bv" <<
power(2, width-1) <<
" "
2388 out <<
" (bvslt prod (bvneg (_ bv" <<
power(2, width - 1) <<
" "
2389 << width * 2 <<
"))))";
2398 else if(op_type.
id()==ID_unsignedbv)
2400 out <<
"(let ((prod (bvmul ((_ zero_extend " << width <<
") ";
2402 out <<
") ((_ zero_extend " << width <<
") ";
2412 out <<
"(mk-" << smt_typename;
2417 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2421 out <<
"(bvuge prod (_ bv" <<
power(2, width) <<
" " << width * 2 <<
"))";
2433 "overflow check should not be performed on unsupported type",
2436 else if(expr.
id() == ID_saturating_plus || expr.
id() == ID_saturating_minus)
2438 const bool subtract = expr.
id() == ID_saturating_minus;
2439 const auto &op_type = expr.
type();
2443 if(op_type.id() == ID_signedbv)
2448 out <<
"(let ((?sum (";
2449 out << (subtract ?
"bvsub" :
"bvadd");
2450 out <<
" ((_ sign_extend 1) ";
2453 out <<
" ((_ sign_extend 1) ";
2460 << width <<
" " << width
2463 << (width - 1) <<
" " << (width - 1) <<
") ?sum)";
2467 out <<
"((_ extract " << width - 1 <<
" 0) ?sum) ";
2470 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2477 else if(op_type.id() == ID_unsignedbv)
2482 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2483 out <<
" ((_ zero_extend 1) ";
2486 out <<
" ((_ zero_extend 1) ";
2491 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2494 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2508 "saturating_plus/minus on unsupported type",
2509 op_type.id_string());
2511 else if(expr.
id()==ID_array)
2517 else if(expr.
id()==ID_literal)
2521 else if(expr.
id()==ID_forall ||
2522 expr.
id()==ID_exists)
2528 throw "MathSAT does not support quantifiers";
2530 if(quantifier_expr.
id() == ID_forall)
2532 else if(quantifier_expr.
id() == ID_exists)
2537 for(
const auto &bound : quantifier_expr.
variables())
2560 else if(expr.
id()==ID_let)
2563 const auto &variables = let_expr.
variables();
2564 const auto &values = let_expr.
values();
2569 for(
auto &binding :
make_range(variables).zip(values))
2588 else if(expr.
id()==ID_constraint_select_one)
2591 "smt2_convt::convert_expr: '" + expr.
id_string() +
2592 "' is not yet supported");
2594 else if(expr.
id() == ID_bswap)
2600 "operand of byte swap expression shall have same type as the expression");
2603 out <<
"(let ((bswap_op ";
2608 bswap_expr.
type().
id() == ID_signedbv ||
2609 bswap_expr.
type().
id() == ID_unsignedbv)
2611 const std::size_t width =
2618 width % bits_per_byte == 0,
2619 "bit width indicated by type of bswap expression should be a multiple "
2620 "of the number of bits per byte");
2622 const std::size_t bytes = width / bits_per_byte;
2631 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2635 out <<
"(bswap_byte_" <<
byte <<
' ';
2636 out <<
"((_ extract " << (
byte * bits_per_byte + (bits_per_byte - 1))
2637 <<
" " << (
byte * bits_per_byte) <<
") bswap_op)";
2646 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2647 out <<
" bswap_byte_" <<
byte;
2658 else if(expr.
id() == ID_popcount)
2662 else if(expr.
id() == ID_count_leading_zeros)
2666 else if(expr.
id() == ID_count_trailing_zeros)
2670 else if(expr.
id() == ID_find_first_set)
2674 else if(expr.
id() == ID_bitreverse)
2678 else if(expr.
id() == ID_zero_extend)
2682 else if(expr.
id() == ID_function_application)
2686 if(function_application_expr.arguments().empty())
2694 for(
auto &op : function_application_expr.arguments())
2702 else if(expr.
id() == ID_cond)
2710 "smt2_convt::convert_expr should not be applied to unsupported "
2720 if(dest_type.
id()==ID_c_enum_tag)
2724 if(src_type.
id()==ID_c_enum_tag)
2727 if(dest_type.
id()==ID_bool)
2731 src_type.
id() == ID_signedbv || src_type.
id() == ID_unsignedbv ||
2732 src_type.
id() == ID_c_bool || src_type.
id() == ID_fixedbv ||
2733 src_type.
id() == ID_pointer || src_type.
id() == ID_integer ||
2734 src_type.
id() == ID_natural || src_type.
id() == ID_rational ||
2735 src_type.
id() == ID_real)
2743 else if(src_type.
id()==ID_floatbv)
2747 out <<
"(not (fp.isZero ";
2759 else if(dest_type.
id()==ID_c_bool)
2768 out <<
" (_ bv1 " << to_width <<
")";
2769 out <<
" (_ bv0 " << to_width <<
")";
2772 else if(dest_type.
id()==ID_signedbv ||
2773 dest_type.
id()==ID_unsignedbv ||
2774 dest_type.
id()==ID_c_enum ||
2775 dest_type.
id()==ID_bv)
2779 if(src_type.
id()==ID_signedbv ||
2780 src_type.
id()==ID_unsignedbv ||
2781 src_type.
id()==ID_c_bool ||
2782 src_type.
id()==ID_c_enum ||
2783 src_type.
id()==ID_bv)
2787 if(from_width==to_width)
2789 else if(from_width<to_width)
2791 if(src_type.
id()==ID_signedbv)
2792 out <<
"((_ sign_extend ";
2794 out <<
"((_ zero_extend ";
2796 out << (to_width-from_width)
2803 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2808 else if(src_type.
id()==ID_fixedbv)
2812 std::size_t from_width=fixedbv_type.
get_width();
2819 out <<
"(let ((?tcop ";
2825 if(to_width>from_integer_bits)
2827 out <<
"((_ sign_extend "
2828 << (to_width-from_integer_bits) <<
") ";
2829 out <<
"((_ extract " << (from_width-1) <<
" "
2830 << from_fraction_bits <<
") ";
2836 out <<
"((_ extract " << (from_fraction_bits+to_width-1)
2837 <<
" " << from_fraction_bits <<
") ";
2842 out <<
" (ite (and ";
2845 out <<
"(not (= ((_ extract " << (from_fraction_bits-1) <<
" 0) ?tcop) "
2846 "(_ bv0 " << from_fraction_bits <<
")))";
2849 out <<
" (= ((_ extract " << (from_width-1) <<
" " << (from_width-1)
2854 out <<
" (_ bv1 " << to_width <<
") (_ bv0 " << to_width <<
"))";
2858 else if(src_type.
id()==ID_floatbv)
2860 if(dest_type.
id()==ID_bv)
2866 defined_expressionst::const_iterator it =
2877 else if(dest_type.
id()==ID_signedbv)
2881 "typecast unexpected "+src_type.
id_string()+
" -> "+
2884 else if(dest_type.
id()==ID_unsignedbv)
2888 "typecast unexpected "+src_type.
id_string()+
" -> "+
2892 else if(src_type.
id()==ID_bool)
2897 if(dest_type.
id()==ID_fixedbv)
2900 out <<
" (concat (_ bv1 "
2903 "(_ bv0 " << spec.
width <<
")";
2907 out <<
" (_ bv1 " << to_width <<
")";
2908 out <<
" (_ bv0 " << to_width <<
")";
2913 else if(src_type.
id()==ID_pointer)
2917 if(from_width<to_width)
2919 out <<
"((_ sign_extend ";
2920 out << (to_width-from_width)
2927 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2932 else if(src_type.
id() == ID_integer || src_type.
id() == ID_natural)
2938 out <<
"(_ bv" << i <<
" " << to_width <<
")";
2941 SMT2_TODO(
"can't convert non-constant integer to bitvector");
2944 src_type.
id() == ID_struct ||
2945 src_type.
id() == ID_struct_tag)
2951 "bit vector with of source and destination type shall be equal");
2958 "bit vector with of source and destination type shall be equal");
2963 src_type.
id() == ID_union ||
2964 src_type.
id() == ID_union_tag)
2968 "bit vector with of source and destination type shall be equal");
2971 else if(src_type.
id()==ID_c_bit_field)
2975 if(from_width==to_width)
2986 std::ostringstream e_str;
2987 e_str << src_type.
id() <<
" -> " << dest_type.
id()
2988 <<
" src == " <<
format(src);
2992 else if(dest_type.
id()==ID_fixedbv)
2998 if(src_type.
id()==ID_unsignedbv ||
2999 src_type.
id()==ID_signedbv ||
3000 src_type.
id()==ID_c_enum)
3007 if(from_width==to_integer_bits)
3009 else if(from_width>to_integer_bits)
3012 out <<
"((_ extract " << (to_integer_bits-1) <<
" 0) ";
3020 from_width < to_integer_bits,
3021 "from_width should be smaller than to_integer_bits as other case "
3022 "have been handled above");
3023 if(dest_type.
id()==ID_unsignedbv)
3025 out <<
"(_ zero_extend "
3026 << (to_integer_bits-from_width) <<
") ";
3032 out <<
"((_ sign_extend "
3033 << (to_integer_bits-from_width) <<
") ";
3039 out <<
"(_ bv0 " << to_fraction_bits <<
")";
3042 else if(src_type.
id()==ID_bool)
3044 out <<
"(concat (concat"
3045 <<
" (_ bv0 " << (to_integer_bits-1) <<
") ";
3051 else if(src_type.
id()==ID_fixedbv)
3056 std::size_t from_width=from_fixedbv_type.
get_width();
3058 out <<
"(let ((?tcop ";
3064 if(to_integer_bits<=from_integer_bits)
3066 out <<
"((_ extract "
3067 << (from_fraction_bits+to_integer_bits-1) <<
" "
3068 << from_fraction_bits
3074 to_integer_bits > from_integer_bits,
3075 "to_integer_bits should be greater than from_integer_bits as the"
3076 "other case has been handled above");
3077 out <<
"((_ sign_extend "
3078 << (to_integer_bits-from_integer_bits)
3080 << (from_width-1) <<
" "
3081 << from_fraction_bits
3087 if(to_fraction_bits<=from_fraction_bits)
3089 out <<
"((_ extract "
3090 << (from_fraction_bits-1) <<
" "
3091 << (from_fraction_bits-to_fraction_bits)
3097 to_fraction_bits > from_fraction_bits,
3098 "to_fraction_bits should be greater than from_fraction_bits as the"
3099 "other case has been handled above");
3100 out <<
"(concat ((_ extract "
3101 << (from_fraction_bits-1) <<
" 0) ";
3104 <<
" (_ bv0 " << to_fraction_bits-from_fraction_bits
3113 else if(dest_type.
id()==ID_pointer)
3117 if(src_type.
id()==ID_pointer)
3123 src_type.
id() == ID_unsignedbv || src_type.
id() == ID_signedbv ||
3124 src_type.
id() == ID_bv)
3130 if(from_width==to_width)
3132 else if(from_width<to_width)
3134 out <<
"((_ sign_extend "
3135 << (to_width-from_width)
3142 out <<
"((_ extract " << to_width <<
" 0) ";
3150 else if(dest_type.
id()==ID_range)
3153 const auto dest_size =
3154 dest_range_type.get_to() - dest_range_type.get_from() + 1;
3156 if(src_type.
id() == ID_range)
3159 const auto src_size =
3160 src_range_type.get_to() - src_range_type.get_from() + 1;
3162 if(src_width < dest_width)
3164 out <<
"((_ zero_extend " << dest_width - src_width <<
") ";
3168 else if(src_width > dest_width)
3170 out <<
"((_ extract " << dest_width - 1 <<
" 0) ";
3182 else if(dest_type.
id()==ID_floatbv)
3191 if(src_type.
id()==ID_bool)
3201 else if(src_type.
id()==ID_c_bool)
3207 else if(src_type.
id() == ID_bv)
3216 out <<
"((_ to_fp " << dest_floatbv_type.get_e() <<
" "
3217 << dest_floatbv_type.get_f() + 1 <<
") ";
3227 else if(dest_type.
id() == ID_integer || dest_type.
id() == ID_natural)
3229 if(src_type.
id()==ID_bool)
3238 else if(dest_type.
id()==ID_c_bit_field)
3243 if(from_width==to_width)
3252 else if(dest_type.
id() == ID_rational)
3254 if(src_type.
id() == ID_signedbv)
3263 "Unknown typecast " + src_type.
id_string() +
" -> rational");
3277 if(dest_type.
id()==ID_floatbv)
3279 if(src_type.
id()==ID_floatbv)
3306 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3307 << dst.
get_f() + 1 <<
") ";
3316 else if(src_type.
id()==ID_unsignedbv)
3337 out <<
"((_ to_fp_unsigned " << dst.
get_e() <<
" "
3338 << dst.
get_f() + 1 <<
") ";
3347 else if(src_type.
id()==ID_signedbv)
3355 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3356 << dst.
get_f() + 1 <<
") ";
3365 else if(src_type.
id()==ID_c_enum_tag)
3379 else if(dest_type.
id()==ID_signedbv)
3384 out <<
"((_ fp.to_sbv " << dest_width <<
") ";
3393 else if(dest_type.
id()==ID_unsignedbv)
3398 out <<
"((_ fp.to_ubv " << dest_width <<
") ";
3421 out <<
"(fp.roundToIntegral ";
3434 expr.
type().
id() == ID_struct_tag
3442 components.size() == expr.
operands().size(),
3443 "number of struct components as indicated by the struct type shall be equal"
3444 "to the number of operands of the struct expression");
3446 DATA_INVARIANT(!components.empty(),
"struct shall have struct components");
3450 const std::string &smt_typename =
datatype_map.at(struct_type);
3453 out <<
"(mk-" << smt_typename;
3456 for(struct_typet::componentst::const_iterator
3457 it=components.begin();
3458 it!=components.end();
3471 auto convert_operand = [
this](
const exprt &op) {
3475 else if(op.type().id() == ID_bool)
3482 std::size_t n_concat = 0;
3483 for(std::size_t i = components.size(); i > 1; i--)
3493 convert_operand(expr.
operands()[i - 1]);
3499 convert_operand(expr.
op0());
3501 out << std::string(n_concat,
')');
3509 const auto &size_expr = array_type.
size();
3515 out <<
"(let ((?far ";
3523 out <<
"(select ?far ";
3545 if(total_width==member_width)
3553 total_width > member_width,
3554 "total_width should be greater than member_width as member_width can be"
3555 "at most as large as total_width and the other case has been handled "
3559 << (total_width-member_width) <<
") ";
3569 if(expr_type.
id()==ID_unsignedbv ||
3570 expr_type.
id()==ID_signedbv ||
3571 expr_type.
id()==ID_bv ||
3572 expr_type.
id()==ID_c_enum ||
3573 expr_type.
id()==ID_c_enum_tag ||
3574 expr_type.
id()==ID_c_bool ||
3575 expr_type.
id()==ID_c_bit_field)
3581 out <<
"(_ bv" << value
3582 <<
" " << width <<
")";
3584 else if(expr_type.
id()==ID_fixedbv)
3590 out <<
"(_ bv" << v <<
" " << spec.
width <<
")";
3592 else if(expr_type.
id()==ID_floatbv)
3605 size_t e=floatbv_type.
get_e();
3606 size_t f=floatbv_type.
get_f()+1;
3612 out <<
"((_ to_fp " << e <<
" " << f <<
")"
3618 out <<
"(_ NaN " << e <<
" " << f <<
")";
3623 out <<
"(_ -oo " << e <<
" " << f <<
")";
3625 out <<
"(_ +oo " << e <<
" " << f <<
")";
3635 <<
"#b" << binaryString.substr(0, 1) <<
" "
3636 <<
"#b" << binaryString.substr(1, e) <<
" "
3637 <<
"#b" << binaryString.substr(1+e, f-1) <<
")";
3645 out <<
"(_ bv" << v <<
" " << spec.
width() <<
")";
3648 else if(expr_type.
id()==ID_pointer)
3662 out <<
"(_ bv" << value <<
" " << width <<
")";
3665 else if(expr_type.
id()==ID_bool)
3669 else if(expr ==
false)
3674 else if(expr_type.
id()==ID_array)
3680 else if(expr_type.
id()==ID_rational)
3683 const bool negative =
has_prefix(value,
"-");
3688 value = value.substr(1);
3691 size_t pos=value.find(
"/");
3693 if(
pos==std::string::npos)
3694 out << value <<
".0";
3697 out <<
"(/ " << value.substr(0,
pos) <<
".0 "
3698 << value.substr(
pos+1) <<
".0)";
3704 else if(expr_type.
id() == ID_real)
3708 if(value.find(
'.') == std::string::npos)
3711 else if(expr_type.
id()==ID_integer)
3717 out <<
"(- " << value.substr(1, std::string::npos) <<
')';
3721 else if(expr_type.
id() == ID_natural)
3725 else if(expr_type.
id() == ID_range)
3728 const auto size = range_type.get_to() - range_type.get_from() + 1;
3731 out <<
"(_ bv" << (value_int - range_type.get_from()) <<
" " << width
3740 if(expr.
type().
id() == ID_integer)
3750 "unsupported type for euclidean_mod: " + expr.
type().
id_string());
3755 if(expr.
type().
id()==ID_unsignedbv ||
3756 expr.
type().
id()==ID_signedbv)
3758 if(expr.
type().
id()==ID_unsignedbv)
3774 std::vector<mp_integer> dynamic_objects;
3777 if(dynamic_objects.empty())
3783 out <<
"(let ((?obj ((_ extract "
3784 << pointer_width-1 <<
" "
3785 << pointer_width-
config.bv_encoding.object_bits <<
") ";
3789 if(dynamic_objects.size()==1)
3791 out <<
"(= (_ bv" << dynamic_objects.front()
3792 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3798 for(
const auto &
object : dynamic_objects)
3799 out <<
" (= (_ bv" <<
object
3800 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3814 op_type.
id() == ID_unsignedbv || op_type.
id() == ID_bv ||
3815 op_type.
id() == ID_range)
3819 if(expr.
id()==ID_le)
3821 else if(expr.
id()==ID_lt)
3823 else if(expr.
id()==ID_ge)
3825 else if(expr.
id()==ID_gt)
3834 else if(op_type.
id()==ID_signedbv ||
3835 op_type.
id()==ID_fixedbv)
3838 if(expr.
id()==ID_le)
3840 else if(expr.
id()==ID_lt)
3842 else if(expr.
id()==ID_ge)
3844 else if(expr.
id()==ID_gt)
3853 else if(op_type.
id()==ID_floatbv)
3858 if(expr.
id()==ID_le)
3860 else if(expr.
id()==ID_lt)
3862 else if(expr.
id()==ID_ge)
3864 else if(expr.
id()==ID_gt)
3877 op_type.
id() == ID_rational || op_type.
id() == ID_integer ||
3878 op_type.
id() == ID_natural || op_type.
id() == ID_real)
3889 else if(op_type.
id() == ID_pointer)
3897 if(expr.
id() == ID_le)
3899 else if(expr.
id() == ID_lt)
3901 else if(expr.
id() == ID_ge)
3903 else if(expr.
id() == ID_gt)
3922 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
3923 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
3928 for(
const auto &op : expr.
operands())
3937 expr.
type().
id() == ID_unsignedbv || expr.
type().
id() == ID_signedbv ||
3938 expr.
type().
id() == ID_fixedbv)
3955 else if(expr.
type().
id() == ID_range)
3965 const auto size = range_type.get_to() - range_type.get_from() + 1;
3972 out <<
" (_ bv" << range_type.get_from() <<
' ' << width
3980 else if(expr.
type().
id() == ID_floatbv)
3987 else if(expr.
type().
id() == ID_pointer)
3993 if(p.
type().
id() != ID_pointer)
3997 p.
type().
id() == ID_pointer,
3998 "one of the operands should have pointer type");
4002 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4005 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
4009 out <<
"(let ((?pointerop ";
4015 const std::size_t offset_bits =
4016 pointer_width -
config.bv_encoding.object_bits;
4019 out <<
"((_ extract " << pointer_width - 1 <<
' ' << offset_bits
4020 <<
") ?pointerop) ";
4021 out <<
"(bvadd ((_ extract " << offset_bits - 1 <<
" 0) ?pointerop) ";
4023 if(element_size >= 2)
4025 out <<
"(bvmul ((_ extract " << offset_bits - 1 <<
" 0) ";
4027 out <<
") (_ bv" << element_size <<
" " << offset_bits <<
"))";
4031 out <<
"((_ extract " << offset_bits - 1 <<
" 0) ";
4070 out <<
"roundNearestTiesToEven";
4072 out <<
"roundTowardNegative";
4074 out <<
"roundTowardPositive";
4076 out <<
"roundTowardZero";
4078 out <<
"roundNearestTiesToAway";
4082 "Rounding mode should have value 0, 1, 2, 3, or 4",
4090 out <<
"(ite (= (_ bv0 " << width <<
") ";
4092 out <<
") roundNearestTiesToEven ";
4094 out <<
"(ite (= (_ bv1 " << width <<
") ";
4096 out <<
") roundTowardNegative ";
4098 out <<
"(ite (= (_ bv2 " << width <<
") ";
4100 out <<
") roundTowardPositive ";
4102 out <<
"(ite (= (_ bv3 " << width <<
") ";
4104 out <<
") roundTowardZero ";
4107 out <<
"roundNearestTiesToAway";
4118 type.
id() == ID_floatbv ||
4119 (type.
id() == ID_complex &&
4124 if(type.
id()==ID_floatbv)
4134 else if(type.
id()==ID_complex)
4141 "type should not be one of the unsupported types",
4151 expr.
type().
id() == ID_integer || expr.
type().
id() == ID_natural ||
4152 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_real)
4160 else if(expr.
type().
id()==ID_unsignedbv ||
4161 expr.
type().
id()==ID_signedbv ||
4162 expr.
type().
id()==ID_fixedbv)
4164 if(expr.
op0().
type().
id()==ID_pointer &&
4170 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4172 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
4175 if(element_size >= 2)
4180 "bitvector width of operand shall be equal to the bitvector width of "
4189 if(element_size >= 2)
4202 else if(expr.
type().
id()==ID_floatbv)
4209 else if(expr.
type().
id()==ID_pointer)
4213 (expr.
op1().
type().
id() == ID_unsignedbv ||
4225 else if(expr.
type().
id() == ID_range)
4231 const auto size = range_type.get_to() - range_type.get_from() + 1;
4234 out <<
"(bvsub (bvsub ";
4238 out <<
") (_ bv" << range_type.get_from() <<
' ' << width
4248 expr.
type().
id() == ID_floatbv,
4249 "type of ieee floating point expression shall be floatbv");
4267 if(expr.
type().
id()==ID_unsignedbv ||
4268 expr.
type().
id()==ID_signedbv)
4270 if(expr.
type().
id()==ID_unsignedbv)
4280 else if(expr.
type().
id()==ID_fixedbv)
4285 out <<
"((_ extract " << spec.
width-1 <<
" 0) ";
4290 out <<
" (_ bv0 " << fraction_bits <<
")) ";
4292 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4298 else if(expr.
type().
id()==ID_floatbv)
4306 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4307 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4322 expr.
type().
id() == ID_floatbv,
4323 "type of ieee floating point expression shall be floatbv");
4354 "expression should have been converted to a variant with two operands");
4356 if(expr.
type().
id()==ID_unsignedbv ||
4357 expr.
type().
id()==ID_signedbv)
4368 else if(expr.
type().
id()==ID_floatbv)
4375 else if(expr.
type().
id()==ID_fixedbv)
4380 out <<
"((_ extract "
4381 << spec.
width+fraction_bits-1 <<
" "
4382 << fraction_bits <<
") ";
4386 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4390 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4397 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4398 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4402 for(
const auto &op : expr.
operands())
4417 expr.
type().
id() == ID_floatbv,
4418 "type of ieee floating point expression shall be floatbv");
4437 expr.
type().
id() == ID_floatbv,
4438 "type of ieee floating point expression shall be floatbv");
4452 "smt2_convt::convert_floatbv_rem to be implemented when not using "
4461 "with expression should have exactly three operands");
4465 if(expr_type.
id()==ID_array)
4489 out <<
"(let ((distance? ";
4490 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4494 if(array_width>index_width)
4496 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4502 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4512 out <<
"(bvshl (_ bv" <<
power(2, sub_width) - 1 <<
" " << array_width
4514 out <<
"distance?)) ";
4518 out <<
"((_ zero_extend " << array_width-sub_width <<
") ";
4520 out <<
") distance?)))";
4523 else if(expr_type.
id() == ID_struct || expr_type.
id() == ID_struct_tag)
4526 expr_type.
id() == ID_struct_tag
4533 const irep_idt &component_name=index.
get(ID_component_name);
4537 "struct should have accessed component");
4541 const std::string &smt_typename =
datatype_map.at(expr_type);
4543 out <<
"(update-" << smt_typename <<
"." << component_name <<
" ";
4551 auto convert_operand = [
this](
const exprt &op)
4556 else if(op.type().id() == ID_bool)
4568 if(m.
width==struct_width)
4571 convert_operand(value);
4575 out <<
"(let ((?withop ";
4576 convert_operand(expr.
old());
4583 <<
"((_ extract " << (struct_width - 1) <<
" " << m.
width
4585 convert_operand(value);
4592 convert_operand(value);
4593 out <<
" ((_ extract " << (m.
offset - 1) <<
" 0) ?withop))";
4598 out <<
"(concat (concat "
4599 <<
"((_ extract " << (struct_width - 1) <<
" "
4601 convert_operand(value);
4602 out <<
") ((_ extract " << (m.
offset - 1) <<
" 0) ?withop)";
4610 else if(expr_type.
id() == ID_union || expr_type.
id() == ID_union_tag)
4618 if(total_width==member_width)
4625 total_width > member_width,
4626 "total width should be greater than member_width as member_width is at "
4627 "most as large as total_width and the other case has been handled "
4630 out <<
"((_ extract "
4632 <<
" " << member_width <<
") ";
4639 else if(expr_type.
id()==ID_bv ||
4640 expr_type.
id()==ID_unsignedbv ||
4641 expr_type.
id()==ID_signedbv)
4656 "with expects struct, union, or array type, but got "+
4664 SMT2_TODO(
"smt2_convt::convert_update to be implemented");
4681 if(array_op_type.
id()==ID_array)
4716 out <<
"((_ extract " << sub_width-1 <<
" 0) ";
4720 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4724 if(array_width>index_width)
4726 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4732 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4744 false,
"index with unsupported array type: " + array_op_type.
id_string());
4751 const typet &struct_op_type = struct_op.
type();
4754 if(struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag)
4757 struct_op_type.
id() == ID_struct_tag
4762 struct_type.
has_component(name),
"struct should have accessed component");
4766 const std::string &smt_typename =
datatype_map.at(struct_type);
4768 out <<
"(" << smt_typename <<
"."
4779 if(expr.
type().
id() == ID_bool)
4785 if(expr.
type().
id() == ID_bool)
4790 struct_op_type.
id() == ID_union || struct_op_type.
id() == ID_union_tag)
4794 width != 0,
"failed to get union member width");
4800 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4808 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4815 "convert_member on an unexpected type "+struct_op_type.
id_string());
4822 if(type.
id()==ID_bool)
4828 else if(type.
id()==ID_array)
4839 std::size_t n_concat = 0;
4853 out << std::string(n_concat,
')');
4858 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4871 std::size_t n_concat = 0;
4872 for(std::size_t i=components.size(); i>1; i--)
4892 out << std::string(n_concat,
')');
4897 else if(type.
id()==ID_floatbv)
4901 "floatbv expressions should be flattened when using FPA theory");
4914 if(type.
id()==ID_bool)
4921 else if(type.
id() == ID_array)
4926 out <<
"(let ((?ufop" << nesting <<
" ";
4937 "cannot unflatten arrays of non-constant size");
4944 out <<
"((as const ";
4949 out <<
"((_ extract " << subtype_width - 1 <<
" "
4950 <<
"0) ?ufop" << nesting <<
")";
4954 std::size_t offset = subtype_width;
4955 for(
mp_integer i = 1; i < size; ++i, offset += subtype_width)
4960 out <<
"((_ extract " << offset + subtype_width - 1 <<
" " << offset
4961 <<
") ?ufop" << nesting <<
")";
4969 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4975 out <<
"(let ((?ufop" << nesting <<
" ";
4980 const std::string &smt_typename =
datatype_map.at(type);
4982 out <<
"(mk-" << smt_typename;
4991 std::size_t offset=0;
4994 for(struct_typet::componentst::const_iterator
4995 it=components.begin();
4996 it!=components.end();
5006 out <<
"((_ extract " << offset+member_width-1 <<
" "
5007 << offset <<
") ?ufop" << nesting <<
")";
5009 offset+=member_width;
5030 if(expr.
id()==ID_and && value)
5032 for(
const auto &op : expr.
operands())
5037 if(expr.
id()==ID_or && !value)
5039 for(
const auto &op : expr.
operands())
5044 if(expr.
id()==ID_not)
5054 if(expr.
id() == ID_equal && value)
5063 if(equal_expr.
lhs().
id()==ID_symbol)
5070 equal_expr.
lhs() != equal_expr.
rhs())
5082 out <<
"; set_to true (equal)\n";
5084 if(equal_expr.
lhs().
type().
id() == ID_mathematical_function)
5088 out <<
"(declare-fun " << smt2_identifier;
5090 auto &mathematical_function_type =
5096 for(
auto &t : mathematical_function_type.domain())
5110 out <<
"(assert (= " << smt2_identifier <<
' ';
5112 out <<
')' <<
')' <<
'\n';
5116 out <<
"(define-fun " << smt2_identifier;
5121 equal_expr.
lhs().
type().
id() != ID_array ||
5149 out <<
"; set_to " << (value?
"true":
"false") <<
"\n"
5160 out << found_literal->second;
5183 exprt lowered_expr = expr;
5190 it->id() == ID_byte_extract_little_endian ||
5191 it->id() == ID_byte_extract_big_endian)
5196 it->id() == ID_byte_update_little_endian ||
5197 it->id() == ID_byte_update_big_endian)
5203 return lowered_expr;
5220 "lower_byte_operators should remove all byte operators");
5227 auto prophecy_r_or_w_ok =
5231 it.mutate() = lowered;
5232 it.next_sibling_or_parent();
5235 auto prophecy_pointer_in_range =
5239 it.mutate() = lowered;
5240 it.next_sibling_or_parent();
5249 return lowered_expr;
5260 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
5262 std::unordered_map<irep_idt, std::optional<identifiert>> shadowed_syms;
5267 for(
const auto &symbol : q_expr.variables())
5269 const auto identifier = symbol.get_identifier();
5272 shadowed_syms.insert(
5274 id_entry.second ? std::nullopt
5275 : std::optional{id_entry.first->second}});
5278 for(
const auto &[
id, shadowed_val] : shadowed_syms)
5281 if(!shadowed_val.has_value())
5284 previous_entry->second = std::move(*shadowed_val);
5290 for(
const auto &op : expr.
operands())
5293 if(expr.
id()==ID_symbol ||
5294 expr.
id()==ID_nondet_symbol)
5297 if(expr.
type().
id()==ID_code)
5302 if(expr.
id()==ID_symbol)
5305 identifier=
"nondet_"+
5316 out <<
"; find_symbols\n";
5317 out <<
"(declare-fun " << smt2_identifier;
5319 if(expr.
type().
id() == ID_mathematical_function)
5321 auto &mathematical_function_type =
5326 for(
auto &type : mathematical_function_type.domain())
5347 else if(expr.
id() == ID_array_of)
5354 const auto &array_type = array_of.type();
5358 out <<
"; the following is a substitute for lambda i. x\n";
5359 out <<
"(declare-fun " <<
id <<
" () ";
5366 out <<
"(assert (forall ((i ";
5368 out <<
")) (= (select " <<
id <<
" i) ";
5386 else if(expr.
id() == ID_array_comprehension)
5393 const auto &array_type = array_comprehension.type();
5394 const auto &array_size = array_type.size();
5398 out <<
"(declare-fun " <<
id <<
" () ";
5402 out <<
"; the following is a substitute for lambda i . x(i)\n";
5403 out <<
"; universally quantified initialization of the array\n";
5404 out <<
"(assert (forall ((";
5408 out <<
")) (=> (and (bvule (_ bv0 " <<
boolbv_width(array_size.type())
5415 out <<
")) (= (select " <<
id <<
" ";
5434 else if(expr.
id()==ID_array)
5441 out <<
"; the following is a substitute for an array constructor" <<
"\n";
5442 out <<
"(declare-fun " <<
id <<
" () ";
5448 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5450 out <<
"(assert (= (select " <<
id <<
" ";
5471 else if(expr.
id()==ID_string_constant)
5481 out <<
"; the following is a substitute for a string" <<
"\n";
5482 out <<
"(declare-fun " <<
id <<
" () ";
5486 for(std::size_t i=0; i<tmp.
operands().size(); i++)
5488 out <<
"(assert (= (select " <<
id <<
' ';
5492 out <<
"))" <<
"\n";
5505 out <<
"(declare-fun " <<
id <<
" () ";
5516 (expr.
id() == ID_floatbv_plus ||
5517 expr.
id() == ID_floatbv_minus ||
5518 expr.
id() == ID_floatbv_mult ||
5519 expr.
id() == ID_floatbv_div ||
5520 expr.
id() == ID_floatbv_typecast ||
5521 expr.
id() == ID_ieee_float_equal ||
5522 expr.
id() == ID_ieee_float_notequal ||
5523 ((expr.
id() == ID_lt ||
5524 expr.
id() == ID_gt ||
5525 expr.
id() == ID_le ||
5526 expr.
id() == ID_ge ||
5527 expr.
id() == ID_isnan ||
5528 expr.
id() == ID_isnormal ||
5529 expr.
id() == ID_isfinite ||
5530 expr.
id() == ID_isinf ||
5531 expr.
id() == ID_sign ||
5532 expr.
id() == ID_unary_minus ||
5533 expr.
id() == ID_typecast ||
5534 expr.
id() == ID_abs) &&
5541 if(
bvfp_set.insert(function).second)
5543 out <<
"; this is a model for " << expr.
id() <<
" : "
5546 <<
"(define-fun " << function <<
" (";
5548 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5552 out <<
"(op" << i <<
' ';
5562 for(std::size_t i = 0; i < tmp1.
operands().size(); i++)
5578 expr.
type().
id() == ID_bv)
5588 out <<
"(declare-fun " <<
id <<
" () ";
5594 out <<
"(assert (= ";
5595 out <<
"((_ to_fp " << floatbv_type.get_e() <<
" "
5596 << floatbv_type.get_f() + 1 <<
") " <<
id <<
')';
5604 else if(expr.
id() == ID_initial_state)
5606 irep_idt function =
"initial-state";
5610 out <<
"(declare-fun " << function <<
" (";
5617 else if(expr.
id() == ID_evaluate)
5623 out <<
"(declare-fun " << function <<
" (";
5633 expr.
id() == ID_state_is_cstring ||
5634 expr.
id() == ID_state_is_dynamic_object ||
5635 expr.
id() == ID_state_live_object || expr.
id() == ID_state_writeable_object)
5638 expr.
id() == ID_state_is_cstring ?
"state-is-cstring"
5639 : expr.
id() == ID_state_is_dynamic_object ?
"state-is-dynamic-object"
5640 : expr.
id() == ID_state_live_object ?
"state-live-object"
5641 :
"state-writeable-object";
5645 out <<
"(declare-fun " << function <<
" (";
5655 expr.
id() == ID_state_r_ok || expr.
id() == ID_state_w_ok ||
5656 expr.
id() == ID_state_rw_ok)
5658 irep_idt function = expr.
id() == ID_state_r_ok ?
"state-r-ok"
5659 : expr.
id() == ID_state_w_ok ?
"state-w-ok"
5664 out <<
"(declare-fun " << function <<
" (";
5675 else if(expr.
id() == ID_update_state)
5682 out <<
"(declare-fun " << function <<
" (";
5693 else if(expr.
id() == ID_enter_scope_state)
5700 out <<
"(declare-fun " << function <<
" (";
5711 else if(expr.
id() == ID_exit_scope_state)
5718 out <<
"(declare-fun " << function <<
" (";
5727 else if(expr.
id() == ID_allocate)
5733 out <<
"(declare-fun " << function <<
" (";
5742 else if(expr.
id() == ID_reallocate)
5748 out <<
"(declare-fun " << function <<
" (";
5759 else if(expr.
id() == ID_deallocate_state)
5765 out <<
"(declare-fun " << function <<
" (";
5774 else if(expr.
id() == ID_object_address)
5776 irep_idt function =
"object-address";
5780 out <<
"(declare-fun " << function <<
" (String) ";
5785 else if(expr.
id() == ID_field_address)
5791 out <<
"(declare-fun " << function <<
" (";
5800 else if(expr.
id() == ID_element_address)
5806 out <<
"(declare-fun " << function <<
" (";
5825 if(expr.
id() == ID_with)
5833 if(type.
id()==ID_array)
5847 out <<
"(_ BitVec 1)";
5853 else if(type.
id()==ID_bool)
5857 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5867 out <<
"(_ BitVec " << width <<
")";
5870 else if(type.
id()==ID_code)
5877 else if(type.
id() == ID_union || type.
id() == ID_union_tag)
5884 union_type.
components().empty() || width != 0,
5885 "failed to get width of union");
5887 out <<
"(_ BitVec " << width <<
")";
5889 else if(type.
id()==ID_pointer)
5894 else if(type.
id()==ID_bv ||
5895 type.
id()==ID_fixedbv ||
5896 type.
id()==ID_unsignedbv ||
5897 type.
id()==ID_signedbv ||
5898 type.
id()==ID_c_bool)
5903 else if(type.
id()==ID_c_enum)
5910 else if(type.
id()==ID_c_enum_tag)
5914 else if(type.
id()==ID_floatbv)
5919 out <<
"(_ FloatingPoint "
5920 << floatbv_type.
get_e() <<
" "
5921 << floatbv_type.
get_f() + 1 <<
")";
5926 else if(type.
id()==ID_rational ||
5929 else if(type.
id()==ID_integer)
5931 else if(type.
id() == ID_natural)
5933 else if(type.
id()==ID_complex)
5943 out <<
"(_ BitVec " << width <<
")";
5946 else if(type.
id()==ID_c_bit_field)
5950 else if(type.
id() == ID_state)
5954 else if(type.
id() == ID_range)
5957 mp_integer size = range_type.get_to() - range_type.get_from() + 1;
5970 std::set<irep_idt> recstack;
5976 std::set<irep_idt> &recstack)
5978 if(type.
id()==ID_array)
5984 else if(type.
id()==ID_complex)
5991 const std::string smt_typename =
5995 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
5996 <<
"(((mk-" << smt_typename;
5998 out <<
" (" << smt_typename <<
".imag ";
6002 out <<
" (" << smt_typename <<
".real ";
6009 else if(type.
id() == ID_struct)
6012 bool need_decl=
false;
6016 const std::string smt_typename =
6031 const std::string &smt_typename =
datatype_map.at(type);
6042 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6043 <<
"(((mk-" << smt_typename <<
" ";
6050 out <<
"(" << smt_typename <<
"." <<
component.get_name()
6056 out <<
"))))" <<
"\n";
6073 for(struct_union_typet::componentst::const_iterator
6074 it=components.begin();
6075 it!=components.end();
6082 out <<
"(define-fun update-" << smt_typename <<
"."
6084 <<
"((s " << smt_typename <<
") "
6087 out <<
")) " << smt_typename <<
" "
6088 <<
"(mk-" << smt_typename
6091 for(struct_union_typet::componentst::const_iterator
6092 it2=components.begin();
6093 it2!=components.end();
6100 out <<
"(" << smt_typename <<
"."
6101 << it2->get_name() <<
" s) ";
6105 out <<
"))" <<
"\n";
6111 else if(type.
id() == ID_union)
6119 else if(type.
id()==ID_code)
6123 for(
const auto ¶m : parameters)
6128 else if(type.
id()==ID_pointer)
6132 else if(type.
id() == ID_struct_tag)
6135 const irep_idt &
id = struct_tag.get_identifier();
6137 if(recstack.find(
id) == recstack.end())
6139 const auto &base_struct =
ns.follow_tag(struct_tag);
6140 recstack.insert(
id);
6145 else if(type.
id() == ID_union_tag)
6148 const irep_idt &
id = union_tag.get_identifier();
6150 if(recstack.find(
id) == recstack.end())
6152 recstack.insert(
id);
6156 else if(type.
id() == ID_state)
6161 out <<
"(declare-sort state 0)\n";
6164 else if(type.
id() == ID_mathematical_function)
6166 const auto &mathematical_function_type =
6168 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
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)
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_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_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)