CBMC
smt2_conv.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 
10 #ifndef CPROVER_SOLVERS_SMT2_SMT2_CONV_H
11 #define CPROVER_SOLVERS_SMT2_SMT2_CONV_H
12 
13 #include <util/pointer_expr.h>
14 #include <util/std_expr.h>
15 #include <util/threeval.h>
16 
17 #include <map>
18 #include <set>
19 #include <sstream>
20 
21 #if !HASH_CODE
23 #endif
24 
27 #include <solvers/prop/literal.h>
29 
30 #include "letify.h"
31 
34 class union_typet;
35 
37 {
38 public:
39  enum class solvert
40  {
41  GENERIC,
42  BOOLECTOR,
44  CVC3,
45  CVC4,
46  MATHSAT,
47  YICES,
48  Z3
49  };
50 
51  smt2_convt(
52  const namespacet &_ns,
53  const std::string &_benchmark,
54  const std::string &_notes,
55  const std::string &_logic,
56  solvert _solver,
57  std::ostream &_out);
58 
59  ~smt2_convt() override = default;
60 
68 
69  exprt handle(const exprt &expr) override;
70  void set_to(const exprt &expr, bool value) override;
71  exprt get(const exprt &expr) const override;
72  std::string decision_procedure_text() const override;
73  void print_assignment(std::ostream &out) const override;
74 
76  void push() override;
77 
79  void push(const std::vector<exprt> &_assumptions) override;
80 
82  void pop() override;
83 
84  std::size_t get_number_of_solver_calls() const override;
85 
86  static std::string convert_identifier(const irep_idt &identifier);
87 
88 protected:
89  const namespacet &ns;
90  std::ostream &out;
91  std::string benchmark, notes, logic;
93 
94  std::vector<exprt> assumptions;
96 
97  std::size_t number_of_solver_calls = 0;
98 
99  resultt dec_solve() override;
100 
101  void write_header();
111  void write_footer();
112 
113  // tweaks for arrays
114  bool use_array_theory(const exprt &);
115  void flatten_array(const exprt &);
116 
117  // specific expressions go here
118  void convert_typecast(const typecast_exprt &expr);
120  void convert_struct(const struct_exprt &expr);
121  void convert_union(const union_exprt &expr);
122  void convert_constant(const constant_exprt &expr);
125  void convert_plus(const plus_exprt &expr);
126  void convert_minus(const minus_exprt &expr);
127  void convert_div(const div_exprt &expr);
128  void convert_mult(const mult_exprt &expr);
129  void convert_rounding_mode_FPA(const exprt &expr);
130  void convert_floatbv_plus(const ieee_float_op_exprt &expr);
131  void convert_floatbv_minus(const ieee_float_op_exprt &expr);
132  void convert_floatbv_div(const ieee_float_op_exprt &expr);
133  void convert_floatbv_mult(const ieee_float_op_exprt &expr);
134  void convert_floatbv_rem(const binary_exprt &expr);
135  void convert_mod(const mod_exprt &expr);
136  void convert_euclidean_mod(const euclidean_mod_exprt &expr);
137  void convert_index(const index_exprt &expr);
138  void convert_member(const member_exprt &expr);
139 
140  void convert_with(const with_exprt &expr);
141  void convert_update(const exprt &expr);
142 
143  void convert_expr(const exprt &);
144  void convert_type(const typet &);
145  void convert_literal(const literalt);
146 
147  literalt convert(const exprt &expr);
148  tvt l_get(literalt l) const;
149 
150  // auxiliary methods
151  exprt prepare_for_convert_expr(const exprt &expr);
152  exprt lower_byte_operators(const exprt &expr);
153  void find_symbols(const exprt &expr);
154  void find_symbols(const typet &type);
155  void find_symbols_rec(const typet &type, std::set<irep_idt> &recstack);
156 
157  // letification
159 
160  // Parsing solver responses
161  constant_exprt parse_literal(const irept &, const typet &type);
162  struct_exprt parse_struct(const irept &s, const struct_typet &type);
163  exprt parse_union(const irept &s, const union_typet &type);
169  exprt parse_array(const irept &s, const array_typet &type);
170  exprt parse_rec(const irept &s, const typet &type);
177  void walk_array_tree(
178  std::unordered_map<int64_t, exprt> *operands_map,
179  const irept &src,
180  const array_typet &type);
181 
182  // we use this to build a bit-vector encoding of the FPA theory
183  void convert_floatbv(const exprt &expr);
184  std::string type2id(const typet &) const;
185  std::string floatbv_suffix(const exprt &) const;
186  std::set<irep_idt> bvfp_set; // already converted
187 
189  {
190  public:
191  smt2_symbolt(const irep_idt &_identifier, const typet &_type)
192  : nullary_exprt(ID_smt2_symbol, _type)
193  { set(ID_identifier, _identifier); }
194 
195  const irep_idt &get_identifier() const
196  {
197  return get(ID_identifier);
198  }
199  };
200 
201  const smt2_symbolt &to_smt2_symbol(const exprt &expr)
202  {
203  assert(expr.id()==ID_smt2_symbol && !expr.has_operands());
204  return static_cast<const smt2_symbolt&>(expr);
205  }
206 
207  // flattens any non-bitvector type into a bitvector,
208  // e.g., booleans, vectors, structs, arrays but also
209  // floats when using the FPA theory.
210  // unflatten() does the opposite.
211  enum class wheret { BEGIN, END };
212  void flatten2bv(const exprt &);
213  void unflatten(wheret, const typet &, unsigned nesting=0);
214 
215  // pointers
218  const exprt &expr, const pointer_typet &result_type);
219 
220  void define_object_size(const irep_idt &id, const object_size_exprt &expr);
221 
222  // keeps track of all non-Boolean symbols and their value
223  struct identifiert
224  {
225  bool is_bound;
228 
230  {
231  type.make_nil();
232  value.make_nil();
233  }
234  };
235 
236  typedef std::unordered_map<irep_idt, identifiert> identifier_mapt;
237 
239 
240  // for modeling structs as SMT datatype when use_datatype is set
241  //
242  // it maintains a map of `struct_typet` or `struct_tag_typet`
243  // to datatype names declared in SMT
244  typedef std::map<typet, std::string> datatype_mapt;
246 
247  // for replacing various defined expressions:
248  //
249  // ID_array_of
250  // ID_array
251  // ID_string_constant
252 
253  typedef std::map<exprt, irep_idt> defined_expressionst;
258  std::unordered_map<irep_idt, bool> set_values;
259 
260  std::map<object_size_exprt, irep_idt> object_sizes;
261 
262  typedef std::set<std::string> smt2_identifierst;
264 
265  // Boolean part
266  std::size_t no_boolean_variables;
267  std::vector<bool> boolean_assignment;
268 };
269 
270 #endif // CPROVER_SOLVERS_SMT2_SMT2_CONV_H
with_exprt
Operator to update elements in structs and arrays.
Definition: std_expr.h:2423
smt2_convt::set_to
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'.
Definition: smt2_conv.cpp:4609
smt2_convt::convert_typecast
void convert_typecast(const typecast_exprt &expr)
Definition: smt2_conv.cpp:2343
smt2_convt::solvert::CVC4
@ CVC4
smt2_convt::convert_euclidean_mod
void convert_euclidean_mod(const euclidean_mod_exprt &expr)
Definition: smt2_conv.cpp:3290
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
smt2_convt::solver
solvert solver
Definition: smt2_conv.h:92
smt2_convt::walk_array_tree
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.
Definition: smt2_conv.cpp:521
smt2_convt::solvert::CPROVER_SMT2
@ CPROVER_SMT2
smt2_convt::print_assignment
void print_assignment(std::ostream &out) const override
Print satisfying assignment to out.
Definition: smt2_conv.cpp:131
letifyt
Introduce LET for common subexpressions.
Definition: letify.h:15
smt2_convt::wheret
wheret
Definition: smt2_conv.h:211
smt2_convt::get_number_of_solver_calls
std::size_t get_number_of_solver_calls() const override
Return the number of incremental solver calls.
Definition: smt2_conv.cpp:5478
smt2_convt::wheret::END
@ END
smt2_convt::letify
letifyt letify
Definition: smt2_conv.h:158
smt2_convt::convert_type
void convert_type(const typet &)
Definition: smt2_conv.cpp:5124
irept::make_nil
void make_nil()
Definition: irep.h:454
typet
The type of an expression, extends irept.
Definition: type.h:28
smt2_convt::pop
void pop() override
Currently, only implements a single stack element (no nested contexts)
Definition: smt2_conv.cpp:904
smt2_convt::datatype_map
datatype_mapt datatype_map
Definition: smt2_conv.h:245
threeval.h
smt2_convt::parse_array
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 ...
Definition: smt2_conv.cpp:477
smt2_convt::use_array_theory
bool use_array_theory(const exprt &)
Definition: smt2_conv.cpp:5103
smt2_convt::convert_floatbv
void convert_floatbv(const exprt &expr)
Definition: smt2_conv.cpp:1012
smt2_convt::use_datatypes
bool use_datatypes
Definition: smt2_conv.h:65
smt2_convt::convert
literalt convert(const exprt &expr)
Definition: smt2_conv.cpp:804
smt2_convt::smt2_symbolt::smt2_symbolt
smt2_symbolt(const irep_idt &_identifier, const typet &_type)
Definition: smt2_conv.h:191
smt2_convt::solvert::MATHSAT
@ MATHSAT
smt2_convt::convert_update
void convert_update(const exprt &expr)
Definition: smt2_conv.cpp:4251
union_exprt
Union constructor from single element.
Definition: std_expr.h:1707
smt2_convt::convert_plus
void convert_plus(const plus_exprt &expr)
Definition: smt2_conv.cpp:3468
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
smt2_convt::convert_floatbv_plus
void convert_floatbv_plus(const ieee_float_op_exprt &expr)
Definition: smt2_conv.cpp:3661
exprt
Base class for all expressions.
Definition: expr.h:55
unary_exprt
Generic base class for unary expressions.
Definition: std_expr.h:313
smt2_convt::convert_expr
void convert_expr(const exprt &)
Definition: smt2_conv.cpp:1046
binary_exprt
A base class for binary expressions.
Definition: std_expr.h:582
smt2_convt::identifier_mapt
std::unordered_map< irep_idt, identifiert > identifier_mapt
Definition: smt2_conv.h:236
smt2_convt::convert_constant
void convert_constant(const constant_exprt &expr)
Definition: smt2_conv.cpp:3146
smt2_convt::convert_literal
void convert_literal(const literalt)
Definition: smt2_conv.cpp:869
smt2_convt::handle
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...
Definition: smt2_conv.cpp:860
pointer_logict
Definition: pointer_logic.h:22
stack_decision_proceduret
Definition: stack_decision_procedure.h:57
div_exprt
Division.
Definition: std_expr.h:1096
smt2_convt::~smt2_convt
~smt2_convt() override=default
smt2_convt::solvert::CVC3
@ CVC3
object_size_exprt
Expression for finding the size (in bytes) of the object a pointer points to.
Definition: pointer_expr.h:1006
smt2_convt::type2id
std::string type2id(const typet &) const
Definition: smt2_conv.cpp:961
smt2_convt::flatten_array
void flatten_array(const exprt &)
produce a flat bit-vector for a given array of fixed size
Definition: smt2_conv.cpp:3086
irep_hash_container.h
smt2_convt::solvert::BOOLECTOR
@ BOOLECTOR
smt2_convt::convert_is_dynamic_object
void convert_is_dynamic_object(const unary_exprt &)
Definition: smt2_conv.cpp:3324
smt2_convt::convert_index
void convert_index(const index_exprt &expr)
Definition: smt2_conv.cpp:4258
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
euclidean_mod_exprt
Boute's Euclidean definition of Modulo – to match SMT-LIB2.
Definition: std_expr.h:1235
smt2_convt::convert_rounding_mode_FPA
void convert_rounding_mode_FPA(const exprt &expr)
Converting a constant or symbolic rounding mode to SMT-LIB.
Definition: smt2_conv.cpp:3604
struct_exprt
Struct constructor from list of elements.
Definition: std_expr.h:1818
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
smt2_convt::notes
std::string notes
Definition: smt2_conv.h:91
nullary_exprt
An expression without operands.
Definition: std_expr.h:21
smt2_convt::to_smt2_symbol
const smt2_symbolt & to_smt2_symbol(const exprt &expr)
Definition: smt2_conv.h:201
stack_decision_procedure.h
smt2_convt::number_of_solver_calls
std::size_t number_of_solver_calls
Definition: smt2_conv.h:97
pointer_logic.h
smt2_convt::convert_mult
void convert_mult(const mult_exprt &expr)
Definition: smt2_conv.cpp:3895
smt2_convt::convert_identifier
static std::string convert_identifier(const irep_idt &identifier)
Definition: smt2_conv.cpp:926
smt2_convt::convert_floatbv_div
void convert_floatbv_div(const ieee_float_op_exprt &expr)
Definition: smt2_conv.cpp:3875
smt2_convt::prepare_for_convert_expr
exprt prepare_for_convert_expr(const exprt &expr)
Perform steps necessary before an expression is passed to convert_expr.
Definition: smt2_conv.cpp:4785
smt2_convt::push
void push() override
Unimplemented.
Definition: smt2_conv.cpp:892
smt2_convt::set_values
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...
Definition: smt2_conv.h:258
smt2_convt::parse_literal
constant_exprt parse_literal(const irept &, const typet &type)
Definition: smt2_conv.cpp:339
smt2_convt::solvert::YICES
@ YICES
exprt::has_operands
bool has_operands() const
Return true if there is at least one operand.
Definition: expr.h:91
smt2_convt::write_footer
void write_footer()
Writes the end of the SMT file to the smt_convt::out stream.
Definition: smt2_conv.cpp:184
smt2_convt::convert_relation
void convert_relation(const binary_relation_exprt &)
Definition: smt2_conv.cpp:3361
floatbv_typecast_exprt
Semantic type conversion from/to floating-point formats.
Definition: floatbv_expr.h:18
smt2_convt::identifier_map
identifier_mapt identifier_map
Definition: smt2_conv.h:238
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
smt2_convt::convert_mod
void convert_mod(const mod_exprt &expr)
Definition: smt2_conv.cpp:3305
smt2_convt::smt2_symbolt::get_identifier
const irep_idt & get_identifier() const
Definition: smt2_conv.h:195
pointer_expr.h
smt2_convt::convert_floatbv_mult
void convert_floatbv_mult(const ieee_float_op_exprt &expr)
Definition: smt2_conv.cpp:3970
smt2_convt::use_check_sat_assuming
bool use_check_sat_assuming
Definition: smt2_conv.h:64
mult_exprt
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1051
smt2_convt::convert_struct
void convert_struct(const struct_exprt &expr)
Definition: smt2_conv.cpp:3020
smt2_convt::define_object_size
void define_object_size(const irep_idt &id, const object_size_exprt &expr)
Definition: smt2_conv.cpp:235
smt2_convt::use_lambda_for_array
bool use_lambda_for_array
Definition: smt2_conv.h:66
smt2_convt::out
std::ostream & out
Definition: smt2_conv.h:90
irept::id
const irep_idt & id() const
Definition: irep.h:396
smt2_convt::bvfp_set
std::set< irep_idt > bvfp_set
Definition: smt2_conv.h:186
union_typet
The union type.
Definition: c_types.h:124
smt2_convt::convert_div
void convert_div(const div_exprt &expr)
Definition: smt2_conv.cpp:3831
smt2_convt::use_array_of_bool
bool use_array_of_bool
Definition: smt2_conv.h:62
smt2_convt::datatype_mapt
std::map< typet, std::string > datatype_mapt
Definition: smt2_conv.h:244
smt2_convt::convert_minus
void convert_minus(const minus_exprt &expr)
Definition: smt2_conv.cpp:3702
tvt
Definition: threeval.h:19
decision_proceduret::resultt
resultt
Result of running the decision procedure.
Definition: decision_procedure.h:43
minus_exprt
Binary minus.
Definition: std_expr.h:1005
literal.h
smt2_convt::boolbv_width
boolbv_widtht boolbv_width
Definition: smt2_conv.h:95
smt2_convt
Definition: smt2_conv.h:36
smt2_convt::find_symbols_rec
void find_symbols_rec(const typet &type, std::set< irep_idt > &recstack)
Definition: smt2_conv.cpp:5263
smt2_convt::convert_with
void convert_with(const with_exprt &expr)
Definition: smt2_conv.cpp:4013
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
boolbv_widtht
Definition: boolbv_width.h:18
smt2_convt::use_FPA_theory
bool use_FPA_theory
Definition: smt2_conv.h:61
smt2_convt::write_header
void write_header()
Definition: smt2_conv.cpp:154
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
smt2_convt::logic
std::string logic
Definition: smt2_conv.h:91
array_typet
Arrays with given size.
Definition: std_types.h:762
smt2_convt::smt2_symbolt
Definition: smt2_conv.h:188
boolbv_width.h
smt2_convt::defined_expressionst
std::map< exprt, irep_idt > defined_expressionst
Definition: smt2_conv.h:253
smt2_convt::parse_rec
exprt parse_rec(const irept &s, const typet &type)
Definition: smt2_conv.cpp:636
smt2_convt::dec_solve
resultt dec_solve() override
Run the decision procedure to solve the problem.
Definition: smt2_conv.cpp:272
smt2_convt::floatbv_suffix
std::string floatbv_suffix(const exprt &) const
Definition: smt2_conv.cpp:1005
smt2_convt::identifiert::identifiert
identifiert()
Definition: smt2_conv.h:229
smt2_convt::smt2_convt
smt2_convt(const namespacet &_ns, const std::string &_benchmark, const std::string &_notes, const std::string &_logic, solvert _solver, std::ostream &_out)
Definition: smt2_conv.cpp:55
smt2_convt::assumptions
std::vector< exprt > assumptions
Definition: smt2_conv.h:94
smt2_convt::lower_byte_operators
exprt lower_byte_operators(const exprt &expr)
Lower byte_update and byte_extract operations within expr.
Definition: smt2_conv.cpp:4753
binary_relation_exprt
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:706
smt2_convt::convert_floatbv_rem
void convert_floatbv_rem(const binary_exprt &expr)
Definition: smt2_conv.cpp:3990
smt2_convt::benchmark
std::string benchmark
Definition: smt2_conv.h:91
smt2_convt::parse_struct
struct_exprt parse_struct(const irept &s, const struct_typet &type)
Definition: smt2_conv.cpp:577
smt2_convt::no_boolean_variables
std::size_t no_boolean_variables
Definition: smt2_conv.h:266
literalt
Definition: literal.h:25
smt2_convt::convert_union
void convert_union(const union_exprt &expr)
Definition: smt2_conv.cpp:3117
smt2_convt::ns
const namespacet & ns
Definition: smt2_conv.h:89
smt2_convt::solvert::GENERIC
@ GENERIC
smt2_convt::emit_set_logic
bool emit_set_logic
Definition: smt2_conv.h:67
smt2_convt::pointer_logic
pointer_logict pointer_logic
Definition: smt2_conv.h:216
smt2_convt::convert_address_of_rec
void convert_address_of_rec(const exprt &expr, const pointer_typet &result_type)
Definition: smt2_conv.cpp:702
smt2_convt::get
exprt get(const exprt &expr) const override
Return expr with variables replaced by values from satisfying assignment if available.
Definition: smt2_conv.cpp:279
ieee_float_op_exprt
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
Definition: floatbv_expr.h:363
smt2_convt::solvert::Z3
@ Z3
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:359
smt2_convt::l_get
tvt l_get(literalt l) const
Definition: smt2_conv.cpp:141
smt2_convt::smt2_identifierst
std::set< std::string > smt2_identifierst
Definition: smt2_conv.h:262
smt2_convt::identifiert
Definition: smt2_conv.h:223
smt2_convt::find_symbols
void find_symbols(const exprt &expr)
Definition: smt2_conv.cpp:4800
letify.h
smt2_convt::solvert
solvert
Definition: smt2_conv.h:39
index_exprt
Array index operator.
Definition: std_expr.h:1409
smt2_convt::boolean_assignment
std::vector< bool > boolean_assignment
Definition: smt2_conv.h:267
smt2_convt::use_as_const
bool use_as_const
Definition: smt2_conv.h:63
smt2_convt::identifiert::type
typet type
Definition: smt2_conv.h:226
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
smt2_convt::object_sizes
std::map< object_size_exprt, irep_idt > object_sizes
Definition: smt2_conv.h:260
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
std_expr.h
smt2_convt::unflatten
void unflatten(wheret, const typet &, unsigned nesting=0)
Definition: smt2_conv.cpp:4505
smt2_convt::parse_union
exprt parse_union(const irept &s, const union_typet &type)
Definition: smt2_conv.cpp:561
smt2_convt::convert_floatbv_minus
void convert_floatbv_minus(const ieee_float_op_exprt &expr)
Definition: smt2_conv.cpp:3811
smt2_convt::flatten2bv
void flatten2bv(const exprt &)
Definition: smt2_conv.cpp:4416
smt2_convt::smt2_identifiers
smt2_identifierst smt2_identifiers
Definition: smt2_conv.h:263
smt2_convt::convert_floatbv_typecast
void convert_floatbv_typecast(const floatbv_typecast_exprt &expr)
Definition: smt2_conv.cpp:2876
smt2_convt::identifiert::value
exprt value
Definition: smt2_conv.h:227
smt2_convt::identifiert::is_bound
bool is_bound
Definition: smt2_conv.h:225
mod_exprt
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition: std_expr.h:1167
smt2_convt::wheret::BEGIN
@ BEGIN
smt2_convt::decision_procedure_text
std::string decision_procedure_text() const override
Return a textual description of the decision procedure.
Definition: smt2_conv.cpp:126
smt2_convt::convert_member
void convert_member(const member_exprt &expr)
Definition: smt2_conv.cpp:4355
smt2_convt::defined_expressions
defined_expressionst defined_expressions
Definition: smt2_conv.h:254