The monoidal coherence theorem #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
In this file, we prove the monoidal coherence theorem, stated in the following form: the free
monoidal category over any type C
is thin.
We follow a proof described by Ilya Beylin and Peter Dybjer, which has been previously formalized
in the proof assistant ALF. The idea is to declare a normal form (with regard to association and
adding units) on objects of the free monoidal category and consider the discrete subcategory of
objects that are in normal form. A normalization procedure is then just a functor
full_normalize : free_monoidal_category C ⥤ discrete (normal_monoidal_object C)
, where
functoriality says that two objects which are related by associators and unitors have the
same normal form. Another desirable property of a normalization procedure is that an object is
isomorphic (i.e., related via associators and unitors) to its normal form. In the case of the
specific normalization procedure we use we not only get these isomorphismns, but also that they
assemble into a natural isomorphism 𝟭 (free_monoidal_category C) ≅ full_normalize ⋙ inclusion
.
But this means that any two parallel morphisms in the free monoidal category factor through a
discrete category in the same way, so they must be equal, and hence the free monoidal category
is thin.
References #
- unit : Π {C : Type u}, category_theory.free_monoidal_category.normal_monoidal_object C
- tensor : Π {C : Type u}, category_theory.free_monoidal_category.normal_monoidal_object C → C → category_theory.free_monoidal_category.normal_monoidal_object C
We say an object in the free monoidal category is in normal form if it is of the form
(((𝟙_ C) ⊗ X₁) ⊗ X₂) ⊗ ⋯
.
Instances for category_theory.free_monoidal_category.normal_monoidal_object
- category_theory.free_monoidal_category.normal_monoidal_object.has_sizeof_inst
Auxiliary definition for inclusion
.
Equations
- category_theory.free_monoidal_category.inclusion_obj (n.tensor a) = (category_theory.free_monoidal_category.inclusion_obj n).tensor (category_theory.free_monoidal_category.of a)
- category_theory.free_monoidal_category.inclusion_obj category_theory.free_monoidal_category.normal_monoidal_object.unit = category_theory.free_monoidal_category.unit
The discrete subcategory of objects in normal form includes into the free monoidal category.
Auxiliary definition for normalize
.
Equations
- (X.tensor Y).normalize_obj n = Y.normalize_obj (X.normalize_obj n).as
- category_theory.free_monoidal_category.unit.normalize_obj n = {as := n}
- (category_theory.free_monoidal_category.of X).normalize_obj n = {as := n.tensor X}
Auxiliary definition for normalize
. Here we prove that objects that are related by
associators and unitors map to the same normal form.
Equations
- category_theory.free_monoidal_category.normalize_map_aux (f.tensor g) = {app := λ (X : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), (category_theory.free_monoidal_category.normalize_map_aux g).app (T.normalize_obj X.as) ≫ (category_theory.discrete.functor W.normalize_obj).map ((category_theory.free_monoidal_category.normalize_map_aux f).app X), naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (f.comp g) = category_theory.free_monoidal_category.normalize_map_aux f ≫ category_theory.free_monoidal_category.normalize_map_aux g
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.ρ_inv _x) = {app := λ (_x_1 : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), category_theory.free_monoidal_category.normalize_map_aux._match_2 _x _x_1, naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.ρ_hom _x) = {app := λ (_x_1 : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), category_theory.free_monoidal_category.normalize_map_aux._match_1 _x _x_1, naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.l_inv _x) = {app := λ (X : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), 𝟙 ((category_theory.discrete.functor _x.normalize_obj).obj X), naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.l_hom _x) = {app := λ (X : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), 𝟙 ((category_theory.discrete.functor (category_theory.free_monoidal_category.unit.tensor _x).normalize_obj).obj X), naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.α_inv _x _x_1 _x_2) = {app := λ (X : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), 𝟙 ((category_theory.discrete.functor (_x.tensor (_x_1.tensor _x_2)).normalize_obj).obj X), naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.α_hom _x _x_1 _x_2) = {app := λ (X : category_theory.discrete (category_theory.free_monoidal_category.normal_monoidal_object C)), 𝟙 ((category_theory.discrete.functor ((_x.tensor _x_1).tensor _x_2).normalize_obj).obj X), naturality' := _}
- category_theory.free_monoidal_category.normalize_map_aux (category_theory.free_monoidal_category.hom.id _x) = 𝟙 (category_theory.discrete.functor _x.normalize_obj)
- category_theory.free_monoidal_category.normalize_map_aux._match_2 _x {as := X} = {down := {down := _}}
- category_theory.free_monoidal_category.normalize_map_aux._match_1 _x {as := X} = {down := {down := _}}
Our normalization procedure works by first defining a functor F C ⥤ (N C ⥤ N C)
(which turns
out to be very easy), and then obtain a functor F C ⥤ N C
by plugging in the normal object
𝟙_ C
.
Equations
- category_theory.free_monoidal_category.normalize C = {obj := λ (X : category_theory.free_monoidal_category C), category_theory.discrete.functor X.normalize_obj, map := λ (X Y : category_theory.free_monoidal_category C), quotient.lift category_theory.free_monoidal_category.normalize_map_aux _, map_id' := _, map_comp' := _}
A variant of the normalization functor where we consider the result as an object in the free monoidal category (rather than an object of the discrete subcategory of objects in normal form).
Equations
- category_theory.free_monoidal_category.normalize' C = category_theory.free_monoidal_category.normalize C ⋙ (category_theory.whiskering_right ((category_theory.discrete ∘ category_theory.free_monoidal_category.normal_monoidal_object) C) ((category_theory.discrete ∘ category_theory.free_monoidal_category.normal_monoidal_object) C) (category_theory.free_monoidal_category C)).obj category_theory.free_monoidal_category.inclusion
The normalization functor for the free monoidal category over C
.
Equations
- category_theory.free_monoidal_category.full_normalize C = {obj := λ (X : category_theory.free_monoidal_category C), ((category_theory.free_monoidal_category.normalize C).obj X).obj {as := category_theory.free_monoidal_category.normal_monoidal_object.unit C}, map := λ (X Y : category_theory.free_monoidal_category C) (f : X ⟶ Y), ((category_theory.free_monoidal_category.normalize C).map f).app {as := category_theory.free_monoidal_category.normal_monoidal_object.unit C}, map_id' := _, map_comp' := _}
Given an object X
of the free monoidal category and an object n
in normal form, taking
the tensor product n ⊗ X
in the free monoidal category is functorial in both X
and n
.
Equations
- category_theory.free_monoidal_category.tensor_func C = {obj := λ (X : category_theory.free_monoidal_category C), category_theory.discrete.functor (λ (n : category_theory.free_monoidal_category.normal_monoidal_object C), category_theory.free_monoidal_category.inclusion.obj {as := n} ⊗ X), map := λ (X Y : category_theory.free_monoidal_category C) (f : X ⟶ Y), {app := λ (n : (category_theory.discrete ∘ category_theory.free_monoidal_category.normal_monoidal_object) C), 𝟙 (category_theory.free_monoidal_category.inclusion.obj {as := n.as}) ⊗ f, naturality' := _}, map_id' := _, map_comp' := _}
Auxiliary definition for normalize_iso
. Here we construct the isomorphism between
n ⊗ X
and normalize X n
.
Equations
- category_theory.free_monoidal_category.normalize_iso_app C (X.tensor Y) n = (α_ (category_theory.free_monoidal_category.inclusion.obj {as := n.as}) X Y).symm ≪≫ (category_theory.free_monoidal_category.normalize_iso_app C X n ⊗ category_theory.iso.refl Y) ≪≫ category_theory.free_monoidal_category.normalize_iso_app C Y (((category_theory.free_monoidal_category.normalize C).obj X).obj n)
- category_theory.free_monoidal_category.normalize_iso_app C category_theory.free_monoidal_category.unit n = ρ_ (category_theory.free_monoidal_category.inclusion.obj {as := n.as})
- category_theory.free_monoidal_category.normalize_iso_app C (category_theory.free_monoidal_category.of X) n = category_theory.iso.refl (((category_theory.free_monoidal_category.tensor_func C).obj (category_theory.free_monoidal_category.of X)).obj n)
Auxiliary definition for normalize_iso
.
The isomorphism between n ⊗ X
and normalize X n
is natural (in both X
and n
, but
naturality in n
is trivial and was "proved" in normalize_iso_aux
). This is the real heart
of our proof of the coherence theorem.
The isomorphism between an object and its normal form is natural.
Equations
- category_theory.free_monoidal_category.full_normalize_iso C = category_theory.nat_iso.of_components (λ (X : category_theory.free_monoidal_category C), (λ_ X).symm ≪≫ ((category_theory.free_monoidal_category.normalize_iso C).app X).app {as := category_theory.free_monoidal_category.normal_monoidal_object.unit C}) _
The monoidal coherence theorem.
Auxiliary construction for showing that the free monoidal category is a groupoid. Do not use
this, use is_iso.inv
instead.
Equations
- category_theory.free_monoidal_category.inverse_aux (f.tensor g) = (category_theory.free_monoidal_category.inverse_aux f).tensor (category_theory.free_monoidal_category.inverse_aux g)
- category_theory.free_monoidal_category.inverse_aux (f.comp g) = (category_theory.free_monoidal_category.inverse_aux g).comp (category_theory.free_monoidal_category.inverse_aux f)
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.ρ_inv _x) = category_theory.free_monoidal_category.hom.ρ_hom _x
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.ρ_hom _x) = category_theory.free_monoidal_category.hom.ρ_inv _x
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.l_inv _x) = category_theory.free_monoidal_category.hom.l_hom _x
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.l_hom _x) = category_theory.free_monoidal_category.hom.l_inv _x
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.α_inv _x _x_1 _x_2) = category_theory.free_monoidal_category.hom.α_hom _x _x_1 _x_2
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.α_hom _x _x_1 _x_2) = category_theory.free_monoidal_category.hom.α_inv _x _x_1 _x_2
- category_theory.free_monoidal_category.inverse_aux (category_theory.free_monoidal_category.hom.id X) = category_theory.free_monoidal_category.hom.id X
Equations
- category_theory.free_monoidal_category.category_theory.groupoid = {to_category := {to_category_struct := category_theory.category.to_category_struct infer_instance, id_comp' := _, comp_id' := _, assoc' := _}, inv := λ (X Y : category_theory.free_monoidal_category C), quotient.lift (λ (f : X.hom Y), ⟦category_theory.free_monoidal_category.inverse_aux f⟧) _, inv_comp' := _, comp_inv' := _}