Skip to content

Commit 6aaaed5

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 e8d4298 commit 6aaaed5

File tree

8 files changed

+47
-46
lines changed

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, romain.brenguier@diffblue.com
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
@@ -149,7 +149,6 @@ string_exprt string_constraint_generatort::get_string_expr(const exprt &expr)
149149
string_exprt string_constraint_generatort::convert_java_string_to_string_exprt(
150150
const exprt &jls)
151151
{
152-
assert(get_mode()==ID_java);
153152
assert(jls.id()==ID_struct);
154153

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

325323
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
@@ -287,16 +287,18 @@ void string_refinementt::concretize_string(const exprt &expr)
287287
if(!to_integer(length, found_length))
288288
{
289289
assert(found_length.is_long());
290-
if(found_length < 0)
290+
if(found_length<0)
291291
{
292+
// Lengths should not be negative.
293+
// TODO: Add constraints no the sign of string lengths.
292294
debug() << "concretize_results: WARNING found length is negative"
293295
<< eom;
294296
}
295297
else
296298
{
297299
size_t concretize_limit=found_length.to_long();
298-
concretize_limit=concretize_limit>MAX_CONCRETE_STRING_SIZE?
299-
MAX_CONCRETE_STRING_SIZE:concretize_limit;
300+
concretize_limit=concretize_limit>generator.max_string_length?
301+
generator.max_string_length:concretize_limit;
300302
exprt content_expr=str.content();
301303
for(size_t i=0; i<concretize_limit; ++i)
302304
{
@@ -316,9 +318,9 @@ void string_refinementt::concretize_string(const exprt &expr)
316318
/// map `found_length`
317319
void string_refinementt::concretize_results()
318320
{
319-
for(const auto& it : symbol_resolve)
321+
for(const auto &it : symbol_resolve)
320322
concretize_string(it.second);
321-
for(const auto& it : generator.created_strings)
323+
for(const auto &it : generator.created_strings)
322324
concretize_string(it);
323325
add_instantiations();
324326
}
@@ -327,7 +329,7 @@ void string_refinementt::concretize_results()
327329
/// `found_length`
328330
void string_refinementt::concretize_lengths()
329331
{
330-
for(const auto& it : symbol_resolve)
332+
for(const auto &it : symbol_resolve)
331333
{
332334
if(refined_string_typet::is_refined_string_type(it.second.type()))
333335
{
@@ -338,7 +340,7 @@ void string_refinementt::concretize_lengths()
338340
found_length[content]=length;
339341
}
340342
}
341-
for(const auto& it : generator.created_strings)
343+
for(const auto &it : generator.created_strings)
342344
{
343345
if(refined_string_typet::is_refined_string_type(it.type()))
344346
{
@@ -357,12 +359,6 @@ void string_refinementt::set_to(const exprt &expr, bool value)
357359
{
358360
assert(equality_propagation);
359361

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

623-
if(n>MAX_CONCRETE_STRING_SIZE)
619+
if(n>generator.max_string_length)
624620
{
625621
#if 0
626622
debug() << "(sr::get_array) long string (size=" << n << ")" << eom;
@@ -1006,6 +1002,7 @@ exprt string_refinementt::negation_of_constraint(
10061002
and_exprt negaxiom(premise, not_exprt(axiom.body()));
10071003

10081004
debug() << "(sr::check_axioms) negated axiom: " << from_expr(negaxiom) << eom;
1005+
substitute_array_access(negaxiom);
10091006
solver << negaxiom;
10101007
}
10111008

@@ -1038,6 +1035,7 @@ bool string_refinementt::check_axioms()
10381035

10391036
satcheck_no_simplifiert sat_check;
10401037
supert solver(ns, sat_check);
1038+
solver.set_ui(ui);
10411039
add_negation_of_constraint_to_solver(axiom_in_model, solver);
10421040

10431041
switch(solver())
@@ -1092,6 +1090,7 @@ bool string_refinementt::check_axioms()
10921090
exprt premise(axiom.premise());
10931091
exprt body(axiom.body());
10941092
implies_exprt instance(premise, body);
1093+
replace_expr(symbol_resolve, instance);
10951094
replace_expr(axiom.univ_var(), val, instance);
10961095
debug() << "adding counter example " << from_expr(instance) << eom;
10971096
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, alberto.griggio@gmail.com
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)