Skip to content

Commit 237ebdd

Browse files
Regular.v: categories in which one can do diagram chasing
Co-authored-by: Thomas Wilskow Thorbjørnsen <thomas.w.thorbjornsen@gmail.com>
1 parent d69ac7f commit 237ebdd

File tree

2 files changed

+375
-5
lines changed

2 files changed

+375
-5
lines changed

theories/WildCat/Core.v

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,125 @@ Definition cat_comp2 {A} `{Is1Cat A} {a b c : A}
150150

151151
Notation "q $@@ p" := (cat_comp2 q p).
152152

153-
(** Monomorphisms and epimorphisms. *)
153+
(** Epimorphisms and monomorphisms. *)
154154

155-
Definition Monic {A} `{Is1Cat A} {b c: A} (f : b $-> c)
156-
:= forall a (g h : a $-> b), f $o g $== f $o h -> g $== h.
155+
Class Epic {A} `{Is1Cat A} {a b : A} (f : a $-> b)
156+
:= isepic : forall {c} (g h : b $-> c), g $o f $== h $o f -> g $== h.
157157

158-
Definition Epic {A} `{Is1Cat A} {a b : A} (f : a $-> b)
159-
:= forall c (g h : b $-> c), g $o f $== h $o f -> g $== h.
158+
Arguments isepic {A}%_type_scope {IsGraph0 Is2Graph0 Is01Cat0 H a b} f {Epic c} g h _.
159+
160+
Section Epimorphisms.
161+
162+
Context {A : Type} `{Is1Cat A}.
163+
164+
#[export]
165+
Instance epic_id (P : A) : Epic (Id P).
166+
Proof.
167+
intros B b b' h.
168+
exact ((cat_idr _)^$ $@ h $@ cat_idr _).
169+
Defined.
170+
171+
Definition epic_homotopic {P P'} (f g : P $-> P') `{!Epic f} (h : f $== g)
172+
: Epic g.
173+
Proof.
174+
intros Q x x' h'.
175+
apply (isepic f).
176+
exact ((x $@L h) $@ h' $@ (x' $@L h^$)).
177+
Defined.
178+
179+
#[export]
180+
Instance epic_compose {P P' P'' : A} (f : P $-> P') (g : P' $-> P'')
181+
`{!Epic f} `{!Epic g}
182+
: Epic (g $o f).
183+
Proof.
184+
intros Q x x' h.
185+
apply (isepic g).
186+
apply (isepic f).
187+
exact ((cat_assoc f g x) $@ h $@ (cat_assoc_opp f g x')).
188+
Defined.
189+
190+
Definition epic_cancel {P P' P'' : A} (f : P $-> P') (g : P' $-> P'')
191+
`{!Epic (g $o f)}
192+
: Epic g.
193+
Proof.
194+
intros Q x x' h.
195+
rapply isepic.
196+
exact ((cat_assoc_opp f g x) $@ (h $@R f) $@ (cat_assoc f g x')).
197+
Defined.
198+
199+
Definition Epi (P' P : A) := { e : P' $-> P & Epic e }.
200+
201+
Definition hom_epi {P' P} (e : Epi P' P) := pr1 e : P' $-> P.
202+
Coercion hom_epi : Epi >-> Hom.
203+
204+
#[export]
205+
Instance epic_epi {P' P} (e : Epi P' P) : Epic e := pr2 e.
206+
207+
Definition id_epi P : Epi P P := (Id P; epic_id P).
208+
209+
End Epimorphisms.
210+
211+
Notation "P' $->> P" := (Epi P' P) (at level 99).
212+
213+
(** Monomorphisms could be defined as epimorphisms in the opposite category, which would allow us to reuse the proofs below. We'd have to move the material on epis and monos to a separate file. *)
214+
215+
Class Monic {A} `{Is1Cat A} {b c: A} (f : b $-> c)
216+
:= ismonic : forall {a} (g h : a $-> b), f $o g $== f $o h -> g $== h.
217+
218+
Arguments ismonic {A}%_type_scope {IsGraph0 Is2Graph0 Is01Cat0 H b c} f {Monic a} g h _.
219+
220+
Section Monomorphisms.
221+
222+
Context {A : Type} `{Is1Cat A}.
223+
224+
#[export]
225+
Instance monic_id (P : A) : Monic (Id P).
226+
Proof.
227+
intros B b b' h.
228+
exact ((cat_idl _)^$ $@ h $@ cat_idl _).
229+
Defined.
230+
231+
Definition monic_homotopic {P P'} (f g : P $-> P') `{!Monic f} (h : f $== g)
232+
: Monic g.
233+
Proof.
234+
intros Q x x' h'.
235+
apply (ismonic f).
236+
exact ((h $@R x) $@ h' $@ (h^$ $@R x')).
237+
Defined.
238+
239+
#[export]
240+
Instance monic_compose {P P' P'' : A} (f : P $-> P') (g : P' $-> P'')
241+
`{!Monic f} `{!Monic g}
242+
: Monic (g $o f).
243+
Proof.
244+
intros Q x x' h.
245+
apply (ismonic f).
246+
apply (ismonic g).
247+
exact ((cat_assoc_opp x f g) $@ h $@ (cat_assoc x' f g)).
248+
Defined.
249+
250+
Definition monic_cancel {P P' P'' : A} (f : P $-> P') (g : P' $-> P'')
251+
`{!Monic (g $o f)}
252+
: Monic f.
253+
Proof.
254+
intros Q x x' h.
255+
rapply ismonic.
256+
exact ((cat_assoc x f g) $@ (g $@L h) $@ (cat_assoc_opp x' f g)).
257+
Defined.
258+
259+
Definition Mono (P' P : A) := { e : P' $-> P & Monic e }.
260+
261+
Definition hom_mono {P' P} (m : Mono P' P) := pr1 m : P' $-> P.
262+
Coercion hom_mono : Mono >-> Hom.
263+
264+
#[export]
265+
Instance monic_mono {P' P} (e : Mono P' P) : Monic e := pr2 e.
266+
267+
Definition id_mono P : Mono P P := (Id P; monic_id P).
268+
269+
End Monomorphisms.
270+
271+
Notation "P' $>-> P" := (Mono P' P) (at level 99).
160272

161273
(** Section might be a clearer name but it's better to avoid confusion with Coq keywords. *)
162274

theories/WildCat/Regular.v

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
Require Import WildCat.SetoidRewrite.
2+
Require Import Basics.Overture Basics.Tactics Basics.Equivalences.
3+
Require Import WildCat.Core WildCat.Equiv WildCat.EquivGpd WildCat.PointedCat
4+
WildCat.Yoneda WildCat.Graph WildCat.ZeroGroupoid WildCat.Pullbacks
5+
WildCat.AbEnriched WildCat.FunctorCat.
6+
7+
(** * A variant of regular categories in which one can do diagram chasing *)
8+
9+
(** ** Definition *)
10+
11+
(** We study a type of wild category that is similar to a regular category. We assume that the category has all pullbacks and that epimorphisms are preserved by pullbacks. Note that we are dealing with the ordinary epimorphisms rather than the effective epimorphisms. This is simply because they are easier to formalize. Also note that we don't assume that kernel pairs have co-equalizers. *)
12+
13+
Class IsRegular (A : Type) `{Is1Cat A} := {
14+
haspullbacks :: HasPullbacks A;
15+
stable_epic :: forall {a b c} (f : a $-> c) (g : b $-> c) {ep : Epic f},
16+
Epic (cat_pb_pr2 (CatPullback:=haspullbacks a b c f g));
17+
}.
18+
19+
(** ** Diagram chasing in a regular category *)
20+
21+
(** One can do a certain amount of diagram chasing in a regular category. We'll see below that more can be done with an enrichment over abelian groups. *)
22+
23+
Section Regular.
24+
25+
Context {A : Type} `{IsRegular A}.
26+
27+
(** A generalized element of [B] with domain [P]. *)
28+
Definition elt (P B : A) := P $-> B.
29+
30+
(** A generalized lift of a generalized element. *)
31+
Definition Lift {B C P : A} (c : elt P C) (f : B $-> C)
32+
:= { P' : A & { e : P' $->> P & { b : elt P' B & f $o b $== c $o e }}}.
33+
34+
Definition epic_elt_lift {B C : A} (f : B $-> C)
35+
(lift : forall P (c : elt P C), Lift c f)
36+
: Epic f.
37+
Proof.
38+
specialize (lift C (Id C)).
39+
destruct lift as [P' [[e ep] [b h]]].
40+
cbn in h.
41+
pose proof (h' := h $@ cat_idl e); clear h.
42+
rapply (epic_cancel b f).
43+
apply (epic_homotopic _ _ h'^$).
44+
Defined.
45+
46+
(** For the converse, we need the pullback epi of an epi. *)
47+
Definition cat_pb_pr2_epi {a b c : A} (f : a $->> c) (g : b $-> c)
48+
: cat_pb f g $->> b.
49+
Proof.
50+
exists (cat_pb_pr2 (f:=f) (g:=g)).
51+
exact _.
52+
Defined.
53+
54+
Definition elt_lift_epic {B C : A} (f : B $-> C) {ef : Epic f}
55+
{P} (c : elt P C)
56+
: Lift c f.
57+
Proof.
58+
exists (cat_pb f c).
59+
exists (cat_pb_pr2_epi (f; ef) c).
60+
exists (cat_pb_pr1 (f:=f) (g:=c)).
61+
apply cat_pb_glue.
62+
Defined.
63+
64+
(** The definition of [Monic] already implicitly involves generalized elements. So this result isn't really needed, but might become more useful if we have a separate notation for applying a function to an [elt]. *)
65+
Definition monic_via_elt {B C : A} (f : B $-> C)
66+
(m : forall P (b b' : elt P B), f $o b $== f $o b' -> b $== b')
67+
: Monic f
68+
:= m.
69+
70+
(** To lift [b] along [f], it's enough to lift a pullback of [b] along an epi. *)
71+
Definition lift_helper {B C P P' : A} {b : elt P C} {f : B $-> C}
72+
(e : P' $->> P) (l : Lift (b $o e) f)
73+
: Lift b f.
74+
Proof.
75+
destruct l as [P'' [[e' ep] [b' h]]].
76+
exists P''.
77+
exists (e $o e'; epic_compose _ _).
78+
exists b'.
79+
rhs' apply (cat_assoc_opp e' e b).
80+
exact h.
81+
Defined.
82+
83+
End Regular.
84+
85+
(** ** Regular categories enriched in abelian groups *)
86+
87+
Class IsAbRegular (A : Type) `{Is1Cat A} := {
88+
isregular_abregular :: IsRegular A;
89+
isabenriched_abregular :: IsAbEnriched A;
90+
}.
91+
92+
Section AbRegular.
93+
94+
Context {A : Type} `{IsAbRegular A}.
95+
96+
Open Scope mc_add_scope.
97+
98+
(** We *define* exactness using generalized elements, which avoids needing to assume the existence of kernels, cokernels or images (or even define them). In a category with kernels and images, you can show that this implies that the natural map from the image to the kernel is monic and epic, so in a nice enough category it is an isomorphism. *)
99+
100+
Class CatIsAbExact {B C D : A} (f : B $-> C) (g : C $-> D) :=
101+
{
102+
isabcomplex : g $o f $== 0;
103+
isabexact : forall P (b : elt P C), g $o b $== 0 -> Lift b f;
104+
}.
105+
106+
(** If a sequence [B $-> C] and [0 : C $-> D] is exact, then [B $-> C] is epi. *)
107+
Definition epic_isabexact_nil_morphism {B C D : A} (f : B $-> C)
108+
`{!CatIsAbExact f (0 : C $-> D)}
109+
: Epic f.
110+
Proof.
111+
apply epic_elt_lift.
112+
intros P c.
113+
apply isabexact.
114+
apply precomp_zero.
115+
Defined.
116+
117+
(** If [B $-> C] is epi, then the sequence [B $-> C] and [0 : C$-> D] is exact. *)
118+
Definition isabexact_nil_morphism_epic {B C D : A} (f : B $->> C)
119+
: CatIsAbExact f (0 : C $-> D).
120+
Proof.
121+
refine {| isabcomplex := precomp_zero _ |}.
122+
intros P c h.
123+
rapply elt_lift_epic.
124+
Defined.
125+
126+
(** This is a variant of [ismonic], where the RHS is [0]. *)
127+
Definition ismonic' {B C : A} (f : B $-> C) `{!Monic f}
128+
{P} (b : elt P B) (h : f $o b $== 0)
129+
: b $== 0.
130+
Proof.
131+
apply (ismonic f).
132+
lhs' exact h.
133+
symmetry.
134+
apply postcomp_zero.
135+
Defined.
136+
137+
(** Monics can be detected if only the zero map is mapped to zero by post composition. *)
138+
Definition monic_via_elt_isemb_ab {B C : A} (f : B $-> C)
139+
(h : forall P : A, forall b : elt P B, f $o b $== 0 -> b $== 0)
140+
: Monic f.
141+
Proof.
142+
apply monic_via_elt; intros P b' b'' h'.
143+
apply inverse_r_homotopy_0gpd in h'.
144+
apply (fun x => postcomp_op_inv f b' b'' $@ x) in h'.
145+
apply moveL_0M_0gpd.
146+
exact (h P (b' - b'') h').
147+
Defined.
148+
149+
(** If [C $-> D] is mono, then the sequence [0 : B $-> C] and [C $-> D] is exact. *)
150+
Definition isabexact_nil_morphism_monic {B C D : A} (f : C $>-> D)
151+
: CatIsAbExact (0 : B $-> C) f.
152+
Proof.
153+
refine {| isabcomplex := postcomp_zero _ |}.
154+
intros P b h.
155+
exists P; exists (id_epi P); exists 0.
156+
lhs' apply postcomp_zero.
157+
rhs' apply cat_idr.
158+
exact (ismonic' f b h)^$.
159+
Defined.
160+
161+
(** If the sequence [0 : B $-> C] and [C $-> D] is exact, then [C $-> D] is a mono. *)
162+
Definition monic_isabexact_nil_morphism {B C D : A} (f : C $-> D)
163+
`{!CatIsAbExact (0 : B $-> C) f}
164+
: Monic f.
165+
Proof.
166+
apply monic_via_elt.
167+
intros P b b' h.
168+
apply inverse_r_homotopy_0gpd in h.
169+
rewrite <- postcomp_op_inv in h.
170+
apply isabexact in h.
171+
destruct h as [P' [e [b'' h]]].
172+
apply moveL_0M_0gpd.
173+
apply (isepic e).
174+
rhs' apply precomp_zero.
175+
rhs_V' apply (precomp_zero b'').
176+
exact h^$.
177+
Defined.
178+
179+
End AbRegular.
180+
181+
(** ** Tactics *)
182+
183+
(** The [fix_left] tactic is the key to smooth diagram chasing in an [IsAbRegular] category. Given [lift : Lift ? ?]; we extract the lifted element using the provided name [d] and the proof it is a lift using the name [l]. Then we update all other generalized elements to have the same domain as [d]. We could also have a limited version of this tactic for an [IsRegular] category. *)
184+
Ltac fix_lift lift d l :=
185+
let P2 := fresh "P" in
186+
let e := fresh "e" in
187+
let ee := fresh "ee" in
188+
destruct lift as [P2 [[e ee] [d l]]];
189+
unfold hom_epi, ".1" in l;
190+
match type of e with
191+
| P2 $-> ?P =>
192+
(* Adjust everything involving the domain [P] to have domain [P2]: *)
193+
repeat match goal with
194+
| [ |- @Lift _ _ _ _ _ _ _ P ?c ?f ] => apply (lift_helper (e; ee)); unfold hom_epi, ".1"
195+
| [ |- @GpdHom (@Hom _ _ P _) _ _ _ _ _ ] => apply ee
196+
| [ |- @GpdHom (@elt _ _ P _) _ _ _ _ _ ] => apply ee
197+
| [ h : @GpdHom (@Hom _ _ P _) _ _ _ _ _ |- _ ] =>
198+
apply (fun w => cat_prewhisker w e) in h
199+
end;
200+
clear ee;
201+
(* Reassociate all homotopies so that [e] is right against the map to its left: *)
202+
rewrite ? (cat_assoc e);
203+
repeat match goal with
204+
| [ h : @GpdHom (@Hom _ _ P2 _) _ _ _ _ _ |- _ ] =>
205+
rewrite ! (cat_assoc e) in h
206+
| [ h : @GpdHom (@Hom _ _ P2 _) _ _ _ _ _ |- _ ] =>
207+
rewrite ! (precomp_op_inv e) in h
208+
| [ h : @GpdHom (@Hom _ _ P2 _) _ _ _ _ _ |- _ ] =>
209+
rewrite ! (precomp_op e) in h
210+
| [ h : @GpdHom (@Hom _ _ P2 _) _ _ _ _ _ |- _ ] =>
211+
rewrite ! (precomp_inv e) in h
212+
end;
213+
(* At this point, all generalized elements [c] with domain [P] should only appear in the form [c $o e], so by generalizing [c $o e] we can replace them with elements with domain [P2]. *)
214+
repeat match goal with
215+
| [ c : elt P ?C |- _ ] =>
216+
let tmp := fresh in
217+
set (tmp := c $o e : elt P2 _) in *; clearbody tmp; clear c; rename tmp into c
218+
end;
219+
(* We may also have expressions of the form [0 $o e], so we replace those with [0]. *)
220+
rewrite ? (precomp_zero e) in *;
221+
(* Now we can get rid of [e] and [P]. Add [try] before these two lines when debugging. *)
222+
clear e P;
223+
rename P2 into P
224+
end.
225+
226+
(** Ideas for making the above tactic faster:
227+
- In localized tests, defining and using things like
228+
[pose (cp := fun c f g w => cat_prewhisker (c:=c) (f:=f) (g:=g) w e).]
229+
made things faster, maybe because typeclass inference of the wild category structure didn't need to be repeated. But when done here, the overall speed does not improve.
230+
- In the last clause of the first [repeat match], we could add "revert h". Then instead of the second [repeat match] we would just need to do rewriting in the goal, without scanning the context for appropriate terms, using something like:
231+
[repeat progress rewrite ? (cat_assoc e), ? (precomp_op_inv e), ? (precomp_op e), ? (precomp_inv e).]
232+
For this to work, we need to extend setoid rewriting to handle [->].
233+
- Alternatively, in the second [repeat match], we could make the matches more specific to ensure that the lemmas we try apply to the situation.
234+
*)
235+
236+
Ltac elt_lift_epic f a b l := fix_lift (elt_lift_epic f a) b l.
237+
238+
Tactic Notation "elt_lift_exact" constr(f) constr(g) constr(a) ident(b) ident(l) :=
239+
let lift := fresh in
240+
unshelve epose proof (lift := isabexact (f:=f) (g:=g) _ a _);
241+
only 2: fix_lift lift b l.
242+
243+
(** This allows us to insert a tactic [tac] before [fix_lift] is called. Typically this is used to clear unneeded hypotheses from the context, which speeds up [fix_lift]. *)
244+
Tactic Notation "elt_lift_exact" constr(f) constr(g) constr(a) ident(b) ident(l) "using" tactic3(tac) :=
245+
let lift := fresh in
246+
unshelve epose proof (lift := isabexact (f:=f) (g:=g) _ a _);
247+
only 2: (tac; fix_lift lift b l).
248+
249+
(** Given a homotopy [h : a $o b = a' $o b'], use associativity to change [a $o (b $o c)] to [a' $o (b' $o c)]. *)
250+
Ltac rewrite_with_assoc h :=
251+
rewrite (cat_assoc_opp _ _ _ $@ cat_prewhisker h _ $@ cat_assoc _ _ _).
252+
253+
Ltac rewrite_with_assoc_opp h :=
254+
rewrite (cat_assoc _ _ _ $@ cat_postwhisker _ h $@ cat_assoc_opp _ _ _).
255+
256+
Ltac provide_lift a :=
257+
refine (_; id_epi _; a; _);
258+
try rhs' napply cat_idr.

0 commit comments

Comments
 (0)