920dc9d449fe8ad43c1615837018ce2cca6361a1
[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 Class CartesianCat `(mc:PreMonoidalCat(C:=C)) :=
198 { car_terminal  : Terminal C
199 ; car_one       : 1 ≅ pmon_I
200 ; car_diagonal  : DiagonalCat mc
201 ; car_law1      : forall {a}, id a ~~ (copy(DiagonalCat:=car_diagonal) _) >>> ((drop a >>> #car_one) ⋉ a) >>> (#(pmon_cancell mc _))
202 ; car_law2      : forall {a}, id a ~~ (copy(DiagonalCat:=car_diagonal) _) >>> (a ⋊ (drop a >>> #car_one)) >>> (#(pmon_cancelr mc _))
203 ; car_cat       := C
204 ; car_mn        := mc
205 }.
206 Coercion car_diagonal : CartesianCat >-> DiagonalCat.
207 Coercion car_terminal : CartesianCat >-> Terminal.
208 Coercion car_mn       : CartesianCat >-> PreMonoidalCat.
209
210 (* Definition 7.23 *)
211 Class MonoidalCat `{C:Category}{Fobj:prod_obj C C -> C}{F:Functor (C ×× C) C Fobj}(I:C) :=
212 { mon_f         := F
213 ; mon_i         := I
214 ; mon_c         := C
215 (*; mon_bin       := BinoidalCat_from_Bifunctor mon_f*)
216 ; mon_first     := fun a b c (f:a~>b) => F \ pair_mor (pair_obj a c) (pair_obj b c) f (id c)
217 ; mon_second    := fun a b c (f:a~>b) => F \ pair_mor (pair_obj c a) (pair_obj c b) (id c) f
218 ; mon_cancelr   :  (func_rlecnac I >>>> F) <~~~> functor_id C
219 ; mon_cancell   :  (func_llecnac I >>>> F) <~~~> functor_id C
220 ; mon_assoc     :  ((F **** (functor_id C)) >>>> F) <~~~> func_cossa >>>> ((((functor_id C) **** F) >>>> F))
221 ; mon_pentagon  :  Pentagon mon_first mon_second (fun a b c => #(mon_assoc (pair_obj (pair_obj a b) c)))
222 ; mon_triangle  :  Triangle mon_first mon_second (fun a b c => #(mon_assoc (pair_obj (pair_obj a b) c)))
223                                                  (fun a => #(mon_cancell a)) (fun a => #(mon_cancelr a))
224 }.
225
226 (* FIXME: show that the endofunctors on any given category form a monoidal category *)
227
228 (* Coq manual on coercions: ... only the oldest one is valid and the
229  * others are ignored. So the order of declaration of coercions is
230  * important. *)
231 Coercion mon_c   : MonoidalCat >-> Category.
232 (*Coercion mon_bin : MonoidalCat >-> BinoidalCat.*)
233 Coercion mon_f   : MonoidalCat >-> Functor.
234 Implicit Arguments mon_f [Ob Hom C Fobj F I].
235 Implicit Arguments mon_i [Ob Hom C Fobj F I].
236 Implicit Arguments mon_c [Ob Hom C Fobj F I].
237 (*Implicit Arguments mon_bin [Ob Hom C Fobj F I].*)
238 Implicit Arguments MonoidalCat [Ob Hom ].
239
240 Section MonoidalCat_is_PreMonoidal.
241   Context `(M:MonoidalCat).
242   Definition mon_bin_M := BinoidalCat_from_Bifunctor (mon_f M).
243   Existing Instance mon_bin_M.
244   Lemma mon_pmon_assoc : forall a b, (bin_second a >>>> bin_first b) <~~~> (bin_first b >>>> bin_second a).
245     intros.
246     set (fun c => mon_assoc (pair_obj (pair_obj a c) b)) as qq.
247     simpl in qq.
248     apply Build_NaturalIsomorphism with (ni_iso:=qq).
249     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj a A) b) (pair_obj (pair_obj a B) b)
250                     (pair_mor (pair_obj (pair_obj a A) b) (pair_obj (pair_obj a B) b)
251                     (pair_mor (pair_obj a A) (pair_obj a B) (id a) f) (id b))) as qr;
252              apply qr).
253     Defined.
254
255   Lemma mon_pmon_assoc_rr   :  forall a b, (bin_first  (a⊗b)) <~~~> (bin_first  a >>>> bin_first  b).
256     intros.
257     set (fun c:C => mon_assoc (pair_obj (pair_obj c a) b)) as qq.
258     simpl in qq.
259     apply ni_inv.
260     apply Build_NaturalIsomorphism with (ni_iso:=qq).
261     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
262                     (pair_mor (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
263                     (pair_mor (pair_obj _ _) (pair_obj _ _) f (id a)) (id b))) as qr;
264               etransitivity; [ idtac | apply qr ];
265               apply comp_respects; try reflexivity;
266               unfold mon_f;
267               simpl;
268               apply ((fmor_respects F) (pair_obj _ _) (pair_obj _ _));
269               split; try reflexivity;
270               symmetry;
271               simpl;
272               set (@fmor_preserves_id _ _ _ _ _ _ _ F (pair_obj a b)) as qqqq;
273               simpl in qqqq;
274               apply qqqq).
275    Defined.
276
277   Lemma mon_pmon_assoc_ll   :  forall a b, (bin_second (a⊗b)) <~~~> (bin_second b >>>> bin_second a).
278     intros.
279     set (fun c:C => mon_assoc (pair_obj (pair_obj a b) c)) as qq.
280     simpl in qq.
281     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (Fobj (pair_obj a b) ⋊-) (b ⋊- >>>> a ⋊-)) as qqq.
282     set (qqq qq) as q'.
283     apply q'.
284     clear q'.
285     clear qqq.
286     abstract (intros; set ((ni_commutes mon_assoc) (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
287                     (pair_mor (pair_obj (pair_obj _ _) _) (pair_obj (pair_obj _ _) _)
288                     (pair_mor (pair_obj _ _) (pair_obj _ _) (id a) (id b)) f)) as qr;
289               etransitivity; [ apply qr | idtac ];
290               apply comp_respects; try reflexivity;
291               unfold mon_f;
292               simpl;
293               apply ((fmor_respects F) (pair_obj _ _) (pair_obj _ _));
294               split; try reflexivity;
295               simpl;
296               set (@fmor_preserves_id _ _ _ _ _ _ _ F (pair_obj a b)) as qqqq;
297               simpl in qqqq;
298               apply qqqq).
299     Defined.
300
301   Lemma mon_pmon_cancelr : (bin_first I0) <~~~> functor_id C.
302     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (bin_first I0) (functor_id C)) as qq.
303     set (mon_cancelr) as z.
304     simpl in z.
305     simpl in qq.
306     set (qq z) as zz.
307     apply zz.
308     abstract (intros;
309               set (ni_commutes mon_cancelr) as q; simpl in *;
310               apply q).
311     Defined.
312
313   Lemma mon_pmon_cancell : (bin_second I0) <~~~> functor_id C.
314     set (@Build_NaturalIsomorphism _ _ _ _ _ _ _ _ (bin_second I0) (functor_id C)) as qq.
315     set (mon_cancell) as z.
316     simpl in z.
317     simpl in qq.
318     set (qq z) as zz.
319     apply zz.
320     abstract (intros;
321               set (ni_commutes mon_cancell) as q; simpl in *;
322               apply q).
323     Defined.
324
325   Lemma mon_pmon_triangle : forall a b, #(mon_pmon_cancelr a) ⋉ b ~~ #(mon_pmon_assoc _ _ _) >>> a ⋊ #(mon_pmon_cancell b).
326     intros.
327     set mon_triangle as q.
328     simpl in q.
329     apply q.
330     Qed.
331
332   Lemma mon_pmon_pentagon a b c d : (#(mon_pmon_assoc a c b ) ⋉ d)  >>>
333                                      #(mon_pmon_assoc a d _ )   >>>
334                                 (a ⋊ #(mon_pmon_assoc b d c))
335                                   ~~ #(mon_pmon_assoc _ d c )   >>>
336                                      #(mon_pmon_assoc a _ b ).
337     set (@pentagon _ _ _ _ _ _ _ mon_pentagon) as x.
338     simpl in x.
339     unfold bin_obj.
340     unfold mon_first in x.
341     simpl in *.
342     apply x.
343     Qed.
344
345   Definition MonoidalCat_is_PreMonoidal : PreMonoidalCat (BinoidalCat_from_Bifunctor (mon_f M)) (mon_i M).
346     refine {| pmon_assoc                 := mon_pmon_assoc
347             ; pmon_cancell               := mon_pmon_cancell
348             ; pmon_cancelr               := mon_pmon_cancelr
349             ; pmon_triangle              := {| triangle := mon_pmon_triangle |}
350             ; pmon_pentagon              := {| pentagon := mon_pmon_pentagon |}
351             ; pmon_assoc_ll              := mon_pmon_assoc_ll
352             ; pmon_assoc_rr              := mon_pmon_assoc_rr
353             |}.
354     abstract (set (coincide mon_triangle) as qq; simpl in *; apply qq).
355     abstract (intros; simpl; reflexivity).
356     abstract (intros; simpl; reflexivity).
357     Defined.
358
359   Lemma MonoidalCat_all_central : forall a b (f:a~~{M}~~>b), CentralMorphism f.
360     intros;
361     set (@fmor_preserves_comp _ _ _ _ _ _ _ M) as fc.
362     apply Build_CentralMorphism;
363     intros; simpl in *.
364     etransitivity.
365       apply fc.
366       symmetry.
367       etransitivity.
368       apply fc.
369       apply (fmor_respects M).
370       simpl.
371       setoid_rewrite left_identity;
372       setoid_rewrite right_identity;
373       split; reflexivity.
374     etransitivity.
375       apply fc.
376       symmetry.
377       etransitivity.
378       apply fc.
379       apply (fmor_respects M).
380       simpl.
381       setoid_rewrite left_identity;
382       setoid_rewrite right_identity;
383       split; reflexivity.
384     Qed.
385
386 End MonoidalCat_is_PreMonoidal.
387
388 Hint Extern 1 => apply MonoidalCat_all_central.
389 Coercion MonoidalCat_is_PreMonoidal : MonoidalCat >-> PreMonoidalCat.
390 (*Lemma CommutativePreMonoidalCategoriesAreMonoidal `(pm:PreMonoidalCat)(cc:CommutativeCat pm) : MonoidalCat pm.*)
391
392 Section MonoidalFunctor.
393   Context `(m1:MonoidalCat(C:=C1)) `(m2:MonoidalCat(C:=C2)).
394   Class MonoidalFunctor {Mobj:C1->C2} (mf_F:Functor C1 C2 Mobj) :=
395   { mf_f         := mf_F where "f ⊕⊕ g" := (@fmor _ _ _ _ _ _ _ m2 _ _ (pair_mor (pair_obj _ _) (pair_obj _ _) f g))
396   ; mf_coherence :  (mf_F **** mf_F) >>>> (mon_f m2) <~~~> (mon_f m1) >>>> mf_F
397   ; mf_phi       := fun a b => #(mf_coherence (pair_obj a b))
398   ; mf_id        :  (mon_i m2) ≅ (mf_F (mon_i m1))
399   ; mf_cancelr   :  forall a,    #(mon_cancelr(MonoidalCat:=m2) (mf_F a)) ~~
400                                   (id (mf_F a)) ⊕⊕ #mf_id >>> mf_phi a (mon_i _) >>> mf_F \ #(mon_cancelr a)
401   ; mf_cancell   :  forall b,    #(mon_cancell (mf_F b)) ~~
402                                  #mf_id ⊕⊕ (id (mf_F b)) >>> mf_phi (mon_i _) b >>> mf_F \ #(mon_cancell b)
403   ; mf_assoc     :  forall a b c, (mf_phi a b) ⊕⊕ (id (mf_F c)) >>> (mf_phi _ c) >>>
404                                   (mf_F \ #(mon_assoc (pair_obj (pair_obj a b) c) )) ~~
405                                           #(mon_assoc (pair_obj (pair_obj _ _) _) )  >>>
406                                   (id (mf_F a)) ⊕⊕ (mf_phi b c) >>> (mf_phi a _)
407   }.
408 End MonoidalFunctor.
409 Coercion mf_f : MonoidalFunctor >-> Functor.
410 Implicit Arguments mf_coherence [ Ob Hom C1 Fobj F I0 m1 Ob0 Hom0 C2 Fobj0 F0 I1 m2 Mobj mf_F ].
411 Implicit Arguments mf_id        [ Ob Hom C1 Fobj F I0 m1 Ob0 Hom0 C2 Fobj0 F0 I1 m2 Mobj mf_F ].
412
413 Section MonoidalFunctorsCompose.
414   Context `(m1:MonoidalCat).
415   Context `(m2:MonoidalCat).
416   Context `(m3:MonoidalCat).
417   Context  {f1obj}(f1:@Functor _ _ m1 _ _ m2 f1obj).
418   Context  {f2obj}(f2:@Functor _ _ m2 _ _ m3 f2obj).
419   Context  (mf1:MonoidalFunctor m1 m2 f1).
420   Context  (mf2:MonoidalFunctor m2 m3 f2).
421
422   Lemma mf_compose_coherence : (f1 >>>> f2) **** (f1 >>>> f2) >>>> m3 <~~~> m1 >>>> (f1 >>>> f2).
423     set (mf_coherence mf1) as mc1.
424     set (mf_coherence mf2) as mc2.
425     set (@ni_comp) as q.
426     set (q _ _ _ _ _ _ _ ((f1 >>>> f2) **** (f1 >>>> f2) >>>> m3) _ ((f1 **** f1 >>>> m2) >>>> f2) _ (m1 >>>> (f1 >>>> f2))) as qq.
427     apply qq; clear qq; clear q.
428     apply (@ni_comp _ _ _ _ _ _ _ _ _ (f1 **** f1 >>>> (f2 **** f2 >>>> m3)) _ _).
429     apply (@ni_comp _ _ _ _ _ _ _ _ _ ((f1 **** f1 >>>> f2 **** f2) >>>> m3) _ _).
430     eapply ni_respects.
431       apply ni_prod_comp.
432       apply ni_id.
433     apply ni_associativity.
434     apply ni_inv.
435     eapply ni_comp.
436       apply (ni_associativity (f1 **** f1) m2 f2).
437       apply (ni_respects (F0:=f1 **** f1)(F1:=f1 **** f1)(G0:=(m2 >>>> f2))(G1:=(f2 **** f2 >>>> m3))).
438         apply ni_id.
439         apply ni_inv.
440         apply mc2.
441     apply ni_inv.
442     eapply ni_comp.
443       eapply ni_inv.
444       apply (ni_associativity m1 f1 f2).
445       apply ni_respects.
446         apply ni_inv.
447         apply mc1.
448         apply ni_id.
449     Qed.
450
451   Instance MonoidalFunctorsCompose : MonoidalFunctor m1 m3 (f1 >>>> f2) :=
452   { mf_id        := id_comp         (mf_id mf2) (functors_preserve_isos f2 (mf_id mf1))
453   ; mf_coherence := mf_compose_coherence
454   }.
455   admit.
456   admit.
457   admit.
458   Defined.
459
460 End MonoidalFunctorsCompose.