Skip to content

Commit b75d745

Browse files
Many corrections in string refinement
Overhaul of string solver contributions The code adding lemmas to the solver for each equality has been completely remastered. It has been simplified and should now cover all foreseable cases. Add overflow constraints on sums for string solver When creating sum expressions during string refinement, e.g. when adding string lengths, we shall add axioms to prevent the solver from finding values that actually come from an integer overflow. Therefore, we introduce a new method plus_exprt_with_overflow_check() that wraps around plus_exprt and generates the relevant axioms. Cache function applications Cache converted function applications to avoid re-generating the axioms if it has already been done for a given function application. This seems to happen for function applications that are in an assertion, and thus are treated separately by convert_bitvector. Remove string_refinement::convert_symbol: the behaviour of this function was to convert java strings to strings of symbols. In hindsight, this was not a good idea, as we still refer to the actual java string fields in some cases, e.g. to read its length. Replace add_axioms_for_string_expr In all add_axioms_... methods, we replace all calls to add_axioms_for_string_expr by the newly created function get_string_expr, which simply returns a string_exprt when we give it an refined expr (such as a string_exprt or a symbol). Update doc in add_axioms_for_index_string Simplify constraint for is_prefix: apply distribution law and update (and refactor) documentation. Remove set_string_symbol_equal_to_expr() Removed mentions of java string type in the string solver Removing mentions of is_c_string_type To use the string solver in C, we should use a struct type with tag __CPROVER_refined_string_type Keep non-string axioms in a list Instead of giving axioms to super::boolbv_set_equality_to_true, which may contain un-substituted symbols, we keep them in a list and substitute them in dec_solve() before giving them to the function. Cleaning the add_axioms_for_string_expr method and renamed it to add_axioms_for_refined_string to signify that it should only be called on expression of type refined string. An assertion was added at the beginning to ensure that. Better get_array and string_of_array functions. Cleaned the implementation of get_array and factorized part of it. Made string_of_array directly take a array_exprt, which can be obtained from get_array. Improved string_of_array for non printable characters Resolve symbol to char arrays in non-string axioms. We introduce a mapping that expresses the maximal traversal of symbols of char array type. We use that map to, either obtain a char array from a symbol, either get a unique symbol the aliases equivalence class. This map is used to replace all symbols of char array type in the axioms that are added using the parent method: supert::boolbv_set_equality_to_true. Defining several intermediary functions for check_axioms and cleaning. Check axioms is quite complicated so we splitted it in several parts. Avoid using same universal variable name in string comparison function. Corrected test in index_of as characters could be signed Corrected return type retrieval in from_float functions. The return type should be given as argument of the helper function add_axioms_from_float. Fixed type of contains in constraint generation Introduce string_refinementt::set_to. We now override the set_to() method instead of set_equality_to_true(). This solves a problem where many lemmas were being dropped. Handle array_of in set_char_array_equality. Java assignments such as char[] str=new char[10] involves assigning the char array to 0, which is done using the array_of operator. This operator is now handled when found on the rhs of a char array assignment. Optimized string hash code and intern functions to only look at seen strings. We only compare the argument to the strings on which hash_code (resp. intern) was already called. Add missing override keyword in declarations Integrate strings into symbol resolution. We now use for strings the mechanism that was made for resolving symbols to char arrays. As a result, the symbol_to_string map has been removed. We introduce an unresolved_symbol map to associate symbols to string expressions that were introduced during constraint generation. Preventing return of nil exprt in sum_over_map Enforce -1 for witnesses when strings are unequal. This makes it easier to see when models for string have different length. Correct array index in get_array Correct a bad array access that caused a segmentation fault on the java_delete test. Adding option to concretize result and get method in string solver The option to concretize makes sure that the model that we get in the end is correct. Overiding the get method is necessary to get the actual valuation of string gotten by the solver. This two additions makes the trace generation for program with strings more likely to be actual traces of the program. Avoid adding axioms for copy Corrected `get` to not replace strings Simplifying lemmas before handing them to the solver This seems to improve performances Ignoring char array that are not symbol or constants Avoid creating new length variable for concat Adding constraint on positive length for refined strings Using get method of the parent class for the size Add function to fill the found_length map Signature for get_array should be constant Corrected overflow problem when integer get to the max size Removing overflow check in universal constraint Enforcing witness -1 when length is not sufficient in suffix Corrected index variable which should be universally quantified Factorizing addition to index set and more debug information Avoiding generating a fresh string for the empty string Enabling string solver to treat more cases and more debug infos Conversion from char pointer to array in the solver Raise a warning if found length is negative Ensure the arguments of parseInt are of the right format For now we add axioms asking for the argument to have the right format but ultimately we should raise an exception when it is not the case (which is not done right now). Corrects the specification of int to string conversion Some problems where encountered for strings with the maximal size possible for an int, which could cause an overflow. Disallow + sign in string from int Java will not add the sign for positive numbers Use get instead of current_model in check_axioms Streamline code of check_axioms() by calling get() insteand of relying on the 'current_model' variable. get() has been adapted to convert array-lists into with expressions, the former not being handled by the string solver.
1 parent 37650c9 commit b75d745

14 files changed

+1323
-525
lines changed

src/solvers/refinement/string_constraint.h

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class string_constraintt: public exprt
4848
return operands()[4];
4949
}
5050

51-
5251
private:
5352
string_constraintt();
5453

src/solvers/refinement/string_constraint_generator.h

+26-19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Romain Brenguier, [email protected]
1414
#define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H
1515

1616
#include <util/string_expr.h>
17+
#include <util/replace_expr.h>
1718
#include <util/refined_string_type.h>
1819
#include <solvers/refinement/string_constraint.h>
1920

@@ -65,21 +66,20 @@ class string_constraint_generatort
6566
symbol_exprt fresh_univ_index(const irep_idt &prefix, const typet &type);
6667
symbol_exprt fresh_boolean(const irep_idt &prefix);
6768
string_exprt fresh_string(const refined_string_typet &type);
69+
string_exprt get_string_expr(const exprt &expr);
70+
string_exprt convert_java_string_to_string_exprt(
71+
const exprt &underlying);
72+
plus_exprt plus_exprt_with_overflow_check(const exprt &op1, const exprt &op2);
6873

69-
// We maintain a map from symbols to strings.
70-
std::map<irep_idt, string_exprt> symbol_to_string;
74+
// Maps unresolved symbols to the string_exprt that was created for them
75+
std::map<irep_idt, string_exprt> unresolved_symbols;
7176

72-
string_exprt find_or_add_string_of_symbol(const symbol_exprt &sym);
7377

74-
void assign_to_symbol(
75-
const symbol_exprt &sym, const string_exprt &expr)
76-
{
77-
symbol_to_string[sym.get_identifier()]=expr;
78-
}
78+
string_exprt find_or_add_string_of_symbol(
79+
const symbol_exprt &sym,
80+
const refined_string_typet &ref_type);
7981

80-
string_exprt add_axioms_for_string_expr(const exprt &expr);
81-
void set_string_symbol_equal_to_expr(
82-
const symbol_exprt &sym, const exprt &str);
82+
string_exprt add_axioms_for_refined_string(const exprt &expr);
8383

8484
exprt add_axioms_for_function_application(
8585
const function_application_exprt &expr);
@@ -96,6 +96,8 @@ class string_constraint_generatort
9696
const std::size_t MAX_FLOAT_LENGTH=15;
9797
const std::size_t MAX_DOUBLE_LENGTH=30;
9898

99+
std::map<function_application_exprt, exprt> function_application_cache;
100+
99101
static irep_idt extract_java_string(const symbol_exprt &s);
100102

101103
exprt axiom_for_is_positive_index(const exprt &x);
@@ -117,6 +119,9 @@ class string_constraint_generatort
117119
// The specification is partial: the actual value is not actually computed
118120
// but we ensure that hash codes of equal strings are equal.
119121
exprt add_axioms_for_hash_code(const function_application_exprt &f);
122+
// To each string on which hash_code was called we associate a symbol
123+
// representing the return value of the hash_code function.
124+
std::map<string_exprt, exprt> hash_code_of_string;
120125

121126
exprt add_axioms_for_is_empty(const function_application_exprt &f);
122127
exprt add_axioms_for_is_prefix(
@@ -224,7 +229,9 @@ class string_constraint_generatort
224229
// the start for negative number
225230
string_exprt add_axioms_from_float(const function_application_exprt &f);
226231
string_exprt add_axioms_from_float(
227-
const exprt &f, bool double_precision=false);
232+
const exprt &f,
233+
const refined_string_typet &ref_type,
234+
bool double_precision);
228235

229236
// Add axioms corresponding to the String.valueOf(D) java function
230237
// TODO: the specifications is only partial
@@ -253,6 +260,7 @@ class string_constraint_generatort
253260
string_exprt add_axioms_for_code_point(
254261
const exprt &code_point, const refined_string_typet &ref_type);
255262
string_exprt add_axioms_for_java_char_array(const exprt &char_array);
263+
exprt add_axioms_for_char_pointer(const function_application_exprt &fun);
256264
string_exprt add_axioms_for_if(const if_exprt &expr);
257265
exprt add_axioms_for_char_literal(const function_application_exprt &f);
258266

@@ -270,6 +278,8 @@ class string_constraint_generatort
270278
const function_application_exprt &f);
271279

272280
exprt add_axioms_for_parse_int(const function_application_exprt &f);
281+
exprt add_axioms_for_correct_number_format(
282+
const string_exprt &str, std::size_t max_size=10);
273283
exprt add_axioms_for_to_char_array(const function_application_exprt &f);
274284
exprt add_axioms_for_compare_to(const function_application_exprt &f);
275285

@@ -278,6 +288,9 @@ class string_constraint_generatort
278288
// string pointers
279289
symbol_exprt add_axioms_for_intern(const function_application_exprt &f);
280290

291+
// Pool used for the intern method
292+
std::map<string_exprt, symbol_exprt> intern_of_string;
293+
281294
// Tells which language is used. C and Java are supported
282295
irep_idt mode;
283296

@@ -293,14 +306,8 @@ class string_constraint_generatort
293306
exprt int_of_hex_char(const exprt &chr) const;
294307
exprt is_high_surrogate(const exprt &chr) const;
295308
exprt is_low_surrogate(const exprt &chr) const;
296-
static exprt character_equals_ignore_case(
309+
exprt character_equals_ignore_case(
297310
exprt char1, exprt char2, exprt char_a, exprt char_A, exprt char_Z);
298-
299-
// Pool used for the intern method
300-
std::map<string_exprt, symbol_exprt> pool;
301-
302-
// Used to determine whether hashcode should be equal
303-
std::map<string_exprt, symbol_exprt> hash;
304311
};
305312

306313
#endif

src/solvers/refinement/string_constraint_generator_code_points.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,18 @@ exprt string_constraint_generatort::add_axioms_for_code_point_at(
160160
{
161161
typet return_type=f.type();
162162
assert(return_type.id()==ID_signedbv);
163-
string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]);
163+
string_exprt str=get_string_expr(args(f, 2)[0]);
164164
const exprt &pos=args(f, 2)[1];
165165

166166
symbol_exprt result=fresh_symbol("char", return_type);
167167
exprt index1=from_integer(1, str.length().type());
168168
const exprt &char1=str[pos];
169-
const exprt &char2=str[plus_exprt(pos, index1)];
169+
const exprt &char2=str[plus_exprt_with_overflow_check(pos, index1)];
170170
exprt char1_as_int=typecast_exprt(char1, return_type);
171171
exprt char2_as_int=typecast_exprt(char2, return_type);
172172
exprt pair=pair_value(char1_as_int, char2_as_int, return_type);
173-
exprt is_low=is_low_surrogate(str[plus_exprt(pos, index1)]);
173+
exprt is_low=is_low_surrogate(
174+
str[plus_exprt_with_overflow_check(pos, index1)]);
174175
exprt return_pair=and_exprt(is_high_surrogate(str[pos]), is_low);
175176

176177
axioms.push_back(implies_exprt(return_pair, equal_exprt(result, pair)));
@@ -199,7 +200,7 @@ exprt string_constraint_generatort::add_axioms_for_code_point_before(
199200
typet return_type=f.type();
200201
assert(return_type.id()==ID_signedbv);
201202
symbol_exprt result=fresh_symbol("char", return_type);
202-
string_exprt str=add_axioms_for_string_expr(args[0]);
203+
string_exprt str=get_string_expr(args[0]);
203204

204205
const exprt &char1=
205206
str[minus_exprt(args[1], from_integer(2, str.length().type()))];
@@ -234,7 +235,7 @@ Function: string_constraint_generatort::add_axioms_for_code_point_count
234235
exprt string_constraint_generatort::add_axioms_for_code_point_count(
235236
const function_application_exprt &f)
236237
{
237-
string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]);
238+
string_exprt str=get_string_expr(args(f, 3)[0]);
238239
const exprt &begin=args(f, 3)[1];
239240
const exprt &end=args(f, 3)[2];
240241
const typet &return_type=f.type();
@@ -265,14 +266,15 @@ Function: string_constraint_generatort::add_axioms_for_offset_by_code_point
265266
exprt string_constraint_generatort::add_axioms_for_offset_by_code_point(
266267
const function_application_exprt &f)
267268
{
268-
string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]);
269+
string_exprt str=get_string_expr(args(f, 3)[0]);
269270
const exprt &index=args(f, 3)[1];
270271
const exprt &offset=args(f, 3)[2];
271272
const typet &return_type=f.type();
272273
symbol_exprt result=fresh_symbol("offset_by_code_point", return_type);
273274

274-
exprt minimum=plus_exprt(index, offset);
275-
exprt maximum=plus_exprt(index, plus_exprt(offset, offset));
275+
exprt minimum=plus_exprt_with_overflow_check(index, offset);
276+
exprt maximum=plus_exprt_with_overflow_check(
277+
index, plus_exprt_with_overflow_check(offset, offset));
276278
axioms.push_back(binary_relation_exprt(result, ID_le, maximum));
277279
axioms.push_back(binary_relation_exprt(result, ID_ge, minimum));
278280

src/solvers/refinement/string_constraint_generator_comparison.cpp

+55-47
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Function: string_constraint_generatort::add_axioms_for_equals
1818
Outputs: a expression of Boolean type
1919
2020
Purpose: add axioms stating that the result is true exactly when the strings
21-
represented by the arguments are equal
21+
represented by the arguments are equal.
22+
the variable ending in `witness_unequal` is -1 if the length differs
23+
or an index at which the strings are different
2224
2325
\*******************************************************************/
2426

@@ -29,8 +31,8 @@ exprt string_constraint_generatort::add_axioms_for_equals(
2931
symbol_exprt eq=fresh_boolean("equal");
3032
typecast_exprt tc_eq(eq, f.type());
3133

32-
string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]);
33-
string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]);
34+
string_exprt s1=get_string_expr(args(f, 2)[0]);
35+
string_exprt s2=get_string_expr(args(f, 2)[1]);
3436
typet index_type=s1.length().type();
3537

3638
// We want to write:
@@ -54,9 +56,10 @@ exprt string_constraint_generatort::add_axioms_for_equals(
5456
binary_relation_exprt(witness, ID_lt, s1.length()),
5557
binary_relation_exprt(witness, ID_ge, zero));
5658
and_exprt witnessing(bound_witness, notequal_exprt(s1[witness], s2[witness]));
57-
implies_exprt a3(
58-
not_exprt(eq),
59-
or_exprt(notequal_exprt(s1.length(), s2.length()), witnessing));
59+
and_exprt diff_length(
60+
notequal_exprt(s1.length(), s2.length()),
61+
equal_exprt(witness, from_integer(-1, index_type)));
62+
implies_exprt a3(not_exprt(eq), or_exprt(diff_length, witnessing));
6063
axioms.push_back(a3);
6164

6265
return tc_eq;
@@ -92,8 +95,13 @@ exprt string_constraint_generatort::character_equals_ignore_case(
9295
// p3 : (is_up2&&'a'-'A'+char2=char1)
9396
equal_exprt p1(char1, char2);
9497
minus_exprt diff=minus_exprt(char_a, char_A);
95-
and_exprt p2(is_upper_case_1, equal_exprt(plus_exprt(diff, char1), char2));
96-
and_exprt p3(is_upper_case_2, equal_exprt(plus_exprt(diff, char2), char1));
98+
99+
// Overflow is not a problem here because is_upper_case conditions
100+
// ensure that we are within a safe range.
101+
and_exprt p2(is_upper_case_1,
102+
equal_exprt(plus_exprt(diff, char1), char2));
103+
and_exprt p3(is_upper_case_2,
104+
equal_exprt(plus_exprt(diff, char2), char1));
97105
return or_exprt(or_exprt(p1, p2), p3);
98106
}
99107

@@ -116,8 +124,8 @@ exprt string_constraint_generatort::add_axioms_for_equals_ignore_case(
116124

117125
symbol_exprt eq=fresh_boolean("equal_ignore_case");
118126
typecast_exprt tc_eq(eq, f.type());
119-
string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]);
120-
string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]);
127+
string_exprt s1=get_string_expr(args(f, 2)[0]);
128+
string_exprt s2=get_string_expr(args(f, 2)[1]);
121129
typet char_type=to_refined_string_type(s1.type()).get_char_type();
122130
exprt char_a=constant_char('a', char_type);
123131
exprt char_A=constant_char('A', char_type);
@@ -174,37 +182,35 @@ Function: string_constraint_generatort::add_axioms_for_hash_code
174182
exprt string_constraint_generatort::add_axioms_for_hash_code(
175183
const function_application_exprt &f)
176184
{
177-
string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]);
185+
string_exprt str=get_string_expr(args(f, 1)[0]);
178186
typet return_type=f.type();
179187
typet index_type=str.length().type();
180188

181-
// initialisation of the missing pool variable
182-
std::map<irep_idt, string_exprt>::iterator it;
183-
for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++)
184-
if(hash.find(it->second)==hash.end())
185-
hash[it->second]=fresh_symbol("hash", return_type);
189+
auto pair=hash_code_of_string.insert(
190+
std::make_pair(str, fresh_symbol("hash", return_type)));
191+
exprt hash=pair.first->second;
186192

187193
// for each string s. either:
188194
// c1: hash(str)=hash(s)
189195
// c2: |str|!=|s|
190-
// c3: (|str|==|s| &&exists i<|s|. s[i]!=str[i])
196+
// c3: (|str|==|s| && exists i<|s|. s[i]!=str[i])
191197

192198
// WARNING: the specification may be incomplete
193-
for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++)
199+
for(auto it : hash_code_of_string)
194200
{
195201
symbol_exprt i=fresh_exist_index("index_hash", index_type);
196-
equal_exprt c1(hash[it->second], hash[str]);
197-
not_exprt c2(equal_exprt(it->second.length(), str.length()));
202+
equal_exprt c1(it.second, hash);
203+
not_exprt c2(equal_exprt(it.first.length(), str.length()));
198204
and_exprt c3(
199-
equal_exprt(it->second.length(), str.length()),
205+
equal_exprt(it.first.length(), str.length()),
200206
and_exprt(
201-
not_exprt(equal_exprt(str[i], it->second[i])),
207+
not_exprt(equal_exprt(str[i], it.first[i])),
202208
and_exprt(
203209
str.axiom_for_is_strictly_longer_than(i),
204210
axiom_for_is_positive_index(i))));
205211
axioms.push_back(or_exprt(c1, or_exprt(c2, c3)));
206212
}
207-
return hash[str];
213+
return hash;
208214
}
209215

210216
/*******************************************************************\
@@ -222,8 +228,8 @@ Function: string_constraint_generatort::add_axioms_for_compare_to
222228
exprt string_constraint_generatort::add_axioms_for_compare_to(
223229
const function_application_exprt &f)
224230
{
225-
string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]);
226-
string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]);
231+
string_exprt s1=get_string_expr(args(f, 2)[0]);
232+
string_exprt s2=get_string_expr(args(f, 2)[1]);
227233
const typet &return_type=f.type();
228234
symbol_exprt res=fresh_symbol("compare_to", return_type);
229235
typet index_type=s1.length().type();
@@ -234,12 +240,12 @@ exprt string_constraint_generatort::add_axioms_for_compare_to(
234240
// a1 : res==0 => |s1|=|s2|
235241
// a2 : forall i<|s1|. s1[i]==s2[i]
236242
// a3 : exists x.
237-
// res!=0 ==> x> 0 &&
238-
// ((|s1| <= |s2| &&x<|s1|) || (|s1| >= |s2| &&x<|s2|)
239-
// &&res=s1[x]-s2[x] )
240-
// || cond2:
241-
// (|s1|<|s2| &&x=|s1|) || (|s1| > |s2| &&x=|s2|) &&res=|s1|-|s2|)
242-
// a4 : forall i<x. res!=0 => s1[i]=s2[i]
243+
// res!=0 ==> x > 0
244+
// && ((|s1| <= |s2| && x<|s1|) || (|s1| >= |s2| &&x<|s2|)
245+
// && res=s1[x]-s2[x] )
246+
// || cond2:
247+
// (|s1|<|s2| &&x=|s1|) || (|s1| > |s2| &&x=|s2|) &&res=|s1|-|s2|)
248+
// a4 : forall i'<x. res!=0 => s1[i]=s2[i]
243249

244250
assert(return_type.id()==ID_signedbv);
245251

@@ -282,7 +288,9 @@ exprt string_constraint_generatort::add_axioms_for_compare_to(
282288
or_exprt(cond1, cond2)));
283289
axioms.push_back(a3);
284290

285-
string_constraintt a4(i, x, not_exprt(res_null), equal_exprt(s1[i], s2[i]));
291+
symbol_exprt i2=fresh_univ_index("QA_compare_to", index_type);
292+
string_constraintt a4(
293+
i2, x, not_exprt(res_null), equal_exprt(s1[i2], s2[i2]));
286294
axioms.push_back(a4);
287295

288296
return res;
@@ -304,46 +312,46 @@ Function: string_constraint_generatort::add_axioms_for_intern
304312
symbol_exprt string_constraint_generatort::add_axioms_for_intern(
305313
const function_application_exprt &f)
306314
{
307-
string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]);
315+
string_exprt str=get_string_expr(args(f, 1)[0]);
316+
// For now we only enforce content equality and not pointer equality
308317
const typet &return_type=f.type();
318+
309319
typet index_type=str.length().type();
310320

311-
// initialisation of the missing pool variable
312-
std::map<irep_idt, string_exprt>::iterator it;
313-
for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++)
314-
if(pool.find(it->second)==pool.end())
315-
pool[it->second]=fresh_symbol("pool", return_type);
321+
auto pair=intern_of_string.insert(
322+
std::make_pair(str, fresh_symbol("pool", return_type)));
323+
symbol_exprt intern=pair.first->second;
316324

317325
// intern(str)=s_0 || s_1 || ...
318326
// for each string s.
319327
// intern(str)=intern(s) || |str|!=|s|
320328
// || (|str|==|s| &&exists i<|s|. s[i]!=str[i])
321329

322330
exprt disj=false_exprt();
323-
for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++)
331+
for(auto it : intern_of_string)
324332
disj=or_exprt(
325-
disj, equal_exprt(pool[str], symbol_exprt(it->first, return_type)));
333+
disj, equal_exprt(intern, it.second));
326334

327335
axioms.push_back(disj);
328336

329337

330338
// WARNING: the specification may be incomplete or incorrect
331-
for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++)
332-
if(it->second!=str)
339+
for(auto it : intern_of_string)
340+
if(it.second!=str)
333341
{
334342
symbol_exprt i=fresh_exist_index("index_intern", index_type);
335343
axioms.push_back(
336344
or_exprt(
337-
equal_exprt(pool[it->second], pool[str]),
345+
equal_exprt(it.second, intern),
338346
or_exprt(
339-
not_exprt(str.axiom_for_has_same_length_as(it->second)),
347+
not_exprt(str.axiom_for_has_same_length_as(it.first)),
340348
and_exprt(
341-
str.axiom_for_has_same_length_as(it->second),
349+
str.axiom_for_has_same_length_as(it.first),
342350
and_exprt(
343-
not_exprt(equal_exprt(str[i], it->second[i])),
351+
not_exprt(equal_exprt(str[i], it.first[i])),
344352
and_exprt(str.axiom_for_is_strictly_longer_than(i),
345353
axiom_for_is_positive_index(i)))))));
346354
}
347355

348-
return pool[str];
356+
return intern;
349357
}

0 commit comments

Comments
 (0)