Theorem: CategoryTheory.MorphismProperty.IsStableUnderProductsOfShape.mk
File: Mathlib/CategoryTheory/MorphismProperty/Limits.lean

tactic: intro X₁ X₂ c₁ c₂ hc₁ hc₂ f hf
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
⊢ W.IsStableUnderProductsOfShape J
state_after: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })

tactic: let φ := fun j => f.app (Discrete.mk j)
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })
state_after: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })

tactic: have hf' := hW _ _ φ (fun j => hf (Discrete.mk j))
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })
state_after: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })

tactic: refine (hW₀.arrow_mk_iso_iff ?_).2 hf'
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ W (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })
state_after: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f }) ≅ Arrow.mk (Pi.map φ)

tactic: refine Arrow.isoMk
  (IsLimit.conePointUniqueUpToIso hc₁ (limit.isLimit X₁) ≪≫ (Pi.isoLimit _).symm)
  (IsLimit.conePointUniqueUpToIso hc₂ (limit.isLimit X₂) ≪≫ (Pi.isoLimit _).symm) ?_
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f }) ≅ Arrow.mk (Pi.map φ)
state_after: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ (hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom =
    (Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
      (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom

tactic: apply limit.hom_ext
state_before: C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ (hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom =
    (Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
      (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom
state_after: case w
C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ ∀ (j : Discrete J),
    ((hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom) ≫
        limit.π (Discrete.functor fun j => X₂.obj { as := j }) j =
      ((Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
          (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom) ≫
        limit.π (Discrete.functor fun j => X₂.obj { as := j }) j

tactic: rintro ⟨j⟩
state_before: case w
C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
⊢ ∀ (j : Discrete J),
    ((hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom) ≫
        limit.π (Discrete.functor fun j => X₂.obj { as := j }) j =
      ((Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
          (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom) ≫
        limit.π (Discrete.functor fun j => X₂.obj { as := j }) j
state_after: case w.mk
C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
j : J
⊢ ((hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom) ≫
      limit.π (Discrete.functor fun j => X₂.obj { as := j }) { as := j } =
    ((Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
        (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom) ≫
      limit.π (Discrete.functor fun j => X₂.obj { as := j }) { as := j }

tactic: simp
state_before: case w.mk
C : Type u
inst✝¹ : Category.{v, u} C
W : MorphismProperty C
J : Type u_1
hW₀ : W.RespectsIso
inst✝ : HasProductsOfShape J C
hW : ∀ (X₁ X₂ : J → C) (f : (j : J) → X₁ j ⟶ X₂ j), (∀ (j : J), W (f j)) → W (Pi.map f)
X₁ X₂ : Discrete J ⥤ C
c₁ : Cone X₁
c₂ : Cone X₂
hc₁ : IsLimit c₁
hc₂ : IsLimit c₂
f : X₁ ⟶ X₂
hf : W.functorCategory (Discrete J) f
φ : (j : J) → X₁.obj { as := j } ⟶ X₂.obj { as := j } := fun j => f.app { as := j }
hf' : W (Pi.map φ)
j : J
⊢ ((hc₁.conePointUniqueUpToIso (limit.isLimit X₁) ≪≫ (Pi.isoLimit X₁).symm).hom ≫ (Arrow.mk (Pi.map φ)).hom) ≫
      limit.π (Discrete.functor fun j => X₂.obj { as := j }) { as := j } =
    ((Arrow.mk (hc₂.lift { pt := c₁.pt, π := c₁.π ≫ f })).hom ≫
        (hc₂.conePointUniqueUpToIso (limit.isLimit X₂) ≪≫ (Pi.isoLimit X₂).symm).hom) ≫
      limit.π (Discrete.functor fun j => X₂.obj { as := j }) { as := j }
state_after: no goals