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.
1347It 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+
2256For 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
3569and understands. ` string_refinementt::set_to ` accepts all constraints that are
3670normally 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
5084String 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
5387which 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
5589linked by using the primitive ` cprover_string_associate_array_to_pointer ` .
5690The 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
6094which 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
6296allocates 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
204238This 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