CBMC
smt_to_smt2_string.cpp
Go to the documentation of this file.
1 // Author: Diffblue Ltd.
2 
3 #include <util/range.h>
4 #include <util/string_utils.h>
5 
13 
14 #include <functional>
15 #include <iostream>
16 #include <sstream>
17 #include <stack>
18 #include <string>
19 
20 static std::string escape_identifier(const irep_idt &identifier)
21 {
22  return smt2_convt::convert_identifier(identifier);
23 }
24 
26 {
27 protected:
28  std::ostream &os;
29 
30 public:
31  explicit smt_index_output_visitort(std::ostream &os) : os(os)
32  {
33  }
34 
35  void visit(const smt_numeral_indext &numeral) override
36  {
37  os << numeral.value();
38  }
39 
40  void visit(const smt_symbol_indext &symbol) override
41  {
42  os << escape_identifier(symbol.identifier());
43  }
44 };
45 
46 std::ostream &operator<<(std::ostream &os, const smt_indext &index)
47 {
48  smt_index_output_visitort visitor{os};
49  index.accept(visitor);
50  return os;
51 }
52 
53 std::string smt_to_smt2_string(const smt_indext &index)
54 {
55  std::stringstream ss;
56  ss << index;
57  return ss.str();
58 }
59 
61 {
62 protected:
63  std::ostream &os;
64 
65 public:
66  explicit smt_sort_output_visitort(std::ostream &os) : os(os)
67  {
68  }
69 
70  void visit(const smt_bool_sortt &) override
71  {
72  os << "Bool";
73  }
74 
75  void visit(const smt_bit_vector_sortt &bit_vec) override
76  {
77  os << "(_ BitVec " << bit_vec.bit_width() << ")";
78  }
79 
80  void visit(const smt_array_sortt &array) override
81  {
82  os << "(Array " << array.index_sort() << " " << array.element_sort() << ")";
83  }
84 };
85 
86 std::ostream &operator<<(std::ostream &os, const smt_sortt &sort)
87 {
89  return os;
90 }
91 
92 std::string smt_to_smt2_string(const smt_sortt &sort)
93 {
94  std::stringstream ss;
95  ss << sort;
96  return ss.str();
97 }
98 
99 struct sorted_variablest final
100 {
101  std::vector<std::reference_wrapper<const smt_identifier_termt>> identifiers;
102 };
103 
120 {
121 private:
122  using output_functiont = std::function<void(std::ostream &)>;
123  std::stack<output_functiont> output_stack;
124 
125  static output_functiont make_output_function(const std::string &output);
126  static output_functiont make_output_function(const smt_indext &output);
127  static output_functiont make_output_function(const smt_sortt &output);
129  template <typename elementt>
131  const std::vector<std::reference_wrapper<const elementt>> &output);
133 
135  template <typename outputt>
136  void push_output(outputt &&output);
137 
139  void push_outputs();
140 
152  template <typename outputt, typename... outputst>
153  void push_outputs(outputt &&output, outputst &&... outputs);
154 
155  smt_term_to_string_convertert() = default;
156 
157  void visit(const smt_bool_literal_termt &bool_literal) override;
158  void visit(const smt_identifier_termt &identifier_term) override;
159  void visit(const smt_bit_vector_constant_termt &bit_vector_constant) override;
160  void
161  visit(const smt_function_application_termt &function_application) override;
162  void visit(const smt_forall_termt &forall) override;
163  void visit(const smt_exists_termt &exists) override;
164 
165 public:
169  static std::ostream &convert(std::ostream &os, const smt_termt &term);
170 };
171 
174 {
175  // `output` must be captured by value to avoid dangling references.
176  return [output](std::ostream &os) { os << output; };
177 }
178 
181 {
182  return [=](std::ostream &os) { os << output; };
183 }
184 
187 {
188  return [=](std::ostream &os) { os << output; };
189 }
190 
193 {
194  return [=](std::ostream &os) { output.accept(*this); };
195 }
196 
197 template <typename elementt>
200  const std::vector<std::reference_wrapper<const elementt>> &outputs)
201 {
202  return [=](std::ostream &os) {
203  for(const auto &output : make_range(outputs.rbegin(), outputs.rend()))
204  {
205  push_outputs(" ", output.get());
206  }
207  };
208 }
209 
212  const sorted_variablest &output)
213 {
214  return [=](std::ostream &os) {
215  const auto push_sorted_variable =
216  [&](const smt_identifier_termt &identifier) {
217  push_outputs("(", identifier, " ", identifier.get_sort(), ")");
218  };
219  for(const auto &bound_variable :
220  make_range(output.identifiers.rbegin(), --output.identifiers.rend()))
221  {
222  push_sorted_variable(bound_variable);
223  push_output(" ");
224  }
225  push_sorted_variable(output.identifiers.front());
226  };
227 }
228 
229 template <typename outputt>
231 {
232  output_stack.push(make_output_function(std::forward<outputt>(output)));
233 }
234 
236 {
237 }
238 
239 template <typename outputt, typename... outputst>
241  outputt &&output,
242  outputst &&... outputs)
243 {
244  push_outputs(std::forward<outputst>(outputs)...);
245  push_output(std::forward<outputt>(output));
246 }
247 
249  const smt_bool_literal_termt &bool_literal)
250 {
251  push_output(bool_literal.value() ? "true" : "false");
252 }
253 
255  const smt_identifier_termt &identifier_term)
256 {
257  auto indices = identifier_term.indices();
258  auto escaped_identifier = escape_identifier(identifier_term.identifier());
259  if(indices.empty())
260  {
261  push_outputs(std::move(escaped_identifier));
262  }
263  else
264  {
265  push_outputs("(_ ", std::move(escaped_identifier), std::move(indices), ")");
266  }
267 }
268 
270  const smt_bit_vector_constant_termt &bit_vector_constant)
271 {
272  auto value = integer2string(bit_vector_constant.value());
273  auto bit_width = std::to_string(bit_vector_constant.get_sort().bit_width());
274  push_outputs("(_ bv", std::move(value), " ", std::move(bit_width), ")");
275 }
276 
278  const smt_function_application_termt &function_application)
279 {
280  const auto &id = function_application.function_identifier();
281  auto arguments = function_application.arguments();
282  push_outputs("(", id, std::move(arguments), ")");
283 }
284 
286 {
287  sorted_variablest bound_variables{forall.bound_variables()};
288  auto predicate = forall.predicate();
289  push_outputs("(forall (", bound_variables, ") ", std::move(predicate), ")");
290 }
291 
293 {
294  sorted_variablest bound_variables{exists.bound_variables()};
295  auto predicate = exists.predicate();
296  push_outputs("(exists (", bound_variables, ") ", std::move(predicate), ")");
297 }
298 
299 std::ostream &
300 smt_term_to_string_convertert::convert(std::ostream &os, const smt_termt &term)
301 {
303  term.accept(converter);
304  while(!converter.output_stack.empty())
305  {
306  auto output_function = std::move(converter.output_stack.top());
307  converter.output_stack.pop();
308  output_function(os);
309  }
310  return os;
311 }
312 
313 std::ostream &operator<<(std::ostream &os, const smt_termt &term)
314 {
316 }
317 
318 std::string smt_to_smt2_string(const smt_termt &term)
319 {
320  std::stringstream ss;
321  ss << term;
322  return ss.str();
323 }
324 
327 {
328 protected:
329  std::ostream &os;
330 
331 public:
332  explicit smt_option_to_string_convertert(std::ostream &os) : os(os)
333  {
334  }
335 
336  void visit(const smt_option_produce_modelst &produce_models) override
337  {
338  os << ":produce-models " << (produce_models.setting() ? "true" : "false");
339  }
340 };
341 
342 std::ostream &operator<<(std::ostream &os, const smt_optiont &option)
343 {
345  return os;
346 }
347 
348 std::string smt_to_smt2_string(const smt_optiont &option)
349 {
350  std::stringstream ss;
351  ss << option;
352  return ss.str();
353 }
354 
356 {
357 protected:
358  std::ostream &os;
359 
360 public:
361  explicit smt_logic_to_string_convertert(std::ostream &os) : os(os)
362  {
363  }
364 
365 #define LOGIC_ID(the_id, the_name) \
366  void visit(const smt_logic_##the_id##t &) override \
367  { \
368  os << #the_name; \
369  }
370 #include "smt_logics.def"
371 #undef LOGIC_ID
372 };
373 
374 std::ostream &operator<<(std::ostream &os, const smt_logict &logic)
375 {
377  return os;
378 }
379 
380 std::string smt_to_smt2_string(const smt_logict &logic)
381 {
382  std::stringstream ss;
383  ss << logic;
384  return ss.str();
385 }
386 
389 {
390 protected:
391  std::ostream &os;
392 
393 public:
394  explicit smt_command_to_string_convertert(std::ostream &os) : os(os)
395  {
396  }
397 
398  void visit(const smt_assert_commandt &assert) override
399  {
400  os << "(assert " << assert.condition() << ")";
401  }
402 
403  void visit(const smt_check_sat_commandt &check_sat) override
404  {
405  os << "(check-sat)";
406  }
407 
409  {
410  os << "(declare-fun " << declare_function.identifier() << " (";
411  const auto parameter_sorts = declare_function.parameter_sorts();
412  join_strings(os, parameter_sorts.begin(), parameter_sorts.end(), ' ');
413  os << ") " << declare_function.return_sort() << ")";
414  }
415 
416  void visit(const smt_define_function_commandt &define_function) override
417  {
418  os << "(define-fun " << define_function.identifier() << " (";
419  const auto parameters = define_function.parameters();
420  join_strings(
421  os,
422  parameters.begin(),
423  parameters.end(),
424  " ",
425  [](const smt_identifier_termt &identifier) {
426  return "(" + smt_to_smt2_string(identifier) + " " +
427  smt_to_smt2_string(identifier.get_sort()) + ")";
428  });
429  os << ") " << define_function.return_sort() << " "
430  << define_function.definition() << ")";
431  }
432 
433  void visit(const smt_exit_commandt &exit) override
434  {
435  os << "(exit)";
436  }
437 
438  void visit(const smt_get_value_commandt &get_value) override
439  {
440  os << "(get-value (" << get_value.descriptor() << "))";
441  }
442 
443  void visit(const smt_pop_commandt &pop) override
444  {
445  os << "(pop " << pop.levels() << ")";
446  }
447 
448  void visit(const smt_push_commandt &push) override
449  {
450  os << "(push " << push.levels() << ")";
451  }
452 
453  void visit(const smt_set_logic_commandt &set_logic) override
454  {
455  os << "(set-logic " << set_logic.logic() << ")";
456  }
457 
458  void visit(const smt_set_option_commandt &set_option) override
459  {
460  os << "(set-option " << set_option.option() << ")";
461  }
462 };
463 
464 std::ostream &operator<<(std::ostream &os, const smt_commandt &command)
465 {
467  return os;
468 }
469 
470 std::string smt_to_smt2_string(const smt_commandt &command)
471 {
472  std::stringstream ss;
473  ss << command;
474  return ss.str();
475 }
sorted_variablest
Definition: smt_to_smt2_string.cpp:99
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
smt_command_to_string_convertert::visit
void visit(const smt_define_function_commandt &define_function) override
Definition: smt_to_smt2_string.cpp:416
smt_command_to_string_convertert::visit
void visit(const smt_exit_commandt &exit) override
Definition: smt_to_smt2_string.cpp:433
smt_option_produce_modelst
Definition: smt_options.h:64
smt_push_commandt
Definition: smt_commands.h:102
smt_set_logic_commandt
Definition: smt_commands.h:116
smt2_conv.h
smt_indext::accept
void accept(smt_index_const_downcast_visitort &) const
Definition: smt_index.cpp:35
exists
mini_bddt exists(const mini_bddt &u, const unsigned var)
Definition: miniBDD.cpp:556
smt_define_function_commandt::return_sort
const smt_sortt & return_sort() const
Definition: smt_commands.cpp:114
smt_function_application_termt::function_identifier
const smt_identifier_termt & function_identifier() const
Definition: smt_terms.cpp:141
escape_identifier
static std::string escape_identifier(const irep_idt &identifier)
Definition: smt_to_smt2_string.cpp:20
smt_identifier_termt
Stores identifiers in unescaped and unquoted form.
Definition: smt_terms.h:91
smt_pop_commandt::levels
size_t levels() const
Definition: smt_commands.cpp:152
smt_option_to_string_convertert
Definition: smt_to_smt2_string.cpp:325
string_utils.h
smt_define_function_commandt::definition
const smt_termt & definition() const
Definition: smt_commands.cpp:119
smt_indext
For implementation of indexed identifiers.
Definition: smt_index.h:13
smt_index_output_visitort::visit
void visit(const smt_symbol_indext &symbol) override
Definition: smt_to_smt2_string.cpp:40
smt_logic_const_downcast_visitort
Definition: smt_logics.h:74
smt_termt
Definition: smt_terms.h:20
smt_set_option_commandt
Definition: smt_commands.h:125
smt_numeral_indext
Definition: smt_index.h:69
smt_symbol_indext::identifier
irep_idt identifier() const
Definition: smt_index.cpp:62
smt_command_to_string_convertert::visit
void visit(const smt_pop_commandt &pop) override
Definition: smt_to_smt2_string.cpp:443
smt_bit_vector_sortt
Definition: smt_sorts.h:83
smt_term_to_string_convertert::make_output_function
static output_functiont make_output_function(const std::string &output)
Definition: smt_to_smt2_string.cpp:173
smt_sort_output_visitort::os
std::ostream & os
Definition: smt_to_smt2_string.cpp:63
smt_index.h
smt_define_function_commandt
Definition: smt_commands.h:64
smt_get_value_commandt::descriptor
const smt_termt & descriptor() const
Definition: smt_commands.cpp:130
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
smt_define_function_commandt::parameters
std::vector< std::reference_wrapper< const smt_identifier_termt > > parameters() const
Definition: smt_commands.cpp:106
smt_bit_vector_constant_termt::value
mp_integer value() const
Definition: smt_terms.cpp:115
smt_commandt::accept
void accept(smt_command_const_downcast_visitort &) const
Definition: smt_commands.cpp:192
smt_term_to_string_convertert::output_functiont
std::function< void(std::ostream &)> output_functiont
Definition: smt_to_smt2_string.cpp:122
smt_set_option_commandt::option
const smt_optiont & option() const
Definition: smt_commands.cpp:174
smt_logic_to_string_convertert::smt_logic_to_string_convertert
smt_logic_to_string_convertert(std::ostream &os)
Definition: smt_to_smt2_string.cpp:361
smt_forall_termt::predicate
const smt_termt & predicate() const
Definition: smt_terms.cpp:175
smt_term_to_string_convertert::push_output
void push_output(outputt &&output)
Single argument version of push_outputs.
Definition: smt_to_smt2_string.cpp:230
smt_index_output_visitort::smt_index_output_visitort
smt_index_output_visitort(std::ostream &os)
Definition: smt_to_smt2_string.cpp:31
smt_bool_literal_termt::value
bool value() const
Definition: smt_terms.cpp:46
smt_bit_vector_sortt::bit_width
std::size_t bit_width() const
Definition: smt_sorts.cpp:60
smt_command_to_string_convertert::visit
void visit(const smt_set_logic_commandt &set_logic) override
Definition: smt_to_smt2_string.cpp:453
smt_define_function_commandt::identifier
const smt_identifier_termt & identifier() const
Definition: smt_commands.cpp:99
smt_sortt::accept
void accept(smt_sort_const_downcast_visitort &) const
Definition: smt_sorts.cpp:95
smt_sorts.h
smt_exit_commandt
Definition: smt_commands.h:80
smt_numeral_indext::value
std::size_t value() const
Definition: smt_index.cpp:50
smt2_convt::convert_identifier
static std::string convert_identifier(const irep_idt &identifier)
Definition: smt2_conv.cpp:926
smt_identifier_termt::indices
std::vector< std::reference_wrapper< const smt_indext > > indices() const
Definition: smt_terms.cpp:86
smt_option_to_string_convertert::smt_option_to_string_convertert
smt_option_to_string_convertert(std::ostream &os)
Definition: smt_to_smt2_string.cpp:332
smt_option_produce_modelst::setting
bool setting() const
Definition: smt_options.cpp:31
smt_declare_function_commandt
Definition: smt_commands.h:46
smt_sort_output_visitort::visit
void visit(const smt_array_sortt &array) override
Definition: smt_to_smt2_string.cpp:80
smt_sort_output_visitort::smt_sort_output_visitort
smt_sort_output_visitort(std::ostream &os)
Definition: smt_to_smt2_string.cpp:66
smt_termt::accept
void accept(smt_term_const_downcast_visitort &) const
Definition: smt_terms.cpp:235
smt_command_const_downcast_visitort
Definition: smt_commands.h:134
smt_logict::accept
void accept(smt_logic_const_downcast_visitort &) const
Definition: smt_logics.cpp:34
smt_check_sat_commandt
Definition: smt_commands.h:40
smt_pop_commandt
Definition: smt_commands.h:109
smt_term_to_string_convertert
Definition: smt_to_smt2_string.cpp:119
join_strings
Stream & join_strings(Stream &&os, const It b, const It e, const Delimiter &delimiter, TransformFunc &&transform_func)
Prints items to an stream, separated by a constant delimiter.
Definition: string_utils.h:62
smt_sortt
Definition: smt_sorts.h:17
smt_bool_sortt
Definition: smt_sorts.h:77
smt_sort_const_downcast_visitort
Definition: smt_sorts.h:100
smt_optiont::accept
void accept(smt_option_const_downcast_visitort &) const
Definition: smt_options.cpp:49
smt_assert_commandt::condition
const smt_termt & condition() const
Definition: smt_commands.cpp:32
smt_logic_to_string_convertert::os
std::ostream & os
Definition: smt_to_smt2_string.cpp:358
smt_identifier_termt::identifier
irep_idt identifier() const
Definition: smt_terms.cpp:80
smt_command_to_string_convertert::visit
void visit(const smt_get_value_commandt &get_value) override
Definition: smt_to_smt2_string.cpp:438
smt_option_to_string_convertert::os
std::ostream & os
Definition: smt_to_smt2_string.cpp:329
smt_commandt
Definition: smt_commands.h:13
range.h
smt_forall_termt::bound_variables
std::vector< std::reference_wrapper< const smt_identifier_termt > > bound_variables() const
Definition: smt_terms.cpp:181
smt_array_sortt::element_sort
const smt_sortt & element_sort() const
Definition: smt_sorts.cpp:79
smt_array_sortt::index_sort
const smt_sortt & index_sort() const
Definition: smt_sorts.cpp:74
smt_command_to_string_convertert::visit
void visit(const smt_set_option_commandt &set_option) override
Definition: smt_to_smt2_string.cpp:458
smt_term_to_string_convertert::visit
void visit(const smt_bool_literal_termt &bool_literal) override
Definition: smt_to_smt2_string.cpp:248
smt_sort_output_visitort::visit
void visit(const smt_bit_vector_sortt &bit_vec) override
Definition: smt_to_smt2_string.cpp:75
smt_forall_termt
Definition: smt_terms.h:225
smt_logic_to_string_convertert
Definition: smt_to_smt2_string.cpp:355
declare_function
static auxiliary_symbolt declare_function(const irep_idt &function_name, const mathematical_function_typet &type, symbol_table_baset &symbol_table)
Declare a function with the given name and type.
Definition: java_utils.cpp:361
smt_command_to_string_convertert::visit
void visit(const smt_declare_function_commandt &declare_function) override
Definition: smt_to_smt2_string.cpp:408
smt_term_to_string_convertert::smt_term_to_string_convertert
smt_term_to_string_convertert()=default
smt_term_to_string_convertert::convert
static std::ostream & convert(std::ostream &os, const smt_termt &term)
This function is complete the external interface to this class.
Definition: smt_to_smt2_string.cpp:300
smt_to_smt2_string
std::string smt_to_smt2_string(const smt_indext &index)
Definition: smt_to_smt2_string.cpp:53
smt_array_sortt
Definition: smt_sorts.h:90
smt_command_to_string_convertert::visit
void visit(const smt_push_commandt &push) override
Definition: smt_to_smt2_string.cpp:448
smt_function_application_termt
Definition: smt_terms.h:132
smt_commands.h
smt_logics.h
smt_index_output_visitort::os
std::ostream & os
Definition: smt_to_smt2_string.cpp:28
smt_get_value_commandt
Definition: smt_commands.h:86
smt_option_const_downcast_visitort
Definition: smt_options.h:71
smt_command_to_string_convertert::os
std::ostream & os
Definition: smt_to_smt2_string.cpp:391
smt_command_to_string_convertert::smt_command_to_string_convertert
smt_command_to_string_convertert(std::ostream &os)
Definition: smt_to_smt2_string.cpp:394
smt_assert_commandt
Definition: smt_commands.h:32
sorted_variablest::identifiers
std::vector< std::reference_wrapper< const smt_identifier_termt > > identifiers
Definition: smt_to_smt2_string.cpp:101
smt_bit_vector_constant_termt::get_sort
const smt_bit_vector_sortt & get_sort() const
Definition: smt_terms.cpp:120
smt_bool_literal_termt
Definition: smt_terms.h:76
smt_option_to_string_convertert::visit
void visit(const smt_option_produce_modelst &produce_models) override
Definition: smt_to_smt2_string.cpp:336
smt_term_to_string_convertert::push_outputs
void push_outputs()
Base case for the recursive push_outputs function template below.
Definition: smt_to_smt2_string.cpp:235
smt_command_to_string_convertert::visit
void visit(const smt_check_sat_commandt &check_sat) override
Definition: smt_to_smt2_string.cpp:403
smt_logict
Definition: smt_logics.h:10
smt_symbol_indext
Definition: smt_index.h:76
smt_command_to_string_convertert
Definition: smt_to_smt2_string.cpp:387
smt_term_to_string_convertert::output_stack
std::stack< output_functiont > output_stack
Definition: smt_to_smt2_string.cpp:123
smt_function_application_termt::arguments
std::vector< std::reference_wrapper< const smt_termt > > arguments() const
Definition: smt_terms.cpp:147
smt_sort_output_visitort::visit
void visit(const smt_bool_sortt &) override
Definition: smt_to_smt2_string.cpp:70
output_function
void output_function(std::ostream &os, const statement_list_parse_treet::functiont &function)
Prints the given Statement List function in a human-readable form to the given output stream.
Definition: statement_list_parse_tree_io.cpp:95
smt_exists_termt
Definition: smt_terms.h:236
smt_index_const_downcast_visitort
Definition: smt_index.h:83
smt_term_const_downcast_visitort
Definition: smt_terms.h:247
smt_index_output_visitort
Definition: smt_to_smt2_string.cpp:25
smt_bit_vector_constant_termt
Definition: smt_terms.h:116
smt_set_logic_commandt::logic
const smt_logict & logic() const
Definition: smt_commands.cpp:163
smt_to_smt2_string.h
smt_push_commandt::levels
size_t levels() const
Definition: smt_commands.cpp:141
smt_command_to_string_convertert::visit
void visit(const smt_assert_commandt &assert) override
Definition: smt_to_smt2_string.cpp:398
smt_terms.h
smt_sort_output_visitort
Definition: smt_to_smt2_string.cpp:60
smt_optiont
Definition: smt_options.h:10
make_range
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition: range.h:524
smt_index_output_visitort::visit
void visit(const smt_numeral_indext &numeral) override
Definition: smt_to_smt2_string.cpp:35
operator<<
std::ostream & operator<<(std::ostream &os, const smt_indext &index)
Definition: smt_to_smt2_string.cpp:46
integer2string
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103