Skip to content

Commit 50732ee

Browse files
author
Owen Jones
committed
Create is_digit_with_radix()
Produces an expression which checks if a character is a valid digit with respect to a particular radix. Includes a unit test.
1 parent 56307d0 commit 50732ee

File tree

4 files changed

+118
-2
lines changed

4 files changed

+118
-2
lines changed

src/solvers/refinement/string_constraint_generator.h

+2
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,6 @@ class string_constraint_generatort
328328
bool is_constant_string(const string_exprt &expr) const;
329329
};
330330

331+
exprt is_digit_with_radix(exprt chr, exprt radix);
332+
331333
#endif

src/solvers/refinement/string_constraint_generator_valueof.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,41 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
490490
}
491491
return i;
492492
}
493+
494+
/// Check if a character is a digit with respect to the given radix, e.g. if the
495+
/// radix is 10 then check if the character is in the range 0-9.
496+
/// \param chr: the character
497+
/// \param radix: the radix
498+
/// \return an expression for the condition
499+
exprt is_digit_with_radix(exprt chr, exprt radix)
500+
{
501+
const typet &char_type=chr.type();
502+
exprt zero_char=from_integer('0', char_type);
503+
exprt nine_char=from_integer('9', char_type);
504+
exprt a_char=from_integer('a', char_type);
505+
exprt A_char=from_integer('A', char_type);
506+
507+
and_exprt is_digit_when_radix_le_10(
508+
binary_relation_exprt(chr, ID_ge, zero_char),
509+
binary_relation_exprt(
510+
chr, ID_lt, plus_exprt(zero_char, typecast_exprt(radix, char_type))));
511+
512+
minus_exprt radix_minus_ten(
513+
typecast_exprt(radix, char_type), from_integer(10, char_type));
514+
515+
or_exprt is_digit_when_radix_gt_10(
516+
and_exprt(
517+
binary_relation_exprt(chr, ID_ge, zero_char),
518+
binary_relation_exprt(chr, ID_le, nine_char)),
519+
and_exprt(
520+
binary_relation_exprt(chr, ID_ge, a_char),
521+
binary_relation_exprt(chr, ID_lt, plus_exprt(a_char, radix_minus_ten))),
522+
and_exprt(
523+
binary_relation_exprt(chr, ID_ge, A_char),
524+
binary_relation_exprt(chr, ID_lt, plus_exprt(A_char, radix_minus_ten))));
525+
526+
return if_exprt(
527+
binary_relation_exprt(radix, ID_le, from_integer(10, radix.type())),
528+
is_digit_when_radix_le_10,
529+
is_digit_when_radix_gt_10);
530+
}

unit/Makefile

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
SRC = unit_tests.cpp \
44
catch_example.cpp \
5+
solvers/refinement/string_constraint_generator_valueof/is_digit_with_radix.cpp \
56
# Empty last line
67

78
INCLUDES= -I ../src/ -I.
@@ -16,14 +17,15 @@ LIBS += ../src/ansi-c/ansi-c$(LIBEXT) \
1617
../src/cpp/cpp$(LIBEXT) \
1718
../src/json/json$(LIBEXT) \
1819
../src/linking/linking$(LIBEXT) \
19-
../src/util/util$(LIBEXT) \
20-
../src/big-int/big-int$(LIBEXT) \
2120
../src/goto-programs/goto-programs$(LIBEXT) \
2221
../src/pointer-analysis/pointer-analysis$(LIBEXT) \
2322
../src/langapi/langapi$(LIBEXT) \
2423
../src/assembler/assembler$(LIBEXT) \
2524
../src/analyses/analyses$(LIBEXT) \
2625
../src/solvers/solvers$(LIBEXT) \
26+
../src/java_bytecode/java_bytecode$(LIBEXT) \
27+
../src/util/util$(LIBEXT) \
28+
../src/big-int/big-int$(LIBEXT) \
2729
# Empty last line
2830

2931
TESTS = unit_tests$(EXEEXT) \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for is_digit_with_radix in
4+
solvers/refinement/string_constraint_generator_valueof.cpp
5+
6+
Author: DiffBlue Limited. All rights reserved.
7+
8+
\*******************************************************************/
9+
10+
#include <catch.hpp>
11+
12+
#include <solvers/refinement/string_constraint_generator.h>
13+
#include <util/namespace.h>
14+
#include <util/symbol_table.h>
15+
#include <util/simplify_expr.h>
16+
#include <util/std_types.h>
17+
18+
SCENARIO("is_digit_with_radix",
19+
"[core][solvers][refinement][string_constraint_generator_valueof]")
20+
{
21+
typet char_type=unsignedbv_typet(16);
22+
typet int_type=signedbv_typet(32);
23+
symbol_tablet symtab;
24+
namespacet ns(symtab);
25+
26+
WHEN("Radix 10")
27+
{
28+
int radix=10;
29+
REQUIRE(true_exprt()==simplify_expr(
30+
is_digit_with_radix(
31+
from_integer('0', char_type),
32+
from_integer(radix, int_type)), ns));
33+
REQUIRE(true_exprt()==simplify_expr(
34+
is_digit_with_radix(
35+
from_integer('9', char_type),
36+
from_integer(radix, int_type)), ns));
37+
REQUIRE(false_exprt()==simplify_expr(
38+
is_digit_with_radix(
39+
from_integer('a', char_type),
40+
from_integer(radix, int_type)), ns));
41+
}
42+
WHEN("Radix 8")
43+
{
44+
int radix=8;
45+
REQUIRE(true_exprt()==simplify_expr(
46+
is_digit_with_radix(
47+
from_integer('7', char_type),
48+
from_integer(radix, int_type)), ns));
49+
REQUIRE(false_exprt()==simplify_expr(
50+
is_digit_with_radix(
51+
from_integer('8', char_type),
52+
from_integer(radix, int_type)), ns));
53+
}
54+
WHEN("Radix 16")
55+
{
56+
int radix=16;
57+
REQUIRE(true_exprt()==simplify_expr(
58+
is_digit_with_radix(
59+
from_integer('a', char_type),
60+
from_integer(radix, int_type)), ns));
61+
REQUIRE(true_exprt()==simplify_expr(
62+
is_digit_with_radix(
63+
from_integer('A', char_type),
64+
from_integer(radix, int_type)), ns));
65+
REQUIRE(true_exprt()==simplify_expr(
66+
is_digit_with_radix(
67+
from_integer('f', char_type),
68+
from_integer(radix, int_type)), ns));
69+
REQUIRE(false_exprt()==simplify_expr(
70+
is_digit_with_radix(
71+
from_integer('g', char_type),
72+
from_integer(radix, int_type)), ns));
73+
}
74+
}

0 commit comments

Comments
 (0)