Skip to content

Commit cae6d27

Browse files
Style improvements in string_constraint_generator_float.cpp
Defining a constant for the maximal value not using scientific notation Adding precondition on the max_size given to fractional part Renaming i argument to int_expr Making comments correspond to added axioms in float to string conversion Replacing magnitude by fraction and improving comments Replacing hexadecimal float number by decimal Hexadecimals are not supported by all compilers Editing TODO in string of float which should be part of specifications Typo in comment (from -> form)
1 parent 4eacbd3 commit cae6d27

File tree

1 file changed

+87
-77
lines changed

1 file changed

+87
-77
lines changed

src/solvers/refinement/string_constraint_generator_float.cpp

+87-77
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ exprt get_exponent(
3030
exprt exp_bits=extractbits_exprt(
3131
src, spec.f+spec.e-1, spec.f, unsignedbv_typet(spec.e));
3232

33-
// Exponent is in biased from (numbers from -128 to 127 are encoded with
33+
// Exponent is in biased form (numbers from -128 to 127 are encoded with
3434
// integer from 0 to 255) we have to remove the bias.
3535
return minus_exprt(
3636
typecast_exprt(exp_bits, signedbv_typet(32)),
3737
from_integer(spec.bias(), signedbv_typet(32)));
3838
}
3939

40-
/// Gets the magnitude without hidden bit
40+
/// Gets the fraction without hidden bit
4141
/// \param src: a floating point expression
4242
/// \param spec: specification for floating points
43-
/// \return An unsigned value representing the magnitude.
44-
exprt get_magnitude(const exprt &src, const ieee_float_spect &spec)
43+
/// \return An unsigned value representing the fractional part.
44+
exprt get_fraction(const exprt &src, const ieee_float_spect &spec)
4545
{
4646
return extractbits_exprt(src, spec.f-1, 0, unsignedbv_typet(spec.f));
4747
}
@@ -61,12 +61,12 @@ exprt get_significand(
6161
{
6262
PRECONDITION(type.id()==ID_unsignedbv);
6363
PRECONDITION(to_unsignedbv_type(type).get_width()>spec.f);
64-
typecast_exprt magnitude(get_magnitude(src, spec), type);
64+
typecast_exprt fraction(get_fraction(src, spec), type);
6565
exprt exponent=get_exponent(src, spec);
6666
equal_exprt all_zeros(exponent, from_integer(0, exponent.type()));
6767
exprt hidden_bit=from_integer((1 << spec.f), type);
68-
plus_exprt with_hidden_bit(magnitude, hidden_bit);
69-
return if_exprt(all_zeros, magnitude, with_hidden_bit);
68+
bitor_exprt with_hidden_bit(fraction, hidden_bit);
69+
return if_exprt(all_zeros, fraction, with_hidden_bit);
7070
}
7171

7272
/// Create an expression to represent a float or double value.
@@ -126,9 +126,9 @@ exprt floatbv_of_int_expr(const exprt &i, const ieee_float_spect &spec)
126126
/// floating point value in decimal.
127127
/// We are looking for d such that n * 10^d = m * 2^e, so:
128128
/// d = log_10(m) + log_10(2) * e - log_10(n)
129-
/// m -- the magnitude -- should be between 1 and 2 so log_10(m)
129+
/// m -- the fraction -- should be between 1 and 2 so log_10(m)
130130
/// in [0,log_10(2)].
131-
/// n -- the magnitude in base 10 -- should be between 1 and 10 so
131+
/// n -- the fraction in base 10 -- should be between 1 and 10 so
132132
/// log_10(n) in [0, 1].
133133
/// So the estimate is given by:
134134
/// d ~=~ floor(log_10(2) * e)
@@ -169,10 +169,12 @@ string_exprt string_constraint_generatort::add_axioms_from_double(
169169

170170
/// Add axioms corresponding to the integer part of m, in decimal form with no
171171
/// leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal
172-
/// digits representing the fractional part of m.
172+
/// digits representing the fractional part of m. This specification is correct
173+
/// for inputs that do not exceed 100000 and the function is unspecified for
174+
/// other values.
173175
///
174176
/// TODO: this specification is not correct for negative numbers and
175-
/// double precision and floating point value that exceed 100000
177+
/// double precision
176178
/// \param f: expression representing a float
177179
/// \param ref_type: refined type for strings
178180
/// \return a new string expression
@@ -186,33 +188,37 @@ string_exprt string_constraint_generatort::add_axioms_for_string_of_float(
186188
// shifted is floor(f * 1e5)
187189
exprt shifting=constant_float(1e5, float_spec);
188190
exprt shifted=round_expr_to_zero(floatbv_mult(f, shifting));
191+
// Numbers with greater or equal value to the following, should use
192+
// the exponent notation.
193+
exprt max_non_exponent_notation=from_integer(100000, shifted.type());
189194
// fractional_part is floor(f * 100000) % 100000
190-
mod_exprt fractional_part(shifted, from_integer(100000, shifted.type()));
195+
mod_exprt fractional_part(shifted, max_non_exponent_notation);
191196
string_exprt fractional_part_str=
192197
add_axioms_for_fractional_part(fractional_part, 6, ref_type);
193198

194-
// The axiom added to convert to integer should always been satisfiable even
195-
// when the precondition are not satisfied.
196-
mod_exprt integer_part(
197-
round_expr_to_zero(f), from_integer(1000000, shifted.type()));
199+
// The axiom added to convert to integer should always be satisfiable even
200+
// when the preconditions are not satisfied.
201+
mod_exprt integer_part(round_expr_to_zero(f), max_non_exponent_notation);
198202
// We should not need more than 8 characters to represent the integer
199203
// part of the float.
200204
string_exprt integer_part_str=add_axioms_from_int(integer_part, 8, ref_type);
201205

202206
return add_axioms_for_concat(integer_part_str, fractional_part_str);
203207
}
204208

205-
/// add axioms for representing the fractional part of a floating point starting
209+
/// Add axioms for representing the fractional part of a floating point starting
206210
/// with a dot
207-
/// \param i: an integer expression
208-
/// \param max_size: a maximal size for the string
211+
/// \param int_expr: an integer expression
212+
/// \param max_size: a maximal size for the string, this includes the
213+
/// potential minus sign and therefore should be greater than 2
209214
/// \param ref_type: a type for refined strings
210215
/// \return a string expression
211216
string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
212-
const exprt &i, size_t max_size, const refined_string_typet &ref_type)
217+
const exprt &int_expr, size_t max_size, const refined_string_typet &ref_type)
213218
{
214-
PRECONDITION(i.type().id()==ID_signedbv);
215-
const typet &type=i.type();
219+
PRECONDITION(int_expr.type().id()==ID_signedbv);
220+
PRECONDITION(max_size>=2);
221+
const typet &type=int_expr.type();
216222
string_exprt res=fresh_string(ref_type);
217223
exprt ten=from_integer(10, type);
218224
const typet &char_type=ref_type.get_char_type();
@@ -223,11 +229,11 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
223229

224230
// We add axioms:
225231
// a1 : 2 <= |res| <= max_size
226-
// a2 : forall 1 <= i < size '0' < res[i] < '9'
227-
// res[0] = '.'
228-
// a3 : i = sum_j 10^j res[j] - '0'
229-
// for all j : !(|res| = j+1 && res[j]='0')
230-
// for all j : |res| <= j => res[j]='0'
232+
// a2 : starts_with_dot && no_trailing_zero && is_number
233+
// starts_with_dot: res[0] = '.'
234+
// is_number: forall i:[1, max_size[. '0' < res[i] < '9'
235+
// no_trailing_zero: forall j:[2, max_size[. !(|res| = j+1 && res[j] = '0')
236+
// a3 : int_expr = sum_j 10^j (j < |res| ? res[j] - '0' : 0)
231237

232238
and_exprt a1(res.axiom_for_is_strictly_longer_than(1),
233239
res.axiom_for_is_shorter_than(max));
@@ -241,20 +247,21 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
241247

242248
for(size_t j=1; j<max_size; j++)
243249
{
250+
// after_end is |res| <= j
244251
binary_relation_exprt after_end(
245252
res.length(), ID_le, from_integer(j, res.length().type()));
246253
mult_exprt ten_sum(sum, ten);
247254

248-
// sum = 10 * sum + (res[j]-'0')
255+
// sum = 10 * sum + after_end ? 0 : (res[j]-'0')
249256
if_exprt to_add(
250257
after_end,
251258
from_integer(0, type),
252259
typecast_exprt(minus_exprt(res[j], zero_char), type));
253260
sum=plus_exprt(ten_sum, to_add);
254261

255262
and_exprt is_number(
256-
binary_relation_exprt(res[j], ID_ge, zero_char),
257-
binary_relation_exprt(res[j], ID_le, nine_char));
263+
binary_relation_exprt(res[j], ID_ge, zero_char),
264+
binary_relation_exprt(res[j], ID_le, nine_char));
258265
digit_constraints.push_back(is_number);
259266

260267
// There are no trailing zeros except for ".0" (i.e j=2)
@@ -263,14 +270,14 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
263270
not_exprt no_trailing_zero(and_exprt(
264271
equal_exprt(res.length(), from_integer(j+1, res.length().type())),
265272
equal_exprt(res[j], zero_char)));
266-
axioms.push_back(no_trailing_zero);
273+
digit_constraints.push_back(no_trailing_zero);
267274
}
268275
}
269276

270277
exprt a2=conjunction(digit_constraints);
271278
axioms.push_back(a2);
272279

273-
equal_exprt a3(i, sum);
280+
equal_exprt a3(int_expr, sum);
274281
axioms.push_back(a3);
275282

276283
return res;
@@ -286,13 +293,12 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
286293
/// $d = floor(log_10(2) * e)$
287294
/// Then $n$ can be expressed by the equation:
288295
/// $log_10(n) = log_10(m) + log_10(2) * e - d$
289-
/// $n = f /10^d = m * 2^e / 10^d = m * 2^e / 10^(floor(log_10(2) * e))$
290-
///
296+
/// $n = f / 10^d = m * 2^e / 10^d = m * 2^e / 10^(floor(log_10(2) * e))$
291297
/// TODO: For now we only consider single precision.
292298
/// \param f: a float expression, which is positive
293299
/// \param max_size: a maximal size for the string
294300
/// \param ref_type: a type for refined strings
295-
/// \return a string expression
301+
/// \return a string expression representing the float in scientific notation
296302
string_exprt string_constraint_generatort::
297303
add_axioms_from_float_scientific_notation(
298304
const exprt &f, const refined_string_typet &ref_type)
@@ -308,57 +314,58 @@ string_exprt string_constraint_generatort::
308314
exprt bin_exponent=get_exponent(f, float_spec);
309315

310316
// $m$ from the formula is a value between 0.0 and 2.0 represented
311-
// with values in the range 0x000000 0x0FFFFFF so 1 corresponds to 0x0800000.
317+
// with values in the range 0x000000 0xFFFFFF so 1 corresponds to 0x800000.
312318
// `bin_significand_int` represents $m * 0x800000$
313319
exprt bin_significand_int=
314320
get_significand(f, float_spec, unsignedbv_typet(32));
315-
// `bin_significand` represents $m$ it is obtained
316-
// by multiplying `binary_significand_as_int` by 1/0x800000=1.192092896e-7.
321+
// `bin_significand` represents $m$ and is obtained
322+
// by multiplying `binary_significand_as_int` by
323+
// 1/0x800000 = 2^-23 = 1.1920928955078125 * 10^-7
317324
exprt bin_significand=floatbv_mult(
318325
floatbv_typecast_exprt(bin_significand_int, round_to_zero_expr, float_type),
319-
constant_float(1.192092896e-7, float_spec));
326+
constant_float(1.1920928955078125e-7, float_spec));
320327

321328
// This is a first approximation of the exponent that will adjust
322-
// if the magnitude we get is greater than 10
329+
// if the fraction we get is greater than 10
323330
exprt dec_exponent_estimate=estimate_decimal_exponent(f, float_spec);
324331

325332
// Table for values of $2^x / 10^(floor(log_10(2)*x))$ where x=Range[0,128]
326333
std::vector<double> two_power_e_over_ten_power_d_table(
327-
{1, 2, 4, 8, 1.6, 3.2, 6.4, 1.28, 2.56,
328-
5.12, 1.024, 2.048, 4.096, 8.192, 1.6384, 3.2768, 6.5536,
329-
1.31072, 2.62144, 5.24288, 1.04858, 2.09715, 4.19430, 8.38861, 1.67772,
330-
3.35544, 6.71089, 1.34218, 2.68435, 5.36871, 1.07374, 2.14748, 4.29497,
331-
8.58993, 1.71799, 3.43597, 6.87195, 1.37439, 2.74878, 5.49756, 1.09951,
332-
2.19902, 4.39805, 8.79609, 1.75922, 3.51844, 7.03687, 1.40737, 2.81475,
333-
5.62950, 1.12590, 2.25180, 4.50360, 9.00720, 1.80144, 3.60288, 7.20576,
334-
1.44115, 2.88230, 5.76461, 1.15292, 2.30584, 4.61169, 9.22337, 1.84467,
335-
3.68935, 7.37870, 1.47574, 2.95148, 5.90296, 1.18059, 2.36118, 4.72237,
336-
9.44473, 1.88895, 3.77789, 7.55579, 1.51116, 3.02231, 6.04463, 1.20893,
337-
2.41785, 4.83570, 9.67141, 1.93428, 3.86856, 7.73713, 1.54743, 3.09485,
338-
6.18970, 1.23794, 2.47588, 4.95176, 9.90352, 1.98070, 3.96141, 7.92282,
339-
1.58456, 3.16913, 6.33825, 1.26765, 2.53530, 5.07060, 1.01412, 2.02824,
340-
4.05648, 8.11296, 1.62259, 3.24519, 6.49037, 1.29807, 2.59615, 5.1923,
341-
1.03846, 2.07692, 4.15384, 8.30767, 1.66153, 3.32307, 6.64614, 1.32923,
342-
2.65846, 5.31691, 1.06338, 2.12676, 4.25353, 8.50706, 1.70141});
334+
{ 1, 2, 4, 8, 1.6, 3.2, 6.4, 1.28, 2.56,
335+
5.12, 1.024, 2.048, 4.096, 8.192, 1.6384, 3.2768, 6.5536,
336+
1.31072, 2.62144, 5.24288, 1.04858, 2.09715, 4.19430, 8.38861, 1.67772,
337+
3.35544, 6.71089, 1.34218, 2.68435, 5.36871, 1.07374, 2.14748, 4.29497,
338+
8.58993, 1.71799, 3.43597, 6.87195, 1.37439, 2.74878, 5.49756, 1.09951,
339+
2.19902, 4.39805, 8.79609, 1.75922, 3.51844, 7.03687, 1.40737, 2.81475,
340+
5.62950, 1.12590, 2.25180, 4.50360, 9.00720, 1.80144, 3.60288, 7.20576,
341+
1.44115, 2.88230, 5.76461, 1.15292, 2.30584, 4.61169, 9.22337, 1.84467,
342+
3.68935, 7.37870, 1.47574, 2.95148, 5.90296, 1.18059, 2.36118, 4.72237,
343+
9.44473, 1.88895, 3.77789, 7.55579, 1.51116, 3.02231, 6.04463, 1.20893,
344+
2.41785, 4.83570, 9.67141, 1.93428, 3.86856, 7.73713, 1.54743, 3.09485,
345+
6.18970, 1.23794, 2.47588, 4.95176, 9.90352, 1.98070, 3.96141, 7.92282,
346+
1.58456, 3.16913, 6.33825, 1.26765, 2.53530, 5.07060, 1.01412, 2.02824,
347+
4.05648, 8.11296, 1.62259, 3.24519, 6.49037, 1.29807, 2.59615, 5.1923,
348+
1.03846, 2.07692, 4.15384, 8.30767, 1.66153, 3.32307, 6.64614, 1.32923,
349+
2.65846, 5.31691, 1.06338, 2.12676, 4.25353, 8.50706, 1.70141});
343350

344351
// Table for values of $2^x / 10^(floor(log_10(2)*x))$ where x=Range[-128,-1]
345352
std::vector<double> two_power_e_over_ten_power_d_table_negatives(
346-
{ 2.93874, 5.87747, 1.17549, 2.35099, 4.70198, 9.40395, 1.88079, 3.76158,
347-
7.52316, 1.50463, 3.00927, 6.01853, 1.20371, 2.40741, 4.81482, 9.62965,
348-
1.92593, 3.85186, 7.70372, 1.54074, 3.08149, 6.16298, 1.23260, 2.46519,
349-
4.93038, 9.86076, 1.97215, 3.94430, 7.88861, 1.57772, 3.15544, 6.31089,
350-
1.26218, 2.52435, 5.04871, 1.00974, 2.01948, 4.03897, 8.07794, 1.61559,
351-
3.23117, 6.46235, 1.29247, 2.58494, 5.16988, 1.03398, 2.06795, 4.13590,
352-
8.27181, 1.65436, 3.30872, 6.61744, 1.32349, 2.64698, 5.29396, 1.05879,
353-
2.11758, 4.23516, 8.47033, 1.69407, 3.38813, 6.77626, 1.35525, 2.71051,
354-
5.42101, 1.08420, 2.16840, 4.33681, 8.67362, 1.73472, 3.46945, 6.93889,
355-
1.38778, 2.77556, 5.55112, 1.11022, 2.22045, 4.44089, 8.88178, 1.77636,
356-
3.55271, 7.10543, 1.42109, 2.84217, 5.68434, 1.13687, 2.27374, 4.54747,
357-
9.09495, 1.81899, 3.63798, 7.27596, 1.45519, 2.91038, 5.82077, 1.16415,
358-
2.32831, 4.65661, 9.31323, 1.86265, 3.72529, 7.45058, 1.49012, 2.98023,
359-
5.96046, 1.19209, 2.38419, 4.76837, 9.53674, 1.90735, 3.81470, 7.62939,
360-
1.52588, 3.05176, 6.10352, 1.22070, 2.44141, 4.88281, 9.76563, 1.95313,
361-
3.90625, 7.81250, 1.56250, 3.12500, 6.25000, 1.25000, 2.50000, 5});
353+
{ 2.93874, 5.87747, 1.17549, 2.35099, 4.70198, 9.40395, 1.88079, 3.76158,
354+
7.52316, 1.50463, 3.00927, 6.01853, 1.20371, 2.40741, 4.81482, 9.62965,
355+
1.92593, 3.85186, 7.70372, 1.54074, 3.08149, 6.16298, 1.23260, 2.46519,
356+
4.93038, 9.86076, 1.97215, 3.94430, 7.88861, 1.57772, 3.15544, 6.31089,
357+
1.26218, 2.52435, 5.04871, 1.00974, 2.01948, 4.03897, 8.07794, 1.61559,
358+
3.23117, 6.46235, 1.29247, 2.58494, 5.16988, 1.03398, 2.06795, 4.13590,
359+
8.27181, 1.65436, 3.30872, 6.61744, 1.32349, 2.64698, 5.29396, 1.05879,
360+
2.11758, 4.23516, 8.47033, 1.69407, 3.38813, 6.77626, 1.35525, 2.71051,
361+
5.42101, 1.08420, 2.16840, 4.33681, 8.67362, 1.73472, 3.46945, 6.93889,
362+
1.38778, 2.77556, 5.55112, 1.11022, 2.22045, 4.44089, 8.88178, 1.77636,
363+
3.55271, 7.10543, 1.42109, 2.84217, 5.68434, 1.13687, 2.27374, 4.54747,
364+
9.09495, 1.81899, 3.63798, 7.27596, 1.45519, 2.91038, 5.82077, 1.16415,
365+
2.32831, 4.65661, 9.31323, 1.86265, 3.72529, 7.45058, 1.49012, 2.98023,
366+
5.96046, 1.19209, 2.38419, 4.76837, 9.53674, 1.90735, 3.81470, 7.62939,
367+
1.52588, 3.05176, 6.10352, 1.22070, 2.44141, 4.88281, 9.76563, 1.95313,
368+
3.90625, 7.81250, 1.56250, 3.12500, 6.25000, 1.25000, 2.50000, 5});
362369

363370
// bias_table used to find the bias factor
364371
exprt conversion_factor_table_size=from_integer(
@@ -392,7 +399,7 @@ string_exprt string_constraint_generatort::
392399
plus_exprt(dec_exponent_estimate, from_integer(1, int_type)),
393400
dec_exponent_estimate);
394401

395-
// `dec_significand` is divided by 10 if it exeeds 10
402+
// `dec_significand` is divided by 10 if it exceeds 10
396403
dec_significand=if_exprt(
397404
estimate_too_small,
398405
floatbv_mult(dec_significand, constant_float(0.1, float_spec)),
@@ -409,9 +416,12 @@ string_exprt string_constraint_generatort::
409416
exprt shifted_float=
410417
round_expr_to_zero(floatbv_mult(fractional_part, shifting));
411418

419+
// Numbers with greater or equal value to the following, should use
420+
// the exponent notation.
421+
exprt max_non_exponent_notation=from_integer(100000, shifted_float.type());
422+
412423
// fractional_part_shifted is floor(f * 100000) % 100000
413-
mod_exprt fractional_part_shifted(
414-
shifted_float, from_integer(100000, shifted_float.type()));
424+
mod_exprt fractional_part_shifted(shifted_float, max_non_exponent_notation);
415425

416426
string_exprt string_fractional_part=add_axioms_for_fractional_part(
417427
fractional_part_shifted, 6, ref_type);
@@ -421,7 +431,7 @@ string_exprt string_constraint_generatort::
421431
string_exprt string_expr_with_fractional_part=add_axioms_for_concat(
422432
string_expr_integer_part, string_fractional_part);
423433

424-
// string_expr_with_E = concat(string_magnitude, string_lit_E)
434+
// string_expr_with_E = concat(string_fraction, string_lit_E)
425435
string_exprt string_expr_with_E=add_axioms_for_concat_char(
426436
string_expr_with_fractional_part,
427437
from_integer('E', ref_type.get_char_type()));
@@ -434,7 +444,7 @@ string_exprt string_constraint_generatort::
434444
return add_axioms_for_concat(string_expr_with_E, exponent_string);
435445
}
436446

437-
/// add axioms corresponding to the scientific representation of floating point
447+
/// Add axioms corresponding to the scientific representation of floating point
438448
/// values
439449
/// \param f: a function application expression
440450
/// \return a new string expression

0 commit comments

Comments
 (0)