Skip to content

Commit 0b58e31

Browse files
Move utility functions to string_refinement_util
This reduces the size of string_refinement files and seperate functions that could be reused outside of string_refinement, for instace for unit testing.
1 parent 68ecd9e commit 0b58e31

File tree

5 files changed

+123
-107
lines changed

5 files changed

+123
-107
lines changed

src/solvers/refinement/string_refinement.cpp

-101
Original file line numberDiff line numberDiff line change
@@ -287,107 +287,6 @@ static void substitute_function_applications_in_equations(
287287
substitute_function_applications(eq.rhs(), generator);
288288
}
289289

290-
/// For now, any unsigned bitvector type of width smaller or equal to 16 is
291-
/// considered a character.
292-
/// \note type that are not characters maybe detected as characters (for
293-
/// instance unsigned char in C), this will make dec_solve do unnecessary
294-
/// steps for these, but should not affect correctness.
295-
/// \param type: a type
296-
/// \return true if the given type represents characters
297-
bool is_char_type(const typet &type)
298-
{
299-
return type.id() == ID_unsignedbv &&
300-
to_unsignedbv_type(type).get_width() <= 16;
301-
}
302-
303-
/// Distinguish char array from other types.
304-
/// For now, any unsigned bitvector type is considered a character.
305-
/// \param type: a type
306-
/// \param ns: namespace
307-
/// \return true if the given type is an array of characters
308-
bool is_char_array_type(const typet &type, const namespacet &ns)
309-
{
310-
if(type.id()==ID_symbol)
311-
return is_char_array_type(ns.follow(type), ns);
312-
return type.id() == ID_array && is_char_type(type.subtype());
313-
}
314-
315-
/// For now, any unsigned bitvector type is considered a character.
316-
/// \param type: a type
317-
/// \return true if the given type represents a pointer to characters
318-
bool is_char_pointer_type(const typet &type)
319-
{
320-
return type.id() == ID_pointer && is_char_type(type.subtype());
321-
}
322-
323-
/// \param type: a type
324-
/// \param pred: a predicate
325-
/// \return true if one of the subtype of `type` satisfies predicate `pred`.
326-
/// The meaning of "subtype" is in the algebraic datatype sense:
327-
/// for example, the subtypes of a struct are the types of its
328-
/// components, the subtype of a pointer is the type it points to,
329-
/// etc...
330-
/// For instance in the type `t` defined by
331-
/// `{ int a; char[] b; double * c; { bool d} e}`, `int`, `char`,
332-
/// `double` and `bool` are subtypes of `t`.
333-
bool has_subtype(
334-
const typet &type,
335-
const std::function<bool(const typet &)> &pred)
336-
{
337-
if(pred(type))
338-
return true;
339-
340-
if(type.id() == ID_struct || type.id() == ID_union)
341-
{
342-
const struct_union_typet &struct_type = to_struct_union_type(type);
343-
return std::any_of(
344-
struct_type.components().begin(),
345-
struct_type.components().end(), // NOLINTNEXTLINE
346-
[&](const struct_union_typet::componentt &comp) {
347-
return has_subtype(comp.type(), pred);
348-
});
349-
}
350-
351-
return std::any_of( // NOLINTNEXTLINE
352-
type.subtypes().begin(), type.subtypes().end(), [&](const typet &t) {
353-
return has_subtype(t, pred);
354-
});
355-
}
356-
357-
/// \param type: a type
358-
/// \return true if a subtype of `type` is an pointer of characters.
359-
/// The meaning of "subtype" is in the algebraic datatype sense:
360-
/// for example, the subtypes of a struct are the types of its
361-
/// components, the subtype of a pointer is the type it points to,
362-
/// etc...
363-
static bool has_char_pointer_subtype(const typet &type)
364-
{
365-
return has_subtype(type, is_char_pointer_type);
366-
}
367-
368-
/// \param type: a type
369-
/// \return true if a subtype of `type` is string_typet.
370-
/// The meaning of "subtype" is in the algebraic datatype sense:
371-
/// for example, the subtypes of a struct are the types of its
372-
/// components, the subtype of a pointer is the type it points to,
373-
/// etc...
374-
static bool has_string_subtype(const typet &type)
375-
{
376-
// NOLINTNEXTLINE
377-
return has_subtype(
378-
type, [](const typet &subtype) { return subtype == string_typet(); });
379-
}
380-
381-
/// \param expr: an expression
382-
/// \param ns: namespace
383-
/// \return true if a subexpression of `expr` is an array of characters
384-
static bool has_char_array_subexpr(const exprt &expr, const namespacet &ns)
385-
{
386-
for(auto it = expr.depth_begin(); it != expr.depth_end(); ++it)
387-
if(is_char_array_type(it->type(), ns))
388-
return true;
389-
return false;
390-
}
391290

392291
void replace_symbols_in_equations(
393292
const union_find_replacet &symbol_resolve,

src/solvers/refinement/string_refinement.h

-6
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,6 @@ exprt concretize_arrays_in_expression(
9393
std::size_t string_max_length,
9494
const namespacet &ns);
9595

96-
bool is_char_array_type(const typet &type, const namespacet &ns);
97-
98-
bool has_subtype(
99-
const typet &type,
100-
const std::function<bool(const typet &)> &pred);
101-
10296
// Declaration required for unit-test:
10397
union_find_replacet string_identifiers_resolution_from_equations(
10498
std::vector<equal_exprt> &equations,

src/solvers/refinement/string_refinement_util.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,74 @@
1010
#include <numeric>
1111
#include <util/arith_tools.h>
1212
#include <util/std_expr.h>
13+
#include <util/expr_iterator.h>
14+
#include <util/magic.h>
1315
#include "string_refinement_util.h"
1416

17+
bool is_char_type(const typet &type)
18+
{
19+
return type.id() == ID_unsignedbv &&
20+
to_unsignedbv_type(type).get_width() <=
21+
STRING_REFINEMENT_MAX_CHAR_WIDTH;
22+
}
23+
24+
bool is_char_array_type(const typet &type, const namespacet &ns)
25+
{
26+
if(type.id() == ID_symbol)
27+
return is_char_array_type(ns.follow(type), ns);
28+
return type.id() == ID_array && is_char_type(type.subtype());
29+
}
30+
31+
bool is_char_pointer_type(const typet &type)
32+
{
33+
return type.id() == ID_pointer && is_char_type(type.subtype());
34+
}
35+
36+
bool has_subtype(
37+
const typet &type,
38+
const std::function<bool(const typet &)> &pred)
39+
{
40+
if(pred(type))
41+
return true;
42+
43+
if(type.id() == ID_struct || type.id() == ID_union)
44+
{
45+
const struct_union_typet &struct_type = to_struct_union_type(type);
46+
return std::any_of(
47+
struct_type.components().begin(),
48+
struct_type.components().end(), // NOLINTNEXTLINE
49+
[&](const struct_union_typet::componentt &comp) {
50+
return has_subtype(comp.type(), pred);
51+
});
52+
}
53+
54+
return std::any_of( // NOLINTNEXTLINE
55+
type.subtypes().begin(), type.subtypes().end(), [&](const typet &t) {
56+
return has_subtype(t, pred);
57+
});
58+
}
59+
60+
bool has_char_pointer_subtype(const typet &type)
61+
{
62+
return has_subtype(type, is_char_pointer_type);
63+
}
64+
65+
bool has_string_subtype(const typet &type)
66+
{
67+
// NOLINTNEXTLINE
68+
return has_subtype(
69+
type, [](const typet &subtype) { return subtype == string_typet(); });
70+
}
71+
72+
bool has_char_array_subexpr(const exprt &expr, const namespacet &ns)
73+
{
74+
const auto it = std::find_if(
75+
expr.depth_begin(), expr.depth_end(), [&](const exprt &e) { // NOLINT
76+
return is_char_array_type(e.type(), ns);
77+
});
78+
return it != expr.depth_end();
79+
}
80+
1581
sparse_arrayt::sparse_arrayt(const with_exprt &expr)
1682
{
1783
auto ref = std::ref(static_cast<const exprt &>(expr));

src/solvers/refinement/string_refinement_util.h

+56
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,62 @@
1111

1212
#include "string_constraint.h"
1313

14+
/// For now, any unsigned bitvector type of width smaller or equal to 16 is
15+
/// considered a character.
16+
/// \note type that are not characters maybe detected as characters (for
17+
/// instance unsigned char in C), this will make dec_solve do unnecessary
18+
/// steps for these, but should not affect correctness.
19+
/// \param type: a type
20+
/// \return true if the given type represents characters
21+
bool is_char_type(const typet &type);
22+
23+
/// Distinguish char array from other types.
24+
/// For now, any unsigned bitvector type is considered a character.
25+
/// \param type: a type
26+
/// \param ns: namespace
27+
/// \return true if the given type is an array of characters
28+
bool is_char_array_type(const typet &type, const namespacet &ns);
29+
30+
/// For now, any unsigned bitvector type is considered a character.
31+
/// \param type: a type
32+
/// \return true if the given type represents a pointer to characters
33+
bool is_char_pointer_type(const typet &type);
34+
35+
/// \param type: a type
36+
/// \param pred: a predicate
37+
/// \return true if one of the subtype of `type` satisfies predicate `pred`.
38+
/// The meaning of "subtype" is in the algebraic datatype sense:
39+
/// for example, the subtypes of a struct are the types of its
40+
/// components, the subtype of a pointer is the type it points to,
41+
/// etc...
42+
/// For instance in the type `t` defined by
43+
/// `{ int a; char[] b; double * c; { bool d} e}`, `int`, `char`,
44+
/// `double` and `bool` are subtypes of `t`.
45+
bool has_subtype(
46+
const typet &type,
47+
const std::function<bool(const typet &)> &pred);
48+
49+
/// \param type: a type
50+
/// \return true if a subtype of `type` is an pointer of characters.
51+
/// The meaning of "subtype" is in the algebraic datatype sense:
52+
/// for example, the subtypes of a struct are the types of its
53+
/// components, the subtype of a pointer is the type it points to,
54+
/// etc...
55+
bool has_char_pointer_subtype(const typet &type);
56+
57+
/// \param type: a type
58+
/// \return true if a subtype of `type` is string_typet.
59+
/// The meaning of "subtype" is in the algebraic datatype sense:
60+
/// for example, the subtypes of a struct are the types of its
61+
/// components, the subtype of a pointer is the type it points to,
62+
/// etc...
63+
bool has_string_subtype(const typet &type);
64+
65+
/// \param expr: an expression
66+
/// \param ns: namespace
67+
/// \return true if a subexpression of `expr` is an array of characters
68+
bool has_char_array_subexpr(const exprt &expr, const namespacet &ns);
69+
1470
struct index_set_pairt
1571
{
1672
std::map<exprt, std::set<exprt>> cumulative;

src/util/magic.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
#include <cstddef>
99

1010
const std::size_t MAX_FLATTENED_ARRAY_SIZE=1000;
11+
const std::size_t STRING_REFINEMENT_MAX_CHAR_WIDTH = 16;
1112

1213
#endif

0 commit comments

Comments
 (0)