CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 <sstream> // IWYU pragma: keep
16#include <stack>
17#include <string>
18
19static std::string escape_identifier(const irep_idt &identifier)
20{
21 return smt2_convt::convert_identifier(identifier);
22}
23
25{
26protected:
27 std::ostream &os;
28
29public:
30 explicit smt_index_output_visitort(std::ostream &os) : os(os)
31 {
32 }
33
34 void visit(const smt_numeral_indext &numeral) override
35 {
36 os << numeral.value();
37 }
38
39 void visit(const smt_symbol_indext &symbol) override
40 {
41 os << escape_identifier(symbol.identifier());
42 }
43};
44
45std::ostream &operator<<(std::ostream &os, const smt_indext &index)
46{
48 index.accept(visitor);
49 return os;
50}
51
52std::string smt_to_smt2_string(const smt_indext &index)
53{
54 std::stringstream ss;
55 ss << index;
56 return ss.str();
57}
58
60{
61protected:
62 std::ostream &os;
63
64public:
65 explicit smt_sort_output_visitort(std::ostream &os) : os(os)
66 {
67 }
68
69 void visit(const smt_bool_sortt &) override
70 {
71 os << "Bool";
72 }
73
74 void visit(const smt_bit_vector_sortt &bit_vec) override
75 {
76 os << "(_ BitVec " << bit_vec.bit_width() << ")";
77 }
78
79 void visit(const smt_array_sortt &array) override
80 {
81 os << "(Array " << array.index_sort() << " " << array.element_sort() << ")";
82 }
83};
84
85std::ostream &operator<<(std::ostream &os, const smt_sortt &sort)
86{
88 return os;
89}
90
91std::string smt_to_smt2_string(const smt_sortt &sort)
92{
93 std::stringstream ss;
94 ss << sort;
95 return ss.str();
96}
97
99{
100 std::vector<std::reference_wrapper<const smt_identifier_termt>> identifiers;
101};
102
119{
120private:
121 using output_functiont = std::function<void(std::ostream &)>;
122 std::stack<output_functiont> output_stack;
123
124 static output_functiont make_output_function(const std::string &output);
126 static output_functiont make_output_function(const smt_sortt &output);
128 template <typename elementt>
130 const std::vector<std::reference_wrapper<const elementt>> &output);
132
134 template <typename outputt>
135 void push_output(outputt &&output);
136
138 void push_outputs();
139
151 template <typename outputt, typename... outputst>
152 void push_outputs(outputt &&output, outputst &&... outputs);
153
155
156 void visit(const smt_bool_literal_termt &bool_literal) override;
157 void visit(const smt_identifier_termt &identifier_term) override;
159 void
160 visit(const smt_function_application_termt &function_application) override;
161 void visit(const smt_forall_termt &forall) override;
162 void visit(const smt_exists_termt &exists) override;
163
164public:
168 static std::ostream &convert(std::ostream &os, const smt_termt &term);
169};
170
173{
174 // `output` must be captured by value to avoid dangling references.
175 return [output](std::ostream &os) { os << output; };
176}
177
180{
181 return [=](std::ostream &os) { os << output; };
182}
183
186{
187 return [=](std::ostream &os) { os << output; };
188}
189
192{
193 return [=](std::ostream &os) { output.accept(*this); };
194}
195
196template <typename elementt>
199 const std::vector<std::reference_wrapper<const elementt>> &outputs)
200{
201 return [=](std::ostream &os) {
202 for(const auto &output : make_range(outputs.rbegin(), outputs.rend()))
203 {
204 push_outputs(" ", output.get());
205 }
206 };
207}
208
211 const sorted_variablest &output)
212{
213 return [=](std::ostream &os) {
214 const auto push_sorted_variable =
215 [&](const smt_identifier_termt &identifier) {
216 push_outputs("(", identifier, " ", identifier.get_sort(), ")");
217 };
218 for(const auto &bound_variable :
219 make_range(output.identifiers.rbegin(), --output.identifiers.rend()))
220 {
222 push_output(" ");
223 }
224 push_sorted_variable(output.identifiers.front());
225 };
226}
227
228template <typename outputt>
230{
231 output_stack.push(make_output_function(std::forward<outputt>(output)));
232}
233
237
238template <typename outputt, typename... outputst>
240 outputt &&output,
241 outputst &&... outputs)
242{
243 push_outputs(std::forward<outputst>(outputs)...);
244 push_output(std::forward<outputt>(output));
245}
246
249{
250 push_output(bool_literal.value() ? "true" : "false");
251}
252
255{
256 auto indices = identifier_term.indices();
258 if(indices.empty())
259 {
261 }
262 else
263 {
264 push_outputs("(_ ", std::move(escaped_identifier), std::move(indices), ")");
265 }
266}
267
270{
271 auto value = integer2string(bit_vector_constant.value());
272 auto bit_width = std::to_string(bit_vector_constant.get_sort().bit_width());
273 push_outputs("(_ bv", std::move(value), " ", std::move(bit_width), ")");
274}
275
277 const smt_function_application_termt &function_application)
278{
279 const auto &id = function_application.function_identifier();
280 auto arguments = function_application.arguments();
281 push_outputs("(", id, std::move(arguments), ")");
282}
283
285{
286 sorted_variablest bound_variables{forall.bound_variables()};
287 auto predicate = forall.predicate();
288 push_outputs("(forall (", bound_variables, ") ", std::move(predicate), ")");
289}
290
292{
293 sorted_variablest bound_variables{exists.bound_variables()};
294 auto predicate = exists.predicate();
295 push_outputs("(exists (", bound_variables, ") ", std::move(predicate), ")");
296}
297
298std::ostream &
300{
302 term.accept(converter);
303 while(!converter.output_stack.empty())
304 {
305 auto output_function = std::move(converter.output_stack.top());
306 converter.output_stack.pop();
307 output_function(os);
308 }
309 return os;
310}
311
312std::ostream &operator<<(std::ostream &os, const smt_termt &term)
313{
315}
316
317std::string smt_to_smt2_string(const smt_termt &term)
318{
319 std::stringstream ss;
320 ss << term;
321 return ss.str();
322}
323
326{
327protected:
328 std::ostream &os;
329
330public:
331 explicit smt_option_to_string_convertert(std::ostream &os) : os(os)
332 {
333 }
334
336 {
337 os << ":produce-models " << (produce_models.setting() ? "true" : "false");
338 }
339};
340
341std::ostream &operator<<(std::ostream &os, const smt_optiont &option)
342{
344 return os;
345}
346
347std::string smt_to_smt2_string(const smt_optiont &option)
348{
349 std::stringstream ss;
350 ss << option;
351 return ss.str();
352}
353
355{
356protected:
357 std::ostream &os;
358
359public:
360 explicit smt_logic_to_string_convertert(std::ostream &os) : os(os)
361 {
362 }
363
364#define LOGIC_ID(the_id, the_name) \
365 void visit(const smt_logic_##the_id##t &) override \
366 { \
367 os << #the_name; \
368 }
369#include "solvers/smt2_incremental/ast/smt_logics.def"
370
371#undef LOGIC_ID
372};
373
374std::ostream &operator<<(std::ostream &os, const smt_logict &logic)
375{
377 return os;
378}
379
380std::string smt_to_smt2_string(const smt_logict &logic)
381{
382 std::stringstream ss;
383 ss << logic;
384 return ss.str();
385}
386
389{
390protected:
391 std::ostream &os;
392
393public:
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
417 {
418 os << "(define-fun " << define_function.identifier() << " (";
419 const auto parameters = define_function.parameters();
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
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
464std::ostream &operator<<(std::ostream &os, const smt_commandt &command)
465{
467 return os;
468}
469
470std::string smt_to_smt2_string(const smt_commandt &command)
471{
472 std::stringstream ss;
473 ss << command;
474 return ss.str();
475}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
static std::string convert_identifier(const irep_idt &identifier)
const smt_sortt & element_sort() const
Definition smt_sorts.cpp:81
const smt_sortt & index_sort() const
Definition smt_sorts.cpp:76
void visit(const smt_declare_function_commandt &declare_function) override
void visit(const smt_pop_commandt &pop) override
void visit(const smt_assert_commandt &assert) override
void visit(const smt_exit_commandt &exit) override
void visit(const smt_get_value_commandt &get_value) override
void visit(const smt_define_function_commandt &define_function) override
void visit(const smt_set_option_commandt &set_option) override
void visit(const smt_set_logic_commandt &set_logic) override
void visit(const smt_push_commandt &push) override
void visit(const smt_check_sat_commandt &check_sat) override
void accept(smt_command_const_downcast_visitort &) const
const smt_identifier_termt & function_identifier() const
std::vector< std::reference_wrapper< const smt_termt > > arguments() const
const smt_termt & descriptor() const
Stores identifiers in unescaped and unquoted form.
Definition smt_terms.h:93
void visit(const smt_numeral_indext &numeral) override
void visit(const smt_symbol_indext &symbol) override
smt_index_output_visitort(std::ostream &os)
For implementation of indexed identifiers.
Definition smt_index.h:14
void accept(smt_index_const_downcast_visitort &) const
Definition smt_index.cpp:35
smt_logic_to_string_convertert(std::ostream &os)
void accept(smt_logic_const_downcast_visitort &) const
void visit(const smt_option_produce_modelst &produce_models) override
smt_option_to_string_convertert(std::ostream &os)
void accept(smt_option_const_downcast_visitort &) const
size_t levels() const
size_t levels() const
const smt_optiont & option() const
smt_sort_output_visitort(std::ostream &os)
void visit(const smt_array_sortt &array) override
void visit(const smt_bit_vector_sortt &bit_vec) override
void visit(const smt_bool_sortt &) override
void accept(smt_sort_const_downcast_visitort &) const
Definition smt_sorts.cpp:97
irep_idt identifier() const
Definition smt_index.cpp:62
void visit(const smt_bool_literal_termt &bool_literal) override
void push_output(outputt &&output)
Single argument version of push_outputs.
std::function< void(std::ostream &)> output_functiont
static output_functiont make_output_function(const std::string &output)
void push_outputs()
Base case for the recursive push_outputs function template below.
std::stack< output_functiont > output_stack
static std::ostream & convert(std::ostream &os, const smt_termt &term)
This function is complete the external interface to this class.
void accept(smt_term_const_downcast_visitort &) const
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.
mini_bddt exists(const mini_bddt &u, const unsigned var)
Definition miniBDD.cpp:556
const std::string integer2string(const mp_integer &n, unsigned base)
Definition mp_arith.cpp:103
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
Data structure for smt sorts.
std::string smt_to_smt2_string(const smt_indext &index)
std::ostream & operator<<(std::ostream &os, const smt_indext &index)
static std::string escape_identifier(const irep_idt &identifier)
Streaming SMT data structures to a string based output stream.
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.
void exit(int status)
Definition stdlib.c:102
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.
std::vector< std::reference_wrapper< const smt_identifier_termt > > identifiers