Skip to content

Commit e2961b5

Browse files
Add builtin class for string_to_upper_case
1 parent fe9071b commit e2961b5

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

src/solvers/refinement/string_builtin_function.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ exprt string_set_char_builtin_functiont::length_constraint() const
187187
equal_exprt(return_code, return_value));
188188
}
189189

190+
static bool eval_is_upper_case(const mp_integer &c)
191+
{
192+
return ('A' <= c && c <= 'Z') || (0xc0 <= c && c <= 0xd6) ||
193+
(0xd8 <= c && c <= 0xde);
194+
}
195+
190196
optionalt<exprt> string_to_lower_case_builtin_functiont::eval(
191197
const std::function<exprt(const exprt &)> &get_value) const
192198
{
@@ -195,9 +201,7 @@ optionalt<exprt> string_to_lower_case_builtin_functiont::eval(
195201
return {};
196202
for(mp_integer &c : input_opt.value())
197203
{
198-
if(
199-
('A' <= c && c <= 'Z') || (0xc0 <= c && c <= 0xd6) ||
200-
(0xd8 <= c && c <= 0xde))
204+
if(eval_is_upper_case(c))
201205
c += 0x20;
202206
}
203207
const auto length =
@@ -206,6 +210,23 @@ optionalt<exprt> string_to_lower_case_builtin_functiont::eval(
206210
return make_string(input_opt.value(), type);
207211
}
208212

213+
optionalt<exprt> string_to_upper_case_builtin_functiont::eval(
214+
const std::function<exprt(const exprt &)> &get_value) const
215+
{
216+
auto input_opt = eval_string(input, get_value);
217+
if(!input_opt)
218+
return {};
219+
for(mp_integer &c : input_opt.value())
220+
{
221+
if(eval_is_upper_case(c - 0x20))
222+
c -= 0x20;
223+
}
224+
const auto length =
225+
from_integer(input_opt.value().size(), result.length().type());
226+
const array_typet type(result.type().subtype(), length);
227+
return make_string(input_opt.value(), type);
228+
}
229+
209230
std::vector<mp_integer> string_insertion_builtin_functiont::eval(
210231
const std::vector<mp_integer> &input1_value,
211232
const std::vector<mp_integer> &input2_value,

src/solvers/refinement/string_builtin_function.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,39 @@ class string_to_lower_case_builtin_functiont
210210
};
211211
};
212212

213+
/// Converting each lowercase character of Basic Latin and Latin-1 supplement
214+
/// to the corresponding uppercase character.
215+
class string_to_upper_case_builtin_functiont
216+
: public string_transformation_builtin_functiont
217+
{
218+
public:
219+
string_to_upper_case_builtin_functiont(
220+
const exprt &return_code,
221+
const std::vector<exprt> &fun_args,
222+
array_poolt &array_pool)
223+
: string_transformation_builtin_functiont(return_code, fun_args, array_pool)
224+
{
225+
}
226+
227+
optionalt<exprt>
228+
eval(const std::function<exprt(const exprt &)> &get_value) const override;
229+
230+
std::string name() const override
231+
{
232+
return "to_upper_case";
233+
}
234+
235+
exprt add_constraints(string_constraint_generatort &generator) const override
236+
{
237+
return generator.add_axioms_for_to_upper_case(result, input);
238+
};
239+
240+
exprt length_constraint() const override
241+
{
242+
return equal_exprt(result.length(), input.length());
243+
};
244+
};
245+
213246
/// String inserting a string into another one
214247
class string_insertion_builtin_functiont : public string_builtin_functiont
215248
{

src/solvers/refinement/string_constraint_generator.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ class string_constraint_generatort final
178178
exprt add_axioms_for_to_lower_case(
179179
const array_string_exprt &res,
180180
const array_string_exprt &str);
181+
exprt add_axioms_for_to_upper_case(
182+
const array_string_exprt &res,
183+
const array_string_exprt &expr);
181184

182185
private:
183186
symbol_exprt fresh_boolean(const irep_idt &prefix);
@@ -338,9 +341,6 @@ class string_constraint_generatort final
338341
exprt add_axioms_for_substring(const function_application_exprt &f);
339342
exprt add_axioms_for_to_lower_case(const function_application_exprt &f);
340343
exprt add_axioms_for_to_upper_case(const function_application_exprt &f);
341-
exprt add_axioms_for_to_upper_case(
342-
const array_string_exprt &res,
343-
const array_string_exprt &expr);
344344
exprt add_axioms_for_trim(const function_application_exprt &f);
345345

346346
exprt add_axioms_for_code_point(

src/solvers/refinement/string_refinement_util.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ static std::unique_ptr<string_builtin_functiont> to_string_builtin_function(
236236
return util_make_unique<string_to_lower_case_builtin_functiont>(
237237
return_code, fun_app.arguments(), array_pool);
238238

239+
if(id == ID_cprover_string_to_upper_case_func)
240+
return util_make_unique<string_to_upper_case_builtin_functiont>(
241+
return_code, fun_app.arguments(), array_pool);
242+
239243
return util_make_unique<string_builtin_function_with_no_evalt>(
240244
return_code, fun_app, array_pool);
241245
}

0 commit comments

Comments
 (0)