Skip to content

Commit d6898ad

Browse files
committed
refactor(RelCat): use a type synonym for homs (#25593)
This improves automation and follows the new pattern for concrete categories (although `RelCat` is *not* a concrete category).
1 parent da0577a commit d6898ad

File tree

1 file changed

+40
-52
lines changed

1 file changed

+40
-52
lines changed

Mathlib/CategoryTheory/Category/RelCat.lean

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -21,89 +21,85 @@ By flipping the arguments to a relation, we construct an equivalence `opEquivale
2121
`RelCat` and its opposite.
2222
-/
2323

24+
open Rel
25+
26+
attribute [local simp] Rel.comp Rel.inv flip
27+
2428
namespace CategoryTheory
2529

2630
universe u
2731

28-
-- This file is about Lean 3 declaration "Rel".
29-
3032
/-- A type synonym for `Type u`, which carries the category instance for which
3133
morphisms are binary relations. -/
3234
def RelCat :=
3335
Type u
3436

35-
instance RelCat.inhabited : Inhabited RelCat := by unfold RelCat; infer_instance
36-
37-
/-- The category of types with binary relations as morphisms. -/
38-
instance rel : LargeCategory RelCat where
39-
Hom X Y := X → Y → Prop
40-
id _ x y := x = y
41-
comp f g x z := ∃ y, f x y ∧ g y z
37+
namespace RelCat
38+
variable {X Y Z : RelCat.{u}}
4239

40+
instance inhabited : Inhabited RelCat := by unfold RelCat; infer_instance
4341

42+
/-- The morphisms in the relation category are relations. -/
43+
structure Hom (X Y : RelCat.{u}) : Type u where
44+
/-- Build a morphism `X ⟶ Y` for `X Y : RelCat` from a relation between `X` and `Y`. -/
45+
ofRel ::
46+
/-- The underlying relation between `X` and `Y` of a morphism `X ⟶ Y` for `X Y : RelCat`. -/
47+
rel : Rel X Y
4448

45-
namespace RelCat
49+
initialize_simps_projections Hom (as_prefix rel)
4650

47-
@[ext] theorem hom_ext {X Y : RelCat} (f g : X ⟶ Y) (h : ∀ a b, f a b ↔ g a b) : f = g :=
48-
funext₂ (fun a b => propext (h a b))
51+
/-- The category of types with binary relations as morphisms. -/
52+
@[simps]
53+
instance instLargeCategory : LargeCategory RelCat where
54+
Hom := Hom
55+
id _ := .ofRel (· = ·)
56+
comp f g := .ofRel <| f.rel.comp g.rel
4957

5058
namespace Hom
5159

52-
protected theorem rel_id (X : RelCat) : 𝟙 X = (· = ·) := rfl
53-
54-
protected theorem rel_comp {X Y Z : RelCat} (f : X ⟶ Y) (g : Y ⟶ Z) : f ≫ g = Rel.comp f g := rfl
60+
@[ext] lemma ext (f g : X ⟶ Y) (h : f.rel = g.rel) : f = g := by
61+
obtain ⟨R⟩ := f; obtain ⟨S⟩ := g; congr
5562

56-
theorem rel_id_apply₂ (X : RelCat) (x y : X) : (𝟙 X) x y ↔ x = y := by
57-
rw [RelCat.Hom.rel_id]
63+
theorem rel_id_apply₂ (X : RelCat) (x y : X) : rel (𝟙 X) x y ↔ x = y := .rfl
5864

59-
theorem rel_comp_apply₂ {X Y Z : RelCat} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) (z : Z) :
60-
(f ≫ g) x z ↔ ∃ y, f x y ∧ g y z := by rfl
65+
theorem rel_comp_apply₂ (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) (z : Z) :
66+
(f ≫ g).rel x z ↔ ∃ y, f.rel x y ∧ g.rel y z := .rfl
6167

6268
end Hom
6369

6470
/-- The essentially surjective faithful embedding
6571
from the category of types and functions into the category of types and relations. -/
72+
@[simps obj map_rel]
6673
def graphFunctor : Type u ⥤ RelCat.{u} where
6774
obj X := X
68-
map f := f.graph
69-
map_id X := by
70-
ext
71-
simp [Hom.rel_id_apply₂]
72-
map_comp f g := by
73-
ext
74-
simp [Hom.rel_comp_apply₂]
75+
map f := .ofRel f.graph
76+
map_comp := by aesop (add simp [Rel.comp])
7577

76-
@[simp] theorem graphFunctor_map {X Y : Type u} (f : X ⟶ Y) (x : X) (y : Y) :
77-
graphFunctor.map f x y ↔ f x = y := f.graph_def x y
78+
@[deprecated rel_graphFunctor_map (since := "2025-06-08")]
79+
theorem graphFunctor_map {X Y : Type u} (f : X ⟶ Y) (x : X) (y : Y) :
80+
(graphFunctor.map f).rel x y ↔ f x = y := .rfl
7881

7982
instance graphFunctor_faithful : graphFunctor.Faithful where
80-
map_injective h := Function.graph_injective h
83+
map_injective h := Function.graph_injective congr(($h).rel)
8184

8285
instance graphFunctor_essSurj : graphFunctor.EssSurj :=
8386
graphFunctor.essSurj_of_surj Function.surjective_id
8487

8588
/-- A relation is an isomorphism in `RelCat` iff it is the image of an isomorphism in
8689
`Type u`. -/
8790
theorem rel_iso_iff {X Y : RelCat} (r : X ⟶ Y) :
88-
IsIso (C := RelCat) r ↔ ∃ f : (Iso (C := Type u) X Y), graphFunctor.map f.hom = r := by
91+
IsIso (C := RelCat) r ↔ ∃ f : Iso (C := Type u) X Y, graphFunctor.map f.hom = r := by
8992
constructor
9093
· intro h
91-
have h1 := congr_fun₂ h.hom_inv_id
92-
have h2 := congr_fun₂ h.inv_hom_id
94+
have h1 := congr_fun₂ congr(($h.hom_inv_id).rel)
95+
have h2 := congr_fun₂ congr(($h.inv_hom_id).rel)
9396
simp only [RelCat.Hom.rel_comp_apply₂, RelCat.Hom.rel_id_apply₂, eq_iff_iff] at h1 h2
9497
obtain ⟨f, hf⟩ := Classical.axiomOfChoice (fun a => (h1 a a).mpr rfl)
9598
obtain ⟨g, hg⟩ := Classical.axiomOfChoice (fun a => (h2 a a).mpr rfl)
9699
suffices hif : IsIso (C := Type u) f by
97100
use asIso f
98101
ext x y
99-
simp only [asIso_hom, graphFunctor_map]
100-
constructor
101-
· rintro rfl
102-
exact (hf x).1
103-
· intro hr
104-
specialize h2 (f x) y
105-
rw [← h2]
106-
use x, (hf x).2, hr
102+
exact ⟨by aesop, fun hxy ↦ (h2 (f x) y).1 ⟨x, (hf x).2, hxy⟩⟩
107103
use g
108104
constructor
109105
· ext x
@@ -121,10 +117,10 @@ open Opposite
121117
/-- The argument-swap isomorphism from `RelCat` to its opposite. -/
122118
def opFunctor : RelCat ⥤ RelCatᵒᵖ where
123119
obj X := op X
124-
map {_ _} r := op (fun y x => r x y)
120+
map {_ _} r := .op <| .ofRel r.rel.inv
125121
map_id X := by
126122
congr
127-
simp only [unop_op, RelCat.Hom.rel_id]
123+
simp only [unop_op, RelCat.rel_id]
128124
ext x y
129125
exact Eq.comm
130126
map_comp {X Y Z} f g := by
@@ -137,15 +133,7 @@ def opFunctor : RelCat ⥤ RelCatᵒᵖ where
137133
/-- The other direction of `opFunctor`. -/
138134
def unopFunctor : RelCatᵒᵖ ⥤ RelCat where
139135
obj X := unop X
140-
map {_ _} r x y := unop r y x
141-
map_id X := by
142-
ext x y
143-
exact Eq.comm
144-
map_comp {X Y Z} f g := by
145-
unfold Category.opposite
146-
ext x y
147-
apply exists_congr
148-
exact fun a => And.comm
136+
map {_ _} r := .ofRel r.unop.rel.inv
149137

150138
@[simp] theorem opFunctor_comp_unopFunctor_eq :
151139
Functor.comp opFunctor unopFunctor = Functor.id _ := rfl
@@ -156,7 +144,7 @@ def unopFunctor : RelCatᵒᵖ ⥤ RelCat where
156144
/-- `RelCat` is self-dual: The map that swaps the argument order of a
157145
relation induces an equivalence between `RelCat` and its opposite. -/
158146
@[simps]
159-
def opEquivalence : Equivalence RelCat RelCatᵒᵖ where
147+
def opEquivalence : RelCat RelCatᵒᵖ where
160148
functor := opFunctor
161149
inverse := unopFunctor
162150
unitIso := Iso.refl _

0 commit comments

Comments
 (0)