Skip to content

Commit 638937a

Browse files
Merge pull request #1709 from romainbrenguier/doc/string-solver-intro
Add introduction to string solver documentation TG-838
2 parents 74be7fb + 1d1be4c commit 638937a

File tree

2 files changed

+80
-33
lines changed

2 files changed

+80
-33
lines changed

src/solvers/module.md

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33

44
\author Kareem Khazem
55

6+
The basic role of solvers is to answer whether the set of equations given
7+
is satisfiable.
8+
One example usage, is to determine whether an assertion in a
9+
program can be violated.
10+
We refer to \ref module_goto-symex for how CBMC and JBMC convert a input program
11+
and property to a set of equations.
12+
13+
The secondary role of solvers is to provide a satisfying assignment of
14+
the variables of the equations, this can for instance be used to construct
15+
a trace.
16+
17+
The most general solver in terms of supported equations is \ref string-solver.
18+
619
\section sat-smt-encoding SAT/SMT Encoding
720

821
In the \ref solvers directory.

src/solvers/refinement/README.md

+67-33
Original file line numberDiff line numberDiff line change
@@ -6,59 +6,93 @@
66

77
\section string_solver_interface String solver interface
88

9+
The string solver is particularly aimed at string logic, but since it inherits
10+
from \ref bv_refinementt it is also capable of handling arithmetic, array logic,
11+
floating point operations etc.
12+
The backend uses the flattening of \ref boolbvt to convert expressions to boolean formula.
13+
14+
An example of a problem given to string solver could look like this:
15+
16+
~~~~~
17+
return_code == cprover_string_concat_func(
18+
length1, array1,
19+
{ .length=length2, .content=content2 },
20+
{ .length=length3, .content=content3 })
21+
length3 == length2
22+
content3 == content2
23+
is_equal == cprover_string_equals_func(length1, array1, 2, {'a', 'a'})
24+
is_equal == 1
25+
~~~~~
26+
27+
Details about the meaning of the primitives `cprover_string_concat_func` and
28+
`cprover_string_equals_func` are given in section \ref primitives "String Primitives".
29+
30+
The first equality means that the string represented by `{length1, array1}` is
31+
the concatanation of the string represented by `{length2, array2}` and
32+
`{length3, array3}`. The second and third mean that `{length2, array2}` and
33+
`{length3, array3}` represent the same string. The fourth means that `is_equal`
34+
is 1 if and only if `{length1, array1}` is the string "aa". The last equation
35+
ensures that `is_equal` has to be equal to 1 in the solution.
36+
37+
For this system of equations the string solver should answer that it is
38+
satisfiable. It is then possible to recover which assignments make all
39+
equation true, in that case `length2 = length3 = 1` and
40+
`content2 = content3 = {'a'}`.
41+
42+
943
\subsection general_interface General interface
1044

11-
The common interface for solvers in CProver is inherited from
45+
The common interface for solvers in CProver is inherited from
1246
`decision_proceduret` and is the common interface for all solvers.
1347
It is essentially composed of these three functions:
1448

15-
- `string_refinementt::set_to(const exprt &expr, bool value)`:
49+
- `string_refinementt::set_to(const exprt &expr, bool value)`:
1650
\copybrief string_refinementt::set_to
17-
- `string_refinementt::dec_solve()`:
51+
- `string_refinementt::dec_solve()`:
1852
\copybrief string_refinementt::dec_solve
19-
- `string_refinementt::get(const exprt &expr) const`:
53+
- `string_refinementt::get(const exprt &expr) const`:
2054
\copybrief string_refinementt::get
21-
55+
2256
For each goal given to CProver:
23-
- `set_to` is called on several equations, roughly one for each step of the
57+
- `set_to` is called on several equations, roughly one for each step of the
2458
symbolic execution that leads to that goal;
2559
- `dec_solve` is called to determine whether the goal is reachable given these
2660
equations;
2761
- `get` is called by the interpreter to obtain concrete value to build a trace
2862
leading to the goal;
29-
- The same process can be repeated for further goals, in that case the
63+
- The same process can be repeated for further goals, in that case the
3064
constraints added by previous calls to `set_to` remain valid.
3165

3266
\subsection specificity Specificity of the string solver
3367

34-
The specificity of the solver is in what kind of expressions `set_to` accepts
68+
The specificity of the solver is in what kind of expressions `set_to` accepts
3569
and understands. `string_refinementt::set_to` accepts all constraints that are
3670
normally accepted by `bv_refinementt`.
3771

3872
`string_refinementt::set_to` also understands constraints of the form:
39-
* `char_pointer1 = b ? char_pointer2 : char_pointer3` where `char_pointer<i>`
73+
* `char_pointer1 = b ? char_pointer2 : char_pointer3` where `char_pointer<i>`
4074
variables are of type pointer to characters and `b` is a Boolean
4175
expression.
4276
* `i = cprover_primitive(args)` where `i` is of signed bit vector type.
4377
String primitives are listed in the next section.
4478

45-
\note In the implementation, equations that are not of these forms are passed
79+
\note In the implementation, equations that are not of these forms are passed
4680
to an embedded `bv_refinementt` solver.
4781

4882
\subsection string-representation String representation in the solver
4983

5084
String primitives can have arguments which are pointers to characters.
51-
These pointers represent strings.
52-
To each of these pointers the string solver associate a char array
85+
These pointers represent strings.
86+
To each of these pointers the string solver associate a char array
5387
which represents the content of the string.
54-
If the pointer is the address of an actual array in the program they should be
88+
If the pointer is the address of an actual array in the program they should be
5589
linked by using the primitive `cprover_string_associate_array_to_pointer`.
5690
The length of the array can also be linked to a variable of the program using
5791
`cprover_string_associate_length_to_array`.
5892

5993
\warning The solver assumes the memory pointed by the arguments is immutable
6094
which is not something that is true in general for C pointers for instance.
61-
Therefore for each transformation on a string, it is assumed the program
95+
Therefore for each transformation on a string, it is assumed the program
6296
allocates a new string before calling a primitive.
6397

6498
\section primitives String primitives
@@ -72,7 +106,7 @@ allocates a new string before calling a primitive.
72106
* `cprover_string_char_at` :
73107
\copybrief string_constraint_generatort::add_axioms_for_char_at(const function_application_exprt &f)
74108
\link string_constraint_generatort::add_axioms_for_char_at(const function_application_exprt &f) More... \endlink
75-
* `cprover_string_length` :
109+
* `cprover_string_length` :
76110
\copybrief string_constraint_generatort::add_axioms_for_length(const function_application_exprt &f)
77111
\link string_constraint_generatort::add_axioms_for_length(const function_application_exprt &f) More... \endlink
78112

@@ -81,10 +115,10 @@ allocates a new string before calling a primitive.
81115
* `cprover_string_compare_to` :
82116
\copybrief string_constraint_generatort::add_axioms_for_compare_to(const function_application_exprt &f)
83117
\link string_constraint_generatort::add_axioms_for_compare_to(const function_application_exprt &f) More... \endlink
84-
* `cprover_string_contains` :
118+
* `cprover_string_contains` :
85119
\copybrief string_constraint_generatort::add_axioms_for_contains(const function_application_exprt &f)
86120
\link string_constraint_generatort::add_axioms_for_contains(const function_application_exprt &f) More... \endlink
87-
* `cprover_string_equals` :
121+
* `cprover_string_equals` :
88122
\copybrief string_constraint_generatort::add_axioms_for_equals(const function_application_exprt &f)
89123
\link string_constraint_generatort::add_axioms_for_equals(const function_application_exprt &f) More... \endlink
90124
* `cprover_string_equals_ignore_case` :
@@ -99,25 +133,25 @@ allocates a new string before calling a primitive.
99133
* `cprover_string_is_suffix` :
100134
\copybrief string_constraint_generatort::add_axioms_for_is_suffix
101135
\link string_constraint_generatort::add_axioms_for_is_suffix More... \endlink
102-
* `cprover_string_index_of` :
136+
* `cprover_string_index_of` :
103137
\copybrief string_constraint_generatort::add_axioms_for_index_of(const function_application_exprt &f)
104138
\link string_constraint_generatort::add_axioms_for_index_of(const function_application_exprt &f) More... \endlink
105139
* `cprover_string_last_index_of` :
106140
\copybrief string_constraint_generatort::add_axioms_for_last_index_of(const function_application_exprt &f)
107141
\link string_constraint_generatort::add_axioms_for_last_index_of(const function_application_exprt &f) More... \endlink
108142

109-
\subsection transformations Transformations:
143+
\subsection transformations Transformations:
110144

111145
* `cprover_string_char_set` :
112146
\copybrief string_constraint_generatort::add_axioms_for_char_set(const function_application_exprt &f)
113147
\link string_constraint_generatort::add_axioms_for_char_set(const function_application_exprt &f) More... \endlink
114-
* `cprover_string_concat` :
148+
* `cprover_string_concat` :
115149
\copybrief string_constraint_generatort::add_axioms_for_concat(const function_application_exprt &f)
116150
\link string_constraint_generatort::add_axioms_for_concat(const function_application_exprt &f) More... \endlink
117151
* `cprover_string_delete` :
118152
\copybrief string_constraint_generatort::add_axioms_for_delete(const function_application_exprt &f)
119153
\link string_constraint_generatort::add_axioms_for_delete(const function_application_exprt &f) More... \endlink
120-
* `cprover_string_insert` :
154+
* `cprover_string_insert` :
121155
\copybrief string_constraint_generatort::add_axioms_for_insert(const function_application_exprt &f)
122156
\link string_constraint_generatort::add_axioms_for_insert(const function_application_exprt &f) More... \endlink
123157
* `cprover_string_replace` :
@@ -126,7 +160,7 @@ allocates a new string before calling a primitive.
126160
* `cprover_string_set_length` :
127161
\copybrief string_constraint_generatort::add_axioms_for_set_length(const function_application_exprt &f)
128162
\link string_constraint_generatort::add_axioms_for_set_length(const function_application_exprt &f) More... \endlink
129-
* `cprover_string_substring` :
163+
* `cprover_string_substring` :
130164
\copybrief string_constraint_generatort::add_axioms_for_substring(const function_application_exprt &f)
131165
\link string_constraint_generatort::add_axioms_for_substring(const function_application_exprt &f) More... \endlink
132166
* `cprover_string_to_lower_case` :
@@ -166,18 +200,18 @@ allocates a new string before calling a primitive.
166200
\subsection deprecated Deprecated primitives:
167201

168202
* `cprover_string_concat_code_point`, `cprover_string_code_point_at`,
169-
`cprover_string_code_point_before`, `cprover_string_code_point_count`:
203+
`cprover_string_code_point_before`, `cprover_string_code_point_count`:
170204
Java specific, should be part of Java models.
171-
* `cprover_string_offset_by_code_point`, `cprover_string_concat_char`,
172-
`cprover_string_concat_int`, `cprover_string_concat_long`,
205+
* `cprover_string_offset_by_code_point`, `cprover_string_concat_char`,
206+
`cprover_string_concat_int`, `cprover_string_concat_long`,
173207
`cprover_string_concat_bool`, `cprover_string_concat_double`,
174-
`cprover_string_concat_float`, `cprover_string_insert_int`,
208+
`cprover_string_concat_float`, `cprover_string_insert_int`,
175209
`cprover_string_insert_long`, `cprover_string_insert_bool`,
176210
`cprover_string_insert_char`, `cprover_string_insert_double`,
177-
`cprover_string_insert_float` :
211+
`cprover_string_insert_float` :
178212
Should be done in two steps: conversion from primitive type and call
179213
to the string primitive.
180-
* `cprover_string_array_of_char_pointer`, `cprover_string_to_char_array` :
214+
* `cprover_string_array_of_char_pointer`, `cprover_string_to_char_array` :
181215
Pointer to char array association
182216
is now handled by `string_constraint_generatort`, there is no need for
183217
explicit conversion.
@@ -186,15 +220,15 @@ allocates a new string before calling a primitive.
186220
Should use `cprover_string_length(s) == 0` instead.
187221
* `cprover_string_empty_string` : Can use literal of empty string instead.
188222
* `cprover_string_of_long` : Should be the same as `cprover_string_of_int`.
189-
* `cprover_string_delete_char_at` : A call to
190-
`cprover_string_delete_char_at(s, i)` would be the same thing as
223+
* `cprover_string_delete_char_at` : A call to
224+
`cprover_string_delete_char_at(s, i)` would be the same thing as
191225
`cprover_string_delete(s, i, i+1)`.
192226
* `cprover_string_of_bool` :
193227
Language dependent, should be implemented in the models.
194228
* `cprover_string_copy` : Same as `cprover_string_substring(s, 0)`.
195229
* `cprover_string_of_int_hex` : Same as `cprover_string_of_int(s, 16)`.
196230
* `cprover_string_of_double` : Same as `cprover_string_of_float`.
197-
231+
198232
\section algorithm Decision algorithm
199233

200234
\copydetails string_refinementt::dec_solve
@@ -203,9 +237,9 @@ allocates a new string before calling a primitive.
203237

204238
This is done by generate_instantiations(messaget::mstreamt &stream, const namespacet &ns, const string_constraint_generatort &generator, const index_set_pairt &index_set, const string_axiomst &axioms).
205239
\copydetails generate_instantiations(messaget::mstreamt &stream, const namespacet &ns, const string_constraint_generatort &generator, const index_set_pairt &index_set, const string_axiomst &axioms)
206-
240+
207241
\subsection axiom-check Axiom check
208242

209243
\copydetails check_axioms(const string_axiomst &axioms, string_constraint_generatort &generator, const std::function<exprt(const exprt &)> &get, messaget::mstreamt &stream, const namespacet &ns, std::size_t max_string_length, bool use_counter_example, ui_message_handlert::uit ui, const union_find_replacet &symbol_resolve)
210-
\link check_axioms(const string_axiomst &axioms, string_constraint_generatort &generator, const std::function<exprt(const exprt &)> &get, messaget::mstreamt &stream, const namespacet &ns, std::size_t max_string_length, bool use_counter_example, ui_message_handlert::uit ui, const union_find_replacet &symbol_resolve)
244+
\link check_axioms(const string_axiomst &axioms, string_constraint_generatort &generator, const std::function<exprt(const exprt &)> &get, messaget::mstreamt &stream, const namespacet &ns, std::size_t max_string_length, bool use_counter_example, ui_message_handlert::uit ui, const union_find_replacet &symbol_resolve)
211245
(See function documentation...) \endlink

0 commit comments

Comments
 (0)