494e7585a1fe2bc5143ae2119918785cf0b5bd4d
[coq-categories.git] / src / MonoidalCategories_ch7_8.v
1 Generalizable All Variables.
2 Require Import Preamble.
3 Require Import Categories_ch1_3.
4 Require Import Functors_ch1_4.
5 Require Import Isomorphisms_ch1_5.
6 Require Import ProductCategories_ch1_6_1.
7 Require Import InitialTerminal_ch2_2.
8 Require Import Subcategories_ch7_1.
9 Require Import NaturalTransformations_ch7_4.
10 Require Import NaturalIsomorphisms_ch7_5.
11 Require Import Coherence_ch7_8.
12
13 (******************************************************************************)
14 (* Chapter 7.8: (Pre)Monoidal Categories                                      *)
15 (******************************************************************************)
16
17 Class BinoidalCat
18 `( C                  :  Category                               )
19 ( bin_obj'            :  C -> C -> C                            ) :=
20 { bin_obj             := bin_obj' where "a ⊗ b" := (bin_obj a b)
21 ; bin_first           :  forall a:C, Functor C C (fun x => x⊗a)
22 ; bin_second          :  forall a:C, Functor C C (fun x => a⊗x)
23 ; bin_c               := C
24 }.
25 Coercion bin_c : BinoidalCat >-> Category.
26 Notation "a ⊗ b"  := (@bin_obj _ _ _ _ _ a b)                              : category_scope.
27 Notation "C ⋊ f"  := (@fmor _ _ _ _ _ _ _ (@bin_second _ _ _ _ _ C) _ _ f) : category_scope.
28 Notation "g ⋉ C"  := (@fmor _ _ _ _ _ _ _ (@bin_first _ _ _ _ _ C) _ _ g)  : category_scope.
29 Notation "C ⋊ -"  := (@bin_second _ _ _ _ _ C)                             : category_scope.
30 Notation "- ⋉ C"  := (@bin_first _ _ _ _ _ C)                              : category_scope.
31
32 Class CentralMorphism `{BinoidalCat}`(f:a~>b) : Prop := 
33 { centralmor_first  : forall `(g:c~>d), (f ⋉ _ >>> _ ⋊ g) ~~ (_ ⋊ g >>> f ⋉ _)
34 ; centralmor_second : forall `(g:c~>d), (g ⋉ _ >>> _ ⋊ f) ~~ (_ ⋊ f >>> g ⋉ _)
35 }.
36
37 (* the central morphisms of a category constitute a subcategory *)
38 Definition Center `(bc:BinoidalCat) : SubCategory bc (fun _ => True) (fun _ _ _ _ f => CentralMorphism f).
39   apply Build_SubCategory; intros; apply Build_CentralMorphism; intros.
40   abstract (setoid_rewrite (fmor_preserves_id(bin_first c));
41               setoid_rewrite (fmor_preserves_id(bin_first d));
42               setoid_rewrite left_identity; setoid_rewrite right_identity; reflexivity).
43   abstract (setoid_rewrite (fmor_preserves_id(bin_second c));
44               setoid_rewrite (fmor_preserves_id(bin_second d));
45               setoid_rewrite left_identity; setoid_rewrite right_identity; reflexivity).
46   abstract (setoid_rewrite <- (fmor_preserves_comp(bin_first c0));
47               setoid_rewrite associativity;
48               setoid_rewrite centralmor_first;
49               setoid_rewrite <- associativity;
50               setoid_rewrite centralmor_first;
51               setoid_rewrite associativity;
52               setoid_rewrite <- (fmor_preserves_comp(bin_first d));
53               reflexivity).
54   abstract (setoid_rewrite <- (fmor_preserves_comp(bin_second d));
55               setoid_rewrite <- associativity;
56               setoid_rewrite centralmor_second;
57               setoid_rewrite associativity;
58               setoid_rewrite centralmor_second;
59               setoid_rewrite <- associativity;
60               setoid_rewrite <- (fmor_preserves_comp(bin_second c0));
61               reflexivity).
62   Qed.
63
64 Class CommutativeCat `(BinoidalCat) :=
65 { commutative_central  :  forall `(f:a~>b), CentralMorphism f
66 ; commutative_morprod  := fun `(f:a~>b)`(g:a~>b) => f ⋉ _ >>> _ ⋊ g
67 }.
68 Notation "f × g"    := (commutative_morprod f g).
69
70 Section BinoidalCat_from_Bifunctor.
71   Context `{C:Category}{Fobj}(F:Functor (C ×× C) C Fobj).
72   Definition BinoidalCat_from_Bifunctor_first (a:C) : Functor C C (fun b => Fobj (pair_obj b a)).
73   apply Build_Functor with (fmor:=(fun a0 b (f:a0~~{C}~~>b) =>
74     @fmor _ _ _ _ _ _ _ F (pair_obj a0 a) (pair_obj b a) (pair_mor (pair_obj a0 a) (pair_obj b a) f (id a)))); intros; simpl;
75     [ abstract (set (fmor_respects(F)) as q; apply q; split; simpl; auto)
76     | abstract (set (fmor_preserves_id(F)) as q; apply q)
77     | abstract (etransitivity; 
78       [ set (@fmor_preserves_comp _ _ _ _ _ _ _ F) as q; apply q
79       | set (fmor_respects(F)) as q; apply q ];
80       split; simpl; auto) ].
81   Defined.
82   Definition BinoidalCat_from_Bifunctor_second (a:C) : Functor C C (fun b => Fobj (pair_obj a b)).
83   apply Build_Functor with (fmor:=(fun a0 b (f:a0~~{C}~~>b) =>
84     @fmor _ _ _ _ _ _ _ F (pair_obj a a0) (pair_obj a b) (pair_mor (pair_obj a a0) (pair_obj a b) (id a) f))); intros;
85     [ abstract (set (fmor_respects(F)) as q; apply q; split; simpl; auto)
86     | abstract (set (fmor_preserves_id(F)) as q; apply q)
87     | abstract (etransitivity; 
88       [ set (@fmor_preserves_comp _ _ _ _ _ _ _ F) as q; apply q
89       | set (fmor_respects(F)) as q; apply q ];
90       split; simpl; auto) ].
91   Defined.
92
93   Definition BinoidalCat_from_Bifunctor : BinoidalCat C (fun a b => Fobj (pair_obj a b)).
94    refine {| bin_first  := BinoidalCat_from_Bifunctor_first
95            ; bin_second := BinoidalCat_from_Bifunctor_second
96           |}.
97    Defined.
98
99   (*
100   Lemma Bifunctors_Create_Commutative_Binoidal_Categories : CommutativeCat (BinoidalCat_from_Bifunctor F).
101   abstract (intros; apply Build_CommutativeCat; intros; apply Build_CentralMorphism; intros; simpl; (
102     etransitivity; [ apply (fmor_preserves_comp(F)) | idtac ]; symmetry;
103     etransitivity; [ apply (fmor_preserves_comp(F)) | idtac ];
104     apply (fmor_respects(F));
105     split;
106       [ etransitivity; [ apply left_identity | symmetry; apply right_identity ]
107       | etransitivity; [ apply right_identity | symmetry; apply left_identity ] ])).
108   Defined.
109   *)
110 End BinoidalCat_from_Bifunctor.
111
112 (* not in Awodey *)
113 Class PreMonoidalCat `(bc:BinoidalCat(C:=C))(I:C) :=
114 { pmon_I          := I
115 ; pmon_bin        := bc
116 ; pmon_cat        := C
117 ; pmon_assoc      : forall a b, (bin_second a >>>> bin_first b) <~~~> (bin_first b >>>> bin_second a)
118 ; pmon_cancelr    :                               (bin_first I) <~~~> functor_id C
119 ; pmon_cancell    :                              (bin_second I) <~~~> functor_id C
120 ; pmon_pentagon   : Pentagon (fun a b c f => f ⋉ c) (fun a b c f => c ⋊ f) (fun a b c => #((pmon_assoc a c) b))
121 ; pmon_triangle   : Triangle (fun a b c f => f ⋉ c) (fun a b c f => c ⋊ f) (fun a b c => #((pmon_assoc a c) b))
122                              (fun a => #(pmon_cancell a)) (fun a => #(pmon_cancelr a))
123 ; pmon_assoc_rr   :  forall a b, (bin_first  (a⊗b)) <~~~> (bin_first  a >>>> bin_first  b)
124 ; pmon_assoc_ll   :  forall a b, (bin_second (a⊗b)) <~~~> (bin_second b >>>> bin_second a)
125 ; pmon_coherent_r :  forall a c d:C,  #(pmon_assoc_rr c d a) ~~ #(pmon_assoc a d c)⁻¹
126 ; pmon_coherent_l :  forall a c d:C,  #(pmon_assoc_ll c a d) ~~ #(pmon_assoc c d a)
127 }.
128 (*
129  * Premonoidal categories actually have three associators (the "f"
130  * indicates the position in which the operation is natural:
131  *
132  *  assoc    : (A ⋊ f) ⋉ C <->  A ⋊ (f ⋉  C)
133  *  assoc_rr : (f ⋉ B) ⋉ C <->  f ⋉ (B  ⊗ C)
134  *  assoc_ll : (A ⋊ B) ⋊ f <-> (A ⊗  B) ⋊ f
135  *
136  * Fortunately, in a monoidal category these are all the same natural
137  * isomorphism (and in any case -- monoidal or not -- the objects in
138  * the left column are all the same and the objects in the right
139  * column are all the same).  This formalization assumes that is the
140  * case even for premonoidal categories with non-central maps, in
141  * order to keep the complexity manageable.  I don't know much about
142  * the consequences of having them and letting them be different; you
143  * might need extra versions of the triangle/pentagon diagrams.
144  *)
145
146 Implicit Arguments pmon_cancell [ Ob Hom C bin_obj' bc I ].
147 Implicit Arguments pmon_cancelr [ Ob Hom C bin_obj' bc I ].
148 Implicit Arguments pmon_assoc   [ Ob Hom C bin_obj' bc I ].
149 Coercion pmon_bin : PreMonoidalCat >-> BinoidalCat.
150
151 (* this turns out to be Exercise VII.1.1 from Mac Lane's CWM *)
152 Lemma MacLane_ex_VII_1_1 `{mn:PreMonoidalCat(I:=EI)} a b
153   : #((pmon_cancelr mn) (a ⊗ b)) ~~ #((pmon_assoc mn a EI) b) >>> (a ⋊-) \ #((pmon_cancelr mn) b).
154   set (pmon_pentagon EI EI a b) as penta. unfold pmon_pentagon in penta.
155   set (pmon_triangle a b) as tria. unfold pmon_triangle in tria.
156   apply (fmor_respects(bin_second EI)) in tria.
157   set (@fmor_preserves_comp) as fpc.
158   setoid_rewrite <- fpc in tria.
159   set (ni_commutes (pmon_assoc mn a b)) as xx.
160   (* FIXME *)
161   Admitted.
162
163 (* Formalized Definition 3.10 *)
164 Class PreMonoidalFunctor
165 `(PM1:PreMonoidalCat(C:=C1)(I:=I1))
166 `(PM2:PreMonoidalCat(C:=C2)(I:=I2))
167  (fobj : C1 -> C2          ) :=
168 { mf_F                :> Functor C1 C2 fobj
169 ; mf_preserves_i      :  mf_F I1 ≅ I2
170 ; mf_preserves_first  :  forall a,   bin_first a >>>> mf_F  <~~~>  mf_F >>>> bin_first  (mf_F a)
171 ; mf_preserves_second :  forall a,  bin_second a >>>> mf_F  <~~~>  mf_F >>>> bin_second (mf_F a)
172 ; mf_preserves_center :  forall `(f:a~>b), CentralMorphism f -> CentralMorphism (mf_F \ f)
173 }.
174 Coercion mf_F : PreMonoidalFunctor >-> Functor.
175
176 (*******************************************************************************)
177 (* Braided and Symmetric Categories                                            *)
178
179 Class BraidedCat `(mc:PreMonoidalCat) :=
180 { br_swap      :  forall a b,   a⊗b ≅ b⊗a
181 ; triangleb    :  forall a:C,     #(pmon_cancelr mc a) ~~ #(br_swap a (pmon_I(PreMonoidalCat:=mc))) >>> #(pmon_cancell mc a)
182 ; hexagon1     :  forall {a b c}, #(pmon_assoc mc _ _ _) >>> #(br_swap a _) >>> #(pmon_assoc mc _ _ _)
183                                   ~~ #(br_swap _ _) ⋉ c >>> #(pmon_assoc mc _ _ _) >>> b ⋊ #(br_swap _ _)
184 ; hexagon2     :  forall {a b c}, #(pmon_assoc mc _ _ _)⁻¹ >>> #(br_swap _ c) >>> #(pmon_assoc mc _ _ _)⁻¹
185                                   ~~ a ⋊ #(br_swap _ _) >>> #(pmon_assoc mc _ _ _)⁻¹ >>> #(br_swap _ _) ⋉ b
186 }.
187
188 Class SymmetricCat `(bc:BraidedCat) :=
189 { symcat_swap  :  forall a b:C, #((br_swap(BraidedCat:=bc)) a b) ~~ #(br_swap _ _)⁻¹
190 }.
191
192 Class DiagonalCat `(BinoidalCat) :=
193 {  copy         :  forall a, a ~> (a⊗a)
194 (* copy >> swap == copy  -- only necessary for non-cartesian braided diagonal categories *)
195 }.
196
197 (* Definition 7.23 *)
198 Class MonoidalCat `{C:Category}{Fobj:prod_obj C C -> C}{F:Functor (C ×× C) C Fobj}(I:C) :=
199 { mon_f         := F
200 ; mon_i         := I
201 ; mon_c         := C
202 (*; mon_bin       := BinoidalCat_from_Bifunctor mon_f*)
203 ; mon_first     := fun a b c (f:a~>b) => F \ pair_mor (pair_obj a c) (pair_obj b c) f (id c)
204 ; mon_second    := fun a b c (f:a~>b) => F \ pair_mor (pair_obj c a) (pair_obj c b) (id c) f
205 ; mon_cancelr   :  (func_rlecnac I >>>> F) <~~~> functor_id C
206 ; mon_cancell   :  (func_llecnac I >>>> F) <~~~> functor_id C
207 ; mon_assoc     :  ((F **** (functor_id C)) >>>> F) <~~~> func_cossa >>>> ((((functor_id C) **** F) >>>> F))
208 ; mon_pentagon  :  Pentagon mon_first mon_second (fun a b c => #(mon_assoc (pair_obj (pair_obj a b) c)))
209 ; mon_triangle  :  Triangle mon_first mon_second (fun a b c => #(mon_assoc (pair_obj (pair_obj a b) c)))
210                                                  (fun a => #(mon_cancell a)) (fun a => #(mon_cancelr a))
211 }.
212
213 (* FIXME: show that the endofunctors on any given category form a monoidal category *)
214
215 (* Coq manual on coercions: ... only the oldest one is valid and the
216  * others are ignored. So the order of declaration of coercions is
217  * important. *)
218 Coercion mon_c   : MonoidalCat >-> Category.
219 (*Coercion mon_bin : MonoidalCat >-> BinoidalCat.*)
220 Coercion mon_f   : MonoidalCat >-> Functor.
221 Implicit Arguments mon_f [Ob Hom C Fobj F I].
222 Implicit Arguments mon_i [Ob Hom C Fobj F I].
223 Implicit Arguments mon_c [Ob Hom C Fobj F I].
224 (*Implicit Arguments mon_bin [Ob Hom C Fobj F I].*)
225 Implicit Arguments MonoidalCat [Ob Hom ].
226
227 Section MonoidalCat_is_PreMonoidal.
228   Context `(M:MonoidalCat).
229   Definition mon_bin_M := BinoidalCat_from_Bifunctor (mon_f M).
230   Existing Instance mon_bin_M.
231   Lemma mon_pmon_assoc : forall a b, (bin_second a >>>> bin_first b) <~~~> (bin_first b >>>> bin_second a).
232     intros.
233     set (fun c => mon_assoc (pair_obj (pair_obj a c) b)) as qq.
234     simpl in qq.
235     apply Build_NaturalIsomorphism with (ni_iso:=qq).
236     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj a A) b) (pair_obj (pair_obj a B) b)
237                     (pair_mor (pair_obj (pair_obj a A) b) (pair_obj (pair_obj a B) b)
238                     (pair_mor (pair_obj a A) (pair_obj a B) (id a) f) (id b))) as qr;
239              apply qr).
240     Defined.
241
242   Lemma mon_pmon_assoc_rr   :  forall a b, (bin_first  (a⊗b)) <~~~> (bin_first  a >>>> bin_first  b).
243     intros.
244     set (fun c:C => mon_assoc (pair_obj (pair_obj c a) b)) as qq.
245     simpl in qq.
246     apply ni_inv.
247     apply Build_NaturalIsomorphism with (ni_iso:=qq).
248     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
249                     (pair_mor (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
250                     (pair_mor (pair_obj _ _) (pair_obj _ _) f (id a)) (id b))) as qr;
251               etransitivity; [ idtac | apply qr ];
252               apply comp_respects; try reflexivity;
253               unfold mon_f;
254               simpl;
255               apply ((fmor_respects F) (pair_obj _ _) (pair_obj _ _));
256               split; try reflexivity;
257               symmetry;
258               simpl;
259               set (@fmor_preserves_id _ _ _ _ _ _ _ F (pair_obj a b)) as qqqq;
260               simpl in qqqq;
261               apply qqqq).
262    Defined.
263
264   Lemma mon_pmon_assoc_ll   :  forall a b, (bin_second (a⊗b)) <~~~> (bin_second b >>>> bin_second a).
265     intros.
266     set (fun c:C => mon_assoc (pair_obj (pair_obj a b) c)) as qq.
267     simpl in qq.
268     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (Fobj (pair_obj a b) ⋊-) (b ⋊- >>>> a ⋊-)) as qqq.
269     set (qqq qq) as q'.
270     apply q'.
271     clear q'.
272     clear qqq.
273     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
274                     (pair_mor (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
275                     (pair_mor (pair_obj _ _) (pair_obj _ _) (id a) (id b)) f)) as qr;
276               etransitivity; [ apply qr | idtac ];
277               apply comp_respects; try reflexivity;
278               unfold mon_f;
279               simpl;
280               apply ((fmor_respects F) (pair_obj _ _) (pair_obj _ _));
281               split; try reflexivity;
282               simpl;
283               set (@fmor_preserves_id _ _ _ _ _ _ _ F (pair_obj a b)) as qqqq;
284               simpl in qqqq;
285               apply qqqq).
286     Defined.
287
288   Lemma mon_pmon_cancelr : (bin_first I0) <~~~> functor_id C.
289     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (bin_first I0) (functor_id C)) as qq.
290     set (mon_cancelr) as z.
291     simpl in z.
292     simpl in qq.
293     set (qq z) as zz.
294     apply zz.
295     abstract (intros;
296               set (ni_commutes mon_cancelr) as q; simpl in *;
297               apply q).
298     Defined.
299
300   Lemma mon_pmon_cancell : (bin_second I0) <~~~> functor_id C.
301     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (bin_second I0) (functor_id C)) as qq.
302     set (mon_cancell) as z.
303     simpl in z.
304     simpl in qq.
305     set (qq z) as zz.
306     apply zz.
307     abstract (intros;
308               set (ni_commutes mon_cancell) as q; simpl in *;
309               apply q).
310     Defined.
311
312   Lemma mon_pmon_triangle : forall a b, #(mon_pmon_cancelr a) ⋉ b ~~ #(mon_pmon_assoc _ _ _) >>> a ⋊ #(mon_pmon_cancell b).
313     intros.
314     set mon_triangle as q.
315     simpl in q.
316     apply q.
317     Qed.
318
319   Lemma mon_pmon_pentagon a b c d : (#(mon_pmon_assoc a c b ) ⋉ d)  >>>
320                                      #(mon_pmon_assoc a d _ )   >>>
321                                 (a ⋊ #(mon_pmon_assoc b d c))
322                                   ~~ #(mon_pmon_assoc _ d c )   >>>
323                                      #(mon_pmon_assoc a _ b ).
324     set (@pentagon _ _ _ _ _ _ _ mon_pentagon) as x.
325     simpl in x.
326     unfold bin_obj.
327     unfold mon_first in x.
328     simpl in *.
329     apply x.
330     Qed.
331
332   Definition MonoidalCat_is_PreMonoidal : PreMonoidalCat (BinoidalCat_from_Bifunctor (mon_f M)) (mon_i M).
333     refine {| pmon_assoc                 := mon_pmon_assoc
334             ; pmon_cancell               := mon_pmon_cancell
335             ; pmon_cancelr               := mon_pmon_cancelr
336             ; pmon_triangle              := {| triangle := mon_pmon_triangle |}
337             ; pmon_pentagon              := {| pentagon := mon_pmon_pentagon |}
338             ; pmon_assoc_ll              := mon_pmon_assoc_ll
339             ; pmon_assoc_rr              := mon_pmon_assoc_rr
340             |}.
341     abstract (set (coincide mon_triangle) as qq; simpl in *; apply qq).
342     abstract (intros; simpl; reflexivity).
343     abstract (intros; simpl; reflexivity).
344     Defined.
345
346   Lemma MonoidalCat_all_central : forall a b (f:a~~{M}~~>b), CentralMorphism f.
347     intros;
348     set (@fmor_preserves_comp _ _ _ _ _ _ _ M) as fc.
349     apply Build_CentralMorphism;
350     intros; simpl in *.
351     etransitivity.
352       apply fc.
353       symmetry.
354       etransitivity.
355       apply fc.
356       apply (fmor_respects M).
357       simpl.
358       setoid_rewrite left_identity;
359       setoid_rewrite right_identity;
360       split; reflexivity.
361     etransitivity.
362       apply fc.
363       symmetry.
364       etransitivity.
365       apply fc.
366       apply (fmor_respects M).
367       simpl.
368       setoid_rewrite left_identity;
369       setoid_rewrite right_identity;
370       split; reflexivity.
371     Qed.
372
373 End MonoidalCat_is_PreMonoidal.
374
375 Hint Extern 1 => apply MonoidalCat_all_central.
376 Coercion MonoidalCat_is_PreMonoidal : MonoidalCat >-> PreMonoidalCat.
377 (*Lemma CommutativePreMonoidalCategoriesAreMonoidal `(pm:PreMonoidalCat)(cc:CommutativeCat pm) : MonoidalCat pm.*)
378
379 Section MonoidalFunctor.
380   Context `(m1:MonoidalCat(C:=C1)) `(m2:MonoidalCat(C:=C2)).
381   Class MonoidalFunctor {Mobj:C1->C2} (mf_F:Functor C1 C2 Mobj) :=
382   { mf_f         := mf_F where "f ⊕⊕ g" := (@fmor _ _ _ _ _ _ _ m2 _ _ (pair_mor (pair_obj _ _) (pair_obj _ _) f g))
383   ; mf_coherence :  (mf_F **** mf_F) >>>> (mon_f m2) <~~~> (mon_f m1) >>>> mf_F
384   ; mf_phi       := fun a b => #(mf_coherence (pair_obj a b))
385   ; mf_id        :  (mon_i m2) ≅ (mf_F (mon_i m1))
386   ; mf_cancelr   :  forall a,    #(mon_cancelr(MonoidalCat:=m2) (mf_F a)) ~~
387                                   (id (mf_F a)) ⊕⊕ #mf_id >>> mf_phi a (mon_i _) >>> mf_F \ #(mon_cancelr a)
388   ; mf_cancell   :  forall b,    #(mon_cancell (mf_F b)) ~~
389                                  #mf_id ⊕⊕ (id (mf_F b)) >>> mf_phi (mon_i _) b >>> mf_F \ #(mon_cancell b)
390   ; mf_assoc     :  forall a b c, (mf_phi a b) ⊕⊕ (id (mf_F c)) >>> (mf_phi _ c) >>>
391                                   (mf_F \ #(mon_assoc (pair_obj (pair_obj a b) c) )) ~~
392                                           #(mon_assoc (pair_obj (pair_obj _ _) _) )  >>>
393                                   (id (mf_F a)) ⊕⊕ (mf_phi b c) >>> (mf_phi a _)
394   }.
395 End MonoidalFunctor.
396 Coercion mf_f : MonoidalFunctor >-> Functor.
397 Implicit Arguments mf_coherence [ Ob Hom C1 Fobj F I0 m1 Ob0 Hom0 C2 Fobj0 F0 I1 m2 Mobj mf_F ].
398 Implicit Arguments mf_id        [ Ob Hom C1 Fobj F I0 m1 Ob0 Hom0 C2 Fobj0 F0 I1 m2 Mobj mf_F ].
399
400 Section MonoidalFunctorsCompose.
401   Context `(m1:MonoidalCat).
402   Context `(m2:MonoidalCat).
403   Context `(m3:MonoidalCat).
404   Context  {f1obj}(f1:@Functor _ _ m1 _ _ m2 f1obj).
405   Context  {f2obj}(f2:@Functor _ _ m2 _ _ m3 f2obj).
406   Context  (mf1:MonoidalFunctor m1 m2 f1).
407   Context  (mf2:MonoidalFunctor m2 m3 f2).
408
409   Lemma mf_compose_coherence : (f1 >>>> f2) **** (f1 >>>> f2) >>>> m3 <~~~> m1 >>>> (f1 >>>> f2).
410     set (mf_coherence mf1) as mc1.
411     set (mf_coherence mf2) as mc2.
412     set (@ni_comp) as q.
413     set (q _ _ _ _ _ _ _ ((f1 >>>> f2) **** (f1 >>>> f2) >>>> m3) _ ((f1 **** f1 >>>> m2) >>>> f2) _ (m1 >>>> (f1 >>>> f2))) as qq.
414     apply qq; clear qq; clear q.
415     apply (@ni_comp _ _ _ _ _ _ _ _ _ (f1 **** f1 >>>> (f2 **** f2 >>>> m3)) _ _).
416     apply (@ni_comp _ _ _ _ _ _ _ _ _ ((f1 **** f1 >>>> f2 **** f2) >>>> m3) _ _).
417     eapply ni_respects.
418       apply ni_prod_comp.
419       apply ni_id.
420     apply ni_associativity.
421     apply ni_inv.
422     eapply ni_comp.
423       apply (ni_associativity (f1 **** f1) m2 f2).
424       apply (ni_respects (F0:=f1 **** f1)(F1:=f1 **** f1)(G0:=(m2 >>>> f2))(G1:=(f2 **** f2 >>>> m3))).
425         apply ni_id.
426         apply ni_inv.
427         apply mc2.
428     apply ni_inv.
429     eapply ni_comp.
430       eapply ni_inv.
431       apply (ni_associativity m1 f1 f2).
432       apply ni_respects.
433         apply ni_inv.
434         apply mc1.
435         apply ni_id.
436     Qed.
437
438   Instance MonoidalFunctorsCompose : MonoidalFunctor m1 m3 (f1 >>>> f2) :=
439   { mf_id        := id_comp         (mf_id mf2) (functors_preserve_isos f2 (mf_id mf1))
440   ; mf_coherence := mf_compose_coherence
441   }.
442   Admitted.
443
444 End MonoidalFunctorsCompose.
445
446 Class CartesianCat `(mc:MonoidalCat) :=
447 { car_terminal  : Terminal mc
448 ; car_one       : (@one _ _ _ car_terminal) ≅ (mon_i mc)
449 ; car_diagonal  : DiagonalCat mc
450 ; car_law1      : forall {a}, id a ~~ (copy(DiagonalCat:=car_diagonal) _) >>> ((drop a >>> #car_one) ⋉ a) >>> (#(pmon_cancell mc _))
451 ; car_law2      : forall {a}, id a ~~ (copy(DiagonalCat:=car_diagonal) _) >>> (a ⋊ (drop a >>> #car_one)) >>> (#(pmon_cancelr mc _))
452 ; car_mn        := mc
453 }.
454 Coercion car_diagonal : CartesianCat >-> DiagonalCat.
455 Coercion car_terminal : CartesianCat >-> Terminal.
456 Coercion car_mn       : CartesianCat >-> MonoidalCat.