Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Mathlib/CategoryTheory/Discrete/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ Please avoid using this directly. -/
@[to_dual existing mk]
abbrev Discrete.Hom.mk' {α : Type u₁} {a b : α} (eq : b = a) : Discrete.Hom a b := ⟨eq.symm⟩

/-- `Discrete.Hom.casesOn'` is the dual of `Discrete.Hom.casesOn`, which is needed for `to_dual`.
Please avoid using this directly. -/
@[to_dual existing casesOn]
abbrev Discrete.Hom.casesOn' {α : Type u₁} {a b : α} {motive : Discrete.Hom a b → Sort*}
(t : Discrete.Hom a b) (mk : (eq : b = a) → motive (mk' eq)) : motive t :=
t.casesOn (mk ·.symm)

/-- The "Discrete" category on a type, whose morphisms are equalities.

Because we do not allow morphisms in `Prop` (only in `Type`),
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/CategoryTheory/Extensive.lean
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ instance types.finitaryExtensive : FinitaryExtensive (Type u) := by
· intro s m e₁ e₂
ext x
simp only [TypeCat.Fun.toFun_apply, Types.binaryCoproductCocone_pt, pair_obj_left,
Functor.const_obj_obj, pair_obj_right, ConcreteCategory.hom_ofHom, TypeCat.Fun.coe_mk]
pair_obj_right, ConcreteCategory.hom_ofHom, TypeCat.Fun.coe_mk]
split_ifs
· rw [← e₁]
rfl
Expand Down
118 changes: 28 additions & 90 deletions Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts/BinaryFan.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,51 @@
variable {C : Type u} [Category.{v} C]

/-- A binary fan is just a cone on a diagram indexing a product. -/
@[to_dual /-- A binary cofan is just a cocone on a diagram indexing a coproduct. -/]
abbrev BinaryFan (X Y : C) :=
Cone (pair X Y)

/-- The first projection of a binary fan. -/
abbrev BinaryFan.fst {X Y : C} (s : BinaryFan X Y) :=
@[to_dual inl /-- The first inclusion of a binary cofan. -/]
abbrev BinaryFan.fst {X Y : C} (s : BinaryFan X Y) : s.pt ⟶ (pair X Y).obj ⟨left⟩ :=
s.π.app ⟨WalkingPair.left⟩

/-- The second projection of a binary fan. -/
abbrev BinaryFan.snd {X Y : C} (s : BinaryFan X Y) :=
@[to_dual inr /-- The second inclusion of a binary cofan. -/]
abbrev BinaryFan.snd {X Y : C} (s : BinaryFan X Y) : s.pt ⟶ (pair X Y).obj ⟨right⟩ :=
s.π.app ⟨WalkingPair.right⟩

-- Marking this `@[simp]` causes loops since `s.fst` is reducibly defeq to the LHS.
@[to_dual ι_app_left]
theorem BinaryFan.π_app_left {X Y : C} (s : BinaryFan X Y) : s.π.app ⟨WalkingPair.left⟩ = s.fst :=
rfl

-- Marking this `@[simp]` causes loops since `s.snd` is reducibly defeq to the LHS.
@[to_dual ι_app_right]
theorem BinaryFan.π_app_right {X Y : C} (s : BinaryFan X Y) : s.π.app ⟨WalkingPair.right⟩ = s.snd :=
rfl

/-- Constructs an isomorphism of `BinaryFan`s out of an isomorphism of the tips that commutes with
the projections. -/
@[to_dual
/-- Constructs an isomorphism of `BinaryCofan`s out of an isomorphism of the tips that commutes with
the injections. -/]
def BinaryFan.ext {A B : C} {c c' : BinaryFan A B} (e : c.pt ≅ c'.pt)
(h₁ : c.fst = e.hom ≫ c'.fst) (h₂ : c.snd = e.hom ≫ c'.snd) : c ≅ c' :=
Cone.ext e (fun j => by rcases j with ⟨⟨⟩⟩ <;> assumption)

@[simp]
@[to_dual (attr := simp) ext_inv_hom]
lemma BinaryFan.ext_hom_hom {A B : C} {c c' : BinaryFan A B} (e : c.pt ≅ c'.pt)
(h₁ : c.fst = e.hom ≫ c'.fst) (h₂ : c.snd = e.hom ≫ c'.snd) :
(ext e h₁ h₂).hom.hom = e.hom := rfl

@[to_dual (attr := simp) ext_hom_hom]
lemma BinaryFan.ext_inv_hom {A B : C} {c c' : BinaryFan A B} (e : c.pt ≅ c'.pt)
(h₁ : c.fst = e.hom ≫ c'.fst) (h₂ : c.snd = e.hom ≫ c'.snd) :
(ext e h₁ h₂).inv.hom = e.inv := rfl

/-- A convenient way to show that a binary fan is a limit. -/
@[to_dual IsColimit.mk]

Check failure on line 78 in Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts/BinaryFan.lean

View workflow job for this annotation

GitHub Actions / ci (fork) / Test and lint

@CategoryTheory.Limits.BinaryCofan.IsColimit.mk definition missing documentation string
def BinaryFan.IsLimit.mk {X Y : C} (s : BinaryFan X Y)
(lift : ∀ {T : C} (_ : T ⟶ X) (_ : T ⟶ Y), T ⟶ s.pt)
(hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.fst = f)
Expand All @@ -77,57 +91,11 @@
· exact hl₂ _ _)
fun _ _ h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩)

@[to_dual IsColimit.hom_ext]
theorem BinaryFan.IsLimit.hom_ext {W X Y : C} {s : BinaryFan X Y} (h : IsLimit s) {f g : W ⟶ s.pt}
(h₁ : f ≫ s.fst = g ≫ s.fst) (h₂ : f ≫ s.snd = g ≫ s.snd) : f = g :=
h.hom_ext fun j => Discrete.recOn j fun j => WalkingPair.casesOn j h₁ h₂

/-- A binary cofan is just a cocone on a diagram indexing a coproduct. -/
abbrev BinaryCofan (X Y : C) := Cocone (pair X Y)

/-- The first inclusion of a binary cofan. -/
abbrev BinaryCofan.inl {X Y : C} (s : BinaryCofan X Y) := s.ι.app ⟨WalkingPair.left⟩

/-- The second inclusion of a binary cofan. -/
abbrev BinaryCofan.inr {X Y : C} (s : BinaryCofan X Y) := s.ι.app ⟨WalkingPair.right⟩

/-- Constructs an isomorphism of `BinaryCofan`s out of an isomorphism of the tips that commutes with
the injections. -/
def BinaryCofan.ext {A B : C} {c c' : BinaryCofan A B} (e : c.pt ≅ c'.pt)
(h₁ : c.inl ≫ e.hom = c'.inl) (h₂ : c.inr ≫ e.hom = c'.inr) : c ≅ c' :=
Cocone.ext e (fun j => by rcases j with ⟨⟨⟩⟩ <;> assumption)

@[simp]
lemma BinaryCofan.ext_hom_hom {A B : C} {c c' : BinaryCofan A B} (e : c.pt ≅ c'.pt)
(h₁ : c.inl ≫ e.hom = c'.inl) (h₂ : c.inr ≫ e.hom = c'.inr) :
(ext e h₁ h₂).hom.hom = e.hom := rfl

-- This cannot be `@[simp]` because `s.inl` is reducibly defeq to the LHS.
theorem BinaryCofan.ι_app_left {X Y : C} (s : BinaryCofan X Y) :
s.ι.app ⟨WalkingPair.left⟩ = s.inl := rfl

-- This cannot be `@[simp]` because `s.inr` is reducibly defeq to the LHS.
theorem BinaryCofan.ι_app_right {X Y : C} (s : BinaryCofan X Y) :
s.ι.app ⟨WalkingPair.right⟩ = s.inr := rfl

/-- A convenient way to show that a binary cofan is a colimit. -/
def BinaryCofan.IsColimit.mk {X Y : C} (s : BinaryCofan X Y)
(desc : ∀ {T : C} (_ : X ⟶ T) (_ : Y ⟶ T), s.pt ⟶ T)
(hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inl ≫ desc f g = f)
(hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inr ≫ desc f g = g)
(uniq :
∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T) (_ : s.inl ≫ m = f) (_ : s.inr ≫ m = g),
m = desc f g) :
IsColimit s :=
Limits.IsColimit.mk (fun t => desc (BinaryCofan.inl t) (BinaryCofan.inr t))
(by
rintro t (rfl | rfl)
· exact hd₁ _ _
· exact hd₂ _ _)
fun _ _ h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩)

theorem BinaryCofan.IsColimit.hom_ext {W X Y : C} {s : BinaryCofan X Y} (h : IsColimit s)
{f g : s.pt ⟶ W} (h₁ : s.inl ≫ f = s.inl ≫ g) (h₂ : s.inr ≫ f = s.inr ≫ g) : f = g :=
h.hom_ext fun j => Discrete.recOn j fun j => WalkingPair.casesOn j h₁ h₂

variable {X Y Z P : C}

Expand All @@ -139,47 +107,34 @@
attribute [local aesop safe cases (rule_sets := [CategoryTheory])] Eq

/-- A binary fan with vertex `P` consists of the two projections `π₁ : P ⟶ X` and `π₂ : P ⟶ Y`. -/
@[simps pt, implicit_reducible]
@[to_dual (attr := simps pt, implicit_reducible)
/-- A binary cofan with vertex `P` consists of the two inclusions `ι₁ : X ⟶ P` and`ι₂ : Y ⟶ P`. -/]
def BinaryFan.mk {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : BinaryFan X Y where
pt := P
π := { app := fun | { as := j } => match j with | left => π₁ | right => π₂ }

/-- A binary cofan with vertex `P` consists of the two inclusions `ι₁ : X ⟶ P` and `ι₂ : Y ⟶ P`. -/
@[simps pt]
def BinaryCofan.mk {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : BinaryCofan X Y where
pt := P
ι := { app := fun | { as := j } => match j with | left => ι₁ | right => ι₂ }

end

@[simp]
@[to_dual (attr := simp) mk_inl]
theorem BinaryFan.mk_fst {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : (BinaryFan.mk π₁ π₂).fst = π₁ :=
rfl

@[simp]
@[to_dual (attr := simp) mk_inr]
theorem BinaryFan.mk_snd {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : (BinaryFan.mk π₁ π₂).snd = π₂ :=
rfl

@[simp]
theorem BinaryCofan.mk_inl {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : (BinaryCofan.mk ι₁ ι₂).inl = ι₁ :=
rfl

@[simp]
theorem BinaryCofan.mk_inr {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : (BinaryCofan.mk ι₁ ι₂).inr = ι₂ :=
rfl

/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
@[to_dual /-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/]
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
Cone.ext (Iso.refl _) fun ⟨l⟩ => by cases l; repeat simp

set_option backward.defeqAttrib.useBackward true in
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
Cocone.ext (Iso.refl _) fun ⟨l⟩ => by cases l; repeat simp
Cone.ext (Iso.refl _) fun ⟨l⟩ => by cases l <;> simp

/-- This is a more convenient formulation to show that a `BinaryFan` constructed using
`BinaryFan.mk` is a limit cone.
-/
@[to_dual
/-- This is a more convenient formulation to show that a `BinaryCofan` constructed using
`BinaryCofan.mk` is a colimit cocone.
-/]
def BinaryFan.isLimitMk {W : C} {fst : W ⟶ X} {snd : W ⟶ Y} (lift : ∀ s : BinaryFan X Y, s.pt ⟶ W)
(fac_left : ∀ s : BinaryFan X Y, lift s ≫ fst = s.fst)
(fac_right : ∀ s : BinaryFan X Y, lift s ≫ snd = s.snd)
Expand All @@ -193,23 +148,6 @@
exacts [fac_left s, fac_right s]
uniq := fun s m w => uniq s m (w ⟨WalkingPair.left⟩) (w ⟨WalkingPair.right⟩) }

/-- This is a more convenient formulation to show that a `BinaryCofan` constructed using
`BinaryCofan.mk` is a colimit cocone.
-/
def BinaryCofan.isColimitMk {W : C} {inl : X ⟶ W} {inr : Y ⟶ W}
(desc : ∀ s : BinaryCofan X Y, W ⟶ s.pt)
(fac_left : ∀ s : BinaryCofan X Y, inl ≫ desc s = s.inl)
(fac_right : ∀ s : BinaryCofan X Y, inr ≫ desc s = s.inr)
(uniq :
∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt) (_ : inl ≫ m = s.inl) (_ : inr ≫ m = s.inr),
m = desc s) :
IsColimit (BinaryCofan.mk inl inr) :=
{ desc := desc
fac := fun s j => by
rcases j with ⟨⟨⟩⟩
exacts [fac_left s, fac_right s]
uniq := fun s m w => uniq s m (w ⟨WalkingPair.left⟩) (w ⟨WalkingPair.right⟩) }

/-- If `s` is a limit binary fan over `X` and `Y`, then every pair of morphisms `f : W ⟶ X` and
`g : W ⟶ Y` induces a morphism `l : W ⟶ s.pt` satisfying `l ≫ s.fst = f` and `l ≫ s.snd = g`.
-/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public import Mathlib.CategoryTheory.Limits.Shapes.Terminal
# Walking pairs

We define a category `WalkingPair`, which is the index category for a binary (co)product diagram.
A convenience method `pair X Y`, for `X, Y` objects of some category `C`, constructs the constructs
the functor from the walking pair, hitting the given objects.
A convenience method `pair X Y`, for `X, Y` objects of some category `C`, constructs the
functor from the walking pair, hitting the given objects.

## References
* [Stacks: Products of pairs](https://stacks.math.columbia.edu/tag/001R)
Expand All @@ -31,6 +31,7 @@ open CategoryTheory
namespace CategoryTheory.Limits

/-- The type of objects for the diagram indexing a binary (co)product. -/
@[to_dual_do_translate]
inductive WalkingPair : Type
| left
| right
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/CategoryTheory/Limits/Types/Coproducts.lean
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ theorem binaryCofan_isColimit_iff {X Y : Type u} (c : BinaryCofan X Y) :
exact this.elim
· rintro T _ _ m rfl rfl
ext x
simp only [TypeCat.Fun.toFun_apply, Functor.const_obj_obj, pair_obj_left, Set.mem_range,
simp only [TypeCat.Fun.toFun_apply, pair_obj_left, Set.mem_range,
comp_apply, pair_obj_right, ConcreteCategory.hom_ofHom, TypeCat.Fun.coe_mk]
split_ifs <;> exact congr_arg _ (Equiv.apply_ofInjective_symm _ ⟨_, _⟩).symm

Expand Down
10 changes: 4 additions & 6 deletions Mathlib/CategoryTheory/Limits/VanKampen.lean
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,7 @@ theorem isUniversalColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C)
simp only [pair_obj_right, Functor.const_obj_obj, Discrete.functor_obj,
Cofan.mk_pt, Cofan.mk_ι_app, Discrete.natTrans_app]
refine IsPullback.of_right ?_ ?_ (IsPullback.of_hasPullback (BinaryCofan.inr c₂) i).flip
· simp only [Functor.const_obj_obj, pair_obj_right, limit.lift_π,
PullbackCone.mk_pt, PullbackCone.mk_π_app]
· simp only [pair_obj_right, limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
exact H _
· simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, Cofan.inj]
obtain ⟨H₁⟩ := t₁'
Expand Down Expand Up @@ -640,17 +639,16 @@ theorem isVanKampenColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C)
apply BinaryCofan.IsColimit.mk _ (fun {T} f₁ f₂ ↦ Hc.desc (Cofan.mk T (Fin.cases f₁
(fun i ↦ Sigma.ι (fun (j : Fin n) ↦ (Discrete.functor F').obj ⟨j.succ⟩) _ ≫ f₂))))
· intro T f₁ f₂
simp only [Discrete.functor_obj, pair_obj_left, BinaryCofan.mk_pt, Functor.const_obj_obj,
simp only [Discrete.functor_obj, pair_obj_left, BinaryCofan.mk_pt,
BinaryCofan.mk_inl, IsColimit.fac, Cofan.mk_pt, Cofan.mk_ι_app,
Fin.cases_zero]
· intro T f₁ f₂
simp only [Discrete.functor_obj, pair_obj_right, BinaryCofan.mk_pt, Functor.const_obj_obj,
BinaryCofan.mk_inr]
simp only [Discrete.functor_obj, pair_obj_right, BinaryCofan.mk_pt, BinaryCofan.mk_inr]
ext j
simp only [colimit.ι_desc_assoc, Discrete.functor_obj, Cofan.mk_pt,
Cofan.mk_ι_app, IsColimit.fac, Fin.cases_succ]
· intro T f₁ f₂ f₃ m₁ m₂
simp only [Discrete.functor_obj_eq_as, pair_obj_left, BinaryCofan.mk_pt, const_obj_obj,
simp only [Discrete.functor_obj_eq_as, pair_obj_left, BinaryCofan.mk_pt,
BinaryCofan.mk_inl, pair_obj_right, BinaryCofan.mk_inr] at m₁ m₂ ⊢
refine Hc.uniq (Cofan.mk T (Fin.cases f₁
(fun i ↦ Sigma.ι (fun (j : Fin n) ↦ (Discrete.functor F').obj ⟨j.succ⟩) _ ≫ f₂))) _ ?_
Expand Down
Loading