l3lab/ntp-mathlib huggingface dataset:
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  

Proof state:
case h
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
⊢ i ≫ e = 𝟙 Y ∧ e ≫ i = p

Next tactic:
constructor
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  constructor
  · 

Proof state:
case h.left
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
⊢ i ≫ e = 𝟙 Y

Next tactic:
ext j
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  constructor
  · ext j
    

Proof state:
case h.left.w.h.h
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
j : J
⊢ (i ≫ e).app j ≫ equalizer.ι (𝟙 (F.obj j)) (p.app j) = (𝟙 Y).app j ≫ equalizer.ι (𝟙 (F.obj j)) (p.app j)

Next tactic:
dsimp
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  constructor
  · ext j
    dsimp
    

Proof state:
case h.left.w.h.h
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
j : J
⊢ (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)) ≫
      equalizer.ι (𝟙 (F.obj j)) (p.app j) =
    𝟙 (equalizer (𝟙 (F.obj j)) (p.app j)) ≫ equalizer.ι (𝟙 (F.obj j)) (p.app j)

Next tactic:
rw [assoc, equalizer.lift_ι, ← equalizer.condition, id_comp, comp_id]
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  constructor
  · ext j
    dsimp
    rw [assoc, equalizer.lift_ι, ← equalizer.condition, id_comp, comp_id]
  · 

Proof state:
case h.right
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
⊢ e ≫ i = p

Next tactic:
ext j
instance functor_category_isIdempotentComplete [IsIdempotentComplete C] :
    IsIdempotentComplete (J ⥤ C) := by
  refine' ⟨fun F p hp => _⟩
  have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance
  haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j)
  /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing
      the equalizer of the identity and `p.app j` on each object `(j : J)`.  -/
  let Y : J ⥤ C :=
    { obj := fun j => Limits.equalizer (𝟙 _) (p.app j)
      map := fun {j j'} φ =>
        equalizer.lift (Limits.equalizer.ι (𝟙 _) (p.app j) ≫ F.map φ)
          (by rw [comp_id, assoc, p.naturality φ, ← assoc, ← Limits.equalizer.condition, comp_id]) }
  let i : Y ⟶ F :=
    { app := fun j => equalizer.ι _ _
      naturality := fun _ _ _ => by rw [equalizer.lift_ι] }
  let e : F ⟶ Y :=
    { app := fun j =>
        equalizer.lift (p.app j) (by simpa only [comp_id] using (congr_app hp j).symm)
      naturality := fun j j' φ => equalizer.hom_ext (by simp) }
  use Y, i, e
  constructor
  · ext j
    dsimp
    rw [assoc, equalizer.lift_ι, ← equalizer.condition, id_comp, comp_id]
  · ext j
    

Proof state:
case h.right.w.h
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.4050, u_1} J
inst✝¹ : Category.{?u.4054, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
inst✝ : IsIdempotentComplete C
F : J ⥤ C
p : F ⟶ F
hp : p ≫ p = p
hC : ∀ (X : C) (p : X ⟶ X), p ≫ p = p → HasEqualizer (𝟙 X) p
this : ∀ (j : J), HasEqualizer (𝟙 (F.obj j)) (p.app j)
Y : J ⥤ C :=
  Functor.mk
    { obj := fun j => equalizer (𝟙 (F.obj j)) (p.app j),
      map := fun {j j'} φ =>
        equalizer.lift (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ)
          (_ :
            (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ 𝟙 (F.obj j') =
              (equalizer.ι (𝟙 (F.obj j)) (p.app j) ≫ F.map φ) ≫ p.app j') }
i : Y ⟶ F := NatTrans.mk fun j => equalizer.ι (𝟙 (F.obj j)) (p.app j)
e : F ⟶ Y := NatTrans.mk fun j => equalizer.lift (p.app j) (_ : p.app j ≫ 𝟙 (F.obj j) = p.app j ≫ p.app j)
j : J
⊢ (e ≫ i).app j = p.app j

Next tactic:
simp
/-- On objects, the functor which sends a formal direct factor `P` of a
functor `F : J ⥤ C` to the functor `J ⥤ Karoubi C` which sends `(j : J)` to
the corresponding direct factor of `F.obj j`. -/
@[simps]
def obj (P : Karoubi (J ⥤ C)) : J ⥤ Karoubi C where
  obj j := ⟨P.X.obj j, P.p.app j, congr_app P.idem j⟩
  map {j j'} φ :=
    { f := P.p.app j ≫ P.X.map φ
      comm := by
        

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.52173, u_1} J
inst✝ : Category.{?u.52177, u_2} C
P✝ Q : Karoubi (J ⥤ C)
f : P✝ ⟶ Q
X : J
P : Karoubi (J ⥤ C)
j j' : J
φ : j ⟶ j'
⊢ P.p.app j ≫ P.X.map φ =
    ((fun j => Karoubi.mk (P.X.obj j) (P.p.app j)) j).p ≫
      (P.p.app j ≫ P.X.map φ) ≫ ((fun j => Karoubi.mk (P.X.obj j) (P.p.app j)) j').p

Next tactic:
simp only [NatTrans.naturality, assoc]
/-- On objects, the functor which sends a formal direct factor `P` of a
functor `F : J ⥤ C` to the functor `J ⥤ Karoubi C` which sends `(j : J)` to
the corresponding direct factor of `F.obj j`. -/
@[simps]
def obj (P : Karoubi (J ⥤ C)) : J ⥤ Karoubi C where
  obj j := ⟨P.X.obj j, P.p.app j, congr_app P.idem j⟩
  map {j j'} φ :=
    { f := P.p.app j ≫ P.X.map φ
      comm := by
        simp only [NatTrans.naturality, assoc]
        

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.52173, u_1} J
inst✝ : Category.{?u.52177, u_2} C
P✝ Q : Karoubi (J ⥤ C)
f : P✝ ⟶ Q
X : J
P : Karoubi (J ⥤ C)
j j' : J
φ : j ⟶ j'
⊢ P.p.app j ≫ P.X.map φ = P.p.app j ≫ P.p.app j ≫ P.p.app j ≫ P.X.map φ

Next tactic:
have h := congr_app P.idem j
/-- On objects, the functor which sends a formal direct factor `P` of a
functor `F : J ⥤ C` to the functor `J ⥤ Karoubi C` which sends `(j : J)` to
the corresponding direct factor of `F.obj j`. -/
@[simps]
def obj (P : Karoubi (J ⥤ C)) : J ⥤ Karoubi C where
  obj j := ⟨P.X.obj j, P.p.app j, congr_app P.idem j⟩
  map {j j'} φ :=
    { f := P.p.app j ≫ P.X.map φ
      comm := by
        simp only [NatTrans.naturality, assoc]
        have h := congr_app P.idem j
        

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.52173, u_1} J
inst✝ : Category.{?u.52177, u_2} C
P✝ Q : Karoubi (J ⥤ C)
f : P✝ ⟶ Q
X : J
P : Karoubi (J ⥤ C)
j j' : J
φ : j ⟶ j'
h : (P.p ≫ P.p).app j = P.p.app j
⊢ P.p.app j ≫ P.X.map φ = P.p.app j ≫ P.p.app j ≫ P.p.app j ≫ P.X.map φ

Next tactic:
rw [NatTrans.comp_app] at h
/-- On objects, the functor which sends a formal direct factor `P` of a
functor `F : J ⥤ C` to the functor `J ⥤ Karoubi C` which sends `(j : J)` to
the corresponding direct factor of `F.obj j`. -/
@[simps]
def obj (P : Karoubi (J ⥤ C)) : J ⥤ Karoubi C where
  obj j := ⟨P.X.obj j, P.p.app j, congr_app P.idem j⟩
  map {j j'} φ :=
    { f := P.p.app j ≫ P.X.map φ
      comm := by
        simp only [NatTrans.naturality, assoc]
        have h := congr_app P.idem j
        rw [NatTrans.comp_app] at h
        

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.52173, u_1} J
inst✝ : Category.{?u.52177, u_2} C
P✝ Q : Karoubi (J ⥤ C)
f : P✝ ⟶ Q
X : J
P : Karoubi (J ⥤ C)
j j' : J
φ : j ⟶ j'
h : P.p.app j ≫ P.p.app j = P.p.app j
⊢ P.p.app j ≫ P.X.map φ = P.p.app j ≫ P.p.app j ≫ P.p.app j ≫ P.X.map φ

Next tactic:
erw [reassoc_of% h, reassoc_of% h]
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j j' : J
φ : j ⟶ j'
⊢ P.X.map φ ≫ (fun j => (f.app j).f) j' = (fun j => (f.app j).f) j ≫ Q.X.map φ

Next tactic:
rw [← Karoubi.comp_p_assoc]
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j j' : J
φ : j ⟶ j'
⊢ P.X.map φ ≫ (fun j => (f.app j).f) j' =
    (f.app j).f ≫ (((karoubiFunctorCategoryEmbedding J C).obj Q).obj j).p ≫ Q.X.map φ

Next tactic:
have h := hom_ext_iff.mp (f.naturality φ)
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            have h := hom_ext_iff.mp (f.naturality φ)
            

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j j' : J
φ : j ⟶ j'
h :
  (((karoubiFunctorCategoryEmbedding J C).obj P).map φ ≫ f.app j').f =
    (f.app j ≫ ((karoubiFunctorCategoryEmbedding J C).obj Q).map φ).f
⊢ P.X.map φ ≫ (fun j => (f.app j).f) j' =
    (f.app j).f ≫ (((karoubiFunctorCategoryEmbedding J C).obj Q).obj j).p ≫ Q.X.map φ

Next tactic:
simp only [comp_f] at h
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            have h := hom_ext_iff.mp (f.naturality φ)
            simp only [comp_f] at h
            

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j j' : J
φ : j ⟶ j'
h :
  (((karoubiFunctorCategoryEmbedding J C).obj P).map φ).f ≫ (f.app j').f =
    (f.app j).f ≫ (((karoubiFunctorCategoryEmbedding J C).obj Q).map φ).f
⊢ P.X.map φ ≫ (fun j => (f.app j).f) j' =
    (f.app j).f ≫ (((karoubiFunctorCategoryEmbedding J C).obj Q).obj j).p ≫ Q.X.map φ

Next tactic:
dsimp [karoubiFunctorCategoryEmbedding] at h
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            have h := hom_ext_iff.mp (f.naturality φ)
            simp only [comp_f] at h
            dsimp [karoubiFunctorCategoryEmbedding] at h
            

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j j' : J
φ : j ⟶ j'
h : (P.p.app j ≫ P.X.map φ) ≫ (f.app j').f = (f.app j).f ≫ Q.p.app j ≫ Q.X.map φ
⊢ P.X.map φ ≫ (fun j => (f.app j).f) j' =
    (f.app j).f ≫ (((karoubiFunctorCategoryEmbedding J C).obj Q).obj j).p ≫ Q.X.map φ

Next tactic:
erw [← h, assoc, ← P.p.naturality_assoc φ, p_comp (f.app j')]
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            have h := hom_ext_iff.mp (f.naturality φ)
            simp only [comp_f] at h
            dsimp [karoubiFunctorCategoryEmbedding] at h
            erw [← h, assoc, ← P.p.naturality_assoc φ, p_comp (f.app j')] }
      comm := by
        

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
⊢ (NatTrans.mk fun j => (f.app j).f) = P.p ≫ (NatTrans.mk fun j => (f.app j).f) ≫ Q.p

Next tactic:
ext j
instance : Full (karoubiFunctorCategoryEmbedding J C) where
  preimage {P Q} f :=
    { f :=
        { app := fun j => (f.app j).f
          naturality := fun j j' φ => by
            rw [← Karoubi.comp_p_assoc]
            have h := hom_ext_iff.mp (f.naturality φ)
            simp only [comp_f] at h
            dsimp [karoubiFunctorCategoryEmbedding] at h
            erw [← h, assoc, ← P.p.naturality_assoc φ, p_comp (f.app j')] }
      comm := by
        ext j
        

Proof state:
case w.h
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.63653, u_1} J
inst✝ : Category.{?u.63657, u_2} C
P✝ Q✝ : Karoubi (J ⥤ C)
f✝ : P✝ ⟶ Q✝
X : J
P Q : Karoubi (J ⥤ C)
f : (karoubiFunctorCategoryEmbedding J C).obj P ⟶ (karoubiFunctorCategoryEmbedding J C).obj Q
j : J
⊢ (NatTrans.mk fun j => (f.app j).f).app j = (P.p ≫ (NatTrans.mk fun j => (f.app j).f) ≫ Q.p).app j

Next tactic:
exact (f.app j).comm
instance : Faithful (karoubiFunctorCategoryEmbedding J C) where
  map_injective h := by
    

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.67162, u_1} J
inst✝ : Category.{?u.67166, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
X✝ Y✝ : Karoubi (J ⥤ C)
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : (karoubiFunctorCategoryEmbedding J C).map a₁✝ = (karoubiFunctorCategoryEmbedding J C).map a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
ext j
instance : Faithful (karoubiFunctorCategoryEmbedding J C) where
  map_injective h := by
    ext j
    

Proof state:
case h.w.h
J : Type u_1
C : Type u_2
inst✝¹ : Category.{?u.67162, u_1} J
inst✝ : Category.{?u.67166, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
X✝ Y✝ : Karoubi (J ⥤ C)
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : (karoubiFunctorCategoryEmbedding J C).map a₁✝ = (karoubiFunctorCategoryEmbedding J C).map a₂✝
j : J
⊢ a₁✝.f.app j = a₂✝.f.app j

Next tactic:
exact hom_ext_iff.mp (congr_app h j)
/-- The composition of `(J ⥤ C) ⥤ Karoubi (J ⥤ C)` and `Karoubi (J ⥤ C) ⥤ (J ⥤ Karoubi C)`
equals the functor `(J ⥤ C) ⥤ (J ⥤ Karoubi C)` given by the composition with
`toKaroubi C : C ⥤ Karoubi C`. -/
theorem toKaroubi_comp_karoubiFunctorCategoryEmbedding :
    toKaroubi _ ⋙ karoubiFunctorCategoryEmbedding J C =
      (whiskeringRight J _ _).obj (toKaroubi C) := by
  

Proof state:
J : Type u_1
C : Type u_2
inst✝¹ : Category.{u_3, u_1} J
inst✝ : Category.{u_4, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
⊢ toKaroubi (J ⥤ C) ⋙ karoubiFunctorCategoryEmbedding J C = (whiskeringRight J C (Karoubi C)).obj (toKaroubi C)

Next tactic:
apply Functor.ext
/-- The composition of `(J ⥤ C) ⥤ Karoubi (J ⥤ C)` and `Karoubi (J ⥤ C) ⥤ (J ⥤ Karoubi C)`
equals the functor `(J ⥤ C) ⥤ (J ⥤ Karoubi C)` given by the composition with
`toKaroubi C : C ⥤ Karoubi C`. -/
theorem toKaroubi_comp_karoubiFunctorCategoryEmbedding :
    toKaroubi _ ⋙ karoubiFunctorCategoryEmbedding J C =
      (whiskeringRight J _ _).obj (toKaroubi C) := by
  apply Functor.ext
  · 

Proof state:
case h_map
J : Type u_1
C : Type u_2
inst✝¹ : Category.{u_3, u_1} J
inst✝ : Category.{u_4, u_2} C
P Q : Karoubi (J ⥤ C)
f : P ⟶ Q
X : J
⊢ autoParam
    (∀ (X Y : J ⥤ C) (f : X ⟶ Y),
      (toKaroubi (J ⥤ C) ⋙ karoubiFunctorCategoryEmbedding J C).map f =
        eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          ((whiskeringRight J C (Karoubi C)).obj (toKaroubi C)).map f ≫
            eqToHom
              (_ :
                ((whiskeringRight J C (Karoubi C)).obj (toKaroubi C)).obj Y =
                  (toKaroubi (J ⥤ C) ⋙ karoubiFunctorCategoryEmbedding J C).obj Y))
    _auto✝

Next tactic:
intro X Y f