CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
string_constraint_generator_testing.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Generates string constraints for string functions that return
4 Boolean values
5
6Author: Romain Brenguier, romain.brenguier@diffblue.com
7
8\*******************************************************************/
9
12
14
15#include <util/deprecate.h>
17
37std::pair<exprt, string_constraintst>
39 const array_string_exprt &prefix,
40 const array_string_exprt &str,
41 const exprt &offset)
42{
43 string_constraintst constraints;
44 const symbol_exprt isprefix = fresh_symbol("isprefix");
45 const typet &index_type = str.length_type();
47 binary_relation_exprt(offset, ID_ge, from_integer(0, offset.type())),
51 ID_ge,
53
54 // Axiom 1.
55 constraints.existential.push_back(
57
58 // Axiom 2.
59 constraints.universal.push_back([&] {
60 const symbol_exprt qvar = fresh_symbol("QA_isprefix", index_type);
61 const exprt body = implies_exprt(
62 isprefix, equal_exprt(str[plus_exprt(qvar, offset)], prefix[qvar]));
63 return string_constraintt(
64 qvar,
65 maximum(
66 from_integer(0, index_type), array_pool.get_or_create_length(prefix)),
67 body,
69 }());
70
71 // Axiom 3.
72 constraints.existential.push_back([&] {
73 const exprt witness = fresh_symbol("witness_not_isprefix", index_type);
77 notequal_exprt(str[plus_exprt(witness, offset)], prefix[witness]));
85 }());
86
87 return {isprefix, std::move(constraints)};
88}
89
95// NOLINTNEXTLINE
105std::pair<exprt, string_constraintst>
108 bool swap_arguments)
109{
111 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
112 PRECONDITION(args.size() == 2 || args.size() == 3);
113 const array_string_exprt &s0 =
115 const array_string_exprt &s1 =
117 const exprt offset =
118 args.size() == 2 ? from_integer(0, s0.length_type()) : args[2];
119 auto pair = add_axioms_for_is_prefix(s0, s1, offset);
120 return {typecast_exprt(pair.first, f.type()), std::move(pair.second)};
121}
122
128DEPRECATED(SINCE(2017, 10, 5, "should use `string_length s == 0` instead"))
130string_constraint_generatort::add_axioms_for_is_empty(
132{
133 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
134 PRECONDITION(f.arguments().size() == 1);
135 // We add axioms:
136 // a1 : is_empty => |s0| = 0
137 // a2 : s0 => is_empty
138
139 symbol_exprt is_empty = fresh_symbol("is_empty");
140 array_string_exprt s0 = get_string_expr(array_pool, f.arguments()[0]);
141 string_constraintst constraints;
142 constraints.existential = {
143 implies_exprt(is_empty, equal_to(array_pool.get_or_create_length(s0), 0)),
144 implies_exprt(equal_to(array_pool.get_or_create_length(s0), 0), is_empty)};
145 return {typecast_exprt(is_empty, f.type()), std::move(constraints)};
146}
147
169DEPRECATED(SINCE(2018, 6, 6, "should use strings_startwith"))
171string_constraint_generatort::add_axioms_for_is_suffix(
173 bool swap_arguments)
174{
175 const function_application_exprt::argumentst &args = f.arguments();
176 PRECONDITION(args.size() == 2); // bad args to string issuffix?
177 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
178
179 string_constraintst constraints;
180 symbol_exprt issuffix = fresh_symbol("issuffix");
182 const array_string_exprt &s0 =
183 get_string_expr(array_pool, args[swap_arguments ? 1u : 0u]);
184 const array_string_exprt &s1 =
185 get_string_expr(array_pool, args[swap_arguments ? 0u : 1u]);
186 const typet &index_type = s0.length_type();
187
189 issuffix,
191 array_pool.get_or_create_length(s1),
192 array_pool.get_or_create_length(s0)));
193 constraints.existential.push_back(a1);
194
195 symbol_exprt qvar = fresh_symbol("QA_suffix", index_type);
197 qvar,
199 array_pool.get_or_create_length(s1),
200 array_pool.get_or_create_length(s0)));
202 qvar,
203 zero_if_negative(array_pool.get_or_create_length(s0)),
205 message_handler);
206 constraints.universal.push_back(a2);
207
208 symbol_exprt witness = fresh_symbol("witness_not_suffix", index_type);
209 const plus_exprt shifted(
210 witness,
212 array_pool.get_or_create_length(s1),
213 array_pool.get_or_create_length(s0)));
215 and_exprt(
217 array_pool.get_or_create_length(s0),
218 array_pool.get_or_create_length(s1)),
219 equal_exprt(witness, from_integer(-1, index_type))),
220 and_exprt(
222 and_exprt(
223 greater_than(array_pool.get_or_create_length(s0), witness),
226
227 constraints.existential.push_back(a3);
228 return {tc_issuffix, std::move(constraints)};
229}
230
249std::pair<exprt, string_constraintst>
252{
253 PRECONDITION(f.arguments().size() == 2);
254 PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool);
255 string_constraintst constraints;
258 const typet &index_type = s0.length_type();
259 const symbol_exprt contains = fresh_symbol("contains");
260 const symbol_exprt startpos = fresh_symbol("startpos_contains", index_type);
261
262 const implies_exprt a1(
263 contains,
267 constraints.existential.push_back(a1);
268
274 constraints.existential.push_back(a2);
275
278 constraints.existential.push_back(a3);
279
280 symbol_exprt qvar = fresh_symbol("QA_contains", index_type);
283 qvar,
287 constraints.universal.push_back(a4);
288
290 from_integer(0, index_type),
291 plus_exprt(from_integer(1, index_type), length_diff),
292 and_exprt(
297 from_integer(0, index_type),
299 s0,
300 s1};
301 constraints.not_contains.push_back(a5);
302
303 return {typecast_exprt(contains, f.type()), std::move(constraints)};
304}
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.
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.
const typet & length_type() const
Definition string_expr.h:70
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_is_prefix(const array_string_exprt &prefix, const array_string_exprt &str, const exprt &offset)
Add axioms stating that the returned expression is true exactly when the offset is greater or equal t...
std::pair< exprt, string_constraintst > add_axioms_for_contains(const function_application_exprt &f)
Test whether a string contains another.
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
#define SINCE(year, month, day, msg)
Definition deprecate.h:26
#define DEPRECATED(msg)
Definition deprecate.h:23
static bool is_empty(const goto_programt &goto_program)
API to expression classes for 'mathematical' expressions.
STL namespace.
#define PRECONDITION(CONDITION)
Definition invariant.h:463
Generates string constraints to link results from string functions with their arguments.
exprt is_positive(const exprt &x)
exprt maximum(const exprt &a, const exprt &b)
exprt zero_if_negative(const exprt &expr)
Returns a non-negative version of the argument.
static bool contains(const exprt &index, const symbol_exprt &qvar)
Look for symbol qvar in the expression index and return true if found.
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< string_not_contains_constraintt > not_contains
std::vector< exprt > existential
std::vector< string_constraintt > universal
Constraints to encode non containement of strings.