l3lab/ntp-mathlib huggingface dataset:
theorem extendSubtype_apply_of_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) :
    e.extendSubtype x = e ⟨x, hx⟩ := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : p x
⊢ (extendSubtype e) x = ↑(e { val := x, property := hx })

Next tactic:
dsimp only [extendSubtype]
theorem extendSubtype_apply_of_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) :
    e.extendSubtype x = e ⟨x, hx⟩ := by
  dsimp only [extendSubtype]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : p x
⊢ (subtypeCongr e (toCompl e)) x = ↑(e { val := x, property := hx })

Next tactic:
simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply]
theorem extendSubtype_apply_of_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) :
    e.extendSubtype x = e ⟨x, hx⟩ := by
  dsimp only [extendSubtype]
  simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : p x
⊢ (sumCompl fun x => q x) (Sum.map (⇑e) (⇑(toCompl e)) ((sumCompl fun x => p x).symm x)) =
    ↑(e { val := x, property := hx })

Next tactic:
rw [sumCompl_apply_symm_of_pos _ _ hx, Sum.map_inl, sumCompl_apply_inl]
theorem extendSubtype_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) :
    q (e.extendSubtype x) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : p x
⊢ q ((extendSubtype e) x)

Next tactic:
convert (e ⟨x, hx⟩).2
theorem extendSubtype_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) :
    q (e.extendSubtype x) := by
  convert (e ⟨x, hx⟩).2
  

Proof state:
case h.e'_1
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : p x
⊢ (extendSubtype e) x = ↑(e { val := x, property := hx })

Next tactic:
rw [e.extendSubtype_apply_of_mem _ hx]
theorem extendSubtype_apply_of_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) :
    e.extendSubtype x = e.toCompl ⟨x, hx⟩ := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : ¬p x
⊢ (extendSubtype e) x = ↑((toCompl e) { val := x, property := hx })

Next tactic:
dsimp only [extendSubtype]
theorem extendSubtype_apply_of_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) :
    e.extendSubtype x = e.toCompl ⟨x, hx⟩ := by
  dsimp only [extendSubtype]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : ¬p x
⊢ (subtypeCongr e (toCompl e)) x = ↑((toCompl e) { val := x, property := hx })

Next tactic:
simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply]
theorem extendSubtype_apply_of_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) :
    e.extendSubtype x = e.toCompl ⟨x, hx⟩ := by
  dsimp only [extendSubtype]
  simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : ¬p x
⊢ (sumCompl fun x => q x) (Sum.map (⇑e) (⇑(toCompl e)) ((sumCompl fun x => p x).symm x)) =
    ↑((toCompl e) { val := x, property := hx })

Next tactic:
rw [sumCompl_apply_symm_of_neg _ _ hx, Sum.map_inr, sumCompl_apply_inr]
theorem extendSubtype_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) :
    ¬q (e.extendSubtype x) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : ¬p x
⊢ ¬q ((extendSubtype e) x)

Next tactic:
convert (e.toCompl ⟨x, hx⟩).2
theorem extendSubtype_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) :
    ¬q (e.extendSubtype x) := by
  convert (e.toCompl ⟨x, hx⟩).2
  

Proof state:
case h.e'_1.h.e'_1
α : Type u_1
β : Type u_2
inst✝³ : Fintype α
inst✝² : DecidableEq β
e✝ : Perm α
f : α ↪ β
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : { x // p x } ≃ { x // q x }
x : α
hx : ¬p x
⊢ (extendSubtype e) x = ↑((toCompl e) { val := x, property := hx })

Next tactic:
rw [e.extendSubtype_apply_of_not_mem _ hx]
theorem IsROrC.tendsto_inverse_atTop_nhds_0_nat :
    Tendsto (fun n : ℕ => (n : 𝕜)⁻¹) atTop (nhds 0) := by
  

Proof state:
𝕜 : Type u_1
inst✝ : IsROrC 𝕜
⊢ Tendsto (fun n => (↑n)⁻¹) atTop (nhds 0)

Next tactic:
convert tendsto_algebraMap_inverse_atTop_nhds_0_nat 𝕜
theorem IsROrC.tendsto_inverse_atTop_nhds_0_nat :
    Tendsto (fun n : ℕ => (n : 𝕜)⁻¹) atTop (nhds 0) := by
  convert tendsto_algebraMap_inverse_atTop_nhds_0_nat 𝕜
  

Proof state:
case h.e'_3.h
𝕜 : Type u_1
inst✝ : IsROrC 𝕜
x✝ : ℕ
⊢ (↑x✝)⁻¹ = (⇑(algebraMap ℝ 𝕜) ∘ fun n => (↑n)⁻¹) x✝

Next tactic:
simp
theorem CompClosure.of {a b : C} (m₁ m₂ : a ⟶ b) (h : r m₁ m₂) : CompClosure r m₁ m₂ := by
  

Proof state:
C : Type u_2
inst✝ : Category.{u_1, u_2} C
r : HomRel C
a b : C
m₁ m₂ : a ⟶ b
h : r m₁ m₂
⊢ CompClosure r m₁ m₂

Next tactic:
simpa using CompClosure.intro (𝟙 _) m₁ m₂ (𝟙 _) h
theorem comp_left {a b c : C} (f : a ⟶ b) :
    ∀ (g₁ g₂ : b ⟶ c) (_ : CompClosure r g₁ g₂), CompClosure r (f ≫ g₁) (f ≫ g₂)
  | _, _, ⟨x, m₁, m₂, y, h⟩ => by 

Proof state:
C : Type u_2
inst✝ : Category.{u_1, u_2} C
r : HomRel C
a b c : C
f : a ⟶ b
a✝ b✝ : C
x : b ⟶ a✝
m₁ m₂ : a✝ ⟶ b✝
y : b✝ ⟶ c
h : r m₁ m₂
⊢ CompClosure r (f ≫ x ≫ m₁ ≫ y) (f ≫ x ≫ m₂ ≫ y)

Next tactic:
simpa using CompClosure.intro (f ≫ x) m₁ m₂ y h
theorem comp_right {a b c : C} (g : b ⟶ c) :
    ∀ (f₁ f₂ : a ⟶ b) (_ : CompClosure r f₁ f₂), CompClosure r (f₁ ≫ g) (f₂ ≫ g)
  | _, _, ⟨x, m₁, m₂, y, h⟩ => by 

Proof state:
C : Type u_2
inst✝ : Category.{u_1, u_2} C
r : HomRel C
a b c : C
g : b ⟶ c
a✝ b✝ : C
x : a ⟶ a✝
m₁ m₂ : a✝ ⟶ b✝
y : b✝ ⟶ b
h : r m₁ m₂
⊢ CompClosure r ((x ≫ m₁ ≫ y) ≫ g) ((x ≫ m₂ ≫ y) ≫ g)

Next tactic:
simpa using CompClosure.intro x m₁ m₂ (y ≫ g) h
instance category : Category (Quotient r) where
  Hom := Hom r
  id a := Quot.mk _ (𝟙 a.as)
  comp := @comp _ _ r
  comp_id f := Quot.inductionOn f $ by simp
  id_comp f := Quot.inductionOn f $ by 

Proof state:
C : Type ?u.6549
inst✝ : Category.{?u.6553, ?u.6549} C
r : HomRel C
X✝ Y✝ : Quotient r
f : X✝ ⟶ Y✝
⊢ ∀ (a : X✝.as ⟶ Y✝.as), 𝟙 X✝ ≫ Quot.mk (CompClosure r) a = Quot.mk (CompClosure r) a

Next tactic:
simp
instance category : Category (Quotient r) where
  Hom := Hom r
  id a := Quot.mk _ (𝟙 a.as)
  comp := @comp _ _ r
  comp_id f := Quot.inductionOn f $ by 

Proof state:
C : Type ?u.6549
inst✝ : Category.{?u.6553, ?u.6549} C
r : HomRel C
X✝ Y✝ : Quotient r
f : X✝ ⟶ Y✝
⊢ ∀ (a : X✝.as ⟶ Y✝.as), Quot.mk (CompClosure r) a ≫ 𝟙 Y✝ = Quot.mk (CompClosure r) a

Next tactic:
simp
instance category : Category (Quotient r) where
  Hom := Hom r
  id a := Quot.mk _ (𝟙 a.as)
  comp := @comp _ _ r
  comp_id f := Quot.inductionOn f $ by simp
  id_comp f := Quot.inductionOn f $ by simp
  assoc f g h := Quot.inductionOn f $ Quot.inductionOn g $ Quot.inductionOn h $ by 

Proof state:
C : Type ?u.6549
inst✝ : Category.{?u.6553, ?u.6549} C
r : HomRel C
W✝ X✝ Y✝ Z✝ : Quotient r
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
⊢ ∀ (a : Y✝.as ⟶ Z✝.as) (a_1 : X✝.as ⟶ Y✝.as) (a_2 : W✝.as ⟶ X✝.as),
    (Quot.mk (CompClosure r) a_2 ≫ Quot.mk (CompClosure r) a_1) ≫ Quot.mk (CompClosure r) a =
      Quot.mk (CompClosure r) a_2 ≫ Quot.mk (CompClosure r) a_1 ≫ Quot.mk (CompClosure r) a

Next tactic:
simp
noncomputable instance fullFunctor : Full (functor r) where
  preimage := @fun X Y f ↦ Quot.out f
  witness f := by
    

Proof state:
C : Type ?u.9520
inst✝ : Category.{?u.9524, ?u.9520} C
r : HomRel C
X✝ Y✝ : C
f : (functor r).obj X✝ ⟶ (functor r).obj Y✝
⊢ (functor r).map ((fun X Y f => Quot.out f) X✝ Y✝ f) = f

Next tactic:
dsimp [functor]
noncomputable instance fullFunctor : Full (functor r) where
  preimage := @fun X Y f ↦ Quot.out f
  witness f := by
    dsimp [functor]
    

Proof state:
C : Type ?u.9520
inst✝ : Category.{?u.9524, ?u.9520} C
r : HomRel C
X✝ Y✝ : C
f : (functor r).obj X✝ ⟶ (functor r).obj Y✝
⊢ Quot.mk (CompClosure r) (Quot.out f) = f

Next tactic:
simp
instance essSurj_functor : EssSurj (functor r) where
  mem_essImage Y :=
    ⟨Y.as, ⟨eqToIso (by
            

Proof state:
C : Type ?u.9843
inst✝ : Category.{?u.9847, ?u.9843} C
r : HomRel C
Y : Quotient r
⊢ (functor r).obj Y.as = Y

Next tactic:
ext
instance essSurj_functor : EssSurj (functor r) where
  mem_essImage Y :=
    ⟨Y.as, ⟨eqToIso (by
            ext
            

Proof state:
case as
C : Type ?u.9843
inst✝ : Category.{?u.9847, ?u.9843} C
r : HomRel C
Y : Quotient r
⊢ ((functor r).obj Y.as).as = Y.as

Next tactic:
rfl
protected theorem induction {P : ∀ {a b : Quotient r}, (a ⟶ b) → Prop}
    (h : ∀ {x y : C} (f : x ⟶ y), P ((functor r).map f)) :
    ∀ {a b : Quotient r} (f : a ⟶ b), P f := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
P : {a b : Quotient r} → (a ⟶ b) → Prop
h : ∀ {x y : C} (f : x ⟶ y), P ((functor r).map f)
⊢ ∀ {a b : Quotient r} (f : a ⟶ b), P f

Next tactic:
rintro ⟨x⟩ ⟨y⟩ ⟨f⟩
protected theorem induction {P : ∀ {a b : Quotient r}, (a ⟶ b) → Prop}
    (h : ∀ {x y : C} (f : x ⟶ y), P ((functor r).map f)) :
    ∀ {a b : Quotient r} (f : a ⟶ b), P f := by
  rintro ⟨x⟩ ⟨y⟩ ⟨f⟩
  

Proof state:
case mk.mk.mk
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
P : {a b : Quotient r} → (a ⟶ b) → Prop
h : ∀ {x y : C} (f : x ⟶ y), P ((functor r).map f)
x y : C
f✝ : { as := x } ⟶ { as := y }
f : { as := x }.as ⟶ { as := y }.as
⊢ P (Quot.mk (CompClosure r) f)

Next tactic:
exact h f
protected theorem sound {a b : C} {f₁ f₂ : a ⟶ b} (h : r f₁ f₂) :
    (functor r).map f₁ = (functor r).map f₂ := by
  

Proof state:
C : Type u_2
inst✝ : Category.{u_1, u_2} C
r : HomRel C
a b : C
f₁ f₂ : a ⟶ b
h : r f₁ f₂
⊢ (functor r).map f₁ = (functor r).map f₂

Next tactic:
simpa using Quot.sound (CompClosure.intro (𝟙 a) f₁ f₂ (𝟙 b) h)
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
⊢ CompClosure r f g ↔ r f g

Next tactic:
constructor
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
⊢ CompClosure r f g → r f g

Next tactic:
intro hfg
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  constructor
  · intro hfg
    

Proof state:
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
hfg : CompClosure r f g
⊢ r f g

Next tactic:
induction' hfg with m m' hm
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  constructor
  · intro hfg
    induction' hfg with m m' hm
    

Proof state:
case mp.intro
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
m m' : C
hm : X ⟶ m
m₁✝ m₂✝ : m ⟶ m'
g✝ : m' ⟶ Y
h✝ : r m₁✝ m₂✝
⊢ r (hm ≫ m₁✝ ≫ g✝) (hm ≫ m₂✝ ≫ g✝)

Next tactic:
exact Congruence.compLeft _ (Congruence.compRight _ (by assumption))
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  constructor
  · intro hfg
    induction' hfg with m m' hm
    exact Congruence.compLeft _ (Congruence.compRight _ (by 

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
m m' : C
hm : X ⟶ m
m₁✝ m₂✝ : m ⟶ m'
g✝ : m' ⟶ Y
h✝ : r m₁✝ m₂✝
⊢ r m₁✝ m₂✝

Next tactic:
assumption
lemma compClosure_iff_self [h : Congruence r] {X Y : C} (f g : X ⟶ Y) :
    CompClosure r f g ↔ r f g := by
  constructor
  · intro hfg
    induction' hfg with m m' hm
    exact Congruence.compLeft _ (Congruence.compRight _ (by assumption))
  · 

Proof state:
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f g : X ⟶ Y
⊢ r f g → CompClosure r f g

Next tactic:
exact CompClosure.of _ _ _
@[simp]
theorem compClosure_eq_self [h : Congruence r] :
    CompClosure r = r := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
⊢ CompClosure r = r

Next tactic:
ext
@[simp]
theorem compClosure_eq_self [h : Congruence r] :
    CompClosure r = r := by
  ext
  

Proof state:
case h.h.h.h.a
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
x✝³ x✝² : C
x✝¹ x✝ : x✝³ ⟶ x✝²
⊢ CompClosure r x✝¹ x✝ ↔ r x✝¹ x✝

Next tactic:
simp only [compClosure_iff_self]
theorem functor_map_eq_iff [h : Congruence r] {X Y : C} (f f' : X ⟶ Y) :
    (functor r).map f = (functor r).map f' ↔ r f f' := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f f' : X ⟶ Y
⊢ (functor r).map f = (functor r).map f' ↔ r f f'

Next tactic:
dsimp [functor]
theorem functor_map_eq_iff [h : Congruence r] {X Y : C} (f f' : X ⟶ Y) :
    (functor r).map f = (functor r).map f' ↔ r f f' := by
  dsimp [functor]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f f' : X ⟶ Y
⊢ Quot.mk (CompClosure r) f = Quot.mk (CompClosure r) f' ↔ r f f'

Next tactic:
rw [Equivalence.quot_mk_eq_iff, compClosure_eq_self r]
theorem functor_map_eq_iff [h : Congruence r] {X Y : C} (f f' : X ⟶ Y) :
    (functor r).map f = (functor r).map f' ↔ r f f' := by
  dsimp [functor]
  rw [Equivalence.quot_mk_eq_iff, compClosure_eq_self r]
  

Proof state:
case h
C : Type u_1
inst✝ : Category.{u_2, u_1} C
r : HomRel C
h : Congruence r
X Y : C
f f' : X ⟶ Y
⊢ _root_.Equivalence (CompClosure r)

Next tactic:
simpa only [compClosure_eq_self r] using h.equivalence
/-- The induced functor on the quotient category. -/
def lift : Quotient r ⥤ D where
  obj a := F.obj a.as
  map := @fun a b hf ↦
    Quot.liftOn hf (fun f ↦ F.map f)
      (by
        

Proof state:
C : Type ?u.12785
inst✝¹ : Category.{?u.12789, ?u.12785} C
r : HomRel C
D : Type ?u.12817
inst✝ : Category.{?u.12821, ?u.12817} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
a b : Quotient r
hf : a ⟶ b
⊢ ∀ (a_1 b_1 : a.as ⟶ b.as), CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1

Next tactic:
rintro _ _ ⟨_, _, _, _, h⟩
/-- The induced functor on the quotient category. -/
def lift : Quotient r ⥤ D where
  obj a := F.obj a.as
  map := @fun a b hf ↦
    Quot.liftOn hf (fun f ↦ F.map f)
      (by
        rintro _ _ ⟨_, _, _, _, h⟩
        

Proof state:
case intro
C : Type ?u.12785
inst✝¹ : Category.{?u.12789, ?u.12785} C
r : HomRel C
D : Type ?u.12817
inst✝ : Category.{?u.12821, ?u.12817} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
a b : Quotient r
hf : a ⟶ b
a✝ b✝ : C
f✝ : a.as ⟶ a✝
m₁✝ m₂✝ : a✝ ⟶ b✝
g✝ : b✝ ⟶ b.as
h : r m₁✝ m₂✝
⊢ (fun f => F.map f) (f✝ ≫ m₁✝ ≫ g✝) = (fun f => F.map f) (f✝ ≫ m₂✝ ≫ g✝)

Next tactic:
simp [H _ _ _ _ h]
/-- The induced functor on the quotient category. -/
def lift : Quotient r ⥤ D where
  obj a := F.obj a.as
  map := @fun a b hf ↦
    Quot.liftOn hf (fun f ↦ F.map f)
      (by
        rintro _ _ ⟨_, _, _, _, h⟩
        simp [H _ _ _ _ h])
  map_id a := F.map_id a.as
  map_comp := by
    

Proof state:
C : Type ?u.12785
inst✝¹ : Category.{?u.12789, ?u.12785} C
r : HomRel C
D : Type ?u.12817
inst✝ : Category.{?u.12821, ?u.12817} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ ∀ {X Y Z : Quotient r} (f : X ⟶ Y) (g : Y ⟶ Z),
    { obj := fun a => F.obj a.as,
            map := fun a b hf =>
              Quot.liftOn hf (fun f => F.map f)
                (_ :
                  ∀ (a_1 b_1 : a.as ⟶ b.as),
                    CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
        (f ≫ g) =
      { obj := fun a => F.obj a.as,
              map := fun a b hf =>
                Quot.liftOn hf (fun f => F.map f)
                  (_ :
                    ∀ (a_1 b_1 : a.as ⟶ b.as),
                      CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
          f ≫
        { obj := fun a => F.obj a.as,
              map := fun a b hf =>
                Quot.liftOn hf (fun f => F.map f)
                  (_ :
                    ∀ (a_1 b_1 : a.as ⟶ b.as),
                      CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
          g

Next tactic:
rintro a b c ⟨f⟩ ⟨g⟩
/-- The induced functor on the quotient category. -/
def lift : Quotient r ⥤ D where
  obj a := F.obj a.as
  map := @fun a b hf ↦
    Quot.liftOn hf (fun f ↦ F.map f)
      (by
        rintro _ _ ⟨_, _, _, _, h⟩
        simp [H _ _ _ _ h])
  map_id a := F.map_id a.as
  map_comp := by
    rintro a b c ⟨f⟩ ⟨g⟩
    

Proof state:
case mk.mk
C : Type ?u.12785
inst✝¹ : Category.{?u.12789, ?u.12785} C
r : HomRel C
D : Type ?u.12817
inst✝ : Category.{?u.12821, ?u.12817} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
a b c : Quotient r
f✝ : a ⟶ b
f : a.as ⟶ b.as
g✝ : b ⟶ c
g : b.as ⟶ c.as
⊢ { obj := fun a => F.obj a.as,
          map := fun a b hf =>
            Quot.liftOn hf (fun f => F.map f)
              (_ :
                ∀ (a_1 b_1 : a.as ⟶ b.as),
                  CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
      (Quot.mk (CompClosure r) f ≫ Quot.mk (CompClosure r) g) =
    { obj := fun a => F.obj a.as,
            map := fun a b hf =>
              Quot.liftOn hf (fun f => F.map f)
                (_ :
                  ∀ (a_1 b_1 : a.as ⟶ b.as),
                    CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
        (Quot.mk (CompClosure r) f) ≫
      { obj := fun a => F.obj a.as,
            map := fun a b hf =>
              Quot.liftOn hf (fun f => F.map f)
                (_ :
                  ∀ (a_1 b_1 : a.as ⟶ b.as),
                    CompClosure r a_1 b_1 → (fun f => F.map f) a_1 = (fun f => F.map f) b_1) }.map
        (Quot.mk (CompClosure r) g)

Next tactic:
exact F.map_comp f g
theorem lift_spec : functor r ⋙ lift r F H = F := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ functor r ⋙ lift r F H = F

Next tactic:
apply Functor.ext
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; 

Proof state:
case h_map
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ autoParam
    (∀ (X Y : C) (f : X ⟶ Y),
      (functor r ⋙ lift r F H).map f =
        eqToHom (_ : ?F.obj X = ?G.obj X) ≫ F.map f ≫ eqToHom (_ : F.obj Y = (functor r ⋙ lift r F H).obj Y))
    _auto✝
case h_obj
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ ∀ (X : C), (functor r ⋙ lift r F H).obj X = F.obj X

Next tactic:
rotate_left
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; rotate_left
  · 

Proof state:
case h_obj
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ ∀ (X : C), (functor r ⋙ lift r F H).obj X = F.obj X

Next tactic:
rintro X
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; rotate_left
  · rintro X
    

Proof state:
case h_obj
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
X : C
⊢ (functor r ⋙ lift r F H).obj X = F.obj X

Next tactic:
rfl
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; rotate_left
  · rintro X
    rfl
  · 

Proof state:
case h_map
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
⊢ autoParam
    (∀ (X Y : C) (f : X ⟶ Y),
      (functor r ⋙ lift r F H).map f =
        eqToHom (_ : (functor r ⋙ lift r F H).obj X = (functor r ⋙ lift r F H).obj X) ≫
          F.map f ≫ eqToHom (_ : F.obj Y = (functor r ⋙ lift r F H).obj Y))
    _auto✝

Next tactic:
rintro X Y f
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; rotate_left
  · rintro X
    rfl
  · rintro X Y f
    

Proof state:
case h_map
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
X Y : C
f : X ⟶ Y
⊢ (functor r ⋙ lift r F H).map f =
    eqToHom (_ : (functor r ⋙ lift r F H).obj X = (functor r ⋙ lift r F H).obj X) ≫
      F.map f ≫ eqToHom (_ : F.obj Y = (functor r ⋙ lift r F H).obj Y)

Next tactic:
dsimp [lift, functor]
theorem lift_spec : functor r ⋙ lift r F H = F := by
  apply Functor.ext; rotate_left
  · rintro X
    rfl
  · rintro X Y f
    dsimp [lift, functor]
    

Proof state:
case h_map
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
r : HomRel C
D : Type u_3
inst✝ : Category.{u_4, u_3} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
X Y : C
f : X ⟶ Y
⊢ Quot.liftOn (Quot.mk (CompClosure r) f) (fun f => F.map f)
      (_ : ∀ (a b : { as := X }.as ⟶ { as := Y }.as), CompClosure r a b → (fun f => F.map f) a = (fun f => F.map f) b) =
    𝟙 (F.obj X) ≫ F.map f ≫ 𝟙 (F.obj Y)

Next tactic:
simp
theorem lift_unique (Φ : Quotient r ⥤ D) (hΦ : functor r ⋙ Φ = F) : Φ = lift r F H := by
  

Proof state:
C : Type u_3
inst✝¹ : Category.{u_1, u_3} C
r : HomRel C
D : Type u_4
inst✝ : Category.{u_2, u_4} D
F : C ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂
Φ : Quotient r ⥤ D
hΦ : functor r ⋙ Φ = F
⊢ Φ = lift r F H

Next tactic:
subst_vars
theorem lift_unique (Φ : Quotient r ⥤ D) (hΦ : functor r ⋙ Φ = F) : Φ = lift r F H := by
  subst_vars
  

Proof state:
C : Type u_3
inst✝¹ : Category.{u_1, u_3} C
r : HomRel C
D : Type u_4
inst✝ : Category.{u_2, u_4} D
Φ : Quotient r ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → (functor r ⋙ Φ).map f₁ = (functor r ⋙ Φ).map f₂
⊢ Φ = lift r (functor r ⋙ Φ) H

Next tactic:
fapply Functor.hext
theorem lift_unique (Φ : Quotient r ⥤ D) (hΦ : functor r ⋙ Φ = F) : Φ = lift r F H := by
  subst_vars
  fapply Functor.hext
  · 

Proof state:
case h_obj
C : Type u_3
inst✝¹ : Category.{u_1, u_3} C
r : HomRel C
D : Type u_4
inst✝ : Category.{u_2, u_4} D
Φ : Quotient r ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → (functor r ⋙ Φ).map f₁ = (functor r ⋙ Φ).map f₂
⊢ ∀ (X : Quotient r), Φ.obj X = (lift r (functor r ⋙ Φ) H).obj X

Next tactic:
rintro X
theorem lift_unique (Φ : Quotient r ⥤ D) (hΦ : functor r ⋙ Φ = F) : Φ = lift r F H := by
  subst_vars
  fapply Functor.hext
  · rintro X
    

Proof state:
case h_obj
C : Type u_3
inst✝¹ : Category.{u_1, u_3} C
r : HomRel C
D : Type u_4
inst✝ : Category.{u_2, u_4} D
Φ : Quotient r ⥤ D
H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → (functor r ⋙ Φ).map f₁ = (functor r ⋙ Φ).map f₂
X : Quotient r
⊢ Φ.obj X = (lift r (functor r ⋙ Φ) H).obj X

Next tactic:
dsimp [lift, Functor]