l3lab/ntp-mathlib huggingface dataset:
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · 

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ repr
      (match (scale 1 b', Nat.succ k) with
      | (b, 0) => oadd (a0 * b) 1 0
      | (b, Nat.succ k) =>
        scale (a0 * b + mulNat a0 k) (oadd a0 n a') + opowAux (a0 * b) a0 (mulNat (oadd a0 n a') m) k m) =
    (ω ^ repr a0 * ↑↑n + repr a' + ↑m) ^ repr o₂

Next tactic:
simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ ((ω ^ repr a0) ^ ω ^ repr 1) ^ repr b' * ((ω ^ repr a0) ^ ↑k * repr (oadd a0 n a')) +
      repr (opowAux (a0 * scale 1 b') a0 (oadd a0 n a' * ↑m) k m) =
    ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ω) ^ repr b' *
      ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ↑k * (ω ^ repr a0 * ↑↑n + (repr a' + ↑m)))

Next tactic:
simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a')) +
      repr (opowAux (a0 * scale 1 b') a0 (oadd a0 n a' * ↑m) k m) =
    ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ω) ^ repr b' *
      ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ↑k * (ω ^ repr a0 * ↑↑n + (repr a' + ↑m)))

Next tactic:
rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a')) +
      ω ^ repr (a0 * scale 1 b') * repr (opowAux 0 a0 (oadd a0 n a' * ↑m) k m) =
    ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ↑k * (ω ^ repr a0 * ↑↑n + (repr a' + ↑m)))

Next tactic:
simp only [repr_mul, repr_scale, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one,
        add_zero, opow_one, opow_mul]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
      simp only [repr_mul, repr_scale, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one,
        add_zero, opow_one, opow_mul]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a')) +
      ((ω ^ repr a0) ^ ω) ^ repr b' * repr (opowAux 0 a0 (oadd a0 n a' * ↑m) k m) =
    ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0 * ↑↑n + (repr a' + ↑m)) ^ ↑k * (ω ^ repr a0 * ↑↑n + (repr a' + ↑m)))

Next tactic:
rw [← mul_add, ← add_assoc ((ω : Ordinal.{0}) ^ repr a0 * (n : ℕ))]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
      simp only [repr_mul, repr_scale, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one,
        add_zero, opow_one, opow_mul]
      rw [← mul_add, ← add_assoc ((ω : Ordinal.{0}) ^ repr a0 * (n : ℕ))]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ ((ω ^ repr a0) ^ ω) ^ repr b' *
      ((ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a') + repr (opowAux 0 a0 (oadd a0 n a' * ↑m) k m)) =
    ((ω ^ repr a0) ^ ω) ^ repr b' * ((ω ^ repr a0 * ↑↑n + repr a' + ↑m) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a' + ↑m))

Next tactic:
congr 1
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
      simp only [repr_mul, repr_scale, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one,
        add_zero, opow_one, opow_mul]
      rw [← mul_add, ← add_assoc ((ω : Ordinal.{0}) ^ repr a0 * (n : ℕ))]
      congr 1
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ.e_a
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ (ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a') + repr (opowAux 0 a0 (oadd a0 n a' * ↑m) k m) =
    (ω ^ repr a0 * ↑↑n + repr a' + ↑m) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a' + ↑m)

Next tactic:
rw [← opow_succ]
theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o₁ ^ repr o₂ := by
  cases' e₁ : split o₁ with a m
  cases' nf_repr_split e₁ with N₁ r₁
  cases' a with a0 n a'
  · cases' m with m
    · by_cases h : o₂ = 0 <;> simp [opow_def, opowAux2, opow, e₁, h, r₁]
      have := mt repr_inj.1 h
      rw [zero_opow this]
    · cases' e₂ : split' o₂ with b' k
      cases' nf_repr_split' e₂ with _ r₂
      by_cases h : m = 0
      · simp [opow_def, opow, e₁, h, r₁, e₂, r₂, -Nat.cast_succ, ← Nat.one_eq_succ_zero]
      simp only [opow_def, opowAux2, opow, e₁, h, r₁, e₂, r₂, repr,
          opow_zero, Nat.succPNat_coe, Nat.cast_succ, Nat.cast_zero, _root_.zero_add, mul_one,
          add_zero, one_opow, npow_eq_pow]
      rw [opow_add, opow_mul, opow_omega, add_one_eq_succ]
      congr
      conv_lhs =>
        simp only [(· ^ ·)]
        simp [Pow.pow, opow, Ordinal.succ_ne_zero]
      · simpa using nat_cast_lt.2 (Nat.succ_lt_succ <| pos_iff_ne_zero.2 h)
      · rw [← Nat.cast_succ, lt_omega]
        exact ⟨_, rfl⟩
  · haveI := N₁.fst
    haveI := N₁.snd
    cases' N₁.of_dvd_omega (split_dvd e₁) with a00 ad
    have al := split_add_lt e₁
    have aa : repr (a' + ofNat m) = repr a' + m := by
      simp only [eq_self_iff_true, ONote.repr_ofNat, ONote.repr_add]
    cases' e₂ : split' o₂ with b' k
    cases' nf_repr_split' e₂ with _ r₂
    simp only [opow_def, opow, e₁, r₁, split_eq_scale_split' e₂, opowAux2, repr]
    cases' k with k <;> skip
    · simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa,
        add_assoc, split_eq_scale_split' e₂]
    · simp [opow, opowAux2, r₂, opow_add, opow_mul, mul_assoc, add_assoc, -repr]
      simp only [repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, opow_one]
      rw [repr_opow_aux₁ a00 al aa, scale_opowAux]
      simp only [repr_mul, repr_scale, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one,
        add_zero, opow_one, opow_mul]
      rw [← mul_add, ← add_assoc ((ω : Ordinal.{0}) ^ repr a0 * (n : ℕ))]
      congr 1
      rw [← opow_succ]
      

Proof state:
case mk.intro.oadd.intro.mk.intro.succ.e_a
o₁ o₂ : ONote
inst✝¹ : NF o₁
inst✝ : NF o₂
m : ℕ
a0 : ONote
n : ℕ+
a' : ONote
e₁ : split o₁ = (oadd a0 n a', m)
N₁ : NF (oadd a0 n a')
r₁ : repr o₁ = repr (oadd a0 n a') + ↑m
this✝ : NF a0
this : NF a'
a00 : repr a0 ≠ 0
ad : ω ∣ repr a'
al : repr a' + ↑m < ω ^ repr a0
aa : repr (a' + ↑m) = repr a' + ↑m
b' : ONote
left✝ : NF b'
k : ℕ
e₂ : split' o₂ = (b', Nat.succ k)
r₂ : repr o₂ = ω * repr b' + ↑(Nat.succ k)
⊢ (ω ^ repr a0) ^ ↑k * (ω ^ repr a0 * ↑↑n + repr a') + repr (opowAux 0 a0 (oadd a0 n a' * ↑m) k m) =
    (ω ^ repr a0 * ↑↑n + repr a' + ↑m) ^ succ ↑k

Next tactic:
exact (repr_opow_aux₂ _ ad a00 al _ _).2
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  

Proof state:
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h : a < b + o
⊢ ∃ i, a < b + f i

Next tactic:
cases' lt_or_le a b with h h'
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  cases' lt_or_le a b with h h'
  · 

Proof state:
case inl
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h✝ : a < b + o
h : a < b
⊢ ∃ i, a < b + f i

Next tactic:
obtain ⟨i⟩ := id hα
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  cases' lt_or_le a b with h h'
  · obtain ⟨i⟩ := id hα
    

Proof state:
case inl.intro
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h✝ : a < b + o
h : a < b
i : α
⊢ ∃ i, a < b + f i

Next tactic:
exact ⟨i, h.trans_le (le_add_right _ _)⟩
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  cases' lt_or_le a b with h h'
  · obtain ⟨i⟩ := id hα
    exact ⟨i, h.trans_le (le_add_right _ _)⟩
  · 

Proof state:
case inr
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h : a < b + o
h' : b ≤ a
⊢ ∃ i, a < b + f i

Next tactic:
rw [← Ordinal.add_sub_cancel_of_le h', add_lt_add_iff_left] at h
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  cases' lt_or_le a b with h h'
  · obtain ⟨i⟩ := id hα
    exact ⟨i, h.trans_le (le_add_right _ _)⟩
  · rw [← Ordinal.add_sub_cancel_of_le h', add_lt_add_iff_left] at h
    

Proof state:
case inr
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h : a - b < o
h' : b ≤ a
⊢ ∃ i, a < b + f i

Next tactic:
refine' (H h).imp fun i H => _
private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → Ordinal}
    (H : ∀ ⦃a⦄, a < o → ∃ i, a < f i) {b : Ordinal} ⦃a⦄ (h : a < b + o) : ∃ i, a < b + f i := by
  cases' lt_or_le a b with h h'
  · obtain ⟨i⟩ := id hα
    exact ⟨i, h.trans_le (le_add_right _ _)⟩
  · rw [← Ordinal.add_sub_cancel_of_le h', add_lt_add_iff_left] at h
    refine' (H h).imp fun i H => _
    

Proof state:
case inr
α : Sort u_1
hα : Nonempty α
o : Ordinal.{u_2}
f : α → Ordinal.{u_2}
H✝ : ∀ ⦃a : Ordinal.{u_2}⦄, a < o → ∃ i, a < f i
b a : Ordinal.{u_2}
h : a - b < o
h' : b ≤ a
i : α
H : a - b < f i
⊢ a < b + f i

Next tactic:
rwa [← Ordinal.add_sub_cancel_of_le h', add_lt_add_iff_left]