l3lab/ntp-mathlib huggingface dataset:
/-- The unit isomorphism of the equivalence
`Karoubi (HomologicalComplex C c) ≌ HomologicalComplex (Karoubi C) c`. -/
@[simps]
def unitIso : 𝟭 (Karoubi (HomologicalComplex C c)) ≅ functor ⋙ inverse where
  hom :=
    { app := fun P =>
        { f :=
            { f := fun n => P.p.f n
              comm' := fun i j _ => by
                dsimp
                simp only [HomologicalComplex.Hom.comm, HomologicalComplex.Hom.comm_assoc,
                  HomologicalComplex.p_idem] }
          comm := by
            ext n
            dsimp
            simp only [HomologicalComplex.p_idem] }
      naturality := fun P Q φ => by
        ext
        dsimp
        simp only [comp_f, HomologicalComplex.comp_f, HomologicalComplex.comp_p_d, Inverse.map_f_f,
          Functor.map_f_f, HomologicalComplex.p_comp_d] }
  inv :=
    { app := fun P =>
        { f :=
            { f := fun n => P.p.f n
              comm' := fun i j _ => by
                dsimp
                simp only [HomologicalComplex.Hom.comm, assoc, HomologicalComplex.p_idem] }
          comm := by
            ext n
            dsimp
            simp only [HomologicalComplex.p_idem] }
      naturality := fun P Q φ => by
        ext
        dsimp
        simp only [comp_f, HomologicalComplex.comp_f, Inverse.map_f_f, Functor.map_f_f,
          HomologicalComplex.comp_p_d, HomologicalComplex.p_comp_d] }
  hom_inv_id := by
    ext
    dsimp
    simp only [HomologicalComplex.p_idem, comp_f, HomologicalComplex.comp_f, _root_.id_eq]
  inv_hom_id := by
    ext
    dsimp
    

Proof state:
case w.h.h.h
C : Type u_1
inst✝¹ : Category.{?u.36754, u_1} C
inst✝ : Preadditive C
ι : Type u_2
c : ComplexShape ι
x✝ : Karoubi (HomologicalComplex C c)
i✝ : ι
⊢ HomologicalComplex.Hom.f x✝.p i✝ ≫ HomologicalComplex.Hom.f x✝.p i✝ = HomologicalComplex.Hom.f x✝.p i✝

Next tactic:
simp only [HomologicalComplex.p_idem, comp_f, HomologicalComplex.comp_f, _root_.id_eq,
      Inverse.obj_p_f, Functor.obj_X_p]
instance [IsIdempotentComplete C] : IsIdempotentComplete (HomologicalComplex C c) := by
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.61997, u_1} C
inst✝³ : Preadditive C
ι : Type u_2
c : ComplexShape ι
α : Type u_3
inst✝² : AddRightCancelSemigroup α
inst✝¹ : One α
inst✝ : IsIdempotentComplete C
⊢ IsIdempotentComplete (HomologicalComplex C c)

Next tactic:
rw [isIdempotentComplete_iff_of_equivalence
      ((toKaroubiEquivalence C).mapHomologicalComplex c),
    ← isIdempotentComplete_iff_of_equivalence (karoubiHomologicalComplexEquivalence C c)]
instance [IsIdempotentComplete C] : IsIdempotentComplete (HomologicalComplex C c) := by
  rw [isIdempotentComplete_iff_of_equivalence
      ((toKaroubiEquivalence C).mapHomologicalComplex c),
    ← isIdempotentComplete_iff_of_equivalence (karoubiHomologicalComplexEquivalence C c)]
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.61997, u_1} C
inst✝³ : Preadditive C
ι : Type u_2
c : ComplexShape ι
α : Type u_3
inst✝² : AddRightCancelSemigroup α
inst✝¹ : One α
inst✝ : IsIdempotentComplete C
⊢ IsIdempotentComplete (Karoubi (HomologicalComplex C c))

Next tactic:
infer_instance
/-- Category structure on `Grpd` -/
instance category : LargeCategory.{max v u} Grpd.{v, u} where
  Hom C D := C ⥤ D
  id C := 𝟭 C
  comp F G := F ⋙ G
  id_comp _ := rfl
  comp_id _ := rfl
  assoc := by 

Proof state:
⊢ ∀ {W X Y Z : Grpd} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z), (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
intros
/-- Category structure on `Grpd` -/
instance category : LargeCategory.{max v u} Grpd.{v, u} where
  Hom C D := C ⥤ D
  id C := 𝟭 C
  comp F G := F ⋙ G
  id_comp _ := rfl
  comp_id _ := rfl
  assoc := by intros; 

Proof state:
W✝ X✝ Y✝ Z✝ : Grpd
f✝ : W✝ ⟶ X✝
g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
⊢ (f✝ ≫ g✝) ≫ h✝ = f✝ ≫ g✝ ≫ h✝

Next tactic:
rfl
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      

Proof state:
J : Type u
F : J → Grpd
⊢ ∀ (s : Limits.Fan F) (j : J),
    (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j

Next tactic:
intros
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      

Proof state:
J : Type u
F : J → Grpd
s✝ : Limits.Fan F
j✝ : J
⊢ (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s✝ ≫ Limits.Fan.proj (piLimitFan F) j✝ = Limits.Fan.proj s✝ j✝

Next tactic:
dsimp only [piLimitFan]
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      

Proof state:
J : Type u
F : J → Grpd
s✝ : Limits.Fan F
j✝ : J
⊢ (Functor.pi' fun j => Limits.Fan.proj s✝ j) ≫
      Limits.Fan.proj (Limits.Fan.mk (of ((j : J) → ↑(F j))) fun j => Pi.eval (fun j => ↑(F j)) j) j✝ =
    Limits.Fan.proj s✝ j✝

Next tactic:
simp [hom_to_functor]
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      simp [hom_to_functor])
    (by
      

Proof state:
J : Type u
F : J → Grpd
⊢ ∀ (s : Limits.Fan F) (m : s.pt ⟶ (piLimitFan F).pt),
    (∀ (j : J), m ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j) →
      m = (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s

Next tactic:
intro s m w
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      simp [hom_to_functor])
    (by
      intro s m w
      

Proof state:
J : Type u
F : J → Grpd
s : Limits.Fan F
m : s.pt ⟶ (piLimitFan F).pt
w : ∀ (j : J), m ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j
⊢ m = (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s

Next tactic:
apply Functor.pi_ext
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      simp [hom_to_functor])
    (by
      intro s m w
      apply Functor.pi_ext
      

Proof state:
case h
J : Type u
F : J → Grpd
s : Limits.Fan F
m : s.pt ⟶ (piLimitFan F).pt
w : ∀ (j : J), m ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j
⊢ ∀ (i : J),
    m ⋙ Pi.eval (fun i => ↑(F i)) i =
      (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s ⋙ Pi.eval (fun i => ↑(F i)) i

Next tactic:
intro j
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      simp [hom_to_functor])
    (by
      intro s m w
      apply Functor.pi_ext
      intro j; 

Proof state:
case h
J : Type u
F : J → Grpd
s : Limits.Fan F
m : s.pt ⟶ (piLimitFan F).pt
w : ∀ (j : J), m ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j
j : J
⊢ m ⋙ Pi.eval (fun i => ↑(F i)) j = (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s ⋙ Pi.eval (fun i => ↑(F i)) j

Next tactic:
specialize w j
/-- The product fan over an indexed family of groupoids, is a limit cone. -/
def piLimitFanIsLimit ⦃J : Type u⦄ (F : J → Grpd.{u, u}) : Limits.IsLimit (piLimitFan F) :=
  Limits.mkFanLimit (piLimitFan F) (fun s => Functor.pi' fun j => s.proj j)
    (by
      intros
      dsimp only [piLimitFan]
      simp [hom_to_functor])
    (by
      intro s m w
      apply Functor.pi_ext
      intro j; specialize w j
      

Proof state:
case h
J : Type u
F : J → Grpd
s : Limits.Fan F
m : s.pt ⟶ (piLimitFan F).pt
j : J
w : m ≫ Limits.Fan.proj (piLimitFan F) j = Limits.Fan.proj s j
⊢ m ⋙ Pi.eval (fun i => ↑(F i)) j = (fun s => Functor.pi' fun j => Limits.Fan.proj s j) s ⋙ Pi.eval (fun i => ↑(F i)) j

Next tactic:
simpa
instance has_pi : Limits.HasProducts Grpd.{u, u} :=
  Limits.hasProducts_of_limit_fans (by 

Proof state:
⊢ {J : Type ?u.17516} → (f : J → Grpd) → Limits.Fan f

Next tactic:
apply piLimitFan
instance has_pi : Limits.HasProducts Grpd.{u, u} :=
  Limits.hasProducts_of_limit_fans (by apply piLimitFan) (by 

Proof state:
⊢ {J : Type u} → (f : J → Grpd) → Limits.IsLimit (piLimitFan f)

Next tactic:
apply piLimitFanIsLimit
@[simp]
theorem piIsoPi_hom_π (J : Type u) (f : J → Grpd.{u, u}) (j : J) :
    (piIsoPi J f).hom ≫ Limits.Pi.π f j = CategoryTheory.Pi.eval _ j := by
  

Proof state:
J : Type u
f : J → Grpd
j : J
⊢ (piIsoPi J f).hom ≫ Limits.Pi.π f j = Pi.eval (fun i => ↑(f i)) j

Next tactic:
simp [piIsoPi]
@[simp]
theorem piIsoPi_hom_π (J : Type u) (f : J → Grpd.{u, u}) (j : J) :
    (piIsoPi J f).hom ≫ Limits.Pi.π f j = CategoryTheory.Pi.eval _ j := by
  simp [piIsoPi]
  

Proof state:
J : Type u
f : J → Grpd
j : J
⊢ (piLimitFan f).π.app { as := j } = Pi.eval (fun i => ↑(f i)) j

Next tactic:
rfl
theorem principal_iff_principal_swap {op : Ordinal → Ordinal → Ordinal} {o : Ordinal} :
    Principal op o ↔ Principal (Function.swap op) o := by
  

Proof state:
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
o : Ordinal.{u_1}
⊢ Principal op o ↔ Principal (Function.swap op) o

Next tactic:
constructor
theorem principal_iff_principal_swap {op : Ordinal → Ordinal → Ordinal} {o : Ordinal} :
    Principal op o ↔ Principal (Function.swap op) o := by
  constructor <;> 

Proof state:
case mp
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
o : Ordinal.{u_1}
⊢ Principal op o → Principal (Function.swap op) o

Next tactic:
exact fun h a b ha hb => h hb ha
theorem principal_iff_principal_swap {op : Ordinal → Ordinal → Ordinal} {o : Ordinal} :
    Principal op o ↔ Principal (Function.swap op) o := by
  constructor <;> 

Proof state:
case mpr
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
o : Ordinal.{u_1}
⊢ Principal (Function.swap op) o → Principal op o

Next tactic:
exact fun h a b ha hb => h hb ha
@[simp]
theorem principal_one_iff {op : Ordinal → Ordinal → Ordinal} : Principal op 1 ↔ op 0 0 = 0 := by
  

Proof state:
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
⊢ Principal op 1 ↔ op 0 0 = 0

Next tactic:
refine' ⟨fun h => _, fun h a b ha hb => _⟩
@[simp]
theorem principal_one_iff {op : Ordinal → Ordinal → Ordinal} : Principal op 1 ↔ op 0 0 = 0 := by
  refine' ⟨fun h => _, fun h a b ha hb => _⟩
  · 

Proof state:
case refine'_1
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
h : Principal op 1
⊢ op 0 0 = 0

Next tactic:
rw [← lt_one_iff_zero]
@[simp]
theorem principal_one_iff {op : Ordinal → Ordinal → Ordinal} : Principal op 1 ↔ op 0 0 = 0 := by
  refine' ⟨fun h => _, fun h a b ha hb => _⟩
  · rw [← lt_one_iff_zero]
    

Proof state:
case refine'_1
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
h : Principal op 1
⊢ op 0 0 < 1

Next tactic:
exact h zero_lt_one zero_lt_one
@[simp]
theorem principal_one_iff {op : Ordinal → Ordinal → Ordinal} : Principal op 1 ↔ op 0 0 = 0 := by
  refine' ⟨fun h => _, fun h a b ha hb => _⟩
  · rw [← lt_one_iff_zero]
    exact h zero_lt_one zero_lt_one
  · 

Proof state:
case refine'_2
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
h : op 0 0 = 0
a b : Ordinal.{u_1}
ha : a < 1
hb : b < 1
⊢ op a b < 1

Next tactic:
rwa [lt_one_iff_zero, ha, hb] at *
theorem Principal.iterate_lt {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal} (hao : a < o)
    (ho : Principal op o) (n : ℕ) : (op a)^[n] a < o := by
  

Proof state:
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
a o : Ordinal.{u_1}
hao : a < o
ho : Principal op o
n : ℕ
⊢ (op a)^[n] a < o

Next tactic:
induction' n with n hn
theorem Principal.iterate_lt {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal} (hao : a < o)
    (ho : Principal op o) (n : ℕ) : (op a)^[n] a < o := by
  induction' n with n hn
  · 

Proof state:
case zero
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
a o : Ordinal.{u_1}
hao : a < o
ho : Principal op o
⊢ (op a)^[Nat.zero] a < o

Next tactic:
rwa [Function.iterate_zero]
theorem Principal.iterate_lt {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal} (hao : a < o)
    (ho : Principal op o) (n : ℕ) : (op a)^[n] a < o := by
  induction' n with n hn
  · rwa [Function.iterate_zero]
  · 

Proof state:
case succ
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
a o : Ordinal.{u_1}
hao : a < o
ho : Principal op o
n : ℕ
hn : (op a)^[n] a < o
⊢ (op a)^[Nat.succ n] a < o

Next tactic:
rw [Function.iterate_succ']
theorem Principal.iterate_lt {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal} (hao : a < o)
    (ho : Principal op o) (n : ℕ) : (op a)^[n] a < o := by
  induction' n with n hn
  · rwa [Function.iterate_zero]
  · rw [Function.iterate_succ']
    

Proof state:
case succ
op : Ordinal.{u_1} → Ordinal.{u_1} → Ordinal.{u_1}
a o : Ordinal.{u_1}
hao : a < o
ho : Principal op o
n : ℕ
hn : (op a)^[n] a < o
⊢ (op a ∘ (op a)^[n]) a < o

Next tactic:
exact ho hao hn
theorem op_eq_self_of_principal {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal.{u}} (hao : a < o)
    (H : IsNormal (op a)) (ho : Principal op o) (ho' : IsLimit o) : op a o = o := by
  

Proof state:
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
a o : Ordinal.{u}
hao : a < o
H : IsNormal (op a)
ho : Principal op o
ho' : IsLimit o
⊢ op a o = o

Next tactic:
refine' le_antisymm _ (H.self_le _)
theorem op_eq_self_of_principal {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal.{u}} (hao : a < o)
    (H : IsNormal (op a)) (ho : Principal op o) (ho' : IsLimit o) : op a o = o := by
  refine' le_antisymm _ (H.self_le _)
  

Proof state:
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
a o : Ordinal.{u}
hao : a < o
H : IsNormal (op a)
ho : Principal op o
ho' : IsLimit o
⊢ op a o ≤ o

Next tactic:
rw [← IsNormal.bsup_eq.{u, u} H ho', bsup_le_iff]
theorem op_eq_self_of_principal {op : Ordinal → Ordinal → Ordinal} {a o : Ordinal.{u}} (hao : a < o)
    (H : IsNormal (op a)) (ho : Principal op o) (ho' : IsLimit o) : op a o = o := by
  refine' le_antisymm _ (H.self_le _)
  rw [← IsNormal.bsup_eq.{u, u} H ho', bsup_le_iff]
  

Proof state:
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
a o : Ordinal.{u}
hao : a < o
H : IsNormal (op a)
ho : Principal op o
ho' : IsLimit o
⊢ ∀ i < o, op a i ≤ o

Next tactic:
exact fun b hbo => (ho hao hbo).le
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  

Proof state:
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
ha : a < nfp (fun o' => blsub₂ o' o' fun a x b x => op a b) o
hb : b < nfp (fun o' => blsub₂ o' o' fun a x b x => op a b) o
⊢ op a b < nfp (fun o' => blsub₂ o' o' fun a x b x => op a b) o

Next tactic:
rw [lt_nfp] at *
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  

Proof state:
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
ha : ∃ n, a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
hb : ∃ n, b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
⊢ ∃ n, op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o

Next tactic:
cases' ha with m hm
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  

Proof state:
case intro
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
hb : ∃ n, b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
⊢ ∃ n, op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o

Next tactic:
cases' hb with n hn
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  

Proof state:
case intro.intro
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
⊢ ∃ n, op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o

Next tactic:
cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · 

Proof state:
case intro.intro.inl
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
⊢ ∃ n, op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o

Next tactic:
use n + 1
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · use n + 1
    

Proof state:
case h
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
⊢ op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n + 1] o

Next tactic:
rw [Function.iterate_succ']
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · use n + 1
    rw [Function.iterate_succ']
    

Proof state:
case h
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
⊢ op a b < ((fun o' => blsub₂ o' o' fun a x b x => op a b) ∘ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n]) o

Next tactic:
exact lt_blsub₂ (@fun a _ b _ => op a b) (hm.trans_le h) hn
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · use n + 1
    rw [Function.iterate_succ']
    exact lt_blsub₂ (@fun a _ b _ => op a b) (hm.trans_le h) hn
  · 

Proof state:
case intro.intro.inr
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
⊢ ∃ n, op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o

Next tactic:
use m + 1
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · use n + 1
    rw [Function.iterate_succ']
    exact lt_blsub₂ (@fun a _ b _ => op a b) (hm.trans_le h) hn
  · use m + 1
    

Proof state:
case h
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
⊢ op a b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m + 1] o

Next tactic:
rw [Function.iterate_succ']
theorem principal_nfp_blsub₂ (op : Ordinal → Ordinal → Ordinal) (o : Ordinal) :
    Principal op (nfp (fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b)) o) :=
  fun a b ha hb => by
  rw [lt_nfp] at *
  cases' ha with m hm
  cases' hb with n hn
  cases' le_total
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[m] o)
    ((fun o' => blsub₂.{u, u, u} o' o' (@fun a _ b _ => op a b))^[n] o) with h h
  · use n + 1
    rw [Function.iterate_succ']
    exact lt_blsub₂ (@fun a _ b _ => op a b) (hm.trans_le h) hn
  · use m + 1
    rw [Function.iterate_succ']
    

Proof state:
case h
op : Ordinal.{u} → Ordinal.{u} → Ordinal.{u}
o a b : Ordinal.{u}
m : ℕ
hm : a < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
n : ℕ
hn : b < (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o
h : (fun o' => blsub₂ o' o' fun a x b x => op a b)^[n] o ≤ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m] o
⊢ op a b < ((fun o' => blsub₂ o' o' fun a x b x => op a b) ∘ (fun o' => blsub₂ o' o' fun a x b x => op a b)^[m]) o

Next tactic:
exact lt_blsub₂ (@fun a _ b _ => op a b) hm (hn.trans_le h)
theorem principal_add_of_le_one {o : Ordinal} (ho : o ≤ 1) : Principal (· + ·) o := by
  

Proof state:
o : Ordinal.{u_1}
ho : o ≤ 1
⊢ Principal (fun x x_1 => x + x_1) o

Next tactic:
rcases le_one_iff.1 ho with (rfl | rfl)
theorem principal_add_of_le_one {o : Ordinal} (ho : o ≤ 1) : Principal (· + ·) o := by
  rcases le_one_iff.1 ho with (rfl | rfl)
  · 

Proof state:
case inl
ho : 0 ≤ 1
⊢ Principal (fun x x_1 => x + x_1) 0

Next tactic:
exact principal_zero
theorem principal_add_of_le_one {o : Ordinal} (ho : o ≤ 1) : Principal (· + ·) o := by
  rcases le_one_iff.1 ho with (rfl | rfl)
  · exact principal_zero
  · 

Proof state:
case inr
ho : 1 ≤ 1
⊢ Principal (fun x x_1 => x + x_1) 1

Next tactic:
exact principal_add_one
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  

Proof state:
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
⊢ IsLimit o

Next tactic:
refine' ⟨fun ho₀ => _, fun a hao => _⟩
theorem principal_add_isLimit {o : Ordinal} (ho₁ : 1 < o) (ho : Principal (· + ·) o) :
    o.IsLimit := by
  refine' ⟨fun ho₀ => _, fun a hao => _⟩
  · 

Proof state:
case refine'_1
o : Ordinal.{u_1}
ho₁ : 1 < o
ho : Principal (fun x x_1 => x + x_1) o
ho₀ : o = 0
⊢ False

Next tactic:
rw [ho₀] at ho₁