|
| 1 | +\page string-solver String solver |
| 2 | + |
| 3 | +\author Romain Brenguier |
| 4 | + |
| 5 | +\tableofcontents |
| 6 | + |
| 7 | +\section string_solver_interface String solver interface |
| 8 | + |
| 9 | +\subsection general_interface General interface |
| 10 | + |
| 11 | +The common interface for solvers in CProver is inherited from |
| 12 | +`decision_proceduret` and is the common interface for all solvers. |
| 13 | +It is essentially composed of these three functions: |
| 14 | + |
| 15 | + - `string_refinementt::set_to(const exprt &expr, bool value)`: |
| 16 | + \copybrief string_refinementt::set_to |
| 17 | + - `string_refinementt::dec_solve()`: |
| 18 | + \copybrief string_refinementt::dec_solve |
| 19 | + - `string_refinementt::get(const exprt &expr) const`: |
| 20 | + \copybrief string_refinementt::get |
| 21 | + |
| 22 | +For each goal given to CProver: |
| 23 | + - `set_to` is called on several equations, roughly one for each step of the |
| 24 | + symbolic execution that leads to that goal; |
| 25 | + - `dec_solve` is called to determine whether the goal is reachable given these |
| 26 | + equations; |
| 27 | + - `get` is called by the interpreter to obtain concrete value to build a trace |
| 28 | + leading to the goal; |
| 29 | + - The same process can be repeated for further goals, in that case the |
| 30 | + constraints added by previous calls to `set_to` remain valid. |
| 31 | + |
| 32 | +\subsection specificity Specificity of the string solver |
| 33 | + |
| 34 | +The specificity of the solver is in what kind of expressions `set_to` accepts |
| 35 | +and understands. `string_refinementt::set_to` accepts all constraints that are |
| 36 | +normally accepted by `bv_refinementt`. |
| 37 | + |
| 38 | +`string_refinementt::set_to` also understands constraints of the form: |
| 39 | + * `char_pointer1 = b ? char_pointer2 : char_pointer3` where `char_pointer<i>` |
| 40 | + variables are of type pointer to characters and `b` is a Boolean |
| 41 | + expression. |
| 42 | + * `i = cprover_primitive(args)` where `i` is of signed bit vector type. |
| 43 | + String primitives are listed in the next section. |
| 44 | + |
| 45 | +\note In the implementation, equations that are not of these forms are passed |
| 46 | + to an embedded `bv_refinementt` solver. |
| 47 | + |
| 48 | +\subsection string-representation String representation in the solver |
| 49 | + |
| 50 | +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 |
| 53 | +which represents the content of the string. |
| 54 | +If the pointer is the address of an actual array in the program they should be |
| 55 | +linked by using the primitive `cprover_string_associate_array_to_pointer`. |
| 56 | +The length of the array can also be linked to a variable of the program using |
| 57 | + `cprover_string_associate_length_to_array`. |
| 58 | + |
| 59 | +\warning The solver assumes the memory pointed by the arguments is immutable |
| 60 | +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 |
| 62 | +allocates a new string before calling a primitive. |
| 63 | + |
| 64 | +\section primitives String primitives |
| 65 | + |
| 66 | +\subsection basic-primitives Basic access: |
| 67 | + |
| 68 | + * `cprover_string_associate_array_to_pointer` : Link with an array of |
| 69 | + characters of the program. |
| 70 | + * `cprover_string_associate_length_to_array` : Link the length of the array |
| 71 | + with the given integer value. |
| 72 | + * `cprover_string_char_at` : |
| 73 | + \copybrief string_constraint_generatort::add_axioms_for_char_at(const function_application_exprt &f) |
| 74 | + \link string_constraint_generatort::add_axioms_for_char_at(const function_application_exprt &f) More... \endlink |
| 75 | + * `cprover_string_length` : |
| 76 | + \copybrief string_constraint_generatort::add_axioms_for_length(const function_application_exprt &f) |
| 77 | + \link string_constraint_generatort::add_axioms_for_length(const function_application_exprt &f) More... \endlink |
| 78 | + |
| 79 | +\subsection comparisons Comparisons: |
| 80 | + |
| 81 | + * `cprover_string_compare_to` : |
| 82 | + \copybrief string_constraint_generatort::add_axioms_for_compare_to(const function_application_exprt &f) |
| 83 | + \link string_constraint_generatort::add_axioms_for_compare_to(const function_application_exprt &f) More... \endlink |
| 84 | + * `cprover_string_contains` : |
| 85 | + \copybrief string_constraint_generatort::add_axioms_for_contains(const function_application_exprt &f) |
| 86 | + \link string_constraint_generatort::add_axioms_for_contains(const function_application_exprt &f) More... \endlink |
| 87 | + * `cprover_string_equals` : |
| 88 | + \copybrief string_constraint_generatort::add_axioms_for_equals(const function_application_exprt &f) |
| 89 | + \link string_constraint_generatort::add_axioms_for_equals(const function_application_exprt &f) More... \endlink |
| 90 | + * `cprover_string_equals_ignore_case` : |
| 91 | + \copybrief string_constraint_generatort::add_axioms_for_equals_ignore_case(const function_application_exprt &f) |
| 92 | + \link string_constraint_generatort::add_axioms_for_equals_ignore_case(const function_application_exprt &f) More... \endlink |
| 93 | + * `cprover_string_hash_code` : |
| 94 | + \copybrief string_constraint_generatort::add_axioms_for_hash_code |
| 95 | + \link string_constraint_generatort::add_axioms_for_hash_code More... \endlink |
| 96 | + * `cprover_string_is_prefix` : |
| 97 | + \copybrief string_constraint_generatort::add_axioms_for_is_prefix |
| 98 | + \link string_constraint_generatort::add_axioms_for_is_prefix More... \endlink |
| 99 | + * `cprover_string_is_suffix` : |
| 100 | + \copybrief string_constraint_generatort::add_axioms_for_is_suffix |
| 101 | + \link string_constraint_generatort::add_axioms_for_is_suffix More... \endlink |
| 102 | + * `cprover_string_index_of` : |
| 103 | + \copybrief string_constraint_generatort::add_axioms_for_index_of(const function_application_exprt &f) |
| 104 | + \link string_constraint_generatort::add_axioms_for_index_of(const function_application_exprt &f) More... \endlink |
| 105 | + * `cprover_string_last_index_of` : |
| 106 | + \copybrief string_constraint_generatort::add_axioms_for_last_index_of(const function_application_exprt &f) |
| 107 | + \link string_constraint_generatort::add_axioms_for_last_index_of(const function_application_exprt &f) More... \endlink |
| 108 | + |
| 109 | +\subsection transformations Transformations: |
| 110 | + |
| 111 | + * `cprover_string_char_set` : |
| 112 | + \copybrief string_constraint_generatort::add_axioms_for_char_set(const function_application_exprt &f) |
| 113 | + \link string_constraint_generatort::add_axioms_for_char_set(const function_application_exprt &f) More... \endlink |
| 114 | + * `cprover_string_concat` : |
| 115 | + \copybrief string_constraint_generatort::add_axioms_for_concat(const function_application_exprt &f) |
| 116 | + \link string_constraint_generatort::add_axioms_for_concat(const function_application_exprt &f) More... \endlink |
| 117 | + * `cprover_string_delete` : |
| 118 | + \copybrief string_constraint_generatort::add_axioms_for_delete(const function_application_exprt &f) |
| 119 | + \link string_constraint_generatort::add_axioms_for_delete(const function_application_exprt &f) More... \endlink |
| 120 | + * `cprover_string_insert` : |
| 121 | + \copybrief string_constraint_generatort::add_axioms_for_insert(const function_application_exprt &f) |
| 122 | + \link string_constraint_generatort::add_axioms_for_insert(const function_application_exprt &f) More... \endlink |
| 123 | + * `cprover_string_replace` : |
| 124 | + \copybrief string_constraint_generatort::add_axioms_for_replace(const function_application_exprt &f) |
| 125 | + \link string_constraint_generatort::add_axioms_for_replace(const function_application_exprt &f) More... \endlink |
| 126 | + * `cprover_string_set_length` : |
| 127 | + \copybrief string_constraint_generatort::add_axioms_for_set_length(const function_application_exprt &f) |
| 128 | + \link string_constraint_generatort::add_axioms_for_set_length(const function_application_exprt &f) More... \endlink |
| 129 | + * `cprover_string_substring` : |
| 130 | + \copybrief string_constraint_generatort::add_axioms_for_substring(const function_application_exprt &f) |
| 131 | + \link string_constraint_generatort::add_axioms_for_substring(const function_application_exprt &f) More... \endlink |
| 132 | + * `cprover_string_to_lower_case` : |
| 133 | + \copybrief string_constraint_generatort::add_axioms_for_to_lower_case(const function_application_exprt &f) |
| 134 | + \link string_constraint_generatort::add_axioms_for_to_lower_case(const function_application_exprt &f) More... \endlink |
| 135 | + * `cprover_string_to_upper_case` : |
| 136 | + \copybrief string_constraint_generatort::add_axioms_for_to_upper_case(const function_application_exprt &f) |
| 137 | + \link string_constraint_generatort::add_axioms_for_to_upper_case(const function_application_exprt &f) More... \endlink |
| 138 | + * `cprover_string_trim` : |
| 139 | + \copybrief string_constraint_generatort::add_axioms_for_trim(const function_application_exprt &f) |
| 140 | + \link string_constraint_generatort::add_axioms_for_trim(const function_application_exprt &f) More... \endlink |
| 141 | + |
| 142 | +\subsection conversions Conversions: |
| 143 | + |
| 144 | + * `cprover_string_format` : |
| 145 | + \copybrief string_constraint_generatort::add_axioms_for_format(const function_application_exprt &f) |
| 146 | + \link string_constraint_generatort::add_axioms_for_format(const function_application_exprt &f) More... \endlink |
| 147 | + * `cprover_string_from_literal` : |
| 148 | + \copybrief string_constraint_generatort::add_axioms_from_literal(const function_application_exprt &f) |
| 149 | + \link string_constraint_generatort::add_axioms_from_literal(const function_application_exprt &f) More... \endlink |
| 150 | + * `cprover_string_of_int` : |
| 151 | + \copybrief string_constraint_generatort::add_axioms_from_int(const function_application_exprt &f) |
| 152 | + \link string_constraint_generatort::add_axioms_from_int(const function_application_exprt &f) More... \endlink |
| 153 | + * `cprover_string_of_float` : |
| 154 | + \copybrief string_constraint_generatort::add_axioms_for_string_of_float(const function_application_exprt &f) |
| 155 | + \link string_constraint_generatort::add_axioms_for_string_of_float(const function_application_exprt &f) More... \endlink |
| 156 | + * `cprover_string_of_float_scientific_notation` : |
| 157 | + \copybrief string_constraint_generatort::add_axioms_from_float_scientific_notation(const function_application_exprt &f) |
| 158 | + \link string_constraint_generatort::add_axioms_from_float_scientific_notation(const function_application_exprt &f) More... \endlink |
| 159 | + * `cprover_string_of_char` : |
| 160 | + \copybrief string_constraint_generatort::add_axioms_from_char(const function_application_exprt &f) |
| 161 | + \link string_constraint_generatort::add_axioms_from_char(const function_application_exprt &f) More... \endlink |
| 162 | + * `cprover_string_parse_int` : |
| 163 | + \copybrief string_constraint_generatort::add_axioms_for_parse_int(const function_application_exprt &f) |
| 164 | + \link string_constraint_generatort::add_axioms_for_parse_int(const function_application_exprt &f) More... \endlink |
| 165 | + |
| 166 | +\subsection deprecated Deprecated primitives: |
| 167 | + |
| 168 | + * `cprover_string_concat_code_point`, `cprover_string_code_point_at`, |
| 169 | + `cprover_string_code_point_before`, `cprover_string_code_point_count`: |
| 170 | + 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`, |
| 173 | + `cprover_string_concat_bool`, `cprover_string_concat_double`, |
| 174 | + `cprover_string_concat_float`, `cprover_string_insert_int`, |
| 175 | + `cprover_string_insert_long`, `cprover_string_insert_bool`, |
| 176 | + `cprover_string_insert_char`, `cprover_string_insert_double`, |
| 177 | + `cprover_string_insert_float` : |
| 178 | + Should be done in two steps: conversion from primitive type and call |
| 179 | + to the string primitive. |
| 180 | + * `cprover_string_array_of_char_pointer`, `cprover_string_to_char_array` : |
| 181 | + Pointer to char array association |
| 182 | + is now handled by `string_constraint_generatort`, there is no need for |
| 183 | + explicit conversion. |
| 184 | + * `cprover_string_intern` : Never tested. |
| 185 | + * `cprover_string_is_empty` : |
| 186 | + Should use `cprover_string_length(s) == 0` instead. |
| 187 | + * `cprover_string_empty_string` : Can use literal of empty string instead. |
| 188 | + * `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 |
| 191 | + `cprover_string_delete(s, i, i+1)`. |
| 192 | + * `cprover_string_of_bool` : |
| 193 | + Language dependent, should be implemented in the models. |
| 194 | + * `cprover_string_copy` : Same as `cprover_string_substring(s, 0)`. |
| 195 | + * `cprover_string_of_int_hex` : Same as `cprover_string_of_int(s, 16)`. |
| 196 | + * `cprover_string_of_double` : Same as `cprover_string_of_float`. |
| 197 | + |
| 198 | +\section algorithm Decision algorithm |
| 199 | + |
| 200 | +\copydetails string_refinementt::dec_solve |
| 201 | + |
| 202 | +\subsection instantiation Instantiation |
| 203 | + |
| 204 | +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). |
| 205 | +\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 | + |
| 207 | +\subsection axiom-check Axiom check |
| 208 | + |
| 209 | +\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) |
| 211 | + (See function documentation...) \endlink |
0 commit comments