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 ≤ b → ℕ → list ℕ

(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 < n → digits_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 < x → x < b → digits b x = [x]

theorem digits_add (b : ℕ) (h : 2 ≤ b) (x y : ℕ) :
x < b → 0 < x ∨ 0 < y → digits 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 ∈ L → l = 0

theorem digits_of_digits (b : ℕ) (h : 2 ≤ b) (L : list ℕ) :
(∀ (l : ℕ), l ∈ L → l < 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) m → d < 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 ≤ b → d ∈ digits b m → d < 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 ∈ l → x < 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 ∈ l → x < 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 ≤ b → m < 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 ≤ b → m ≠ 0 → b ^ (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