@@ -29,33 +29,6 @@ string_transformation_builtin_functiont::
29
29
const auto arg1 = expr_checked_cast<struct_exprt>(fun_args[2 ]);
30
30
input = array_pool.find (arg1.op1 (), arg1.op0 ());
31
31
result = array_pool.find (fun_args[1 ], fun_args[0 ]);
32
- args.insert (args.end (), fun_args.begin () + 3 , fun_args.end ());
33
- }
34
-
35
- optionalt<exprt> string_transformation_builtin_functiont::eval (
36
- const std::function<exprt(const exprt &)> &get_value) const
37
- {
38
- const auto &input_value = eval_string (input, get_value);
39
- if (!input_value.has_value ())
40
- return {};
41
-
42
- std::vector<mp_integer> arg_values;
43
- const auto &insert = std::back_inserter (arg_values);
44
- const mp_integer unknown (' ?' );
45
- std::transform (
46
- args.begin (), args.end (), insert, [&](const exprt &e) { // NOLINT
47
- if (const auto val = numeric_cast<mp_integer>(get_value (e)))
48
- return *val;
49
- INVARIANT (
50
- get_value (e).id () == ID_unknown,
51
- " array valuation should only contain constants and unknown" );
52
- return unknown;
53
- });
54
-
55
- const auto result_value = eval (*input_value, arg_values);
56
- const auto length = from_integer (result_value.size (), result.length ().type ());
57
- const array_typet type (result.type ().subtype (), length);
58
- return make_string (result_value, type);
59
32
}
60
33
61
34
string_insertion_builtin_functiont::string_insertion_builtin_functiont (
@@ -162,14 +135,56 @@ std::vector<mp_integer> string_concatenation_builtin_functiont::eval(
162
135
return result;
163
136
}
164
137
165
- std::vector<mp_integer> string_concat_char_builtin_functiont::eval (
166
- const std::vector<mp_integer> &input_value,
167
- const std::vector<mp_integer> &args_value) const
138
+ optionalt<exprt> string_concat_char_builtin_functiont::eval (
139
+ const std::function<exprt(const exprt &)> &get_value) const
168
140
{
169
- PRECONDITION (args_value.size () == 1 );
170
- std::vector<mp_integer> result (input_value);
171
- result.push_back (args_value[0 ]);
172
- return result;
141
+ auto input_opt = eval_string (input, get_value);
142
+ if (!input_opt.has_value ())
143
+ return {};
144
+ const mp_integer char_val = [&] {
145
+ if (const auto val = numeric_cast<mp_integer>(get_value (character)))
146
+ return *val;
147
+ INVARIANT (
148
+ get_value (character).id () == ID_unknown,
149
+ " character valuation should only contain constants and unknown" );
150
+ return mp_integer (CHARACTER_FOR_UNKNOWN);
151
+ }();
152
+ input_opt.value ().push_back (char_val);
153
+ const auto length =
154
+ from_integer (input_opt.value ().size (), result.length ().type ());
155
+ const array_typet type (result.type ().subtype (), length);
156
+ return make_string (input_opt.value (), type);
157
+ }
158
+
159
+ optionalt<exprt> string_set_char_builtin_functiont::eval (
160
+ const std::function<exprt(const exprt &)> &get_value) const
161
+ {
162
+ auto input_opt = eval_string (input, get_value);
163
+ const auto char_opt = numeric_cast<mp_integer>(get_value (character));
164
+ const auto position_opt = numeric_cast<mp_integer>(get_value (position));
165
+ if (!input_opt || !char_opt || !position_opt)
166
+ return {};
167
+ if (0 <= *position_opt && *position_opt < input_opt.value ().size ())
168
+ input_opt.value ()[numeric_cast_v<std::size_t >(*position_opt)] = *char_opt;
169
+ const auto length =
170
+ from_integer (input_opt.value ().size (), result.length ().type ());
171
+ const array_typet type (result.type ().subtype (), length);
172
+ return make_string (input_opt.value (), type);
173
+ }
174
+
175
+ exprt string_set_char_builtin_functiont::length_constraint () const
176
+ {
177
+ const exprt out_of_bounds = or_exprt (
178
+ binary_relation_exprt (position, ID_ge, input.length ()),
179
+ binary_relation_exprt (
180
+ position, ID_le, from_integer (0 , input.length ().type ())));
181
+ const exprt return_value = if_exprt (
182
+ out_of_bounds,
183
+ from_integer (1 , return_code.type ()),
184
+ from_integer (0 , return_code.type ()));
185
+ return and_exprt (
186
+ equal_exprt (result.length (), input.length ()),
187
+ equal_exprt (return_code, return_value));
173
188
}
174
189
175
190
std::vector<mp_integer> string_insertion_builtin_functiont::eval (
0 commit comments