@@ -43,7 +43,8 @@ string_refinementt::string_refinementt(
43
43
supert(_ns, _prop),
44
44
use_counter_example(false ),
45
45
do_concretizing(false ),
46
- initial_loop_bound(refinement_bound)
46
+ initial_loop_bound(refinement_bound),
47
+ non_empty_string(false )
47
48
{ }
48
49
49
50
/* ******************************************************************\
@@ -65,6 +66,52 @@ void string_refinementt::set_mode()
65
66
66
67
/* ******************************************************************\
67
68
69
+ Function: string_refinementt::set_max_string_length
70
+
71
+ Inputs:
72
+ i - maximum length which is allowed for strings.
73
+ negative number means no limit
74
+
75
+ Purpose: Add constraints on the size of strings used in the
76
+ program.
77
+
78
+ \*******************************************************************/
79
+
80
+ void string_refinementt::set_max_string_length (int i)
81
+ {
82
+ generator.max_string_length =i;
83
+ }
84
+
85
+ /* ******************************************************************\
86
+
87
+ Function: string_refinementt::set_max_string_length
88
+
89
+ Purpose: Add constraints on the size of nondet character arrays
90
+ to ensure they have length at least 1
91
+
92
+ \*******************************************************************/
93
+
94
+ void string_refinementt::enforce_non_empty_string ()
95
+ {
96
+ non_empty_string=true ;
97
+ }
98
+
99
+ /* ******************************************************************\
100
+
101
+ Function: string_refinementt::enforce_printable_characters
102
+
103
+ Purpose: Add constraints on characters used in the program
104
+ to ensure they are printable
105
+
106
+ \*******************************************************************/
107
+
108
+ void string_refinementt::enforce_printable_characters ()
109
+ {
110
+ generator.force_printable_characters =true ;
111
+ }
112
+
113
+ /* ******************************************************************\
114
+
68
115
Function: string_refinementt::display_index_set
69
116
70
117
Purpose: display the current index set, for debugging
@@ -283,52 +330,71 @@ bool string_refinementt::add_axioms_for_string_assigns(const exprt &lhs,
283
330
284
331
/* ******************************************************************\
285
332
286
- Function: string_refinementt::concretize_results
333
+ Function: string_refinementt::concretize_string
287
334
288
- Purpose: For each string whose length has been solved, add constants
335
+ Input:
336
+ expr - an expression
337
+
338
+ Purpose: If the expression is of type string, then adds constants
289
339
to the index set to force the solver to pick concrete values
290
340
for each character, and fill the map `found_length`
291
341
292
342
\*******************************************************************/
293
343
294
- void string_refinementt::concretize_results ( )
344
+ void string_refinementt::concretize_string ( const exprt &expr )
295
345
{
296
- for ( const auto & it : symbol_resolve )
346
+ if ( refined_string_typet::is_refined_string_type (expr. type ()) )
297
347
{
298
- if (refined_string_typet::is_refined_string_type (it.second .type ()))
348
+ string_exprt str=to_string_expr (expr);
349
+ exprt length=get (str.length ());
350
+ add_lemma (equal_exprt (str.length (), length));
351
+ exprt content=str.content ();
352
+ replace_expr (symbol_resolve, content);
353
+ found_length[content]=length;
354
+ mp_integer found_length;
355
+ if (!to_integer (length, found_length))
299
356
{
300
- string_exprt str=to_string_expr (it.second );
301
- exprt length=current_model[str.length ()];
302
- exprt content=str.content ();
303
- replace_expr (symbol_resolve, content);
304
- found_length[content]=length;
305
- mp_integer found_length;
306
- if (!to_integer (length, found_length))
357
+ assert (found_length.is_long ());
358
+ if (found_length < 0 )
307
359
{
308
- assert (found_length.is_long ());
309
- if (found_length < 0 )
310
- {
311
- debug () << " concretize_results: WARNING found length is negative"
312
- << eom;
313
- }
314
- else
360
+ debug () << " concretize_results: WARNING found length is negative"
361
+ << eom;
362
+ }
363
+ else
364
+ {
365
+ size_t concretize_limit=found_length.to_long ();
366
+ concretize_limit=concretize_limit>MAX_CONCRETE_STRING_SIZE?
367
+ MAX_CONCRETE_STRING_SIZE:concretize_limit;
368
+ exprt content_expr=str.content ();
369
+ for (size_t i=0 ; i<concretize_limit; ++i)
315
370
{
316
- size_t concretize_limit=found_length.to_long ();
317
- concretize_limit=concretize_limit>MAX_CONCRETE_STRING_SIZE?
318
- MAX_CONCRETE_STRING_SIZE:concretize_limit;
319
- exprt content_expr=str.content ();
320
- replace_expr (current_model, content_expr);
321
- for (size_t i=0 ; i<concretize_limit; ++i)
322
- {
323
- auto i_expr=from_integer (i, str.length ().type ());
324
- debug () << " Concretizing " << from_expr (content_expr)
325
- << " / " << i << eom;
326
- current_index_set[str.content ()].insert (i_expr);
327
- }
371
+ auto i_expr=from_integer (i, str.length ().type ());
372
+ debug () << " Concretizing " << from_expr (content_expr)
373
+ << " / " << i << eom;
374
+ current_index_set[str.content ()].insert (i_expr);
375
+ index_set[str.content ()].insert (i_expr);
328
376
}
329
377
}
330
378
}
331
379
}
380
+ }
381
+
382
+ /* ******************************************************************\
383
+
384
+ Function: string_refinementt::concretize_results
385
+
386
+ Purpose: For each string whose length has been solved, add constants
387
+ to the index set to force the solver to pick concrete values
388
+ for each character, and fill the map `found_length`
389
+
390
+ \*******************************************************************/
391
+
392
+ void string_refinementt::concretize_results ()
393
+ {
394
+ for (const auto & it : symbol_resolve)
395
+ concretize_string (it.second );
396
+ for (const auto & it : generator.created_strings )
397
+ concretize_string (it);
332
398
add_instantiations ();
333
399
}
334
400
@@ -348,7 +414,18 @@ void string_refinementt::concretize_lengths()
348
414
if (refined_string_typet::is_refined_string_type (it.second .type ()))
349
415
{
350
416
string_exprt str=to_string_expr (it.second );
351
- exprt length=current_model[str.length ()];
417
+ exprt length=get (str.length ());
418
+ exprt content=str.content ();
419
+ replace_expr (symbol_resolve, content);
420
+ found_length[content]=length;
421
+ }
422
+ }
423
+ for (const auto & it : generator.created_strings )
424
+ {
425
+ if (refined_string_typet::is_refined_string_type (it.type ()))
426
+ {
427
+ string_exprt str=to_string_expr (it);
428
+ exprt length=get (str.length ());
352
429
exprt content=str.content ();
353
430
replace_expr (symbol_resolve, content);
354
431
found_length[content]=length;
@@ -869,6 +946,7 @@ void string_refinementt::fill_model()
869
946
}
870
947
}
871
948
949
+
872
950
/* ******************************************************************\
873
951
874
952
Function: string_refinementt::add_negation_of_constraint_to_solver
0 commit comments