l3lab/ntp-mathlib huggingface dataset:
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  

Proof state:
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
⊢ IsNormal (enumOrd s) ↔ IsClosed s

Next tactic:
refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · 

Proof state:
case refine'_1
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
⊢ sup f ∈ s

Next tactic:
let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    

Proof state:
case refine'_1
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
⊢ sup f ∈ s

Next tactic:
suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      

Proof state:
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
this : enumOrd s (sup g) = sup f
⊢ sup f ∈ s

Next tactic:
rw [← this]
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      

Proof state:
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
this : enumOrd s (sup g) = sup f
⊢ enumOrd s (sup g) ∈ s

Next tactic:
exact enumOrd_mem hs _
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    

Proof state:
case refine'_1
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
⊢ enumOrd s (sup g) = sup f

Next tactic:
rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    

Proof state:
case refine'_1
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
⊢ sup (enumOrd s ∘ g) = sup f

Next tactic:
congr
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    

Proof state:
case refine'_1.e_f
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
⊢ enumOrd s ∘ g = f

Next tactic:
ext x
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    

Proof state:
case refine'_1.e_f.h
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
x : ι
⊢ (enumOrd s ∘ g) x = f x

Next tactic:
change ((enumOrdOrderIso hs) _).val = f x
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    

Proof state:
case refine'_1.e_f.h
s : Set Ordinal.{u}
a : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsNormal (enumOrd s)
ι : Type u
hι : Nonempty ι
f : ι → Ordinal.{u}
hf : ∀ (i : ι), f i ∈ s
g : ι → Ordinal.{u} := fun i => (OrderIso.symm (enumOrdOrderIso hs)) { val := f i, property := (_ : f i ∈ s) }
x : ι
⊢ ↑((enumOrdOrderIso hs) (g x)) = f x

Next tactic:
rw [OrderIso.apply_symm_apply]
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · 

Proof state:
case refine'_2
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h : IsClosed s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
⊢ enumOrd s a ≤ o

Next tactic:
rw [isClosed_iff_bsup] at h
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    

Proof state:
case refine'_2
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
⊢ enumOrd s a ≤ o

Next tactic:
suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    

Proof state:
case refine'_2
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
this : enumOrd s a ≤ bsup a fun b x => enumOrd s b
⊢ enumOrd s a ≤ o
case this
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
⊢ enumOrd s a ≤ bsup a fun b x => enumOrd s b

Next tactic:
exact this.trans (bsup_le H)
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    

Proof state:
case this
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
⊢ enumOrd s a ≤ bsup a fun b x => enumOrd s b

Next tactic:
cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    

Proof state:
case this.intro
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
⊢ enumOrd s a ≤ bsup a fun b x => enumOrd s b

Next tactic:
rw [← hb]
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    rw [← hb]
    

Proof state:
case this.intro
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
⊢ enumOrd s a ≤ enumOrd s b

Next tactic:
apply Hs.monotone
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    rw [← hb]
    apply Hs.monotone
    

Proof state:
case this.intro.a
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
⊢ a ≤ b

Next tactic:
by_contra! hba
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    rw [← hb]
    apply Hs.monotone
    by_contra! hba
    

Proof state:
case this.intro.a
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
hba : b < a
⊢ False

Next tactic:
apply (Hs (lt_succ b)).not_le
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    rw [← hb]
    apply Hs.monotone
    by_contra! hba
    apply (Hs (lt_succ b)).not_le
    

Proof state:
case this.intro.a
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
hba : b < a
⊢ enumOrd s (succ b) ≤ enumOrd s b

Next tactic:
rw [hb]
theorem enumOrd_isNormal_iff_isClosed (hs : s.Unbounded (· < ·)) :
    IsNormal (enumOrd s) ↔ IsClosed s := by
  have Hs := enumOrd_strictMono hs
  refine'
    ⟨fun h => isClosed_iff_sup.2 fun {ι} hι f hf => _, fun h =>
      (isNormal_iff_strictMono_limit _).2 ⟨Hs, fun a ha o H => _⟩⟩
  · let g : ι → Ordinal.{u} := fun i => (enumOrdOrderIso hs).symm ⟨_, hf i⟩
    suffices enumOrd s (sup.{u, u} g) = sup.{u, u} f by
      rw [← this]
      exact enumOrd_mem hs _
    rw [@IsNormal.sup.{u, u, u} _ h ι g hι]
    congr
    ext x
    change ((enumOrdOrderIso hs) _).val = f x
    rw [OrderIso.apply_symm_apply]
  · rw [isClosed_iff_bsup] at h
    suffices : enumOrd s a ≤ bsup.{u, u} a fun b (_ : b < a) => enumOrd s b
    exact this.trans (bsup_le H)
    cases' enumOrd_surjective hs _
        (h ha.1 (fun b _ => enumOrd s b) fun b _ => enumOrd_mem hs b) with
      b hb
    rw [← hb]
    apply Hs.monotone
    by_contra! hba
    apply (Hs (lt_succ b)).not_le
    rw [hb]
    

Proof state:
case this.intro.a
s : Set Ordinal.{u}
a✝ : Ordinal.{u}
hs : Set.Unbounded (fun x x_1 => x < x_1) s
Hs : StrictMono (enumOrd s)
h :
  ∀ {o : Ordinal.{u}},
    o ≠ 0 →
      ∀ (f : (a : Ordinal.{u}) → a < o → Ordinal.{u}), (∀ (i : Ordinal.{u}) (hi : i < o), f i hi ∈ s) → bsup o f ∈ s
a : Ordinal.{u}
ha : IsLimit a
o : Ordinal.{u}
H : ∀ b < a, enumOrd s b ≤ o
b : Ordinal.{u}
hb : enumOrd s b = bsup a fun b x => enumOrd s b
hba : b < a
⊢ enumOrd s (succ b) ≤ bsup a fun b x => enumOrd s b

Next tactic:
exact le_bsup.{u, u} _ _ (ha.2 _ hba)
@[ext]
theorem ext {α : Type u} {a b : Thunk α} (eq : a.get = b.get) : a = b := by
  

Proof state:
α : Type u
a b : Thunk α
eq : Thunk.get a = Thunk.get b
⊢ a = b

Next tactic:
have ⟨_⟩ := a
@[ext]
theorem ext {α : Type u} {a b : Thunk α} (eq : a.get = b.get) : a = b := by
  have ⟨_⟩ := a
  

Proof state:
α : Type u
a b : Thunk α
fn✝ : Unit → α
eq : Thunk.get { fn := fn✝ } = Thunk.get b
⊢ { fn := fn✝ } = b

Next tactic:
have ⟨_⟩ := b
@[ext]
theorem ext {α : Type u} {a b : Thunk α} (eq : a.get = b.get) : a = b := by
  have ⟨_⟩ := a
  have ⟨_⟩ := b
  

Proof state:
α : Type u
a b : Thunk α
fn✝¹ fn✝ : Unit → α
eq : Thunk.get { fn := fn✝¹ } = Thunk.get { fn := fn✝ }
⊢ { fn := fn✝¹ } = { fn := fn✝ }

Next tactic:
congr
@[ext]
theorem ext {α : Type u} {a b : Thunk α} (eq : a.get = b.get) : a = b := by
  have ⟨_⟩ := a
  have ⟨_⟩ := b
  congr
  

Proof state:
case e_fn
α : Type u
a b : Thunk α
fn✝¹ fn✝ : Unit → α
eq : Thunk.get { fn := fn✝¹ } = Thunk.get { fn := fn✝ }
⊢ fn✝¹ = fn✝

Next tactic:
exact funext fun _ ↦ eq
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  

Proof state:
α : Type u
inst✝ : DecidableEq α
⊢ DecidableEq (Thunk α)

Next tactic:
intro a b
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  intro a b
  

Proof state:
α : Type u
inst✝ : DecidableEq α
a b : Thunk α
⊢ Decidable (a = b)

Next tactic:
have : a = b ↔ a.get = b.get := ⟨by intro x; rw [x], by intro; ext; assumption⟩
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  intro a b
  have : a = b ↔ a.get = b.get := ⟨by 

Proof state:
α : Type u
inst✝ : DecidableEq α
a b : Thunk α
⊢ a = b → Thunk.get a = Thunk.get b

Next tactic:
intro x
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  intro a b
  have : a = b ↔ a.get = b.get := ⟨by intro x; 

Proof state:
α : Type u
inst✝ : DecidableEq α
a b : Thunk α
x : a = b
⊢ Thunk.get a = Thunk.get b

Next tactic:
rw [x]
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  intro a b
  have : a = b ↔ a.get = b.get := ⟨by intro x; rw [x], by 

Proof state:
α : Type u
inst✝ : DecidableEq α
a b : Thunk α
⊢ Thunk.get a = Thunk.get b → a = b

Next tactic:
intro
instance {α : Type u} [DecidableEq α] : DecidableEq (Thunk α) := by
  intro a b
  have : a = b ↔ a.get = b.get := ⟨by intro x; rw [x], by intro; 

Proof state:
α : Type u
inst✝ : DecidableEq α
a b : Thunk α
a✝ : Thunk.get a = Thunk.get b
⊢ a = b

Next tactic:
ext