51 #define UNEXPECTEDCASE(S) PRECONDITION_WITH_DIAGNOSTICS(false, S);
54 #define SMT2_TODO(S) PRECONDITION_WITH_DIAGNOSTICS(false, "TODO: " S)
58 const std::string &_benchmark,
59 const std::string &_notes,
60 const std::string &_logic,
63 : use_FPA_theory(false),
64 use_array_of_bool(false),
66 use_check_sat_assuming(false),
68 use_lambda_for_array(false),
72 benchmark(_benchmark),
78 no_boolean_variables(0)
169 "variable number shall be within bounds");
175 out <<
"; SMT 2" <<
"\n";
184 out <<
"; Generated for the CPROVER SMT2 solver\n";
break;
194 out <<
"(set-info :source \"" <<
notes <<
"\")" <<
"\n";
196 out <<
"(set-option :produce-models true)" <<
"\n";
202 out <<
"(set-logic " <<
logic <<
")" <<
"\n";
215 out <<
"(check-sat-assuming (";
225 out <<
"; assumptions\n";
236 out <<
"(check-sat)\n";
244 out <<
"(get-value (" <<
id <<
"))"
252 out <<
"; end of SMT2 file"
259 if(type.
id() == ID_empty)
261 else if(type.
id() == ID_struct_tag)
263 else if(type.
id() == ID_union_tag)
265 else if(type.
id() == ID_struct || type.
id() == ID_union)
274 else if(
auto array_type = type_try_dynamic_cast<array_typet>(type))
290 std::size_t number = 0;
291 std::size_t h=pointer_width-1;
296 const typet &type = o.type();
300 (o.id() != ID_symbol && o.id() != ID_string_constant) ||
301 !size_expr.has_value())
308 out <<
"(assert (=> (= "
309 <<
"((_ extract " << h <<
" " << l <<
") ";
312 <<
"(= " <<
id <<
" ";
337 if(expr.
id()==ID_symbol)
344 return it->second.value;
347 else if(expr.
id()==ID_nondet_symbol)
354 return it->second.value;
356 else if(expr.
id() == ID_literal)
364 else if(expr.
id() == ID_not)
369 else if(op.is_false())
374 (!expr.
has_operands() && (expr.
id() == ID_struct || expr.
id() == ID_array)))
386 op = std::move(eval_op);
421 if(s.size()>=2 && s[0]==
'#' && s[1]==
'b')
426 else if(s.size()>=2 && s[0]==
'#' && s[1]==
'x')
437 else if(src.
get_sub().size()==2 &&
442 else if(src.
get_sub().size()==3 &&
445 src.
get_sub()[1].id_string().substr(0, 2)==
"bv")
449 else if(src.
get_sub().size()==4 &&
452 if(type.
id()==ID_floatbv)
461 const auto s1_int = numeric_cast_v<mp_integer>(
s1);
462 const auto s2_int = numeric_cast_v<mp_integer>(
s2);
463 const auto s3_int = numeric_cast_v<mp_integer>(s3);
467 s1_int << (floatbv_type.
get_e() + floatbv_type.
get_f()),
473 else if(src.
get_sub().size()==4 &&
481 else if(src.
get_sub().size()==4 &&
489 else if(src.
get_sub().size()==4 &&
498 if(type.
id()==ID_signedbv ||
499 type.
id()==ID_unsignedbv ||
500 type.
id()==ID_c_enum ||
501 type.
id()==ID_c_bool)
505 else if(type.
id()==ID_c_enum_tag)
511 result.
type() = type;
514 else if(type.
id()==ID_fixedbv ||
515 type.
id()==ID_floatbv)
520 else if(type.
id()==ID_integer ||
527 "smt2_convt::parse_literal should not be of unsupported type " +
535 std::unordered_map<int64_t, exprt> operands_map;
539 auto maybe_default_op = operands_map.find(-1);
541 if(maybe_default_op == operands_map.end())
544 default_op = maybe_default_op->second;
546 auto maybe_size = numeric_cast<std::int64_t>(type.
size());
547 if(maybe_size.has_value())
549 while(i < maybe_size.value())
551 auto found_op = operands_map.find(i);
552 if(found_op != operands_map.end())
553 operands.emplace_back(found_op->second);
555 operands.emplace_back(default_op);
563 auto found_op = operands_map.find(i);
564 while(found_op != operands_map.end())
566 operands.emplace_back(found_op->second);
568 found_op = operands_map.find(i);
570 operands.emplace_back(default_op);
576 std::unordered_map<int64_t, exprt> *operands_map,
589 bool failure =
to_integer(index_constant, tempint);
592 long index = tempint.to_long();
594 operands_map->emplace(index, value);
596 else if(src.
get_sub().size()==2 &&
597 src.
get_sub()[0].get_sub().size()==3 &&
598 src.
get_sub()[0].get_sub()[0].id()==
"as" &&
599 src.
get_sub()[0].get_sub()[1].id()==
"const")
603 operands_map->emplace(-1, default_value);
636 if(components.empty())
644 for(std::size_t i=0; i<components.size(); i++)
654 src.
get_sub().size() > j,
"insufficient number of component values");
671 std::size_t offset=0;
673 for(std::size_t i=0; i<components.size(); i++)
678 std::size_t component_width=
boolbv_width(components[i].type());
681 offset + component_width <= total_width,
682 "struct component bits shall be within struct bit vector");
684 std::string component_binary=
686 total_width-offset-component_width, component_width);
691 offset+=component_width;
705 for(
const auto &binding : src.
get_sub()[1].get_sub())
707 const irep_idt &name = binding.get_sub()[0].id();
718 return parse_rec(bindings_it->second, type);
722 type.
id() == ID_signedbv || type.
id() == ID_unsignedbv ||
723 type.
id() == ID_integer || type.
id() == ID_rational ||
724 type.
id() == ID_real || type.
id() == ID_c_enum ||
725 type.
id() == ID_c_enum_tag || type.
id() == ID_fixedbv ||
726 type.
id() == ID_floatbv || type.
id() == ID_c_bool || type.
id() == ID_range)
730 else if(type.
id()==ID_bool)
732 if(src.
id()==ID_1 || src.
id()==ID_true)
734 else if(src.
id()==ID_0 || src.
id()==ID_false)
737 else if(type.
id()==ID_pointer)
743 mp_integer v = numeric_cast_v<mp_integer>(bv_expr);
752 else if(type.
id()==ID_struct)
756 else if(type.
id() == ID_struct_tag)
761 struct_expr.type() = type;
762 return std::move(struct_expr);
764 else if(type.
id()==ID_union)
768 else if(type.
id() == ID_union_tag)
772 union_expr.type() = type;
775 else if(type.
id()==ID_array)
789 expr.
id() == ID_string_constant || expr.
id() == ID_label)
792 const std::size_t max_objects = std::size_t(1) << object_bits;
795 if(object_id >= max_objects)
798 "too many addressed objects: maximum number of objects is set to 2^n=" +
801 "use the `--object-bits n` option to increase the maximum number"};
804 out <<
"(concat (_ bv" << object_id <<
" " << object_bits <<
")"
805 <<
" (_ bv0 " <<
boolbv_width(result_type) - object_bits <<
"))";
807 else if(expr.
id()==ID_index)
816 if(array.
type().
id()==ID_pointer)
818 else if(array.
type().
id()==ID_array)
838 else if(expr.
id()==ID_member)
843 const typet &struct_op_type = struct_op.
type();
846 struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag,
847 "member expression operand shall have struct type");
850 struct_op_type.
id() == ID_struct_tag
867 else if(expr.
id()==ID_if)
882 "operand of address of expression should not be of kind " +
890 if(node.
id() == ID_exists || node.
id() == ID_forall)
906 else if(expr.
id()==ID_literal)
918 out <<
"; convert\n";
919 out <<
"; Converting var_no " << l.
var_no() <<
" with expr ID of "
929 out <<
"(declare-fun ";
931 out <<
" () Bool)\n";
932 out <<
"(assert (= ";
944 out <<
"(define-fun " << identifier <<
" () Bool ";
972 const auto identifier =
994 for(
auto &assumption : _assumptions)
1005 if(identifier.empty())
1030 std::string result =
"|";
1032 for(
auto ch : identifier)
1057 if(type.
id()==ID_floatbv)
1062 else if(type.
id() == ID_bv)
1066 else if(type.
id()==ID_unsignedbv)
1070 else if(type.
id()==ID_c_bool)
1074 else if(type.
id()==ID_signedbv)
1078 else if(type.
id()==ID_bool)
1082 else if(type.
id()==ID_c_enum_tag)
1086 else if(type.
id() == ID_pointer)
1090 else if(type.
id() == ID_struct_tag)
1097 else if(type.
id() == ID_union_tag)
1101 else if(type.
id() == ID_array)
1122 if(expr.
id()==ID_symbol)
1129 if(expr.
id()==ID_smt2_symbol)
1137 !expr.
operands().empty(),
"non-symbol expressions shall have operands");
1143 for(
const auto &op : expr.
operands())
1171 converter_result->second(expr);
1176 if(expr.
id()==ID_symbol)
1182 else if(expr.
id()==ID_nondet_symbol)
1185 DATA_INVARIANT(!
id.empty(),
"nondet symbol must have identifier");
1188 else if(expr.
id()==ID_smt2_symbol)
1194 else if(expr.
id()==ID_typecast)
1198 else if(expr.
id()==ID_floatbv_typecast)
1202 else if(expr.
id()==ID_struct)
1206 else if(expr.
id()==ID_union)
1214 else if(expr.
id() == ID_concatenation && expr.
operands().size() == 1)
1218 "concatenation over a single operand should have matching types",
1223 else if(expr.
id()==ID_concatenation ||
1224 expr.
id()==ID_bitand ||
1225 expr.
id()==ID_bitor ||
1226 expr.
id()==ID_bitxor ||
1227 expr.
id()==ID_bitnand ||
1228 expr.
id()==ID_bitnor)
1232 "given expression should have at least two operands",
1237 if(expr.
id()==ID_concatenation)
1239 else if(expr.
id()==ID_bitand)
1241 else if(expr.
id()==ID_bitor)
1243 else if(expr.
id()==ID_bitxor)
1245 else if(expr.
id()==ID_bitnand)
1247 else if(expr.
id()==ID_bitnor)
1250 for(
const auto &op : expr.
operands())
1258 else if(expr.
id()==ID_bitnot)
1266 else if(expr.
id()==ID_unary_minus)
1271 unary_minus_expr.
type().
id() == ID_rational ||
1272 unary_minus_expr.
type().
id() == ID_integer ||
1273 unary_minus_expr.
type().
id() == ID_real)
1279 else if(unary_minus_expr.
type().
id() == ID_floatbv)
1298 else if(expr.
id()==ID_unary_plus)
1303 else if(expr.
id()==ID_sign)
1309 if(op_type.
id()==ID_floatbv)
1313 out <<
"(fp.isNegative ";
1320 else if(op_type.
id()==ID_signedbv)
1326 out <<
" (_ bv0 " << op_width <<
"))";
1331 "sign should not be applied to unsupported type",
1334 else if(expr.
id()==ID_if)
1346 else if(expr.
id()==ID_and ||
1352 "logical and, or, and xor expressions should have Boolean type");
1355 "logical and, or, and xor expressions should have at least two operands");
1357 out <<
"(" << expr.
id();
1358 for(
const auto &op : expr.
operands())
1365 else if(expr.
id()==ID_implies)
1370 implies_expr.
is_boolean(),
"implies expression should have Boolean type");
1378 else if(expr.
id()==ID_not)
1383 not_expr.
is_boolean(),
"not expression should have Boolean type");
1389 else if(expr.
id() == ID_equal)
1395 "operands of equal expression shall have same type");
1410 else if(expr.
id() == ID_notequal)
1416 "operands of not equal expression shall have same type");
1424 else if(expr.
id()==ID_ieee_float_equal ||
1425 expr.
id()==ID_ieee_float_notequal)
1432 rel_expr.lhs().type() == rel_expr.rhs().type(),
1433 "operands of float equal and not equal expressions shall have same type");
1438 if(rel_expr.id() == ID_ieee_float_notequal)
1447 if(rel_expr.id() == ID_ieee_float_notequal)
1453 else if(expr.
id()==ID_le ||
1460 else if(expr.
id()==ID_plus)
1464 else if(expr.
id()==ID_floatbv_plus)
1468 else if(expr.
id()==ID_minus)
1472 else if(expr.
id()==ID_floatbv_minus)
1476 else if(expr.
id()==ID_div)
1480 else if(expr.
id()==ID_floatbv_div)
1484 else if(expr.
id()==ID_mod)
1488 else if(expr.
id() == ID_euclidean_mod)
1492 else if(expr.
id()==ID_mult)
1496 else if(expr.
id()==ID_floatbv_mult)
1500 else if(expr.
id() == ID_floatbv_rem)
1504 else if(expr.
id()==ID_address_of)
1510 else if(expr.
id() == ID_array_of)
1515 array_of_expr.type().id() == ID_array,
1516 "array of expression shall have array type");
1520 out <<
"((as const ";
1528 defined_expressionst::const_iterator it =
1534 else if(expr.
id() == ID_array_comprehension)
1539 array_comprehension.type().id() == ID_array,
1540 "array_comprehension expression shall have array type");
1544 out <<
"(lambda ((";
1547 convert_type(array_comprehension.type().size().type());
1559 else if(expr.
id()==ID_index)
1563 else if(expr.
id()==ID_ashr ||
1564 expr.
id()==ID_lshr ||
1570 if(type.
id()==ID_unsignedbv ||
1571 type.
id()==ID_signedbv ||
1574 if(shift_expr.
id() == ID_ashr)
1576 else if(shift_expr.
id() == ID_lshr)
1578 else if(shift_expr.
id() == ID_shl)
1608 if(width_op0==width_op1)
1610 else if(width_op0>width_op1)
1612 out <<
"((_ zero_extend " << width_op0-width_op1 <<
") ";
1618 out <<
"((_ extract " << width_op0-1 <<
" 0) ";
1625 "unsupported distance type for " + shift_expr.
id_string() +
": " +
1632 "unsupported type for " + shift_expr.
id_string() +
": " +
1635 else if(expr.
id() == ID_rol || expr.
id() == ID_ror)
1641 type.
id() == ID_unsignedbv || type.
id() == ID_signedbv ||
1646 if(shift_expr.
id() == ID_rol)
1647 out <<
"((_ rotate_left";
1648 else if(shift_expr.
id() == ID_ror)
1649 out <<
"((_ rotate_right";
1655 auto distance_int_op = numeric_cast<mp_integer>(shift_expr.
distance());
1657 if(distance_int_op.has_value())
1659 out << distance_int_op.value();
1663 "distance type for " + shift_expr.
id_string() +
"must be constant");
1672 "unsupported type for " + shift_expr.
id_string() +
": " +
1675 else if(expr.
id() == ID_named_term)
1679 convert(named_term_expr.value());
1683 else if(expr.
id()==ID_with)
1687 else if(expr.
id()==ID_update)
1691 else if(expr.
id() == ID_update_bit)
1695 else if(expr.
id() == ID_update_bits)
1699 else if(expr.
id() == ID_object_address)
1701 out <<
"(object-address ";
1706 else if(expr.
id() == ID_element_address)
1712 auto element_size_expr_opt =
1722 *element_size_expr_opt, element_address_expr.index().type()));
1725 else if(expr.
id() == ID_field_address)
1734 else if(expr.
id()==ID_member)
1738 else if(expr.
id()==ID_pointer_offset)
1743 op.type().id() == ID_pointer,
1744 "operand of pointer offset expression shall be of pointer type");
1746 std::size_t offset_bits =
1751 if(offset_bits>result_width)
1752 offset_bits=result_width;
1755 if(result_width>offset_bits)
1756 out <<
"((_ zero_extend " << result_width-offset_bits <<
") ";
1758 out <<
"((_ extract " << offset_bits-1 <<
" 0) ";
1762 if(result_width>offset_bits)
1765 else if(expr.
id()==ID_pointer_object)
1770 op.type().id() == ID_pointer,
1771 "pointer object expressions should be of pointer type");
1777 out <<
"((_ zero_extend " << ext <<
") ";
1779 out <<
"((_ extract "
1780 << pointer_width-1 <<
" "
1788 else if(expr.
id() == ID_is_dynamic_object)
1792 else if(expr.
id() == ID_is_invalid_pointer)
1796 out <<
"(= ((_ extract "
1797 << pointer_width-1 <<
" "
1803 else if(expr.
id()==ID_string_constant)
1809 else if(expr.
id()==ID_extractbit)
1818 out <<
"(= ((_ extract " << i <<
" " << i <<
") ";
1824 out <<
"(= ((_ extract 0 0) ";
1834 else if(expr.
id()==ID_extractbits)
1844 out <<
"((_ extract " << (width + index_i - 1) <<
" " << index_i <<
") ";
1851 out <<
"(= ((_ extract 0 0) ";
1860 SMT2_TODO(
"smt2: extractbits with non-constant index");
1863 else if(expr.
id()==ID_replication)
1867 mp_integer times = numeric_cast_v<mp_integer>(replication_expr.
times());
1869 out <<
"((_ repeat " << times <<
") ";
1873 else if(expr.
id()==ID_byte_extract_little_endian ||
1874 expr.
id()==ID_byte_extract_big_endian)
1877 false,
"byte_extract ops should be lowered in prepare_for_convert_expr");
1879 else if(expr.
id()==ID_byte_update_little_endian ||
1880 expr.
id()==ID_byte_update_big_endian)
1883 false,
"byte_update ops should be lowered in prepare_for_convert_expr");
1885 else if(expr.
id()==ID_abs)
1891 if(type.
id()==ID_signedbv)
1895 out <<
"(ite (bvslt ";
1897 out <<
" (_ bv0 " << result_width <<
")) ";
1904 else if(type.
id()==ID_fixedbv)
1908 out <<
"(ite (bvslt ";
1910 out <<
" (_ bv0 " << result_width <<
")) ";
1917 else if(type.
id()==ID_floatbv)
1931 else if(expr.
id()==ID_isnan)
1937 if(op_type.
id()==ID_fixedbv)
1939 else if(op_type.
id()==ID_floatbv)
1943 out <<
"(fp.isNaN ";
1953 else if(expr.
id()==ID_isfinite)
1959 if(op_type.
id()==ID_fixedbv)
1961 else if(op_type.
id()==ID_floatbv)
1967 out <<
"(not (fp.isNaN ";
1971 out <<
"(not (fp.isInfinite ";
1983 else if(expr.
id()==ID_isinf)
1989 if(op_type.
id()==ID_fixedbv)
1991 else if(op_type.
id()==ID_floatbv)
1995 out <<
"(fp.isInfinite ";
2005 else if(expr.
id()==ID_isnormal)
2011 if(op_type.
id()==ID_fixedbv)
2013 else if(op_type.
id()==ID_floatbv)
2017 out <<
"(fp.isNormal ";
2030 expr.
id() == ID_overflow_result_plus ||
2031 expr.
id() == ID_overflow_result_minus)
2040 "overflow plus and overflow minus expressions shall be of Boolean type");
2043 expr.
id() == ID_overflow_result_minus;
2044 const typet &op_type = op0.type();
2047 if(op_type.
id()==ID_signedbv)
2050 out <<
"(let ((?sum (";
2051 out << (subtract?
"bvsub":
"bvadd");
2052 out <<
" ((_ sign_extend 1) ";
2055 out <<
" ((_ sign_extend 1) ";
2065 out <<
"(mk-" << smt_typename;
2070 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2075 "((_ extract " << width <<
" " << width <<
") ?sum) "
2076 "((_ extract " << (width-1) <<
" " << (width-1) <<
") ?sum)";
2086 else if(op_type.
id()==ID_unsignedbv ||
2087 op_type.
id()==ID_pointer)
2090 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2091 out <<
" ((_ zero_extend 1) ";
2094 out <<
" ((_ zero_extend 1) ";
2106 out <<
"(mk-" << smt_typename;
2107 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2111 out <<
"((_ extract " << width <<
" " << width <<
") ?sum)";
2122 "overflow check should not be performed on unsupported type",
2127 expr.
id() == ID_overflow_result_mult)
2136 "overflow mult expression shall be of Boolean type");
2141 const typet &op_type = op0.type();
2144 if(op_type.
id()==ID_signedbv)
2146 out <<
"(let ( (prod (bvmul ((_ sign_extend " << width <<
") ";
2148 out <<
") ((_ sign_extend " << width <<
") ";
2158 out <<
"(mk-" << smt_typename;
2163 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2167 out <<
"(or (bvsge prod (_ bv" <<
power(2, width-1) <<
" "
2169 out <<
" (bvslt prod (bvneg (_ bv" <<
power(2, width - 1) <<
" "
2170 << width * 2 <<
"))))";
2179 else if(op_type.
id()==ID_unsignedbv)
2181 out <<
"(let ((prod (bvmul ((_ zero_extend " << width <<
") ";
2183 out <<
") ((_ zero_extend " << width <<
") ";
2193 out <<
"(mk-" << smt_typename;
2198 out <<
" ((_ extract " << width - 1 <<
" 0) prod) ";
2202 out <<
"(bvuge prod (_ bv" <<
power(2, width) <<
" " << width * 2 <<
"))";
2214 "overflow check should not be performed on unsupported type",
2217 else if(expr.
id() == ID_saturating_plus || expr.
id() == ID_saturating_minus)
2219 const bool subtract = expr.
id() == ID_saturating_minus;
2220 const auto &op_type = expr.
type();
2224 if(op_type.id() == ID_signedbv)
2229 out <<
"(let ((?sum (";
2230 out << (subtract ?
"bvsub" :
"bvadd");
2231 out <<
" ((_ sign_extend 1) ";
2234 out <<
" ((_ sign_extend 1) ";
2241 << width <<
" " << width
2244 << (width - 1) <<
" " << (width - 1) <<
") ?sum)";
2248 out <<
"((_ extract " << width - 1 <<
" 0) ?sum) ";
2251 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2258 else if(op_type.id() == ID_unsignedbv)
2263 out <<
"(let ((?sum (" << (subtract ?
"bvsub" :
"bvadd");
2264 out <<
" ((_ zero_extend 1) ";
2267 out <<
" ((_ zero_extend 1) ";
2272 out <<
"(ite (= ((_ extract " << width <<
" " << width <<
") ?sum) #b0) ";
2275 out <<
" ((_ extract " << width - 1 <<
" 0) ?sum) ";
2289 "saturating_plus/minus on unsupported type",
2290 op_type.id_string());
2292 else if(expr.
id()==ID_array)
2298 else if(expr.
id()==ID_literal)
2302 else if(expr.
id()==ID_forall ||
2303 expr.
id()==ID_exists)
2309 throw "MathSAT does not support quantifiers";
2311 if(quantifier_expr.
id() == ID_forall)
2313 else if(quantifier_expr.
id() == ID_exists)
2318 for(
const auto &bound : quantifier_expr.
variables())
2337 const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
2341 else if(expr.
id()==ID_let)
2344 const auto &variables = let_expr.
variables();
2345 const auto &values = let_expr.
values();
2350 for(
auto &binding :
make_range(variables).zip(values))
2369 else if(expr.
id()==ID_constraint_select_one)
2372 "smt2_convt::convert_expr: '" + expr.
id_string() +
2373 "' is not yet supported");
2375 else if(expr.
id() == ID_bswap)
2381 "operand of byte swap expression shall have same type as the expression");
2384 out <<
"(let ((bswap_op ";
2389 bswap_expr.
type().
id() == ID_signedbv ||
2390 bswap_expr.
type().
id() == ID_unsignedbv)
2392 const std::size_t width =
2399 width % bits_per_byte == 0,
2400 "bit width indicated by type of bswap expression should be a multiple "
2401 "of the number of bits per byte");
2403 const std::size_t bytes = width / bits_per_byte;
2412 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2416 out <<
"(bswap_byte_" <<
byte <<
' ';
2417 out <<
"((_ extract " << (
byte * bits_per_byte + (bits_per_byte - 1))
2418 <<
" " << (
byte * bits_per_byte) <<
") bswap_op)";
2427 for(std::size_t
byte = 0;
byte < bytes;
byte++)
2428 out <<
" bswap_byte_" <<
byte;
2439 else if(expr.
id() == ID_popcount)
2443 else if(expr.
id() == ID_count_leading_zeros)
2447 else if(expr.
id() == ID_count_trailing_zeros)
2451 else if(expr.
id() == ID_find_first_set)
2455 else if(expr.
id() == ID_bitreverse)
2459 else if(expr.
id() == ID_zero_extend)
2463 else if(expr.
id() == ID_function_application)
2467 if(function_application_expr.arguments().empty())
2475 for(
auto &op : function_application_expr.arguments())
2486 "smt2_convt::convert_expr should not be applied to unsupported type",
2495 if(dest_type.
id()==ID_c_enum_tag)
2499 if(src_type.
id()==ID_c_enum_tag)
2502 if(dest_type.
id()==ID_bool)
2505 if(src_type.
id()==ID_signedbv ||
2506 src_type.
id()==ID_unsignedbv ||
2507 src_type.
id()==ID_c_bool ||
2508 src_type.
id()==ID_fixedbv ||
2509 src_type.
id()==ID_pointer ||
2510 src_type.
id()==ID_integer)
2518 else if(src_type.
id()==ID_floatbv)
2522 out <<
"(not (fp.isZero ";
2534 else if(dest_type.
id()==ID_c_bool)
2543 out <<
" (_ bv1 " << to_width <<
")";
2544 out <<
" (_ bv0 " << to_width <<
")";
2547 else if(dest_type.
id()==ID_signedbv ||
2548 dest_type.
id()==ID_unsignedbv ||
2549 dest_type.
id()==ID_c_enum ||
2550 dest_type.
id()==ID_bv)
2554 if(src_type.
id()==ID_signedbv ||
2555 src_type.
id()==ID_unsignedbv ||
2556 src_type.
id()==ID_c_bool ||
2557 src_type.
id()==ID_c_enum ||
2558 src_type.
id()==ID_bv)
2562 if(from_width==to_width)
2564 else if(from_width<to_width)
2566 if(src_type.
id()==ID_signedbv)
2567 out <<
"((_ sign_extend ";
2569 out <<
"((_ zero_extend ";
2571 out << (to_width-from_width)
2578 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2583 else if(src_type.
id()==ID_fixedbv)
2587 std::size_t from_width=fixedbv_type.
get_width();
2594 out <<
"(let ((?tcop ";
2600 if(to_width>from_integer_bits)
2602 out <<
"((_ sign_extend "
2603 << (to_width-from_integer_bits) <<
") ";
2604 out <<
"((_ extract " << (from_width-1) <<
" "
2605 << from_fraction_bits <<
") ";
2611 out <<
"((_ extract " << (from_fraction_bits+to_width-1)
2612 <<
" " << from_fraction_bits <<
") ";
2617 out <<
" (ite (and ";
2620 out <<
"(not (= ((_ extract " << (from_fraction_bits-1) <<
" 0) ?tcop) "
2621 "(_ bv0 " << from_fraction_bits <<
")))";
2624 out <<
" (= ((_ extract " << (from_width-1) <<
" " << (from_width-1)
2629 out <<
" (_ bv1 " << to_width <<
") (_ bv0 " << to_width <<
"))";
2633 else if(src_type.
id()==ID_floatbv)
2635 if(dest_type.
id()==ID_bv)
2641 defined_expressionst::const_iterator it =
2652 else if(dest_type.
id()==ID_signedbv)
2656 "typecast unexpected "+src_type.
id_string()+
" -> "+
2659 else if(dest_type.
id()==ID_unsignedbv)
2663 "typecast unexpected "+src_type.
id_string()+
" -> "+
2667 else if(src_type.
id()==ID_bool)
2672 if(dest_type.
id()==ID_fixedbv)
2675 out <<
" (concat (_ bv1 "
2678 "(_ bv0 " << spec.
width <<
")";
2682 out <<
" (_ bv1 " << to_width <<
")";
2683 out <<
" (_ bv0 " << to_width <<
")";
2688 else if(src_type.
id()==ID_pointer)
2692 if(from_width<to_width)
2694 out <<
"((_ sign_extend ";
2695 out << (to_width-from_width)
2702 out <<
"((_ extract " << (to_width-1) <<
" 0) ";
2707 else if(src_type.
id()==ID_integer)
2713 out <<
"(_ bv" << i <<
" " << to_width <<
")";
2716 SMT2_TODO(
"can't convert non-constant integer to bitvector");
2719 src_type.
id() == ID_struct ||
2720 src_type.
id() == ID_struct_tag)
2726 "bit vector with of source and destination type shall be equal");
2733 "bit vector with of source and destination type shall be equal");
2738 src_type.
id() == ID_union ||
2739 src_type.
id() == ID_union_tag)
2743 "bit vector with of source and destination type shall be equal");
2746 else if(src_type.
id()==ID_c_bit_field)
2750 if(from_width==to_width)
2761 std::ostringstream e_str;
2762 e_str << src_type.
id() <<
" -> " << dest_type.
id()
2763 <<
" src == " <<
format(src);
2767 else if(dest_type.
id()==ID_fixedbv)
2773 if(src_type.
id()==ID_unsignedbv ||
2774 src_type.
id()==ID_signedbv ||
2775 src_type.
id()==ID_c_enum)
2782 if(from_width==to_integer_bits)
2784 else if(from_width>to_integer_bits)
2787 out <<
"((_ extract " << (to_integer_bits-1) <<
" 0) ";
2795 from_width < to_integer_bits,
2796 "from_width should be smaller than to_integer_bits as other case "
2797 "have been handled above");
2798 if(dest_type.
id()==ID_unsignedbv)
2800 out <<
"(_ zero_extend "
2801 << (to_integer_bits-from_width) <<
") ";
2807 out <<
"((_ sign_extend "
2808 << (to_integer_bits-from_width) <<
") ";
2814 out <<
"(_ bv0 " << to_fraction_bits <<
")";
2817 else if(src_type.
id()==ID_bool)
2819 out <<
"(concat (concat"
2820 <<
" (_ bv0 " << (to_integer_bits-1) <<
") ";
2826 else if(src_type.
id()==ID_fixedbv)
2831 std::size_t from_width=from_fixedbv_type.
get_width();
2833 out <<
"(let ((?tcop ";
2839 if(to_integer_bits<=from_integer_bits)
2841 out <<
"((_ extract "
2842 << (from_fraction_bits+to_integer_bits-1) <<
" "
2843 << from_fraction_bits
2849 to_integer_bits > from_integer_bits,
2850 "to_integer_bits should be greater than from_integer_bits as the"
2851 "other case has been handled above");
2852 out <<
"((_ sign_extend "
2853 << (to_integer_bits-from_integer_bits)
2855 << (from_width-1) <<
" "
2856 << from_fraction_bits
2862 if(to_fraction_bits<=from_fraction_bits)
2864 out <<
"((_ extract "
2865 << (from_fraction_bits-1) <<
" "
2866 << (from_fraction_bits-to_fraction_bits)
2872 to_fraction_bits > from_fraction_bits,
2873 "to_fraction_bits should be greater than from_fraction_bits as the"
2874 "other case has been handled above");
2875 out <<
"(concat ((_ extract "
2876 << (from_fraction_bits-1) <<
" 0) ";
2879 <<
" (_ bv0 " << to_fraction_bits-from_fraction_bits
2888 else if(dest_type.
id()==ID_pointer)
2892 if(src_type.
id()==ID_pointer)
2898 src_type.
id() == ID_unsignedbv || src_type.
id() == ID_signedbv ||
2899 src_type.
id() == ID_bv)
2905 if(from_width==to_width)
2907 else if(from_width<to_width)
2909 out <<
"((_ sign_extend "
2910 << (to_width-from_width)
2917 out <<
"((_ extract " << to_width <<
" 0) ";
2925 else if(dest_type.
id()==ID_range)
2928 const auto dest_size =
2929 dest_range_type.get_to() - dest_range_type.get_from() + 1;
2931 if(src_type.
id() == ID_range)
2934 const auto src_size =
2935 src_range_type.get_to() - src_range_type.get_from() + 1;
2937 if(src_width < dest_width)
2939 out <<
"((_ zero_extend " << dest_width - src_width <<
") ";
2943 else if(src_width > dest_width)
2945 out <<
"((_ extract " << dest_width - 1 <<
" 0) ";
2957 else if(dest_type.
id()==ID_floatbv)
2966 if(src_type.
id()==ID_bool)
2981 a.
build(significand, exponent);
2989 a.
build(significand, exponent);
2995 else if(src_type.
id()==ID_c_bool)
3001 else if(src_type.
id() == ID_bv)
3010 out <<
"((_ to_fp " << dest_floatbv_type.get_e() <<
" "
3011 << dest_floatbv_type.get_f() + 1 <<
") ";
3021 else if(dest_type.
id()==ID_integer)
3023 if(src_type.
id()==ID_bool)
3032 else if(dest_type.
id()==ID_c_bit_field)
3037 if(from_width==to_width)
3058 if(dest_type.
id()==ID_floatbv)
3060 if(src_type.
id()==ID_floatbv)
3087 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3088 << dst.
get_f() + 1 <<
") ";
3097 else if(src_type.
id()==ID_unsignedbv)
3118 out <<
"((_ to_fp_unsigned " << dst.
get_e() <<
" "
3119 << dst.
get_f() + 1 <<
") ";
3128 else if(src_type.
id()==ID_signedbv)
3136 out <<
"((_ to_fp " << dst.
get_e() <<
" "
3137 << dst.
get_f() + 1 <<
") ";
3146 else if(src_type.
id()==ID_c_enum_tag)
3160 else if(dest_type.
id()==ID_signedbv)
3165 out <<
"((_ fp.to_sbv " << dest_width <<
") ";
3174 else if(dest_type.
id()==ID_unsignedbv)
3179 out <<
"((_ fp.to_ubv " << dest_width <<
") ";
3198 expr.
type().
id() == ID_struct_tag
3206 components.size() == expr.
operands().size(),
3207 "number of struct components as indicated by the struct type shall be equal"
3208 "to the number of operands of the struct expression");
3210 DATA_INVARIANT(!components.empty(),
"struct shall have struct components");
3214 const std::string &smt_typename =
datatype_map.at(struct_type);
3217 out <<
"(mk-" << smt_typename;
3220 for(struct_typet::componentst::const_iterator
3221 it=components.begin();
3222 it!=components.end();
3235 auto convert_operand = [
this](
const exprt &op) {
3239 else if(op.type().id() == ID_bool)
3246 std::size_t n_concat = 0;
3247 for(std::size_t i = components.size(); i > 1; i--)
3257 convert_operand(expr.
operands()[i - 1]);
3263 convert_operand(expr.
op0());
3265 out << std::string(n_concat,
')');
3273 const auto &size_expr = array_type.
size();
3279 out <<
"(let ((?far ";
3287 out <<
"(select ?far ";
3309 if(total_width==member_width)
3317 total_width > member_width,
3318 "total_width should be greater than member_width as member_width can be"
3319 "at most as large as total_width and the other case has been handled "
3323 << (total_width-member_width) <<
") ";
3333 if(expr_type.
id()==ID_unsignedbv ||
3334 expr_type.
id()==ID_signedbv ||
3335 expr_type.
id()==ID_bv ||
3336 expr_type.
id()==ID_c_enum ||
3337 expr_type.
id()==ID_c_enum_tag ||
3338 expr_type.
id()==ID_c_bool ||
3339 expr_type.
id()==ID_c_bit_field)
3345 out <<
"(_ bv" << value
3346 <<
" " << width <<
")";
3348 else if(expr_type.
id()==ID_fixedbv)
3354 out <<
"(_ bv" << v <<
" " << spec.
width <<
")";
3356 else if(expr_type.
id()==ID_floatbv)
3369 size_t e=floatbv_type.
get_e();
3370 size_t f=floatbv_type.
get_f()+1;
3376 out <<
"((_ to_fp " << e <<
" " << f <<
")"
3382 out <<
"(_ NaN " << e <<
" " << f <<
")";
3387 out <<
"(_ -oo " << e <<
" " << f <<
")";
3389 out <<
"(_ +oo " << e <<
" " << f <<
")";
3399 <<
"#b" << binaryString.substr(0, 1) <<
" "
3400 <<
"#b" << binaryString.substr(1, e) <<
" "
3401 <<
"#b" << binaryString.substr(1+e, f-1) <<
")";
3409 out <<
"(_ bv" << v <<
" " << spec.
width() <<
")";
3412 else if(expr_type.
id()==ID_pointer)
3426 out <<
"(_ bv" << value <<
" " << width <<
")";
3429 else if(expr_type.
id()==ID_bool)
3438 else if(expr_type.
id()==ID_array)
3444 else if(expr_type.
id()==ID_rational)
3447 const bool negative =
has_prefix(value,
"-");
3452 size_t pos=value.find(
"/");
3454 if(
pos==std::string::npos)
3455 out << value <<
".0";
3458 out <<
"(/ " << value.substr(0,
pos) <<
".0 "
3459 << value.substr(
pos+1) <<
".0)";
3465 else if(expr_type.
id()==ID_integer)
3471 out <<
"(- " << value.substr(1, std::string::npos) <<
')';
3475 else if(expr_type.
id() == ID_range)
3478 const auto size = range_type.get_to() - range_type.get_from() + 1;
3480 const auto value_int = numeric_cast_v<mp_integer>(expr);
3481 out <<
"(_ bv" << (value_int - range_type.get_from()) <<
" " << width
3490 if(expr.
type().
id() == ID_integer)
3500 "unsupported type for euclidean_mod: " + expr.
type().
id_string());
3505 if(expr.
type().
id()==ID_unsignedbv ||
3506 expr.
type().
id()==ID_signedbv)
3508 if(expr.
type().
id()==ID_unsignedbv)
3524 std::vector<mp_integer> dynamic_objects;
3527 if(dynamic_objects.empty())
3533 out <<
"(let ((?obj ((_ extract "
3534 << pointer_width-1 <<
" "
3539 if(dynamic_objects.size()==1)
3541 out <<
"(= (_ bv" << dynamic_objects.front()
3548 for(
const auto &
object : dynamic_objects)
3549 out <<
" (= (_ bv" <<
object
3563 if(op_type.
id()==ID_unsignedbv ||
3564 op_type.
id()==ID_bv)
3567 if(expr.
id()==ID_le)
3569 else if(expr.
id()==ID_lt)
3571 else if(expr.
id()==ID_ge)
3573 else if(expr.
id()==ID_gt)
3582 else if(op_type.
id()==ID_signedbv ||
3583 op_type.
id()==ID_fixedbv)
3586 if(expr.
id()==ID_le)
3588 else if(expr.
id()==ID_lt)
3590 else if(expr.
id()==ID_ge)
3592 else if(expr.
id()==ID_gt)
3601 else if(op_type.
id()==ID_floatbv)
3606 if(expr.
id()==ID_le)
3608 else if(expr.
id()==ID_lt)
3610 else if(expr.
id()==ID_ge)
3612 else if(expr.
id()==ID_gt)
3624 else if(op_type.
id()==ID_rational ||
3625 op_type.
id()==ID_integer)
3636 else if(op_type.
id() == ID_pointer)
3644 if(expr.
id() == ID_le)
3646 else if(expr.
id() == ID_lt)
3648 else if(expr.
id() == ID_ge)
3650 else if(expr.
id() == ID_gt)
3669 expr.
type().
id() == ID_rational || expr.
type().
id() == ID_integer ||
3670 expr.
type().
id() == ID_real)
3675 for(
const auto &op : expr.
operands())
3684 expr.
type().
id() == ID_unsignedbv || expr.
type().
id() == ID_signedbv ||
3685 expr.
type().
id() == ID_fixedbv || expr.
type().
id() == ID_range)
3702 else if(expr.
type().
id() == ID_floatbv)
3709 else if(expr.
type().
id() == ID_pointer)
3715 if(p.
type().
id() != ID_pointer)
3719 p.
type().
id() == ID_pointer,
3720 "one of the operands should have pointer type");
3724 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
3727 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
3731 out <<
"(let ((?pointerop ";
3737 const std::size_t offset_bits =
3741 out <<
"((_ extract " << pointer_width - 1 <<
' ' << offset_bits
3742 <<
") ?pointerop) ";
3743 out <<
"(bvadd ((_ extract " << offset_bits - 1 <<
" 0) ?pointerop) ";
3745 if(element_size >= 2)
3747 out <<
"(bvmul ((_ extract " << offset_bits - 1 <<
" 0) ";
3749 out <<
") (_ bv" << element_size <<
" " << offset_bits <<
"))";
3753 out <<
"((_ extract " << offset_bits - 1 <<
" 0) ";
3789 mp_integer value = numeric_cast_v<mp_integer>(cexpr);
3792 out <<
"roundNearestTiesToEven";
3794 out <<
"roundTowardNegative";
3796 out <<
"roundTowardPositive";
3798 out <<
"roundTowardZero";
3802 "Rounding mode should have value 0, 1, 2, or 3",
3810 out <<
"(ite (= (_ bv0 " << width <<
") ";
3812 out <<
") roundNearestTiesToEven ";
3814 out <<
"(ite (= (_ bv1 " << width <<
") ";
3816 out <<
") roundTowardNegative ";
3818 out <<
"(ite (= (_ bv2 " << width <<
") ";
3820 out <<
") roundTowardPositive ";
3823 out <<
"roundTowardZero";
3834 type.
id() == ID_floatbv ||
3835 (type.
id() == ID_complex &&
3840 if(type.
id()==ID_floatbv)
3850 else if(type.
id()==ID_complex)
3857 "type should not be one of the unsupported types",
3866 if(expr.
type().
id()==ID_integer)
3874 else if(expr.
type().
id()==ID_unsignedbv ||
3875 expr.
type().
id()==ID_signedbv ||
3876 expr.
type().
id()==ID_fixedbv)
3878 if(expr.
op0().
type().
id()==ID_pointer &&
3884 base_type.id() != ID_empty,
"no pointer arithmetic over void pointers");
3886 CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
3889 if(element_size >= 2)
3894 "bitvector width of operand shall be equal to the bitvector width of "
3903 if(element_size >= 2)
3916 else if(expr.
type().
id()==ID_floatbv)
3923 else if(expr.
type().
id()==ID_pointer)
3927 (expr.
op1().
type().
id() == ID_unsignedbv ||
3946 expr.
type().
id() == ID_floatbv,
3947 "type of ieee floating point expression shall be floatbv");
3965 if(expr.
type().
id()==ID_unsignedbv ||
3966 expr.
type().
id()==ID_signedbv)
3968 if(expr.
type().
id()==ID_unsignedbv)
3978 else if(expr.
type().
id()==ID_fixedbv)
3983 out <<
"((_ extract " << spec.
width-1 <<
" 0) ";
3988 out <<
" (_ bv0 " << fraction_bits <<
")) ";
3990 out <<
"((_ sign_extend " << fraction_bits <<
") ";
3996 else if(expr.
type().
id()==ID_floatbv)
4010 expr.
type().
id() == ID_floatbv,
4011 "type of ieee floating point expression shall be floatbv");
4042 "expression should have been converted to a variant with two operands");
4044 if(expr.
type().
id()==ID_unsignedbv ||
4045 expr.
type().
id()==ID_signedbv)
4056 else if(expr.
type().
id()==ID_floatbv)
4063 else if(expr.
type().
id()==ID_fixedbv)
4068 out <<
"((_ extract "
4069 << spec.
width+fraction_bits-1 <<
" "
4070 << fraction_bits <<
") ";
4074 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4078 out <<
"((_ sign_extend " << fraction_bits <<
") ";
4084 else if(expr.
type().
id()==ID_rational ||
4085 expr.
type().
id()==ID_integer ||
4086 expr.
type().
id()==ID_real)
4090 for(
const auto &op : expr.
operands())
4105 expr.
type().
id() == ID_floatbv,
4106 "type of ieee floating point expression shall be floatbv");
4125 expr.
type().
id() == ID_floatbv,
4126 "type of ieee floating point expression shall be floatbv");
4140 "smt2_convt::convert_floatbv_rem to be implemented when not using "
4151 std::size_t s=expr.
operands().size();
4166 "with expression should have been converted to a version with three "
4171 if(expr_type.
id()==ID_array)
4195 out <<
"(let ((distance? ";
4196 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4200 if(array_width>index_width)
4202 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4208 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4218 out <<
"(bvshl (_ bv" <<
power(2, sub_width) - 1 <<
" " << array_width
4220 out <<
"distance?)) ";
4224 out <<
"((_ zero_extend " << array_width-sub_width <<
") ";
4226 out <<
") distance?)))";
4229 else if(expr_type.
id() == ID_struct || expr_type.
id() == ID_struct_tag)
4232 expr_type.
id() == ID_struct_tag
4239 const irep_idt &component_name=index.
get(ID_component_name);
4243 "struct should have accessed component");
4247 const std::string &smt_typename =
datatype_map.at(expr_type);
4249 out <<
"(update-" << smt_typename <<
"." << component_name <<
" ";
4263 out <<
"(let ((?withop ";
4267 if(m.
width==struct_width)
4277 <<
"((_ extract " << (struct_width-1) <<
" "
4278 << m.
width <<
") ?withop) ";
4287 out <<
" ((_ extract " << (m.
offset - 1) <<
" 0) ?withop))";
4292 out <<
"(concat (concat "
4293 <<
"((_ extract " << (struct_width-1) <<
" "
4296 out <<
") ((_ extract " << (m.
offset-1) <<
" 0) ?withop)";
4303 else if(expr_type.
id() == ID_union || expr_type.
id() == ID_union_tag)
4311 if(total_width==member_width)
4318 total_width > member_width,
4319 "total width should be greater than member_width as member_width is at "
4320 "most as large as total_width and the other case has been handled "
4323 out <<
"((_ extract "
4325 <<
" " << member_width <<
") ";
4332 else if(expr_type.
id()==ID_bv ||
4333 expr_type.
id()==ID_unsignedbv ||
4334 expr_type.
id()==ID_signedbv)
4349 "with expects struct, union, or array type, but got "+
4357 SMT2_TODO(
"smt2_convt::convert_update to be implemented");
4374 if(array_op_type.
id()==ID_array)
4409 out <<
"((_ extract " << sub_width-1 <<
" 0) ";
4413 out <<
"(bvmul (_ bv" << sub_width <<
" " << array_width <<
") ";
4417 if(array_width>index_width)
4419 out <<
"((_ zero_extend " << array_width-index_width <<
") ";
4425 out <<
"((_ extract " << array_width-1 <<
" 0) ";
4437 false,
"index with unsupported array type: " + array_op_type.
id_string());
4444 const typet &struct_op_type = struct_op.
type();
4447 if(struct_op_type.
id() == ID_struct || struct_op_type.
id() == ID_struct_tag)
4450 struct_op_type.
id() == ID_struct_tag
4455 struct_type.
has_component(name),
"struct should have accessed component");
4459 const std::string &smt_typename =
datatype_map.at(struct_type);
4461 out <<
"(" << smt_typename <<
"."
4472 if(expr.
type().
id() == ID_bool)
4478 if(expr.
type().
id() == ID_bool)
4483 struct_op_type.
id() == ID_union || struct_op_type.
id() == ID_union_tag)
4487 width != 0,
"failed to get union member width");
4493 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4501 out <<
"((_ extract " << (width - 1) <<
" 0) ";
4508 "convert_member on an unexpected type "+struct_op_type.
id_string());
4515 if(type.
id()==ID_bool)
4521 else if(type.
id()==ID_array)
4532 std::size_t n_concat = 0;
4546 out << std::string(n_concat,
')');
4551 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4564 std::size_t n_concat = 0;
4565 for(std::size_t i=components.size(); i>1; i--)
4585 out << std::string(n_concat,
')');
4590 else if(type.
id()==ID_floatbv)
4594 "floatbv expressions should be flattened when using FPA theory");
4607 if(type.
id()==ID_bool)
4614 else if(type.
id() == ID_array)
4619 out <<
"(let ((?ufop" << nesting <<
" ";
4630 "cannot unflatten arrays of non-constant size");
4637 out <<
"((as const ";
4642 out <<
"((_ extract " << subtype_width - 1 <<
" "
4643 <<
"0) ?ufop" << nesting <<
")";
4647 std::size_t offset = subtype_width;
4648 for(
mp_integer i = 1; i < size; ++i, offset += subtype_width)
4653 out <<
"((_ extract " << offset + subtype_width - 1 <<
" " << offset
4654 <<
") ?ufop" << nesting <<
")";
4662 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
4668 out <<
"(let ((?ufop" << nesting <<
" ";
4673 const std::string &smt_typename =
datatype_map.at(type);
4675 out <<
"(mk-" << smt_typename;
4684 std::size_t offset=0;
4687 for(struct_typet::componentst::const_iterator
4688 it=components.begin();
4689 it!=components.end();
4699 out <<
"((_ extract " << offset+member_width-1 <<
" "
4700 << offset <<
") ?ufop" << nesting <<
")";
4702 offset+=member_width;
4723 if(expr.
id()==ID_and && value)
4725 for(
const auto &op : expr.
operands())
4730 if(expr.
id()==ID_or && !value)
4732 for(
const auto &op : expr.
operands())
4737 if(expr.
id()==ID_not)
4747 if(expr.
id() == ID_equal && value)
4756 if(equal_expr.
lhs().
id()==ID_symbol)
4763 equal_expr.
lhs() != equal_expr.
rhs())
4775 out <<
"; set_to true (equal)\n";
4777 if(equal_expr.
lhs().
type().
id() == ID_mathematical_function)
4781 out <<
"(declare-fun " << smt2_identifier;
4783 auto &mathematical_function_type =
4789 for(
auto &t : mathematical_function_type.domain())
4803 out <<
"(assert (= " << smt2_identifier <<
' ';
4805 out <<
')' <<
')' <<
'\n';
4809 out <<
"(define-fun " << smt2_identifier;
4814 equal_expr.
lhs().
type().
id() != ID_array ||
4842 out <<
"; set_to " << (value?
"true":
"false") <<
"\n"
4853 out << found_literal->second;
4876 exprt lowered_expr = expr;
4883 it->id() == ID_byte_extract_little_endian ||
4884 it->id() == ID_byte_extract_big_endian)
4889 it->id() == ID_byte_update_little_endian ||
4890 it->id() == ID_byte_update_big_endian)
4896 return lowered_expr;
4913 "lower_byte_operators should remove all byte operators");
4920 auto prophecy_r_or_w_ok =
4921 expr_try_dynamic_cast<prophecy_r_or_w_ok_exprt>(*it))
4924 it.mutate() = lowered;
4925 it.next_sibling_or_parent();
4928 auto prophecy_pointer_in_range =
4929 expr_try_dynamic_cast<prophecy_pointer_in_range_exprt>(*it))
4932 it.mutate() = lowered;
4933 it.next_sibling_or_parent();
4942 return lowered_expr;
4953 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
4955 std::unordered_map<irep_idt, std::optional<identifiert>> shadowed_syms;
4960 for(
const auto &symbol : q_expr.variables())
4962 const auto identifier = symbol.get_identifier();
4965 shadowed_syms.insert(
4967 id_entry.second ? std::nullopt
4968 : std::optional{id_entry.first->second}});
4971 for(
const auto &[
id, shadowed_val] : shadowed_syms)
4974 if(!shadowed_val.has_value())
4977 previous_entry->second = std::move(*shadowed_val);
4983 for(
const auto &op : expr.
operands())
4986 if(expr.
id()==ID_symbol ||
4987 expr.
id()==ID_nondet_symbol)
4990 if(expr.
type().
id()==ID_code)
4995 if(expr.
id()==ID_symbol)
4998 identifier=
"nondet_"+
5009 out <<
"; find_symbols\n";
5010 out <<
"(declare-fun " << smt2_identifier;
5012 if(expr.
type().
id() == ID_mathematical_function)
5014 auto &mathematical_function_type =
5019 for(
auto &type : mathematical_function_type.domain())
5040 else if(expr.
id() == ID_array_of)
5047 const auto &array_type = array_of.type();
5051 out <<
"; the following is a substitute for lambda i. x\n";
5052 out <<
"(declare-fun " <<
id <<
" () ";
5059 out <<
"(assert (forall ((i ";
5061 out <<
")) (= (select " <<
id <<
" i) ";
5079 else if(expr.
id() == ID_array_comprehension)
5086 const auto &array_type = array_comprehension.type();
5087 const auto &array_size = array_type.size();
5091 out <<
"(declare-fun " <<
id <<
" () ";
5095 out <<
"; the following is a substitute for lambda i . x(i)\n";
5096 out <<
"; universally quantified initialization of the array\n";
5097 out <<
"(assert (forall ((";
5101 out <<
")) (=> (and (bvule (_ bv0 " <<
boolbv_width(array_size.type())
5108 out <<
")) (= (select " <<
id <<
" ";
5127 else if(expr.
id()==ID_array)
5134 out <<
"; the following is a substitute for an array constructor" <<
"\n";
5135 out <<
"(declare-fun " <<
id <<
" () ";
5141 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5143 out <<
"(assert (= (select " <<
id <<
" ";
5164 else if(expr.
id()==ID_string_constant)
5174 out <<
"; the following is a substitute for a string" <<
"\n";
5175 out <<
"(declare-fun " <<
id <<
" () ";
5179 for(std::size_t i=0; i<tmp.
operands().size(); i++)
5181 out <<
"(assert (= (select " <<
id <<
' ';
5185 out <<
"))" <<
"\n";
5192 const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
5198 out <<
"(declare-fun " <<
id <<
" () ";
5209 (expr.
id() == ID_floatbv_plus ||
5210 expr.
id() == ID_floatbv_minus ||
5211 expr.
id() == ID_floatbv_mult ||
5212 expr.
id() == ID_floatbv_div ||
5213 expr.
id() == ID_floatbv_typecast ||
5214 expr.
id() == ID_ieee_float_equal ||
5215 expr.
id() == ID_ieee_float_notequal ||
5216 ((expr.
id() == ID_lt ||
5217 expr.
id() == ID_gt ||
5218 expr.
id() == ID_le ||
5219 expr.
id() == ID_ge ||
5220 expr.
id() == ID_isnan ||
5221 expr.
id() == ID_isnormal ||
5222 expr.
id() == ID_isfinite ||
5223 expr.
id() == ID_isinf ||
5224 expr.
id() == ID_sign ||
5225 expr.
id() == ID_unary_minus ||
5226 expr.
id() == ID_typecast ||
5227 expr.
id() == ID_abs) &&
5234 if(
bvfp_set.insert(
function).second)
5236 out <<
"; this is a model for " << expr.
id() <<
" : "
5239 <<
"(define-fun " <<
function <<
" (";
5241 for(std::size_t i = 0; i < expr.
operands().size(); i++)
5245 out <<
"(op" << i <<
' ';
5255 for(std::size_t i = 0; i < tmp1.
operands().size(); i++)
5271 expr.
type().
id() == ID_bv)
5281 out <<
"(declare-fun " <<
id <<
" () ";
5287 out <<
"(assert (= ";
5288 out <<
"((_ to_fp " << floatbv_type.get_e() <<
" "
5289 << floatbv_type.get_f() + 1 <<
") " <<
id <<
')';
5297 else if(expr.
id() == ID_initial_state)
5299 irep_idt function =
"initial-state";
5303 out <<
"(declare-fun " <<
function <<
" (";
5310 else if(expr.
id() == ID_evaluate)
5316 out <<
"(declare-fun " <<
function <<
" (";
5326 expr.
id() == ID_state_is_cstring ||
5327 expr.
id() == ID_state_is_dynamic_object ||
5328 expr.
id() == ID_state_live_object || expr.
id() == ID_state_writeable_object)
5331 expr.
id() == ID_state_is_cstring ?
"state-is-cstring"
5332 : expr.
id() == ID_state_is_dynamic_object ?
"state-is-dynamic-object"
5333 : expr.
id() == ID_state_live_object ?
"state-live-object"
5334 :
"state-writeable-object";
5338 out <<
"(declare-fun " <<
function <<
" (";
5348 expr.
id() == ID_state_r_ok || expr.
id() == ID_state_w_ok ||
5349 expr.
id() == ID_state_rw_ok)
5351 irep_idt function = expr.
id() == ID_state_r_ok ?
"state-r-ok"
5352 : expr.
id() == ID_state_w_ok ?
"state-w-ok"
5357 out <<
"(declare-fun " <<
function <<
" (";
5368 else if(expr.
id() == ID_update_state)
5375 out <<
"(declare-fun " <<
function <<
" (";
5386 else if(expr.
id() == ID_enter_scope_state)
5393 out <<
"(declare-fun " <<
function <<
" (";
5404 else if(expr.
id() == ID_exit_scope_state)
5411 out <<
"(declare-fun " <<
function <<
" (";
5420 else if(expr.
id() == ID_allocate)
5426 out <<
"(declare-fun " <<
function <<
" (";
5435 else if(expr.
id() == ID_reallocate)
5441 out <<
"(declare-fun " <<
function <<
" (";
5452 else if(expr.
id() == ID_deallocate_state)
5458 out <<
"(declare-fun " <<
function <<
" (";
5467 else if(expr.
id() == ID_object_address)
5469 irep_idt function =
"object-address";
5473 out <<
"(declare-fun " <<
function <<
" (String) ";
5478 else if(expr.
id() == ID_field_address)
5484 out <<
"(declare-fun " <<
function <<
" (";
5493 else if(expr.
id() == ID_element_address)
5499 out <<
"(declare-fun " <<
function <<
" (";
5518 if(expr.
id() == ID_with)
5526 if(type.
id()==ID_array)
5540 out <<
"(_ BitVec 1)";
5546 else if(type.
id()==ID_bool)
5550 else if(type.
id() == ID_struct || type.
id() == ID_struct_tag)
5560 out <<
"(_ BitVec " << width <<
")";
5563 else if(type.
id()==ID_code)
5570 else if(type.
id() == ID_union || type.
id() == ID_union_tag)
5577 union_type.
components().empty() || width != 0,
5578 "failed to get width of union");
5580 out <<
"(_ BitVec " << width <<
")";
5582 else if(type.
id()==ID_pointer)
5587 else if(type.
id()==ID_bv ||
5588 type.
id()==ID_fixedbv ||
5589 type.
id()==ID_unsignedbv ||
5590 type.
id()==ID_signedbv ||
5591 type.
id()==ID_c_bool)
5596 else if(type.
id()==ID_c_enum)
5603 else if(type.
id()==ID_c_enum_tag)
5607 else if(type.
id()==ID_floatbv)
5612 out <<
"(_ FloatingPoint "
5613 << floatbv_type.
get_e() <<
" "
5614 << floatbv_type.
get_f() + 1 <<
")";
5619 else if(type.
id()==ID_rational ||
5622 else if(type.
id()==ID_integer)
5624 else if(type.
id()==ID_complex)
5634 out <<
"(_ BitVec " << width <<
")";
5637 else if(type.
id()==ID_c_bit_field)
5641 else if(type.
id() == ID_state)
5645 else if(type.
id() == ID_range)
5648 mp_integer size = range_type.get_to() - range_type.get_from() + 1;
5661 std::set<irep_idt> recstack;
5667 std::set<irep_idt> &recstack)
5669 if(type.
id()==ID_array)
5675 else if(type.
id()==ID_complex)
5682 const std::string smt_typename =
5686 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
5687 <<
"(((mk-" << smt_typename;
5689 out <<
" (" << smt_typename <<
".imag ";
5693 out <<
" (" << smt_typename <<
".real ";
5700 else if(type.
id() == ID_struct)
5703 bool need_decl=
false;
5707 const std::string smt_typename =
5722 const std::string &smt_typename =
datatype_map.at(type);
5733 out <<
"(declare-datatypes ((" << smt_typename <<
" 0)) "
5734 <<
"(((mk-" << smt_typename <<
" ";
5741 out <<
"(" << smt_typename <<
"." <<
component.get_name()
5747 out <<
"))))" <<
"\n";
5764 for(struct_union_typet::componentst::const_iterator
5765 it=components.begin();
5766 it!=components.end();
5773 out <<
"(define-fun update-" << smt_typename <<
"."
5775 <<
"((s " << smt_typename <<
") "
5778 out <<
")) " << smt_typename <<
" "
5779 <<
"(mk-" << smt_typename
5782 for(struct_union_typet::componentst::const_iterator
5783 it2=components.begin();
5784 it2!=components.end();
5791 out <<
"(" << smt_typename <<
"."
5792 << it2->get_name() <<
" s) ";
5796 out <<
"))" <<
"\n";
5802 else if(type.
id() == ID_union)
5810 else if(type.
id()==ID_code)
5814 for(
const auto ¶m : parameters)
5819 else if(type.
id()==ID_pointer)
5823 else if(type.
id() == ID_struct_tag)
5826 const irep_idt &
id = struct_tag.get_identifier();
5828 if(recstack.find(
id) == recstack.end())
5831 recstack.insert(
id);
5836 else if(type.
id() == ID_union_tag)
5839 const irep_idt &
id = union_tag.get_identifier();
5841 if(recstack.find(
id) == recstack.end())
5843 recstack.insert(
id);
5847 else if(type.
id() == ID_state)
5852 out <<
"(declare-sort state 0)\n";
5855 else if(type.
id() == ID_mathematical_function)
5857 const auto &mathematical_function_type =
5859 for(
auto &d_type : mathematical_function_type.domain())
API to expression classes for bitvectors.
const update_bit_exprt & to_update_bit_expr(const exprt &expr)
Cast an exprt to an update_bit_exprt.
bool can_cast_expr< mult_overflow_exprt >(const exprt &base)
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
bool can_cast_expr< minus_overflow_exprt >(const exprt &base)
const extractbit_exprt & to_extractbit_expr(const exprt &expr)
Cast an exprt to an extractbit_exprt.
const extractbits_exprt & to_extractbits_expr(const exprt &expr)
Cast an exprt to an extractbits_exprt.
bool can_cast_expr< overflow_result_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.
const bitreverse_exprt & to_bitreverse_expr(const exprt &expr)
Cast an exprt to a bitreverse_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.
bool can_cast_expr< plus_overflow_exprt >(const exprt &base)
const bitnot_exprt & to_bitnot_expr(const exprt &expr)
Cast an exprt to a bitnot_exprt.
const replication_exprt & to_replication_expr(const exprt &expr)
Cast an exprt to a replication_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 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 floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_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.
exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
Rewrite a byte extract expression to more fundamental operations.
exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
Rewrite a byte update expression to more fundamental operations.
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
typet c_bit_field_replacement_type(const c_bit_field_typet &src, const namespacet &ns)
pointer_typet pointer_type(const typet &subtype)
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
const c_bool_typet & to_c_bool_type(const typet &type)
Cast a typet to a c_bool_typet.
Operator to return the address of an object.
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 typet & element_type() const
The type of the elements of the array.
const exprt & size() const
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
const membert & get_member(const struct_typet &type, const irep_idt &member) const
The byte swap expression.
std::size_t get_bits_per_byte() const
std::vector< parametert > parameterst
const parameterst & parameters() const
struct configt::bv_encodingt bv_encoding
A constant literal expression.
const irep_idt & get_value() const
void set_value(const irep_idt &value)
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.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
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.
bool is_true() const
Return whether the expression is a constant representing true.
depth_iteratort depth_end()
bool is_boolean() const
Return whether the expression represents a Boolean.
depth_iteratort depth_begin()
bool is_false() const
Return whether the expression is a constant representing false.
bool is_zero() const
Return whether the expression is a constant representing 0.
typet & type()
Return the type of the expression.
bool is_constant() const
Return whether the expression is a constant.
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
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
constant_exprt to_expr() const
static ieee_floatt plus_infinity(const ieee_float_spect &_spec)
static ieee_floatt NaN(const ieee_float_spect &_spec)
static ieee_floatt minus_infinity(const ieee_float_spect &_spec)
void build(const mp_integer &exp, const mp_integer &frac)
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.
exprt & where()
convenience accessor for binding().where()
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
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.
const mp_integer & get_invalid_object() const
numberingt< exprt, irep_hash > objects
exprt pointer_expr(const pointert &pointer, const pointer_typet &type) const
Convert an (object,offset) pair to an expression.
void get_dynamic_objects(std::vector< mp_integer > &objects) const
mp_integer add_object(const exprt &expr)
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.
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 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)
std::size_t no_boolean_variables
smt2_identifierst smt2_identifiers
void convert_floatbv(const exprt &expr)
literalt convert(const exprt &expr)
const smt2_symbolt & to_smt2_symbol(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 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
const componentst & components() 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)
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 isnormal_exprt & to_isnormal_expr(const exprt &expr)
Cast an exprt to a isnormal_exprt.
const isnan_exprt & to_isnan_expr(const exprt &expr)
Cast an exprt to a isnan_exprt.
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
const isfinite_exprt & to_isfinite_expr(const exprt &expr)
Cast an exprt to a isfinite_exprt.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
const isinf_exprt & to_isinf_expr(const exprt &expr)
Cast an exprt to a isinf_exprt.
const std::string & id2string(const irep_idt &d)
static std::string binary(const constant_exprt &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.
double pow(double x, double y)
API to expression classes for 'mathematical' expressions.
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_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 pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_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 element_address_exprt & to_element_address_expr(const exprt &expr)
Cast an exprt to an element_address_exprt.
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)
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.
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)
void solver(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
#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 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 notequal_exprt & to_notequal_expr(const exprt &expr)
Cast an exprt to an notequal_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const update_exprt & to_update_expr(const exprt &expr)
Cast an exprt to an update_exprt.
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
const unary_plus_exprt & to_unary_plus_expr(const exprt &expr)
Cast an exprt to a unary_plus_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const mod_exprt & to_mod_expr(const exprt &expr)
Cast an exprt to a mod_exprt.
const array_comprehension_exprt & to_array_comprehension_expr(const exprt &expr)
Cast an exprt to a array_comprehension_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
const named_term_exprt & to_named_term_expr(const exprt &expr)
Cast an exprt to a named_term_exprt.
const div_exprt & to_div_expr(const exprt &expr)
Cast an exprt to a div_exprt.
const minus_exprt & to_minus_expr(const exprt &expr)
Cast an exprt to a minus_exprt.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
const array_of_exprt & to_array_of_expr(const exprt &expr)
Cast an exprt to an array_of_exprt.
const euclidean_mod_exprt & to_euclidean_mod_expr(const exprt &expr)
Cast an exprt to a euclidean_mod_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const nondet_symbol_exprt & to_nondet_symbol_expr(const exprt &expr)
Cast an exprt to a nondet_symbol_exprt.
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
const sign_exprt & to_sign_expr(const exprt &expr)
Cast an exprt to a sign_exprt.
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const mult_exprt & to_mult_expr(const exprt &expr)
Cast an exprt to a mult_exprt.
const range_typet & to_range_type(const typet &type)
Cast a typet to a range_typet.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::size_t unsafe_string2size_t(const std::string &str, int base)
const string_constantt & to_string_constant(const exprt &expr)
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.