CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
string_constraint_generator_comparison.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Generates string constraints for function comparing strings,
4 such as: equals, equalsIgnoreCase, compareTo, hashCode, intern
5
6Author: Romain Brenguier, romain.brenguier@diffblue.com
7
8\*******************************************************************/
9
13
15
17
30std::pair<exprt, string_constraintst>
33{
34 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
35 PRECONDITION(f.arguments().size() == 2);
36
37 string_constraintst constraints;
40 symbol_exprt eq = fresh_symbol("equal");
42
43 typet index_type = s1.length_type();
44
45 // Axiom 1.
46 constraints.existential.push_back(implies_exprt(
47 eq,
51
52 // Axiom 2.
53 constraints.universal.push_back([&] {
54 const symbol_exprt qvar = fresh_symbol("QA_equal", index_type);
55 return string_constraintt(
56 qvar,
60 }());
61
62 // Axiom 3.
63 constraints.existential.push_back([&] {
64 const symbol_exprt witness = fresh_symbol("witness_unequal", index_type);
65 const exprt zero = from_integer(0, index_type);
76 equal_exprt(witness, from_integer(-1, index_type)));
78 }());
79
80 return {tc_eq, std::move(constraints)};
81}
82
93 const exprt &char1,
94 const exprt &char2,
95 const exprt &char_a,
96 const exprt &char_A,
97 const exprt &char_Z)
98{
105
106 // Three possibilities:
107 // p1 : char1=char2
108 // p2 : (is_up1&&'a'-'A'+char1=char2)
109 // p3 : (is_up2&&'a'-'A'+char2=char1)
110 const equal_exprt p1(char1, char2);
112
113 // Overflow is not a problem here because is_upper_case conditions
114 // ensure that we are within a safe range.
115 const exprt p2 =
117 const exprt p3 =
119 return or_exprt(p1, p2, p3);
120}
121
135std::pair<exprt, string_constraintst>
138{
139 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
140 PRECONDITION(f.arguments().size() == 2);
141 string_constraintst constraints;
142 const symbol_exprt eq = fresh_symbol("equal_ignore_case");
145 const typet char_type = to_type_with_subtype(s1.content().type()).subtype();
146 const exprt char_a = from_integer('a', char_type);
147 const exprt char_A = from_integer('A', char_type);
148 const exprt char_Z = from_integer('Z', char_type);
149 const typet index_type = s1.length_type();
150
151 const implies_exprt a1(
152 eq,
156 constraints.existential.push_back(a1);
157
158 const symbol_exprt qvar = fresh_symbol("QA_equal_ignore_case", index_type);
159 const exprt constr2 =
162 qvar,
166 constraints.universal.push_back(a2);
167
168 const symbol_exprt witness =
169 fresh_symbol("witness_unequal_ignore_case", index_type);
170 const exprt zero = from_integer(0, witness.type());
177 const implies_exprt a3(
178 not_exprt(eq),
179 or_exprt(
184 constraints.existential.push_back(a3);
185
186 return {typecast_exprt(eq, f.type()), std::move(constraints)};
187}
188
208std::pair<exprt, string_constraintst>
211{
212 PRECONDITION(f.arguments().size() == 2);
213 const typet &return_type = f.type();
214 PRECONDITION(return_type.id() == ID_signedbv);
215 string_constraintst constraints;
218 const symbol_exprt res = fresh_symbol("compare_to", return_type);
219 const typet &index_type = s1.length_type();
220
221 const equal_exprt res_null(res, from_integer(0, return_type));
222 const implies_exprt a1(
223 res_null,
227 constraints.existential.push_back(a1);
228
229 const symbol_exprt i = fresh_symbol("QA_compare_to", index_type);
231 i,
235 constraints.universal.push_back(a2);
236
237 const symbol_exprt x = fresh_symbol("index_compare_to", index_type);
239 res,
241 typecast_exprt(s1[x], return_type), typecast_exprt(s2[x], return_type)));
243 res,
247 const or_exprt guard1(
248 and_exprt(
253 and_exprt(
259 const or_exprt guard2(
260 and_exprt(
265 and_exprt(
271
272 const implies_exprt a3(
274 and_exprt(
275 binary_relation_exprt(x, ID_ge, from_integer(0, return_type)),
276 or_exprt(cond1, cond2)));
277 constraints.existential.push_back(a3);
278
279 const symbol_exprt i2 = fresh_symbol("QA_compare_to", index_type);
281 i2,
285 constraints.universal.push_back(a4);
286
287 return {res, std::move(constraints)};
288}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
array_string_exprt get_string_expr(array_poolt &array_pool, const exprt &expr)
Fetch the string_exprt corresponding to the given refined_string_exprt.
bitvector_typet char_type()
Definition c_types.cpp:106
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Boolean AND.
Definition std_expr.h:2125
exprt get_or_create_length(const array_string_exprt &s)
Get the length of an array_string_exprt from the array_pool.
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition std_expr.h:762
The Boolean type.
Definition std_types.h:36
Equality.
Definition std_expr.h:1366
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
Application of (mathematical) function.
Boolean implication.
Definition std_expr.h:2225
const irep_idt & id() const
Definition irep.h:388
Binary minus.
Definition std_expr.h:1061
Boolean negation.
Definition std_expr.h:2454
Disequality.
Definition std_expr.h:1425
Boolean OR.
Definition std_expr.h:2270
The plus expression Associativity is not specified.
Definition std_expr.h:1002
std::pair< exprt, string_constraintst > add_axioms_for_compare_to(const function_application_exprt &f)
Lexicographic comparison of two strings.
std::pair< exprt, string_constraintst > add_axioms_for_equals_ignore_case(const function_application_exprt &f)
Equality of the content ignoring case of characters.
std::pair< exprt, string_constraintst > add_axioms_for_equals(const function_application_exprt &f)
Equality of the content of two strings.
Expression to hold a symbol (variable)
Definition std_expr.h:131
Semantic type conversion.
Definition std_expr.h:2073
The type of an expression, extends irept.
Definition type.h:29
API to expression classes for 'mathematical' expressions.
#define PRECONDITION(CONDITION)
Definition invariant.h:463
Generates string constraints to link results from string functions with their arguments.
exprt zero_if_negative(const exprt &expr)
Returns a non-negative version of the argument.
static exprt character_equals_ignore_case(const exprt &char1, const exprt &char2, const exprt &char_a, const exprt &char_A, const exprt &char_Z)
Returns an expression which is true when the two given characters are equal when ignoring case for AS...
binary_relation_exprt less_than_or_equal_to(exprt lhs, exprt rhs)
Definition string_expr.h:37
binary_relation_exprt greater_or_equal_to(exprt lhs, exprt rhs)
Definition string_expr.h:20
binary_relation_exprt greater_than(exprt lhs, exprt rhs)
Definition string_expr.h:26
equal_exprt equal_to(exprt lhs, exprt rhs)
Definition string_expr.h:55
Collection of constraints of different types: existential formulas, universal formulas,...
std::vector< exprt > existential
std::vector< string_constraintt > universal
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition type.h:208