77#include < vector>
88#include < util/optional.h>
99#include < util/string_expr.h>
10+ #include " string_constraint_generator.h"
1011
1112class array_poolt ;
1213
@@ -32,8 +33,33 @@ class string_builtin_functiont
3233
3334 virtual std::string name () const = 0;
3435
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:
3656 string_builtin_functiont () = default ;
57+
58+ protected:
59+ explicit string_builtin_functiont (const exprt &return_code)
60+ : return_code(return_code)
61+ {
62+ }
3763};
3864
3965// / String builtin_function transforming one string into another
@@ -43,14 +69,14 @@ class string_transformation_builtin_functiont : public string_builtin_functiont
4369 array_string_exprt result;
4470 array_string_exprt input;
4571 std::vector<exprt> args;
46- exprt return_code;
4772
4873 // / Constructor from arguments of a function application.
4974 // / The arguments in `fun_args` should be in order:
5075 // / an integer `result.length`, a character pointer `&result[0]`,
5176 // / a string `arg1` of type refined_string_typet, and potentially some
5277 // / arguments of primitive types.
5378 string_transformation_builtin_functiont (
79+ const exprt &return_code,
5480 const std::vector<exprt> &fun_args,
5581 array_poolt &array_pool);
5682
@@ -70,6 +96,11 @@ class string_transformation_builtin_functiont : public string_builtin_functiont
7096
7197 optionalt<exprt>
7298 eval (const std::function<exprt(const exprt &)> &get_value) const override ;
99+
100+ bool maybe_testing_function () const override
101+ {
102+ return false ;
103+ }
73104};
74105
75106// / Adding a character at the end of a string
@@ -82,9 +113,10 @@ class string_concat_char_builtin_functiont
82113 // / an integer `result.length`, a character pointer `&result[0]`,
83114 // / a string `arg1` of type refined_string_typet, and a character.
84115 string_concat_char_builtin_functiont (
116+ const exprt &return_code,
85117 const std::vector<exprt> &fun_args,
86118 array_poolt &array_pool)
87- : string_transformation_builtin_functiont(fun_args, array_pool)
119+ : string_transformation_builtin_functiont(return_code, fun_args, array_pool)
88120 {
89121 }
90122
@@ -96,6 +128,16 @@ class string_concat_char_builtin_functiont
96128 {
97129 return " concat_char" ;
98130 }
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+ }
99141};
100142
101143// / String inserting a string into another one
@@ -106,7 +148,6 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
106148 array_string_exprt input1;
107149 array_string_exprt input2;
108150 std::vector<exprt> args;
109- exprt return_code;
110151
111152 // / Constructor from arguments of a function application.
112153 // / The arguments in `fun_args` should be in order:
@@ -115,6 +156,7 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
115156 // / a string `arg2` of type refined_string_typet,
116157 // / and potentially some arguments of primitive types.
117158 string_insertion_builtin_functiont (
159+ const exprt &return_code,
118160 const std::vector<exprt> &fun_args,
119161 array_poolt &array_pool);
120162
@@ -141,8 +183,34 @@ class string_insertion_builtin_functiont : public string_builtin_functiont
141183 return " insert" ;
142184 }
143185
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+
144209protected:
145- string_insertion_builtin_functiont () = default ;
210+ explicit string_insertion_builtin_functiont (const exprt &return_code)
211+ : string_builtin_functiont(return_code)
212+ {
213+ }
146214};
147215
148216class string_concatenation_builtin_functiont final
@@ -156,6 +224,7 @@ class string_concatenation_builtin_functiont final
156224 // / a string `arg2` of type refined_string_typet,
157225 // / optionally followed by an integer `start` and an integer `end`.
158226 string_concatenation_builtin_functiont (
227+ const exprt &return_code,
159228 const std::vector<exprt> &fun_args,
160229 array_poolt &array_pool);
161230
@@ -168,6 +237,26 @@ class string_concatenation_builtin_functiont final
168237 {
169238 return " concat" ;
170239 }
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+ }
171260};
172261
173262// / String creation from other types
@@ -182,6 +271,11 @@ class string_creation_builtin_functiont : public string_builtin_functiont
182271 {
183272 return result;
184273 }
274+
275+ bool maybe_testing_function () const override
276+ {
277+ return false ;
278+ }
185279};
186280
187281// / String test
@@ -197,4 +291,53 @@ class string_test_builtin_functiont : public string_builtin_functiont
197291 }
198292};
199293
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+
200343#endif // CPROVER_SOLVERS_REFINEMENT_STRING_BUILTIN_FUNCTION_H
0 commit comments