Skip to content

Commit cf33f24

Browse files
romainbrenguiertautschnig
authored andcommitted
Bug corrections in string refinement
Case of array-of in substitute array access making substitute_array_access do in-place substitution Setting the type for unknown values in substitute_array_access Unknown values could cause type problems if we do not force the type for them. Setting ui for temporary solver Remove the mode option from string solver This option is no longer requiered because the implementation is now language independent. Adapt add_axioms_for_insert for 5 arguments #110 Fixed linting issue in string_constraint_generator_concat.cpp Comment on the maximal length for string Using max_string_length as the limit for refinement Using unsigned type for max string length Using const ref in substitute_array_with_expr Correcting type of max_string_length and length comparison functions space before & sign instead of after Correcting initial_loop_bound type Putting each cbmc option on a separate line for easy merging Use size_t for string sizes Add comment in concretize_string
1 parent 39f4157 commit cf33f24

8 files changed

+47
-46
lines changed

src/cbmc/cbmc_parse_options.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ class optionst;
4141
"(no-sat-preprocessor)" \
4242
"(no-pretty-names)(beautify)" \
4343
"(dimacs)(refine)(max-node-refinement):(refine-arrays)(refine-arithmetic)"\
44-
"(refine-strings)(string-non-empty)(string-printable)(string-max-length):" \
44+
"(refine-strings)" \
45+
"(string-non-empty)" \
46+
"(string-printable)" \
47+
"(string-max-length):" \
4548
"(aig)(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \
4649
"(little-endian)(big-endian)" \
4750
"(show-goto-functions)(show-loops)" \

src/solvers/refinement/string_constraint_generator.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Author: Romain Brenguier, [email protected]
2020
#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H
2121
#define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H
2222

23+
#include <limits>
2324
#include <util/string_expr.h>
2425
#include <util/replace_expr.h>
2526
#include <util/refined_string_type.h>
@@ -29,30 +30,20 @@ class string_constraint_generatort
2930
{
3031
public:
3132
// This module keeps a list of axioms. It has methods which generate
32-
// string constraints for different string funcitons and add them
33+
// string constraints for different string functions and add them
3334
// to the axiom list.
3435

3536
string_constraint_generatort():
36-
mode(ID_unknown),
37-
max_string_length(-1),
37+
max_string_length(std::numeric_limits<size_t>::max()),
3838
force_printable_characters(false)
3939
{ }
4040

4141
// Constraints on the maximal length of strings
42-
int max_string_length;
42+
size_t max_string_length;
4343

4444
// Should we add constraints on the characters
4545
bool force_printable_characters;
4646

47-
void set_mode(irep_idt _mode)
48-
{
49-
// only C and java modes supported
50-
assert((_mode==ID_java) || (_mode==ID_C));
51-
mode=_mode;
52-
}
53-
54-
irep_idt &get_mode() { return mode; }
55-
5647
// Axioms are of three kinds: universally quantified string constraint,
5748
// not contains string constraints and simple formulas.
5849
std::list<exprt> axioms;

src/solvers/refinement/string_constraint_generator_concat.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ string_exprt string_constraint_generatort::add_axioms_for_concat(
3030
// a4 : forall i<|s1|. res[i]=s1[i]
3131
// a5 : forall i<|s2|. res[i+|s1|]=s2[i]
3232

33-
equal_exprt a1(res.length(), plus_exprt_with_overflow_check(s1.length(), s2.length()));
33+
equal_exprt a1(
34+
res.length(), plus_exprt_with_overflow_check(s1.length(), s2.length()));
3435
axioms.push_back(a1);
3536
axioms.push_back(s1.axiom_for_is_shorter_than(res));
3637
axioms.push_back(s2.axiom_for_is_shorter_than(res));

src/solvers/refinement/string_constraint_generator_insert.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,30 @@ string_exprt string_constraint_generatort::add_axioms_for_insert(
2626
return add_axioms_for_concat(concat1, suf);
2727
}
2828

29-
/// add axioms corresponding to the StringBuilder.insert(String) java function
29+
/// add axioms corresponding to the StringBuilder.insert(int, CharSequence) and
30+
/// StringBuilder.insert(int, CharSequence, int, int) java functions
3031
/// \par parameters: function application with three arguments: two strings and
3132
/// an index
3233
/// \return a new string expression
3334
string_exprt string_constraint_generatort::add_axioms_for_insert(
3435
const function_application_exprt &f)
3536
{
36-
string_exprt s1=get_string_expr(args(f, 3)[0]);
37-
string_exprt s2=get_string_expr(args(f, 3)[2]);
38-
return add_axioms_for_insert(s1, s2, args(f, 3)[1]);
37+
assert(f.arguments().size()>=3);
38+
string_exprt s1=get_string_expr(f.arguments()[0]);
39+
string_exprt s2=get_string_expr(f.arguments()[2]);
40+
const exprt &offset=f.arguments()[1];
41+
if(f.arguments().size()==5)
42+
{
43+
const exprt &start=f.arguments()[3];
44+
const exprt &end=f.arguments()[4];
45+
string_exprt substring=add_axioms_for_substring(s2, start, end);
46+
return add_axioms_for_insert(s1, substring, offset);
47+
}
48+
else
49+
{
50+
assert(f.arguments().size()==3);
51+
return add_axioms_for_insert(s1, s2, offset);
52+
}
3953
}
4054

4155
/// add axioms corresponding to the StringBuilder.insert(I) java function

src/solvers/refinement/string_constraint_generator_main.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ string_exprt string_constraint_generatort::get_string_expr(const exprt &expr)
150150
string_exprt string_constraint_generatort::convert_java_string_to_string_exprt(
151151
const exprt &jls)
152152
{
153-
assert(get_mode()==ID_java);
154153
assert(jls.id()==ID_struct);
155154

156155
exprt length(to_struct_expr(jls).op1());
@@ -320,7 +319,6 @@ exprt string_constraint_generatort::add_axioms_for_function_application(
320319
// TODO: This part needs some improvement.
321320
// Stripping the symbol name is not a very robust process.
322321
new_expr.function() = symbol_exprt(str_id.substr(0, pos+4));
323-
assert(get_mode()==ID_java);
324322
new_expr.type() = refined_string_typet(java_int_type(), java_char_type());
325323

326324
auto res_it=function_application_cache.insert(std::make_pair(new_expr,

src/solvers/refinement/string_refinement.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,18 @@ void string_refinementt::concretize_string(const exprt &expr)
288288
if(!to_integer(length, found_length))
289289
{
290290
assert(found_length.is_long());
291-
if(found_length < 0)
291+
if(found_length<0)
292292
{
293+
// Lengths should not be negative.
294+
// TODO: Add constraints no the sign of string lengths.
293295
debug() << "concretize_results: WARNING found length is negative"
294296
<< eom;
295297
}
296298
else
297299
{
298300
size_t concretize_limit=found_length.to_long();
299-
concretize_limit=concretize_limit>MAX_CONCRETE_STRING_SIZE?
300-
MAX_CONCRETE_STRING_SIZE:concretize_limit;
301+
concretize_limit=concretize_limit>generator.max_string_length?
302+
generator.max_string_length:concretize_limit;
301303
exprt content_expr=str.content();
302304
for(size_t i=0; i<concretize_limit; ++i)
303305
{
@@ -317,9 +319,9 @@ void string_refinementt::concretize_string(const exprt &expr)
317319
/// map `found_length`
318320
void string_refinementt::concretize_results()
319321
{
320-
for(const auto& it : symbol_resolve)
322+
for(const auto &it : symbol_resolve)
321323
concretize_string(it.second);
322-
for(const auto& it : generator.created_strings)
324+
for(const auto &it : generator.created_strings)
323325
concretize_string(it);
324326
add_instantiations();
325327
}
@@ -328,7 +330,7 @@ void string_refinementt::concretize_results()
328330
/// `found_length`
329331
void string_refinementt::concretize_lengths()
330332
{
331-
for(const auto& it : symbol_resolve)
333+
for(const auto &it : symbol_resolve)
332334
{
333335
if(refined_string_typet::is_refined_string_type(it.second.type()))
334336
{
@@ -339,7 +341,7 @@ void string_refinementt::concretize_lengths()
339341
found_length[content]=length;
340342
}
341343
}
342-
for(const auto& it : generator.created_strings)
344+
for(const auto &it : generator.created_strings)
343345
{
344346
if(refined_string_typet::is_refined_string_type(it.type()))
345347
{
@@ -358,12 +360,6 @@ void string_refinementt::set_to(const exprt &expr, bool value)
358360
{
359361
assert(equality_propagation);
360362

361-
// TODO: remove the mode field of generator since we should be language
362-
// independent.
363-
// We only set the mode once.
364-
if(generator.get_mode()==ID_unknown)
365-
set_mode();
366-
367363
if(expr.id()==ID_equal)
368364
{
369365
equal_exprt eq_expr=to_equal_expr(expr);
@@ -621,7 +617,7 @@ exprt string_refinementt::get_array(const exprt &arr, const exprt &size) const
621617
array_typet ret_type(char_type, from_integer(n, index_type));
622618
array_exprt ret(ret_type);
623619

624-
if(n>MAX_CONCRETE_STRING_SIZE)
620+
if(n>generator.max_string_length)
625621
{
626622
#if 0
627623
debug() << "(sr::get_array) long string (size=" << n << ")" << eom;
@@ -1007,6 +1003,7 @@ exprt string_refinementt::negation_of_constraint(
10071003
and_exprt negaxiom(premise, not_exprt(axiom.body()));
10081004

10091005
debug() << "(sr::check_axioms) negated axiom: " << from_expr(negaxiom) << eom;
1006+
substitute_array_access(negaxiom);
10101007
solver << negaxiom;
10111008
}
10121009

@@ -1039,6 +1036,7 @@ bool string_refinementt::check_axioms()
10391036

10401037
satcheck_no_simplifiert sat_check;
10411038
supert solver(ns, sat_check);
1039+
solver.set_ui(ui);
10421040
add_negation_of_constraint_to_solver(axiom_in_model, solver);
10431041

10441042
switch(solver())
@@ -1093,6 +1091,7 @@ bool string_refinementt::check_axioms()
10931091
exprt premise(axiom.premise());
10941092
exprt body(axiom.body());
10951093
implies_exprt instance(premise, body);
1094+
replace_expr(symbol_resolve, instance);
10961095
replace_expr(axiom.univ_var(), val, instance);
10971096
debug() << "adding counter example " << from_expr(instance) << eom;
10981097
add_lemma(instance);

src/solvers/refinement/string_refinement.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ Author: Alberto Griggio, [email protected]
2525
#include <solvers/refinement/string_constraint.h>
2626
#include <solvers/refinement/string_constraint_generator.h>
2727

28-
// Defines a limit on the string witnesses we will output.
29-
// Longer strings are still concidered possible by the solver but
30-
// it will not output them.
31-
#define MAX_CONCRETE_STRING_SIZE 500
32-
3328
#define MAX_NB_REFINEMENT 100
3429

3530
class string_refinementt: public bv_refinementt
@@ -48,7 +43,7 @@ class string_refinementt: public bv_refinementt
4843
// Should we concretize strings when the solver finished
4944
bool do_concretizing;
5045

51-
void set_max_string_length(int i);
46+
void set_max_string_length(size_t i);
5247
void enforce_non_empty_string();
5348
void enforce_printable_characters();
5449

@@ -113,8 +108,8 @@ class string_refinementt: public bv_refinementt
113108
exprt substitute_function_applications(exprt expr);
114109
typet substitute_java_string_types(typet type);
115110
exprt substitute_java_strings(exprt expr);
116-
exprt substitute_array_with_expr(exprt &expr, exprt &index) const;
117-
exprt substitute_array_access(exprt &expr) const;
111+
exprt substitute_array_with_expr(const exprt &expr, const exprt &index) const;
112+
void substitute_array_access(exprt &expr) const;
118113
void add_symbol_to_symbol_map(const exprt &lhs, const exprt &rhs);
119114
bool is_char_array(const typet &type) const;
120115
bool add_axioms_for_string_assigns(const exprt &lhs, const exprt &rhs);

src/util/string_expr.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class string_exprt: public struct_exprt
7777
return binary_relation_exprt(rhs.length(), ID_lt, length());
7878
}
7979

80-
binary_relation_exprt axiom_for_is_strictly_longer_than(int i) const
80+
binary_relation_exprt axiom_for_is_strictly_longer_than(mp_integer i) const
8181
{
8282
return axiom_for_is_strictly_longer_than(from_integer(i, length().type()));
8383
}
@@ -94,7 +94,7 @@ class string_exprt: public struct_exprt
9494
return binary_relation_exprt(length(), ID_le, rhs);
9595
}
9696

97-
binary_relation_exprt axiom_for_is_shorter_than(int i) const
97+
binary_relation_exprt axiom_for_is_shorter_than(mp_integer i) const
9898
{
9999
return axiom_for_is_shorter_than(from_integer(i, length().type()));
100100
}
@@ -122,7 +122,7 @@ class string_exprt: public struct_exprt
122122
return equal_exprt(length(), rhs);
123123
}
124124

125-
equal_exprt axiom_for_has_length(int i) const
125+
equal_exprt axiom_for_has_length(mp_integer i) const
126126
{
127127
return axiom_for_has_length(from_integer(i, length().type()));
128128
}

0 commit comments

Comments
 (0)