CBMC
boolbv_let.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "boolbv.h"
10 
11 #include <util/range.h>
12 #include <util/replace_symbol.h>
13 #include <util/std_expr.h>
14 
16 {
17  const auto &variables = expr.variables();
18  const auto &values = expr.values();
19 
21  expr.type() == expr.where().type(),
22  "let must have the type of the 'where' operand");
23 
24  // Check the types.
25  for(auto &binding : make_range(variables).zip(values))
26  {
28  binding.first.type() == binding.second.type(),
29  "let value must have the type of the let symbol");
30  }
31 
32  // A let expression can bind multiple symbols simultaneously.
33  // This is a 'concurrent' binding, i.e., the symbols are not yet
34  // visible when evaluating the values. SMT-LIB also has this
35  // semantics. We therefore first convert all values,
36  // and only then assign them.
37  std::vector<bvt> converted_values;
38  converted_values.reserve(variables.size());
39 
40  for(auto &value : values)
41  {
42  if(!bv_width.get_width_opt(value.type()).has_value())
43  converted_values.emplace_back();
44  else
45  converted_values.push_back(convert_bv(value));
46  }
47 
48  // get fresh bound symbols
49  auto fresh_variables = fresh_binding(expr.binding());
50 
51  // Now assign
52  for(const auto &binding : make_range(fresh_variables).zip(converted_values))
53  {
54  bool is_boolean = binding.first.type().id() == ID_bool;
55  const auto &identifier = binding.first.get_identifier();
56 
57  // make the symbol visible
58  if(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  // rename the bound symbols in 'where'
74  exprt where_renamed = expr.where();
75  replace_symbol(where_renamed);
76 
77  // recursive call
78  bvt result_bv = convert_bv(where_renamed);
79 
80  // the mapping can now be deleted
81  for(const auto &entry : fresh_variables)
82  {
83  const auto &type = entry.type();
84  if(type.id() == ID_bool)
85  symbols.erase(entry.get_identifier());
86  else
87  map.erase_literals(entry.get_identifier(), type);
88  }
89 
90  return result_bv;
91 }
boolbv_mapt::erase_literals
void erase_literals(const irep_idt &identifier, const typet &type)
Definition: boolbv_map.cpp:118
boolbvt::bv_width
boolbv_widtht bv_width
Definition: boolbv.h:116
boolbvt::map
boolbv_mapt map
Definition: boolbv.h:123
bvt
std::vector< literalt > bvt
Definition: literal.h:201
boolbvt::fresh_binding
binding_exprt::variablest fresh_binding(const binding_exprt &)
create new, unique variables for the given binding
Definition: boolbv.cpp:537
replace_symbol.h
prop_conv_solvert::symbols
symbolst symbols
Definition: prop_conv_solver.h:121
exprt
Base class for all expressions.
Definition: expr.h:55
boolbv_widtht::get_width_opt
virtual optionalt< std::size_t > get_width_opt(const typet &type) const
Definition: boolbv_width.h:31
let_exprt::variables
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
Definition: std_expr.h:3223
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
boolbvt::convert_bv
virtual const bvt & convert_bv(const exprt &expr, const optionalt< std::size_t > expected_width={})
Convert expression to vector of literalts, using an internal cache to speed up conversion if availabl...
Definition: boolbv.cpp:39
range.h
replace_symbolt::insert
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...
Definition: replace_symbol.cpp:24
boolbvt::convert_let
virtual bvt convert_let(const let_exprt &)
Definition: boolbv_let.cpp:15
boolbv.h
let_exprt::values
operandst & values()
Definition: std_expr.h:3212
let_exprt::where
exprt & where()
convenience accessor for binding().where()
Definition: std_expr.h:3235
std_expr.h
let_exprt::binding
binding_exprt & binding()
Definition: std_expr.h:3170
make_range
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition: range.h:524
let_exprt
A let expression.
Definition: std_expr.h:3141
boolbv_mapt::set_literals
void set_literals(const irep_idt &identifier, const typet &type, const bvt &literals)
Definition: boolbv_map.cpp:75
replace_symbolt
Replace a symbol expression by a given expression.
Definition: replace_symbol.h:27