13
13
14
14
#include < solvers/refinement/string_constraint_generator.h>
15
15
16
- // / add axioms to say that the returned string expression is equal to the
17
- // / concatenation of the two string expressions given as input
18
- // / \par parameters: two string expressions
16
+ // / Add axioms to say that the returned string expression is equal to the
17
+ // / concatenation of s1 with the substring of s2 starting at index start_index
18
+ // / and ending at index end_index.
19
+ // /
20
+ // / If start_index >= end_index, the value returned is s1.
21
+ // / If end_index > |s2| and/or start_index < 0, the appended string will be of
22
+ // / length end_index - start_index and padded with non-deterministic values.
23
+ // /
24
+ // / \param s1: string expression
25
+ // / \param s2: string expression
26
+ // / \param start_index: expression representing an integer
27
+ // / \param end_index: expression representing an integer
19
28
// / \return a new string expression
20
- string_exprt string_constraint_generatort::add_axioms_for_concat (
21
- const string_exprt &s1, const string_exprt &s2)
29
+ string_exprt string_constraint_generatort::add_axioms_for_concat_substr (
30
+ const string_exprt &s1,
31
+ const string_exprt &s2,
32
+ const exprt &start_index,
33
+ const exprt &end_index)
22
34
{
23
35
const refined_string_typet &ref_type=to_refined_string_type (s1.type ());
24
36
string_exprt res=fresh_string (ref_type);
25
37
26
38
// We add axioms:
27
- // a1 : |res|=|s1|+|s2|
28
- // a2 : |s1| <= |res| (to avoid overflow with very long strings)
29
- // a3 : |s2| <= |res| (to avoid overflow with very long strings)
30
- // a4 : forall i<|s1|. res[i]=s1[i]
31
- // a5 : forall i<|s2|. res[i+|s1|]=s2[i]
32
-
33
- equal_exprt a1 (
34
- res.length (), plus_exprt_with_overflow_check (s1.length (), s2.length ()));
39
+ // a1 : end_index > start_index => |res|=|s1|+ end_index - start_index
40
+ // a2 : end_index <= start_index => res = s1
41
+ // a3 : forall i<|s1|. res[i]=s1[i]
42
+ // a4 : forall i< end_index - start_index. res[i+|s1|]=s2[start_index+i]
43
+
44
+ binary_relation_exprt prem (end_index, ID_gt, start_index);
45
+
46
+ exprt res_length=plus_exprt_with_overflow_check (
47
+ s1.length (), minus_exprt (end_index, start_index));
48
+ implies_exprt a1 (prem, equal_exprt (res.length (), res_length));
35
49
axioms.push_back (a1);
36
- axioms.push_back (s1.axiom_for_is_shorter_than (res));
37
- axioms.push_back (s2.axiom_for_is_shorter_than (res));
50
+
51
+ implies_exprt a2 (not_exprt (prem), equal_exprt (res.length (), s1.length ()));
52
+ axioms.push_back (a2);
38
53
39
54
symbol_exprt idx=fresh_univ_index (" QA_index_concat" , res.length ().type ());
40
- string_constraintt a4 (idx, s1.length (), equal_exprt (s1[idx], res[idx]));
41
- axioms.push_back (a4 );
55
+ string_constraintt a3 (idx, s1.length (), equal_exprt (s1[idx], res[idx]));
56
+ axioms.push_back (a3 );
42
57
43
58
symbol_exprt idx2=fresh_univ_index (" QA_index_concat2" , res.length ().type ());
44
- equal_exprt res_eq (s2[idx2], res[plus_exprt (idx2, s1.length ())]);
45
- string_constraintt a5 (idx2, s2.length (), res_eq);
46
- axioms.push_back (a5);
59
+ equal_exprt res_eq (
60
+ res[plus_exprt (idx2, s1.length ())], s2[plus_exprt (start_index, idx2)]);
61
+ string_constraintt a4 (idx2, minus_exprt (end_index, start_index), res_eq);
62
+ axioms.push_back (a4);
47
63
48
64
return res;
49
65
}
50
66
51
- // / add axioms to say that the returned string expression is equal to the
52
- // / concatenation of the two string arguments of the function application
53
- // / \par parameters: function application with two arguments which are strings
67
+ // / Add axioms to say that the returned string expression is equal to the
68
+ // / concatenation of the two string expressions given as input.
69
+ // /
70
+ // / \param s1: the string expression to append to
71
+ // / \param s2: the string expression to append to the first one
72
+ // / \return a new string expression
73
+ string_exprt string_constraint_generatort::add_axioms_for_concat (
74
+ const string_exprt &s1, const string_exprt &s2)
75
+ {
76
+ exprt index_zero=from_integer (0 , s2.length ().type ());
77
+ return add_axioms_for_concat_substr (s1, s2, index_zero, s2.length ());
78
+ }
79
+
80
+ // / Add axioms to say that the returned string expression is equal to the
81
+ // / concatenation of the two string arguments of the function application.
82
+ // /
83
+ // / In case 4 arguments instead of 2 are given the last two arguments are
84
+ // / intepreted as a start index and last index from which we extract a substring
85
+ // / of the second argument: this is similar to the Java
86
+ // / StringBuilder.append(CharSequence s, int start, int end) method.
87
+ // /
88
+ // / \param f: function application with two arguments which are strings
54
89
// / \return a new string expression
55
90
string_exprt string_constraint_generatort::add_axioms_for_concat (
56
91
const function_application_exprt &f)
57
92
{
58
93
const function_application_exprt::argumentst &args=f.arguments ();
59
- assert (args.size ()==2 );
60
-
94
+ PRECONDITION (args.size ()>=2 );
61
95
string_exprt s1=get_string_expr (args[0 ]);
62
96
string_exprt s2=get_string_expr (args[1 ]);
63
-
97
+ if (args.size ()!=2 )
98
+ {
99
+ PRECONDITION (args.size ()==4 );
100
+ return add_axioms_for_concat_substr (s1, s2, args[2 ], args[3 ]);
101
+ }
64
102
return add_axioms_for_concat (s1, s2);
65
103
}
66
104
67
- // / add axioms corresponding to the StringBuilder.append(I) java function
68
- // / \par parameters : function application with two arguments: a string and an
69
- // / integer
105
+ // / Add axioms corresponding to the StringBuilder.append(I) java function
106
+ // / \param f : function application with two arguments: a string and an
107
+ // / integer
70
108
// / \return a new string expression
71
109
string_exprt string_constraint_generatort::add_axioms_for_concat_int (
72
110
const function_application_exprt &f)
@@ -79,8 +117,8 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_int(
79
117
}
80
118
81
119
// / Add axioms corresponding to the StringBuilder.append(J) java function
82
- // / \par parameters : function application with two arguments: a string and a
83
- // / integer of type long
120
+ // / \param f : function application with two arguments: a string and an
121
+ // / integer of type long
84
122
// / \return a new string expression
85
123
string_exprt string_constraint_generatort::add_axioms_for_concat_long (
86
124
const function_application_exprt &f)
@@ -91,8 +129,8 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_long(
91
129
return add_axioms_for_concat (s1, s2);
92
130
}
93
131
94
- // / add axioms corresponding to the StringBuilder.append(Z) java function
95
- // / \par parameters : function application two arguments: a string and a bool
132
+ // / Add axioms corresponding to the StringBuilder.append(Z) java function
133
+ // / \param f : function application two arguments: a string and a bool
96
134
// / \return a new string expression
97
135
string_exprt string_constraint_generatort::add_axioms_for_concat_bool (
98
136
const function_application_exprt &f)
@@ -103,9 +141,8 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_bool(
103
141
return add_axioms_for_concat (s1, s2);
104
142
}
105
143
106
- // / add axioms corresponding to the StringBuilder.append(C) java function
107
- // / \par parameters: function application with two arguments: a string and a
108
- // / char
144
+ // / Add axioms corresponding to the StringBuilder.append(C) java function
145
+ // / \param f: function application with two arguments: a string and a char
109
146
// / \return a new string expression
110
147
string_exprt string_constraint_generatort::add_axioms_for_concat_char (
111
148
const function_application_exprt &f)
@@ -116,37 +153,34 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_char(
116
153
return add_axioms_for_concat (s1, s2);
117
154
}
118
155
119
- // / add axioms corresponding to the StringBuilder.append(D) java function
120
- // / \par parameters: function application with two arguments: a string and a
121
- // / double
156
+ // / Add axioms corresponding to the StringBuilder.append(D) java function
157
+ // / \param f: function application with two arguments: a string and a double
122
158
// / \return a new string expression
123
159
string_exprt string_constraint_generatort::add_axioms_for_concat_double (
124
160
const function_application_exprt &f)
125
161
{
126
162
string_exprt s1=get_string_expr (args (f, 2 )[0 ]);
127
- assert (refined_string_typet::is_refined_string_type (f.type ()));
163
+ PRECONDITION (refined_string_typet::is_refined_string_type (f.type ()));
128
164
refined_string_typet ref_type=to_refined_string_type (f.type ());
129
165
string_exprt s2=add_axioms_from_float (args (f, 2 )[1 ], ref_type, true );
130
166
return add_axioms_for_concat (s1, s2);
131
167
}
132
168
133
- // / add axioms corresponding to the StringBuilder.append(F) java function
134
- // / \par parameters: function application with two arguments: a string and a
135
- // / float
169
+ // / Add axioms corresponding to the StringBuilder.append(F) java function
170
+ // / \param f: function application with two arguments: a string and a float
136
171
// / \return a new string expression
137
172
string_exprt string_constraint_generatort::add_axioms_for_concat_float (
138
173
const function_application_exprt &f)
139
174
{
140
175
string_exprt s1=get_string_expr (args (f, 2 )[0 ]);
141
- assert (refined_string_typet::is_refined_string_type (f.type ()));
176
+ PRECONDITION (refined_string_typet::is_refined_string_type (f.type ()));
142
177
refined_string_typet ref_type=to_refined_string_type (f.type ());
143
178
string_exprt s2=add_axioms_from_float (args (f, 2 )[1 ], ref_type, false );
144
179
return add_axioms_for_concat (s1, s2);
145
180
}
146
181
147
182
// / Add axioms corresponding to the StringBuilder.appendCodePoint(I) function
148
- // / \par parameters: function application with two arguments: a string and a
149
- // / code point
183
+ // / \param f: function application with two arguments: a string and a code point
150
184
// / \return a new string expression
151
185
string_exprt string_constraint_generatort::add_axioms_for_concat_code_point (
152
186
const function_application_exprt &f)
0 commit comments