l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = repr o₁ - repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (Ordinal.zero_sub _).symm
  | oadd e n a, 0, _, _ => (Ordinal.sub_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    haveI := h₁.snd; haveI := h₂.snd; have h' := repr_sub a₁ a₂
    conv_lhs at h' => dsimp [HSub.hSub, Sub.sub, sub]
    conv_lhs => dsimp only [HSub.hSub, Sub.sub]; dsimp only [sub]
    have ee := @cmp_compares _ _ h₁.fst h₂.fst
    cases h : cmp e₁ e₂ <;> simp only [h] at ee
    · rw [Ordinal.sub_eq_zero_iff_le.2]
      · rfl
      exact le_of_lt (oadd_lt_oadd_1 h₁ ee)
    · change e₁ = e₂ at ee
      subst e₂
      dsimp only
      cases mn : (n₁ : ℕ) - n₂ <;> dsimp only
      · by_cases en : n₁ = n₂
        · simpa [en]
        · simp only [en, ite_false]
          exact
            (Ordinal.sub_eq_zero_iff_le.2 <|
                le_of_lt <|
                  oadd_lt_oadd_2 h₁ <|
                    lt_of_le_of_ne (tsub_eq_zero_iff_le.1 mn) (mt PNat.eq en)).symm
      · simp [Nat.succPNat, -Nat.cast_succ]
        rw [(tsub_eq_iff_eq_add_of_le <| le_of_lt <| Nat.lt_of_sub_eq_succ mn).1 mn, add_comm,
          Nat.cast_add, mul_add, add_assoc, add_sub_add_cancel]
        

Proof state:
case eq.succ
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
this✝ : NF a₁
this : NF a₂
h' : repr (sub a₁ a₂) = repr a₁ - repr a₂
h₂ : NF (oadd e₁ n₂ a₂)
h : cmp e₁ e₁ = Ordering.eq
n✝ : ℕ
mn : ↑n₁ - ↑n₂ = Nat.succ n✝
⊢ ω ^ repr e₁ * ↑(Nat.succ n✝) + repr a₁ = ω ^ repr e₁ * ↑(Nat.succ n✝) + repr a₁ - repr a₂

Next tactic:
refine'
          (Ordinal.sub_eq_of_add_eq <|
              add_absorp h₂.snd'.repr_lt <| le_trans _ (le_add_right _ _)).symm
@[simp]
theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = repr o₁ - repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (Ordinal.zero_sub _).symm
  | oadd e n a, 0, _, _ => (Ordinal.sub_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    haveI := h₁.snd; haveI := h₂.snd; have h' := repr_sub a₁ a₂
    conv_lhs at h' => dsimp [HSub.hSub, Sub.sub, sub]
    conv_lhs => dsimp only [HSub.hSub, Sub.sub]; dsimp only [sub]
    have ee := @cmp_compares _ _ h₁.fst h₂.fst
    cases h : cmp e₁ e₂ <;> simp only [h] at ee
    · rw [Ordinal.sub_eq_zero_iff_le.2]
      · rfl
      exact le_of_lt (oadd_lt_oadd_1 h₁ ee)
    · change e₁ = e₂ at ee
      subst e₂
      dsimp only
      cases mn : (n₁ : ℕ) - n₂ <;> dsimp only
      · by_cases en : n₁ = n₂
        · simpa [en]
        · simp only [en, ite_false]
          exact
            (Ordinal.sub_eq_zero_iff_le.2 <|
                le_of_lt <|
                  oadd_lt_oadd_2 h₁ <|
                    lt_of_le_of_ne (tsub_eq_zero_iff_le.1 mn) (mt PNat.eq en)).symm
      · simp [Nat.succPNat, -Nat.cast_succ]
        rw [(tsub_eq_iff_eq_add_of_le <| le_of_lt <| Nat.lt_of_sub_eq_succ mn).1 mn, add_comm,
          Nat.cast_add, mul_add, add_assoc, add_sub_add_cancel]
        refine'
          (Ordinal.sub_eq_of_add_eq <|
              add_absorp h₂.snd'.repr_lt <| le_trans _ (le_add_right _ _)).symm
        

Proof state:
case eq.succ
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
this✝ : NF a₁
this : NF a₂
h' : repr (sub a₁ a₂) = repr a₁ - repr a₂
h₂ : NF (oadd e₁ n₂ a₂)
h : cmp e₁ e₁ = Ordering.eq
n✝ : ℕ
mn : ↑n₁ - ↑n₂ = Nat.succ n✝
⊢ ω ^ repr e₁ ≤ ω ^ repr e₁ * ↑(Nat.succ n✝)

Next tactic:
simpa using mul_le_mul_left' (nat_cast_le.2 <| Nat.succ_pos _) _
@[simp]
theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = repr o₁ - repr o₂
  | 0, o, _, h₂ => by cases o <;> exact (Ordinal.zero_sub _).symm
  | oadd e n a, 0, _, _ => (Ordinal.sub_zero _).symm
  | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by
    haveI := h₁.snd; haveI := h₂.snd; have h' := repr_sub a₁ a₂
    conv_lhs at h' => dsimp [HSub.hSub, Sub.sub, sub]
    conv_lhs => dsimp only [HSub.hSub, Sub.sub]; dsimp only [sub]
    have ee := @cmp_compares _ _ h₁.fst h₂.fst
    cases h : cmp e₁ e₂ <;> simp only [h] at ee
    · rw [Ordinal.sub_eq_zero_iff_le.2]
      · rfl
      exact le_of_lt (oadd_lt_oadd_1 h₁ ee)
    · change e₁ = e₂ at ee
      subst e₂
      dsimp only
      cases mn : (n₁ : ℕ) - n₂ <;> dsimp only
      · by_cases en : n₁ = n₂
        · simpa [en]
        · simp only [en, ite_false]
          exact
            (Ordinal.sub_eq_zero_iff_le.2 <|
                le_of_lt <|
                  oadd_lt_oadd_2 h₁ <|
                    lt_of_le_of_ne (tsub_eq_zero_iff_le.1 mn) (mt PNat.eq en)).symm
      · simp [Nat.succPNat, -Nat.cast_succ]
        rw [(tsub_eq_iff_eq_add_of_le <| le_of_lt <| Nat.lt_of_sub_eq_succ mn).1 mn, add_comm,
          Nat.cast_add, mul_add, add_assoc, add_sub_add_cancel]
        refine'
          (Ordinal.sub_eq_of_add_eq <|
              add_absorp h₂.snd'.repr_lt <| le_trans _ (le_add_right _ _)).symm
        simpa using mul_le_mul_left' (nat_cast_le.2 <| Nat.succ_pos _) _
    · 

Proof state:
case gt
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
this✝ : NF a₁
this : NF a₂
h' : repr (sub a₁ a₂) = repr a₁ - repr a₂
h : cmp e₁ e₂ = Ordering.gt
ee : Ordering.Compares Ordering.gt e₁ e₂
⊢ repr
      (match Ordering.gt with
      | Ordering.lt => 0
      | Ordering.gt => oadd e₁ n₁ a₁
      | Ordering.eq =>
        match ↑n₁ - ↑n₂ with
        | 0 => if n₁ = n₂ then sub a₁ a₂ else 0
        | Nat.succ k => oadd e₁ (Nat.succPNat k) a₁) =
    repr (oadd e₁ n₁ a₁) - repr (oadd e₂ n₂ a₂)

Next tactic:
exact
        (Ordinal.sub_eq_of_add_eq <|
            add_absorp (h₂.below_of_lt ee).repr_lt <| omega_le_oadd _ _ _).symm
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by 

Proof state:
o : ONote
⊢ 0 * o = 0

Next tactic:
cases o
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by cases o <;> 

Proof state:
case zero
⊢ 0 * zero = 0

Next tactic:
rfl
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by cases o <;> 

Proof state:
case oadd
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
⊢ 0 * oadd a✝² a✝¹ a✝ = 0

Next tactic:
rfl
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by cases o <;> rfl
  mul_zero o := by 

Proof state:
o : ONote
⊢ o * 0 = 0

Next tactic:
cases o
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by cases o <;> rfl
  mul_zero o := by cases o <;> 

Proof state:
case zero
⊢ zero * 0 = 0

Next tactic:
rfl
instance : MulZeroClass ONote where
  mul := (· * ·)
  zero := 0
  zero_mul o := by cases o <;> rfl
  mul_zero o := by cases o <;> 

Proof state:
case oadd
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
⊢ oadd a✝² a✝¹ a✝ * 0 = 0

Next tactic:
rfl
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    

Proof state:
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
⊢ NFBelow (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) (repr e₁ + b₂)

Next tactic:
have IH := oadd_mul_nfBelow h₁ h₂.snd
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    

Proof state:
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
⊢ NFBelow (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) (repr e₁ + b₂)

Next tactic:
by_cases e0 : e₂ = 0
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> 

Proof state:
case pos
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : e₂ = 0
⊢ NFBelow (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) (repr e₁ + b₂)

Next tactic:
simp [e0, oadd_mul]
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> 

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
⊢ NFBelow (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) (repr e₁ + b₂)

Next tactic:
simp [e0, oadd_mul]
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · 

Proof state:
case pos
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : e₂ = 0
⊢ NFBelow (oadd e₁ (n₁ * n₂) a₁) (repr e₁ + b₂)

Next tactic:
apply NFBelow.oadd h₁.fst h₁.snd
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      

Proof state:
case pos
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : e₂ = 0
⊢ repr e₁ < repr e₁ + b₂

Next tactic:
simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · 

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
⊢ NFBelow (oadd (e₁ + e₂) n₂ (oadd e₁ n₁ a₁ * a₂)) (repr e₁ + b₂)

Next tactic:
haveI := h₁.fst
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this : NF e₁
⊢ NFBelow (oadd (e₁ + e₂) n₂ (oadd e₁ n₁ a₁ * a₂)) (repr e₁ + b₂)

Next tactic:
haveI := h₂.fst
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      haveI := h₂.fst
      

Proof state:
case neg
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ NFBelow (oadd (e₁ + e₂) n₂ (oadd e₁ n₁ a₁ * a₂)) (repr e₁ + b₂)

Next tactic:
apply NFBelow.oadd
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      haveI := h₂.fst
      apply NFBelow.oadd
      

Proof state:
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ NF (e₁ + e₂)
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ NFBelow (oadd e₁ n₁ a₁ * a₂) (repr (e₁ + e₂))
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ repr (e₁ + e₂) < repr e₁ + b₂

Next tactic:
infer_instance
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      haveI := h₂.fst
      apply NFBelow.oadd
      infer_instance
      · 

Proof state:
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ NFBelow (oadd e₁ n₁ a₁ * a₂) (repr (e₁ + e₂))

Next tactic:
rwa [repr_add]
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      haveI := h₂.fst
      apply NFBelow.oadd
      infer_instance
      · rwa [repr_add]
      · 

Proof state:
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ repr (e₁ + e₂) < repr e₁ + b₂

Next tactic:
rw [repr_add, add_lt_add_iff_left]
theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) :
    ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂)
  | 0, b₂, _ => NFBelow.zero
  | oadd e₂ n₂ a₂, b₂, h₂ => by
    have IH := oadd_mul_nfBelow h₁ h₂.snd
    by_cases e0 : e₂ = 0 <;> simp [e0, oadd_mul]
    · apply NFBelow.oadd h₁.fst h₁.snd
      simpa using (add_lt_add_iff_left (repr e₁)).2 (lt_of_le_of_lt (Ordinal.zero_le _) h₂.lt)
    · haveI := h₁.fst
      haveI := h₂.fst
      apply NFBelow.oadd
      infer_instance
      · rwa [repr_add]
      · rw [repr_add, add_lt_add_iff_left]
        

Proof state:
case neg.a
e₁ : ONote
n₁ : ℕ+
a₁ : ONote
b₁ : Ordinal.{0}
h₁ : NFBelow (oadd e₁ n₁ a₁) b₁
e₂ : ONote
n₂ : ℕ+
a₂ : ONote
b₂ : Ordinal.{0}
h₂ : NFBelow (oadd e₂ n₂ a₂) b₂
IH : NFBelow (oadd e₁ n₁ a₁ * a₂) (repr e₁ + repr e₂)
e0 : ¬e₂ = 0
this✝ : NF e₁
this : NF e₂
⊢ repr e₂ < b₂

Next tactic:
exact h₂.lt
instance mul_nf : ∀ (o₁ o₂) [NF o₁] [NF o₂], NF (o₁ * o₂)
  | 0, o, _, h₂ => by 

Proof state:
o : ONote
x✝ : NF 0
h₂ : NF o
⊢ NF (0 * o)

Next tactic:
cases o
instance mul_nf : ∀ (o₁ o₂) [NF o₁] [NF o₂], NF (o₁ * o₂)
  | 0, o, _, h₂ => by cases o <;> 

Proof state:
case zero
x✝ : NF 0
h₂ : NF zero
⊢ NF (0 * zero)

Next tactic:
exact NF.zero
instance mul_nf : ∀ (o₁ o₂) [NF o₁] [NF o₂], NF (o₁ * o₂)
  | 0, o, _, h₂ => by cases o <;> 

Proof state:
case oadd
x✝ : NF 0
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
h₂ : NF (oadd a✝² a✝¹ a✝)
⊢ NF (0 * oadd a✝² a✝¹ a✝)

Next tactic:
exact NF.zero
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by 

Proof state:
o : ONote
x✝ : NF 0
h₂ : NF o
⊢ repr (0 * o) = repr 0 * repr o

Next tactic:
cases o
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> 

Proof state:
case zero
x✝ : NF 0
h₂ : NF zero
⊢ repr (0 * zero) = repr 0 * repr zero

Next tactic:
exact (zero_mul _).symm
@[simp]
theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
  | 0, o, _, h₂ => by cases o <;> 

Proof state:
case oadd
x✝ : NF 0
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
h₂ : NF (oadd a✝² a✝¹ a✝)
⊢ repr (0 * oadd a✝² a✝¹ a✝) = repr 0 * repr (oadd a✝² a✝¹ a✝)

Next tactic:
exact (zero_mul _).symm
@[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
    

Proof state:
e₁ : ONote
n₁ : ℕ+
a₁ e₂ : ONote
n₂ : ℕ+
a₂ : ONote
h₁ : NF (oadd e₁ n₁ a₁)
h₂ : NF (oadd e₂ n₂ a₂)
⊢ repr (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd
@[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
    

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₂
⊢ repr (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
conv =>
      lhs
      simp [(· * ·)]
@[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 =>
      

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₂
| repr (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
lhs
      simp [(· * ·)]
@[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 =>
      

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₂
| repr (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
lhs
@[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
      

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₂
| repr (oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂)

Next tactic:
simp [(· * ·)]
@[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 [(· * ·)]
    

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₂
⊢ repr (Mul.mul (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂)) = repr (oadd e₁ n₁ a₁) * repr (oadd e₂ n₂ a₂)

Next tactic:
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)
@[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
      

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₂
⊢ repr a₁ + ω ^ repr e₁ * ↑↑n₁ = ω ^ repr e₁ * ↑↑n₁

Next tactic:
apply add_absorp h₁.snd'.repr_lt
@[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
      

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₂
⊢ ω ^ repr e₁ ≤ ω ^ repr e₁ * ↑↑n₁

Next tactic:
simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega_pos).2 (nat_cast_le.2 n₁.2)