l3lab/ntp-mathlib huggingface dataset:
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    

Proof state:
case pos
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1
case neg
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
case pos => simp only [hnb, if_true, List.length]
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
case pos => simp only [hnb, if_true, List.length]
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => 

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
simp only [hnb, if_true, List.length]
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    

Proof state:
case neg
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by simp
      apply to_digits_core_lens_eq_aux
      exact lens_eq
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by simp
      apply to_digits_core_lens_eq_aux
      exact lens_eq
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
⊢ List.length
      (if n / b = 0 then digitChar (n % b) :: c :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: c :: tl)) =
    List.length (if n / b = 0 then digitChar (n % b) :: tl else toDigitsCore b f (n / b) (digitChar (n % b) :: tl)) + 1

Next tactic:
generalize hx: Nat.digitChar (n % b) = x
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
⊢ List.length (if n / b = 0 then x :: c :: tl else toDigitsCore b f (n / b) (x :: c :: tl)) =
    List.length (if n / b = 0 then x :: tl else toDigitsCore b f (n / b) (x :: tl)) + 1

Next tactic:
simp only [hx, hnb, if_false] at ih
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
⊢ List.length (if n / b = 0 then x :: c :: tl else toDigitsCore b f (n / b) (x :: c :: tl)) =
    List.length (if n / b = 0 then x :: tl else toDigitsCore b f (n / b) (x :: tl)) + 1

Next tactic:
simp only [hnb, if_false]
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b f n (c :: tl)) = List.length (toDigitsCore b f n tl) + 1
n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
⊢ List.length (toDigitsCore b f (n / b) (x :: c :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1

Next tactic:
specialize ih (n / b) c (x :: tl)
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      

Proof state:
b f n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
ih : List.length (toDigitsCore b f (n / b) (c :: x :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1
⊢ List.length (toDigitsCore b f (n / b) (x :: c :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1

Next tactic:
rw [← ih]
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      

Proof state:
b f n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
ih : List.length (toDigitsCore b f (n / b) (c :: x :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1
⊢ List.length (toDigitsCore b f (n / b) (x :: c :: tl)) = List.length (toDigitsCore b f (n / b) (c :: x :: tl))

Next tactic:
have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by simp
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by 

Proof state:
b f n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
ih : List.length (toDigitsCore b f (n / b) (c :: x :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1
⊢ List.length (x :: c :: tl) = List.length (c :: x :: tl)

Next tactic:
simp
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by simp
      

Proof state:
b f n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
ih : List.length (toDigitsCore b f (n / b) (c :: x :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1
lens_eq : List.length (x :: c :: tl) = List.length (c :: x :: tl)
⊢ List.length (toDigitsCore b f (n / b) (x :: c :: tl)) = List.length (toDigitsCore b f (n / b) (c :: x :: tl))

Next tactic:
apply to_digits_core_lens_eq_aux
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; simp only [Nat.toDigitsCore, List.length])
  | succ f ih =>
    by_cases hnb : (n / b) = 0
    case pos => simp only [hnb, if_true, List.length]
    case neg =>
      generalize hx: Nat.digitChar (n % b) = x
      simp only [hx, hnb, if_false] at ih
      simp only [hnb, if_false]
      specialize ih (n / b) c (x :: tl)
      rw [← ih]
      have lens_eq : (x :: (c :: tl)).length = (c :: x :: tl).length := by simp
      apply to_digits_core_lens_eq_aux
      

Proof state:
case a
b f n : ℕ
c : Char
tl : List Char
hnb : ¬n / b = 0
x : Char
hx : digitChar (n % b) = x
ih : List.length (toDigitsCore b f (n / b) (c :: x :: tl)) = List.length (toDigitsCore b f (n / b) (x :: tl)) + 1
lens_eq : List.length (x :: c :: tl) = List.length (c :: x :: tl)
⊢ List.length (x :: c :: tl) = List.length (c :: x :: tl)

Next tactic:
exact lens_eq
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (

Proof state:
case zero
b : ℕ
⊢ ∀ (n : ℕ) (c : Char) (tl : List Char),
    List.length (toDigitsCore b zero n (c :: tl)) = List.length (toDigitsCore b zero n tl) + 1

Next tactic:
intro n c tl
lemma to_digits_core_lens_eq (b f : Nat) : ∀ (n : Nat) (c : Char) (tl : List Char),
    (Nat.toDigitsCore b f n (c :: tl)).length = (Nat.toDigitsCore b f n tl).length + 1 := by
  induction f with (intro n c tl; 

Proof state:
case zero
b n : ℕ
c : Char
tl : List Char
⊢ List.length (toDigitsCore b zero n (c :: tl)) = List.length (toDigitsCore b zero n tl) + 1

Next tactic:
simp only [Nat.toDigitsCore, List.length]
lemma nat_repr_len_aux (n b e : Nat) (h_b_pos : 0 < b) :  n < b ^ e.succ → n / b < b ^ e := by
  

Proof state:
n b e : ℕ
h_b_pos : 0 < b
⊢ n < b ^ succ e → n / b < b ^ e

Next tactic:
simp only [Nat.pow_succ]
lemma nat_repr_len_aux (n b e : Nat) (h_b_pos : 0 < b) :  n < b ^ e.succ → n / b < b ^ e := by
  simp only [Nat.pow_succ]
  

Proof state:
n b e : ℕ
h_b_pos : 0 < b
⊢ n < b ^ e * b → n / b < b ^ e

Next tactic:
exact (@Nat.div_lt_iff_lt_mul b n (b ^ e) h_b_pos).mpr
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  

Proof state:
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ e
h_e_pos : 0 < e
⊢ List.length (toDigitsCore b f n []) ≤ e

Next tactic:
induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  | succ f ih =>
    cases e with
    | zero => exact False.elim (Nat.lt_irrefl 0 h_e_pos)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by decide) h
        specialize ih (n / b) e (nat_repr_len_aux n b e ‹0 < b› hlt) h_pred_pos
        by_cases hdiv_ten : n / b = 0
        case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_pos
        case neg =>
          simp only [hdiv_ten,
            to_digits_core_lens_eq b f (n / b) (Nat.digitChar $ n % b), if_false]
          exact Nat.succ_le_succ ih
      case neg =>
        have _ : e = 0 := Nat.eq_zero_of_not_pos h_pred_pos
        rw [‹e = 0›]
        have _ : b ^ 1 = b := by simp only [pow_succ, pow_zero, Nat.one_mul]
        have _ : n < b := ‹b ^ 1 = b› ▸ (‹e = 0› ▸ hlt : n < b ^ Nat.succ 0)
        simp [(@Nat.div_eq_of_lt n b ‹n < b› : n / b = 0)]
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    

Proof state:
case succ
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n e : ℕ
hlt : n < b ^ e
h_e_pos : 0 < e
⊢ List.length (toDigitsCore b (succ f) n []) ≤ e

Next tactic:
simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  

Proof state:
case succ
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n e : ℕ
hlt : n < b ^ e
h_e_pos : 0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ e

Next tactic:
| succ f ih =>
    cases e with
    | zero => exact False.elim (Nat.lt_irrefl 0 h_e_pos)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by decide) h
        specialize ih (n / b) e (nat_repr_len_aux n b e ‹0 < b› hlt) h_pred_pos
        by_cases hdiv_ten : n / b = 0
        case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_pos
        case neg =>
          simp only [hdiv_ten,
            to_digits_core_lens_eq b f (n / b) (Nat.digitChar $ n % b), if_false]
          exact Nat.succ_le_succ ih
      case neg =>
        have _ : e = 0 := Nat.eq_zero_of_not_pos h_pred_pos
        rw [‹e = 0›]
        have _ : b ^ 1 = b := by simp only [pow_succ, pow_zero, Nat.one_mul]
        have _ : n < b := ‹b ^ 1 = b› ▸ (‹e = 0› ▸ hlt : n < b ^ Nat.succ 0)
        simp [(@Nat.div_eq_of_lt n b ‹n < b› : n / b = 0)]
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  | succ f ih =>
    

Proof state:
case succ
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n e : ℕ
hlt : n < b ^ e
h_e_pos : 0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ e

Next tactic:
cases e with
    | zero => exact False.elim (Nat.lt_irrefl 0 h_e_pos)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by decide) h
        specialize ih (n / b) e (nat_repr_len_aux n b e ‹0 < b› hlt) h_pred_pos
        by_cases hdiv_ten : n / b = 0
        case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_pos
        case neg =>
          simp only [hdiv_ten,
            to_digits_core_lens_eq b f (n / b) (Nat.digitChar $ n % b), if_false]
          exact Nat.succ_le_succ ih
      case neg =>
        have _ : e = 0 := Nat.eq_zero_of_not_pos h_pred_pos
        rw [‹e = 0›]
        have _ : b ^ 1 = b := by simp only [pow_succ, pow_zero, Nat.one_mul]
        have _ : n < b := ‹b ^ 1 = b› ▸ (‹e = 0› ▸ hlt : n < b ^ Nat.succ 0)
        simp [(@Nat.div_eq_of_lt n b ‹n < b› : n / b = 0)]
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  | succ f ih =>
    cases e with
    

Proof state:
case succ.zero
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n : ℕ
hlt : n < b ^ zero
h_e_pos : 0 < zero
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ zero

Next tactic:
| zero => exact False.elim (Nat.lt_irrefl 0 h_e_pos)
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  | succ f ih =>
    cases e with
    | zero => 

Proof state:
case succ.zero
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n : ℕ
hlt : n < b ^ zero
h_e_pos : 0 < zero
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ zero

Next tactic:
exact False.elim (Nat.lt_irrefl 0 h_e_pos)
/-- The String representation produced by toDigitsCore has the proper length relative to
the number of digits in `n < e` for some base `b`. Since this works with any base greater
than one, it can be used for binary, decimal, and hex. -/
lemma to_digits_core_length (b : Nat) (h : 2 <= b) (f n e : Nat)
    (hlt : n < b ^ e) (h_e_pos: 0 < e) : (Nat.toDigitsCore b f n []).length <= e := by
  induction f generalizing n e hlt h_e_pos with
    simp only [Nat.toDigitsCore, List.length, Nat.zero_le]
  | succ f ih =>
    cases e with
    | zero => exact False.elim (Nat.lt_irrefl 0 h_e_pos)
    

Proof state:
case succ.succ
b : ℕ
h : 2 ≤ b
f : ℕ
ih : ∀ (n e : ℕ), n < b ^ e → 0 < e → List.length (toDigitsCore b f n []) ≤ e
n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
| succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by decide) h
        specialize ih (n / b) e (nat_repr_len_aux n b e ‹0 < b› hlt) h_pred_pos
        by_cases hdiv_ten : n / b = 0
        case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_pos
        case neg =>
          simp only [hdiv_ten,
            to_digits_core_lens_eq b f (n / b) (Nat.digitChar $ n % b), if_false]
          exact Nat.succ_le_succ ih
      case neg =>
        have _ : e = 0 := Nat.eq_zero_of_not_pos h_pred_pos
        rw [‹e = 0›]
        have _ : b ^ 1 = b := by simp only [pow_succ, pow_zero, Nat.one_mul]
        have _ : n < b := ‹b ^ 1 = b› ▸ (‹e = 0› ▸ hlt : n < b ^ Nat.succ 0)
        simp [(@Nat.div_eq_of_lt n b ‹n < b› : n / b = 0)]