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,
160 "variable number shall be within bounds");
166 out <<
"; SMT 2" <<
"\n";
175 out <<
"; Generated for the CPROVER SMT2 solver\n";
break;
183 out <<
"(set-info :source \"" <<
notes <<
"\")" <<
"\n";
185 out <<
"(set-option :produce-models true)" <<
"\n";
191 out <<
"(set-logic " <<
logic <<
")" <<
"\n";
206 out <<
"(check-sat-assuming (";
216 out <<
"; assumptions\n";
227 out <<
"(check-sat)\n";
238 out <<
"(get-value (" <<
id <<
"))"
246 out <<
"; end of SMT2 file"
256 std::size_t number = 0;
257 std::size_t h=pointer_width-1;
258 std::size_t l=pointer_width-
config.bv_encoding.object_bits;
262 const typet &type = o.type();
266 (o.id() != ID_symbol && o.id() != ID_string_constant) ||
267 !size_expr.has_value())
274 out <<
"(assert (=> (= "
275 <<
"((_ extract " << h <<
" " << l <<
") ";
277 out <<
") (_ bv" << number <<
" " <<
config.bv_encoding.object_bits <<
"))"
278 <<
"(= " <<
id <<
" ";
303 if(expr.
id()==ID_symbol)
310 return it->second.value;
313 else if(expr.
id()==ID_nondet_symbol)
320 return it->second.value;
322 else if(expr.
id() == ID_literal)
330 else if(expr.
id() == ID_not)
340 (!expr.
has_operands() && (expr.
id() == ID_struct || expr.
id() == ID_array)))
352 op = std::move(eval_op);
387 if(s.size()>=2 && s[0]==
'#' && s[1]==
'b')
392 else if(s.size()>=2 && s[0]==
'#' && s[1]==
'x')
399 std::size_t
pos = s.find(
".");
400 if(
pos != std::string::npos)
403 if(type.
id() == ID_rational)
411 else if(type.
id() == ID_real)
422 "smt2_convt::parse_literal parsed a number with a decimal point "
431 else if(src.
get_sub().size()==2 &&
436 else if(src.
get_sub().size()==3 &&
439 src.
get_sub()[1].id_string().substr(0, 2)==
"bv")
444 type.
id() == ID_rational && src.
get_sub().size() == 3 &&
455 else if(src.
get_sub().size()==4 &&
458 if(type.
id()==ID_floatbv)
473 s1_int << (floatbv_type.
get_e() + floatbv_type.
get_f()),
479 else if(src.
get_sub().size()==4 &&
488 else if(src.
get_sub().size()==4 &&
497 else if(src.
get_sub().size()==4 &&
507 src.
get_sub()[0].id() ==
"root-obj")
520 src.
get_sub()[1].id().empty() && src.
get_sub()[1].get_sub().size() == 3 &&
521 src.
get_sub()[1].get_sub()[0].id() ==
"+",
522 "unexpected root-obj expression",
529 !
failed,
"failed to parse rational constant coefficient", src.
pretty());
533 sum_lhs.
get_sub()[0].id() ==
"^" && sum_lhs.
get_sub()[1].id() ==
"x",
534 "unexpected first operand to root-obj",
538 degree > 0,
"polynomial degree must be positive", src.
pretty());
539 std::vector<rationalt> coefficients{degree + 1,
rationalt{}};
540 coefficients.front() = constant_coeff;
546 if(type.
id()==ID_signedbv ||
547 type.
id()==ID_unsignedbv ||
548 type.
id()==ID_c_enum ||
549 type.
id()==ID_c_bool)
553 else if(type.
id()==ID_c_enum_tag)
559 result.
type() = type;
562 else if(type.
id()==ID_fixedbv ||
563 type.
id()==ID_floatbv)
569 type.
id() == ID_integer || type.
id() == ID_natural ||
570 type.
id() == ID_rational || type.
id() == ID_real)
574 else if(type.
id() == ID_range)
580 "smt2_convt::parse_literal should not be of unsupported type " +
588 std::unordered_map<int64_t, exprt> operands_map;
592 auto maybe_default_op = operands_map.find(-1);
594 if(maybe_default_op == operands_map.end())
597 default_op = maybe_default_op->second;
600 if(maybe_size.has_value())
602 while(i < maybe_size.value())
604 auto found_op = operands_map.find(i);
605 if(found_op != operands_map.end())
606 operands.emplace_back(found_op->second);
608 operands.emplace_back(default_op);
616 auto found_op = operands_map.find(i);
617 while(found_op != operands_map.end())
619 operands.emplace_back(found_op->second);
621 found_op = operands_map.find(i);
623 operands.emplace_back(default_op);
629 std::unordered_map<int64_t, exprt> *operands_map,
642 bool failure =
to_integer(index_constant, tempint);
645 long index = tempint.to_long();
647 operands_map->emplace(index, value);
649 else if(src.
get_sub().size()==2 &&
650 src.
get_sub()[0].get_sub().size()==3 &&
651 src.
get_sub()[0].get_sub()[0].id()==
"as" &&
652 src.
get_sub()[0].get_sub()[1].id()==
"const")
656 operands_map->emplace(-1, default_value);
689 if(components.empty())
697 for(std::size_t i=0; i<components.size(); i++)
707 src.
get_sub().size() > j,
"insufficient number of component values");
724 std::size_t offset=0;
726 for(std::size_t i=0; i<components.size(); i++)
731 std::size_t component_width=
boolbv_width(components[i].type());
734 offset + component_width <= total_width,
735 "struct component bits shall be within struct bit vector");
737 std::string component_binary=
739 total_width-offset-component_width, component_width);
744 offset+=component_width;
758 for(
const auto &binding : src.
get_sub()[1].get_sub())
760 const irep_idt &name = binding.get_sub()[0].id();
771 return parse_rec(bindings_it->second, type);
775 type.
id() == ID_signedbv || type.
id() == ID_unsignedbv ||
776 type.
id() == ID_integer || type.
id() == ID_rational ||
777 type.
id() == ID_natural || type.
id() == ID_real || type.
id() == ID_c_enum ||
778 type.
id() == ID_c_enum_tag || type.
id() == ID_fixedbv ||
779 type.
id() == ID_floatbv || type.
id() == ID_c_bool || type.
id() == ID_range)
783 else if(type.
id()==ID_bool)
785 if(src.
id()==ID_1 || src.
id()==ID_true)
787 else if(src.
id()==ID_0 || src.
id()==ID_false)
790 else if(type.
id()==ID_pointer)
805 else if(type.
id()==ID_struct)
809 else if(type.
id() == ID_struct_tag)
814 struct_expr.type() = type;
815 return std::move(struct_expr);
817 else if(type.
id()==ID_union)
821 else if(type.
id() == ID_union_tag)
825 union_expr.type() = type;
828 else if(type.
id()==ID_array)
842 expr.
id() == ID_string_constant || expr.
id() == ID_label)
844 const std::size_t object_bits =
config.bv_encoding.object_bits;
845 const std::size_t max_objects = std::size_t(1) << object_bits;
848 if(object_id >= max_objects)
851 "too many addressed objects: maximum number of objects is set to 2^n=" +
852 std::to_string(max_objects) +
853 " (with n=" + std::to_string(object_bits) +
"); " +
854 "use the `--object-bits n` option to increase the maximum number"};
857 out <<
"(concat (_ bv" << object_id <<
" " << object_bits <<
")"
858 <<
" (_ bv0 " <<
boolbv_width(result_type) - object_bits <<
"))";
860 else if(expr.
id()==ID_index)
869 if(array.
type().
id()==ID_pointer)
871 else if(array.
type().
id()==ID_array)
891 else if(expr.
id()==ID_member)
896 const typet &struct_op_type = struct_op.
type();
899 struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag,
900 "member expression operand shall have struct type");
903 struct_op_type.
id() == ID_struct_tag
920 else if(expr.
id()==ID_if)
935 "operand of address of expression should not be of kind " +
943 if(node.
id() == ID_exists || node.
id() == ID_forall)
957 else if(expr ==
false)
959 else if(expr.
id()==ID_literal)
971 out <<
"; convert\n";
972 out <<
"; Converting var_no " << l.
var_no() <<
" with expr ID of "
982 out <<
"(declare-fun ";
984 out <<
" () Bool)\n";
985 out <<
"(assert (= ";
997 out <<
"(define-fun " << identifier <<
" () Bool ";
1025 const auto identifier =
1047 for(
auto &assumption : _assumptions)
1058 if(identifier.empty())
1061 if(isdigit(identifier[0]))
1083 std::string result =
"|";
1085 for(
auto ch : identifier)
1093 result+=std::to_string(ch);
1110 if(type.
id()==ID_floatbv)
1113 return "f"+std::to_string(spec.
width())+
"_"+std::to_string(spec.
f);
1115 else if(type.
id() == ID_bv)
1119 else if(type.
id()==ID_unsignedbv)
1123 else if(type.
id()==ID_c_bool)
1127 else if(type.
id()==ID_signedbv)
1131 else if(type.
id()==ID_bool)
1135 else if(type.
id()==ID_c_enum_tag)
1139 else if(type.
id() == ID_pointer)
1143 else if(type.
id() == ID_struct_tag)
1150 else if(type.
id() == ID_union_tag)
1154 else if(type.
id() == ID_array)
1175 if(expr.
id()==ID_symbol)
1182 if(expr.
id()==ID_smt2_symbol)
1190 !expr.
operands().empty(),
"non-symbol expressions shall have operands");
1196 for(
const auto &op : expr.
operands())
1224 converter_result->second(expr);
1229 if(expr.
id()==ID_symbol)
1235 else if(expr.
id()==ID_nondet_symbol)
1238 DATA_INVARIANT(!
id.empty(),
"nondet symbol must have identifier");
1241 else if(expr.
id()==ID_smt2_symbol)
1247 else if(expr.
id()==ID_typecast)
1251 else if(expr.
id()==ID_floatbv_typecast)
1255 else if(expr.
id() == ID_floatbv_round_to_integral)
1259 else if(expr.
id()==ID_struct)
1263 else if(expr.
id()==ID_union)
1271 else if(expr.
id() == ID_concatenation)
1275 "concatenation expression should have at least one operand",
1280 for(
const auto &op : expr.
operands())
1283 non_zero_width_ops.push_back(op);
1287 !non_zero_width_ops.empty(),
1288 "concatenation must have at least one non-zero-width operand");
1290 if(non_zero_width_ops.size() == 1)
1299 for(
const auto &op : non_zero_width_ops)
1309 expr.
id() == ID_bitand || expr.
id() == ID_bitor || expr.
id() == ID_bitxor)
1313 "given expression should have at least one operand",
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)
1333 for(
const auto &op : expr.
operands())
1343 expr.
id() == ID_bitxnor || expr.
id() == ID_bitnand ||
1344 expr.
id() == ID_bitnor)
1353 if(binary_expr.id() == ID_bitxnor)
1355 else if(binary_expr.id() == ID_bitnand)
1357 else if(binary_expr.id() == ID_bitnor)
1365 else if(expr.
operands().size() == 1)
1371 else if(expr.
operands().size() >= 3)
1374 if(expr.
id() == ID_bitxnor)
1376 else if(expr.
id() == ID_bitnand)
1378 else if(expr.
id() == ID_bitnor)
1381 for(
const auto &op : expr.
operands())
1393 expr.
id_string() +
" should have at least one operand");
1396 else if(expr.
id()==ID_bitnot)
1404 else if(expr.
id()==ID_unary_minus)
1407 const auto &type = expr.
type();
1410 type.id() == ID_rational || type.id() == ID_integer ||
1411 type.id() == ID_real)
1417 else if(type.id() == ID_range)
1426 else if(type.id() == ID_floatbv)
1446 else if(expr.
id()==ID_unary_plus)
1451 else if(expr.
id()==ID_sign)
1457 if(op_type.
id()==ID_floatbv)
1461 out <<
"(fp.isNegative ";
1468 else if(op_type.
id()==ID_signedbv)
1474 out <<
" (_ bv0 " << op_width <<
"))";
1479 "sign should not be applied to unsupported type",
1482 else if(expr.
id()==ID_if)
1520 else if(expr.
id()==ID_and ||
1526 "logical and, or, and xor expressions should have Boolean type");
1529 "logical and, or, and xor expressions should have at least two operands");
1531 out <<
"(" << expr.
id();
1532 for(
const auto &op : expr.
operands())
1539 else if(expr.
id() == ID_nand || expr.
id() == ID_nor || expr.
id() == ID_xnor)
1543 "logical nand, nor, xnor expressions should have Boolean type");
1546 "logical nand, nor, xnor expressions should have at least one operand");
1554 if(expr.
id() == ID_nand)
1556 else if(expr.
id() == ID_nor)
1558 else if(expr.
id() == ID_xnor)
1562 for(
const auto &op : expr.
operands())
1571 else if(expr.
id()==ID_implies)
1576 implies_expr.
is_boolean(),
"implies expression should have Boolean type");
1584 else if(expr.
id()==ID_not)
1589 not_expr.
is_boolean(),
"not expression should have Boolean type");
1595 else if(expr.
id() == ID_equal)
1601 "operands of equal expression shall have same type");
1616 else if(expr.
id() == ID_notequal)
1622 "operands of not equal expression shall have same type");
1630 else if(expr.
id()==ID_ieee_float_equal ||
1631 expr.
id()==ID_ieee_float_notequal)
1638 rel_expr.lhs().type() == rel_expr.rhs().type(),
1639 "operands of float equal and not equal expressions shall have same type");
1644 if(rel_expr.id() == ID_ieee_float_notequal)
1653 if(rel_expr.id() == ID_ieee_float_notequal)
1659 else if(expr.
id()==ID_le ||
1666 else if(expr.
id()==ID_plus)
1670 else if(expr.
id()==ID_floatbv_plus)
1674 else if(expr.
id()==ID_minus)
1678 else if(expr.
id()==ID_floatbv_minus)
1682 else if(expr.
id()==ID_div)
1686 else if(expr.
id()==ID_floatbv_div)
1690 else if(expr.
id()==ID_mod)
1694 else if(expr.
id() == ID_euclidean_mod)
1698 else if(expr.
id()==ID_mult)
1702 else if(expr.
id()==ID_floatbv_mult)
1706 else if(expr.
id() == ID_floatbv_rem)
1710 else if(expr.
id() == ID_floatbv_fma)
1714 else if(expr.
id()==ID_address_of)
1720 else if(expr.
id() == ID_array_of)
1725 array_of_expr.type().id() == ID_array,
1726 "array of expression shall have array type");
1730 out <<
"((as const ";
1738 defined_expressionst::const_iterator it =
1744 else if(expr.
id() == ID_array_comprehension)
1749 array_comprehension.type().id() == ID_array,
1750 "array_comprehension expression shall have array type");
1754 out <<
"(lambda ((";
1757 convert_type(array_comprehension.type().size().type());
1769 else if(expr.
id()==ID_index)
1773 else if(expr.
id()==ID_ashr ||
1774 expr.
id()==ID_lshr ||
1780 if(type.
id()==ID_unsignedbv ||
1781 type.
id()==ID_signedbv ||
1784 if(shift_expr.
id() == ID_ashr)
1786 else if(shift_expr.
id() == ID_lshr)
1788 else if(shift_expr.
id() == ID_shl)
1799 const auto &distance_type = shift_expr.
distance().
type();
1800 if(distance_type.id() == ID_integer || distance_type.id() == ID_natural)
1811 distance_type.id() == ID_signedbv ||
1812 distance_type.id() == ID_unsignedbv ||
1813 distance_type.id() == ID_c_enum || distance_type.id() == ID_c_bool)
1818 if(width_op0==width_op1)
1820 else if(width_op0>width_op1)
1822 out <<
"((_ zero_extend " << width_op0-width_op1 <<
") ";
1828 out <<
"((_ extract " << width_op0-1 <<
" 0) ";
1836 "unsupported distance type for " + shift_expr.
id_string() +
": " +
1837 distance_type.id_string());
1844 "unsupported type for " + shift_expr.
id_string() +
": " +
1847 else if(expr.
id() == ID_rol || expr.
id() == ID_ror)
1853 type.
id() == ID_unsignedbv || type.
id() == ID_signedbv ||
1858 if(shift_expr.
id() == ID_rol)
1859 out <<
"((_ rotate_left";
1860 else if(shift_expr.
id() == ID_ror)
1861 out <<
"((_ rotate_right";
1869 if(distance_int_op.has_value())
1871 out << distance_int_op.value();
1875 "distance type for " + shift_expr.
id_string() +
"must be constant");
1884 "unsupported type for " + shift_expr.
id_string() +
": " +
1887 else if(expr.
id() == ID_named_term)
1891 convert(named_term_expr.value());
1895 else if(expr.
id()==ID_with)
1899 else if(expr.
id()==ID_update)
1903 else if(expr.
id() == ID_update_bit)
1907 else if(expr.
id() == ID_update_bits)
1911 else if(expr.
id() == ID_object_address)
1913 out <<
"(object-address ";
1918 else if(expr.
id() == ID_element_address)
1924 auto element_size_expr_opt =
1934 *element_size_expr_opt, element_address_expr.index().type()));
1937 else if(expr.
id() == ID_field_address)
1946 else if(expr.
id()==ID_member)
1950 else if(expr.
id()==ID_pointer_offset)
1955 op.type().id() == ID_pointer,
1956 "operand of pointer offset expression shall be of pointer type");
1958 std::size_t offset_bits =
1963 if(offset_bits>result_width)
1964 offset_bits=result_width;
1967 if(result_width>offset_bits)
1968 out <<
"((_ zero_extend " << result_width-offset_bits <<
") ";
1970 out <<
"((_ extract " << offset_bits-1 <<
" 0) ";
1974 if(result_width>offset_bits)
1977 else if(expr.
id()==ID_pointer_object)
1982 op.type().id() == ID_pointer,
1983 "pointer object expressions should be of pointer type");
1989 out <<
"((_ zero_extend " << ext <<
") ";
1991 out <<
"((_ extract "
1992 << pointer_width-1 <<
" "
1993 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2000 else if(expr.
id() == ID_is_dynamic_object)
2004 else if(expr.
id() == ID_is_invalid_pointer)
2008 out <<
"(= ((_ extract "
2009 << pointer_width-1 <<
" "
2010 << pointer_width-
config.bv_encoding.object_bits <<
") ";
2013 <<
" " <<
config.bv_encoding.object_bits <<
"))";
2015 else if(expr.
id()==ID_string_constant)
2021 else if(expr.
id()==ID_extractbit)
2030 out <<
"(= ((_ extract " << i <<
" " << i <<
") ";
2036 out <<
"(= ((_ extract 0 0) ";
2046 else if(expr.
id() == ID_onehot)
2050 else if(expr.
id() == ID_onehot0)
2054 else if(expr.
id()==ID_extractbits)
2064 out <<
"((_ extract " << (width + index_i - 1) <<
" " << index_i <<
") ";
2071 out <<
"(= ((_ extract 0 0) ";
2080 SMT2_TODO(
"smt2: extractbits with non-constant index");
2083 else if(expr.
id()==ID_replication)
2093 out <<
"((_ repeat " << times <<
") ";
2097 else if(expr.
id()==ID_byte_extract_little_endian ||
2098 expr.
id()==ID_byte_extract_big_endian)
2101 false,
"byte_extract ops should be lowered in prepare_for_convert_expr");
2103 else if(expr.
id()==ID_byte_update_little_endian ||
2104 expr.
id()==ID_byte_update_big_endian)
2107 false,
"byte_update ops should be lowered in prepare_for_convert_expr");
2109 else if(expr.
id()==ID_abs)
2115 if(type.
id()==ID_signedbv)
2119 out <<
"(ite (bvslt ";
2121 out <<
" (_ bv0 " << result_width <<
")) ";
2128 else if(type.
id()==ID_fixedbv)
2132 out <<
"(ite (bvslt ";
2134 out <<
" (_ bv0 " << result_width <<
")) ";
2141 else if(type.
id()==ID_floatbv)
2155 else if(expr.
id()==ID_isnan)
2161 if(op_type.
id()==ID_fixedbv)
2163 else if(op_type.
id()==ID_floatbv)
2167 out <<
"(fp.isNaN ";
2177 else if(expr.
id()==ID_isfinite)
2183 if(op_type.
id()==ID_fixedbv)
2185 else if(op_type.
id()==ID_floatbv)
2191 out <<
"(not (fp.isNaN ";
2195 out <<
"(not (fp.isInfinite ";
2207 else if(expr.
id()==ID_isinf)
2213 if(op_type.
id()==ID_fixedbv)
2215 else if(op_type.
id()==ID_floatbv)
2219 out <<
"(fp.isInfinite ";
2229 else if(expr.
id()==ID_isnormal)
2235 if(op_type.
id()==ID_fixedbv)
2237 else if(op_type.
id()==ID_floatbv)
2241 out <<
"(fp.isNormal ";
2254 expr.
id() == ID_overflow_result_plus ||
2255 expr.
id() == ID_overflow_result_minus)
2264 "overflow plus and overflow minus expressions shall be of Boolean type");
2267 expr.
id() == ID_overflow_result_minus;
2268 const typet &op_type = op0.type();
2271 if(op_type.
id()==ID_signedbv)
2274 out <<
"(let ((?sum (";
2275 out << (subtract?
"bvsub":
"bvadd");
2276 out <<
" ((_ sign_extend 1) ";
2279 out <<
" ((_ sign_extend 1) ";
2289 out <<
"(mk-" << smt_typename;
2294 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2299 "((_ extract " << width <<
" " << width <<
") ?sum) "
2300 "((_ extract " << (width-1) <<
" " << (width-1) <<
") ?sum)";
2310 else if(op_type.
id()==ID_unsignedbv ||
2311 op_type.
id()==ID_pointer)
2314 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2315 out <<
" ((_ zero_extend 1) ";
2318 out <<
" ((_ zero_extend 1) ";
2330 out <<
"(mk-" << smt_typename;
2331 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2335 out <<
"((_ extract " << width <<
" " << width <<
") ?sum)";
2346 "overflow check should not be performed on unsupported type",
2351 expr.
id() == ID_overflow_result_mult)
2360 "overflow mult expression shall be of Boolean type");
2365 const typet &op_type = op0.type();
2368 if(op_type.
id()==ID_signedbv)
2370 out <<
"(let ( (prod (bvmul ((_ sign_extend " << width <<
") ";
2372 out <<
") ((_ sign_extend " << width <<
") ";
2382 out <<
"(mk-" << smt_typename;
2387 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2391 out <<
"(or (bvsge prod (_ bv" <<
power(2, width-1) <<
" "
2393 out <<
" (bvslt prod (bvneg (_ bv" <<
power(2, width - 1) <<
" "
2394 << width * 2 <<
"))))";
2403 else if(op_type.
id()==ID_unsignedbv)
2405 out <<
"(let ((prod (bvmul ((_ zero_extend " << width <<
") ";
2407 out <<
") ((_ zero_extend " << width <<
") ";
2417 out <<
"(mk-" << smt_typename;
2422 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2426 out <<
"(bvuge prod (_ bv" <<
power(2, width) <<
" " << width * 2 <<
"))";
2438 "overflow check should not be performed on unsupported type",
2441 else if(expr.
id() == ID_saturating_plus || expr.
id() == ID_saturating_minus)
2443 const bool subtract = expr.
id() == ID_saturating_minus;
2444 const auto &op_type = expr.
type();
2448 if(op_type.id() == ID_signedbv)
2453 out <<
"(let ((?sum (";
2454 out << (subtract ?
"bvsub" :
"bvadd");
2455 out <<
" ((_ sign_extend 1) ";
2458 out <<
" ((_ sign_extend 1) ";
2465 << width <<
" " << width
2468 << (width - 1) <<
" " << (width - 1) <<
") ?sum)";
2472 out <<
"((_ extract " << width - 1 <<
" 0) ?sum) ";
2475 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2482 else if(op_type.id() == ID_unsignedbv)
2487 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2488 out <<
" ((_ zero_extend 1) ";
2491 out <<
" ((_ zero_extend 1) ";
2496 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2499 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2513 "saturating_plus/minus on unsupported type",
2514 op_type.id_string());
2516 else if(expr.
id()==ID_array)
2522 else if(expr.
id()==ID_literal)
2526 else if(expr.
id()==ID_forall ||
2527 expr.
id()==ID_exists)
2533 throw "MathSAT does not support quantifiers";
2535 if(quantifier_expr.
id() == ID_forall)
2537 else if(quantifier_expr.
id() == ID_exists)
2542 for(
const auto &bound : quantifier_expr.
variables())
2565 else if(expr.
id()==ID_let)
2568 const auto &variables = let_expr.
variables();
2569 const auto &values = let_expr.
values();
2574 for(
auto &binding :
make_range(variables).zip(values))
2593 else if(expr.
id()==ID_constraint_select_one)
2596 "smt2_convt::convert_expr: '" + expr.
id_string() +
2597 "' is not yet supported");
2599 else if(expr.
id() == ID_bswap)
2605 "operand of byte swap expression shall have same type as the expression");
2608 out <<
"(let ((bswap_op ";
2613 bswap_expr.
type().
id() == ID_signedbv ||
2614 bswap_expr.
type().
id() == ID_unsignedbv)
2616 const std::size_t width =
2623 width % bits_per_byte == 0,
2624 "bit width indicated by type of bswap expression should be a multiple "
2625 "of the number of bits per byte");
2627 const std::size_t bytes = width / bits_per_byte;
2636 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2640 out <<
"(bswap_byte_" <<
byte <<
' ';
2641 out <<
"((_ extract " << (
byte * bits_per_byte + (bits_per_byte - 1))
2642 <<
" " << (
byte * bits_per_byte) <<
") bswap_op)";
2651 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2652 out <<
" bswap_byte_" <<
byte;
2663 else if(expr.
id() == ID_popcount)
2667 else if(expr.
id() == ID_count_leading_zeros)
2671 else if(expr.
id() == ID_count_trailing_zeros)
2675 else if(expr.
id() == ID_find_first_set)
2679 else if(expr.
id() == ID_bitreverse)
2683 else if(expr.
id() == ID_zero_extend)
2687 else if(expr.
id() == ID_function_application)
2691 if(function_application_expr.arguments().empty())
2699 for(
auto &op : function_application_expr.arguments())
2707 else if(expr.
id() == ID_cond)
2712 else if(expr.
id() == ID_reduction_and)
2719 else if(expr.
id() == ID_reduction_nand)
2725 else if(expr.
id() == ID_reduction_or)
2732 else if(expr.
id() == ID_reduction_nor)
2738 else if(expr.
id() == ID_reduction_xor)
2754 out <<
"(let ((?rop ";
2760 for(std::size_t i = 0; i < width; i++)
2761 out <<
" ((_ extract " << i <<
" " << i <<
") ?rop)";
2767 else if(expr.
id() == ID_reduction_xnor)
2776 "smt2_convt::convert_expr should not be applied to unsupported "
2787 if(dest_type == src.
type())
2793 if(dest_type.
id()==ID_c_enum_tag)
2797 if(src_type.
id()==ID_c_enum_tag)
2800 if(dest_type.
id()==ID_bool)
2804 src_type.
id() == ID_signedbv || src_type.
id() == ID_unsignedbv ||
2805 src_type.
id() == ID_c_bool || src_type.
id() == ID_fixedbv ||
2806 src_type.
id() == ID_pointer || src_type.
id() == ID_integer ||
2807 src_type.
id() == ID_natural || src_type.
id() == ID_rational ||
2808 src_type.
id() == ID_real)
2816 else if(src_type.
id()==ID_floatbv)
2820 out <<
"(not (fp.isZero ";
2832 else if(dest_type.
id()==ID_c_bool)
2841 out <<
" (_ bv1 " << to_width <<
")";
2842 out <<
" (_ bv0 " << to_width <<
")";
2845 else if(dest_type.
id()==ID_signedbv ||
2846 dest_type.
id()==ID_unsignedbv ||
2847 dest_type.
id()==ID_c_enum ||
2848 dest_type.
id()==ID_bv)
2852 if(src_type.
id()==ID_signedbv ||
2853 src_type.
id()==ID_unsignedbv ||
2854 src_type.
id()==ID_c_bool ||
2855 src_type.
id()==ID_c_enum ||
2856 src_type.
id()==ID_bv)
2860 if(from_width==to_width)
2862 else if(from_width<to_width)
2864 if(src_type.
id()==ID_signedbv)
2865 out <<
"((_ sign_extend ";
2867 out <<
"((_ zero_extend ";
2869 out << (to_width-from_width)
2876 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2881 else if(src_type.
id()==ID_fixedbv)
2885 std::size_t from_width=fixedbv_type.
get_width();
2892 out <<
"(let ((?tcop ";
2898 if(to_width>from_integer_bits)
2900 out <<
"((_ sign_extend "
2901 << (to_width-from_integer_bits) <<
") ";
2902 out <<
"((_ extract " << (from_width-1) <<
" "
2903 << from_fraction_bits <<
") ";
2909 out <<
"((_ extract " << (from_fraction_bits+to_width-1)
2910 <<
" " << from_fraction_bits <<
") ";
2915 out <<
" (ite (and ";
2918 out <<
"(not (= ((_ extract " << (from_fraction_bits-1) <<
" 0) ?tcop) "
2919 "(_ bv0 " << from_fraction_bits <<
")))";
2922 out <<
" (= ((_ extract " << (from_width-1) <<
" " << (from_width-1)
2927 out <<
" (_ bv1 " << to_width <<
") (_ bv0 " << to_width <<
"))";
2931 else if(src_type.
id()==ID_floatbv)
2933 if(dest_type.
id()==ID_bv)
2939 defined_expressionst::const_iterator it =
2950 else if(dest_type.
id()==ID_signedbv)
2954 "typecast unexpected "+src_type.
id_string()+
" -> "+
2957 else if(dest_type.
id()==ID_unsignedbv)
2961 "typecast unexpected "+src_type.
id_string()+
" -> "+
2965 else if(src_type.
id()==ID_bool)
2970 if(dest_type.
id()==ID_fixedbv)
2973 out <<
" (concat (_ bv1 "
2976 "(_ bv0 " << spec.
width <<
")";
2980 out <<
" (_ bv1 " << to_width <<
")";
2981 out <<
" (_ bv0 " << to_width <<
")";
2986 else if(src_type.
id()==ID_pointer)
2990 if(from_width<to_width)
2992 out <<
"((_ sign_extend ";
2993 out << (to_width-from_width)
3000 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
3005 else if(src_type.
id() == ID_integer || src_type.
id() == ID_natural)
3011 out <<
"(_ bv" << i <<
" " << to_width <<
")";
3014 SMT2_TODO(
"can't convert non-constant integer to bitvector");
3017 src_type.
id() == ID_struct ||
3018 src_type.
id() == ID_struct_tag)
3024 "bit vector with of source and destination type shall be equal");
3031 "bit vector with of source and destination type shall be equal");
3036 src_type.
id() == ID_union ||
3037 src_type.
id() == ID_union_tag)
3041 "bit vector with of source and destination type shall be equal");
3044 else if(src_type.
id()==ID_c_bit_field)
3048 if(from_width==to_width)
3059 std::ostringstream e_str;
3060 e_str << src_type.
id() <<
" -> " << dest_type.
id()
3061 <<
" src == " <<
format(src);
3065 else if(dest_type.
id()==ID_fixedbv)
3071 if(src_type.
id()==ID_unsignedbv ||
3072 src_type.
id()==ID_signedbv ||
3073 src_type.
id()==ID_c_enum)
3080 if(from_width==to_integer_bits)
3082 else if(from_width>to_integer_bits)
3085 out <<
"((_ extract " << (to_integer_bits-1) <<
" 0) ";
3093 from_width < to_integer_bits,
3094 "from_width should be smaller than to_integer_bits as other case "
3095 "have been handled above");
3096 if(dest_type.
id()==ID_unsignedbv)
3098 out <<
"(_ zero_extend "
3099 << (to_integer_bits-from_width) <<
") ";
3105 out <<
"((_ sign_extend "
3106 << (to_integer_bits-from_width) <<
") ";
3112 out <<
"(_ bv0 " << to_fraction_bits <<
")";
3115 else if(src_type.
id()==ID_bool)
3117 out <<
"(concat (concat"
3118 <<
" (_ bv0 " << (to_integer_bits-1) <<
") ";
3124 else if(src_type.
id()==ID_fixedbv)
3129 std::size_t from_width=from_fixedbv_type.
get_width();
3131 out <<
"(let ((?tcop ";
3137 if(to_integer_bits<=from_integer_bits)
3139 out <<
"((_ extract "
3140 << (from_fraction_bits+to_integer_bits-1) <<
" "
3141 << from_fraction_bits
3147 to_integer_bits > from_integer_bits,
3148 "to_integer_bits should be greater than from_integer_bits as the"
3149 "other case has been handled above");
3150 out <<
"((_ sign_extend "
3151 << (to_integer_bits-from_integer_bits)
3153 << (from_width-1) <<
" "
3154 << from_fraction_bits
3160 if(to_fraction_bits<=from_fraction_bits)
3162 out <<
"((_ extract "
3163 << (from_fraction_bits-1) <<
" "
3164 << (from_fraction_bits-to_fraction_bits)
3170 to_fraction_bits > from_fraction_bits,
3171 "to_fraction_bits should be greater than from_fraction_bits as the"
3172 "other case has been handled above");
3173 out <<
"(concat ((_ extract "
3174 << (from_fraction_bits-1) <<
" 0) ";
3177 <<
" (_ bv0 " << to_fraction_bits-from_fraction_bits
3186 else if(dest_type.
id()==ID_pointer)
3190 if(src_type.
id()==ID_pointer)
3196 src_type.
id() == ID_unsignedbv || src_type.
id() == ID_signedbv ||
3197 src_type.
id() == ID_bv)
3203 if(from_width==to_width)
3205 else if(from_width<to_width)
3207 out <<
"((_ sign_extend "
3208 << (to_width-from_width)
3215 out <<
"((_ extract " << to_width <<
" 0) ";
3223 else if(dest_type.
id()==ID_range)
3226 const auto dest_width =
address_bits(dest_range_type.size());
3227 if(src_type.
id() == ID_range)
3230 const auto src_width =
address_bits(src_range_type.size());
3231 if(src_width < dest_width)
3233 out <<
"((_ zero_extend " << dest_width - src_width <<
") ";
3237 else if(src_width > dest_width)
3239 out <<
"((_ extract " << dest_width - 1 <<
" 0) ";
3251 else if(dest_type.
id()==ID_floatbv)
3260 if(src_type.
id()==ID_bool)
3270 else if(src_type.
id()==ID_c_bool)
3276 else if(src_type.
id() == ID_bv)
3285 out <<
"((_ to_fp " << dest_floatbv_type.get_e() <<
" "
3286 << dest_floatbv_type.get_f() + 1 <<
") ";
3296 else if(dest_type.
id() == ID_integer || dest_type.
id() == ID_natural)
3298 if(src_type.
id()==ID_bool)
3307 else if(dest_type.
id()==ID_c_bit_field)
3312 if(from_width==to_width)
3321 else if(dest_type.
id() == ID_rational)
3323 if(src_type.
id() == ID_signedbv)
3332 "Unknown typecast " + src_type.
id_string() +
" -> rational");
3346 if(dest_type.
id()==ID_floatbv)
3348 if(src_type.
id()==ID_floatbv)
3375 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3376 << dst.
get_f() + 1 <<
") ";
3385 else if(src_type.
id()==ID_unsignedbv)
3406 out <<
"((_ to_fp_unsigned " << dst.
get_e() <<
" "
3407 << dst.
get_f() + 1 <<
") ";
3416 else if(src_type.
id()==ID_signedbv)
3424 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3425 << dst.
get_f() + 1 <<
") ";
3434 else if(src_type.
id()==ID_c_enum_tag)
3448 else if(dest_type.
id()==ID_signedbv)
3453 out <<
"((_ fp.to_sbv " << dest_width <<
") ";
3462 else if(dest_type.
id()==ID_unsignedbv)
3467 out <<
"((_ fp.to_ubv " << dest_width <<
") ";
3490 out <<
"(fp.roundToIntegral ";
3503 expr.
type().
id() == ID_struct_tag
3511 components.size() == expr.
operands().size(),
3512 "number of struct components as indicated by the struct type shall be equal"
3513 "to the number of operands of the struct expression");
3515 DATA_INVARIANT(!components.empty(),
"struct shall have struct components");
3519 const std::string &smt_typename =
datatype_map.at(struct_type);
3522 out <<
"(mk-" << smt_typename;
3525 for(struct_typet::componentst::const_iterator
3526 it=components.begin();
3527 it!=components.end();
3540 auto convert_operand = [
this](
const exprt &op) {
3544 else if(op.type().id() == ID_bool)
3551 std::size_t n_concat = 0;
3552 for(std::size_t i = components.size(); i > 1; i--)
3562 convert_operand(expr.
operands()[i - 1]);
3568 convert_operand(expr.
op0());
3570 out << std::string(n_concat,
')');
3578 const auto &size_expr = array_type.
size();
3584 out <<
"(let ((?far ";
3592 out <<
"(select ?far ";
3614 if(total_width==member_width)
3622 total_width > member_width,
3623 "total_width should be greater than member_width as member_width can be"
3624 "at most as large as total_width and the other case has been handled "
3628 << (total_width-member_width) <<
") ";
3638 if(expr_type.
id()==ID_unsignedbv ||
3639 expr_type.
id()==ID_signedbv ||
3640 expr_type.
id()==ID_bv ||
3641 expr_type.
id()==ID_c_enum ||
3642 expr_type.
id()==ID_c_enum_tag ||
3643 expr_type.
id()==ID_c_bool ||
3644 expr_type.
id()==ID_c_bit_field)
3650 out <<
"(_ bv" << value
3651 <<
" " << width <<
")";
3653 else if(expr_type.
id()==ID_fixedbv)
3659 out <<
"(_ bv" << v <<
" " << spec.
width <<
")";
3661 else if(expr_type.
id()==ID_floatbv)
3674 size_t e=floatbv_type.
get_e();
3675 size_t f=floatbv_type.
get_f()+1;
3681 out <<
"((_ to_fp " << e <<
" " << f <<
")"
3687 out <<
"(_ NaN " << e <<
" " << f <<
")";
3692 out <<
"(_ -oo " << e <<
" " << f <<
")";
3694 out <<
"(_ +oo " << e <<
" " << f <<
")";
3704 <<
"#b" << binaryString.substr(0, 1) <<
" "
3705 <<
"#b" << binaryString.substr(1, e) <<
" "
3706 <<
"#b" << binaryString.substr(1+e, f-1) <<
")";
3714 out <<
"(_ bv" << v <<
" " << spec.
width() <<
")";
3717 else if(expr_type.
id()==ID_pointer)
3731 out <<
"(_ bv" << value <<
" " << width <<
")";
3734 else if(expr_type.
id()==ID_bool)
3738 else if(expr ==
false)
3743 else if(expr_type.
id()==ID_array)
3749 else if(expr_type.
id()==ID_rational)
3752 const bool negative =
has_prefix(value,
"-");
3757 value = value.substr(1);
3760 size_t pos=value.find(
"/");
3762 if(
pos==std::string::npos)
3763 out << value <<
".0";
3766 out <<
"(/ " << value.substr(0,
pos) <<
".0 "
3767 << value.substr(
pos+1) <<
".0)";
3773 else if(expr_type.
id() == ID_real)
3777 if(value.find(
'.') == std::string::npos)
3780 else if(expr_type.
id()==ID_integer)
3786 out <<
"(- " << value.substr(1, std::string::npos) <<
')';
3790 else if(expr_type.
id() == ID_natural)
3794 else if(expr_type.
id() == ID_range)
3799 out <<
"(_ bv" << (value_int - range_type.from()) <<
" " << width <<
")";
3807 if(expr.
type().
id() == ID_integer)
3817 "unsupported type for euclidean_mod: " + expr.
type().
id_string());
3822 if(expr.
type().
id()==ID_unsignedbv ||
3823 expr.
type().
id()==ID_signedbv)
3825 if(expr.
type().
id()==ID_unsignedbv)
3841 std::vector<mp_integer> dynamic_objects;
3844 if(dynamic_objects.empty())
3850 out <<
"(let ((?obj ((_ extract "
3851 << pointer_width-1 <<
" "
3852 << pointer_width-
config.bv_encoding.object_bits <<
") ";
3856 if(dynamic_objects.size()==1)
3858 out <<
"(= (_ bv" << dynamic_objects.front()
3859 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3865 for(
const auto &
object : dynamic_objects)
3866 out <<
" (= (_ bv" <<
object
3867 <<
" " <<
config.bv_encoding.object_bits <<
") ?obj)";
3881 op_type.
id() == ID_unsignedbv || op_type.
id() == ID_bv ||
3882 op_type.
id() == ID_range)
3886 if(expr.
id()==ID_le)
3888 else if(expr.
id()==ID_lt)
3890 else if(expr.
id()==ID_ge)
3892 else if(expr.
id()==ID_gt)
3901 else if(op_type.
id()==ID_signedbv ||
3902 op_type.
id()==ID_fixedbv)
3905 if(expr.
id()==ID_le)
3907 else if(expr.
id()==ID_lt)
3909 else if(expr.
id()==ID_ge)
3911 else if(expr.
id()==ID_gt)
3920 else if(op_type.
id()==ID_floatbv)
3925 if(expr.
id()==ID_le)
3927 else if(expr.
id()==ID_lt)
3929 else if(expr.
id()==ID_ge)
3931 else if(expr.
id()==ID_gt)
3944 op_type.
id() == ID_rational || op_type.
id() == ID_integer ||
3945 op_type.
id() == ID_natural || op_type.
id() == ID_real)
3956 else if(op_type.
id() == ID_pointer)
3964 if(expr.
id() == ID_le)
3966 else if(expr.
id() == ID_lt)
3968 else if(expr.
id() == ID_ge)
3970 else if(expr.
id() == ID_gt)
3989 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
3990 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
3995 for(
const auto &op : expr.
operands())
4004 expr.
type().
id() == ID_unsignedbv || expr.
type().
id() == ID_signedbv ||
4005 expr.
type().
id() == ID_fixedbv)
4022 else if(expr.
type().
id() == ID_range)
4037 out <<
" (_ bv" << range_type.from() <<
' ' << width
4045 else if(expr.
type().
id() == ID_floatbv)
4052 else if(expr.
type().
id() == ID_pointer)
4058 if(p.
type().
id() != ID_pointer)
4062 p.
type().
id() == ID_pointer,
4063 "one of the operands should have pointer type");
4067 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4070 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
4074 out <<
"(let ((?pointerop ";
4080 const std::size_t offset_bits =
4081 pointer_width -
config.bv_encoding.object_bits;
4084 out <<
"((_ extract " << pointer_width - 1 <<
' ' << offset_bits
4085 <<
") ?pointerop) ";
4086 out <<
"(bvadd ((_ extract " << offset_bits - 1 <<
" 0) ?pointerop) ";
4088 if(element_size >= 2)
4090 out <<
"(bvmul ((_ extract " << offset_bits - 1 <<
" 0) ";
4092 out <<
") (_ bv" << element_size <<
" " << offset_bits <<
"))";
4096 out <<
"((_ extract " << offset_bits - 1 <<
" 0) ";
4135 out <<
"roundNearestTiesToEven";
4137 out <<
"roundTowardNegative";
4139 out <<
"roundTowardPositive";
4141 out <<
"roundTowardZero";
4143 out <<
"roundNearestTiesToAway";
4147 "Rounding mode should have value 0, 1, 2, 3, or 4",
4155 out <<
"(ite (= (_ bv0 " << width <<
") ";
4157 out <<
") roundNearestTiesToEven ";
4159 out <<
"(ite (= (_ bv1 " << width <<
") ";
4161 out <<
") roundTowardNegative ";
4163 out <<
"(ite (= (_ bv2 " << width <<
") ";
4165 out <<
") roundTowardPositive ";
4167 out <<
"(ite (= (_ bv3 " << width <<
") ";
4169 out <<
") roundTowardZero ";
4172 out <<
"roundNearestTiesToAway";
4183 type.
id() == ID_floatbv ||
4184 (type.
id() == ID_complex &&
4189 if(type.
id()==ID_floatbv)
4199 else if(type.
id()==ID_complex)
4206 "type should not be one of the unsupported types",
4216 expr.
type().
id() == ID_integer || expr.
type().
id() == ID_natural ||
4217 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_real)
4225 else if(expr.
type().
id()==ID_unsignedbv ||
4226 expr.
type().
id()==ID_signedbv ||
4227 expr.
type().
id()==ID_fixedbv)
4229 if(expr.
op0().
type().
id()==ID_pointer &&
4235 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
4237 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
4240 if(element_size >= 2)
4245 "bitvector width of operand shall be equal to the bitvector width of "
4254 if(element_size >= 2)
4267 else if(expr.
type().
id()==ID_floatbv)
4274 else if(expr.
type().
id()==ID_pointer)
4278 (expr.
op1().
type().
id() == ID_unsignedbv ||
4290 else if(expr.
type().
id() == ID_range)
4297 out <<
"(bvsub (bvsub ";
4301 out <<
") (_ bv" << range_type.from() <<
' ' << width <<
"))";
4310 expr.
type().
id() == ID_floatbv,
4311 "type of ieee floating point expression shall be floatbv");
4329 if(expr.
type().
id()==ID_unsignedbv ||
4330 expr.
type().
id()==ID_signedbv)
4332 if(expr.
type().
id()==ID_unsignedbv)
4342 else if(expr.
type().
id()==ID_fixedbv)
4347 out <<
"((_ extract " << spec.
width-1 <<
" 0) ";
4352 out <<
" (_ bv0 " << fraction_bits <<
")) ";
4354 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4360 else if(expr.
type().
id()==ID_floatbv)
4368 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4369 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4384 expr.
type().
id() == ID_floatbv,
4385 "type of ieee floating point expression shall be floatbv");
4416 "expression should have been converted to a variant with two operands");
4418 if(expr.
type().
id()==ID_unsignedbv ||
4419 expr.
type().
id()==ID_signedbv)
4430 else if(expr.
type().
id()==ID_floatbv)
4437 else if(expr.
type().
id()==ID_fixedbv)
4442 out <<
"((_ extract "
4443 << spec.
width+fraction_bits-1 <<
" "
4444 << fraction_bits <<
") ";
4448 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4452 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4459 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
4460 expr.
type().
id() == ID_natural || expr.
type().
id() == ID_real)
4464 for(
const auto &op : expr.
operands())
4479 expr.
type().
id() == ID_floatbv,
4480 "type of ieee floating point expression shall be floatbv");
4499 expr.
type().
id() == ID_floatbv,
4500 "type of ieee floating point expression shall be floatbv");
4514 "smt2_convt::convert_floatbv_rem to be implemented when not using "
4522 expr.
type().
id() == ID_floatbv,
4523 "type of ieee floating point expression shall be floatbv");
4545 "with expression should have exactly three operands");
4549 if(expr_type.
id()==ID_array)
4573 out <<
"(let ((distance? ";
4574 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4578 if(array_width>index_width)
4580 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4586 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4596 out <<
"(bvshl (_ bv" <<
power(2, sub_width) - 1 <<
" " << array_width
4598 out <<
"distance?)) ";
4602 out <<
"((_ zero_extend " << array_width-sub_width <<
") ";
4604 out <<
") distance?)))";
4607 else if(expr_type.
id() == ID_struct || expr_type.
id() == ID_struct_tag)
4610 expr_type.
id() == ID_struct_tag
4617 const irep_idt &component_name=index.
get(ID_component_name);
4621 "struct should have accessed component");
4625 const std::string &smt_typename =
datatype_map.at(expr_type);
4627 out <<
"(update-" << smt_typename <<
"." << component_name <<
" ";
4635 auto convert_operand = [
this](
const exprt &op)
4640 else if(op.type().id() == ID_bool)
4652 if(m.
width==struct_width)
4655 convert_operand(value);
4659 out <<
"(let ((?withop ";
4660 convert_operand(expr.
old());
4667 <<
"((_ extract " << (struct_width - 1) <<
" " << m.
width
4669 convert_operand(value);
4676 convert_operand(value);
4677 out <<
" ((_ extract " << (m.
offset - 1) <<
" 0) ?withop))";
4682 out <<
"(concat (concat "
4683 <<
"((_ extract " << (struct_width - 1) <<
" "
4685 convert_operand(value);
4686 out <<
") ((_ extract " << (m.
offset - 1) <<
" 0) ?withop)";
4694 else if(expr_type.
id() == ID_union || expr_type.
id() == ID_union_tag)
4702 if(total_width==member_width)
4709 total_width > member_width,
4710 "total width should be greater than member_width as member_width is at "
4711 "most as large as total_width and the other case has been handled "
4714 out <<
"((_ extract "
4716 <<
" " << member_width <<
") ";
4723 else if(expr_type.
id()==ID_bv ||
4724 expr_type.
id()==ID_unsignedbv ||
4725 expr_type.
id()==ID_signedbv)
4740 "with expects struct, union, or array type, but got "+
4748 SMT2_TODO(
"smt2_convt::convert_update to be implemented");
4765 if(array_op_type.
id()==ID_array)
4800 out <<
"((_ extract " << sub_width-1 <<
" 0) ";
4804 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4808 if(array_width>index_width)
4810 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4816 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4828 false,
"index with unsupported array type: " + array_op_type.
id_string());
4835 const typet &struct_op_type = struct_op.
type();
4838 if(struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag)
4841 struct_op_type.
id() == ID_struct_tag
4846 struct_type.
has_component(name),
"struct should have accessed component");
4850 const std::string &smt_typename =
datatype_map.at(struct_type);
4852 out <<
"(" << smt_typename <<
"."
4863 if(expr.
type().
id() == ID_bool)
4869 if(expr.
type().
id() == ID_bool)
4874 struct_op_type.
id() == ID_union || struct_op_type.
id() == ID_union_tag)
4878 width != 0,
"failed to get union member width");
4884 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4892 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4899 "convert_member on an unexpected type "+struct_op_type.
id_string());
4906 if(type.
id()==ID_bool)
4912 else if(type.
id()==ID_array)
4923 std::size_t n_concat = 0;
4937 out << std::string(n_concat,
')');
4942 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4955 std::size_t n_concat = 0;
4956 for(std::size_t i=components.size(); i>1; i--)
4976 out << std::string(n_concat,
')');
4981 else if(type.
id()==ID_floatbv)
4996 out <<
"(_ bv" << value <<
" " << spec.
width() <<
")";
5001 "flatten2bv of a non-constant FPA-encoded float is unsupported");
5016 if(type.
id()==ID_bool)
5023 else if(type.
id() == ID_array)
5028 out <<
"(let ((?ufop" << nesting <<
" ";
5039 "cannot unflatten arrays of non-constant size");
5050 out <<
"((as const ";
5058 "unflatten relies on `(lambda ...)` for constant arrays "
5059 "when `(as const ...)` is unavailable");
5065 out <<
"(lambda ((?ufidx" << nesting <<
" ";
5071 out <<
"((_ extract " << subtype_width - 1 <<
" "
5072 <<
"0) ?ufop" << nesting <<
")";
5076 std::size_t offset = subtype_width;
5077 for(
mp_integer i = 1; i < size; ++i, offset += subtype_width)
5082 out <<
"((_ extract " << offset + subtype_width - 1 <<
" " << offset
5083 <<
") ?ufop" << nesting <<
")";
5091 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5097 out <<
"(let ((?ufop" << nesting <<
" ";
5102 const std::string &smt_typename =
datatype_map.at(type);
5104 out <<
"(mk-" << smt_typename;
5113 std::size_t offset=0;
5116 for(struct_typet::componentst::const_iterator
5117 it=components.begin();
5118 it!=components.end();
5128 out <<
"((_ extract " << offset+member_width-1 <<
" "
5129 << offset <<
") ?ufop" << nesting <<
")";
5131 offset+=member_width;
5152 if(expr.
id()==ID_and && value)
5154 for(
const auto &op : expr.
operands())
5159 if(expr.
id()==ID_or && !value)
5161 for(
const auto &op : expr.
operands())
5166 if(expr.
id()==ID_not)
5176 if(expr.
id() == ID_equal && value)
5185 if(equal_expr.
lhs().
id()==ID_symbol)
5192 equal_expr.
lhs() != equal_expr.
rhs())
5204 out <<
"; set_to true (equal)\n";
5212 auto emit_definition_body = [&]()
5215 equal_expr.
lhs().
type().
id() != ID_array ||
5228 if(equal_expr.
lhs().
type().
id() == ID_mathematical_function)
5232 out <<
"(declare-fun " << smt2_identifier;
5234 auto &mathematical_function_type =
5240 for(
auto &t : mathematical_function_type.domain())
5254 out <<
"(assert (= " << smt2_identifier <<
' ';
5256 out <<
')' <<
')' <<
'\n';
5269 out <<
"(declare-fun " << smt2_identifier;
5273 out <<
"(assert (= " << smt2_identifier <<
' ';
5274 emit_definition_body();
5279 out <<
"(define-fun " << smt2_identifier;
5283 emit_definition_body();
5299 out <<
"; set_to " << (value?
"true":
"false") <<
"\n"
5310 out << found_literal->second;
5333 exprt lowered_expr = expr;
5340 it->id() == ID_byte_extract_little_endian ||
5341 it->id() == ID_byte_extract_big_endian)
5346 it->id() == ID_byte_update_little_endian ||
5347 it->id() == ID_byte_update_big_endian)
5353 return lowered_expr;
5370 "lower_byte_operators should remove all byte operators");
5377 auto prophecy_r_or_w_ok =
5381 it.mutate() = lowered;
5382 it.next_sibling_or_parent();
5385 auto prophecy_pointer_in_range =
5389 it.mutate() = lowered;
5390 it.next_sibling_or_parent();
5399 return lowered_expr;
5419 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
5421 std::unordered_map<irep_idt, std::optional<identifiert>> shadowed_syms;
5426 for(
const auto &symbol : q_expr.variables())
5428 const auto identifier = symbol.identifier();
5431 shadowed_syms.insert(
5433 id_entry.second ? std::nullopt
5434 : std::optional{id_entry.first->second}});
5437 for(
const auto &[
id, shadowed_val] : shadowed_syms)
5440 if(!shadowed_val.has_value())
5443 previous_entry->second = std::move(*shadowed_val);
5449 for(
const auto &op : expr.
operands())
5452 if(expr.
id()==ID_symbol ||
5453 expr.
id()==ID_nondet_symbol)
5456 if(expr.
type().
id()==ID_code)
5461 if(expr.
id()==ID_symbol)
5464 identifier=
"nondet_"+
5475 out <<
"; find_symbols\n";
5476 out <<
"(declare-fun " << smt2_identifier;
5478 if(expr.
type().
id() == ID_mathematical_function)
5480 auto &mathematical_function_type =
5485 for(
auto &type : mathematical_function_type.domain())
5509 if(expr.
type().
id() == ID_range)
5514 out <<
"(assert (bvule " << smt2_identifier <<
' ';
5521 else if(expr.
id() == ID_array_of)
5528 const auto &array_type = array_of.type();
5532 out <<
"; the following is a substitute for lambda i. x\n";
5533 out <<
"(declare-fun " <<
id <<
" () ";
5540 out <<
"(assert (forall ((i ";
5542 out <<
")) (= (select " <<
id <<
" i) ";
5560 else if(expr.
id() == ID_array_comprehension)
5567 const auto &array_type = array_comprehension.type();
5568 const auto &array_size = array_type.size();
5572 out <<
"(declare-fun " <<
id <<
" () ";
5576 out <<
"; the following is a substitute for lambda i . x(i)\n";
5577 out <<
"; universally quantified initialization of the array\n";
5578 out <<
"(assert (forall ((";
5582 out <<
")) (=> (and (bvule (_ bv0 " <<
boolbv_width(array_size.type())
5589 out <<
")) (= (select " <<
id <<
" ";
5608 else if(expr.
id()==ID_array)
5615 out <<
"; the following is a substitute for an array constructor" <<
"\n";
5616 out <<
"(declare-fun " <<
id <<
" () ";
5622 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5624 out <<
"(assert (= (select " <<
id <<
" ";
5645 else if(expr.
id()==ID_string_constant)
5655 out <<
"; the following is a substitute for a string" <<
"\n";
5656 out <<
"(declare-fun " <<
id <<
" () ";
5660 for(std::size_t i=0; i<tmp.
operands().size(); i++)
5662 out <<
"(assert (= (select " <<
id <<
' ';
5666 out <<
"))" <<
"\n";
5679 out <<
"(declare-fun " <<
id <<
" () ";
5690 (expr.
id() == ID_floatbv_plus ||
5691 expr.
id() == ID_floatbv_minus ||
5692 expr.
id() == ID_floatbv_mult ||
5693 expr.
id() == ID_floatbv_div ||
5694 expr.
id() == ID_floatbv_fma ||
5695 expr.
id() == ID_floatbv_typecast ||
5696 expr.
id() == ID_ieee_float_equal ||
5697 expr.
id() == ID_ieee_float_notequal ||
5698 ((expr.
id() == ID_lt ||
5699 expr.
id() == ID_gt ||
5700 expr.
id() == ID_le ||
5701 expr.
id() == ID_ge ||
5702 expr.
id() == ID_isnan ||
5703 expr.
id() == ID_isnormal ||
5704 expr.
id() == ID_isfinite ||
5705 expr.
id() == ID_isinf ||
5706 expr.
id() == ID_sign ||
5707 expr.
id() == ID_unary_minus ||
5708 expr.
id() == ID_typecast ||
5709 expr.
id() == ID_abs) &&
5716 if(
bvfp_set.insert(function).second)
5718 out <<
"; this is a model for " << expr.
id() <<
" : "
5721 <<
"(define-fun " << function <<
" (";
5723 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5727 out <<
"(op" << i <<
' ';
5737 for(std::size_t i = 0; i < tmp1.
operands().size(); i++)
5753 expr.
type().
id() == ID_bv)
5763 out <<
"(declare-fun " <<
id <<
" () ";
5769 out <<
"(assert (= ";
5770 out <<
"((_ to_fp " << floatbv_type.get_e() <<
" "
5771 << floatbv_type.get_f() + 1 <<
") " <<
id <<
')';
5779 else if(expr.
id() == ID_initial_state)
5781 irep_idt function =
"initial-state";
5785 out <<
"(declare-fun " << function <<
" (";
5792 else if(expr.
id() == ID_evaluate)
5798 out <<
"(declare-fun " << function <<
" (";
5808 expr.
id() == ID_state_is_cstring ||
5809 expr.
id() == ID_state_is_dynamic_object ||
5810 expr.
id() == ID_state_live_object || expr.
id() == ID_state_writeable_object)
5813 expr.
id() == ID_state_is_cstring ?
"state-is-cstring"
5814 : expr.
id() == ID_state_is_dynamic_object ?
"state-is-dynamic-object"
5815 : expr.
id() == ID_state_live_object ?
"state-live-object"
5816 :
"state-writeable-object";
5820 out <<
"(declare-fun " << function <<
" (";
5830 expr.
id() == ID_state_r_ok || expr.
id() == ID_state_w_ok ||
5831 expr.
id() == ID_state_rw_ok)
5833 irep_idt function = expr.
id() == ID_state_r_ok ?
"state-r-ok"
5834 : expr.
id() == ID_state_w_ok ?
"state-w-ok"
5839 out <<
"(declare-fun " << function <<
" (";
5850 else if(expr.
id() == ID_update_state)
5857 out <<
"(declare-fun " << function <<
" (";
5868 else if(expr.
id() == ID_enter_scope_state)
5875 out <<
"(declare-fun " << function <<
" (";
5886 else if(expr.
id() == ID_exit_scope_state)
5893 out <<
"(declare-fun " << function <<
" (";
5902 else if(expr.
id() == ID_allocate)
5908 out <<
"(declare-fun " << function <<
" (";
5917 else if(expr.
id() == ID_reallocate)
5923 out <<
"(declare-fun " << function <<
" (";
5934 else if(expr.
id() == ID_deallocate_state)
5940 out <<
"(declare-fun " << function <<
" (";
5949 else if(expr.
id() == ID_object_address)
5951 irep_idt function =
"object-address";
5955 out <<
"(declare-fun " << function <<
" (String) ";
5960 else if(expr.
id() == ID_field_address)
5966 out <<
"(declare-fun " << function <<
" (";
5975 else if(expr.
id() == ID_element_address)
5981 out <<
"(declare-fun " << function <<
" (";
6000 if(expr.
id() == ID_with)
6002 else if(expr.
id() == ID_if)
6038 if(type.
id()==ID_array)
6052 out <<
"(_ BitVec 1)";
6058 else if(type.
id()==ID_bool)
6062 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
6072 out <<
"(_ BitVec " << width <<
")";
6075 else if(type.
id()==ID_code)
6082 else if(type.
id() == ID_union || type.
id() == ID_union_tag)
6089 union_type.
components().empty() || width != 0,
6090 "failed to get width of union");
6092 out <<
"(_ BitVec " << width <<
")";
6094 else if(type.
id()==ID_pointer)
6099 else if(type.
id()==ID_bv ||
6100 type.
id()==ID_fixedbv ||
6101 type.
id()==ID_unsignedbv ||
6102 type.
id()==ID_signedbv ||
6103 type.
id()==ID_c_bool)
6108 else if(type.
id()==ID_c_enum)
6115 else if(type.
id()==ID_c_enum_tag)
6119 else if(type.
id()==ID_floatbv)
6124 out <<
"(_ FloatingPoint "
6125 << floatbv_type.
get_e() <<
" "
6126 << floatbv_type.
get_f() + 1 <<
")";
6131 else if(type.
id()==ID_rational ||
6134 else if(type.
id()==ID_integer)
6136 else if(type.
id() == ID_natural)
6138 else if(type.
id()==ID_complex)
6148 out <<
"(_ BitVec " << width <<
")";
6151 else if(type.
id()==ID_c_bit_field)
6155 else if(type.
id() == ID_state)
6159 else if(type.
id() == ID_range)
6162 if(range_type.empty())
6174 std::set<irep_idt> recstack;
6180 std::set<irep_idt> &recstack)
6182 if(type.
id()==ID_array)
6188 else if(type.
id()==ID_complex)
6195 const std::string smt_typename =
6199 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6200 <<
"(((mk-" << smt_typename;
6202 out <<
" (" << smt_typename <<
".imag ";
6206 out <<
" (" << smt_typename <<
".real ";
6213 else if(type.
id() == ID_struct)
6216 bool need_decl=
false;
6220 const std::string smt_typename =
6235 const std::string &smt_typename =
datatype_map.at(type);
6246 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
6247 <<
"(((mk-" << smt_typename <<
" ";
6254 out <<
"(" << smt_typename <<
"." <<
component.get_name()
6260 out <<
"))))" <<
"\n";
6277 for(struct_union_typet::componentst::const_iterator
6278 it=components.begin();
6279 it!=components.end();
6286 out <<
"(define-fun update-" << smt_typename <<
"."
6288 <<
"((s " << smt_typename <<
") "
6291 out <<
")) " << smt_typename <<
" "
6292 <<
"(mk-" << smt_typename
6295 for(struct_union_typet::componentst::const_iterator
6296 it2=components.begin();
6297 it2!=components.end();
6304 out <<
"(" << smt_typename <<
"."
6305 << it2->get_name() <<
" s) ";
6309 out <<
"))" <<
"\n";
6315 else if(type.
id() == ID_union)
6323 else if(type.
id()==ID_code)
6327 for(
const auto ¶m : parameters)
6332 else if(type.
id()==ID_pointer)
6336 else if(type.
id() == ID_struct_tag)
6339 const irep_idt &
id = struct_tag.get_identifier();
6341 if(recstack.find(
id) == recstack.end())
6343 const auto &base_struct =
ns.follow_tag(struct_tag);
6344 recstack.insert(
id);
6349 else if(type.
id() == ID_union_tag)
6352 const irep_idt &
id = union_tag.get_identifier();
6354 if(recstack.find(
id) == recstack.end())
6356 recstack.insert(
id);
6360 else if(type.
id() == ID_state)
6365 out <<
"(declare-sort state 0)\n";
6368 else if(type.
id() == ID_mathematical_function)
6370 const auto &mathematical_function_type =
6372 for(
auto &d_type : mathematical_function_type.domain())
API to expression classes for bitvectors.
const onehot0_exprt & to_onehot0_expr(const exprt &expr)
Cast an exprt to a onehot0_exprt.
const replication_exprt & to_replication_expr(const exprt &expr)
Cast an exprt to a replication_exprt.
const reduction_xnor_exprt & to_reduction_xnor_expr(const exprt &expr)
Cast an exprt to a reduction_xnor_exprt.
const reduction_nand_exprt & to_reduction_nand_expr(const exprt &expr)
Cast an exprt to a reduction_nand_exprt.
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
const reduction_and_exprt & to_reduction_and_expr(const exprt &expr)
Cast an exprt to a reduction_and_exprt.
const reduction_or_exprt & to_reduction_or_expr(const exprt &expr)
Cast an exprt to a reduction_or_exprt.
const popcount_exprt & to_popcount_expr(const exprt &expr)
Cast an exprt to a popcount_exprt.
const update_bits_exprt & to_update_bits_expr(const exprt &expr)
Cast an exprt to an update_bits_exprt.
const extractbits_exprt & to_extractbits_expr(const exprt &expr)
Cast an exprt to an extractbits_exprt.
const onehot_exprt & to_onehot_expr(const exprt &expr)
Cast an exprt to a onehot_exprt.
bool can_cast_expr< minus_overflow_exprt >(const exprt &base)
const find_first_set_exprt & to_find_first_set_expr(const exprt &expr)
Cast an exprt to a find_first_set_exprt.
bool can_cast_expr< overflow_result_exprt >(const exprt &base)
const update_bit_exprt & to_update_bit_expr(const exprt &expr)
Cast an exprt to an update_bit_exprt.
const bitnot_exprt & to_bitnot_expr(const exprt &expr)
Cast an exprt to a bitnot_exprt.
const bswap_exprt & to_bswap_expr(const exprt &expr)
Cast an exprt to a bswap_exprt.
const count_leading_zeros_exprt & to_count_leading_zeros_expr(const exprt &expr)
Cast an exprt to a count_leading_zeros_exprt.
const reduction_xor_exprt & to_reduction_xor_expr(const exprt &expr)
Cast an exprt to a reduction_xor_exprt.
const bitreverse_exprt & to_bitreverse_expr(const exprt &expr)
Cast an exprt to a bitreverse_exprt.
const extractbit_exprt & to_extractbit_expr(const exprt &expr)
Cast an exprt to an extractbit_exprt.
const reduction_nor_exprt & to_reduction_nor_expr(const exprt &expr)
Cast an exprt to a reduction_nor_exprt.
const zero_extend_exprt & to_zero_extend_expr(const exprt &expr)
Cast an exprt to a zero_extend_exprt.
const count_trailing_zeros_exprt & to_count_trailing_zeros_expr(const exprt &expr)
Cast an exprt to a count_trailing_zeros_exprt.
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
bool has_byte_operator(const exprt &src)
Return true iff src or one of its operands contain a byte extract or byte update expression.
Expression classes for byte-level operators.
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
Rewrite a byte extract expression to more fundamental operations.
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
Rewrite a byte update expression to more fundamental operations.
typet c_bit_field_replacement_type(const c_bit_field_typet &src, const namespacet &ns)
unsignedbv_typet size_type()
pointer_typet pointer_type(const typet &subtype)
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const c_bool_typet & to_c_bool_type(const typet &type)
Cast a typet to a c_bool_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Operator to return the address of an object.
Represents real numbers as roots (zeros) of a polynomial with rational coefficients.
constant_exprt as_expr() const
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Pointer-typed bitvector constant annotated with the pointer expression that the bitvector is the nume...
Array constructor from list of elements.
typet index_type() const
The type of the index expressions into any instance of this type.
const exprt & size() const
const typet & element_type() const
The type of the elements of the array.
A base class for binary expressions.
A base class for relations, i.e., binary predicates whose two operands have the same type.
Bit-wise negation of bit-vectors.
constant_exprt all_zeros_expr() const
constant_exprt all_ones_expr() const
std::size_t get_width() const
The byte swap expression.
std::size_t get_bits_per_byte() const
std::vector< parametert > parameterst
const parameterst & parameters() const
A constant literal expression.
const irep_idt & get_value() const
bool is_null_pointer() const
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
resultt
Result of running the decision procedure.
Boute's Euclidean definition of Modulo – to match SMT-LIB2.
Base class for all expressions.
std::vector< exprt > operandst
bool has_operands() const
Return true if there is at least one operand.
depth_iteratort depth_end()
bool is_boolean() const
Return whether the expression represents a Boolean.
depth_iteratort depth_begin()
bool is_constant() const
Return whether the expression is a constant.
typet & type()
Return the type of the expression.
void visit_post(std::function< void(exprt &)>)
These are post-order traversal visitors, i.e., the visitor is executed on a node after its children h...
The Boolean constant false.
std::size_t get_fraction_bits() const
Fixed-width bit-vector with signed fixed-point interpretation.
std::size_t get_fraction_bits() const
std::size_t get_integer_bits() const
Fused multiply-add expression: round(op0 * op1 + op2) with a single rounding.
exprt & op_multiply_lhs()
exprt & op_multiply_rhs()
Round a floating-point number to an integral value considering the given rounding mode.
Semantic type conversion from/to floating-point formats.
Fixed-width bit-vector with IEEE floating-point interpretation.
std::size_t get_f() const
std::size_t get_e() const
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
std::size_t width() const
An IEEE 754 floating-point value, including specificiation.
static ieee_float_valuet minus_infinity(const ieee_float_spect &_spec)
static ieee_float_valuet one(const floatbv_typet &)
constant_exprt to_expr() const
static ieee_float_valuet zero(const floatbv_typet &type)
static ieee_float_valuet NaN(const ieee_float_spect &_spec)
static ieee_float_valuet plus_infinity(const ieee_float_spect &_spec)
The trinary if-then-else operator.
There are a large number of kinds of tree structured or tree-like data in CPROVER.
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const irep_idt & get(const irep_idt &name) const
const std::string & id_string() const
const irep_idt & id() const
Evaluates to true if the operand is finite.
Evaluates to true if the operand is infinite.
Evaluates to true if the operand is NaN.
Evaluates to true if the operand is a normal number.
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
exprt & where()
convenience accessor for binding().where()
literalt get_literal() const
Extract member of struct or union.
const exprt & struct_op() const
irep_idt get_component_name() const
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Binary multiplication Associativity is not specified.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
const irep_idt & get_identifier() const
Expression for finding the size (in bytes) of the object a pointer points to.
The plus expression Associativity is not specified.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
A base class for quantifier expressions.
Unbounded, signed rational numbers.
Boolean reduction: true iff every bit of the operand is 1.
Boolean reduction: true iff any bit of the operand is 1.
Boolean reduction: XOR (parity) of all bits in the operand.
A base class for shift and rotate operators.
Sign of an expression Predicate is true if _op is negative, false otherwise.
const irep_idt & get_identifier() const
void convert_relation(const binary_relation_exprt &)
bool use_lambda_for_array
void convert_type(const typet &)
void unflatten(wheret, const typet &, unsigned nesting=0)
bool use_array_theory(const exprt &)
void find_symbols(const exprt &expr)
Find and declare symbols used in an expression This function traverses the expression tree and create...
std::size_t number_of_solver_calls
void convert_typecast(const typecast_exprt &expr)
void write_footer()
Writes the end of the SMT file to the smt_convt::out stream.
tvt l_get(literalt l) const
void convert_floatbv_rem(const binary_exprt &expr)
std::unordered_map< irep_idt, irept > current_bindings
resultt dec_solve(const exprt &) override
Implementation of the decision procedure.
std::set< irep_idt > bvfp_set
void convert_address_of_rec(const exprt &expr, const pointer_typet &result_type)
void push() override
Unimplemented.
void convert_is_dynamic_object(const unary_exprt &)
void convert_literal(const literalt)
void convert_floatbv_div(const ieee_float_op_exprt &expr)
void convert_string_literal(const std::string &)
std::size_t get_number_of_solver_calls() const override
Return the number of incremental solver calls.
void convert_floatbv_mult(const ieee_float_op_exprt &expr)
boolbv_widtht boolbv_width
void convert_constant(const constant_exprt &expr)
std::string floatbv_suffix(const exprt &) const
void flatten2bv(const exprt &)
void convert_floatbv_fma(const floatbv_fma_exprt &expr)
void convert_div(const div_exprt &expr)
exprt lower_byte_operators(const exprt &expr)
Lower byte_update and byte_extract operations within expr.
std::string type2id(const typet &) const
void convert_rounding_mode_FPA(const exprt &expr)
Converting a constant or symbolic rounding mode to SMT-LIB.
void convert_floatbv_typecast(const floatbv_typecast_exprt &expr)
struct_exprt parse_struct(const irept &s, const struct_typet &type)
void convert_mult(const mult_exprt &expr)
void convert_update_bit(const update_bit_exprt &)
exprt prepare_for_convert_expr(const exprt &expr)
Perform steps necessary before an expression is passed to convert_expr.
exprt get(const exprt &expr) const override
Return expr with variables replaced by values from satisfying assignment if available.
std::string decision_procedure_text() const override
Return a textual description of the decision procedure.
void convert_floatbv_minus(const ieee_float_op_exprt &expr)
bool use_check_sat_assuming
std::map< object_size_exprt, irep_idt > object_sizes
void define_object_size(const irep_idt &id, const object_size_exprt &expr)
datatype_mapt datatype_map
void convert_mod(const mod_exprt &expr)
static std::string convert_identifier(const irep_idt &identifier)
void convert_floatbv_plus(const ieee_float_op_exprt &expr)
void convert_struct(const struct_exprt &expr)
std::unordered_map< irep_idt, bool > set_values
The values which boolean identifiers have been smt2_convt::set_to or in other words those which are a...
smt2_convt(const namespacet &_ns, const std::string &_benchmark, const std::string &_notes, const std::string &_logic, solvert _solver, std::ostream &_out)
void convert_member(const member_exprt &expr)
void convert_euclidean_mod(const euclidean_mod_exprt &expr)
void convert_index(const index_exprt &expr)
pointer_logict pointer_logic
exprt handle(const exprt &expr) override
Generate a handle, which is an expression that has the same value as the argument in any model that i...
void print_assignment(std::ostream &out) const override
Print satisfying assignment to out.
void walk_array_tree(std::unordered_map< int64_t, exprt > *operands_map, const irept &src, const array_typet &type)
This function walks the SMT output and populates a map with index/value pairs for the array.
void convert_floatbv_round_to_integral(const floatbv_round_to_integral_exprt &)
void set_to(const exprt &expr, bool value) override
For a Boolean expression expr, add the constraint 'expr' if value is true, otherwise add 'not expr'.
exprt parse_rec(const irept &s, const typet &type)
void convert_union(const union_exprt &expr)
exprt parse_union(const irept &s, const union_typet &type)
exprt parse_array(const irept &s, const array_typet &type)
This function is for parsing array output from SMT solvers when "(get-value |???|)" returns an array ...
std::vector< bool > boolean_assignment
void flatten_array(const exprt &)
produce a flat bit-vector for a given array of fixed size
void convert_with(const with_exprt &expr)
std::vector< literalt > assumptions
void convert_plus(const plus_exprt &expr)
defined_expressionst defined_expressions
void pop() override
Currently, only implements a single stack element (no nested contexts).
void convert_update_bits(const update_bits_exprt &)
void find_symbols_rec(const typet &type, std::set< irep_idt > &recstack)
void convert_update(const update_exprt &)
std::set< irep_idt > state_fkt_declared
identifier_mapt identifier_map
void convert_minus(const minus_exprt &expr)
void convert_expr(const exprt &)
constant_exprt parse_literal(const irept &, const typet &type)
const smt2_symbolt & to_smt2_symbol(const exprt &expr)
std::size_t no_boolean_variables
smt2_identifierst smt2_identifiers
void convert_floatbv(const exprt &expr)
literalt convert(const exprt &expr)
array_exprt to_array_expr() const
convert string into array constant
Struct constructor from list of elements.
Structure type, corresponds to C style structs.
const irep_idt & get_name() const
const componentst & components() const
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
bool has_component(const irep_idt &component_name) const
std::vector< componentt > componentst
void identifier(const irep_idt &identifier)
The Boolean constant true.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
Generic base class for unary expressions.
The unary minus expression.
Union constructor from single element.
Fixed-width bit-vector with unsigned binary interpretation.
Replaces a sub-range of a bit-vector operand.
exprt lower() const
A lowering to masking, shifting, or.
Replaces a sub-range of a bit-vector operand.
exprt lower() const
A lowering to masking, shifting, or.
Operator to update elements in structs and arrays.
Operator to update elements in structs and arrays.
bool has_prefix(const std::string &s, const std::string &prefix)
bool can_cast_expr(const exprt &base)
Check whether a reference to a generic exprt is of a specific derived class.
auto expr_try_dynamic_cast(TExpr &base) -> typename detail::expr_try_dynamic_cast_return_typet< T, TExpr >::type
Try to cast a reference to a generic exprt to a specific derived class.
Forward depth-first search iterators These iterators' copy operations are expensive,...
exprt make_binary(const exprt &expr)
splits an expression with >=3 operands into nested binary expressions
Deprecated expression utility functions.
exprt float_bv(const exprt &src)
API to expression classes for floating-point arithmetic.
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
const floatbv_fma_exprt & to_floatbv_fma_expr(const exprt &expr)
const floatbv_round_to_integral_exprt & to_floatbv_round_to_integral_expr(const exprt &expr)
Cast an exprt to a floatbv_round_to_integral_exprt.
const isnormal_exprt & to_isnormal_expr(const exprt &expr)
Cast an exprt to a isnormal_exprt.
const isinf_exprt & to_isinf_expr(const exprt &expr)
Cast an exprt to a isinf_exprt.
const isfinite_exprt & to_isfinite_expr(const exprt &expr)
Cast an exprt to a isfinite_exprt.
const isnan_exprt & to_isnan_expr(const exprt &expr)
Cast an exprt to a isnan_exprt.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
const std::string & id2string(const irep_idt &d)
static std::string binary(const constant_exprt &src)
exprt to_expr(const namespacet &ns, const irep_idt &identifier, const std::string &src)
bool is_true(const literalt &l)
literalt const_literal(bool value)
const literal_exprt & to_literal_expr(const exprt &expr)
Cast a generic exprt to a literal_exprt.
API to expression classes for 'mathematical' expressions.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
const integer_range_typet & to_integer_range_type(const typet &type)
Cast a typet to a integer_range_typet.
const mathematical_function_typet & to_mathematical_function_type(const typet &type)
Cast a typet to a mathematical_function_typet.
const mp_integer string2integer(const std::string &n, unsigned base)
mp_integer bitwise_or(const mp_integer &a, const mp_integer &b)
bitwise 'or' of two nonnegative integers
const std::string integer2binary(const mp_integer &n, std::size_t width)
const element_address_exprt & to_element_address_expr(const exprt &expr)
Cast an exprt to an element_address_exprt.
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
bool is_zero_width(const typet &type, const namespacet &ns)
Returns true iff type has effective width of zero bits.
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
exprt pointer_offset(const exprt &pointer)
exprt object_size(const exprt &pointer)
exprt same_object(const exprt &p1, const exprt &p2)
Various predicates over pointers in programs.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
exprt simplify_expr(exprt src, const namespacet &ns)
static bool has_quantifier(const exprt &expr)
static bool is_smt2_simple_identifier(const std::string &identifier)
#define UNEXPECTEDCASE(S)
bool is_smt2_simple_symbol_character(char ch)
Tokenizer for the SMT-LIB v2.6 syntax.
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Same as invariant, with one or more diagnostics attached Diagnostics can be of any type that has a sp...
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
#define CHECK_RETURN_WITH_DIAGNOSTICS(CONDITION,...)
#define DATA_INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
#define UNREACHABLE_BECAUSE(REASON)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
API to expression classes.
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
const array_of_exprt & to_array_of_expr(const exprt &expr)
Cast an exprt to an array_of_exprt.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
const unary_plus_exprt & to_unary_plus_expr(const exprt &expr)
Cast an exprt to a unary_plus_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const mod_exprt & to_mod_expr(const exprt &expr)
Cast an exprt to a mod_exprt.
const mult_exprt & to_mult_expr(const exprt &expr)
Cast an exprt to a mult_exprt.
const array_comprehension_exprt & to_array_comprehension_expr(const exprt &expr)
Cast an exprt to a array_comprehension_exprt.
const ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
const named_term_exprt & to_named_term_expr(const exprt &expr)
Cast an exprt to a named_term_exprt.
const cond_exprt & to_cond_expr(const exprt &expr)
Cast an exprt to a cond_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const div_exprt & to_div_expr(const exprt &expr)
Cast an exprt to a div_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const notequal_exprt & to_notequal_expr(const exprt &expr)
Cast an exprt to an notequal_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const minus_exprt & to_minus_expr(const exprt &expr)
Cast an exprt to a minus_exprt.
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
const update_exprt & to_update_expr(const exprt &expr)
Cast an exprt to an update_exprt.
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
const nondet_symbol_exprt & to_nondet_symbol_expr(const exprt &expr)
Cast an exprt to a nondet_symbol_exprt.
const sign_exprt & to_sign_expr(const exprt &expr)
Cast an exprt to a sign_exprt.
const euclidean_mod_exprt & to_euclidean_mod_expr(const exprt &expr)
Cast an exprt to a euclidean_mod_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
std::size_t unsafe_string2size_t(const std::string &str, int base)
const string_constantt & to_string_constant(const exprt &expr)
static bool failed(bool error_indicator)