[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type ?u.69019
f : J → C
inst✝ : HasProduct f
j j' : J
w : j = j'
⊢ f j = f j'
[PROOFSTEP]
simp [w]
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type u_1
f : J → C
inst✝ : HasProduct f
j j' : J
w : j = j'
⊢ π f j ≫ eqToHom (_ : f j = f j') = π f j'
[PROOFSTEP]
cases w
[GOAL]
case refl
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type u_1
f : J → C
inst✝ : HasProduct f
j : J
⊢ π f j ≫ eqToHom (_ : f j = f j) = π f j
[PROOFSTEP]
simp
  -- The `simpNF` linter incorrectly identifies these as simp lemmas that could never apply.
  -- https://github.com/leanprover-community/mathlib4/issues/5049
  -- They are used by `simp` in `Sigma.whisker_equiv` below.
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type ?u.69987
f : J → C
inst✝ : HasCoproduct f
j j' : J
w : j = j'
⊢ f j = f j'
[PROOFSTEP]
simp [w]
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type u_1
f : J → C
inst✝ : HasCoproduct f
j j' : J
w : j = j'
⊢ eqToHom (_ : f j = f j') ≫ ι f j' = ι f j
[PROOFSTEP]
cases w
[GOAL]
case refl
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
J : Type u_1
f : J → C
inst✝ : HasCoproduct f
j : J
⊢ eqToHom (_ : f j = f j) ≫ ι f j = ι f j
[PROOFSTEP]
simp
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
f g : β → C
inst✝² : HasProduct f
inst✝¹ : HasProduct g
p : (b : β) → f b ⟶ g b
inst✝ : ∀ (i : β), Mono (p i)
⊢ ∀ (j : Discrete β), Mono (NatTrans.app (Discrete.natTrans fun X => p X.as) j)
[PROOFSTEP]
dsimp
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
f g : β → C
inst✝² : HasProduct f
inst✝¹ : HasProduct g
p : (b : β) → f b ⟶ g b
inst✝ : ∀ (i : β), Mono (p i)
⊢ ∀ (j : Discrete β), Mono (p j.as)
[PROOFSTEP]
infer_instance
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
f g : β → C
inst✝² : HasCoproduct f
inst✝¹ : HasCoproduct g
p : (b : β) → f b ⟶ g b
inst✝ : ∀ (i : β), Epi (p i)
⊢ ∀ (j : Discrete β), Epi (NatTrans.app (Discrete.natTrans fun X => p X.as) j)
[PROOFSTEP]
dsimp
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
f g : β → C
inst✝² : HasCoproduct f
inst✝¹ : HasCoproduct g
p : (b : β) → f b ⟶ g b
inst✝ : ∀ (i : β), Epi (p i)
⊢ ∀ (j : Discrete β), Epi (p j.as)
[PROOFSTEP]
infer_instance
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
J : Type ?u.78866
K : Type ?u.78950
f : J → C
g : K → C
e : J ≃ K
w : (j : J) → g (↑e j) ≅ f j
inst✝¹ : HasProduct f
inst✝ : HasProduct g
k : K
⊢ g (↑e (↑e.symm k)) = g k
[PROOFSTEP]
simp
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
J : Type ?u.94443
K : Type ?u.94527
f : J → C
g : K → C
e : J ≃ K
w : (j : J) → g (↑e j) ≅ f j
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct g
k : K
⊢ g k = g (↑e (↑e.symm k))
[PROOFSTEP]
simp
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
G : C ⥤ D
f : β → C
inst✝¹ : HasProduct f
inst✝ : HasProduct fun b => G.obj (f b)
P : C
g : (j : β) → P ⟶ f j
⊢ G.map (Pi.lift g) ≫ piComparison G f = Pi.lift fun j => G.map (g j)
[PROOFSTEP]
ext j
[GOAL]
case h
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
G : C ⥤ D
f : β → C
inst✝¹ : HasProduct f
inst✝ : HasProduct fun b => G.obj (f b)
P : C
g : (j : β) → P ⟶ f j
j : β
⊢ (G.map (Pi.lift g) ≫ piComparison G f) ≫ Pi.π (fun b => G.obj (f b)) j =
    (Pi.lift fun j => G.map (g j)) ≫ Pi.π (fun b => G.obj (f b)) j
[PROOFSTEP]
simp only [Discrete.functor_obj, Category.assoc, piComparison_comp_π, ← G.map_comp, limit.lift_π, Fan.mk_pt,
  Fan.mk_π_app]
[GOAL]
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
G : C ⥤ D
f : β → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct fun b => G.obj (f b)
P : C
g : (j : β) → f j ⟶ P
⊢ sigmaComparison G f ≫ G.map (Sigma.desc g) = Sigma.desc fun j => G.map (g j)
[PROOFSTEP]
ext j
[GOAL]
case h
β : Type w
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
G : C ⥤ D
f : β → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct fun b => G.obj (f b)
P : C
g : (j : β) → f j ⟶ P
j : β
⊢ Sigma.ι (fun b => G.obj (f b)) j ≫ sigmaComparison G f ≫ G.map (Sigma.desc g) =
    Sigma.ι (fun b => G.obj (f b)) j ≫ Sigma.desc fun j => G.map (g j)
[PROOFSTEP]
simp only [Discrete.functor_obj, ι_comp_sigmaComparison_assoc, ← G.map_comp, colimit.ι_desc, Cofan.mk_pt,
  Cofan.mk_ι_app]
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ ((Functor.const (Discrete β)).obj (f default)).obj { as := j } = (Discrete.functor f).obj { as := j }
[PROOFSTEP]
dsimp
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ f default = f j
[PROOFSTEP]
congr
[GOAL]
case e_a
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ default = j
[PROOFSTEP]
apply Subsingleton.elim
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cone (Discrete.functor f)
j : Discrete β
⊢ (fun s => NatTrans.app s.π default) s ≫
      NatTrans.app
        { pt := f default,
            π :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                        (Discrete.functor f).obj { as := j }) }.π
        j =
    NatTrans.app s.π j
[PROOFSTEP]
have h := Subsingleton.elim j default
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cone (Discrete.functor f)
j : Discrete β
h : j = default
⊢ (fun s => NatTrans.app s.π default) s ≫
      NatTrans.app
        { pt := f default,
            π :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                        (Discrete.functor f).obj { as := j }) }.π
        j =
    NatTrans.app s.π j
[PROOFSTEP]
subst h
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cone (Discrete.functor f)
⊢ (fun s => NatTrans.app s.π default) s ≫
      NatTrans.app
        { pt := f default,
            π :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                        (Discrete.functor f).obj { as := j }) }.π
        default =
    NatTrans.app s.π default
[PROOFSTEP]
simp
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cone (Discrete.functor f)
m :
  s.pt ⟶
    { pt := f default,
        π :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } =>
              eqToHom
                (_ :
                  ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                    (Discrete.functor f).obj { as := j }) }.pt
w :
  ∀ (j : Discrete β),
    m ≫
        NatTrans.app
          { pt := f default,
              π :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } =>
                    eqToHom
                      (_ :
                        ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                          (Discrete.functor f).obj { as := j }) }.π
          j =
      NatTrans.app s.π j
⊢ m = (fun s => NatTrans.app s.π default) s
[PROOFSTEP]
specialize w default
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cone (Discrete.functor f)
m :
  s.pt ⟶
    { pt := f default,
        π :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } =>
              eqToHom
                (_ :
                  ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                    (Discrete.functor f).obj { as := j }) }.pt
w :
  m ≫
      NatTrans.app
        { pt := f default,
            π :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      ((Functor.const (Discrete β)).obj (f default)).obj { as := j } =
                        (Discrete.functor f).obj { as := j }) }.π
        default =
    NatTrans.app s.π default
⊢ m = (fun s => NatTrans.app s.π default) s
[PROOFSTEP]
simpa using w
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ (Discrete.functor f).obj { as := j } = ((Functor.const (Discrete β)).obj (f default)).obj { as := j }
[PROOFSTEP]
dsimp
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ f j = f default
[PROOFSTEP]
congr
[GOAL]
case e_a
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ j = default
[PROOFSTEP]
apply Subsingleton.elim
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
j : Discrete β
⊢ NatTrans.app
        { pt := f default,
            ι :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      (Discrete.functor f).obj { as := j } =
                        ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.ι
        j ≫
      (fun s => NatTrans.app s.ι default) s =
    NatTrans.app s.ι j
[PROOFSTEP]
have h := Subsingleton.elim j default
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
j : Discrete β
h : j = default
⊢ NatTrans.app
        { pt := f default,
            ι :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      (Discrete.functor f).obj { as := j } =
                        ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.ι
        j ≫
      (fun s => NatTrans.app s.ι default) s =
    NatTrans.app s.ι j
[PROOFSTEP]
subst h
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
⊢ NatTrans.app
        { pt := f default,
            ι :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      (Discrete.functor f).obj { as := j } =
                        ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.ι
        default ≫
      (fun s => NatTrans.app s.ι default) s =
    NatTrans.app s.ι default
[PROOFSTEP]
apply Category.id_comp
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } =>
              eqToHom
                (_ :
                  (Discrete.functor f).obj { as := j } =
                    ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.pt ⟶
    s.pt
w :
  ∀ (j : Discrete β),
    NatTrans.app
          { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } =>
                    eqToHom
                      (_ :
                        (Discrete.functor f).obj { as := j } =
                          ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.ι
          j ≫
        m =
      NatTrans.app s.ι j
⊢ m = (fun s => NatTrans.app s.ι default) s
[PROOFSTEP]
specialize w default
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } =>
              eqToHom
                (_ :
                  (Discrete.functor f).obj { as := j } =
                    ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.pt ⟶
    s.pt
w :
  NatTrans.app
        { pt := f default,
            ι :=
              Discrete.natTrans fun x =>
                match x with
                | { as := j } =>
                  eqToHom
                    (_ :
                      (Discrete.functor f).obj { as := j } =
                        ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.ι
        default ≫
      m =
    NatTrans.app s.ι default
⊢ m = (fun s => NatTrans.app s.ι default) s
[PROOFSTEP]
erw [Category.id_comp] at w
[GOAL]
β : Type w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } =>
              eqToHom
                (_ :
                  (Discrete.functor f).obj { as := j } =
                    ((Functor.const (Discrete β)).obj (f default)).obj { as := j }) }.pt ⟶
    s.pt
w : m = NatTrans.app s.ι default
⊢ m = (fun s => NatTrans.app s.ι default) s
[PROOFSTEP]
exact w
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasProduct f
inst✝ : HasProduct (f ∘ ↑ε)
b : β
⊢ (reindex ε f).hom ≫ π f (↑ε b) = π (f ∘ ↑ε) b
[PROOFSTEP]
dsimp [Pi.reindex]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasProduct f
inst✝ : HasProduct (f ∘ ↑ε)
b : β
⊢ (HasLimit.isoOfEquivalence (Discrete.equivalence ε)
          (Discrete.natIso fun x =>
            Iso.refl ((Discrete.functor f).obj ((Discrete.functor (Discrete.mk ∘ ↑ε)).obj x)))).hom ≫
      π f (↑ε b) =
    π (f ∘ ↑ε) b
[PROOFSTEP]
simp only [HasLimit.isoOfEquivalence_hom_π, Discrete.equivalence_inverse, Discrete.functor_obj, Function.comp_apply,
  Functor.id_obj, Discrete.equivalence_functor, Functor.comp_obj, Discrete.natIso_inv_app, Iso.refl_inv,
  Category.id_comp]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasProduct f
inst✝ : HasProduct (f ∘ ↑ε)
b : β
⊢ limit.π (Discrete.functor (f ∘ ↑ε)) { as := ↑ε.symm (↑ε b) } ≫
      (Discrete.functor f).map (NatTrans.app (Equivalence.counit (Discrete.equivalence ε)) { as := ↑ε b }) =
    π (f ∘ ↑ε) b
[PROOFSTEP]
exact limit.w (Discrete.functor (f ∘ ε)) (Discrete.eqToHom' (ε.symm_apply_apply b))
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasProduct f
inst✝ : HasProduct (f ∘ ↑ε)
b : β
⊢ (reindex ε f).inv ≫ π (f ∘ ↑ε) b = π f (↑ε b)
[PROOFSTEP]
simp [Iso.inv_comp_eq]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
⊢ ι (f ∘ ↑ε) b ≫ (reindex ε f).hom = ι f (↑ε b)
[PROOFSTEP]
dsimp [Sigma.reindex]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
⊢ ι (f ∘ ↑ε) b ≫
      (HasColimit.isoOfEquivalence (Discrete.equivalence ε)
          (Discrete.natIso fun x =>
            Iso.refl ((Discrete.functor f).obj ((Discrete.functor (Discrete.mk ∘ ↑ε)).obj x)))).hom =
    ι f (↑ε b)
[PROOFSTEP]
simp only [HasColimit.isoOfEquivalence_hom_π, Functor.id_obj, Discrete.functor_obj, Function.comp_apply,
  Discrete.equivalence_functor, Discrete.equivalence_inverse, Functor.comp_obj, Discrete.natIso_inv_app, Iso.refl_inv,
  Category.id_comp]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
⊢ (Discrete.functor (f ∘ ↑ε)).map (NatTrans.app (Equivalence.unit (Discrete.equivalence ε)) { as := b }) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) } =
    ι f (↑ε b)
[PROOFSTEP]
have h := colimit.w (Discrete.functor f) (Discrete.eqToHom' (ε.apply_symm_apply (ε b)))
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ (Discrete.functor (f ∘ ↑ε)).map (NatTrans.app (Equivalence.unit (Discrete.equivalence ε)) { as := b }) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) } =
    ι f (↑ε b)
[PROOFSTEP]
simp only [Discrete.functor_obj] at h
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ (Discrete.functor (f ∘ ↑ε)).map (NatTrans.app (Equivalence.unit (Discrete.equivalence ε)) { as := b }) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) } =
    ι f (↑ε b)
[PROOFSTEP]
erw [← h, eqToHom_map, eqToHom_map, eqToHom_trans_assoc]
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ eqToHom (_ : f (↑ε b) = f (↑ε b)) ≫ colimit.ι (Discrete.functor f) { as := ↑ε b } = ι f (↑ε b)
case p
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ { as := b } = { as := ↑ε.symm (↑ε b) }
case p
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ { as := b } = { as := ↑ε.symm (↑ε b) }
case p
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ { as := b } = { as := ↑ε.symm (↑ε b) }
[PROOFSTEP]
all_goals {simp
}
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ eqToHom (_ : f (↑ε b) = f (↑ε b)) ≫ colimit.ι (Discrete.functor f) { as := ↑ε b } = ι f (↑ε b)
[PROOFSTEP]
{simp
}
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ eqToHom (_ : f (↑ε b) = f (↑ε b)) ≫ colimit.ι (Discrete.functor f) { as := ↑ε b } = ι f (↑ε b)
[PROOFSTEP]
simp
[GOAL]
case p
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ { as := b } = { as := ↑ε.symm (↑ε b) }
[PROOFSTEP]
{simp
}
[GOAL]
case p
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
h :
  (Discrete.functor f).map (Discrete.eqToHom' (_ : ↑ε (↑ε.symm (↑ε b)) = ↑ε b)) ≫
      colimit.ι (Discrete.functor f) { as := ↑ε b } =
    colimit.ι (Discrete.functor f) { as := ↑ε (↑ε.symm (↑ε b)) }
⊢ { as := b } = { as := ↑ε.symm (↑ε b) }
[PROOFSTEP]
simp
[GOAL]
β : Type w
C : Type u
inst✝² : Category.{v, u} C
γ : Type v
ε : β ≃ γ
f : γ → C
inst✝¹ : HasCoproduct f
inst✝ : HasCoproduct (f ∘ ↑ε)
b : β
⊢ ι f (↑ε b) ≫ (reindex ε f).inv = ι (f ∘ ↑ε) b
[PROOFSTEP]
simp [Iso.comp_inv_eq]


[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
P Q : IsKernelPair f a b
⊢ P = Q
[PROOFSTEP]
cases P
[GOAL]
case mk
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
Q : IsKernelPair f a b
toCommSq✝ : CommSq a b f f
isLimit'✝ : Nonempty (IsLimit (PullbackCone.mk a b (_ : a ≫ f = b ≫ f)))
⊢ (_ : IsPullback a b f f) = Q
[PROOFSTEP]
cases Q
[GOAL]
case mk.mk
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
toCommSq✝¹ : CommSq a b f f
isLimit'✝¹ : Nonempty (IsLimit (PullbackCone.mk a b (_ : a ≫ f = b ≫ f)))
toCommSq✝ : CommSq a b f f
isLimit'✝ : Nonempty (IsLimit (PullbackCone.mk a b (_ : a ≫ f = b ≫ f)))
⊢ (_ : IsPullback a b f f) = (_ : IsPullback a b f f)
[PROOFSTEP]
congr
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
S : C
k : IsKernelPair f a b
p q : S ⟶ X
w : p ≫ f = q ≫ f
⊢ lift k p q w ≫ a = p ∧ lift k p q w ≫ b = q
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
⊢ { l //
    l ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s ∧
      l ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s ∧
        ∀ {m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt},
          m ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s →
            m ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s → m = l }
[PROOFSTEP]
let s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) := PullbackCone.mk s.fst s.snd (s.condition_assoc _)
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
⊢ { l //
    l ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s ∧
      l ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s ∧
        ∀ {m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt},
          m ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s →
            m ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s → m = l }
[PROOFSTEP]
refine'
  ⟨big_k.isLimit.lift s', big_k.isLimit.fac _ WalkingCospan.left, big_k.isLimit.fac _ WalkingCospan.right, fun m₁ m₂ =>
    _⟩
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
m✝ : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt
m₁ : m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s
m₂ : m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s
⊢ m✝ = IsLimit.lift (IsPullback.isLimit big_k) s'
[PROOFSTEP]
apply big_k.isLimit.hom_ext
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
m✝ : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt
m₁ : m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s
m₂ : m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s
⊢ ∀ (j : WalkingCospan),
    m✝ ≫ NatTrans.app (IsPullback.cone big_k).π j =
      IsLimit.lift (IsPullback.isLimit big_k) s' ≫ NatTrans.app (IsPullback.cone big_k).π j
[PROOFSTEP]
refine' (PullbackCone.mk a b _ : PullbackCone (f₁ ≫ f₂) _).equalizer_ext _ _
[GOAL]
case refine'_1
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
m✝ : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt
m₁ : m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s
m₂ : m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s
⊢ a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂
[PROOFSTEP]
apply reassoc_of% comm
[GOAL]
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
m✝ : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt
m₁ : m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s
m₂ : m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s
⊢ m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)) =
    IsLimit.lift (IsPullback.isLimit big_k) s' ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂))
[PROOFSTEP]
apply m₁.trans (big_k.isLimit.fac s' WalkingCospan.left).symm
[GOAL]
case refine'_3
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
comm : a ≫ f₁ = b ≫ f₁
big_k : IsKernelPair (f₁ ≫ f₂) a b
s : PullbackCone f₁ f₁
s' : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂) :=
  PullbackCone.mk (PullbackCone.fst s) (PullbackCone.snd s)
    (_ : PullbackCone.fst s ≫ f₁ ≫ f₂ = PullbackCone.snd s ≫ f₁ ≫ f₂)
m✝ : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)).pt
m₁ : m✝ ≫ PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.fst s
m₂ : m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ = b ≫ f₁)) = PullbackCone.snd s
⊢ m✝ ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)) =
    IsLimit.lift (IsPullback.isLimit big_k) s' ≫ PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂))
[PROOFSTEP]
apply m₂.trans (big_k.isLimit.fac s' WalkingCospan.right).symm
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
big_k : IsKernelPair (f₁ ≫ f₂) a b
⊢ a ≫ f₁ = b ≫ f₁
[PROOFSTEP]
rw [← cancel_mono f₂, assoc, assoc, big_k.w]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
⊢ a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂
[PROOFSTEP]
rw [small_k.w_assoc]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
⊢ IsLimit (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂))
[PROOFSTEP]
refine'
  PullbackCone.isLimitAux _ (fun s => small_k.lift s.fst s.snd (by rw [← cancel_mono f₂, assoc, s.condition, assoc]))
    (by simp) (by simp) _
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
⊢ PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁
[PROOFSTEP]
rw [← cancel_mono f₂, assoc, s.condition, assoc]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
⊢ ∀ (s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)),
    (fun s =>
            lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
              (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
          s ≫
        PullbackCone.fst (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)) =
      PullbackCone.fst s
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
⊢ ∀ (s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)),
    (fun s =>
            lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
              (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
          s ≫
        PullbackCone.snd (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)) =
      PullbackCone.snd s
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
⊢ ∀ (s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)) (m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt),
    (∀ (j : WalkingCospan),
        m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j) →
      m =
        (fun s =>
            lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
              (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
          s
[PROOFSTEP]
intro s m hm
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ m =
    (fun s =>
        lift small_k (PullbackCone.fst s) (PullbackCone.snd s) (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
      s
[PROOFSTEP]
apply small_k.isLimit.hom_ext
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ ∀ (j : WalkingCospan),
    m ≫ NatTrans.app (IsPullback.cone small_k).π j =
      (fun s =>
            lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
              (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
          s ≫
        NatTrans.app (IsPullback.cone small_k).π j
[PROOFSTEP]
apply PullbackCone.equalizer_ext small_k.cone _ _
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ m ≫ PullbackCone.fst (IsPullback.cone small_k) =
    (fun s =>
          lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
            (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
        s ≫
      PullbackCone.fst (IsPullback.cone small_k)
[PROOFSTEP]
exact (hm WalkingCospan.left).trans (by simp)
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ NatTrans.app s.π WalkingCospan.left =
    (fun s =>
          lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
            (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
        s ≫
      PullbackCone.fst (IsPullback.cone small_k)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ m ≫ PullbackCone.snd (IsPullback.cone small_k) =
    (fun s =>
          lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
            (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
        s ≫
      PullbackCone.snd (IsPullback.cone small_k)
[PROOFSTEP]
exact (hm WalkingCospan.right).trans (by simp)
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
f₁ : X ⟶ Y
f₂ : Y ⟶ Z
inst✝ : Mono f₂
small_k : IsKernelPair f₁ a b
s : PullbackCone (f₁ ≫ f₂) (f₁ ≫ f₂)
m : s.pt ⟶ (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).pt
hm :
  ∀ (j : WalkingCospan), m ≫ NatTrans.app (PullbackCone.mk a b (_ : a ≫ f₁ ≫ f₂ = b ≫ f₁ ≫ f₂)).π j = NatTrans.app s.π j
⊢ NatTrans.app s.π WalkingCospan.right =
    (fun s =>
          lift small_k (PullbackCone.fst s) (PullbackCone.snd s)
            (_ : PullbackCone.fst s ≫ f₁ = PullbackCone.snd s ≫ f₁))
        s ≫
      PullbackCone.snd (IsPullback.cone small_k)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
⊢ IsColimit (Cofork.ofπ f (_ : a ≫ f = b ≫ f))
[PROOFSTEP]
let t := k.isLimit.lift (PullbackCone.mk _ _ r.w)
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
⊢ IsColimit (Cofork.ofπ f (_ : a ≫ f = b ≫ f))
[PROOFSTEP]
have ht : t ≫ a = r.left := k.isLimit.fac _ WalkingCospan.left
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
⊢ IsColimit (Cofork.ofπ f (_ : a ≫ f = b ≫ f))
[PROOFSTEP]
have kt : t ≫ b = r.right := k.isLimit.fac _ WalkingCospan.right
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
kt : t ≫ b = RegularEpi.right
⊢ IsColimit (Cofork.ofπ f (_ : a ≫ f = b ≫ f))
[PROOFSTEP]
refine'
  Cofork.IsColimit.mk _
    (fun s => Cofork.IsColimit.desc r.isColimit s.π (by rw [← ht, assoc, s.condition, reassoc_of% kt])) (fun s => _)
    (fun s m w => _)
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
kt : t ≫ b = RegularEpi.right
s : Cofork a b
⊢ RegularEpi.left ≫ Cofork.π s = RegularEpi.right ≫ Cofork.π s
[PROOFSTEP]
rw [← ht, assoc, s.condition, reassoc_of% kt]
[GOAL]
case refine'_1
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
kt : t ≫ b = RegularEpi.right
s : Cofork a b
⊢ Cofork.π (Cofork.ofπ f (_ : a ≫ f = b ≫ f)) ≫
      (fun s =>
          Cofork.IsColimit.desc RegularEpi.isColimit (Cofork.π s)
            (_ : RegularEpi.left ≫ Cofork.π s = RegularEpi.right ≫ Cofork.π s))
        s =
    Cofork.π s
[PROOFSTEP]
apply Cofork.IsColimit.π_desc' r.isColimit
[GOAL]
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
kt : t ≫ b = RegularEpi.right
s : Cofork a b
m : (Cofork.ofπ f (_ : a ≫ f = b ≫ f)).pt ⟶ s.pt
w : Cofork.π (Cofork.ofπ f (_ : a ≫ f = b ≫ f)) ≫ m = Cofork.π s
⊢ m =
    (fun s =>
        Cofork.IsColimit.desc RegularEpi.isColimit (Cofork.π s)
          (_ : RegularEpi.left ≫ Cofork.π s = RegularEpi.right ≫ Cofork.π s))
      s
[PROOFSTEP]
apply Cofork.IsColimit.hom_ext r.isColimit
[GOAL]
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
k : IsKernelPair f a b
r : RegularEpi f
t : (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)).pt ⟶
  (IsPullback.cone k).pt :=
  IsLimit.lift (IsPullback.isLimit k)
    (PullbackCone.mk RegularEpi.left RegularEpi.right (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f))
ht : t ≫ a = RegularEpi.left
kt : t ≫ b = RegularEpi.right
s : Cofork a b
m : (Cofork.ofπ f (_ : a ≫ f = b ≫ f)).pt ⟶ s.pt
w : Cofork.π (Cofork.ofπ f (_ : a ≫ f = b ≫ f)) ≫ m = Cofork.π s
⊢ Cofork.π (Cofork.ofπ f (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)) ≫ m =
    Cofork.π (Cofork.ofπ f (_ : RegularEpi.left ≫ f = RegularEpi.right ≫ f)) ≫
      (fun s =>
          Cofork.IsColimit.desc RegularEpi.isColimit (Cofork.π s)
            (_ : RegularEpi.left ≫ Cofork.π s = RegularEpi.right ≫ Cofork.π s))
        s
[PROOFSTEP]
exact w.trans (Cofork.IsColimit.π_desc' r.isColimit _ _).symm
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
⊢ f ≫ 𝟙 Z = 𝟙 X ≫ f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
⊢ f ≫ 𝟙 Z = 𝟙 X ≫ f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
⊢ IsKernelPair pullback.fst
    (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
    (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
[PROOFSTEP]
refine'
  ⟨⟨by rw [pullback.lift_fst, pullback.lift_fst]⟩,
    ⟨PullbackCone.isLimitAux _
        (fun s => pullback.lift (s.fst ≫ pullback.fst) (h.lift (s.fst ≫ pullback.snd) (s.snd ≫ pullback.snd) _) _)
        (fun s => _) (fun s => _) (fun s m hm => _)⟩⟩
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
⊢ pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫ pullback.fst =
    pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫ pullback.fst
[PROOFSTEP]
rw [pullback.lift_fst, pullback.lift_fst]
[GOAL]
case refine'_1
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g
[PROOFSTEP]
simp_rw [Category.assoc, ← pullback.condition, ← Category.assoc, s.condition]
[GOAL]
case refine'_2
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ (PullbackCone.fst s ≫ pullback.fst) ≫ f =
    lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
        (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
      a₁ ≫ g
[PROOFSTEP]
simp only [assoc, lift_fst_assoc, pullback.condition]
[GOAL]
case refine'_3
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ (fun s =>
          pullback.lift (PullbackCone.fst s ≫ pullback.fst)
            (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
              (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
            (_ :
              (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                    (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                  a₁ ≫ g))
        s ≫
      PullbackCone.fst
        (PullbackCone.mk
          (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
          (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
          (_ :
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                pullback.fst =
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                pullback.fst)) =
    PullbackCone.fst s
[PROOFSTEP]
ext
[GOAL]
case refine'_3.h₀
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        PullbackCone.fst
          (PullbackCone.mk
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
            (_ :
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                  pullback.fst =
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                  pullback.fst))) ≫
      pullback.fst =
    PullbackCone.fst s ≫ pullback.fst
[PROOFSTEP]
simp
[GOAL]
case refine'_3.h₁
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        PullbackCone.fst
          (PullbackCone.mk
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
            (_ :
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                  pullback.fst =
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                  pullback.fst))) ≫
      pullback.snd =
    PullbackCone.fst s ≫ pullback.snd
[PROOFSTEP]
simp
[GOAL]
case refine'_4
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ (fun s =>
          pullback.lift (PullbackCone.fst s ≫ pullback.fst)
            (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
              (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
            (_ :
              (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                    (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                  a₁ ≫ g))
        s ≫
      PullbackCone.snd
        (PullbackCone.mk
          (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
          (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
          (_ :
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                pullback.fst =
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                pullback.fst)) =
    PullbackCone.snd s
[PROOFSTEP]
ext
[GOAL]
case refine'_4.h₀
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        PullbackCone.snd
          (PullbackCone.mk
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
            (_ :
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                  pullback.fst =
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                  pullback.fst))) ≫
      pullback.fst =
    PullbackCone.snd s ≫ pullback.fst
[PROOFSTEP]
simp [s.condition]
[GOAL]
case refine'_4.h₁
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
⊢ ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        PullbackCone.snd
          (PullbackCone.mk
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
            (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
            (_ :
              pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                  pullback.fst =
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                  pullback.fst))) ≫
      pullback.snd =
    PullbackCone.snd s ≫ pullback.snd
[PROOFSTEP]
simp
[GOAL]
case refine'_5
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
m :
  s.pt ⟶
    (PullbackCone.mk (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
        (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
        (_ :
          pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
              pullback.fst =
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
              pullback.fst)).pt
hm :
  ∀ (j : WalkingCospan),
    m ≫
        NatTrans.app
          (PullbackCone.mk
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
              (_ :
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                    pullback.fst =
                  pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                    pullback.fst)).π
          j =
      NatTrans.app s.π j
⊢ m =
    (fun s =>
        pullback.lift (PullbackCone.fst s ≫ pullback.fst)
          (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
            (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
          (_ :
            (PullbackCone.fst s ≫ pullback.fst) ≫ f =
              lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                  (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                a₁ ≫ g))
      s
[PROOFSTEP]
apply pullback.hom_ext
[GOAL]
case refine'_5.h₀
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
m :
  s.pt ⟶
    (PullbackCone.mk (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
        (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
        (_ :
          pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
              pullback.fst =
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
              pullback.fst)).pt
hm :
  ∀ (j : WalkingCospan),
    m ≫
        NatTrans.app
          (PullbackCone.mk
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
              (_ :
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                    pullback.fst =
                  pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                    pullback.fst)).π
          j =
      NatTrans.app s.π j
⊢ m ≫ pullback.fst =
    (fun s =>
          pullback.lift (PullbackCone.fst s ≫ pullback.fst)
            (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
              (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
            (_ :
              (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                    (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                  a₁ ≫ g))
        s ≫
      pullback.fst
[PROOFSTEP]
simpa using hm WalkingCospan.left =≫ pullback.fst
[GOAL]
case refine'_5.h₁
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
m :
  s.pt ⟶
    (PullbackCone.mk (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
        (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
        (_ :
          pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
              pullback.fst =
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
              pullback.fst)).pt
hm :
  ∀ (j : WalkingCospan),
    m ≫
        NatTrans.app
          (PullbackCone.mk
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
              (_ :
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                    pullback.fst =
                  pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                    pullback.fst)).π
          j =
      NatTrans.app s.π j
⊢ m ≫ pullback.snd =
    (fun s =>
          pullback.lift (PullbackCone.fst s ≫ pullback.fst)
            (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
              (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
            (_ :
              (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                    (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                  a₁ ≫ g))
        s ≫
      pullback.snd
[PROOFSTEP]
apply PullbackCone.IsLimit.hom_ext h.isLimit
[GOAL]
case refine'_5.h₁.h₀
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
m :
  s.pt ⟶
    (PullbackCone.mk (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
        (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
        (_ :
          pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
              pullback.fst =
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
              pullback.fst)).pt
hm :
  ∀ (j : WalkingCospan),
    m ≫
        NatTrans.app
          (PullbackCone.mk
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
              (_ :
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                    pullback.fst =
                  pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                    pullback.fst)).π
          j =
      NatTrans.app s.π j
⊢ (m ≫ pullback.snd) ≫ PullbackCone.fst (IsPullback.cone h) =
    ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        pullback.snd) ≫
      PullbackCone.fst (IsPullback.cone h)
[PROOFSTEP]
simpa using hm WalkingCospan.left =≫ pullback.snd
[GOAL]
case refine'_5.h₁.h₁
C : Type u
inst✝² : Category.{v, u} C
R X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
a b : R ⟶ X✝
X Y Z A : C
g : Y ⟶ Z
a₁ a₂ : A ⟶ Y
h : IsKernelPair g a₁ a₂
f : X ⟶ Z
inst✝¹ : HasPullback f g
inst✝ : HasPullback f (a₁ ≫ g)
s : PullbackCone pullback.fst pullback.fst
m :
  s.pt ⟶
    (PullbackCone.mk (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
        (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
        (_ :
          pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
              pullback.fst =
            pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
              pullback.fst)).pt
hm :
  ∀ (j : WalkingCospan),
    m ≫
        NatTrans.app
          (PullbackCone.mk
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g))
              (pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g))
              (_ :
                pullback.map f (a₁ ≫ g) f g (𝟙 X) a₁ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₁ ≫ g) ≫
                    pullback.fst =
                  pullback.map f (a₁ ≫ g) f g (𝟙 X) a₂ (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) (_ : (a₁ ≫ g) ≫ 𝟙 Z = a₂ ≫ g) ≫
                    pullback.fst)).π
          j =
      NatTrans.app s.π j
⊢ (m ≫ pullback.snd) ≫ PullbackCone.snd (IsPullback.cone h) =
    ((fun s =>
            pullback.lift (PullbackCone.fst s ≫ pullback.fst)
              (lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g))
              (_ :
                (PullbackCone.fst s ≫ pullback.fst) ≫ f =
                  lift h (PullbackCone.fst s ≫ pullback.snd) (PullbackCone.snd s ≫ pullback.snd)
                      (_ : (PullbackCone.fst s ≫ pullback.snd) ≫ g = (PullbackCone.snd s ≫ pullback.snd) ≫ g) ≫
                    a₁ ≫ g))
          s ≫
        pullback.snd) ≫
      PullbackCone.snd (IsPullback.cone h)
[PROOFSTEP]
simpa using hm WalkingCospan.right =≫ pullback.snd
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
⊢ Mono f
[PROOFSTEP]
obtain ⟨l, h₁, h₂⟩ := Limits.PullbackCone.IsLimit.lift' h.isLimit (𝟙 _) (𝟙 _) (by simp [h.w])
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
⊢ 𝟙 X ≫ f = 𝟙 X ≫ f
[PROOFSTEP]
simp [h.w]
[GOAL]
case mk.intro
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l ≫ PullbackCone.fst (IsPullback.cone h) = 𝟙 X
h₂ : l ≫ PullbackCone.snd (IsPullback.cone h) = 𝟙 X
⊢ Mono f
[PROOFSTEP]
rw [IsPullback.cone_fst, ← IsIso.eq_comp_inv, Category.id_comp] at h₁
[GOAL]
case mk.intro
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l = inv a
h₂ : l ≫ PullbackCone.snd (IsPullback.cone h) = 𝟙 X
⊢ Mono f
[PROOFSTEP]
rw [h₁, IsIso.inv_comp_eq, Category.comp_id] at h₂
[GOAL]
case mk.intro
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l = inv a
h₂ : PullbackCone.snd (IsPullback.cone h) = a
⊢ Mono f
[PROOFSTEP]
constructor
[GOAL]
case mk.intro.right_cancellation
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l = inv a
h₂ : PullbackCone.snd (IsPullback.cone h) = a
⊢ ∀ {Z : C} (g h : Z ⟶ X), g ≫ f = h ≫ f → g = h
[PROOFSTEP]
intro Z g₁ g₂ e
[GOAL]
case mk.intro.right_cancellation
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z✝ : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l = inv a
h₂ : PullbackCone.snd (IsPullback.cone h) = a
Z : C
g₁ g₂ : Z ⟶ X
e : g₁ ≫ f = g₂ ≫ f
⊢ g₁ = g₂
[PROOFSTEP]
obtain ⟨l', rfl, rfl⟩ := Limits.PullbackCone.IsLimit.lift' h.isLimit _ _ e
[GOAL]
case mk.intro.right_cancellation.mk.intro
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z✝ : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : IsIso a
l : X ⟶ (IsPullback.cone h).pt
h₁ : l = inv a
h₂ : PullbackCone.snd (IsPullback.cone h) = a
Z : C
l' : Z ⟶ (IsPullback.cone h).pt
e : (l' ≫ PullbackCone.fst (IsPullback.cone h)) ≫ f = (l' ≫ PullbackCone.snd (IsPullback.cone h)) ≫ f
⊢ l' ≫ PullbackCone.fst (IsPullback.cone h) = l' ≫ PullbackCone.snd (IsPullback.cone h)
[PROOFSTEP]
rw [IsPullback.cone_fst, h₂]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : Mono f
⊢ IsIso a
[PROOFSTEP]
rw [←
  show _ = a from
    (Category.comp_id _).symm.trans
      ((IsKernelPair.id_of_mono f).isLimit.conePointUniqueUpToIso_inv_comp h.isLimit WalkingCospan.left)]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
h : IsKernelPair f a b
inst✝ : Mono f
⊢ IsIso
    (IsLimit.conePointUniqueUpToIso (IsPullback.isLimit (_ : IsKernelPair f (𝟙 X) (𝟙 X))) (IsPullback.isLimit h)).inv
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ IsKernelPair f a a
[PROOFSTEP]
change IsPullback _ _ _ _
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ IsPullback a a f f
[PROOFSTEP]
convert (IsPullback.of_horiz_isIso ⟨(rfl : a ≫ 𝟙 X = _)⟩).paste_vert (IsKernelPair.id_of_mono f)
[GOAL]
case h.e'_8
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ a = a ≫ 𝟙 X
case h.e'_9
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ f = 𝟙 X ≫ f
[PROOFSTEP]
all_goals {simp
}
[GOAL]
case h.e'_8
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ a = a ≫ 𝟙 X
[PROOFSTEP]
{simp
}
[GOAL]
case h.e'_8
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ a = a ≫ 𝟙 X
[PROOFSTEP]
simp
[GOAL]
case h.e'_9
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ f = 𝟙 X ≫ f
[PROOFSTEP]
{simp
}
[GOAL]
case h.e'_9
C : Type u
inst✝² : Category.{v, u} C
R X Y Z : C
f : X ⟶ Y
a b : R ⟶ X
inst✝¹ : IsIso a
inst✝ : Mono f
⊢ f = 𝟙 X ≫ f
[PROOFSTEP]
simp


[GOAL]
C : Type u
inst✝² : Category.{v, u} C
D : Type w
inst✝¹ : Category.{max v u, w} D
inst✝ : Abelian D
J : GrothendieckTopology C
j : ℕ
F : Discrete (Fin j) ⥤ Sheaf J D
⊢ HasLimit F
[PROOFSTEP]
infer_instance


[GOAL]
R : Type u
inst✝ : Ring R
M N : ModuleCat R
⊢ ∀ ⦃X Y : Discrete WalkingPair⦄ (f : X ⟶ Y),
    ((Functor.const (Discrete WalkingPair)).obj (of R (↑M × ↑N))).map f ≫
        (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N)) Y =
      (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N)) X ≫
        (pair M N).map f
[PROOFSTEP]
rintro ⟨⟨⟩⟩ ⟨⟨⟩⟩ ⟨⟨⟨⟩⟩⟩
[GOAL]
case mk.left.mk.left.up.up.refl
R : Type u
inst✝ : Ring R
M N : ModuleCat R
⊢ ((Functor.const (Discrete WalkingPair)).obj (of R (↑M × ↑N))).map
        { down := { down := (_ : { as := WalkingPair.left }.as = { as := WalkingPair.left }.as) } } ≫
      (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N))
        { as := WalkingPair.left } =
    (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N))
        { as := WalkingPair.left } ≫
      (pair M N).map { down := { down := (_ : { as := WalkingPair.left }.as = { as := WalkingPair.left }.as) } }
[PROOFSTEP]
rfl
[GOAL]
case mk.right.mk.right.up.up.refl
R : Type u
inst✝ : Ring R
M N : ModuleCat R
⊢ ((Functor.const (Discrete WalkingPair)).obj (of R (↑M × ↑N))).map
        { down := { down := (_ : { as := WalkingPair.right }.as = { as := WalkingPair.right }.as) } } ≫
      (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N))
        { as := WalkingPair.right } =
    (fun j => Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N))
        { as := WalkingPair.right } ≫
      (pair M N).map { down := { down := (_ : { as := WalkingPair.right }.as = { as := WalkingPair.right }.as) } }
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝ : Ring R
M N : ModuleCat R
⊢ ∀ (s : Cone (pair M N)) (j : Discrete WalkingPair),
    (fun s =>
            LinearMap.prod (NatTrans.app s.π { as := WalkingPair.left }) (NatTrans.app s.π { as := WalkingPair.right }))
          s ≫
        NatTrans.app
          { pt := of R (↑M × ↑N),
              π :=
                NatTrans.mk fun j =>
                  Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.π
          j =
      NatTrans.app s.π j
[PROOFSTEP]
rintro s (⟨⟩ | ⟨⟩)
[GOAL]
case mk.left
R : Type u
inst✝ : Ring R
M N : ModuleCat R
s : Cone (pair M N)
⊢ (fun s => LinearMap.prod (NatTrans.app s.π { as := WalkingPair.left }) (NatTrans.app s.π { as := WalkingPair.right }))
        s ≫
      NatTrans.app
        { pt := of R (↑M × ↑N),
            π :=
              NatTrans.mk fun j =>
                Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.π
        { as := WalkingPair.left } =
    NatTrans.app s.π { as := WalkingPair.left }
[PROOFSTEP]
rfl
[GOAL]
case mk.right
R : Type u
inst✝ : Ring R
M N : ModuleCat R
s : Cone (pair M N)
⊢ (fun s => LinearMap.prod (NatTrans.app s.π { as := WalkingPair.left }) (NatTrans.app s.π { as := WalkingPair.right }))
        s ≫
      NatTrans.app
        { pt := of R (↑M × ↑N),
            π :=
              NatTrans.mk fun j =>
                Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.π
        { as := WalkingPair.right } =
    NatTrans.app s.π { as := WalkingPair.right }
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝ : Ring R
M N : ModuleCat R
s : Cone (pair M N)
m :
  s.pt ⟶
    { pt := of R (↑M × ↑N),
        π :=
          NatTrans.mk fun j =>
            Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.pt
w :
  ∀ (j : Discrete WalkingPair),
    m ≫
        NatTrans.app
          { pt := of R (↑M × ↑N),
              π :=
                NatTrans.mk fun j =>
                  Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.π
          j =
      NatTrans.app s.π j
⊢ m =
    (fun s =>
        LinearMap.prod (NatTrans.app s.π { as := WalkingPair.left }) (NatTrans.app s.π { as := WalkingPair.right }))
      s
[PROOFSTEP]
simp_rw [← w ⟨WalkingPair.left⟩, ← w ⟨WalkingPair.right⟩]
[GOAL]
R : Type u
inst✝ : Ring R
M N : ModuleCat R
s : Cone (pair M N)
m :
  s.pt ⟶
    { pt := of R (↑M × ↑N),
        π :=
          NatTrans.mk fun j =>
            Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.pt
w :
  ∀ (j : Discrete WalkingPair),
    m ≫
        NatTrans.app
          { pt := of R (↑M × ↑N),
              π :=
                NatTrans.mk fun j =>
                  Discrete.casesOn j fun j => WalkingPair.casesOn j (LinearMap.fst R ↑M ↑N) (LinearMap.snd R ↑M ↑N) }.π
          j =
      NatTrans.app s.π j
⊢ m = LinearMap.prod (m ≫ LinearMap.fst R ↑M ↑N) (m ≫ LinearMap.snd R ↑M ↑N)
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Fan f
x y : ↑s.pt
⊢ (fun x j => ↑(NatTrans.app s.π { as := j }) x) (x + y) =
    (fun x j => ↑(NatTrans.app s.π { as := j }) x) x + (fun x j => ↑(NatTrans.app s.π { as := j }) x) y
[PROOFSTEP]
simp only [Functor.const_obj_obj, map_add]
[GOAL]
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Fan f
x y : ↑s.pt
⊢ (fun j => ↑(NatTrans.app s.π { as := j }) x + ↑(NatTrans.app s.π { as := j }) y) =
    (fun j => ↑(NatTrans.app s.π { as := j }) x) + fun j => ↑(NatTrans.app s.π { as := j }) y
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Fan f
r : R
x : ↑s.pt
⊢ AddHom.toFun
      { toFun := fun x j => ↑(NatTrans.app s.π { as := j }) x,
        map_add' :=
          (_ :
            ∀ (x y : ↑s.pt),
              (fun x j => ↑(NatTrans.app s.π { as := j }) x) (x + y) =
                (fun x j => ↑(NatTrans.app s.π { as := j }) x) x + (fun x j => ↑(NatTrans.app s.π { as := j }) x) y) }
      (r • x) =
    ↑(RingHom.id R) r •
      AddHom.toFun
        { toFun := fun x j => ↑(NatTrans.app s.π { as := j }) x,
          map_add' :=
            (_ :
              ∀ (x y : ↑s.pt),
                (fun x j => ↑(NatTrans.app s.π { as := j }) x) (x + y) =
                  (fun x j => ↑(NatTrans.app s.π { as := j }) x) x + (fun x j => ↑(NatTrans.app s.π { as := j }) x) y) }
        x
[PROOFSTEP]
simp only [Functor.const_obj_obj, map_smul]
[GOAL]
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Fan f
r : R
x : ↑s.pt
⊢ (fun j => r • ↑(NatTrans.app s.π { as := j }) x) = ↑(RingHom.id R) r • fun j => ↑(NatTrans.app s.π { as := j }) x
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Cone (Discrete.functor f)
m : s.pt ⟶ { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.pt
w :
  ∀ (j : Discrete J),
    m ≫ NatTrans.app { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.π j =
      NatTrans.app s.π j
⊢ m = lift f s
[PROOFSTEP]
ext x
[GOAL]
case h
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Cone (Discrete.functor f)
m : s.pt ⟶ { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.pt
w :
  ∀ (j : Discrete J),
    m ≫ NatTrans.app { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.π j =
      NatTrans.app s.π j
x : ↑s.pt
⊢ ↑m x = ↑(lift f s) x
[PROOFSTEP]
funext j
[GOAL]
case h.h
R : Type u
inst✝ : Ring R
J : Type w
f : J → ModuleCat R
s : Cone (Discrete.functor f)
m : s.pt ⟶ { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.pt
w :
  ∀ (j : Discrete J),
    m ≫ NatTrans.app { pt := of R ((j : J) → ↑(f j)), π := Discrete.natTrans fun j => LinearMap.proj j.as }.π j =
      NatTrans.app s.π j
x : ↑s.pt
j : J
⊢ ↑m x j = ↑(lift f s) x j
[PROOFSTEP]
exact congr_arg (fun g : s.pt ⟶ f j => (g : s.pt → f j) x) (w ⟨j⟩)


[GOAL]
α : Type v
inst✝ : Fintype α
⊢ Small.{w, v} α
[PROOFSTEP]
rw [small_congr (Fintype.equivFin α)]
[GOAL]
α : Type v
inst✝ : Fintype α
⊢ Small.{w, 0} (Fin (Fintype.card α))
[PROOFSTEP]
infer_instance


[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
E✝ X✝ : C
f : 0 ⟶ X✝
e : E✝ ⟶ X✝
x✝ : Epi e
⊢ 0 ≫ e = f
[PROOFSTEP]
ext
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
P Q : C
i : P ≅ Q
hP : Projective P
E✝ X✝ : C
f : Q ⟶ X✝
e : E✝ ⟶ X✝
e_epi : Epi e
f' : P ⟶ E✝
hf' : f' ≫ e = i.hom ≫ f
⊢ (i.inv ≫ f') ≫ e = f
[PROOFSTEP]
simp [hf']
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
P Q : C
inst✝² : HasBinaryCoproduct P Q
inst✝¹ : Projective P
inst✝ : Projective Q
E✝ X✝ : C
f : P ⨿ Q ⟶ X✝
e : E✝ ⟶ X✝
epi : Epi e
⊢ coprod.desc (factorThru (coprod.inl ≫ f) e) (factorThru (coprod.inr ≫ f) e) ≫ e = f
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
β : Type v
g : β → C
inst✝¹ : HasCoproduct g
inst✝ : ∀ (b : β), Projective (g b)
E✝ X✝ : C
f : ∐ g ⟶ X✝
e : E✝ ⟶ X✝
epi : Epi e
⊢ (Sigma.desc fun b => factorThru (Sigma.ι g b ≫ f) e) ≫ e = f
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
P Q : C
inst✝³ : HasZeroMorphisms C
inst✝² : HasBinaryBiproduct P Q
inst✝¹ : Projective P
inst✝ : Projective Q
E✝ X✝ : C
f : P ⊞ Q ⟶ X✝
e : E✝ ⟶ X✝
epi : Epi e
⊢ biprod.desc (factorThru (biprod.inl ≫ f) e) (factorThru (biprod.inr ≫ f) e) ≫ e = f
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
β : Type v
g : β → C
inst✝² : HasZeroMorphisms C
inst✝¹ : HasBiproduct g
inst✝ : ∀ (b : β), Projective (g b)
E✝ X✝ : C
f : ⨁ g ⟶ X✝
e : E✝ ⟶ X✝
epi : Epi e
⊢ (biproduct.desc fun b => factorThru (biproduct.ι g b ≫ f) e) ≫ e = f
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝ : Functor.PreservesEpimorphisms G
P : C
hP : Projective P
E✝ X✝ : D
f : F.obj P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
⊢ ∃ f', f' ≫ g = f
[PROOFSTEP]
rcases hP.factors (adj.unit.app P ≫ G.map f) (G.map g) with ⟨f', hf'⟩
[GOAL]
case intro
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝ : Functor.PreservesEpimorphisms G
P : C
hP : Projective P
E✝ X✝ : D
f : F.obj P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
f' : P ⟶ G.obj E✝
hf' : f' ≫ G.map g = NatTrans.app adj.unit P ≫ G.map f
⊢ ∃ f', f' ≫ g = f
[PROOFSTEP]
use F.map f' ≫ adj.counit.app _
[GOAL]
case h
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝ : Functor.PreservesEpimorphisms G
P : C
hP : Projective P
E✝ X✝ : D
f : F.obj P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
f' : P ⟶ G.obj E✝
hf' : f' ≫ G.map g = NatTrans.app adj.unit P ≫ G.map f
⊢ (F.map f' ≫ NatTrans.app adj.counit E✝) ≫ g = f
[PROOFSTEP]
rw [Category.assoc, ← Adjunction.counit_naturality, ← Category.assoc, ← F.map_comp, hf']
[GOAL]
case h
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝ : Functor.PreservesEpimorphisms G
P : C
hP : Projective P
E✝ X✝ : D
f : F.obj P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
f' : P ⟶ G.obj E✝
hf' : f' ≫ G.map g = NatTrans.app adj.unit P ≫ G.map f
⊢ F.map (NatTrans.app adj.unit P ≫ G.map f) ≫ NatTrans.app adj.counit X✝ = f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝¹ : Full F
inst✝ : Faithful F
P : C
hP : Projective (F.obj P)
E✝ X✝ : C
f : P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
⊢ ∃ f', f' ≫ g = f
[PROOFSTEP]
haveI := Adjunction.leftAdjointPreservesColimits.{0, 0} adj
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝¹ : Full F
inst✝ : Faithful F
P : C
hP : Projective (F.obj P)
E✝ X✝ : C
f : P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
this : PreservesColimitsOfSize.{0, 0, v, v', u, u'} F
⊢ ∃ f', f' ≫ g = f
[PROOFSTEP]
rcases(@hP).1 (F.map f) (F.map g) with ⟨f', hf'⟩
[GOAL]
case intro
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝¹ : Full F
inst✝ : Faithful F
P : C
hP : Projective (F.obj P)
E✝ X✝ : C
f : P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
this : PreservesColimitsOfSize.{0, 0, v, v', u, u'} F
f' : F.obj P ⟶ F.obj E✝
hf' : f' ≫ F.map g = F.map f
⊢ ∃ f', f' ≫ g = f
[PROOFSTEP]
use adj.unit.app _ ≫ G.map f' ≫ (inv <| adj.unit.app _)
[GOAL]
case h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝¹ : Full F
inst✝ : Faithful F
P : C
hP : Projective (F.obj P)
E✝ X✝ : C
f : P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
this : PreservesColimitsOfSize.{0, 0, v, v', u, u'} F
f' : F.obj P ⟶ F.obj E✝
hf' : f' ≫ F.map g = F.map f
⊢ (NatTrans.app adj.unit P ≫ G.map f' ≫ inv (NatTrans.app adj.unit E✝)) ≫ g = f
[PROOFSTEP]
refine' Faithful.map_injective (F := F) _
[GOAL]
case h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
inst✝¹ : Full F
inst✝ : Faithful F
P : C
hP : Projective (F.obj P)
E✝ X✝ : C
f : P ⟶ X✝
g : E✝ ⟶ X✝
x✝ : Epi g
this : PreservesColimitsOfSize.{0, 0, v, v', u, u'} F
f' : F.obj P ⟶ F.obj E✝
hf' : f' ≫ F.map g = F.map f
⊢ F.map ((NatTrans.app adj.unit P ≫ G.map f' ≫ inv (NatTrans.app adj.unit E✝)) ≫ g) = F.map f
[PROOFSTEP]
simpa
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
⊢ EnoughProjectives C ↔ EnoughProjectives D
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
⊢ EnoughProjectives C → EnoughProjectives D
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
⊢ EnoughProjectives D → EnoughProjectives C
[PROOFSTEP]
all_goals intro H; constructor; intro X; constructor
[GOAL]
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
⊢ EnoughProjectives C → EnoughProjectives D
[PROOFSTEP]
intro H
[GOAL]
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives C
⊢ EnoughProjectives D
[PROOFSTEP]
constructor
[GOAL]
case mp.presentation
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives C
⊢ ∀ (X : D), Nonempty (ProjectivePresentation X)
[PROOFSTEP]
intro X
[GOAL]
case mp.presentation
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives C
X : D
⊢ Nonempty (ProjectivePresentation X)
[PROOFSTEP]
constructor
[GOAL]
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
⊢ EnoughProjectives D → EnoughProjectives C
[PROOFSTEP]
intro H
[GOAL]
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives D
⊢ EnoughProjectives C
[PROOFSTEP]
constructor
[GOAL]
case mpr.presentation
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives D
⊢ ∀ (X : C), Nonempty (ProjectivePresentation X)
[PROOFSTEP]
intro X
[GOAL]
case mpr.presentation
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives D
X : C
⊢ Nonempty (ProjectivePresentation X)
[PROOFSTEP]
constructor
[GOAL]
case mp.presentation.val
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives C
X : D
⊢ ProjectivePresentation X
[PROOFSTEP]
exact F.symm.projectivePresentationOfMapProjectivePresentation _ (Nonempty.some (H.presentation (F.inverse.obj X)))
[GOAL]
case mpr.presentation.val
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
F✝ F : C ≌ D
H : EnoughProjectives D
X : C
⊢ ProjectivePresentation X
[PROOFSTEP]
exact F.projectivePresentationOfMapProjectivePresentation X (Nonempty.some (H.presentation (F.functor.obj X)))
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
⊢ lift h f g hfg w ≫ f = h
[PROOFSTEP]
simp only [Exact.lift]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
⊢ factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
        (factorThruImageSubobject f) ≫
      f =
    h
[PROOFSTEP]
conv_lhs =>
  congr
  rfl
  rw [← imageSubobject_arrow_comp f]
    -- See the porting note on `Exact.epi`.
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
      (factorThruImageSubobject f) ≫
    f
[PROOFSTEP]
  congr
  rfl
  rw [← imageSubobject_arrow_comp f]
    -- See the porting note on `Exact.epi`.
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
      (factorThruImageSubobject f) ≫
    f
[PROOFSTEP]
  congr
  rfl
  rw [← imageSubobject_arrow_comp f]
    -- See the porting note on `Exact.epi`.
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
      (factorThruImageSubobject f) ≫
    f
[PROOFSTEP]
congr
[GOAL]
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
    (factorThruImageSubobject f)
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| f
[PROOFSTEP]
rfl
[GOAL]
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| f
[PROOFSTEP]
rw [← imageSubobject_arrow_comp f]
  -- See the porting note on `Exact.epi`.
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
⊢ factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
        (factorThruImageSubobject f) ≫
      factorThruImageSubobject f ≫ Subobject.arrow (imageSubobject f) =
    h
[PROOFSTEP]
haveI := hfg.epi
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
this : Epi (imageToKernel f g (_ : f ≫ g = 0))
⊢ factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
        (factorThruImageSubobject f) ≫
      factorThruImageSubobject f ≫ Subobject.arrow (imageSubobject f) =
    h
[PROOFSTEP]
rw [← Category.assoc, factorThru_comp, ← imageToKernel_arrow f g, ← Category.assoc,
  CategoryTheory.Projective.factorThru_comp, factorThruKernelSubobject_comp_arrow]