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

tactic: by_cases b0 : b = 0
state_before: a b c : Ordinal.{u_1}
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: case pos
a b c : Ordinal.{u_1}
b0 : b = 0
⊢ a ^ (b * c) = (a ^ b) ^ c

case neg
a b c : Ordinal.{u_1}
b0 : ¬b = 0
⊢ a ^ (b * c) = (a ^ b) ^ c

tactic: by_cases a0 : a = 0
state_before: case neg
a b c : Ordinal.{u_1}
b0 : ¬b = 0
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: case pos
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : a = 0
⊢ a ^ (b * c) = (a ^ b) ^ c

case neg
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
⊢ a ^ (b * c) = (a ^ b) ^ c

tactic: cases' eq_or_lt_of_le (one_le_iff_ne_zero.2 a0) with a1 a1
state_before: case neg
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: case neg.inl
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
a1 : 1 = a
⊢ a ^ (b * c) = (a ^ b) ^ c

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

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

tactic: simp only [b0, zero_mul, opow_zero, one_opow]
state_before: case pos
a b c : Ordinal.{u_1}
b0 : b = 0
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: no goals

tactic: subst a
state_before: case pos
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : a = 0
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: case pos
b c : Ordinal.{u_1}
b0 : ¬b = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c

tactic: by_cases c0 : c = 0
state_before: case pos
b c : Ordinal.{u_1}
b0 : ¬b = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c
state_after: case pos
b c : Ordinal.{u_1}
b0 : ¬b = 0
c0 : c = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c

case neg
b c : Ordinal.{u_1}
b0 : ¬b = 0
c0 : ¬c = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c

tactic: simp only [zero_opow b0, zero_opow c0, zero_opow (mul_ne_zero b0 c0)]
state_before: case neg
b c : Ordinal.{u_1}
b0 : ¬b = 0
c0 : ¬c = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c
state_after: no goals

tactic: simp only [c0, mul_zero, opow_zero]
state_before: case pos
b c : Ordinal.{u_1}
b0 : ¬b = 0
c0 : c = 0
⊢ 0 ^ (b * c) = (0 ^ b) ^ c
state_after: no goals

tactic: subst a1
state_before: case neg.inl
a b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
a1 : 1 = a
⊢ a ^ (b * c) = (a ^ b) ^ c
state_after: case neg.inl
b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬1 = 0
⊢ 1 ^ (b * c) = (1 ^ b) ^ c

tactic: simp only [one_opow]
state_before: case neg.inl
b c : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬1 = 0
⊢ 1 ^ (b * c) = (1 ^ b) ^ c
state_after: no goals

tactic: simp only [mul_zero, opow_zero]
state_before: case neg.inr.H₁
a b : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
a1 : 1 < a
⊢ a ^ (b * 0) = (a ^ b) ^ 0
state_after: no goals

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

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

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

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

tactic: exact (opow_le_of_limit (opow_ne_zero _ a0) l).symm
state_before: case neg.inr.H₃
a b : Ordinal.{u_1}
b0 : ¬b = 0
a0 : ¬a = 0
a1 : 1 < a
c : Ordinal.{u_1}
l : c.IsLimit
IH : ∀ o' < c, a ^ (b * o') = (a ^ b) ^ o'
d : Ordinal.{u_1}
⊢ (∀ b_1 < c, (a ^ b) ^ b_1 ≤ d) ↔ (a ^ b) ^ c ≤ d
state_after: no goals