@@ -43,7 +43,8 @@ string_refinementt::string_refinementt(
4343 supert(_ns, _prop),
4444 use_counter_example(false ),
4545 do_concretizing(false ),
46- initial_loop_bound(refinement_bound)
46+ initial_loop_bound(refinement_bound),
47+ non_empty_string(false )
4748{ }
4849
4950/* ******************************************************************\
@@ -65,6 +66,52 @@ void string_refinementt::set_mode()
6566
6667/* ******************************************************************\
6768
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+
68115Function: string_refinementt::display_index_set
69116
70117 Purpose: display the current index set, for debugging
@@ -283,52 +330,71 @@ bool string_refinementt::add_axioms_for_string_assigns(const exprt &lhs,
283330
284331/* ******************************************************************\
285332
286- Function: string_refinementt::concretize_results
333+ Function: string_refinementt::concretize_string
287334
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
289339 to the index set to force the solver to pick concrete values
290340 for each character, and fill the map `found_length`
291341
292342\*******************************************************************/
293343
294- void string_refinementt::concretize_results ( )
344+ void string_refinementt::concretize_string ( const exprt &expr )
295345{
296- for ( const auto & it : symbol_resolve )
346+ if ( refined_string_typet::is_refined_string_type (expr. type ()) )
297347 {
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))
299356 {
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 )
307359 {
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)
315370 {
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);
328376 }
329377 }
330378 }
331379 }
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);
332398 add_instantiations ();
333399}
334400
@@ -348,7 +414,18 @@ void string_refinementt::concretize_lengths()
348414 if (refined_string_typet::is_refined_string_type (it.second .type ()))
349415 {
350416 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 ());
352429 exprt content=str.content ();
353430 replace_expr (symbol_resolve, content);
354431 found_length[content]=length;
@@ -869,6 +946,7 @@ void string_refinementt::fill_model()
869946 }
870947}
871948
949+
872950/* ******************************************************************\
873951
874952Function: string_refinementt::add_negation_of_constraint_to_solver
0 commit comments