l3lab/ntp-mathlib huggingface dataset:
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · 

Proof state:
case inl.intro.intro
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
i : Ordinal.{u}
h : i < a ♯ b
a' : Ordinal.{u}
ha' : a' < a
hi : i ≤ a' ♯ b
⊢ f i h <
    max (blsub a fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) (blsub b fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b))

Next tactic:
exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · 

Proof state:
case inr.intro.intro
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
i : Ordinal.{u}
h : i < a ♯ b
b' : Ordinal.{u}
hb' : b' < b
hi : i ≤ a ♯ b'
⊢ f i h <
    max (blsub a fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) (blsub b fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b))

Next tactic:
exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  

Proof state:
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (blsub a fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) ≤ blsub (a ♯ b) f
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (blsub b fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b)) ≤ blsub (a ♯ b) f

Next tactic:
all_goals
    apply blsub_le_of_brange_subset.{u, u, v}
    rintro c ⟨d, hd, rfl⟩
    apply mem_brange_self
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    

Proof state:
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (blsub a fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) ≤ blsub (a ♯ b) f

Next tactic:
apply blsub_le_of_brange_subset.{u, u, v}
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    apply blsub_le_of_brange_subset.{u, u, v}
    

Proof state:
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (brange a fun a_1 ha => (fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) a_1 ha) ⊆
    brange (a ♯ b) fun a_1 ha => f a_1 ha

Next tactic:
rintro c ⟨d, hd, rfl⟩
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    apply blsub_le_of_brange_subset.{u, u, v}
    rintro c ⟨d, hd, rfl⟩
    

Proof state:
case intro.intro
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
d : Ordinal.{u}
hd : d < a
⊢ (fun a_1 ha => (fun a' ha' => f (a' ♯ b) (_ : a' ♯ b < a ♯ b)) a_1 ha) d hd ∈ brange (a ♯ b) fun a_1 ha => f a_1 ha

Next tactic:
apply mem_brange_self
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    

Proof state:
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (blsub b fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b)) ≤ blsub (a ♯ b) f

Next tactic:
apply blsub_le_of_brange_subset.{u, u, v}
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    apply blsub_le_of_brange_subset.{u, u, v}
    

Proof state:
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
⊢ (brange b fun a_1 ha => (fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b)) a_1 ha) ⊆
    brange (a ♯ b) fun a_1 ha => f a_1 ha

Next tactic:
rintro c ⟨d, hd, rfl⟩
theorem blsub_nadd_of_mono {f : ∀ c < a ♯ b, Ordinal.{max u v}}
    (hf : ∀ {i j} (hi hj), i ≤ j → f i hi ≤ f j hj) :
    -- Porting note: needed to add universe hint blsub.{u,v} in the line below
    blsub.{u,v} _ f =
      max (blsub.{u, v} a fun a' ha' => f (a' ♯ b) <| nadd_lt_nadd_right ha' b)
        (blsub.{u, v} b fun b' hb' => f (a ♯ b') <| nadd_lt_nadd_left hb' a) := by
  apply (blsub_le_iff.2 fun i h => _).antisymm (max_le _ _)
  intro i h
  · rcases lt_nadd_iff.1 h with (⟨a', ha', hi⟩ | ⟨b', hb', hi⟩)
    · exact lt_max_of_lt_left ((hf h (nadd_lt_nadd_right ha' b) hi).trans_lt (lt_blsub _ _ ha'))
    · exact lt_max_of_lt_right ((hf h (nadd_lt_nadd_left hb' a) hi).trans_lt (lt_blsub _ _ hb'))
  all_goals
    apply blsub_le_of_brange_subset.{u, u, v}
    rintro c ⟨d, hd, rfl⟩
    

Proof state:
case intro.intro
a b c : Ordinal.{u}
f : (c : Ordinal.{u}) → c < a ♯ b → Ordinal.{max u v}
hf : ∀ {i j : Ordinal.{u}} (hi : i < a ♯ b) (hj : j < a ♯ b), i ≤ j → f i hi ≤ f j hj
d : Ordinal.{u}
hd : d < b
⊢ (fun a_1 ha => (fun b' hb' => f (a ♯ b') (_ : a ♯ b' < a ♯ b)) a_1 ha) d hd ∈ brange (a ♯ b) fun a_1 ha => f a_1 ha

Next tactic:
apply mem_brange_self
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  

Proof state:
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ a ♯ b ♯ c = a ♯ (b ♯ c)

Next tactic:
rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · 

Proof state:
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ max (blsub a fun a' ha' => a' ♯ b ♯ c) (max (blsub b fun b' hb' => a ♯ b' ♯ c) (blsub c fun b' x => a ♯ b ♯ b')) =
    max (blsub a fun a' x => a' ♯ (b ♯ c))
      (max (blsub b fun a' ha' => a ♯ (a' ♯ c)) (blsub c fun b' hb' => a ♯ (b ♯ b')))

Next tactic:
congr
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> 

Proof state:
case e_a.e_f
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ (fun a' ha' => a' ♯ b ♯ c) = fun a' x => a' ♯ (b ♯ c)

Next tactic:
ext (d hd)
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> 

Proof state:
case e_a.e_a.e_f
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ (fun b' hb' => a ♯ b' ♯ c) = fun a' ha' => a ♯ (a' ♯ c)

Next tactic:
ext (d hd)
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> 

Proof state:
case e_a.e_a.e_f
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ (fun b' x => a ♯ b ♯ b') = fun b' hb' => a ♯ (b ♯ b')

Next tactic:
ext (d hd)
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> ext (d hd) <;> 

Proof state:
case e_a.e_f.h.h
a✝ b✝ c✝ : Ordinal.{u}
a b c d : Ordinal.{u_1}
hd : d < a
⊢ d ♯ b ♯ c = d ♯ (b ♯ c)

Next tactic:
apply nadd_assoc
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> ext (d hd) <;> 

Proof state:
case e_a.e_a.e_f.h.h
a✝ b✝ c✝ : Ordinal.{u}
a b c d : Ordinal.{u_1}
hd : d < b
⊢ a ♯ d ♯ c = a ♯ (d ♯ c)

Next tactic:
apply nadd_assoc
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> ext (d hd) <;> 

Proof state:
case e_a.e_a.e_f.h.h
a✝ b✝ c✝ : Ordinal.{u}
a b c d : Ordinal.{u_1}
hd : d < c
⊢ a ♯ b ♯ d = a ♯ (b ♯ d)

Next tactic:
apply nadd_assoc
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> ext (d hd) <;> apply nadd_assoc
  · 

Proof state:
case hf
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ ∀ {i j : Ordinal.{u_1}}, i < b ♯ c → j < b ♯ c → i ≤ j → a ♯ i ≤ a ♯ j

Next tactic:
exact fun _ _ h => nadd_le_nadd_left h a
theorem nadd_assoc (a b c) : a ♯ b ♯ c = a ♯ (b ♯ c) := by
  rw [nadd_def a (b ♯ c), nadd_def, blsub_nadd_of_mono, blsub_nadd_of_mono, max_assoc]
  · congr <;> ext (d hd) <;> apply nadd_assoc
  · exact fun _ _ h => nadd_le_nadd_left h a
  · 

Proof state:
case hf
a✝ b✝ c✝ : Ordinal.{u}
a b c : Ordinal.{u_1}
⊢ ∀ {i j : Ordinal.{u_1}}, i < a ♯ b → j < a ♯ b → i ≤ j → i ♯ c ≤ j ♯ c

Next tactic:
exact fun _ _ h => nadd_le_nadd_right h c
@[simp]
theorem nadd_zero : a ♯ 0 = a := by
  

Proof state:
a b c : Ordinal.{u}
⊢ a ♯ 0 = a

Next tactic:
induction' a using Ordinal.induction with a IH
@[simp]
theorem nadd_zero : a ♯ 0 = a := by
  induction' a using Ordinal.induction with a IH
  

Proof state:
case h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 0 = k
⊢ a ♯ 0 = a

Next tactic:
rw [nadd_def, blsub_zero, max_zero_right]
@[simp]
theorem nadd_zero : a ♯ 0 = a := by
  induction' a using Ordinal.induction with a IH
  rw [nadd_def, blsub_zero, max_zero_right]
  

Proof state:
case h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 0 = k
⊢ (blsub a fun a' x => a' ♯ 0) = a

Next tactic:
convert blsub_id a
@[simp]
theorem nadd_zero : a ♯ 0 = a := by
  induction' a using Ordinal.induction with a IH
  rw [nadd_def, blsub_zero, max_zero_right]
  convert blsub_id a
  

Proof state:
case h.e'_2.h.e'_2.h.h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 0 = k
x✝¹ : Ordinal.{u}
x✝ : x✝¹ < a
⊢ x✝¹ ♯ 0 = x✝¹

Next tactic:
rename_i hb
@[simp]
theorem nadd_zero : a ♯ 0 = a := by
  induction' a using Ordinal.induction with a IH
  rw [nadd_def, blsub_zero, max_zero_right]
  convert blsub_id a
  rename_i hb
  

Proof state:
case h.e'_2.h.e'_2.h.h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 0 = k
x✝ : Ordinal.{u}
hb : x✝ < a
⊢ x✝ ♯ 0 = x✝

Next tactic:
exact IH _ hb
@[simp]
theorem zero_nadd : 0 ♯ a = a := by 

Proof state:
a b c : Ordinal.{u}
⊢ 0 ♯ a = a

Next tactic:
rw [nadd_comm, nadd_zero]
@[simp]
theorem nadd_one : a ♯ 1 = succ a := by
  

Proof state:
a b c : Ordinal.{u}
⊢ a ♯ 1 = succ a

Next tactic:
induction' a using Ordinal.induction with a IH
@[simp]
theorem nadd_one : a ♯ 1 = succ a := by
  induction' a using Ordinal.induction with a IH
  

Proof state:
case h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 1 = succ k
⊢ a ♯ 1 = succ a

Next tactic:
rw [nadd_def, blsub_one, nadd_zero, max_eq_right_iff, blsub_le_iff]
@[simp]
theorem nadd_one : a ♯ 1 = succ a := by
  induction' a using Ordinal.induction with a IH
  rw [nadd_def, blsub_one, nadd_zero, max_eq_right_iff, blsub_le_iff]
  

Proof state:
case h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 1 = succ k
⊢ ∀ i < a, i ♯ 1 < succ a

Next tactic:
intro i hi
@[simp]
theorem nadd_one : a ♯ 1 = succ a := by
  induction' a using Ordinal.induction with a IH
  rw [nadd_def, blsub_one, nadd_zero, max_eq_right_iff, blsub_le_iff]
  intro i hi
  

Proof state:
case h
a✝ b c a : Ordinal.{u}
IH : ∀ k < a, k ♯ 1 = succ k
i : Ordinal.{u}
hi : i < a
⊢ i ♯ 1 < succ a

Next tactic:
rwa [IH i hi, succ_lt_succ_iff]
@[simp]
theorem one_nadd : 1 ♯ a = succ a := by 

Proof state:
a b c : Ordinal.{u}
⊢ 1 ♯ a = succ a

Next tactic:
rw [nadd_comm, nadd_one]
theorem nadd_succ : a ♯ succ b = succ (a ♯ b) := by 

Proof state:
a b c : Ordinal.{u}
⊢ a ♯ succ b = succ (a ♯ b)

Next tactic:
rw [← nadd_one (a ♯ b), nadd_assoc, nadd_one]
theorem succ_nadd : succ a ♯ b = succ (a ♯ b) := by 

Proof state:
a b c : Ordinal.{u}
⊢ succ a ♯ b = succ (a ♯ b)

Next tactic:
rw [← one_nadd (a ♯ b), ← nadd_assoc, one_nadd]
@[simp]
theorem nadd_nat (n : ℕ) : a ♯ n = a + n := by
  

Proof state:
a b c : Ordinal.{u}
n : ℕ
⊢ a ♯ ↑n = a + ↑n

Next tactic:
induction' n with n hn
@[simp]
theorem nadd_nat (n : ℕ) : a ♯ n = a + n := by
  induction' n with n hn
  · 

Proof state:
case zero
a b c : Ordinal.{u}
⊢ a ♯ ↑Nat.zero = a + ↑Nat.zero

Next tactic:
simp
@[simp]
theorem nadd_nat (n : ℕ) : a ♯ n = a + n := by
  induction' n with n hn
  · simp
  · 

Proof state:
case succ
a b c : Ordinal.{u}
n : ℕ
hn : a ♯ ↑n = a + ↑n
⊢ a ♯ ↑(Nat.succ n) = a + ↑(Nat.succ n)

Next tactic:
rw [Nat.cast_succ, add_one_eq_succ, nadd_succ, add_succ, hn]
@[simp]
theorem nat_nadd (n : ℕ) : ↑n ♯ a = a + n := by 

Proof state:
a b c : Ordinal.{u}
n : ℕ
⊢ ↑n ♯ a = a + ↑n

Next tactic:
rw [nadd_comm, nadd_nat]
theorem add_le_nadd : a + b ≤ a ♯ b := by
  

Proof state:
a b c : Ordinal.{u}
⊢ a + b ≤ a ♯ b

Next tactic:
induction b using limitRecOn with
  | H₁ => simp
  | H₂ c h =>
    rwa [add_succ, nadd_succ, succ_le_succ_iff]
  | H₃ c hc H =>
    simp_rw [← IsNormal.blsub_eq.{u, u} (add_isNormal a) hc, blsub_le_iff]
    exact fun i hi => (H i hi).trans_lt (nadd_lt_nadd_left hi a)
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  

Proof state:
case H₁
a b c : Ordinal.{u}
⊢ a + 0 ≤ a ♯ 0

Next tactic:
| H₁ => simp
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => 

Proof state:
case H₁
a b c : Ordinal.{u}
⊢ a + 0 ≤ a ♯ 0

Next tactic:
simp
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => simp
  

Proof state:
case H₂
a b c✝ c : Ordinal.{u}
h : a + c ≤ a ♯ c
⊢ a + succ c ≤ a ♯ succ c

Next tactic:
| H₂ c h =>
    rwa [add_succ, nadd_succ, succ_le_succ_iff]
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => simp
  | H₂ c h =>
    

Proof state:
case H₂
a b c✝ c : Ordinal.{u}
h : a + c ≤ a ♯ c
⊢ a + succ c ≤ a ♯ succ c

Next tactic:
rwa [add_succ, nadd_succ, succ_le_succ_iff]
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => simp
  | H₂ c h =>
    rwa [add_succ, nadd_succ, succ_le_succ_iff]
  

Proof state:
case H₃
a b c✝ c : Ordinal.{u}
hc : IsLimit c
H : ∀ o' < c, a + o' ≤ a ♯ o'
⊢ a + c ≤ a ♯ c

Next tactic:
| H₃ c hc H =>
    simp_rw [← IsNormal.blsub_eq.{u, u} (add_isNormal a) hc, blsub_le_iff]
    exact fun i hi => (H i hi).trans_lt (nadd_lt_nadd_left hi a)
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => simp
  | H₂ c h =>
    rwa [add_succ, nadd_succ, succ_le_succ_iff]
  | H₃ c hc H =>
    

Proof state:
case H₃
a b c✝ c : Ordinal.{u}
hc : IsLimit c
H : ∀ o' < c, a + o' ≤ a ♯ o'
⊢ a + c ≤ a ♯ c

Next tactic:
simp_rw [← IsNormal.blsub_eq.{u, u} (add_isNormal a) hc, blsub_le_iff]
theorem add_le_nadd : a + b ≤ a ♯ b := by
  induction b using limitRecOn with
  | H₁ => simp
  | H₂ c h =>
    rwa [add_succ, nadd_succ, succ_le_succ_iff]
  | H₃ c hc H =>
    simp_rw [← IsNormal.blsub_eq.{u, u} (add_isNormal a) hc, blsub_le_iff]
    

Proof state:
case H₃
a b c✝ c : Ordinal.{u}
hc : IsLimit c
H : ∀ o' < c, a + o' ≤ a ♯ o'
⊢ ∀ i < c, a + i < a ♯ c

Next tactic:
exact fun i hi => (H i hi).trans_lt (nadd_lt_nadd_left hi a)
instance add_contravariantClass_le :
    ContravariantClass NatOrdinal.{u} NatOrdinal.{u} (· + ·) (· ≤ ·) :=
  ⟨fun a b c h => by
    

Proof state:
a b c : NatOrdinal
h : a + b ≤ a + c
⊢ b ≤ c

Next tactic:
by_contra! h'
instance add_contravariantClass_le :
    ContravariantClass NatOrdinal.{u} NatOrdinal.{u} (· + ·) (· ≤ ·) :=
  ⟨fun a b c h => by
    by_contra! h'
    

Proof state:
a b c : NatOrdinal
h : a + b ≤ a + c
h' : c < b
⊢ False

Next tactic:
exact h.not_lt (add_lt_add_left h' a)
@[simp]
theorem toOrdinal_cast_nat (n : ℕ) : toOrdinal n = n := by
  

Proof state:
n : ℕ
⊢ toOrdinal ↑n = ↑n

Next tactic:
induction' n with n hn
@[simp]
theorem toOrdinal_cast_nat (n : ℕ) : toOrdinal n = n := by
  induction' n with n hn
  · 

Proof state:
case zero
⊢ toOrdinal ↑Nat.zero = ↑Nat.zero

Next tactic:
rfl
@[simp]
theorem toOrdinal_cast_nat (n : ℕ) : toOrdinal n = n := by
  induction' n with n hn
  · rfl
  · 

Proof state:
case succ
n : ℕ
hn : toOrdinal ↑n = ↑n
⊢ toOrdinal ↑(Nat.succ n) = ↑(Nat.succ n)

Next tactic:
change (toOrdinal n) ♯ 1 = n + 1
@[simp]
theorem toOrdinal_cast_nat (n : ℕ) : toOrdinal n = n := by
  induction' n with n hn
  · rfl
  · change (toOrdinal n) ♯ 1 = n + 1
    

Proof state:
case succ
n : ℕ
hn : toOrdinal ↑n = ↑n
⊢ toOrdinal ↑n ♯ 1 = ↑n + 1

Next tactic:
rw [hn]
@[simp]
theorem toOrdinal_cast_nat (n : ℕ) : toOrdinal n = n := by
  induction' n with n hn
  · rfl
  · change (toOrdinal n) ♯ 1 = n + 1
    rw [hn]; 

Proof state:
case succ
n : ℕ
hn : toOrdinal ↑n = ↑n
⊢ ↑n ♯ 1 = ↑n + 1

Next tactic:
exact nadd_one n
@[simp]
theorem toNatOrdinal_cast_nat (n : ℕ) : toNatOrdinal n = n := by
  

Proof state:
n : ℕ
⊢ toNatOrdinal ↑n = ↑n

Next tactic:
rw [← toOrdinal_cast_nat n]
@[simp]
theorem toNatOrdinal_cast_nat (n : ℕ) : toNatOrdinal n = n := by
  rw [← toOrdinal_cast_nat n]
  

Proof state:
n : ℕ
⊢ toNatOrdinal (toOrdinal ↑n) = ↑n

Next tactic:
rfl
theorem le_nadd_self {a b} : a ≤ b ♯ a := by 

Proof state:
a b : Ordinal.{u_1}
⊢ a ≤ b ♯ a

Next tactic:
simpa using nadd_le_nadd_right (Ordinal.zero_le b) a
theorem le_self_nadd {a b} : a ≤ a ♯ b := by 

Proof state:
a b : Ordinal.{u_1}
⊢ a ≤ a ♯ b

Next tactic:
simpa using nadd_le_nadd_left (Ordinal.zero_le b) a
theorem nmul_def (a b : Ordinal) :
    a ⨳ b = sInf {c | ∀ a' < a, ∀ b' < b, a' ⨳ b ♯ a ⨳ b' < c ♯ a' ⨳ b'} := by 

Proof state:
a✝ b✝ c d : Ordinal.{u}
a b : Ordinal.{u_1}
⊢ a ⨳ b = sInf {c | ∀ a' < a, ∀ b' < b, a' ⨳ b ♯ a ⨳ b' < c ♯ a' ⨳ b'}

Next tactic:
rw [nmul]
theorem nmul_nadd_lt {a' b' : Ordinal} (ha : a' < a) (hb : b' < b) :
    a' ⨳ b ♯ a ⨳ b' < a ⨳ b ♯ a' ⨳ b' := by
  

Proof state:
a b c d a' b' : Ordinal.{u}
ha : a' < a
hb : b' < b
⊢ a' ⨳ b ♯ a ⨳ b' < a ⨳ b ♯ a' ⨳ b'

Next tactic:
rw [nmul_def a b]
theorem nmul_nadd_lt {a' b' : Ordinal} (ha : a' < a) (hb : b' < b) :
    a' ⨳ b ♯ a ⨳ b' < a ⨳ b ♯ a' ⨳ b' := by
  rw [nmul_def a b]
  

Proof state:
a b c d a' b' : Ordinal.{u}
ha : a' < a
hb : b' < b
⊢ a' ⨳ b ♯ a ⨳ b' < sInf {c | ∀ a' < a, ∀ b' < b, a' ⨳ b ♯ a ⨳ b' < c ♯ a' ⨳ b'} ♯ a' ⨳ b'

Next tactic:
exact csInf_mem (nmul_nonempty a b) a' ha b' hb
theorem nmul_nadd_le {a' b' : Ordinal} (ha : a' ≤ a) (hb : b' ≤ b) :
    a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b' := by
  

Proof state:
a b c d a' b' : Ordinal.{u}
ha : a' ≤ a
hb : b' ≤ b
⊢ a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b'

Next tactic:
rcases lt_or_eq_of_le ha with (ha | rfl)
theorem nmul_nadd_le {a' b' : Ordinal} (ha : a' ≤ a) (hb : b' ≤ b) :
    a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b' := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · 

Proof state:
case inl
a b c d a' b' : Ordinal.{u}
ha✝ : a' ≤ a
hb : b' ≤ b
ha : a' < a
⊢ a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b'

Next tactic:
rcases lt_or_eq_of_le hb with (hb | rfl)
theorem nmul_nadd_le {a' b' : Ordinal} (ha : a' ≤ a) (hb : b' ≤ b) :
    a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b' := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · rcases lt_or_eq_of_le hb with (hb | rfl)
    · 

Proof state:
case inl.inl
a b c d a' b' : Ordinal.{u}
ha✝ : a' ≤ a
hb✝ : b' ≤ b
ha : a' < a
hb : b' < b
⊢ a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b'

Next tactic:
exact (nmul_nadd_lt ha hb).le
theorem nmul_nadd_le {a' b' : Ordinal} (ha : a' ≤ a) (hb : b' ≤ b) :
    a' ⨳ b ♯ a ⨳ b' ≤ a ⨳ b ♯ a' ⨳ b' := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · rcases lt_or_eq_of_le hb with (hb | rfl)
    · exact (nmul_nadd_lt ha hb).le
    · 

Proof state:
case inl.inr
a c d a' b' : Ordinal.{u}
ha✝ : a' ≤ a
ha : a' < a
hb : b' ≤ b'
⊢ a' ⨳ b' ♯ a ⨳ b' ≤ a ⨳ b' ♯ a' ⨳ b'

Next tactic:
rw [nadd_comm]