l3lab/ntp-mathlib huggingface dataset:
theorem principal_mul_of_le_two {o : Ordinal} (ho : o ≤ 2) : Principal (· * ·) o := by
  rcases lt_or_eq_of_le ho with (ho | rfl)
  · have h₂ : succ (1 : Ordinal) = 2 := by simp
    rw [← h₂, lt_succ_iff] at ho
    rcases lt_or_eq_of_le ho with (ho | rfl)
    · rw [lt_one_iff_zero.1 ho]
      

Proof state:
case inl.inl
o : Ordinal.{u_1}
ho✝¹ : o ≤ 2
ho✝ : o ≤ 1
h₂ : succ 1 = 2
ho : o < 1
⊢ Principal (fun x x_1 => x * x_1) 0

Next tactic:
exact principal_zero
theorem principal_mul_of_le_two {o : Ordinal} (ho : o ≤ 2) : Principal (· * ·) o := by
  rcases lt_or_eq_of_le ho with (ho | rfl)
  · have h₂ : succ (1 : Ordinal) = 2 := by simp
    rw [← h₂, lt_succ_iff] at ho
    rcases lt_or_eq_of_le ho with (ho | rfl)
    · rw [lt_one_iff_zero.1 ho]
      exact principal_zero
    · 

Proof state:
case inl.inr
h₂ : succ 1 = 2
ho✝ : 1 ≤ 2
ho : 1 ≤ 1
⊢ Principal (fun x x_1 => x * x_1) 1

Next tactic:
exact principal_mul_one
theorem principal_mul_of_le_two {o : Ordinal} (ho : o ≤ 2) : Principal (· * ·) o := by
  rcases lt_or_eq_of_le ho with (ho | rfl)
  · have h₂ : succ (1 : Ordinal) = 2 := by simp
    rw [← h₂, lt_succ_iff] at ho
    rcases lt_or_eq_of_le ho with (ho | rfl)
    · rw [lt_one_iff_zero.1 ho]
      exact principal_zero
    · exact principal_mul_one
  · 

Proof state:
case inr
ho : 2 ≤ 2
⊢ Principal (fun x x_1 => x * x_1) 2

Next tactic:
exact principal_mul_two
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  

Proof state:
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂ : o ≠ 2
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · 

Proof state:
case inl
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂ : o ≠ 2
ho₁ : o < 2
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
replace ho₁ : o < succ 1 := by simpa using ho₁
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by 

Proof state:
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂ : o ≠ 2
ho₁ : o < 2
⊢ o < succ 1

Next tactic:
simpa using ho₁
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    

Proof state:
case inl
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂ : o ≠ 2
ho₁ : o < succ 1
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
rw [lt_succ_iff] at ho₁
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    rw [lt_succ_iff] at ho₁
    

Proof state:
case inl
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂ : o ≠ 2
ho₁ : o ≤ 1
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
exact principal_add_of_le_one ho₁
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    rw [lt_succ_iff] at ho₁
    exact principal_add_of_le_one ho₁
  · 

Proof state:
case inr
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂✝ : o ≠ 2
ho₂ : o > 2
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
refine' fun a b hao hbo => lt_of_le_of_lt _ (ho (max_lt hao hbo) ho₂)
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    rw [lt_succ_iff] at ho₁
    exact principal_add_of_le_one ho₁
  · refine' fun a b hao hbo => lt_of_le_of_lt _ (ho (max_lt hao hbo) ho₂)
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂✝ : o ≠ 2
ho₂ : o > 2
a b : Ordinal.{u_1}
hao : a < o
hbo : b < o
⊢ (fun x x_1 => x + x_1) a b ≤ (fun x x_1 => x * x_1) (max a b) 2

Next tactic:
dsimp only
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    rw [lt_succ_iff] at ho₁
    exact principal_add_of_le_one ho₁
  · refine' fun a b hao hbo => lt_of_le_of_lt _ (ho (max_lt hao hbo) ho₂)
    dsimp only
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂✝ : o ≠ 2
ho₂ : o > 2
a b : Ordinal.{u_1}
hao : a < o
hbo : b < o
⊢ a + b ≤ max a b * 2

Next tactic:
rw [← one_add_one_eq_two, mul_add, mul_one]
theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) :
    Principal (· + ·) o := by
  cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂
  · replace ho₁ : o < succ 1 := by simpa using ho₁
    rw [lt_succ_iff] at ho₁
    exact principal_add_of_le_one ho₁
  · refine' fun a b hao hbo => lt_of_le_of_lt _ (ho (max_lt hao hbo) ho₂)
    dsimp only
    rw [← one_add_one_eq_two, mul_add, mul_one]
    

Proof state:
case inr
o : Ordinal.{u_1}
ho : Principal (fun x x_1 => x * x_1) o
ho₂✝ : o ≠ 2
ho₂ : o > 2
a b : Ordinal.{u_1}
hao : a < o
hbo : b < o
⊢ a + b ≤ max a b + max a b

Next tactic:
exact add_le_add (le_max_left a b) (le_max_right a b)
theorem principal_mul_isLimit {o : Ordinal.{u}} (ho₂ : 2 < o) (ho : Principal (· * ·) o) :
    o.IsLimit :=
  principal_add_isLimit ((lt_succ 1).trans (by 

Proof state:
o : Ordinal.{u}
ho₂ : 2 < o
ho : Principal (fun x x_1 => x * x_1) o
⊢ succ 1 < o

Next tactic:
simpa using ho₂
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  

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

Next tactic:
refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · 

Proof state:
case refine'_1
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
⊢ a * o = o

Next tactic:
cases' le_or_gt o 2 with ho ho
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · 

Proof state:
case refine'_1.inl
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
⊢ a * o = o

Next tactic:
convert one_mul o
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      

Proof state:
case h.e'_2.h.e'_5
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
⊢ a = 1

Next tactic:
apply le_antisymm
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · 

Proof state:
case h.e'_2.h.e'_5.a
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
⊢ a ≤ 1

Next tactic:
have : a < succ 1 := hao.trans_le (by simpa using ho)
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by 

Proof state:
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
⊢ o ≤ succ 1

Next tactic:
simpa using ho
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        

Proof state:
case h.e'_2.h.e'_5.a
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
this : a < succ 1
⊢ a ≤ 1

Next tactic:
rwa [lt_succ_iff] at this
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · 

Proof state:
case h.e'_2.h.e'_5.a
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o ≤ 2
⊢ 1 ≤ a

Next tactic:
rwa [← succ_le_iff, succ_zero] at ha₀
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · 

Proof state:
case refine'_1.inr
o : Ordinal.{u_1}
h : Principal (fun x x_1 => x * x_1) o
a : Ordinal.{u_1}
ha₀ : 0 < a
hao : a < o
ho : o > 2
⊢ a * o = o

Next tactic:
exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · 

Proof state:
case refine'_2
o : Ordinal.{u_1}
h : ∀ (a : Ordinal.{u_1}), 0 < a → 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:
rcases eq_or_ne a 0 with (rfl | ha)
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · rcases eq_or_ne a 0 with (rfl | ha)
    · 

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

Next tactic:
dsimp only
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · rcases eq_or_ne a 0 with (rfl | ha)
    · dsimp only; 

Proof state:
case refine'_2.inl
o : Ordinal.{u_1}
h : ∀ (a : Ordinal.{u_1}), 0 < a → a < o → a * o = o
b : Ordinal.{u_1}
hbo : b < o
hao : 0 < o
⊢ 0 * b < o

Next tactic:
rwa [zero_mul]
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · rcases eq_or_ne a 0 with (rfl | ha)
    · dsimp only; rwa [zero_mul]
    

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

Next tactic:
rw [← Ordinal.pos_iff_ne_zero] at ha
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · rcases eq_or_ne a 0 with (rfl | ha)
    · dsimp only; rwa [zero_mul]
    rw [← Ordinal.pos_iff_ne_zero] at ha
    

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

Next tactic:
rw [← h a ha hao]
theorem principal_mul_iff_mul_left_eq {o : Ordinal} :
    Principal (· * ·) o ↔ ∀ a, 0 < a → a < o → a * o = o := by
  refine' ⟨fun h a ha₀ hao => _, fun h a b hao hbo => _⟩
  · cases' le_or_gt o 2 with ho ho
    · convert one_mul o
      apply le_antisymm
      · have : a < succ 1 := hao.trans_le (by simpa using ho)
        rwa [lt_succ_iff] at this
      · rwa [← succ_le_iff, succ_zero] at ha₀
    · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h)
  · rcases eq_or_ne a 0 with (rfl | ha)
    · dsimp only; rwa [zero_mul]
    rw [← Ordinal.pos_iff_ne_zero] at ha
    rw [← h a ha hao]
    

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

Next tactic:
exact (mul_isNormal ha).strictMono hbo
theorem principal_mul_omega : Principal (· * ·) omega := fun a b ha hb =>
  match a, b, lt_omega.1 ha, lt_omega.1 hb with
  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ => by
    

Proof state:
a b : Ordinal.{u_1}
m n : ℕ
ha : ↑m < ω
hb : ↑n < ω
⊢ (fun x x_1 => x * x_1) ↑m ↑n < ω

Next tactic:
dsimp only
theorem principal_mul_omega : Principal (· * ·) omega := fun a b ha hb =>
  match a, b, lt_omega.1 ha, lt_omega.1 hb with
  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ => by
    dsimp only; 

Proof state:
a b : Ordinal.{u_1}
m n : ℕ
ha : ↑m < ω
hb : ↑n < ω
⊢ ↑m * ↑n < ω

Next tactic:
rw [← nat_cast_mul]
theorem principal_mul_omega : Principal (· * ·) omega := fun a b ha hb =>
  match a, b, lt_omega.1 ha, lt_omega.1 hb with
  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ => by
    dsimp only; rw [← nat_cast_mul]
    

Proof state:
a b : Ordinal.{u_1}
m n : ℕ
ha : ↑m < ω
hb : ↑n < ω
⊢ ↑(m * n) < ω

Next tactic:
apply nat_lt_omega
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  

Proof state:
a b c : Ordinal.{u_1}
c0 : 0 < c
ha : a < ω ^ c
hb : b < ω
⊢ a * b < ω ^ c

Next tactic:
rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · 

Proof state:
case inl
a b : Ordinal.{u_1}
hb : b < ω
c0 : 0 < 0
ha : a < ω ^ 0
⊢ a * b < ω ^ 0

Next tactic:
exact (lt_irrefl _).elim c0
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · 

Proof state:
case inr.inl.intro
a b : Ordinal.{u_1}
hb : b < ω
c : Ordinal.{u_1}
c0 : 0 < succ c
ha : a < ω ^ succ c
⊢ a * b < ω ^ succ c

Next tactic:
rw [opow_succ] at ha
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    

Proof state:
case inr.inl.intro
a b : Ordinal.{u_1}
hb : b < ω
c : Ordinal.{u_1}
c0 : 0 < succ c
ha : a < ω ^ c * ω
⊢ a * b < ω ^ succ c

Next tactic:
rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    

Proof state:
case inr.inl.intro.intro.intro
a b : Ordinal.{u_1}
hb : b < ω
c : Ordinal.{u_1}
c0 : 0 < succ c
ha : a < ω ^ c * ω
n : Ordinal.{u_1}
hn : n < ω
an : a < ω ^ c * n
⊢ a * b < ω ^ succ c

Next tactic:
apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    

Proof state:
case inr.inl.intro.intro.intro
a b : Ordinal.{u_1}
hb : b < ω
c : Ordinal.{u_1}
c0 : 0 < succ c
ha : a < ω ^ c * ω
n : Ordinal.{u_1}
hn : n < ω
an : a < ω ^ c * n
⊢ ω ^ c * n * b < ω ^ succ c

Next tactic:
rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
    

Proof state:
case inr.inl.intro.intro.intro
a b : Ordinal.{u_1}
hb : b < ω
c : Ordinal.{u_1}
c0 : 0 < succ c
ha : a < ω ^ c * ω
n : Ordinal.{u_1}
hn : n < ω
an : a < ω ^ c * n
⊢ n * b < ω

Next tactic:
exact principal_mul_omega hn hb
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
    exact principal_mul_omega hn hb
  · 

Proof state:
case inr.inr
a b c : Ordinal.{u_1}
c0 : 0 < c
ha : a < ω ^ c
hb : b < ω
l : IsLimit c
⊢ a * b < ω ^ c

Next tactic:
rcases ((opow_isNormal one_lt_omega).limit_lt l).1 ha with ⟨x, hx, ax⟩
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
    exact principal_mul_omega hn hb
  · rcases ((opow_isNormal one_lt_omega).limit_lt l).1 ha with ⟨x, hx, ax⟩
    

Proof state:
case inr.inr.intro.intro
a b c : Ordinal.{u_1}
c0 : 0 < c
ha : a < ω ^ c
hb : b < ω
l : IsLimit c
x : Ordinal.{u_1}
hx : x < c
ax : a < ω ^ x
⊢ a * b < ω ^ c

Next tactic:
refine' (mul_le_mul' (le_of_lt ax) (le_of_lt hb)).trans_lt _
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
    exact principal_mul_omega hn hb
  · rcases ((opow_isNormal one_lt_omega).limit_lt l).1 ha with ⟨x, hx, ax⟩
    refine' (mul_le_mul' (le_of_lt ax) (le_of_lt hb)).trans_lt _
    

Proof state:
case inr.inr.intro.intro
a b c : Ordinal.{u_1}
c0 : 0 < c
ha : a < ω ^ c
hb : b < ω
l : IsLimit c
x : Ordinal.{u_1}
hx : x < c
ax : a < ω ^ x
⊢ ω ^ x * ω < ω ^ c

Next tactic:
rw [← opow_succ, opow_lt_opow_iff_right one_lt_omega]
theorem mul_lt_omega_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < (omega^c)) (hb : b < omega) :
    a * b < (omega^c) := by
  rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l)
  · exact (lt_irrefl _).elim c0
  · rw [opow_succ] at ha
    rcases ((mul_isNormal <| opow_pos _ omega_pos).limit_lt omega_isLimit).1 ha with ⟨n, hn, an⟩
    apply (mul_le_mul_right' (le_of_lt an) _).trans_lt
    rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega_pos)]
    exact principal_mul_omega hn hb
  · rcases ((opow_isNormal one_lt_omega).limit_lt l).1 ha with ⟨x, hx, ax⟩
    refine' (mul_le_mul' (le_of_lt ax) (le_of_lt hb)).trans_lt _
    rw [← opow_succ, opow_lt_opow_iff_right one_lt_omega]
    

Proof state:
case inr.inr.intro.intro
a b c : Ordinal.{u_1}
c0 : 0 < c
ha : a < ω ^ c
hb : b < ω
l : IsLimit c
x : Ordinal.{u_1}
hx : x < c
ax : a < ω ^ x
⊢ succ x < c

Next tactic:
exact l.2 _ hx
theorem mul_omega_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < (omega^omega^b)) :
    a * (omega^omega^b) = (omega^omega^b) := by
  

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

Next tactic:
by_cases b0 : b = 0
theorem mul_omega_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < (omega^omega^b)) :
    a * (omega^omega^b) = (omega^omega^b) := by
  by_cases b0 : b = 0;
  · 

Proof state:
case pos
a b : Ordinal.{u_1}
a0 : 0 < a
h : a < ω ^ ω ^ b
b0 : b = 0
⊢ a * ω ^ ω ^ b = ω ^ ω ^ b

Next tactic:
rw [b0, opow_zero, opow_one] at h ⊢
theorem mul_omega_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < (omega^omega^b)) :
    a * (omega^omega^b) = (omega^omega^b) := by
  by_cases b0 : b = 0;
  · rw [b0, opow_zero, opow_one] at h ⊢
    

Proof state:
case pos
a b : Ordinal.{u_1}
a0 : 0 < a
h : a < ω
b0 : b = 0
⊢ a * ω = ω

Next tactic:
exact mul_omega a0 h
theorem mul_omega_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < (omega^omega^b)) :
    a * (omega^omega^b) = (omega^omega^b) := by
  by_cases b0 : b = 0;
  · rw [b0, opow_zero, opow_one] at h ⊢
    exact mul_omega a0 h
  

Proof state:
case neg
a b : Ordinal.{u_1}
a0 : 0 < a
h : a < ω ^ ω ^ b
b0 : ¬b = 0
⊢ a * ω ^ ω ^ b = ω ^ ω ^ b

Next tactic:
refine'
    le_antisymm _
      (by simpa only [one_mul] using mul_le_mul_right' (one_le_iff_pos.2 a0) (omega^omega^b))
theorem mul_omega_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < (omega^omega^b)) :
    a * (omega^omega^b) = (omega^omega^b) := by
  by_cases b0 : b = 0;
  · rw [b0, opow_zero, opow_one] at h ⊢
    exact mul_omega a0 h
  refine'
    le_antisymm _
      (by 

Proof state:
a b : Ordinal.{u_1}
a0 : 0 < a
h : a < ω ^ ω ^ b
b0 : ¬b = 0
⊢ ω ^ ω ^ b ≤ a * ω ^ ω ^ b

Next tactic:
simpa only [one_mul] using mul_le_mul_right' (one_le_iff_pos.2 a0) (omega^omega^b)