51template <
typename factoryt>
55 const factoryt &factory)
60 return converted.at(expr);
62 return std::accumulate(
73template <
typename target_typet>
78 return can_cast_type<target_typet>(operand.type());
159static std::function<std::function<smt_termt(smt_termt)>(std::size_t)>
181 "Generation of SMT formula for type cast to fixed-point bitvector "
188 "Generation of SMT formula for type cast to floating-point bitvector "
230 "Generation of SMT formula for type cast to bit vector from type: " +
237 "Generation of SMT formula for type cast to bit vector from type: " +
249 from_term.
get_sort().accept(converter);
251 return *converter.result;
258 const auto &from_term = converted.at(cast.
op());
268 "Generation of SMT formula for type cast expression: " + cast.
pretty());
276 "Generation of SMT formula for floating point type cast expression: " +
285 "Generation of SMT formula for struct construction expression: " +
294 "Generation of SMT formula for union construction expression: " +
325 "Conversion of array SMT literal " +
array_sort.pretty());
333 const size_t bit_width =
337 const auto address = 0;
351 sort.accept(converter);
365 "Generation of SMT formula for concatenation expression: " +
381 "Generation of SMT formula for bitwise and expression: " +
398 "Generation of SMT formula for bitwise or expression: " +
415 "Generation of SMT formula for bitwise xor expression: " +
431 "Generation of SMT formula for bitnot_exprt: " + bitwise_not.
pretty());
446 "Generation of SMT formula for unary minus expression: " +
456 "Generation of SMT formula for unary plus expression: " +
465 "Generation of SMT formula for \"is negative\" expression: " +
508 converted.at(implies.
op0()), converted.at(implies.
op1()));
523 converted.at(equal.
op0()), converted.at(equal.
op1()));
531 converted.at(not_equal.
op0()), converted.at(not_equal.
op1()));
539 "Generation of SMT formula for floating point equality expression: " +
548 "Generation of SMT formula for floating point not equal expression: " +
552template <
typename unsigned_factory_typet,
typename signed_factory_typet>
577 "pointer comparison requires that both operand types are pointers.");
589 "Generation of SMT formula for relational expression: " +
606 const auto greater_than_or_equal =
610 *greater_than_or_equal,
624 const auto less_than_or_equal =
643 return can_cast_type<integer_bitvector_typet>(operand.type());
653 "We are only handling a binary version of plus when it has a pointer "
674 "An addition expression with both operands being pointers when they are "
675 "not dereferenced is malformed");
683 converted.at(pointer),
689 "Generation of SMT formula for plus expression: " + plus.
pretty());
714 converted.at(minus.
lhs()), converted.at(minus.
rhs()));
722 "only pointers of the same object type can be subtracted.");
725 converted.at(minus.
lhs()), converted.at(minus.
rhs())),
734 "minus expressions of pointer and integer expect lhs to be the pointer");
738 converted.at(minus.
lhs()),
745 "Generation of SMT formula for minus expression: " + minus.
pretty());
778 "Generation of SMT formula for divide expression: " + divide.
pretty());
789 "Generation of SMT formula for floating point operation expression: " +
822 "Generation of SMT formula for remainder (modulus) expression: " +
832 "Generation of SMT formula for euclidean modulo expression: " +
844 return can_cast_type<integer_bitvector_typet>(operand.type());
853 "Generation of SMT formula for multiply expression: " +
872 type,
"Result of the address_of operator should have pointer type.");
874 const auto object = object_map.find(base);
876 object != object_map.end(),
877 "Objects should be tracked before converting their address to SMT terms");
878 const std::size_t
object_id =
object->second.unique_id;
880 const std::size_t
max_objects = std::size_t(1) << object_bits;
884 "too many addressed objects: maximum number of objects is set to 2^n=" +
885 std::to_string(
max_objects) +
" (with n=" + std::to_string(object_bits) +
887 "use the `--object-bits n` option to increase the maximum number"};
892 type->get_width() > object_bits,
893 "Pointer should be wider than object_bits in order to allow for offset "
895 const size_t offset_bits = type->get_width() - object_bits;
904 "Generation of SMT formula for address of expression: " +
923 "Generation of SMT formula for array comprehension expression: " +
936template <
typename factoryt,
typename shiftt>
938 const factoryt &factory,
950 "Shift expressions are expected to have bit vector operands.");
952 shift.type() == shift.op0().type(),
953 "Shift expression type must be equals to first operand type.");
965 const auto result = factory(
1002 "Generation of SMT formula for shift expression: " + shift.
pretty());
1010 for(
auto it = ++
with.operands().begin(); it !=
with.operands().end(); it += 2)
1028 "Generation of SMT formula for with expression: " +
with.pretty());
1036 "Generation of SMT formula for update expression: " + update.
pretty());
1044 "Generation of SMT formula for member extraction expression: " +
1056 pointer_sort,
"Pointers should be encoded as bit vector sorted terms.");
1057 const std::size_t pointer_width =
pointer_sort->bit_width();
1076 width >= object_bits,
1077 "Width should be at least as big as the number of object bits.");
1080 width - 1, width - object_bits)(converted.at(pointer_expr));
1095 "Generation of SMT formula for string constant expression: " +
1104 "Generation of SMT formula for extract bit expression: " +
1122 "Generation of SMT formula for extract bits expression: " +
1131 "Generation of SMT formula for bit vector replication expression: " +
1140 "Generation of SMT formula for byte extract expression: " +
1149 "Generation of SMT formula for byte update expression: " +
1158 "Generation of SMT formula for absolute value of expression: " +
1167 "Generation of SMT formula for is not a number expression: " +
1176 "Generation of SMT formula for is finite expression: " +
1185 "Generation of SMT formula for is infinite expression: " +
1194 "Generation of SMT formula for is infinite expression: " +
1206 "Most significant bit can only be extracted from bit vector terms.");
1239 "Generation of SMT formula for plus overflow expression: " +
1271 "Generation of SMT formula for minus overflow expression: " +
1299 const std::size_t width =
signed_type->get_width();
1314 "Generation of SMT formula for multiply overflow expression: " +
1324 INVARIANT(type,
"Pointer object should have a bitvector-based type.");
1326 const std::size_t width = type->get_width();
1329 width >= object_bits,
1330 "Width should be at least as big as the number of object bits.");
1331 const std::size_t
ext = width - object_bits;
1347 INVARIANT(type,
"Pointer offset should have a bitvector-based type.");
1349 const std::size_t width = type->get_width();
1367 "Generation of SMT formula for shift left overflow expression: " +
1386 "Generation of SMT formula for literal expression: " +
literal.pretty());
1394 "Generation of SMT formula for for all expression: " +
for_all.pretty());
1402 "Generation of SMT formula for exists expression: " +
exists.pretty());
1410 "Generation of SMT formula for vector expression: " + vector.
pretty());
1421 pointer_sort,
"Pointers should be encoded as bit vector sorted terms.");
1422 const std::size_t pointer_width =
pointer_sort->bit_width();
1433 "Generation of SMT formula for let expression: " +
let.pretty());
1441 "Generation of SMT formula for byte swap expression: " +
1450 "Generation of SMT formula for population count expression: " +
1459 "Generation of SMT formula for count leading zeros expression: " +
1468 "Generation of SMT formula for count trailing zeros expression: " +
1477 "zero_extend expression should have been lowered by the decision "
1478 "procedure before conversion to smt terms");
1486 "prophecy_r_or_w_ok expression should have been lowered by the decision "
1487 "procedure before conversion to smt terms");
1495 "prophecy_pointer_in_range expression should have been lowered by the "
1496 "decision procedure before conversion to smt terms");
1704 const auto is_dynamic_object =
1812 "constraint_select_one is not expected in smt conversion: " +
1852 "Generation of SMT formula for unknown kind of expression: " +
1856#ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1857template <
typename functiont>
1871template <
typename functiont>
1902 std::function<
bool(
const exprt &)> filter,
1914 std::stack<stack_entryt> stack;
1916 stack.emplace(&
_expr);
1918 while(!stack.empty())
1920 auto &top = stack.top();
1921 if(top.operands_pushed)
1929 top.operands_pushed =
true;
1931 for(
auto &op : top.e->operands())
1944#ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1948 "Conversion of expr to smt should be non-recursive. "
1949 "Re-entrance found in conversion of " +
1958 [](
const exprt &expr) {
1968 [&](
const exprt &expr) {
API to expression classes for bitvectors.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
bool can_cast_type< integer_bitvector_typet >(const typet &type)
Check whether a reference to a typet is an integer_bitvector_typet.
bool can_cast_type< unsignedbv_typet >(const typet &type)
Check whether a reference to a typet is a unsignedbv_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
Expression classes for byte-level operators.
pointer_typet pointer_type(const typet &subtype)
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Expression to define a mapping from an argument (index) to elements.
Array constructor from list of elements.
Array constructor from single element.
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.
A base class for relations, i.e., binary predicates whose two operands have the same type.
Bit-wise negation of bit-vectors.
Base class of fixed-width bit-vector types.
std::size_t get_width() const
The byte swap expression.
Expression corresponding to op() where the bytes starting at position offset (given in number of byte...
Concatenation of bit-vector operands.
struct configt::bv_encodingt bv_encoding
A constant literal expression.
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
The count trailing zeros (counting the number of zero bits starting from the least-significant bit) e...
Boute's Euclidean definition of Modulo – to match SMT-LIB2.
Base class for all expressions.
void visit_pre(std::function< void(exprt &)>)
typet & type()
Return the type of the expression.
Semantic type conversion from/to floating-point formats.
IEEE-floating-point equality.
IEEE floating-point disequality.
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
The trinary if-then-else operator.
Unbounded, signed integers (mathematical integers, not bitvectors)
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const irep_idt & id() const
Evaluates to true if the operand is a pointer to a dynamic object.
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.
Extract member of struct or union.
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Binary multiplication Associativity is not specified.
A base class for multi-ary expressions Associativity is not specified.
Expression to hold a nondeterministic choice.
Expression for finding the size (in bytes) of the object a pointer points to.
The plus expression Associativity is not specified.
A numerical identifier for the object a pointer points to.
The offset (in bytes) of a pointer relative to the object.
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.
The popcount (counting the number of bits set to 1) expression.
pointer_in_range (see pointer_in_range_exprt) with prophecy expressions to encode whether a pointer r...
A base class for a predicate that indicates that an address range is ok to read or write or both.
A base class for shift and rotate operators.
Sign of an expression Predicate is true if _op is negative, false otherwise.
static const smt_function_application_termt::factoryt< storet > store
static const smt_function_application_termt::factoryt< selectt > select
static const smt_function_application_termt::factoryt< ort > make_or
static const smt_function_application_termt::factoryt< unsigned_less_than_or_equalt > unsigned_less_than_or_equal
static const smt_function_application_termt::factoryt< signed_less_than_or_equalt > signed_less_than_or_equal
static const smt_function_application_termt::factoryt< addt > add
static const smt_function_application_termt::factoryt< arithmetic_shift_rightt > arithmetic_shift_right
static const smt_function_application_termt::factoryt< signed_greater_than_or_equalt > signed_greater_than_or_equal
static const smt_function_application_termt::factoryt< unsigned_greater_thant > unsigned_greater_than
static const smt_function_application_termt::factoryt< unsigned_remaindert > unsigned_remainder
static const smt_function_application_termt::factoryt< unsigned_greater_than_or_equalt > unsigned_greater_than_or_equal
static const smt_function_application_termt::factoryt< xort > make_xor
static const smt_function_application_termt::factoryt< nott > make_not
static const smt_function_application_termt::factoryt< shift_leftt > shift_left
static const smt_function_application_termt::factoryt< multiplyt > multiply
static smt_function_application_termt::factoryt< sign_extendt > sign_extend(std::size_t i)
static const smt_function_application_termt::factoryt< signed_less_thant > signed_less_than
static smt_function_application_termt::factoryt< zero_extendt > zero_extend(std::size_t i)
static smt_function_application_termt::factoryt< extractt > extract(std::size_t i, std::size_t j)
Makes a factory for extract function applications.
static const smt_function_application_termt::factoryt< signed_greater_thant > signed_greater_than
static const smt_function_application_termt::factoryt< logical_shift_rightt > logical_shift_right
static const smt_function_application_termt::factoryt< negatet > negate
Arithmetic negation in two's complement.
static const smt_function_application_termt::factoryt< concatt > concat
static const smt_function_application_termt::factoryt< unsigned_dividet > unsigned_divide
static const smt_function_application_termt::factoryt< unsigned_less_thant > unsigned_less_than
static const smt_function_application_termt::factoryt< signed_dividet > signed_divide
static const smt_function_application_termt::factoryt< signed_remaindert > signed_remainder
static const smt_function_application_termt::factoryt< subtractt > subtract
static const smt_function_application_termt::factoryt< andt > make_and
static const smt_function_application_termt::factoryt< distinctt > distinct
Makes applications of the function which returns true iff its two arguments are not identical.
static const smt_function_application_termt::factoryt< if_then_elset > if_then_else
static const smt_function_application_termt::factoryt< impliest > implies
static const smt_function_application_termt::factoryt< ort > make_or
static const smt_function_application_termt::factoryt< equalt > equal
static const smt_function_application_termt::factoryt< andt > make_and
static const smt_function_application_termt::factoryt< xort > make_xor
static const smt_function_application_termt::factoryt< nott > make_not
Stores identifiers in unescaped and unquoted form.
const smt_sortt & get_sort() const
Struct constructor from list of elements.
Expression to hold a symbol (variable)
const irep_idt & get_identifier() const
Semantic type conversion.
The type of an expression, extends irept.
The unary minus expression.
The unary plus expression.
Union constructor from single element.
Operator to update elements in structs and arrays.
Vector constructor from list of elements.
Operator to update elements in structs and arrays.
zero extension The operand is converted to the given type by either a) truncating if the new type is ...
void filtered_visit_post(const exprt &_expr, std::function< bool(const exprt &)> filter, std::function< void(const exprt &)> visitor)
Post order traversal where the children of a node are only visited if applying the filter function to...
exprt lower_address_of_array_index(exprt expr)
Lower the address_of(array[idx]) sub expressions in expr to idx + address_of(array),...
static smt_termt convert_bit_vector_cast(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
static std::optional< smt_termt > try_relational_conversion(const exprt &expr, const sub_expression_mapt &converted)
static smt_termt most_significant_bit_is_set(const smt_termt &input)
Constructs a term which is true if the most significant bit of input is set.
static smt_termt convert_array_update_to_smt(const with_exprt &with, const sub_expression_mapt &converted)
static smt_termt make_bitvector_resize_cast(const smt_termt &from_term, const bitvector_typet &from_type, const bitvector_typet &to_type)
static std::function< std::function< smt_termt(smt_termt)>(std::size_t)> extension_for_type(const typet &type)
static smt_termt convert_multiary_operator_to_terms(const multi_ary_exprt &expr, const sub_expression_mapt &converted, const factoryt &factory)
Converts operator expressions with 2 or more operands to terms expressed as binary operator applicati...
std::unordered_map< exprt, smt_termt, irep_hash > sub_expression_mapt
Post order visitation is used in order to construct the the smt terms bottom upwards without using re...
static smt_termt make_not_zero(const smt_termt &input, const typet &source_type)
Makes a term which is true if input is not 0 / false.
static smt_termt convert_relational_to_smt(const binary_relation_exprt &binary_relation, const unsigned_factory_typet &unsigned_factory, const signed_factory_typet &signed_factory, const sub_expression_mapt &converted)
static smt_termt dispatch_expr_to_smt_conversion(const exprt &expr, const sub_expression_mapt &converted, const smt_object_mapt &object_map, const type_size_mapt &pointer_sizes, const smt_object_sizet::make_applicationt &call_object_size, const smt_is_dynamic_objectt::make_applicationt &apply_is_dynamic_object)
static smt_termt convert_to_smt_shift(const factoryt &factory, const shiftt &shift, const sub_expression_mapt &converted)
static smt_sortt convert_type_to_smt_sort(const bool_typet &type)
static smt_termt convert_c_bool_cast(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
Returns a cast to C bool expressed in smt terms.
at_scope_exitt< functiont > at_scope_exit(functiont exit_function)
static bool operands_are_of_type(const exprt &expr)
Ensures that all operands of the argument expression have related types.
static smt_termt convert_expr_to_smt(const symbol_exprt &symbol_expr)
Templated functions to cast to specific exprt-derived classes.
API to expression classes for floating-point arithmetic.
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
API to expression classes for 'mathematical' expressions.
mini_bddt exists(const mini_bddt &u, const unsigned var)
mp_integer bitwise_xor(const mp_integer &a, const mp_integer &b)
bitwise 'xor' of two nonnegative integers
exprt make_invalid_pointer_expr()
Create the invalid pointer constant.
exprt find_object_base_expression(const address_of_exprt &address_of)
The model of addresses we use consists of a unique object identifier and an offset.
std::unordered_map< exprt, decision_procedure_objectt, irep_hash > smt_object_mapt
Mapping from an object's base expression to the set of information about it which we track.
API to expression classes for Pointers.
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
exprt pointer_offset(const exprt &pointer)
exprt object_size(const exprt &pointer)
exprt pointer_object(const exprt &p)
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)
#define UNIMPLEMENTED_FEATURE(FEATURE)
#define UNREACHABLE
This should be used to mark dead code.
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
#define POSTCONDITION(CONDITION)
#define UNREACHABLE_BECAUSE(REASON)
API to expression classes.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
bool can_cast_type< code_typet >(const typet &type)
Check whether a reference to a typet is a code_typet.
binary_relation_exprt less_than(exprt lhs, exprt rhs)
binary_relation_exprt greater_than(exprt lhs, exprt rhs)
at_scope_exitt(functiont exit_function)
void visit(const smt_array_sortt &) override
const smt_termt & from_term
sort_based_cast_to_bit_vector_convertert(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
void visit(const smt_bool_sortt &) override
const bitvector_typet & to_type
void visit(const smt_bit_vector_sortt &) override
std::optional< smt_termt > result
void visit(const smt_array_sortt &array_sort) override
void visit(const smt_bit_vector_sortt &bit_vector_sort) override
std::optional< smt_termt > result
const constant_exprt & member_input
void visit(const smt_bool_sortt &) override
sort_based_literal_convertert(const constant_exprt &input)
std::unordered_map< typet, smt_termt, irep_hash > type_size_mapt