l3lab/ntp-mathlib huggingface dataset:
private theorem enumOrd_mem_aux (hS : Unbounded (· < ·) S) (o) :
    enumOrd S o ∈ S ∩ Set.Ici (blsub.{u, u} o fun c _ => enumOrd S c) := by
  rw [enumOrd_def']
  

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
o : Ordinal.{u}
⊢ sInf (S ∩ Ici (blsub o fun a x => enumOrd S a)) ∈ S ∩ Ici (blsub o fun c x => enumOrd S c)

Next tactic:
exact csInf_mem (enumOrd_def'_nonempty hS _)
/-- A more workable definition for `enumOrd`. -/
theorem enumOrd_def (o) : enumOrd S o = sInf (S ∩ { b | ∀ c, c < o → enumOrd S c < b }) := by
  

Proof state:
S : Set Ordinal.{u}
o : Ordinal.{u}
⊢ enumOrd S o = sInf (S ∩ {b | ∀ c < o, enumOrd S c < b})

Next tactic:
rw [enumOrd_def']
/-- A more workable definition for `enumOrd`. -/
theorem enumOrd_def (o) : enumOrd S o = sInf (S ∩ { b | ∀ c, c < o → enumOrd S c < b }) := by
  rw [enumOrd_def']
  

Proof state:
S : Set Ordinal.{u}
o : Ordinal.{u}
⊢ sInf (S ∩ Ici (blsub o fun a x => enumOrd S a)) = sInf (S ∩ {b | ∀ c < o, enumOrd S c < b})

Next tactic:
congr
/-- A more workable definition for `enumOrd`. -/
theorem enumOrd_def (o) : enumOrd S o = sInf (S ∩ { b | ∀ c, c < o → enumOrd S c < b }) := by
  rw [enumOrd_def']
  congr; 

Proof state:
case e_a.e_a
S : Set Ordinal.{u}
o : Ordinal.{u}
⊢ Ici (blsub o fun a x => enumOrd S a) = {b | ∀ c < o, enumOrd S c < b}

Next tactic:
ext
/-- A more workable definition for `enumOrd`. -/
theorem enumOrd_def (o) : enumOrd S o = sInf (S ∩ { b | ∀ c, c < o → enumOrd S c < b }) := by
  rw [enumOrd_def']
  congr; ext
  

Proof state:
case e_a.e_a.h
S : Set Ordinal.{u}
o x✝ : Ordinal.{u}
⊢ x✝ ∈ Ici (blsub o fun a x => enumOrd S a) ↔ x✝ ∈ {b | ∀ c < o, enumOrd S c < b}

Next tactic:
exact ⟨fun h a hao => (lt_blsub.{u, u} _ _ hao).trans_le h, blsub_le⟩
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o : Ordinal.{u_1}
⊢ enumOrd (range f) o = f o

Next tactic:
apply Ordinal.induction o
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o : Ordinal.{u_1}
⊢ ∀ (j : Ordinal.{u_1}), (∀ k < j, enumOrd (range f) k = f k) → enumOrd (range f) j = f j

Next tactic:
intro a H
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
⊢ enumOrd (range f) a = f a

Next tactic:
rw [enumOrd_def a]
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
⊢ sInf (range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}) = f a

Next tactic:
have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
b : Ordinal.{u_1}
hb : b < a
⊢ enumOrd (range f) b < f a

Next tactic:
rw [H b hb]
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
b : Ordinal.{u_1}
hb : b < a
⊢ f b < f a

Next tactic:
exact hf hb
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
Hfa : f a ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}
⊢ sInf (range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}) = f a

Next tactic:
refine' (csInf_le' Hfa).antisymm ((le_csInf_iff'' ⟨_, Hfa⟩).2 _)
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
    refine' (csInf_le' Hfa).antisymm ((le_csInf_iff'' ⟨_, Hfa⟩).2 _)
    

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
Hfa : f a ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}
⊢ ∀ b ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}, f a ≤ b

Next tactic:
rintro _ ⟨⟨c, rfl⟩, hc : ∀ b < a, enumOrd (range f) b < f c⟩
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
    refine' (csInf_le' Hfa).antisymm ((le_csInf_iff'' ⟨_, Hfa⟩).2 _)
    rintro _ ⟨⟨c, rfl⟩, hc : ∀ b < a, enumOrd (range f) b < f c⟩
    

Proof state:
case intro.intro
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
Hfa : f a ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}
c : Ordinal.{u_1}
hc : ∀ b < a, enumOrd (range f) b < f c
⊢ f a ≤ f c

Next tactic:
rw [hf.le_iff_le]
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
    refine' (csInf_le' Hfa).antisymm ((le_csInf_iff'' ⟨_, Hfa⟩).2 _)
    rintro _ ⟨⟨c, rfl⟩, hc : ∀ b < a, enumOrd (range f) b < f c⟩
    rw [hf.le_iff_le]
    

Proof state:
case intro.intro
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
Hfa : f a ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}
c : Ordinal.{u_1}
hc : ∀ b < a, enumOrd (range f) b < f c
⊢ a ≤ c

Next tactic:
contrapose! hc
@[simp]
theorem enumOrd_range {f : Ordinal → Ordinal} (hf : StrictMono f) : enumOrd (range f) = f :=
  funext fun o => by
    apply Ordinal.induction o
    intro a H
    rw [enumOrd_def a]
    have Hfa : f a ∈ range f ∩ { b | ∀ c, c < a → enumOrd (range f) c < b } :=
      ⟨mem_range_self a, fun b hb => by
        rw [H b hb]
        exact hf hb⟩
    refine' (csInf_le' Hfa).antisymm ((le_csInf_iff'' ⟨_, Hfa⟩).2 _)
    rintro _ ⟨⟨c, rfl⟩, hc : ∀ b < a, enumOrd (range f) b < f c⟩
    rw [hf.le_iff_le]
    contrapose! hc
    

Proof state:
case intro.intro
S : Set Ordinal.{u}
f : Ordinal.{u_1} → Ordinal.{u_1}
hf : StrictMono f
o a : Ordinal.{u_1}
H : ∀ k < a, enumOrd (range f) k = f k
Hfa : f a ∈ range f ∩ {b | ∀ c < a, enumOrd (range f) c < b}
c : Ordinal.{u_1}
hc : c < a
⊢ ∃ b < a, f c ≤ enumOrd (range f) b

Next tactic:
exact ⟨c, hc, (H c hc).ge⟩
@[simp]
theorem enumOrd_univ : enumOrd Set.univ = id := by
  

Proof state:
S : Set Ordinal.{u}
⊢ enumOrd Set.univ = id

Next tactic:
rw [← range_id]
@[simp]
theorem enumOrd_univ : enumOrd Set.univ = id := by
  rw [← range_id]
  

Proof state:
S : Set Ordinal.{u}
⊢ enumOrd (range id) = id

Next tactic:
exact enumOrd_range strictMono_id
@[simp]
theorem enumOrd_zero : enumOrd S 0 = sInf S := by
  

Proof state:
S : Set Ordinal.{u}
⊢ enumOrd S 0 = sInf S

Next tactic:
rw [enumOrd_def]
@[simp]
theorem enumOrd_zero : enumOrd S 0 = sInf S := by
  rw [enumOrd_def]
  

Proof state:
S : Set Ordinal.{u}
⊢ sInf (S ∩ {b | ∀ c < 0, enumOrd S c < b}) = sInf S

Next tactic:
simp [Ordinal.not_lt_zero]
theorem enumOrd_succ_le {a b} (hS : Unbounded (· < ·) S) (ha : a ∈ S) (hb : enumOrd S b < a) :
    enumOrd S (succ b) ≤ a := by
  

Proof state:
S : Set Ordinal.{u}
a b : Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
ha : a ∈ S
hb : enumOrd S b < a
⊢ enumOrd S (succ b) ≤ a

Next tactic:
rw [enumOrd_def]
theorem enumOrd_succ_le {a b} (hS : Unbounded (· < ·) S) (ha : a ∈ S) (hb : enumOrd S b < a) :
    enumOrd S (succ b) ≤ a := by
  rw [enumOrd_def]
  

Proof state:
S : Set Ordinal.{u}
a b : Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
ha : a ∈ S
hb : enumOrd S b < a
⊢ sInf (S ∩ {b_1 | ∀ c < succ b, enumOrd S c < b_1}) ≤ a

Next tactic:
exact
    csInf_le' ⟨ha, fun c hc => ((enumOrd_strictMono hS).monotone (le_of_lt_succ hc)).trans_lt hb⟩
theorem enumOrd_le_of_subset {S T : Set Ordinal} (hS : Unbounded (· < ·) S) (hST : S ⊆ T) (a) :
    enumOrd T a ≤ enumOrd S a := by
  

Proof state:
S✝ : Set Ordinal.{u}
S T : Set Ordinal.{u_1}
hS : Unbounded (fun x x_1 => x < x_1) S
hST : S ⊆ T
a : Ordinal.{u_1}
⊢ enumOrd T a ≤ enumOrd S a

Next tactic:
apply Ordinal.induction a
theorem enumOrd_le_of_subset {S T : Set Ordinal} (hS : Unbounded (· < ·) S) (hST : S ⊆ T) (a) :
    enumOrd T a ≤ enumOrd S a := by
  apply Ordinal.induction a
  

Proof state:
S✝ : Set Ordinal.{u}
S T : Set Ordinal.{u_1}
hS : Unbounded (fun x x_1 => x < x_1) S
hST : S ⊆ T
a : Ordinal.{u_1}
⊢ ∀ (j : Ordinal.{u_1}), (∀ k < j, enumOrd T k ≤ enumOrd S k) → enumOrd T j ≤ enumOrd S j

Next tactic:
intro b H
theorem enumOrd_le_of_subset {S T : Set Ordinal} (hS : Unbounded (· < ·) S) (hST : S ⊆ T) (a) :
    enumOrd T a ≤ enumOrd S a := by
  apply Ordinal.induction a
  intro b H
  

Proof state:
S✝ : Set Ordinal.{u}
S T : Set Ordinal.{u_1}
hS : Unbounded (fun x x_1 => x < x_1) S
hST : S ⊆ T
a b : Ordinal.{u_1}
H : ∀ k < b, enumOrd T k ≤ enumOrd S k
⊢ enumOrd T b ≤ enumOrd S b

Next tactic:
rw [enumOrd_def]
theorem enumOrd_le_of_subset {S T : Set Ordinal} (hS : Unbounded (· < ·) S) (hST : S ⊆ T) (a) :
    enumOrd T a ≤ enumOrd S a := by
  apply Ordinal.induction a
  intro b H
  rw [enumOrd_def]
  

Proof state:
S✝ : Set Ordinal.{u}
S T : Set Ordinal.{u_1}
hS : Unbounded (fun x x_1 => x < x_1) S
hST : S ⊆ T
a b : Ordinal.{u_1}
H : ∀ k < b, enumOrd T k ≤ enumOrd S k
⊢ sInf (T ∩ {b_1 | ∀ c < b, enumOrd T c < b_1}) ≤ enumOrd S b

Next tactic:
exact csInf_le' ⟨hST (enumOrd_mem hS b), fun c h => (H c h).trans_lt (enumOrd_strictMono hS h)⟩
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
⊢ enumOrd S (sSup {a | enumOrd S a ≤ s}) = s

Next tactic:
apply le_antisymm
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · 

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
⊢ enumOrd S (sSup {a | enumOrd S a ≤ s}) ≤ s

Next tactic:
rw [enumOrd_def]
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
⊢ sInf (S ∩ {b | ∀ c < sSup {a | enumOrd S a ≤ s}, enumOrd S c < b}) ≤ s

Next tactic:
refine' csInf_le' ⟨hs, fun a ha => _⟩
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
a : Ordinal.{u}
ha : a < sSup {a | enumOrd S a ≤ s}
⊢ enumOrd S a < s

Next tactic:
have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        exact csInf_le' hs
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
a : Ordinal.{u}
ha : a < sSup {a | enumOrd S a ≤ s}
⊢ enumOrd S 0 ≤ s

Next tactic:
rw [enumOrd_zero]
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
a : Ordinal.{u}
ha : a < sSup {a | enumOrd S a ≤ s}
⊢ sInf S ≤ s

Next tactic:
exact csInf_le' hs
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        exact csInf_le' hs
      -- Porting note: `flip` is required to infer a metavariable.
      

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
a : Ordinal.{u}
ha : a < sSup {a | enumOrd S a ≤ s}
this : enumOrd S 0 ≤ s
⊢ enumOrd S a < s

Next tactic:
rcases flip exists_lt_of_lt_csSup ha ⟨0, this⟩ with ⟨b, hb, hab⟩
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        exact csInf_le' hs
      -- Porting note: `flip` is required to infer a metavariable.
      rcases flip exists_lt_of_lt_csSup ha ⟨0, this⟩ with ⟨b, hb, hab⟩
      

Proof state:
case a.intro.intro
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
a : Ordinal.{u}
ha : a < sSup {a | enumOrd S a ≤ s}
this : enumOrd S 0 ≤ s
b : Ordinal.{u}
hb : b ∈ {a | enumOrd S a ≤ s}
hab : a < b
⊢ enumOrd S a < s

Next tactic:
exact (enumOrd_strictMono hS hab).trans_le hb
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        exact csInf_le' hs
      -- Porting note: `flip` is required to infer a metavariable.
      rcases flip exists_lt_of_lt_csSup ha ⟨0, this⟩ with ⟨b, hb, hab⟩
      exact (enumOrd_strictMono hS hab).trans_le hb
    · 

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
⊢ s ≤ enumOrd S (sSup {a | enumOrd S a ≤ s})

Next tactic:
by_contra! h
theorem enumOrd_surjective (hS : Unbounded (· < ·) S) : ∀ s ∈ S, ∃ a, enumOrd S a = s := fun s hs =>
  ⟨sSup { a | enumOrd S a ≤ s }, by
    apply le_antisymm
    · rw [enumOrd_def]
      refine' csInf_le' ⟨hs, fun a ha => _⟩
      have : enumOrd S 0 ≤ s := by
        rw [enumOrd_zero]
        exact csInf_le' hs
      -- Porting note: `flip` is required to infer a metavariable.
      rcases flip exists_lt_of_lt_csSup ha ⟨0, this⟩ with ⟨b, hb, hab⟩
      exact (enumOrd_strictMono hS hab).trans_le hb
    · by_contra! h
      

Proof state:
case a
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
s : Ordinal.{u}
hs : s ∈ S
h : enumOrd S (sSup {a | enumOrd S a ≤ s}) < s
⊢ False

Next tactic:
exact
        (le_csSup ⟨s, fun a => (lt_wf.self_le_of_strictMono (enumOrd_strictMono hS) a).trans⟩
              (enumOrd_succ_le hS hs h)).not_lt
          (lt_succ _)
theorem range_enumOrd (hS : Unbounded (· < ·) S) : range (enumOrd S) = S := by
  

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ range (enumOrd S) = S

Next tactic:
rw [range_eq_iff]
theorem range_enumOrd (hS : Unbounded (· < ·) S) : range (enumOrd S) = S := by
  rw [range_eq_iff]
  

Proof state:
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ (∀ (a : Ordinal.{u}), enumOrd S a ∈ S) ∧ ∀ b ∈ S, ∃ a, enumOrd S a = b

Next tactic:
exact ⟨enumOrd_mem hS, enumOrd_surjective hS⟩
/-- A characterization of `enumOrd`: it is the unique strict monotonic function with range `S`. -/
theorem eq_enumOrd (f : Ordinal → Ordinal) (hS : Unbounded (· < ·) S) :
    StrictMono f ∧ range f = S ↔ f = enumOrd S := by
  

Proof state:
S : Set Ordinal.{u}
f : Ordinal.{u} → Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ StrictMono f ∧ range f = S ↔ f = enumOrd S

Next tactic:
constructor
/-- A characterization of `enumOrd`: it is the unique strict monotonic function with range `S`. -/
theorem eq_enumOrd (f : Ordinal → Ordinal) (hS : Unbounded (· < ·) S) :
    StrictMono f ∧ range f = S ↔ f = enumOrd S := by
  constructor
  · 

Proof state:
case mp
S : Set Ordinal.{u}
f : Ordinal.{u} → Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ StrictMono f ∧ range f = S → f = enumOrd S

Next tactic:
rintro ⟨h₁, h₂⟩
/-- A characterization of `enumOrd`: it is the unique strict monotonic function with range `S`. -/
theorem eq_enumOrd (f : Ordinal → Ordinal) (hS : Unbounded (· < ·) S) :
    StrictMono f ∧ range f = S ↔ f = enumOrd S := by
  constructor
  · rintro ⟨h₁, h₂⟩
    

Proof state:
case mp.intro
S : Set Ordinal.{u}
f : Ordinal.{u} → Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
h₁ : StrictMono f
h₂ : range f = S
⊢ f = enumOrd S

Next tactic:
rwa [← lt_wf.eq_strictMono_iff_eq_range h₁ (enumOrd_strictMono hS), range_enumOrd hS]
/-- A characterization of `enumOrd`: it is the unique strict monotonic function with range `S`. -/
theorem eq_enumOrd (f : Ordinal → Ordinal) (hS : Unbounded (· < ·) S) :
    StrictMono f ∧ range f = S ↔ f = enumOrd S := by
  constructor
  · rintro ⟨h₁, h₂⟩
    rwa [← lt_wf.eq_strictMono_iff_eq_range h₁ (enumOrd_strictMono hS), range_enumOrd hS]
  · 

Proof state:
case mpr
S : Set Ordinal.{u}
f : Ordinal.{u} → Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ f = enumOrd S → StrictMono f ∧ range f = S

Next tactic:
rintro rfl
/-- A characterization of `enumOrd`: it is the unique strict monotonic function with range `S`. -/
theorem eq_enumOrd (f : Ordinal → Ordinal) (hS : Unbounded (· < ·) S) :
    StrictMono f ∧ range f = S ↔ f = enumOrd S := by
  constructor
  · rintro ⟨h₁, h₂⟩
    rwa [← lt_wf.eq_strictMono_iff_eq_range h₁ (enumOrd_strictMono hS), range_enumOrd hS]
  · rintro rfl
    

Proof state:
case mpr
S : Set Ordinal.{u}
hS : Unbounded (fun x x_1 => x < x_1) S
⊢ StrictMono (enumOrd S) ∧ range (enumOrd S) = S

Next tactic:
exact ⟨enumOrd_strictMono hS, range_enumOrd hS⟩
@[simp]
theorem one_add_nat_cast (m : ℕ) : 1 + (m : Ordinal) = succ m := by
  

Proof state:
m : ℕ
⊢ 1 + ↑m = ↑(succ m)

Next tactic:
rw [← Nat.cast_one, ← Nat.cast_add, add_comm]
@[simp]
theorem one_add_nat_cast (m : ℕ) : 1 + (m : Ordinal) = succ m := by
  rw [← Nat.cast_one, ← Nat.cast_add, add_comm]
  

Proof state:
m : ℕ
⊢ ↑(m + 1) = ↑(succ m)

Next tactic:
rfl
@[simp, norm_cast]
theorem nat_cast_mul (m : ℕ) : ∀ n : ℕ, ((m * n : ℕ) : Ordinal) = m * n
  | 0 => by 

Proof state:
m : ℕ
⊢ ↑(m * 0) = ↑m * ↑0

Next tactic:
simp
@[simp, norm_cast]
theorem nat_cast_mul (m : ℕ) : ∀ n : ℕ, ((m * n : ℕ) : Ordinal) = m * n
  | 0 => by simp
  | n + 1 => by 

Proof state:
m n : ℕ
⊢ ↑(m * (n + 1)) = ↑m * ↑(n + 1)

Next tactic:
rw [Nat.mul_succ, Nat.cast_add, nat_cast_mul m n, Nat.cast_succ, mul_add_one]
@[simp, norm_cast]
theorem nat_cast_le {m n : ℕ} : (m : Ordinal) ≤ n ↔ m ≤ n := by
  

Proof state:
m n : ℕ
⊢ ↑m ≤ ↑n ↔ m ≤ n

Next tactic:
rw [← Cardinal.ord_nat, ← Cardinal.ord_nat, Cardinal.ord_le_ord, Cardinal.natCast_le]
@[simp, norm_cast]
theorem nat_cast_lt {m n : ℕ} : (m : Ordinal) < n ↔ m < n := by
  

Proof state:
m n : ℕ
⊢ ↑m < ↑n ↔ m < n

Next tactic:
simp only [lt_iff_le_not_le, nat_cast_le]
@[simp, norm_cast]
theorem nat_cast_inj {m n : ℕ} : (m : Ordinal) = n ↔ m = n := by
  

Proof state:
m n : ℕ
⊢ ↑m = ↑n ↔ m = n

Next tactic:
simp only [le_antisymm_iff, nat_cast_le]
@[simp, norm_cast]
theorem nat_cast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by
  

Proof state:
m n : ℕ
⊢ ↑(m - n) = ↑m - ↑n

Next tactic:
rcases le_total m n with h | h
@[simp, norm_cast]
theorem nat_cast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by
  rcases le_total m n with h | h
  · 

Proof state:
case inl
m n : ℕ
h : m ≤ n
⊢ ↑(m - n) = ↑m - ↑n

Next tactic:
rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (nat_cast_le.2 h)]
@[simp, norm_cast]
theorem nat_cast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by
  rcases le_total m n with h | h
  · rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (nat_cast_le.2 h)]
    

Proof state:
case inl
m n : ℕ
h : m ≤ n
⊢ ↑0 = 0

Next tactic:
rfl
@[simp, norm_cast]
theorem nat_cast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by
  rcases le_total m n with h | h
  · rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (nat_cast_le.2 h)]
    rfl
  · 

Proof state:
case inr
m n : ℕ
h : n ≤ m
⊢ ↑(m - n) = ↑m - ↑n

Next tactic:
apply (add_left_cancel n).1
@[simp, norm_cast]
theorem nat_cast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by
  rcases le_total m n with h | h
  · rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (nat_cast_le.2 h)]
    rfl
  · apply (add_left_cancel n).1
    

Proof state:
case inr
m n : ℕ
h : n ≤ m
⊢ ↑n + ↑(m - n) = ↑n + (↑m - ↑n)

Next tactic:
rw [← Nat.cast_add, add_tsub_cancel_of_le h, Ordinal.add_sub_cancel_of_le (nat_cast_le.2 h)]
@[simp, norm_cast]
theorem nat_cast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by
  

Proof state:
m n : ℕ
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
rcases eq_or_ne n 0 with (rfl | hn)
@[simp, norm_cast]
theorem nat_cast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · 

Proof state:
case inl
m : ℕ
⊢ ↑(m / 0) = ↑m / ↑0

Next tactic:
simp
@[simp, norm_cast]
theorem nat_cast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  · 

Proof state:
case inr
m n : ℕ
hn : n ≠ 0
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
have hn' := nat_cast_ne_zero.2 hn
@[simp, norm_cast]
theorem nat_cast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  · have hn' := nat_cast_ne_zero.2 hn
    

Proof state:
case inr
m n : ℕ
hn : n ≠ 0
hn' : ↑n ≠ 0
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
apply le_antisymm
@[simp, norm_cast]
theorem nat_cast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  · have hn' := nat_cast_ne_zero.2 hn
    apply le_antisymm
    · 

Proof state:
case inr.a
m n : ℕ
hn : n ≠ 0
hn' : ↑n ≠ 0
⊢ ↑(m / n) ≤ ↑m / ↑n

Next tactic:
rw [le_div hn', ← nat_cast_mul, nat_cast_le, mul_comm]