Skip to content

Commit 3cb7bca

Browse files
romainbrenguierRomain Brenguier
authored and
Romain Brenguier
committed
Cleaning dependencies of the string solver
`src/util` is a more appropriate place for the `string_exprt` class We changed the constructor with one type argument to be similar to other `exprt` constructors. This constructor was used to generate a struct with fresh symbols but this is no longer the case, so we use a function fresh string instead. Dependencies in the solver that were not needed have been removed. For some functions this requieres us to now pass the string type as argument.
1 parent a9bafad commit 3cb7bca

18 files changed

+411
-466
lines changed

src/solvers/refinement/refined_string_type.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ Author: Romain Brenguier, [email protected]
1010
1111
\*******************************************************************/
1212

13-
#include <solvers/refinement/refined_string_type.h>
14-
#include <ansi-c/string_constant.h>
1513
#include <util/cprover_prefix.h>
1614

15+
#include "refined_string_type.h"
16+
1717
/*******************************************************************\
1818
1919
Constructor: refined_string_typet::refined_string_typet
@@ -22,11 +22,12 @@ Constructor: refined_string_typet::refined_string_typet
2222
2323
\*******************************************************************/
2424

25-
refined_string_typet::refined_string_typet(typet char_type)
25+
refined_string_typet::refined_string_typet(
26+
const typet &index_type, const typet &char_type)
2627
{
27-
infinity_exprt infinite_index(refined_string_typet::index_type());
28+
infinity_exprt infinite_index(index_type);
2829
array_typet char_array(char_type, infinite_index);
29-
components().emplace_back("length", refined_string_typet::index_type());
30+
components().emplace_back("length", index_type);
3031
components().emplace_back("content", char_array);
3132
}
3233

src/solvers/refinement/refined_string_type.h

+2-30
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ Author: Romain Brenguier, [email protected]
1717
#include <util/std_expr.h>
1818
#include <util/arith_tools.h>
1919
#include <util/expr_util.h>
20-
#include <ansi-c/c_types.h>
21-
#include <java_bytecode/java_types.h>
2220

2321
// Internal type used for string refinement
2422
class refined_string_typet: public struct_typet
2523
{
2624
public:
27-
explicit refined_string_typet(typet char_type);
25+
refined_string_typet(const typet &index_type, const typet &char_type);
2826

2927
// Type for the content (list of characters) of a string
3028
const array_typet &get_content_type() const
@@ -33,7 +31,7 @@ class refined_string_typet: public struct_typet
3331
return to_array_type(components()[1].type());
3432
}
3533

36-
const typet &get_char_type()
34+
const typet &get_char_type() const
3735
{
3836
assert(components().size()==2);
3937
return components()[0].type();
@@ -44,16 +42,6 @@ class refined_string_typet: public struct_typet
4442
return get_content_type().size().type();
4543
}
4644

47-
static typet index_type()
48-
{
49-
return signed_int_type();
50-
}
51-
52-
static typet java_index_type()
53-
{
54-
return java_int_type();
55-
}
56-
5745
// For C the unrefined string type is __CPROVER_string, for java it is a
5846
// pointer to a struct with tag java.lang.String
5947

@@ -67,22 +55,6 @@ class refined_string_typet: public struct_typet
6755

6856
static bool is_java_char_sequence_type(const typet &type);
6957

70-
static typet get_char_type(const exprt &expr)
71-
{
72-
if(is_c_string_type(expr.type()))
73-
return char_type();
74-
else
75-
return java_char_type();
76-
}
77-
78-
static typet get_index_type(const exprt &expr)
79-
{
80-
if(is_c_string_type(expr.type()))
81-
return index_type();
82-
else
83-
return java_index_type();
84-
}
85-
8658
static bool is_unrefined_string_type(const typet &type)
8759
{
8860
return (

src/solvers/refinement/string_constraint.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,16 @@ class string_not_contains_constraintt: public exprt
111111
{
112112
public:
113113
// string_not contains_constraintt are formula of the form:
114-
// forall x in [lb,ub[. p(x) => exists y in [lb,ub[. s1[x+y] != s2[y]
114+
// forall x in [lb,ub[. p(x) => exists y in [lb,ub[. s0[x+y] != s1[y]
115115

116116
string_not_contains_constraintt(
117117
exprt univ_lower_bound,
118118
exprt univ_bound_sup,
119119
exprt premise,
120120
exprt exists_bound_inf,
121121
exprt exists_bound_sup,
122-
exprt s0,
123-
exprt s1) :
122+
const string_exprt &s0,
123+
const string_exprt &s1):
124124
exprt(ID_string_not_contains_constraint)
125125
{
126126
copy_to_operands(univ_lower_bound, univ_bound_sup, premise);
@@ -153,14 +153,14 @@ class string_not_contains_constraintt: public exprt
153153
return operands()[4];
154154
}
155155

156-
const exprt &s0() const
156+
const string_exprt &s0() const
157157
{
158-
return operands()[5];
158+
return to_string_expr(operands()[5]);
159159
}
160160

161-
const exprt &s1() const
161+
const string_exprt &s1() const
162162
{
163-
return operands()[6];
163+
return to_string_expr(operands()[6]);
164164
}
165165
};
166166

src/solvers/refinement/string_constraint_generator.h

+24-33
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ Author: Romain Brenguier, [email protected]
1313
#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H
1414
#define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H
1515

16-
#include <ansi-c/c_types.h>
16+
#include <util/string_expr.h>
1717
#include <solvers/refinement/refined_string_type.h>
18-
#include <solvers/refinement/string_expr.h>
1918
#include <solvers/refinement/string_constraint.h>
2019

2120
class string_constraint_generatort
@@ -26,33 +25,18 @@ class string_constraint_generatort
2625
// to the axiom list.
2726

2827
string_constraint_generatort():
29-
mode(ID_unknown), refined_string_type(char_type())
28+
mode(ID_unknown)
3029
{ }
3130

3231
void set_mode(irep_idt _mode)
3332
{
3433
// only C and java modes supported
3534
assert((_mode==ID_java) || (_mode==ID_C));
3635
mode=_mode;
37-
refined_string_type=refined_string_typet(get_char_type());
3836
}
3937

4038
irep_idt &get_mode() { return mode; }
4139

42-
typet get_char_type() const;
43-
typet get_index_type() const
44-
{
45-
if(mode==ID_java)
46-
return refined_string_typet::java_index_type();
47-
assert(mode==ID_C);
48-
return refined_string_typet::index_type();
49-
}
50-
51-
const refined_string_typet &get_refined_string_type() const
52-
{
53-
return refined_string_type;
54-
}
55-
5640
// Axioms are of three kinds: universally quantified string constraint,
5741
// not contains string constraints and simple formulas.
5842
std::list<exprt> axioms;
@@ -73,9 +57,14 @@ class string_constraint_generatort
7357
return index_exprt(witness.at(c), univ_val);
7458
}
7559

76-
symbol_exprt fresh_exist_index(const irep_idt &prefix);
77-
symbol_exprt fresh_univ_index(const irep_idt &prefix);
60+
static unsigned next_symbol_id;
61+
62+
static symbol_exprt fresh_symbol(
63+
const irep_idt &prefix, const typet &type=bool_typet());
64+
symbol_exprt fresh_exist_index(const irep_idt &prefix, const typet &type);
65+
symbol_exprt fresh_univ_index(const irep_idt &prefix, const typet &type);
7866
symbol_exprt fresh_boolean(const irep_idt &prefix);
67+
string_exprt fresh_string(const refined_string_typet &type);
7968

8069
// We maintain a map from symbols to strings.
8170
std::map<irep_idt, string_exprt> symbol_to_string;
@@ -95,7 +84,7 @@ class string_constraint_generatort
9584
exprt add_axioms_for_function_application(
9685
const function_application_exprt &expr);
9786

98-
constant_exprt constant_char(int i) const;
87+
static constant_exprt constant_char(int i, const typet &char_type);
9988

10089
private:
10190
// The integer with the longest string is Integer.MIN_VALUE which is -2^31,
@@ -107,7 +96,7 @@ class string_constraint_generatort
10796
const std::size_t MAX_FLOAT_LENGTH=15;
10897
const std::size_t MAX_DOUBLE_LENGTH=30;
10998

110-
irep_idt extract_java_string(const symbol_exprt &s) const;
99+
static irep_idt extract_java_string(const symbol_exprt &s);
111100

112101
exprt axiom_for_is_positive_index(const exprt &x);
113102

@@ -123,7 +112,6 @@ class string_constraint_generatort
123112
exprt add_axioms_for_contains(const function_application_exprt &f);
124113
exprt add_axioms_for_equals(const function_application_exprt &f);
125114
exprt add_axioms_for_equals_ignore_case(const function_application_exprt &f);
126-
exprt add_axioms_for_data(const function_application_exprt &f);
127115

128116
// Add axioms corresponding to the String.hashCode java function
129117
// The specification is partial: the actual value is not actually computed
@@ -153,7 +141,8 @@ class string_constraint_generatort
153141
string_exprt add_axioms_for_concat_float(const function_application_exprt &f);
154142
string_exprt add_axioms_for_concat_code_point(
155143
const function_application_exprt &f);
156-
string_exprt add_axioms_for_constant(irep_idt sval);
144+
string_exprt add_axioms_for_constant(
145+
irep_idt sval, const refined_string_typet &ref_type);
157146
string_exprt add_axioms_for_delete(
158147
const string_exprt &str, const exprt &start, const exprt &end);
159148
string_exprt add_axioms_for_delete(const function_application_exprt &expr);
@@ -173,15 +162,19 @@ class string_constraint_generatort
173162
const function_application_exprt &f);
174163
string_exprt add_axioms_from_literal(const function_application_exprt &f);
175164
string_exprt add_axioms_from_int(const function_application_exprt &f);
176-
string_exprt add_axioms_from_int(const exprt &i, size_t max_size);
177-
string_exprt add_axioms_from_int_hex(const exprt &i);
165+
string_exprt add_axioms_from_int(
166+
const exprt &i, size_t max_size, const refined_string_typet &ref_type);
167+
string_exprt add_axioms_from_int_hex(
168+
const exprt &i, const refined_string_typet &ref_type);
178169
string_exprt add_axioms_from_int_hex(const function_application_exprt &f);
179170
string_exprt add_axioms_from_long(const function_application_exprt &f);
180171
string_exprt add_axioms_from_long(const exprt &i, size_t max_size);
181172
string_exprt add_axioms_from_bool(const function_application_exprt &f);
182-
string_exprt add_axioms_from_bool(const exprt &i);
173+
string_exprt add_axioms_from_bool(
174+
const exprt &i, const refined_string_typet &ref_type);
183175
string_exprt add_axioms_from_char(const function_application_exprt &f);
184-
string_exprt add_axioms_from_char(const exprt &i);
176+
string_exprt add_axioms_from_char(
177+
const exprt &i, const refined_string_typet &ref_type);
185178
string_exprt add_axioms_from_char_array(const function_application_exprt &f);
186179
string_exprt add_axioms_from_char_array(
187180
const exprt &length,
@@ -257,7 +250,8 @@ class string_constraint_generatort
257250
// TODO: not working correctly at the moment
258251
string_exprt add_axioms_for_value_of(const function_application_exprt &f);
259252

260-
string_exprt add_axioms_for_code_point(const exprt &code_point);
253+
string_exprt add_axioms_for_code_point(
254+
const exprt &code_point, const refined_string_typet &ref_type);
261255
string_exprt add_axioms_for_java_char_array(const exprt &char_array);
262256
string_exprt add_axioms_for_if(const if_exprt &expr);
263257
exprt add_axioms_for_char_literal(const function_application_exprt &f);
@@ -287,9 +281,6 @@ class string_constraint_generatort
287281
// Tells which language is used. C and Java are supported
288282
irep_idt mode;
289283

290-
// Type of strings used in the refinement
291-
refined_string_typet refined_string_type;
292-
293284
// assert that the number of argument is equal to nb and extract them
294285
static const function_application_exprt::argumentst &args(
295286
const function_application_exprt &expr, size_t nb)
@@ -299,7 +290,7 @@ class string_constraint_generatort
299290
return args;
300291
}
301292

302-
exprt int_of_hex_char(exprt chr) const;
293+
exprt int_of_hex_char(const exprt &chr) const;
303294
exprt is_high_surrogate(const exprt &chr) const;
304295
exprt is_low_surrogate(const exprt &chr) const;
305296
static exprt character_equals_ignore_case(

src/solvers/refinement/string_constraint_generator_code_points.cpp

+17-19
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ Function: string_constraint_generatort::add_axioms_for_code_point
2323
\*******************************************************************/
2424

2525
string_exprt string_constraint_generatort::add_axioms_for_code_point(
26-
const exprt &code_point)
26+
const exprt &code_point, const refined_string_typet &ref_type)
2727
{
28-
string_exprt res(get_char_type());
28+
string_exprt res=fresh_string(ref_type);
2929
const typet &type=code_point.type();
3030
assert(type.id()==ID_signedbv);
3131

@@ -50,21 +50,21 @@ string_exprt string_constraint_generatort::add_axioms_for_code_point(
5050
implies_exprt a2(not_exprt(small), res.axiom_for_has_length(2));
5151
axioms.push_back(a2);
5252

53-
typecast_exprt code_point_as_char(code_point, get_char_type());
53+
typecast_exprt code_point_as_char(code_point, ref_type.get_char_type());
5454
implies_exprt a3(small, equal_exprt(res[0], code_point_as_char));
5555
axioms.push_back(a3);
5656

5757
plus_exprt first_char(
5858
hexD800, div_exprt(minus_exprt(code_point, hex010000), hex0400));
5959
implies_exprt a4(
6060
not_exprt(small),
61-
equal_exprt(res[0], typecast_exprt(first_char, get_char_type())));
61+
equal_exprt(res[0], typecast_exprt(first_char, ref_type.get_char_type())));
6262
axioms.push_back(a4);
6363

6464
plus_exprt second_char(hexDC00, mod_exprt(code_point, hex0400));
6565
implies_exprt a5(
6666
not_exprt(small),
67-
equal_exprt(res[1], typecast_exprt(second_char, get_char_type())));
67+
equal_exprt(res[1], typecast_exprt(second_char, ref_type.get_char_type())));
6868
axioms.push_back(a5);
6969

7070
return res;
@@ -88,8 +88,8 @@ Function: string_constraint_generatort::is_high_surrogate
8888
exprt string_constraint_generatort::is_high_surrogate(const exprt &chr) const
8989
{
9090
return and_exprt(
91-
binary_relation_exprt(chr, ID_ge, constant_char(0xD800)),
92-
binary_relation_exprt(chr, ID_le, constant_char(0xDBFF)));
91+
binary_relation_exprt(chr, ID_ge, constant_char(0xD800, chr.type())),
92+
binary_relation_exprt(chr, ID_le, constant_char(0xDBFF, chr.type())));
9393
}
9494

9595
/*******************************************************************\
@@ -110,8 +110,8 @@ Function: string_constraint_generatort::is_low_surrogate
110110
exprt string_constraint_generatort::is_low_surrogate(const exprt &chr) const
111111
{
112112
return and_exprt(
113-
binary_relation_exprt(chr, ID_ge, constant_char(0xDC00)),
114-
binary_relation_exprt(chr, ID_le, constant_char(0xDFFF)));
113+
binary_relation_exprt(chr, ID_ge, constant_char(0xDC00, chr.type())),
114+
binary_relation_exprt(chr, ID_le, constant_char(0xDFFF, chr.type())));
115115
}
116116

117117
/*******************************************************************\
@@ -163,8 +163,8 @@ exprt string_constraint_generatort::add_axioms_for_code_point_at(
163163
string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]);
164164
const exprt &pos=args(f, 2)[1];
165165

166-
symbol_exprt result=string_exprt::fresh_symbol("char", return_type);
167-
exprt index1=from_integer(1, get_index_type());
166+
symbol_exprt result=fresh_symbol("char", return_type);
167+
exprt index1=from_integer(1, str.length().type());
168168
const exprt &char1=str[pos];
169169
const exprt &char2=str[plus_exprt(pos, index1)];
170170
exprt char1_as_int=typecast_exprt(char1, return_type);
@@ -198,13 +198,13 @@ exprt string_constraint_generatort::add_axioms_for_code_point_before(
198198
assert(args.size()==2);
199199
typet return_type=f.type();
200200
assert(return_type.id()==ID_signedbv);
201-
symbol_exprt result=string_exprt::fresh_symbol("char", return_type);
201+
symbol_exprt result=fresh_symbol("char", return_type);
202202
string_exprt str=add_axioms_for_string_expr(args[0]);
203203

204204
const exprt &char1=
205-
str[minus_exprt(args[1], from_integer(2, get_index_type()))];
205+
str[minus_exprt(args[1], from_integer(2, str.length().type()))];
206206
const exprt &char2=
207-
str[minus_exprt(args[1], from_integer(1, get_index_type()))];
207+
str[minus_exprt(args[1], from_integer(1, str.length().type()))];
208208
exprt char1_as_int=typecast_exprt(char1, return_type);
209209
exprt char2_as_int=typecast_exprt(char2, return_type);
210210

@@ -238,10 +238,9 @@ exprt string_constraint_generatort::add_axioms_for_code_point_count(
238238
const exprt &begin=args(f, 3)[1];
239239
const exprt &end=args(f, 3)[2];
240240
const typet &return_type=f.type();
241-
symbol_exprt result=
242-
string_exprt::fresh_symbol("code_point_count", return_type);
241+
symbol_exprt result=fresh_symbol("code_point_count", return_type);
243242
minus_exprt length(end, begin);
244-
div_exprt minimum(length, from_integer(2, get_index_type()));
243+
div_exprt minimum(length, from_integer(2, length.type()));
245244
axioms.push_back(binary_relation_exprt(result, ID_le, length));
246245
axioms.push_back(binary_relation_exprt(result, ID_ge, minimum));
247246

@@ -270,8 +269,7 @@ exprt string_constraint_generatort::add_axioms_for_offset_by_code_point(
270269
const exprt &index=args(f, 3)[1];
271270
const exprt &offset=args(f, 3)[2];
272271
const typet &return_type=f.type();
273-
symbol_exprt result=
274-
string_exprt::fresh_symbol("offset_by_code_point", return_type);
272+
symbol_exprt result=fresh_symbol("offset_by_code_point", return_type);
275273

276274
exprt minimum=plus_exprt(index, offset);
277275
exprt maximum=plus_exprt(index, plus_exprt(offset, offset));

0 commit comments

Comments
 (0)