CBMC
Loading...
Searching...
No Matches
boolbv_let.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
10#include <util/range.h>
11#include <util/replace_symbol.h>
12#include <util/std_expr.h>
13
14#include "boolbv.h"
15
17{
18 const auto &variables = expr.variables();
19 const auto &values = expr.values();
20
22 expr.type() == expr.where().type(),
23 "let must have the type of the 'where' operand");
24
25 // Check the types.
26 for(auto &binding : make_range(variables).zip(values))
27 {
29 binding.first.type() == binding.second.type(),
30 "let value must have the type of the let symbol");
31 }
32
33 // A let expression can bind multiple symbols simultaneously.
34 // This is a 'concurrent' binding, i.e., the symbols are not yet
35 // visible when evaluating the values. SMT-LIB also has this
36 // semantics. We therefore first convert all values,
37 // and only then assign them.
38 std::vector<bvt> converted_values;
39 converted_values.reserve(variables.size());
40
41 for(auto &value : values)
42 {
43 if(!bv_width.get_width_opt(value.type()).has_value())
44 converted_values.emplace_back();
45 else
46 converted_values.push_back(convert_bv(value));
47 }
48
49 // get fresh bound symbols
51
52 // Now assign
53 for(const auto &binding : make_range(fresh_variables).zip(converted_values))
54 {
55 const auto &identifier = binding.first.identifier();
56
57 // make the symbol visible
58 if(binding.first.is_boolean())
59 {
60 DATA_INVARIANT(binding.second.size() == 1, "boolean values have one bit");
61 symbols[identifier] = binding.second[0];
62 }
63 else
64 map.set_literals(identifier, binding.first.type(), binding.second);
65 }
66
67 // for renaming the bound symbols
68 replace_symbolt replace_symbol;
69
70 for(const auto &pair : make_range(variables).zip(fresh_variables))
71 replace_symbol.insert(pair.first, pair.second);
72
73 // Connect fresh let-bound symbols to their values in the array theory.
74 for(const auto &pair : make_range(fresh_variables).zip(values))
75 {
76 if(
77 pair.first.type().id() == ID_array &&
79 {
82 : pair.second;
83 record_array_let_binding(pair.first, pair.second);
84 }
85 }
86
87 // rename the bound symbols in 'where'
88 exprt where_renamed = expr.where();
89 replace_symbol(where_renamed);
90
91 // recursive call
92 bvt result_bv = convert_bv(where_renamed);
93
94 // the mapping can now be deleted
95 for(const auto &entry : fresh_variables)
96 {
97 const auto &type = entry.type();
98 if(type.id() == ID_bool)
99 symbols.erase(entry.identifier());
100 else
101 map.erase_literals(entry.identifier(), type);
102 }
103
104 return result_bv;
105}
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_operators(const exprt &src, const namespacet &ns)
Rewrite an expression possibly containing byte-extract or -update expressions to more fundamental ope...
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:566
const namespacet & ns
Definition arrays.h:63
void record_array_let_binding(const symbol_exprt &symbol, const exprt &value)
Record that symbol is equal to value for the purposes of the array theory.
Definition arrays.cpp:83
void erase_literals(const irep_idt &identifier, const typet &type)
void set_literals(const irep_idt &identifier, const typet &type, const bvt &literals)
virtual std::optional< std::size_t > get_width_opt(const typet &type) const
virtual const bvt & convert_bv(const exprt &expr, const std::optional< std::size_t > expected_width={})
Convert expression to vector of literalts, using an internal cache to speed up conversion if availabl...
Definition boolbv.cpp:40
virtual bvt convert_let(const let_exprt &)
binding_exprt::variablest fresh_binding(const binding_exprt &)
create new, unique variables for the given binding
Definition boolbv.cpp:561
bool is_unbounded_array(const typet &type) const override
Definition boolbv.cpp:542
boolbv_widtht bv_width
Definition boolbv.h:120
boolbv_mapt map
Definition boolbv.h:127
Base class for all expressions.
Definition expr.h:57
typet & type()
Return the type of the expression.
Definition expr.h:85
A let expression.
Definition std_expr.h:3259
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
Definition std_expr.h:3340
operandst & values()
Definition std_expr.h:3329
exprt & where()
convenience accessor for binding().where()
Definition std_expr.h:3352
binding_exprt & binding()
Definition std_expr.h:3287
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...
std::vector< literalt > bvt
Definition literal.h:201
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition range.h:522
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
API to expression classes.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888