l3lab/ntp-mathlib huggingface dataset:
/-- 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)
    | succ e =>
      

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:
by_cases h_pred_pos : 0 < e
/-- 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)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      

Proof state:
case pos
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
h_pred_pos : 0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e
case neg
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
h_pred_pos : ¬0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
/-- 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)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      

Proof state:
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
h_pred_pos : 0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
/-- 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)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        

Proof state:
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
h_pred_pos : 0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
have _ : 0 < b := Nat.lt_trans (by decide) h
/-- 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)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by 

Proof state:
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
h_pred_pos : 0 < e
⊢ 0 < 1

Next tactic:
decide
/-- 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)
    | succ e =>
      by_cases h_pred_pos : 0 < e
      case pos =>
        have _ : 0 < b := Nat.lt_trans (by decide) h
        

Proof state:
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
h_pred_pos : 0 < e
x✝ : 0 < b
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
specialize ih (n / b) e (nat_repr_len_aux n b e ‹0 < b› hlt) h_pred_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)
    | 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
        

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

Next tactic:
by_cases hdiv_ten : 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
    | 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
        

Proof state:
case pos
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : n / b = 0
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e
case neg
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : ¬n / b = 0
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_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)
    | 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
        

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

Next tactic:
case pos => simp only [hdiv_ten]; exact Nat.le.step h_pred_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)
    | 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 => 

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

Next tactic:
simp only [hdiv_ten]
/-- 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)
    | 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]; 

Proof state:
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : n / b = 0
⊢ List.length (if True then [digitChar (n % b)] else toDigitsCore b f 0 [digitChar (n % b)]) ≤ succ e

Next tactic:
exact Nat.le.step h_pred_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)
    | 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
        

Proof state:
case neg
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : ¬n / b = 0
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
/-- 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)
    | 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
        

Proof state:
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : ¬n / b = 0
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
/-- 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)
    | 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 =>
          

Proof state:
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : ¬n / b = 0
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
simp only [hdiv_ten,
            to_digits_core_lens_eq b f (n / b) (Nat.digitChar $ n % b), if_false]
/-- 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)
    | 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]
          

Proof state:
b : ℕ
h : 2 ≤ b
f n e : ℕ
hlt : n < b ^ succ e
h_e_pos : 0 < succ e
h_pred_pos : 0 < e
x✝ : 0 < b
ih : List.length (toDigitsCore b f (n / b) []) ≤ e
hdiv_ten : ¬n / b = 0
⊢ List.length (toDigitsCore b f (n / b) []) + 1 ≤ succ e

Next tactic:
exact Nat.succ_le_succ ih
/-- 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)
    | 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
      

Proof state:
case neg
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
h_pred_pos : ¬0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
    | 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
      

Proof state:
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
h_pred_pos : ¬0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
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
    | 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 =>
        

Proof state:
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
h_pred_pos : ¬0 < e
⊢ List.length (if n / b = 0 then [digitChar (n % b)] else toDigitsCore b f (n / b) [digitChar (n % b)]) ≤ succ e

Next tactic:
have _ : e = 0 := Nat.eq_zero_of_not_pos h_pred_pos