mathlib documentation

data.​nat.​digits

data.​nat.​digits

Digits of a natural number

This provides a basic API for extracting the digits of a natural number in a given base, and reconstructing numbers from their digits.

We also prove some divisibility tests based on digits, in particular completing Theorem #85 from https://www.cs.ru.nl/~freek/100/.

def digits_aux_0  :

(Impl.) An auxiliary definition for digits, to help get the desired definitional unfolding.

Equations
def digits_aux_1  :

(Impl.) An auxiliary definition for digits, to help get the desired definitional unfolding.

Equations
def digits_aux (b : ) :
2 blist

(Impl.) An auxiliary definition for digits, to help get the desired definitional unfolding.

Equations
@[simp]
theorem digits_aux_zero (b : ) (h : 2 b) :

theorem digits_aux_def (b : ) (h : 2 b) (n : ) :
0 < ndigits_aux b h n = n % b :: digits_aux b h (n / b)

def digits  :
list

digits b n gives the digits, in little-endian order, of a natural number n in a specified base b.

In any base, we have of_digits b L = L.foldr (λ x y, x + b * y) 0.

  • For any 2 ≤ b, we have l < b for any l ∈ digits b n, and the last digit is not zero. This uniquely specifies the behaviour of digits b.
  • For b = 1, we define digits 1 n = list.repeat 1 n.
  • For b = 0, we define digits 0 n = [n], except digits 0 0 = [].

Note this differs from the existing nat.to_digits in core, which is used for printing numerals. In particular, nat.to_digits b 0 = [0], while digits b 0 = [].

Equations
@[simp]
theorem digits_zero (b : ) :

@[simp]
theorem digits_zero_zero  :

@[simp]
theorem digits_zero_succ (n : ) :
digits 0 n.succ = [n + 1]

@[simp]
theorem digits_one (n : ) :

@[simp]
theorem digits_one_succ (n : ) :
digits 1 (n + 1) = 1 :: digits 1 n

@[simp]
theorem digits_add_two_add_one (b n : ) :
digits (b + 2) (n + 1) = (n + 1) % (b + 2) :: digits (b + 2) ((n + 1) / (b + 2))

@[simp]
theorem digits_of_lt (b x : ) :
0 < xx < bdigits b x = [x]

theorem digits_add (b : ) (h : 2 b) (x y : ) :
x < b0 < x 0 < ydigits b (x + b * y) = x :: digits b y

def of_digits {α : Type u_1} [semiring α] :
α → list → α

of_digits b L takes a list L of natural numbers, and interprets them as a number in semiring, as the little-endian digits in base b.

Equations
theorem of_digits_eq_foldr {α : Type u_1} [semiring α] (b : α) (L : list ) :
of_digits b L = list.foldr (λ (x : ) (y : α), x + b * y) 0 L

@[simp]
theorem of_digits_singleton {b n : } :
of_digits b [n] = n

@[simp]
theorem of_digits_one_cons {α : Type u_1} [semiring α] (h : ) (L : list ) :
of_digits 1 (h :: L) = h + of_digits 1 L

theorem of_digits_append {b : } {l1 l2 : list } :
of_digits b (l1 ++ l2) = of_digits b l1 + b ^ l1.length * of_digits b l2

theorem coe_of_digits (α : Type u_1) [semiring α] (b : ) (L : list ) :

theorem coe_int_of_digits (b : ) (L : list ) :

theorem digits_zero_of_eq_zero {b : } (h : 1 b) {L : list } (w : of_digits b L = 0) (l : ) :
l Ll = 0

theorem digits_of_digits (b : ) (h : 2 b) (L : list ) :
(∀ (l : ), l Ll < b)(∀ (h : L list.nil), L.last h 0)digits b (of_digits b L) = L

theorem of_digits_digits (b n : ) :
of_digits b (digits b n) = n

theorem of_digits_one (L : list ) :

Properties

This section contains various lemmas of properties relating to digits and of_digits.

theorem digits_eq_nil_iff_eq_zero {b n : } :

theorem digits_last {b m : } (h : 2 b) (hm : 0 < m) (p : digits b m list.nil) (q : digits b (m / b) list.nil) :
(digits b m).last p = (digits b (m / b)).last q

theorem last_digit_ne_zero (b : ) {m : } (hm : m 0) :
(digits b m).last _ 0

theorem digits_lt_base' {b m d : } :
d digits (b + 2) md < b + 2

The digits in the base b+2 expansion of n are all less than b+2

theorem digits_lt_base {b m d : } :
2 bd digits b md < b

The digits in the base b expansion of n are all less than b, if b ≥ 2

theorem of_digits_lt_base_pow_length' {b : } {l : list } :
(∀ (x : ), x lx < b + 2)of_digits (b + 2) l < (b + 2) ^ l.length

an n-digit number in base b + 2 is less than (b + 2)^n

theorem of_digits_lt_base_pow_length {b : } {l : list } :
2 b(∀ (x : ), x lx < b)of_digits b l < b ^ l.length

an n-digit number in base b is less than b^n if b ≥ 2

theorem lt_base_pow_length_digits' {b m : } :
m < (b + 2) ^ (digits (b + 2) m).length

Any number m is less than (b+2)^(number of digits in the base b + 2 representation of m)

theorem lt_base_pow_length_digits {b m : } :
2 bm < b ^ (digits b m).length

Any number m is less than b^(number of digits in the base b representation of m)

theorem of_digits_digits_append_digits {b m n : } :
of_digits b (digits b n ++ digits b m) = n + b ^ (digits b n).length * m

theorem digits_len_le_digits_len_succ (b n : ) :
(digits b n).length (digits b (n + 1)).length

theorem le_digits_len_le (b n m : ) :
n m(digits b n).length (digits b m).length

theorem pow_length_le_mul_of_digits {b : } {l : list } (hl : l list.nil) :
l.last hl 0(b + 2) ^ l.length (b + 2) * of_digits (b + 2) l

theorem base_pow_length_digits_le' (b m : ) :
m 0(b + 2) ^ (digits (b + 2) m).length (b + 2) * m

Any non-zero natural number m is greater than (b+2)^((number of digits in the base (b+2) representation of m) - 1)

theorem base_pow_length_digits_le (b m : ) :
2 bm 0b ^ (digits b m).length b * m

Any non-zero natural number m is greater than b^((number of digits in the base b representation of m) - 1)

Modular Arithmetic

theorem dvd_of_digits_sub_of_digits {α : Type u_1} [comm_ring α] {a b k : α} (h : k a - b) (L : list ) :

theorem of_digits_modeq' (b b' k : ) (h : b b' [MOD k]) (L : list ) :

theorem of_digits_modeq (b k : ) (L : list ) :
of_digits b L of_digits (b % k) L [MOD k]

theorem of_digits_mod (b k : ) (L : list ) :
of_digits b L % k = of_digits (b % k) L % k

theorem of_digits_zmodeq' (b b' : ) (k : ) (h : b b' [ZMOD k]) (L : list ) :

theorem of_digits_zmodeq (b : ) (k : ) (L : list ) :

theorem of_digits_zmod (b : ) (k : ) (L : list ) :
of_digits b L % k = of_digits (b % k) L % k

theorem modeq_digits_sum (b b' : ) (h : b' % b = 1) (n : ) :
n (digits b' n).sum [MOD b]

theorem modeq_three_digits_sum (n : ) :
n (digits 10 n).sum [MOD 3]

theorem modeq_nine_digits_sum (n : ) :
n (digits 10 n).sum [MOD 9]

theorem zmodeq_of_digits_digits (b b' : ) (c : ) (h : b' c [ZMOD b]) (n : ) :

theorem of_digits_neg_one (L : list ) :
of_digits (-1) L = (list.map (λ (n : ), n) L).alternating_sum

theorem modeq_eleven_digits_sum (n : ) :
n (list.map (λ (n : ), n) (digits 10 n)).alternating_sum [ZMOD 11]

Divisibility

theorem dvd_iff_dvd_digits_sum (b b' : ) (h : b' % b = 1) (n : ) :
b n b (digits b' n).sum

theorem three_dvd_iff (n : ) :
3 n 3 (digits 10 n).sum

theorem nine_dvd_iff (n : ) :
9 n 9 (digits 10 n).sum

theorem dvd_iff_dvd_of_digits (b b' : ) (c : ) (h : b b' - c) (n : ) :
b n b of_digits c (digits b' n)

theorem eleven_dvd_iff (n : ) :
11 n 11 (list.map (λ (n : ), n) (digits 10 n)).alternating_sum