Skip to content

Commit 875d554

Browse files
author
Daniel Kroening
committed
Merge branch 'develop' of github.com:diffblue/cbmc into develop
2 parents 3a06eda + 6d6e1df commit 875d554

File tree

6 files changed

+111
-93
lines changed

6 files changed

+111
-93
lines changed

src/java_bytecode/character_refine_preprocess.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ codet character_refine_preprocesst::convert_is_identifier_ignorable_int(
581581
}
582582

583583
/// Converts function call to an assignment of an expression corresponding to
584-
/// the java method Character.isIdeographic:(C)Z
584+
/// the java method Character.isIdeographic:(I)Z
585585
/// \param target: a position in a goto program
586586
codet character_refine_preprocesst::convert_is_ideographic(
587587
conversion_inputt &target)
@@ -753,7 +753,7 @@ codet character_refine_preprocesst::convert_is_lower_case_int(
753753
}
754754

755755
/// Converts function call to an assignment of an expression corresponding to
756-
/// the java method Character.isLowSurrogate:(I)Z
756+
/// the java method Character.isLowSurrogate:(C)Z
757757
/// \param target: a position in a goto program
758758
codet character_refine_preprocesst::convert_is_low_surrogate(
759759
conversion_inputt &target)
@@ -1127,7 +1127,7 @@ exprt character_refine_preprocesst::expr_of_low_surrogate(
11271127
}
11281128

11291129
/// Converts function call to an assignment of an expression corresponding to
1130-
/// the java method Character.lowSurrogate:(I)Z
1130+
/// the java method Character.lowSurrogate:(I)C
11311131
/// \param target: a position in a goto program
11321132
codet character_refine_preprocesst::convert_low_surrogate(
11331133
conversion_inputt &target)
@@ -1394,7 +1394,7 @@ void character_refine_preprocesst::initialize_conversion_table()
13941394
// "(Ljava.lang.CharSequence;I)I"
13951395
// Not supported "java::java.lang.Character.codePointCount:([CII)I"
13961396
// Not supported "java::java.lang.Character.codePointCount:"
1397-
// "(Ljava.lang.CharSequence;I)I"
1397+
// "(Ljava.lang.CharSequence;II)I"
13981398
// Not supported "java::java.lang.Character.compareTo:"
13991399
// "(Ljava.lang.Character;)I"
14001400

@@ -1422,11 +1422,11 @@ void character_refine_preprocesst::initialize_conversion_table()
14221422
&character_refine_preprocesst::convert_get_numeric_value_int;
14231423
conversion_table["java::java.lang.Character.getType:(C)I"]=
14241424
&character_refine_preprocesst::convert_get_type_char;
1425-
conversion_table["java::java.lang.Character.getType:(I)Z"]=
1425+
conversion_table["java::java.lang.Character.getType:(I)I"]=
14261426
&character_refine_preprocesst::convert_get_type_int;
14271427
conversion_table["java::java.lang.Character.hashCode:()I"]=
14281428
&character_refine_preprocesst::convert_hash_code;
1429-
conversion_table["java::java.lang.Character.highSurrogate:(C)Z"]=
1429+
conversion_table["java::java.lang.Character.highSurrogate:(I)C"]=
14301430
&character_refine_preprocesst::convert_high_surrogate;
14311431
conversion_table["java::java.lang.Character.isAlphabetic:(I)Z"]=
14321432
&character_refine_preprocesst::convert_is_alphabetic;
@@ -1446,7 +1446,7 @@ void character_refine_preprocesst::initialize_conversion_table()
14461446
&character_refine_preprocesst::convert_is_identifier_ignorable_char;
14471447
conversion_table["java::java.lang.Character.isIdentifierIgnorable:(I)Z"]=
14481448
&character_refine_preprocesst::convert_is_identifier_ignorable_int;
1449-
conversion_table["java::java.lang.Character.isIdeographic:(C)Z"]=
1449+
conversion_table["java::java.lang.Character.isIdeographic:(I)Z"]=
14501450
&character_refine_preprocesst::convert_is_ideographic;
14511451
conversion_table["java::java.lang.Character.isISOControl:(C)Z"]=
14521452
&character_refine_preprocesst::convert_is_ISO_control_char;
@@ -1476,7 +1476,7 @@ void character_refine_preprocesst::initialize_conversion_table()
14761476
&character_refine_preprocesst::convert_is_lower_case_char;
14771477
conversion_table["java::java.lang.Character.isLowerCase:(I)Z"]=
14781478
&character_refine_preprocesst::convert_is_lower_case_int;
1479-
conversion_table["java::java.lang.Character.isLowSurrogate:(I)Z"]=
1479+
conversion_table["java::java.lang.Character.isLowSurrogate:(C)Z"]=
14801480
&character_refine_preprocesst::convert_is_low_surrogate;
14811481
conversion_table["java::java.lang.Character.isMirrored:(C)Z"]=
14821482
&character_refine_preprocesst::convert_is_mirrored_char;
@@ -1516,7 +1516,7 @@ void character_refine_preprocesst::initialize_conversion_table()
15161516
&character_refine_preprocesst::convert_is_whitespace_char;
15171517
conversion_table["java::java.lang.Character.isWhitespace:(I)Z"]=
15181518
&character_refine_preprocesst::convert_is_whitespace_int;
1519-
conversion_table["java::java.lang.Character.lowSurrogate:(I)Z"]=
1519+
conversion_table["java::java.lang.Character.lowSurrogate:(I)C"]=
15201520
&character_refine_preprocesst::convert_is_low_surrogate;
15211521

15221522
// Not supported "java::java.lang.Character.offsetByCodePoints:([CIIII)I"
@@ -1528,7 +1528,7 @@ void character_refine_preprocesst::initialize_conversion_table()
15281528
conversion_table["java::java.lang.Character.toChars:(I)[C"]=
15291529
&character_refine_preprocesst::convert_to_chars;
15301530

1531-
// Not supported "java::java.lang.Character.toChars:(I[CI])I"
1531+
// Not supported "java::java.lang.Character.toChars:(I[CI)I"
15321532

15331533
conversion_table["java::java.lang.Character.toCodePoint:(CC)I"]=
15341534
&character_refine_preprocesst::convert_to_code_point;

src/solvers/refinement/string_constraint_instantiation.cpp

+28-43
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,46 @@ Author: Jesse Sigal, [email protected]
1111

1212
#include <solvers/refinement/string_constraint_instantiation.h>
1313

14-
#include <solvers/refinement/string_constraint.h>
15-
#include <solvers/refinement/string_constraint_generator.h>
16-
#include <solvers/refinement/string_refinement.h>
17-
1814
/// Instantiates a quantified formula representing `not_contains` by
1915
/// substituting the quantifiers and generating axioms.
2016
/// \related string_refinementt
2117
/// \param [in] axiom: the axiom to instantiate
22-
/// \param [in] index_set0: the index set for `axiom.s0()`
23-
/// \param [in] index_set1: the index set for `axiom.s1()`
18+
/// \param [in] index_pairs: the pairs of indices to at which to instantiate
2419
/// \param [in] generator: generator to be used to get `axiom`'s witness
2520
/// \return the lemmas produced through instantiation
2621
std::vector<exprt> instantiate_not_contains(
2722
const string_not_contains_constraintt &axiom,
28-
const std::set<exprt> &index_set0,
29-
const std::set<exprt> &index_set1,
23+
const std::set<std::pair<exprt, exprt>> &index_pairs,
3024
const string_constraint_generatort &generator)
3125
{
3226
std::vector<exprt> lemmas;
3327

34-
const string_exprt s0=to_string_expr(axiom.s0());
35-
const string_exprt s1=to_string_expr(axiom.s1());
36-
37-
for(const auto &i0 : index_set0)
38-
for(const auto &i1 : index_set1)
39-
{
40-
const minus_exprt val(i0, i1);
41-
const exprt witness=generator.get_witness_of(axiom, val);
42-
const and_exprt prem_and_is_witness(
43-
axiom.premise(),
44-
equal_exprt(witness, i1));
45-
46-
const not_exprt differ(equal_exprt(s0[i0], s1[i1]));
47-
const implies_exprt lemma(prem_and_is_witness, differ);
48-
lemmas.push_back(lemma);
49-
50-
// we put bounds on the witnesses:
51-
// 0 <= v <= |s0| - |s1| ==> 0 <= v+w[v] < |s0| && 0 <= w[v] < |s1|
52-
const exprt zero=from_integer(0, val.type());
53-
const binary_relation_exprt c1(zero, ID_le, plus_exprt(val, witness));
54-
const binary_relation_exprt c2(
55-
s0.length(), ID_gt, plus_exprt(val, witness));
56-
const binary_relation_exprt c3(s1.length(), ID_gt, witness);
57-
const binary_relation_exprt c4(zero, ID_le, witness);
58-
59-
const minus_exprt diff(s0.length(), s1.length());
60-
61-
const and_exprt premise(
62-
binary_relation_exprt(zero, ID_le, val),
63-
binary_relation_exprt(diff, ID_ge, val));
64-
const implies_exprt witness_bounds(
65-
premise,
66-
and_exprt(and_exprt(c1, c2), and_exprt(c3, c4)));
67-
lemmas.push_back(witness_bounds);
68-
}
28+
const string_exprt &s0=to_string_expr(axiom.s0());
29+
const string_exprt &s1=to_string_expr(axiom.s1());
30+
31+
for(const auto &pair : index_pairs)
32+
{
33+
// We have s0[x+f(x)] and s1[f(x)], so to have i0 indexing s0 and i1
34+
// indexing s1, we need x = i0 - i1 and f(i0 - i1) = f(x) = i1.
35+
const exprt &i0=pair.first;
36+
const exprt &i1=pair.second;
37+
const minus_exprt val(i0, i1);
38+
const and_exprt universal_bound(
39+
binary_relation_exprt(axiom.univ_lower_bound(), ID_le, val),
40+
binary_relation_exprt(axiom.univ_upper_bound(), ID_gt, val));
41+
const exprt f=generator.get_witness_of(axiom, val);
42+
const equal_exprt relevancy(f, i1);
43+
const and_exprt premise(relevancy, axiom.premise(), universal_bound);
44+
45+
const notequal_exprt differ(s0[i0], s1[i1]);
46+
const and_exprt existential_bound(
47+
binary_relation_exprt(axiom.exists_lower_bound(), ID_le, i1),
48+
binary_relation_exprt(axiom.exists_upper_bound(), ID_gt, i1));
49+
const and_exprt body(differ, existential_bound);
50+
51+
const implies_exprt lemma(premise, body);
52+
lemmas.push_back(lemma);
53+
}
6954

7055
return lemmas;
7156
}

src/solvers/refinement/string_constraint_instantiation.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ Author: Jesse Sigal, [email protected]
1717

1818
std::vector<exprt> instantiate_not_contains(
1919
const string_not_contains_constraintt &axiom,
20-
const std::set<exprt> &index_set0,
21-
const std::set<exprt> &index_set1,
20+
const std::set<std::pair<exprt, exprt>> &index_pairs,
2221
const string_constraint_generatort &generator);
2322

2423
#endif // CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_INSTANTIATION_H

src/solvers/refinement/string_refinement.cpp

+47-21
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static std::vector<exprt> instantiate_not_contains(
9999
const namespacet &ns,
100100
const string_not_contains_constraintt &axiom,
101101
const std::map<exprt, std::set<exprt>> &index_set,
102+
const std::map<exprt, std::set<exprt>> &current_index_set,
102103
const string_constraint_generatort &generator);
103104

104105
static exprt get_array(
@@ -850,7 +851,12 @@ decision_proceduret::resultt string_refinementt::dec_solve()
850851
debug() << "constraint " << i << '\n';
851852
const std::vector<exprt> lemmas=
852853
instantiate_not_contains(
853-
debug(), ns, not_contains_axioms[i], index_set, generator);
854+
debug(),
855+
ns,
856+
not_contains_axioms[i],
857+
index_set,
858+
current_index_set,
859+
generator);
854860
for(const exprt &lemma : lemmas)
855861
add_lemma(lemma);
856862
}
@@ -1510,23 +1516,26 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
15101516

15111517
if(use_counter_example)
15121518
{
1513-
// TODO: add counter examples for not_contains?
1519+
stream << "Adding counter-examples: " << eom;
1520+
// TODO: add counter-examples for universal constraints?
15141521

1515-
// Checking if the current solution satisfies the constraints
15161522
std::vector<exprt> lemmas;
1517-
for(const auto &v : violated)
1523+
for(const auto &v : violated_not_contains)
15181524
{
15191525
const exprt &val=v.second;
1520-
const string_constraintt &axiom=universal_axioms[v.first];
1521-
1522-
exprt premise(axiom.premise());
1523-
exprt body(axiom.body());
1524-
implies_exprt instance(premise, body);
1525-
replace_expr(symbol_resolve, instance);
1526-
replace_expr(axiom.univ_var(), val, instance);
1527-
stream << "adding counter example " << from_expr(ns, "", instance)
1528-
<< eom;
1529-
lemmas.push_back(instance);
1526+
const string_not_contains_constraintt &axiom=
1527+
not_contains_axioms[v.first];
1528+
1529+
const exprt func_val=generator.get_witness_of(axiom, val);
1530+
const exprt comp_val=simplify_sum(plus_exprt(val, func_val));
1531+
1532+
std::set<std::pair<exprt, exprt>> indices;
1533+
indices.insert(std::pair<exprt, exprt>(comp_val, func_val));
1534+
const exprt counter=::instantiate_not_contains(
1535+
axiom, indices, generator)[0];
1536+
1537+
stream << " - " << from_expr(ns, "", counter) << eom;
1538+
lemmas.push_back(counter);
15301539
}
15311540
return { false, lemmas };
15321541
}
@@ -1960,19 +1969,36 @@ static std::vector<exprt> instantiate_not_contains(
19601969
const namespacet &ns,
19611970
const string_not_contains_constraintt &axiom,
19621971
const std::map<exprt, std::set<exprt>> &index_set,
1972+
const std::map<exprt, std::set<exprt>> &current_index_set,
19631973
const string_constraint_generatort &generator)
19641974
{
1965-
const string_exprt s0=to_string_expr(axiom.s0());
1966-
const string_exprt s1=to_string_expr(axiom.s1());
1975+
const string_exprt &s0=axiom.s0();
1976+
const string_exprt &s1=axiom.s1();
19671977

19681978
stream << "instantiate not contains " << from_expr(ns, "", s0) << " : "
19691979
<< from_expr(ns, "", s1) << messaget::eom;
1970-
const auto &i0=index_set.find(s0.content());
1971-
const auto &i1=index_set.find(s1.content());
1972-
if(i0!=index_set.end() && i1!=index_set.end())
1980+
1981+
const auto &index_set0=index_set.find(s0.content());
1982+
const auto &index_set1=index_set.find(s1.content());
1983+
const auto &current_index_set0=current_index_set.find(s0.content());
1984+
const auto &current_index_set1=current_index_set.find(s1.content());
1985+
1986+
if(index_set0!=index_set.end() &&
1987+
index_set1!=index_set.end() &&
1988+
current_index_set0!=index_set.end() &&
1989+
current_index_set1!=index_set.end())
19731990
{
1974-
return ::instantiate_not_contains(
1975-
axiom, i0->second, i1->second, generator);
1991+
typedef std::pair<exprt, exprt> expr_pairt;
1992+
std::set<expr_pairt> index_pairs;
1993+
1994+
for(const auto &ic0 : current_index_set0->second)
1995+
for(const auto &i1 : index_set1->second)
1996+
index_pairs.insert(expr_pairt(ic0, i1));
1997+
for(const auto &ic1 : current_index_set1->second)
1998+
for(const auto &i0 : index_set0->second)
1999+
index_pairs.insert(expr_pairt(i0, ic1));
2000+
2001+
return ::instantiate_not_contains(axiom, index_pairs, generator);
19762002
}
19772003
return { };
19782004
}

src/solvers/refinement/string_refinement.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class string_refinementt final: public bv_refinementt
3939
bool string_non_empty=false;
4040
/// Concretize strings after solver is finished
4141
bool trace=false;
42-
bool use_counter_example=false;
42+
bool use_counter_example=true;
4343
};
4444
public:
4545
/// string_refinementt constructor arguments

0 commit comments

Comments
 (0)