7
7
#include < vector>
8
8
#include < util/optional.h>
9
9
#include < util/string_expr.h>
10
+ #include " string_constraint_generator.h"
10
11
11
12
class array_poolt ;
12
13
@@ -32,8 +33,33 @@ class string_builtin_functiont
32
33
33
34
virtual std::string name () const = 0;
34
35
35
- protected:
36
+ // / Add constraints ensuring that the value of result expression of the
37
+ // / builtin function corresponds to the value of the function call.
38
+ virtual exprt
39
+ add_constraints (string_constraint_generatort &constraint_generator) const = 0 ;
40
+
41
+ // / Constraint ensuring that the length of the strings are coherent with
42
+ // / the function call.
43
+ virtual exprt length_constraint () const = 0;
44
+
45
+ exprt return_code;
46
+
47
+ // / Tells whether the builtin function can be a testing function, that is a
48
+ // / function that does not return a string, for instance like `equals`,
49
+ // / `indexOf` or `compare`.
50
+ virtual bool maybe_testing_function () const
51
+ {
52
+ return true ;
53
+ }
54
+
55
+ private:
36
56
string_builtin_functiont () = default ;
57
+
58
+ protected:
59
+ explicit string_builtin_functiont (const exprt &return_code)
60
+ : return_code(return_code)
61
+ {
62
+ }
37
63
};
38
64
39
65
// / String builtin_function transforming one string into another
@@ -43,14 +69,14 @@ class string_transformation_builtin_functiont : public string_builtin_functiont
43
69
array_string_exprt result;
44
70
array_string_exprt input;
45
71
std::vector<exprt> args;
46
- exprt return_code;
47
72
48
73
// / Constructor from arguments of a function application.
49
74
// / The arguments in `fun_args` should be in order:
50
75
// / an integer `result.length`, a character pointer `&result[0]`,
51
76
// / a string `arg1` of type refined_string_typet, and potentially some
52
77
// / arguments of primitive types.
53
78
string_transformation_builtin_functiont (
79
+ const exprt &return_code,
54
80
const std::vector<exprt> &fun_args,
55
81
array_poolt &array_pool);
56
82
@@ -70,6 +96,11 @@ class string_transformation_builtin_functiont : public string_builtin_functiont
70
96
71
97
optionalt<exprt>
72
98
eval (const std::function<exprt(const exprt &)> &get_value) const override ;
99
+
100
+ bool maybe_testing_function () const override
101
+ {
102
+ return false ;
103
+ }
73
104
};
74
105
75
106
// / Adding a character at the end of a string
@@ -82,9 +113,10 @@ class string_concat_char_builtin_functiont
82
113
// / an integer `result.length`, a character pointer `&result[0]`,
83
114
// / a string `arg1` of type refined_string_typet, and a character.
84
115
string_concat_char_builtin_functiont (
116
+ const exprt &return_code,
85
117
const std::vector<exprt> &fun_args,
86
118
array_poolt &array_pool)
87
- : string_transformation_builtin_functiont(fun_args, array_pool)
119
+ : string_transformation_builtin_functiont(return_code, fun_args, array_pool)
88
120
{
89
121
}
90
122
@@ -96,6 +128,16 @@ class string_concat_char_builtin_functiont
96
128
{
97
129
return " concat_char" ;
98
130
}
131
+
132
+ exprt add_constraints (string_constraint_generatort &generator) const override
133
+ {
134
+ return generator.add_axioms_for_concat_char (result, input, args[0 ]);
135
+ }
136
+
137
+ exprt length_constraint () const override
138
+ {
139
+ return length_constraint_for_concat_char (result, input);
140
+ }
99
141
};
100
142
101
143
// / String inserting a string into another one
@@ -106,7 +148,6 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
106
148
array_string_exprt input1;
107
149
array_string_exprt input2;
108
150
std::vector<exprt> args;
109
- exprt return_code;
110
151
111
152
// / Constructor from arguments of a function application.
112
153
// / The arguments in `fun_args` should be in order:
@@ -115,6 +156,7 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
115
156
// / a string `arg2` of type refined_string_typet,
116
157
// / and potentially some arguments of primitive types.
117
158
string_insertion_builtin_functiont (
159
+ const exprt &return_code,
118
160
const std::vector<exprt> &fun_args,
119
161
array_poolt &array_pool);
120
162
@@ -141,8 +183,34 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
141
183
return " insert" ;
142
184
}
143
185
186
+ exprt add_constraints (string_constraint_generatort &generator) const override
187
+ {
188
+ if (args.size () == 1 )
189
+ return generator.add_axioms_for_insert (result, input1, input2, args[0 ]);
190
+ if (args.size () == 3 )
191
+ UNIMPLEMENTED;
192
+ UNREACHABLE;
193
+ };
194
+
195
+ exprt length_constraint () const override
196
+ {
197
+ if (args.size () == 1 )
198
+ return length_constraint_for_insert (result, input1, input2, args[0 ]);
199
+ if (args.size () == 3 )
200
+ UNIMPLEMENTED;
201
+ UNREACHABLE;
202
+ };
203
+
204
+ bool maybe_testing_function () const override
205
+ {
206
+ return false ;
207
+ }
208
+
144
209
protected:
145
- string_insertion_builtin_functiont () = default ;
210
+ explicit string_insertion_builtin_functiont (const exprt &return_code)
211
+ : string_builtin_functiont(return_code)
212
+ {
213
+ }
146
214
};
147
215
148
216
class string_concatenation_builtin_functiont final
@@ -156,6 +224,7 @@ class string_concatenation_builtin_functiont final
156
224
// / a string `arg2` of type refined_string_typet,
157
225
// / optionally followed by an integer `start` and an integer `end`.
158
226
string_concatenation_builtin_functiont (
227
+ const exprt &return_code,
159
228
const std::vector<exprt> &fun_args,
160
229
array_poolt &array_pool);
161
230
@@ -168,6 +237,26 @@ class string_concatenation_builtin_functiont final
168
237
{
169
238
return " concat" ;
170
239
}
240
+
241
+ exprt add_constraints (string_constraint_generatort &generator) const override
242
+ {
243
+ if (args.size () == 0 )
244
+ return generator.add_axioms_for_concat (result, input1, input2);
245
+ if (args.size () == 2 )
246
+ return generator.add_axioms_for_concat_substr (
247
+ result, input1, input2, args[0 ], args[1 ]);
248
+ UNREACHABLE;
249
+ };
250
+
251
+ exprt length_constraint () const override
252
+ {
253
+ if (args.size () == 0 )
254
+ return length_constraint_for_concat (result, input1, input2);
255
+ if (args.size () == 2 )
256
+ return length_constraint_for_concat_substr (
257
+ result, input1, input2, args[0 ], args[1 ]);
258
+ UNREACHABLE;
259
+ }
171
260
};
172
261
173
262
// / String creation from other types
@@ -182,6 +271,11 @@ class string_creation_builtin_functiont : public string_builtin_functiont
182
271
{
183
272
return result;
184
273
}
274
+
275
+ bool maybe_testing_function () const override
276
+ {
277
+ return false ;
278
+ }
185
279
};
186
280
187
281
// / String test
@@ -197,4 +291,53 @@ class string_test_builtin_functiont : public string_builtin_functiont
197
291
}
198
292
};
199
293
294
+ // / Functions that are not yet supported in this class but are supported by
295
+ // / string_constraint_generatort.
296
+ // / \note Ultimately this should be disappear, once all builtin function have
297
+ // / a corresponding string_builtin_functiont class.
298
+ class string_builtin_function_with_no_evalt : public string_builtin_functiont
299
+ {
300
+ public:
301
+ function_application_exprt function_application;
302
+ optionalt<array_string_exprt> string_res;
303
+ std::vector<array_string_exprt> string_args;
304
+ std::vector<exprt> args;
305
+
306
+ string_builtin_function_with_no_evalt (
307
+ const exprt &return_code,
308
+ const function_application_exprt &f,
309
+ array_poolt &array_pool);
310
+
311
+ std::string name () const override
312
+ {
313
+ return id2string (function_application.function ().get_identifier ());
314
+ }
315
+ std::vector<array_string_exprt> string_arguments () const override
316
+ {
317
+ return std::vector<array_string_exprt>(string_args);
318
+ }
319
+ optionalt<array_string_exprt> string_result () const override
320
+ {
321
+ return string_res;
322
+ }
323
+
324
+ optionalt<exprt>
325
+ eval (const std::function<exprt(const exprt &)> &get_value) const override
326
+ {
327
+ return {};
328
+ }
329
+
330
+ exprt add_constraints (string_constraint_generatort &generator) const override
331
+ {
332
+ return generator.add_axioms_for_function_application (function_application);
333
+ };
334
+
335
+ exprt length_constraint () const override
336
+ {
337
+ // For now, there is no need for implementing that as `add_constraints`
338
+ // should always be called on these functions
339
+ UNIMPLEMENTED;
340
+ }
341
+ };
342
+
200
343
#endif // CPROVER_SOLVERS_REFINEMENT_STRING_BUILTIN_FUNCTION_H
0 commit comments