CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
smt2_format.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "smt2_format.h"
10
11#include <util/arith_tools.h>
13#include <util/ieee_float.h>
14
15std::ostream &smt2_format_rec(std::ostream &out, const typet &type)
16{
17 if(type.id() == ID_unsignedbv)
18 out << "(_ BitVec " << to_unsignedbv_type(type).get_width() << ')';
19 else if(type.id() == ID_bool)
20 out << "Bool";
21 else if(type.id() == ID_integer)
22 out << "Int";
23 else if(type.id() == ID_real)
24 out << "Real";
25 else if(type.id() == ID_array)
26 {
27 const auto &array_type = to_array_type(type);
28 out << "(Array " << smt2_format(array_type.size().type()) << ' '
29 << smt2_format(array_type.element_type()) << ')';
30 }
31 else if(type.id() == ID_floatbv)
32 {
33 const auto &floatbv_type = to_floatbv_type(type);
34 // the width of the mantissa needs to be increased by one to
35 // include the hidden bit
36 out << "(_ FloatingPoint " << floatbv_type.get_e() << ' '
37 << floatbv_type.get_f() + 1 << ')';
38 }
39 else
40 out << "? " << type.id();
41
42 return out;
43}
44
45std::ostream &smt2_format_rec(std::ostream &out, const exprt &expr)
46{
47 if(expr.is_constant())
48 {
49 const auto &constant_expr = to_constant_expr(expr);
50 const auto &value = constant_expr.get_value();
51 const typet &expr_type = expr.type();
52
53 if(expr_type.id() == ID_unsignedbv)
54 {
55 const std::size_t width = to_unsignedbv_type(expr_type).get_width();
56
58
59 out << "(_ bv" << int_value << " " << width << ")";
60 }
61 else if(expr_type.id() == ID_bool)
62 {
63 if(expr.is_true())
64 out << "true";
65 else if(expr.is_false())
66 out << "false";
67 else
68 DATA_INVARIANT(false, "unknown Boolean constant");
69 }
70 else if(expr_type.id() == ID_integer)
71 {
72 // negative numbers need to be encoded using a unary minus expression
74 if(int_value < 0)
75 out << "(- " << -int_value << ')';
76 else
77 out << int_value;
78 }
79 else if(expr_type.id() == ID_string)
80 {
81 out << '"';
82
83 for(const auto &c : value)
84 {
85 // " is the only escape sequence
86 if(c == '"')
87 out << '"' << '"';
88 else
89 out << c;
90 }
91
92 out << '"';
93 }
94 else if(expr_type.id() == ID_floatbv)
95 {
97 const size_t e = v.spec.e;
98 const size_t f = v.spec.f + 1; // SMT-LIB counts the hidden bit
99
100 if(v.is_NaN())
101 {
102 out << "(_ NaN " << e << " " << f << ")";
103 }
104 else if(v.is_infinity())
105 {
106 if(v.get_sign())
107 out << "(_ -oo " << e << " " << f << ")";
108 else
109 out << "(_ +oo " << e << " " << f << ")";
110 }
111 else
112 {
113 // Zero, normal or subnormal
114
115 mp_integer binary = v.pack();
116 std::string binaryString(integer2binary(v.pack(), v.spec.width()));
117
118 out << "(fp "
119 << "#b" << binaryString.substr(0, 1) << " "
120 << "#b" << binaryString.substr(1, e) << " "
121 << "#b" << binaryString.substr(1 + e, f - 1) << ")";
122 }
123 }
124 else
125 DATA_INVARIANT(false, "unhandled constant: " + expr_type.id_string());
126 }
127 else if(expr.id() == ID_symbol)
128 {
129 const auto &identifier = to_symbol_expr(expr).get_identifier();
130 if(expr.get_bool("#quoted"))
131 {
132 out << '|';
133 out << identifier;
134 out << '|';
135 }
136 else
137 out << identifier;
138 }
139 else if(expr.id() == ID_with && expr.type().id() == ID_array)
140 {
141 const auto &with_expr = to_with_expr(expr);
142 out << "(store " << smt2_format(with_expr.old()) << ' '
143 << smt2_format(with_expr.where()) << ' '
144 << smt2_format(with_expr.new_value()) << ')';
145 }
146 else if(expr.id() == ID_array_list)
147 {
148 const auto &array_list_expr = to_multi_ary_expr(expr);
149
150 for(std::size_t i = 0; i < array_list_expr.operands().size(); i += 2)
151 out << "(store ";
152
153 out << "((as const " << smt2_format(expr.type()) << ") "
154 << smt2_format(
155 from_integer(0, to_array_type(expr.type()).element_type()))
156 << ')';
157
158 for(std::size_t i = 0; i < array_list_expr.operands().size(); i += 2)
159 {
161 i < array_list_expr.operands().size() - 1,
162 "array_list has even number of operands");
163 out << ' ' << smt2_format(array_list_expr.operands()[i]) << ' '
164 << smt2_format(array_list_expr.operands()[i + 1]) << ')';
165 }
166 }
167 else
168 out << "? " << expr.id();
169
170 return out;
171}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Pre-defined bitvector types.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Base class for all expressions.
Definition expr.h:56
bool is_true() const
Return whether the expression is a constant representing true.
Definition expr.cpp:27
bool is_false() const
Return whether the expression is a constant representing false.
Definition expr.cpp:34
bool is_constant() const
Return whether the expression is a constant.
Definition expr.h:212
typet & type()
Return the type of the expression.
Definition expr.h:84
std::size_t f
Definition ieee_float.h:26
std::size_t width() const
Definition ieee_float.h:50
std::size_t e
Definition ieee_float.h:26
An IEEE 754 floating-point value, including specificiation.
Definition ieee_float.h:117
bool is_NaN() const
Definition ieee_float.h:259
ieee_float_spect spec
Definition ieee_float.h:119
mp_integer pack() const
bool get_sign() const
Definition ieee_float.h:254
bool is_infinity() const
Definition ieee_float.h:260
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
const irep_idt & id() const
Definition irep.h:388
The type of an expression, extends irept.
Definition type.h:29
static std::string binary(const constant_exprt &src)
const std::string integer2binary(const mp_integer &n, std::size_t width)
Definition mp_arith.cpp:64
std::ostream & smt2_format_rec(std::ostream &out, const typet &type)
static smt2_format_containert< T > smt2_format(const T &_o)
Definition smt2_format.h:28
BigInt mp_integer
Definition smt_terms.h:17
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition std_expr.h:987
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition std_expr.h:3172
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
const with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
Definition std_expr.h:2660
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888