Theorem: Ordinal.opow_add
File: Mathlib/SetTheory/Ordinal/Exponential.lean

tactic: rcases eq_or_ne a 0 with (rfl | a0)
state_before: a b c : Ordinal.{u_1}
⊢ a ^ (b + c) = a ^ b * a ^ c
state_after: case inl
b c : Ordinal.{u_1}
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c

case inr
a b c : Ordinal.{u_1}
a0 : a ≠ 0
⊢ a ^ (b + c) = a ^ b * a ^ c

tactic: rcases eq_or_lt_of_le (one_le_iff_ne_zero.2 a0) with (rfl | a1)
state_before: case inr
a b c : Ordinal.{u_1}
a0 : a ≠ 0
⊢ a ^ (b + c) = a ^ b * a ^ c
state_after: case inr.inl
b c : Ordinal.{u_1}
a0 : 1 ≠ 0
⊢ 1 ^ (b + c) = 1 ^ b * 1 ^ c

case inr.inr
a b c : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
⊢ a ^ (b + c) = a ^ b * a ^ c

tactic: induction c using limitRecOn with
| H₁ => simp
| H₂ c IH =>
  rw [add_succ, opow_succ, IH, opow_succ, mul_assoc]
| H₃ c l IH =>
  refine
    eq_of_forall_ge_iff fun d =>
      (((opow_isNormal a1).trans (add_isNormal b)).limit_le l).trans ?_
  dsimp only [Function.comp_def]
  simp (config := { contextual := true }) only [IH]
  exact
    (((mul_isNormal <| opow_pos b (Ordinal.pos_iff_ne_zero.2 a0)).trans
            (opow_isNormal a1)).limit_le
        l).symm
state_before: case inr.inr
a b c : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
⊢ a ^ (b + c) = a ^ b * a ^ c
state_after: no goals

tactic: rcases eq_or_ne c 0 with (rfl | c0)
state_before: case inl
b c : Ordinal.{u_1}
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c
state_after: case inl.inl
b : Ordinal.{u_1}
⊢ 0 ^ (b + 0) = 0 ^ b * 0 ^ 0

case inl.inr
b c : Ordinal.{u_1}
c0 : c ≠ 0
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c

tactic: have : b + c ≠ 0 := ((Ordinal.pos_iff_ne_zero.2 c0).trans_le (le_add_left _ _)).ne'
state_before: case inl.inr
b c : Ordinal.{u_1}
c0 : c ≠ 0
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c
state_after: case inl.inr
b c : Ordinal.{u_1}
c0 : c ≠ 0
this : b + c ≠ 0
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c

tactic: simp only [zero_opow c0, zero_opow this, mul_zero]
state_before: case inl.inr
b c : Ordinal.{u_1}
c0 : c ≠ 0
this : b + c ≠ 0
⊢ 0 ^ (b + c) = 0 ^ b * 0 ^ c
state_after: no goals

tactic: simp
state_before: case inl.inl
b : Ordinal.{u_1}
⊢ 0 ^ (b + 0) = 0 ^ b * 0 ^ 0
state_after: no goals

tactic: simp only [one_opow, mul_one]
state_before: case inr.inl
b c : Ordinal.{u_1}
a0 : 1 ≠ 0
⊢ 1 ^ (b + c) = 1 ^ b * 1 ^ c
state_after: no goals

tactic: simp
state_before: case inr.inr.H₁
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
⊢ a ^ (b + 0) = a ^ b * a ^ 0
state_after: no goals

tactic: rw [add_succ, opow_succ, IH, opow_succ, mul_assoc]
state_before: case inr.inr.H₂
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
IH : a ^ (b + c) = a ^ b * a ^ c
⊢ a ^ (b + succ c) = a ^ b * a ^ succ c
state_after: no goals

tactic: refine
  eq_of_forall_ge_iff fun d =>
    (((opow_isNormal a1).trans (add_isNormal b)).limit_le l).trans ?_
state_before: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
⊢ a ^ (b + c) = a ^ b * a ^ c
state_after: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, ((fun x => a ^ x) ∘ fun x => b + x) b_1 ≤ d) ↔ a ^ b * a ^ c ≤ d

tactic: dsimp only [Function.comp_def]
state_before: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, ((fun x => a ^ x) ∘ fun x => b + x) b_1 ≤ d) ↔ a ^ b * a ^ c ≤ d
state_after: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, a ^ (b + b_1) ≤ d) ↔ a ^ b * a ^ c ≤ d

tactic: simp (config := { contextual := true }) only [IH]
state_before: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, a ^ (b + b_1) ≤ d) ↔ a ^ b * a ^ c ≤ d
state_after: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, a ^ b * a ^ b_1 ≤ d) ↔ a ^ b * a ^ c ≤ d

tactic: exact
  (((mul_isNormal <| opow_pos b (Ordinal.pos_iff_ne_zero.2 a0)).trans
          (opow_isNormal a1)).limit_le
      l).symm
state_before: case inr.inr.H₃
a b : Ordinal.{u_1}
a0 : a ≠ 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b + o') = a ^ b * a ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, a ^ b * a ^ b_1 ≤ d) ↔ a ^ b * a ^ c ≤ d
state_after: no goals