@@ -98,16 +98,14 @@ exprt string_constraint_generatort::add_axioms_for_substring(
9898}
9999
100100// / Add axioms ensuring that `res` corresponds to the substring of `str`
101- // / between indexes `start` and `end`.
101+ // / between indexes `start' = max(start, 0)` and
102+ // / `end' = max(min(end, |str|), start')`.
102103// /
103104// / These axioms are:
104- // / 1. \f$ {\tt start} < {\tt end} \Rightarrow
105- // / |{\tt res}| = {\tt end} - {\tt start} \f$
106- // / 2. \f$ {\tt start} \ge {\tt end} \Rightarrow |{\tt res}| = 0 \f$
107- // / 3. \f$ |{\tt str}| > {\tt end} \f$
108- // / 4. \f$ \forall i<|{\tt str}|.\ {\tt res}[i]={\tt str}[{\tt start}+i] \f$
109- // / \todo Should return code different from 0 if `|str| <= |end|` instead of
110- // / adding constraint 3.
105+ // / 1. \f$ |{\tt res}| = end' - start' \f$
106+ // / 2. \f$ \forall i<|{\tt res}|.\ {\tt res}[i]={\tt str}[{\tt start'}+i] \f$
107+ // / \todo Should return code different from 0 if `start' != start` or
108+ // / `end' != end`
111109// / \param res: array of characters expression
112110// / \param str: array of characters expression
113111// / \param start: integer expression
@@ -123,26 +121,19 @@ exprt string_constraint_generatort::add_axioms_for_substring(
123121 PRECONDITION (start.type ()==index_type);
124122 PRECONDITION (end.type ()==index_type);
125123
126- // We add axioms:
124+ const exprt start1 = maximum (start, from_integer (0 , start.type ()));
125+ const exprt end1 = maximum (minimum (end, str.length ()), start1);
127126
128- implies_exprt a1 (
129- binary_relation_exprt (start, ID_lt, end),
130- res.axiom_for_has_length (minus_exprt (end, start)));
131- lemmas.push_back (a1);
127+ // Axiom 1.
128+ lemmas.push_back (equal_exprt (res.length (), minus_exprt (end1, start1)));
132129
133- exprt is_empty=res.axiom_for_has_length (from_integer (0 , index_type));
134- implies_exprt a2 (binary_relation_exprt (start, ID_ge, end), is_empty);
135- lemmas.push_back (a2);
130+ // Axiom 2.
131+ constraints.push_back ([&] { // NOLINT
132+ const symbol_exprt idx = fresh_univ_index (" QA_index_substring" , index_type);
133+ return string_constraintt (
134+ idx, res.length (), equal_exprt (res[idx], str[plus_exprt (start1, idx)]));
135+ }());
136136
137- // Warning: check what to do if the string is not long enough
138- lemmas.push_back (str.axiom_for_length_ge (end));
139-
140- symbol_exprt idx=fresh_univ_index (" QA_index_substring" , index_type);
141- string_constraintt a4 (idx,
142- res.length (),
143- equal_exprt (res[idx],
144- str[plus_exprt (start, idx)]));
145- constraints.push_back (a4);
146137 return from_integer (0 , signedbv_typet (32 ));
147138}
148139
0 commit comments