l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    

Proof state:
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
by_cases e0 : e₂ = 0
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> 

Proof state:
case pos
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : e₂ = 0
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
simp [e0, mul]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> 

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
simp [e0, mul]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · 

Proof state:
case pos
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : e₂ = 0
⊢ ω ^ repr e₁ * (↑↑n₁ * ↑↑n₂) + repr a₁ = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (↑↑n₂ + repr a₂)

Next tactic:
cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      

Proof state:
case pos.intro
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : e₂ = 0
x : ℕ
xe : ↑n₂ = Nat.succ x
⊢ ω ^ repr e₁ * (↑↑n₁ * ↑↑n₂) + repr a₁ = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (↑↑n₂ + repr a₂)

Next tactic:
simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      

Proof state:
case pos.intro
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : e₂ = 0
x : ℕ
xe : ↑n₂ = Nat.succ x
⊢ ω ^ repr e₁ * (↑↑n₁ * ↑(Nat.succ x)) + repr a₁ = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * ↑(Nat.succ x)

Next tactic:
rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · 

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (ω ^ repr e₂ * ↑↑n₂ + repr a₂)

Next tactic:
haveI := h₁.fst
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this : NF e₁
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (ω ^ repr e₂ * ↑↑n₂ + repr a₂)

Next tactic:
haveI := h₂.fst
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (ω ^ repr e₂ * ↑↑n₂ + repr a₂)

Next tactic:
simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ ω ^ repr e₁ * ω ^ repr e₂ * ↑↑n₂ + (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * repr a₂ =
    (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * (ω ^ repr e₂ * ↑↑n₂) + (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * repr a₂

Next tactic:
rw [← mul_assoc]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
      rw [← mul_assoc]
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ ω ^ repr e₁ * ω ^ repr e₂ * ↑↑n₂ + (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * repr a₂ =
    (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * ω ^ repr e₂ * ↑↑n₂ + (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * repr a₂

Next tactic:
congr 2
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
      rw [← mul_assoc]
      congr 2
      

Proof state:
case neg.e_a.e_a
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ ω ^ repr e₁ * ω ^ repr e₂ = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * ω ^ repr e₂

Next tactic:
have := mt repr_inj.1 e0
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
      rw [← mul_assoc]
      congr 2
      have := mt repr_inj.1 e0
      

Proof state:
case neg.e_a.e_a
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝¹ : NF e₁
this✝ : NF e₂
this : ¬repr e₂ = repr 0
⊢ ω ^ repr e₁ * ω ^ repr e₂ = (ω ^ repr e₁ * ↑↑n₁ + repr a₁) * ω ^ repr e₂

Next tactic:
rw [add_mul_limit ao (opow_isLimit_left omega_isLimit this), mul_assoc,
        mul_omega_dvd (nat_cast_pos.2 n₁.pos) (nat_lt_omega _)]
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm
  | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
    conv =>
      lhs
      simp [(· * ·)]
    have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by
      apply add_absorp h₁.snd'.repr_lt
      simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)
    by_cases e0 : e₂ = 0 <;> simp [e0, mul]
    · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe
      simp only [xe, h₂.zero_of_zero e0, repr, add_zero]
      rw [nat_cast_succ x, add_mul_succ _ ao, mul_assoc]
    · haveI := h₁.fst
      haveI := h₂.fst
      simp only [Mul.mul, mul, e0, ite_false, repr._eq_2, repr_add, opow_add, IH, repr, mul_add]
      rw [← mul_assoc]
      congr 2
      have := mt repr_inj.1 e0
      rw [add_mul_limit ao (opow_isLimit_left omega_isLimit this), mul_assoc,
        mul_omega_dvd (nat_cast_pos.2 n₁.pos) (nat_lt_omega _)]
      

Proof state:
case neg.e_a.e_a
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
IH : repr (mul (oadd e₁ n₁ a₁) a₂) = repr (oadd e₁ n₁ a₁) * repr a₂
ao : repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁
e0 : ¬e₂ = 0
this✝¹ : NF e₁
this✝ : NF e₂
this : ¬repr e₂ = repr 0
⊢ ω ∣ ω ^ repr e₂

Next tactic:
simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 this)
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by 

Proof state:
o' : ONote
m : ℕ
x✝ : NF 0
p : split' 0 = (o', m)
⊢ split 0 = (scale 1 o', m)

Next tactic:
injection p
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; 

Proof state:
o' : ONote
m : ℕ
x✝ : NF 0
fst_eq✝ : 0 = o'
snd_eq✝ : 0 = m
⊢ split 0 = (scale 1 o', m)

Next tactic:
substs o' m
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; 

Proof state:
x✝ : NF 0
⊢ split 0 = (scale 1 0, 0)

Next tactic:
rfl
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    

Proof state:
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
p : split' (oadd e n a) = (o', m)
⊢ split (oadd e n a) = (scale 1 o', m)

Next tactic:
by_cases e0 : e = 0
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> 

Proof state:
case pos
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
p : split' (oadd e n a) = (o', m)
e0 : e = 0
⊢ split (oadd e n a) = (scale 1 o', m)

Next tactic:
simp [e0, split, split'] at p ⊢
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> 

Proof state:
case neg
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
p : split' (oadd e n a) = (o', m)
e0 : ¬e = 0
⊢ split (oadd e n a) = (scale 1 o', m)

Next tactic:
simp [e0, split, split'] at p ⊢
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · 

Proof state:
case pos
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : e = 0
p : 0 = o' ∧ ↑n = m
⊢ 0 = scale 1 o' ∧ ↑n = m

Next tactic:
rcases p with ⟨rfl, rfl⟩
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      

Proof state:
case pos.intro
e : ONote
n : ℕ+
a : ONote
h : NF (oadd e n a)
e0 : e = 0
⊢ 0 = scale 1 0 ∧ ↑n = ↑n

Next tactic:
exact ⟨rfl, rfl⟩
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · 

Proof state:
case neg
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
p : oadd (e - 1) n (split' a).1 = o' ∧ (split' a).2 = m
⊢ oadd e n (split a).1 = scale 1 o' ∧ (split a).2 = m

Next tactic:
revert p
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · revert p
      

Proof state:
case neg
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
⊢ oadd (e - 1) n (split' a).1 = o' ∧ (split' a).2 = m → oadd e n (split a).1 = scale 1 o' ∧ (split a).2 = m

Next tactic:
cases' h' : split' a with a' m'
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · revert p
      cases' h' : split' a with a' m'
      

Proof state:
case neg.mk
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
a' : ONote
m' : ℕ
h' : split' a = (a', m')
⊢ oadd (e - 1) n (a', m').1 = o' ∧ (a', m').2 = m → oadd e n (split a).1 = scale 1 o' ∧ (split a).2 = m

Next tactic:
haveI := h.fst
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · revert p
      cases' h' : split' a with a' m'
      haveI := h.fst
      

Proof state:
case neg.mk
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
a' : ONote
m' : ℕ
h' : split' a = (a', m')
this : NF e
⊢ oadd (e - 1) n (a', m').1 = o' ∧ (a', m').2 = m → oadd e n (split a).1 = scale 1 o' ∧ (split a).2 = m

Next tactic:
haveI := h.snd
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · revert p
      cases' h' : split' a with a' m'
      haveI := h.fst
      haveI := h.snd
      

Proof state:
case neg.mk
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
a' : ONote
m' : ℕ
h' : split' a = (a', m')
this✝ : NF e
this : NF a
⊢ oadd (e - 1) n (a', m').1 = o' ∧ (a', m').2 = m → oadd e n (split a).1 = scale 1 o' ∧ (split a).2 = m

Next tactic:
simp only [split_eq_scale_split' h', and_imp]
theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → split o = (scale 1 o', m)
  | 0, o', m, _, p => by injection p; substs o' m; rfl
  | oadd e n a, o', m, h, p => by
    by_cases e0 : e = 0 <;> simp [e0, split, split'] at p ⊢
    · rcases p with ⟨rfl, rfl⟩
      exact ⟨rfl, rfl⟩
    · revert p
      cases' h' : split' a with a' m'
      haveI := h.fst
      haveI := h.snd
      simp only [split_eq_scale_split' h', and_imp]
      

Proof state:
case neg.mk
e : ONote
n : ℕ+
a o' : ONote
m : ℕ
h : NF (oadd e n a)
e0 : ¬e = 0
a' : ONote
m' : ℕ
h' : split' a = (a', m')
this✝ : NF e
this : NF a
⊢ oadd (e - 1) n a' = o' → m' = m → oadd e n (scale 1 a') = scale 1 o' ∧ m' = m

Next tactic:
have : 1 + (e - 1) = e := by
        refine' repr_inj.1 _
        simp only [repr_add, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero,
          repr_sub]
        have := mt repr_inj.1 e0
        refine' Ordinal.add_sub_cancel_of_le _
        have := (one_le_iff_ne_zero.2 this)
        exact this