32 #include <unordered_set>
268 target << constraint;
298 out <<
';' <<
' ' << text <<
'\n';
327 std::unordered_set<symbol_exprt, irep_hash> &result)
329 if(src.
id() == ID_object_address)
347 const goto_functionst::function_mapt::const_iterator,
372 const std::unordered_set<symbol_exprt, irep_hash> &)
const;
376 std::vector<symbol_exprt> &nondet_symbols)
const;
404 const std::string &suffix)
const
418 auto incoming_it =
incoming.find(loc);
422 std::vector<symbol_exprt> symbols;
423 symbols.reserve(incoming_it->second.size());
425 for(
auto &loc_in : incoming_it->second)
431 loc_in->is_goto() && !loc_in->condition().is_true() &&
432 loc != std::next(loc_in))
459 const exprt &what)
const
467 std::vector<symbol_exprt> &nondet_symbols)
const
469 if(what.
id() == ID_side_effect)
472 auto statement = side_effect.get_statement();
473 if(statement == ID_nondet)
477 auto symbol =
symbol_exprt(identifier, side_effect.type());
478 nondet_symbols.push_back(symbol);
479 return std::move(symbol);
497 const std::unordered_set<symbol_exprt, irep_hash> &bound_symbols)
const
501 if(what.
id() == ID_symbol)
505 if(bound_symbols.find(symbol_expr) == bound_symbols.end())
513 what.
id() == ID_dereference || what.
id() == ID_member ||
514 what.
id() == ID_index)
518 else if(what.
id() == ID_forall || what.
id() == ID_exists)
521 auto new_bound_symbols = bound_symbols;
523 for(
const auto &v : new_quantifier_expr.variables())
524 new_bound_symbols.insert(v);
527 loc, state, new_quantifier_expr.where(), new_bound_symbols);
529 return std::move(new_quantifier_expr);
531 else if(what.
id() == ID_address_of)
536 else if(what.
id() == ID_r_ok || what.
id() == ID_w_ok || what.
id() == ID_rw_ok)
582 std::move(condition)),
589 if(expr.
id() == ID_symbol)
591 if(expr.
type().
id() == ID_array)
600 else if(expr.
id() == ID_member)
603 auto compound_address =
address_rec(loc, state, std::move(compound));
606 if(expr.
type().
id() == ID_array)
610 std::move(compound_address),
620 else if(expr.
id() == ID_index)
623 auto index_evaluated =
625 auto array_address =
address_rec(loc, state, std::move(array));
627 std::move(array_address), std::move(index_evaluated));
629 else if(expr.
id() == ID_dereference)
631 else if(expr.
id() == ID_string_constant)
637 else if(expr.
id() == ID_array)
643 else if(expr.
id() == ID_union)
662 std::vector<symbol_exprt> nondet_symbols;
668 binding.insert(binding.end(), nondet_symbols.begin(), nondet_symbols.end());
685 incoming[it->get_target()].push_back(it);
690 auto next = std::next(it);
691 if(it->is_goto() && it->condition().is_true())
703 if(src.
id() == ID_not)
715 auto identifier =
function.get_identifier();
721 if(identifier ==
"malloc")
725 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[0]);
727 auto lhs_address =
address_rec(loc, state, loc->call_lhs());
729 ID_allocate, state, lhs_address, size_evaluated,
state_typet());
741 if(!f->second.body_available())
744 if(loc->call_lhs().is_not_nil())
747 loc->call_lhs().type(), loc->source_location());
760 for(std::size_t i = 0; i < type.parameters().size(); i++)
763 f->second.parameter_identifiers[i], type.parameters()[i].type()));
764 auto argument = loc->call_arguments()[i];
776 auto new_state_prefix =
778 body_state_encoding.encode(
782 function_entry_state,
787 auto exit_loc = std::prev(f->second.body.instructions.end());
801 const auto &
function = loc->call_function();
802 if(
function.
id() == ID_dereference)
806 "can't do function pointers", loc->source_location());
808 else if(
function.
id() == ID_symbol)
815 false,
"got function that's neither a symbol nor a function pointer");
820 goto_functionst::function_mapt::const_iterator f_entry,
823 const auto &goto_function = f_entry->second;
843 const std::string &state_prefix,
844 const std::string &annotation,
846 const exprt &return_lhs,
883 auto &lhs = loc->assign_lhs();
884 auto &rhs = loc->assign_rhs();
886 if(lhs.
type().
id() == ID_array)
891 else if(lhs.
type().
id() == ID_struct_tag)
897 lhs.
id() == ID_symbol &&
908 else if(loc->is_assume())
912 auto condition_evaluated =
evaluate_expr(loc, state, loc->condition());
919 else if(loc->is_goto())
922 const auto &condition = loc->condition();
931 auto condition_evaluated =
evaluate_expr(loc, state, condition);
944 else if(loc->is_assert())
953 loc->is_skip() || loc->is_assert() || loc->is_location() ||
954 loc->is_end_function() || loc->is_other())
958 else if(loc->is_decl() || loc->is_dead())
963 else if(loc->is_function_call())
967 else if(loc->is_set_return_value())
969 const auto &rhs = loc->return_value();
986 bool program_is_inlined,
989 if(program_is_inlined)
1006 for(
auto &f : sorted)
1008 const auto &symbol = ns.
lookup(f->first);
1021 std::unordered_set<symbol_exprt, irep_hash>
1024 std::unordered_set<symbol_exprt, irep_hash> result;
1026 for(
auto &expr : src)
1036 for(
auto &v : variables)
1037 domain.push_back(v.type());
1048 if(src.
id() == ID_forall)
1053 forall_expr.variables().front().type().id() == ID_state)
1057 new_variables.insert(
1058 new_variables.end(),
1062 .variables() = std::move(new_variables);
1066 else if(src.
id() == ID_function_application)
1070 function_application.arguments().size() == 1 &&
1071 function_application.arguments().front().type().id() == ID_state)
1073 function_application.function().type() =
1076 if(function_application.arguments().front().id() == ID_symbol)
1079 for(
auto &v : variables)
1080 new_arguments.push_back(v);
1081 function_application.arguments() = new_arguments;
1083 else if(function_application.arguments().front().id() == ID_tuple)
1086 function_application.arguments().front().operands().size() ==
1088 "tuple size must match");
1089 auto operands = function_application.arguments().front().operands();
1090 function_application.arguments() = operands;
1098 else if(src.
id() == ID_evaluate)
1101 if(evaluate_expr.address().id() == ID_object_address)
1107 else if(src.
id() == ID_update_state)
1110 if(update_state_expr.address().id() == ID_object_address)
1115 for(
auto &v : variables)
1118 operands.push_back(update_state_expr.new_value());
1120 operands.push_back(v);
1136 variables.push_back(v);
1138 if(variables.empty())
1146 return id2string(a.get_identifier()) < id2string(b.get_identifier());
1149 for(
auto &c : constraints)
1157 std::vector<exprt> new_constraints;
1158 new_constraints.reserve(constraints.size());
1161 for(
auto &expr : constraints)
1163 bool retain_constraint =
true;
1168 if(expr.
id() == ID_equal)
1171 if(equal_expr.lhs().id() == ID_symbol)
1181 values.
insert(symbol_expr, equal_expr.rhs());
1183 retain_constraint =
false;
1188 if(retain_constraint)
1189 new_constraints.push_back(std::move(expr));
1192 constraints = std::move(new_constraints);
1195 for(
auto &expr : constraints)
1197 if(expr.
id() == ID_equal &&
to_equal_expr(expr).lhs().
id() == ID_symbol)
void validate_expr(const shuffle_vector_exprt &value)
pointer_typet pointer_type(const typet &subtype)
const code_with_contract_typet & to_code_with_contract_type(const typet &type)
Cast a typet to a code_with_contract_typet.
allocate_exprt(exprt state, exprt address, exprt size)
const exprt & state() const
const exprt & address() const
const exprt & size() const
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
const typet & element_type() const
The type of the elements of the array.
void annotation(const std::string &text) override
ascii_encoding_targett(std::ostream &_out)
void set_to_true(source_locationt, exprt) override
A base class for binary expressions.
const exprt & op2() const =delete
std::vector< symbol_exprt > variablest
bool has_contract() const
container_encoding_targett()=default
std::vector< exprt > constraintst
source_locationt last_source_location
void set_to_true(source_locationt source_location, exprt expr) override
void set_to_true(const exprt &)
For a Boolean expression expr, add the constraint 'expr'.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Operator to return the address of an array element relative to a base address.
void set_to_true(exprt expr)
virtual void annotation(const std::string &)
virtual ~encoding_targett()=default
void set_source_location(source_locationt __source_location)
virtual void set_to_true(source_locationt, exprt)=0
source_locationt source_location
const exprt & state() const
const exprt & address() const
evaluate_exprt(exprt state, exprt address, typet type)
Base class for all expressions.
std::vector< exprt > operandst
bool is_true() const
Return whether the expression is a constant representing true.
source_locationt & add_source_location()
const source_locationt & source_location() const
typet & type()
Return the type of the expression.
Operator to return the address of a field relative to a base address.
Application of (mathematical) function.
A collection of goto functions.
function_mapt function_map
std::vector< function_mapt::const_iterator > sorted() const
returns a vector of the iterators in alphabetical order
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
symbol_tablet symbol_table
Symbol table.
goto_functionst goto_functions
GOTO functions.
instructionst instructions
The list of instructions in the goto program.
instructionst::const_iterator const_targett
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
const irep_idt & id() const
A (mathematical) lambda expression.
A type for mathematical functions (do not confuse with functions/methods in code)
std::vector< typet > domaint
const exprt & struct_op() const
irep_idt get_component_name() const
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Operator to return the address of an object.
symbol_exprt object_expr() const
Replace a symbol expression by a given expression.
void insert(const class symbol_exprt &old_expr, const exprt &new_expr)
Sets old_expr to be replaced by new_expr if we don't already have a replacement; otherwise does nothi...
bool replaces_symbol(const irep_idt &id) const
A side_effect_exprt that returns a non-deterministically chosen value.
void set_to_true(source_locationt, exprt expr) override
smt2_encoding_targett(const namespacet &ns, std::ostream &_out)
void annotation(const std::string &text) override
state_encoding_smt2_convt smt2_conv
static const source_locationt & nil()
static exprt state_lambda_expr(exprt)
exprt evaluate_expr_rec(loct, const exprt &, const exprt &, const std::unordered_set< symbol_exprt, irep_hash > &) const
void setup_incoming(const goto_functiont &)
exprt forall_states_expr(loct, exprt, exprt) const
symbol_exprt in_state_expr(loct) const
void function_call(goto_programt::const_targett, encoding_targett &)
exprt address_rec(loct, const exprt &, exprt) const
goto_programt::const_targett loct
void encode(const goto_functiont &, const irep_idt function_identifier, const std::string &state_prefix, const std::vector< irep_idt > &call_stack, const std::string &annotation, const symbol_exprt &entry_state, const exprt &return_lhs, encoding_targett &)
std::vector< symbol_exprt > incoming_symbols(loct) const
symbol_exprt out_state_expr(loct) const
state_encodingt(const goto_functionst &__goto_functions)
std::map< loct, std::vector< loct >, goto_programt::target_less_than > incomingt
exprt replace_nondet_rec(loct, const exprt &, std::vector< symbol_exprt > &nondet_symbols) const
void function_call_symbol(goto_programt::const_targett, encoding_targett &)
exprt evaluate_expr(loct, const exprt &, const exprt &) const
symbol_exprt out_state_expr(loct, bool taken) const
symbol_exprt state_expr_with_suffix(loct, const std::string &suffix) const
exprt evaluate_expr(loct, const exprt &) const
exprt assignment_constraint(loct, exprt lhs, exprt rhs) const
std::vector< symbol_exprt > incoming_symbols(loct) const
void operator()(const goto_functionst::function_mapt::const_iterator, encoding_targett &)
static exprt state_lambda_expr(exprt)
exprt forall_states_expr(loct, exprt) const
const goto_functionst & goto_functions
Expression to hold a symbol (variable)
An expression with three operands.
The Boolean constant true.
The type of an expression, extends irept.
const exprt & state() const
update_state_exprt(exprt state, exprt address, exprt new_value)
const exprt & new_value() const
const exprt & address() const
bool has_prefix(const std::string &s, const std::string &prefix)
#define forall_expr(it, expr)
#define forall_goto_program_instructions(it, program)
static typet new_state_predicate_type(const binding_exprt::variablest &variables)
void equality_propagation(std::vector< exprt > &constraints)
const update_state_exprt & to_update_state_expr(const exprt &expr)
Cast an exprt to a update_state_exprt.
static void find_variables_rec(const exprt &src, std::unordered_set< symbol_exprt, irep_hash > &result)
static symbol_exprt state_expr()
std::unordered_set< symbol_exprt, irep_hash > find_variables(const std::vector< exprt > &src)
Returns the set of program variables (as identified by object_address expressions) in the given expre...
const evaluate_exprt & to_evaluate_expr(const exprt &expr)
Cast an exprt to a evaluate_exprt.
void horn_encoding(const goto_modelt &goto_model, std::ostream &out)
exprt variable_encoding(exprt src, const binding_exprt::variablest &variables)
const allocate_exprt & to_allocate_expr(const exprt &expr)
Cast an exprt to a allocate_exprt.
void state_encoding(const goto_modelt &goto_model, bool program_is_inlined, encoding_targett &dest)
static void operator<<(encoding_targett &target, exprt constraint)
static exprt simplifying_not(exprt src)
static mathematical_function_typet state_predicate_type()
const std::string & id2string(const irep_idt &d)
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 forall_exprt & to_forall_expr(const exprt &expr)
API to expression classes for Pointers.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_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.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
side_effect_exprt & to_side_effect_expr(exprt &expr)
API to expression classes.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
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.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
A total order over targett and const_targett.