l3lab/ntp-mathlib huggingface dataset:
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    

Proof state:
case refine'_1
o : Ordinal.{u_1}
ho₁ : 1 < 0
ho : Principal (fun x x_1 => x + x_1) o
ho₀ : o = 0
⊢ False

Next tactic:
exact not_lt_of_gt zero_lt_one ho₁
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    exact not_lt_of_gt zero_lt_one ho₁
  · 

Proof state:
case refine'_2
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
⊢ succ a < o

Next tactic:
rcases eq_or_ne a 0 with ha | ha
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    exact not_lt_of_gt zero_lt_one ho₁
  · rcases eq_or_ne a 0 with ha | ha
    · 

Proof state:
case refine'_2.inl
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ha : a = 0
⊢ succ a < o

Next tactic:
rw [ha, succ_zero]
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    exact not_lt_of_gt zero_lt_one ho₁
  · rcases eq_or_ne a 0 with ha | ha
    · rw [ha, succ_zero]
      

Proof state:
case refine'_2.inl
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ha : a = 0
⊢ 1 < o

Next tactic:
exact ho₁
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    exact not_lt_of_gt zero_lt_one ho₁
  · rcases eq_or_ne a 0 with ha | ha
    · rw [ha, succ_zero]
      exact ho₁
    · 

Proof state:
case refine'_2.inr
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ha : a ≠ 0
⊢ succ a < o

Next tactic:
refine' lt_of_le_of_lt _ (ho hao hao)
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · rw [ho₀] at ho₁
    exact not_lt_of_gt zero_lt_one ho₁
  · rcases eq_or_ne a 0 with ha | ha
    · rw [ha, succ_zero]
      exact ho₁
    · refine' lt_of_le_of_lt _ (ho hao hao)
      

Proof state:
case refine'_2.inr
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ha : a ≠ 0
⊢ succ a ≤ (fun x x_1 => x + x_1) a a

Next tactic:
rwa [← add_one_eq_succ, add_le_add_iff_left, one_le_iff_ne_zero]
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  

Proof state:
o : Ordinal.{u_1}
⊢ Principal (fun x x_1 => x + x_1) o ↔ ∀ a < o, a + o = o

Next tactic:
refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · 

Proof state:
case refine'_1
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
⊢ a + o = o

Next tactic:
cases' lt_or_le 1 o with ho₁ ho₁
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · 

Proof state:
case refine'_1.inl
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ho₁ : 1 < o
⊢ a + o = o

Next tactic:
exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · 

Proof state:
case refine'_1.inr
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) o
a : Ordinal.{u_1}
hao : a < o
ho₁ : o ≤ 1
⊢ a + o = o

Next tactic:
rcases le_one_iff.1 ho₁ with (rfl | rfl)
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · rcases le_one_iff.1 ho₁ with (rfl | rfl)
      · 

Proof state:
case refine'_1.inr.inl
a : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) 0
hao : a < 0
ho₁ : 0 ≤ 1
⊢ a + 0 = 0

Next tactic:
exact (Ordinal.not_lt_zero a hao).elim
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · rcases le_one_iff.1 ho₁ with (rfl | rfl)
      · exact (Ordinal.not_lt_zero a hao).elim
      · 

Proof state:
case refine'_1.inr.inr
a : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) 1
hao : a < 1
ho₁ : 1 ≤ 1
⊢ a + 1 = 1

Next tactic:
rw [lt_one_iff_zero] at hao
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · rcases le_one_iff.1 ho₁ with (rfl | rfl)
      · exact (Ordinal.not_lt_zero a hao).elim
      · rw [lt_one_iff_zero] at hao
        

Proof state:
case refine'_1.inr.inr
a : Ordinal.{u_1}
ho : Principal (fun x x_1 => x + x_1) 1
hao : a = 0
ho₁ : 1 ≤ 1
⊢ a + 1 = 1

Next tactic:
rw [hao, zero_add]
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · rcases le_one_iff.1 ho₁ with (rfl | rfl)
      · exact (Ordinal.not_lt_zero a hao).elim
      · rw [lt_one_iff_zero] at hao
        rw [hao, zero_add]
  · 

Proof state:
case refine'_2
o : Ordinal.{u_1}
h : ∀ a < o, a + o = o
a b : Ordinal.{u_1}
hao : a < o
hbo : b < o
⊢ (fun x x_1 => x + x_1) a b < o

Next tactic:
rw [← h a hao]
theorem principal_add_iff_add_left_eq_self {o : Ordinal} :
    Principal (· + ·) o ↔ ∀ a < o, a + o = o := by
  refine' ⟨fun ho a hao => _, fun h a b hao hbo => _⟩
  · cases' lt_or_le 1 o with ho₁ ho₁
    · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho)
    · rcases le_one_iff.1 ho₁ with (rfl | rfl)
      · exact (Ordinal.not_lt_zero a hao).elim
      · rw [lt_one_iff_zero] at hao
        rw [hao, zero_add]
  · rw [← h a hao]
    

Proof state:
case refine'_2
o : Ordinal.{u_1}
h : ∀ a < o, a + o = o
a b : Ordinal.{u_1}
hao : a < o
hbo : b < o
⊢ (fun x x_1 => x + x_1) a b < a + o

Next tactic:
exact (add_isNormal a).strictMono hbo
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  

Proof state:
a : Ordinal.{u_1}
ha : ¬Principal (fun x x_1 => x + x_1) a
⊢ ∃ b c, ∃ (_ : b < a) (_ : c < a), b + c = a

Next tactic:
unfold Principal at ha
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  unfold Principal at ha
  

Proof state:
a : Ordinal.{u_1}
ha : ¬∀ ⦃a_1 b : Ordinal.{u_1}⦄, a_1 < a → b < a → (fun x x_1 => x + x_1) a_1 b < a
⊢ ∃ b c, ∃ (_ : b < a) (_ : c < a), b + c = a

Next tactic:
push_neg at ha
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  unfold Principal at ha
  push_neg at ha
  

Proof state:
a : Ordinal.{u_1}
ha : ∃ a_1 b, a_1 < a ∧ b < a ∧ a ≤ a_1 + b
⊢ ∃ b c, ∃ (_ : b < a) (_ : c < a), b + c = a

Next tactic:
rcases ha with ⟨b, c, hb, hc, H⟩
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  unfold Principal at ha
  push_neg at ha
  rcases ha with ⟨b, c, hb, hc, H⟩
  

Proof state:
case intro.intro.intro.intro
a b c : Ordinal.{u_1}
hb : b < a
hc : c < a
H : a ≤ b + c
⊢ ∃ b c, ∃ (_ : b < a) (_ : c < a), b + c = a

Next tactic:
refine'
    ⟨b, _, hb, lt_of_le_of_ne (sub_le_self a b) fun hab => _, Ordinal.add_sub_cancel_of_le hb.le⟩
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  unfold Principal at ha
  push_neg at ha
  rcases ha with ⟨b, c, hb, hc, H⟩
  refine'
    ⟨b, _, hb, lt_of_le_of_ne (sub_le_self a b) fun hab => _, Ordinal.add_sub_cancel_of_le hb.le⟩
  

Proof state:
case intro.intro.intro.intro
a b c : Ordinal.{u_1}
hb : b < a
hc : c < a
H : a ≤ b + c
hab : a - b = a
⊢ False

Next tactic:
rw [← sub_le, hab] at H
theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) :
    ∃ (b c : _) (_ : b < a) (_ : c < a), b + c = a := by
  unfold Principal at ha
  push_neg at ha
  rcases ha with ⟨b, c, hb, hc, H⟩
  refine'
    ⟨b, _, hb, lt_of_le_of_ne (sub_le_self a b) fun hab => _, Ordinal.add_sub_cancel_of_le hb.le⟩
  rw [← sub_le, hab] at H
  

Proof state:
case intro.intro.intro.intro
a b c : Ordinal.{u_1}
hb : b < a
hc : c < a
H : a ≤ c
hab : a - b = a
⊢ False

Next tactic:
exact H.not_lt hc
theorem principal_add_iff_add_lt_ne_self {a} :
    Principal (· + ·) a ↔ ∀ ⦃b c⦄, b < a → c < a → b + c ≠ a :=
  ⟨fun ha b c hb hc => (ha hb hc).ne, fun H => by
    

Proof state:
a : Ordinal.{u_1}
H : ∀ ⦃b c : Ordinal.{u_1}⦄, b < a → c < a → b + c ≠ a
⊢ Principal (fun x x_1 => x + x_1) a

Next tactic:
by_contra! ha
theorem principal_add_iff_add_lt_ne_self {a} :
    Principal (· + ·) a ↔ ∀ ⦃b c⦄, b < a → c < a → b + c ≠ a :=
  ⟨fun ha b c hb hc => (ha hb hc).ne, fun H => by
    by_contra! ha
    

Proof state:
a : Ordinal.{u_1}
H : ∀ ⦃b c : Ordinal.{u_1}⦄, b < a → c < a → b + c ≠ a
ha : ¬Principal (fun x x_1 => x + x_1) a
⊢ False

Next tactic:
rcases exists_lt_add_of_not_principal_add ha with ⟨b, c, hb, hc, rfl⟩
theorem principal_add_iff_add_lt_ne_self {a} :
    Principal (· + ·) a ↔ ∀ ⦃b c⦄, b < a → c < a → b + c ≠ a :=
  ⟨fun ha b c hb hc => (ha hb hc).ne, fun H => by
    by_contra! ha
    rcases exists_lt_add_of_not_principal_add ha with ⟨b, c, hb, hc, rfl⟩
    

Proof state:
case intro.intro.intro.intro
b c : Ordinal.{u_1}
H : ∀ ⦃b_1 c_1 : Ordinal.{u_1}⦄, b_1 < b + c → c_1 < b + c → b_1 + c_1 ≠ b + c
ha : ¬Principal (fun x x_1 => x + x_1) (b + c)
hb : b < b + c
hc : c < b + c
⊢ False

Next tactic:
exact (H hb hc).irrefl
theorem add_omega {a : Ordinal} (h : a < omega) : a + omega = omega := by
  

Proof state:
a : Ordinal.{u_1}
h : a < ω
⊢ a + ω = ω

Next tactic:
rcases lt_omega.1 h with ⟨n, rfl⟩
theorem add_omega {a : Ordinal} (h : a < omega) : a + omega = omega := by
  rcases lt_omega.1 h with ⟨n, rfl⟩
  

Proof state:
case intro
n : ℕ
h : ↑n < ω
⊢ ↑n + ω = ω

Next tactic:
clear h
theorem add_omega {a : Ordinal} (h : a < omega) : a + omega = omega := by
  rcases lt_omega.1 h with ⟨n, rfl⟩
  clear h; 

Proof state:
case intro
n : ℕ
⊢ ↑n + ω = ω

Next tactic:
induction' n with n IH
theorem add_omega {a : Ordinal} (h : a < omega) : a + omega = omega := by
  rcases lt_omega.1 h with ⟨n, rfl⟩
  clear h; induction' n with n IH
  · 

Proof state:
case intro.zero
⊢ ↑Nat.zero + ω = ω

Next tactic:
rw [Nat.cast_zero, zero_add]
theorem add_omega {a : Ordinal} (h : a < omega) : a + omega = omega := by
  rcases lt_omega.1 h with ⟨n, rfl⟩
  clear h; induction' n with n IH
  · rw [Nat.cast_zero, zero_add]
  · 

Proof state:
case intro.succ
n : ℕ
IH : ↑n + ω = ω
⊢ ↑(Nat.succ n) + ω = ω

Next tactic:
rwa [Nat.cast_succ, add_assoc, one_add_of_omega_le (le_refl _)]
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  

Proof state:
a b : Ordinal.{u_1}
h : a < ω ^ b
⊢ a + ω ^ b = ω ^ b

Next tactic:
refine' le_antisymm _ (le_add_left _ _)
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  

Proof state:
a b : Ordinal.{u_1}
h : a < ω ^ b
⊢ a + ω ^ b ≤ ω ^ b

Next tactic:
induction' b using limitRecOn with b _ b l IH
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · 

Proof state:
case H₁
a : Ordinal.{u_1}
h : a < ω ^ 0
⊢ a + ω ^ 0 ≤ ω ^ 0

Next tactic:
rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    

Proof state:
case H₁
a : Ordinal.{u_1}
h : a = 0
⊢ a + ω ^ 0 ≤ ω ^ 0

Next tactic:
rw [h, zero_add]
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · 

Proof state:
case H₂
a b : Ordinal.{u_1}
a✝ : a < ω ^ b → a + ω ^ b ≤ ω ^ b
h : a < ω ^ succ b
⊢ a + ω ^ succ b ≤ ω ^ succ b

Next tactic:
rw [opow_succ] at h
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · rw [opow_succ] at h
    

Proof state:
case H₂
a b : Ordinal.{u_1}
a✝ : a < ω ^ b → a + ω ^ b ≤ ω ^ b
h : a < ω ^ b * ω
⊢ a + ω ^ succ b ≤ ω ^ succ b

Next tactic:
rcases (lt_mul_of_limit omega_isLimit).1 h with ⟨x, xo, ax⟩
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · rw [opow_succ] at h
    rcases (lt_mul_of_limit omega_isLimit).1 h with ⟨x, xo, ax⟩
    

Proof state:
case H₂.intro.intro
a b : Ordinal.{u_1}
a✝ : a < ω ^ b → a + ω ^ b ≤ ω ^ b
h : a < ω ^ b * ω
x : Ordinal.{u_1}
xo : x < ω
ax : a < ω ^ b * x
⊢ a + ω ^ succ b ≤ ω ^ succ b

Next tactic:
refine' le_trans (add_le_add_right (le_of_lt ax) _) _
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · rw [opow_succ] at h
    rcases (lt_mul_of_limit omega_isLimit).1 h with ⟨x, xo, ax⟩
    refine' le_trans (add_le_add_right (le_of_lt ax) _) _
    

Proof state:
case H₂.intro.intro
a b : Ordinal.{u_1}
a✝ : a < ω ^ b → a + ω ^ b ≤ ω ^ b
h : a < ω ^ b * ω
x : Ordinal.{u_1}
xo : x < ω
ax : a < ω ^ b * x
⊢ ω ^ b * x + ω ^ succ b ≤ ω ^ succ b

Next tactic:
rw [opow_succ, ← mul_add, add_omega xo]
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · rw [opow_succ] at h
    rcases (lt_mul_of_limit omega_isLimit).1 h with ⟨x, xo, ax⟩
    refine' le_trans (add_le_add_right (le_of_lt ax) _) _
    rw [opow_succ, ← mul_add, add_omega xo]
  · 

Proof state:
case H₃
a b : Ordinal.{u_1}
l : IsLimit b
IH : ∀ o' < b, a < ω ^ o' → a + ω ^ o' ≤ ω ^ o'
h : a < ω ^ b
⊢ a + ω ^ b ≤ ω ^ b

Next tactic:
rcases (lt_opow_of_limit omega_ne_zero l).1 h with ⟨x, xb, ax⟩
theorem add_omega_opow {a b : Ordinal} (h : a < (omega^b)) : a + (omega^b) = (omega^b) := by
  refine' le_antisymm _ (le_add_left _ _)
  induction' b using limitRecOn with b _ b l IH
  · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h
    rw [h, zero_add]
  · rw [opow_succ] at h
    rcases (lt_mul_of_limit omega_isLimit).1 h with ⟨x, xo, ax⟩
    refine' le_trans (add_le_add_right (le_of_lt ax) _) _
    rw [opow_succ, ← mul_add, add_omega xo]
  · rcases (lt_opow_of_limit omega_ne_zero l).1 h with ⟨x, xb, ax⟩
    

Proof state:
case H₃.intro.intro
a b : Ordinal.{u_1}
l : IsLimit b
IH : ∀ o' < b, a < ω ^ o' → a + ω ^ o' ≤ ω ^ o'
h : a < ω ^ b
x : Ordinal.{u_1}
xb : x < b
ax : a < ω ^ x
⊢ a + ω ^ b ≤ ω ^ b

Next tactic:
exact
      (((add_isNormal a).trans (opow_isNormal one_lt_omega)).limit_le l).2 fun y yb =>
        (add_le_add_left (opow_le_opow_right omega_pos (le_max_right _ _)) _).trans
          (le_trans
            (IH _ (max_lt xb yb) (ax.trans_le <| opow_le_opow_right omega_pos (le_max_left _ _)))
            (opow_le_opow_right omega_pos <| le_of_lt <| max_lt xb yb))
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  

Proof state:
o : Ordinal.{u_1}
⊢ Principal (fun x x_1 => x + x_1) o ↔ o = 0 ∨ ∃ a, o = ω ^ a

Next tactic:
rcases eq_or_ne o 0 with (rfl | ho)
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · 

Proof state:
case inl
⊢ Principal (fun x x_1 => x + x_1) 0 ↔ 0 = 0 ∨ ∃ a, 0 = ω ^ a

Next tactic:
simp only [principal_zero, Or.inl]
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · 

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
⊢ Principal (fun x x_1 => x + x_1) o ↔ o = 0 ∨ ∃ a, o = ω ^ a

Next tactic:
rw [principal_add_iff_add_left_eq_self]
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
⊢ (∀ a < o, a + o = o) ↔ o = 0 ∨ ∃ a, o = ω ^ a

Next tactic:
simp only [ho, false_or_iff]
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
⊢ (∀ a < o, a + o = o) ↔ ∃ a, o = ω ^ a

Next tactic:
refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
H : ∀ a < o, a + o = o
h : ω ^ log ω o < o
⊢ False

Next tactic:
have := H _ h
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
    have := H _ h
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
H : ∀ a < o, a + o = o
h : ω ^ log ω o < o
this : ω ^ log ω o + o = o
⊢ False

Next tactic:
have := lt_opow_succ_log_self one_lt_omega o
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
    have := H _ h
    have := lt_opow_succ_log_self one_lt_omega o
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
H : ∀ a < o, a + o = o
h : ω ^ log ω o < o
this✝ : ω ^ log ω o + o = o
this : o < ω ^ succ (log ω o)
⊢ False

Next tactic:
rw [opow_succ, lt_mul_of_limit omega_isLimit] at this
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
    have := H _ h
    have := lt_opow_succ_log_self one_lt_omega o
    rw [opow_succ, lt_mul_of_limit omega_isLimit] at this
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : o ≠ 0
H : ∀ a < o, a + o = o
h : ω ^ log ω o < o
this✝ : ω ^ log ω o + o = o
this : ∃ c' < ω, o < ω ^ log ω o * c'
⊢ False

Next tactic:
rcases this with ⟨a, ao, h'⟩
/-- The main characterization theorem for additive principal ordinals. -/
theorem principal_add_iff_zero_or_omega_opow {o : Ordinal} :
    Principal (· + ·) o ↔ o = 0 ∨ ∃ a : Ordinal, o = (omega^a) := by
  rcases eq_or_ne o 0 with (rfl | ho)
  · simp only [principal_zero, Or.inl]
  · rw [principal_add_iff_add_left_eq_self]
    simp only [ho, false_or_iff]
    refine'
      ⟨fun H => ⟨_, ((lt_or_eq_of_le (opow_log_le_self _ ho)).resolve_left fun h => _).symm⟩,
        fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega_opow⟩
    have := H _ h
    have := lt_opow_succ_log_self one_lt_omega o
    rw [opow_succ, lt_mul_of_limit omega_isLimit] at this
    rcases this with ⟨a, ao, h'⟩
    

Proof state:
case inr.intro.intro
o : Ordinal.{u_1}
ho : o ≠ 0
H : ∀ a < o, a + o = o
h : ω ^ log ω o < o
this : ω ^ log ω o + o = o
a : Ordinal.{u_1}
ao : a < ω
h' : o < ω ^ log ω o * a
⊢ False

Next tactic:
rcases lt_omega.1 ao with ⟨n, rfl⟩