l3lab/ntp-mathlib huggingface dataset:
theorem cond_decide_mod_two (x : ℕ) [d : Decidable (x % 2 = 1)] :
    cond (@decide (x % 2 = 1) d) 1 0 = x % 2 := by
  

Proof state:
x : ℕ
d : Decidable (x % 2 = 1)
⊢ (bif decide (x % 2 = 1) then 1 else 0) = x % 2

Next tactic:
by_cases h : x % 2 = 1
theorem cond_decide_mod_two (x : ℕ) [d : Decidable (x % 2 = 1)] :
    cond (@decide (x % 2 = 1) d) 1 0 = x % 2 := by
  by_cases h : x % 2 = 1
  · 

Proof state:
case pos
x : ℕ
d : Decidable (x % 2 = 1)
h : x % 2 = 1
⊢ (bif decide (x % 2 = 1) then 1 else 0) = x % 2

Next tactic:
simp! [*]
theorem cond_decide_mod_two (x : ℕ) [d : Decidable (x % 2 = 1)] :
    cond (@decide (x % 2 = 1) d) 1 0 = x % 2 := by
  by_cases h : x % 2 = 1
  · simp! [*]
  · 

Proof state:
case neg
x : ℕ
d : Decidable (x % 2 = 1)
h : ¬x % 2 = 1
⊢ (bif decide (x % 2 = 1) then 1 else 0) = x % 2

Next tactic:
cases mod_two_eq_zero_or_one x
theorem cond_decide_mod_two (x : ℕ) [d : Decidable (x % 2 = 1)] :
    cond (@decide (x % 2 = 1) d) 1 0 = x % 2 := by
  by_cases h : x % 2 = 1
  · simp! [*]
  · cases mod_two_eq_zero_or_one x <;> 

Proof state:
case neg.inl
x : ℕ
d : Decidable (x % 2 = 1)
h : ¬x % 2 = 1
h✝ : x % 2 = 0
⊢ (bif decide (x % 2 = 1) then 1 else 0) = x % 2

Next tactic:
simp! [*, Nat.zero_ne_one]
theorem cond_decide_mod_two (x : ℕ) [d : Decidable (x % 2 = 1)] :
    cond (@decide (x % 2 = 1) d) 1 0 = x % 2 := by
  by_cases h : x % 2 = 1
  · simp! [*]
  · cases mod_two_eq_zero_or_one x <;> 

Proof state:
case neg.inr
x : ℕ
d : Decidable (x % 2 = 1)
h : ¬x % 2 = 1
h✝ : x % 2 = 1
⊢ (bif decide (x % 2 = 1) then 1 else 0) = x % 2

Next tactic:
simp! [*, Nat.zero_ne_one]
private def wf_lbp : WellFounded (@lbp p) :=
  ⟨let ⟨n, pn⟩ := H
    suffices ∀ m k, n ≤ k + m → Acc lbp k from fun a => this _ _ (Nat.le_add_left _ _)
    fun m =>
    Nat.recOn m
      (fun k kn =>
        ⟨_, fun y r =>
          match y, r with
          | _, ⟨rfl, a⟩ => absurd pn (a _ kn)⟩)
      fun m IH k kn =>
      ⟨_, fun y r =>
        match y, r with
        | _, ⟨rfl, _a⟩ => IH _ (by 

Proof state:
p : ℕ → Prop
inst✝ : DecidablePred p
H : ∃ n, p n
n : ℕ
pn : p n
m✝ m : ℕ
IH : ∀ (k : ℕ), n ≤ k + m → Acc Nat.lbp k
k : ℕ
kn : n ≤ k + succ m
y : ℕ
r : Nat.lbp y k
_a : ∀ (k_1 : ℕ), k_1 ≤ k → ¬p k_1
⊢ n ≤ k + 1 + m

Next tactic:
rw [Nat.add_right_comm]
private def wf_lbp : WellFounded (@lbp p) :=
  ⟨let ⟨n, pn⟩ := H
    suffices ∀ m k, n ≤ k + m → Acc lbp k from fun a => this _ _ (Nat.le_add_left _ _)
    fun m =>
    Nat.recOn m
      (fun k kn =>
        ⟨_, fun y r =>
          match y, r with
          | _, ⟨rfl, a⟩ => absurd pn (a _ kn)⟩)
      fun m IH k kn =>
      ⟨_, fun y r =>
        match y, r with
        | _, ⟨rfl, _a⟩ => IH _ (by rw [Nat.add_right_comm]; 

Proof state:
p : ℕ → Prop
inst✝ : DecidablePred p
H : ∃ n, p n
n : ℕ
pn : p n
m✝ m : ℕ
IH : ∀ (k : ℕ), n ≤ k + m → Acc Nat.lbp k
k : ℕ
kn : n ≤ k + succ m
y : ℕ
r : Nat.lbp y k
_a : ∀ (k_1 : ℕ), k_1 ≤ k → ¬p k_1
⊢ n ≤ k + m + 1

Next tactic:
exact kn
protected def findX : { n // p n ∧ ∀ m < n, ¬p m } :=
  @WellFounded.fix _ (fun k => (∀ n < k, ¬p n) → { n // p n ∧ ∀ m < n, ¬p m }) lbp (wf_lbp H)
    (fun m IH al =>
      if pm : p m then ⟨m, pm, al⟩
      else
        have : ∀ n ≤ m, ¬p n := fun n h =>
          Or.elim (Decidable.lt_or_eq_of_le h) (al n) fun e => by 

Proof state:
p : ℕ → Prop
inst✝ : DecidablePred p
H : ∃ n, p n
m : ℕ
IH : (y : ℕ) → Nat.lbp y m → (fun k => (∀ (n : ℕ), n < k → ¬p n) → { n // p n ∧ ∀ (m : ℕ), m < n → ¬p m }) y
al : ∀ (n : ℕ), n < m → ¬p n
pm : ¬p m
n : ℕ
h : n ≤ m
e : n = m
⊢ ¬p n

Next tactic:
rw [e]
protected def findX : { n // p n ∧ ∀ m < n, ¬p m } :=
  @WellFounded.fix _ (fun k => (∀ n < k, ¬p n) → { n // p n ∧ ∀ m < n, ¬p m }) lbp (wf_lbp H)
    (fun m IH al =>
      if pm : p m then ⟨m, pm, al⟩
      else
        have : ∀ n ≤ m, ¬p n := fun n h =>
          Or.elim (Decidable.lt_or_eq_of_le h) (al n) fun e => by rw [e]; 

Proof state:
p : ℕ → Prop
inst✝ : DecidablePred p
H : ∃ n, p n
m : ℕ
IH : (y : ℕ) → Nat.lbp y m → (fun k => (∀ (n : ℕ), n < k → ¬p n) → { n // p n ∧ ∀ (m : ℕ), m < n → ¬p m }) y
al : ∀ (n : ℕ), n < m → ¬p n
pm : ¬p m
n : ℕ
h : n ≤ m
e : n = m
⊢ ¬p m

Next tactic:
exact pm
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  

Proof state:
b f : ℕ
⊢ ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)

Next tactic:
induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
      exact ih trivial
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (

Proof state:
case zero
b : ℕ
⊢ ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b zero n l1) = List.length (toDigitsCore b zero n l2)

Next tactic:
simp only [Nat.toDigitsCore, List.length]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; 

Proof state:
case zero
b : ℕ
⊢ ℕ → ∀ (l1 l2 : List Char), List.length l1 = List.length l2 → List.length l1 = List.length l2

Next tactic:
intro n l1 l2 hlen
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  

Proof state:
case zero
b n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
⊢ List.length l1 = List.length l2

Next tactic:
| zero => assumption
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => 

Proof state:
case zero
b n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
⊢ List.length l1 = List.length l2

Next tactic:
assumption
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (

Proof state:
case succ
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
⊢ ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 →
      List.length (toDigitsCore b (succ f) n l1) = List.length (toDigitsCore b (succ f) n l2)

Next tactic:
simp only [Nat.toDigitsCore, List.length]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; 

Proof state:
case succ
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
⊢ ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 →
      List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
        List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
intro n l1 l2 hlen
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  

Proof state:
case succ
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
| succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
      exact ih trivial
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    

Proof state:
case succ
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
by_cases hx : n / b = 0
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    

Proof state:
case pos
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))
case neg
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => 

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    

Proof state:
case neg
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
      exact ih trivial
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
      exact ih trivial
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
⊢ List.length (if n / b = 0 then digitChar (n % b) :: l1 else toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (if n / b = 0 then digitChar (n % b) :: l2 else toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
simp only [hx, if_false]
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      simp only [hx, if_false]
      

Proof state:
b f : ℕ
ih :
  ∀ (n : ℕ) (l1 l2 : List Char),
    List.length l1 = List.length l2 → List.length (toDigitsCore b f n l1) = List.length (toDigitsCore b f n l2)
n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
⊢ List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      

Proof state:
b f n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
ih :
  List.length (digitChar (n % b) :: l1) = List.length (digitChar (n % b) :: l2) →
    List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
      List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l2))
⊢ List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
lemma to_digits_core_lens_eq_aux (b f : Nat) :
    ∀ (n : Nat) (l1 l2 : List Char), l1.length = l2.length →
    (Nat.toDigitsCore b f n l1).length = (Nat.toDigitsCore b f n l2).length := by
  induction f with (simp only [Nat.toDigitsCore, List.length]; intro n l1 l2 hlen)
  | zero => assumption
  | succ f ih =>
    by_cases hx : n / b = 0
    case pos => simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen]
    case neg =>
      simp only [hx, if_false]
      specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2)
      simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih
      

Proof state:
b f n : ℕ
l1 l2 : List Char
hlen : List.length l1 = List.length l2
hx : ¬n / b = 0
ih :
  True →
    List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
      List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l2))
⊢ List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l1)) =
    List.length (toDigitsCore b f (n / b) (digitChar (n % b) :: l2))

Next tactic:
exact ih trivial
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
  

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

Next tactic:
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
      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 succ
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),
    List.length (toDigitsCore b (succ f) n (c :: tl)) = List.length (toDigitsCore b (succ f) 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 succ
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
⊢ List.length (toDigitsCore b (succ f) n (c :: tl)) = List.length (toDigitsCore b (succ f) n tl) + 1

Next tactic:
simp only [Nat.toDigitsCore, 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])
  

Proof state:
case succ
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
⊢ 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:
| 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
      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 =>
    

Proof state:
case succ
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
⊢ 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:
by_cases hnb : (n / b) = 0