Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
Project: Xena
Path: Maths_Challenges / _target / deps / mathlib / src / category_theory / monoidal / category.lean
Views: 18536License: APACHE
/- Copyright (c) 2018 Michael Jendrusch. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Michael Jendrusch, Scott Morrison -/ import category_theory.products.basic import category_theory.natural_isomorphism import tactic.basic import tactic.slice open category_theory universes v u open category_theory open category_theory.category open category_theory.iso namespace category_theory /-- In a monoidal category, we can take the tensor product of objects, `X ⊗ Y` and of morphisms `f ⊗ g`. Tensor product does not need to be strictly associative on objects, but there is a specified associator, `α_ X Y Z : (X ⊗ Y) ⊗ Z ≅ X ⊗ (Y ⊗ Z)`. There is a tensor unit `𝟙_ C`, with specified left and right unitor isomorphisms `λ_ X : 𝟙_ C ⊗ X ≅ X` and `ρ_ X : X ⊗ 𝟙_ C ≅ X`. These associators and unitors satisfy the pentagon and triangle equations. -/ class monoidal_category (C : Type u) [𝒞 : category.{v} C] := -- curried tensor product of objects: (tensor_obj : C → C → C) (infixr ` ⊗ `:70 := tensor_obj) -- This notation is only temporary -- curried tensor product of morphisms: (tensor_hom : Π {X₁ Y₁ X₂ Y₂ : C}, (X₁ ⟶ Y₁) → (X₂ ⟶ Y₂) → ((X₁ ⊗ X₂) ⟶ (Y₁ ⊗ Y₂))) (infixr ` ⊗' `:69 := tensor_hom) -- This notation is only temporary -- tensor product laws: (tensor_id' : ∀ (X₁ X₂ : C), (𝟙 X₁) ⊗' (𝟙 X₂) = 𝟙 (X₁ ⊗ X₂) . obviously) (tensor_comp' : ∀ {X₁ Y₁ Z₁ X₂ Y₂ Z₂ : C} (f₁ : X₁ ⟶ Y₁) (f₂ : X₂ ⟶ Y₂) (g₁ : Y₁ ⟶ Z₁) (g₂ : Y₂ ⟶ Z₂), (f₁ ≫ g₁) ⊗' (f₂ ≫ g₂) = (f₁ ⊗' f₂) ≫ (g₁ ⊗' g₂) . obviously) -- tensor unit: (tensor_unit : C) (notation `𝟙_` := tensor_unit) -- associator: (associator : Π X Y Z : C, (X ⊗ Y) ⊗ Z ≅ X ⊗ (Y ⊗ Z)) (notation `α_` := associator) (associator_naturality' : ∀ {X₁ X₂ X₃ Y₁ Y₂ Y₃ : C} (f₁ : X₁ ⟶ Y₁) (f₂ : X₂ ⟶ Y₂) (f₃ : X₃ ⟶ Y₃), ((f₁ ⊗' f₂) ⊗' f₃) ≫ (α_ Y₁ Y₂ Y₃).hom = (α_ X₁ X₂ X₃).hom ≫ (f₁ ⊗' (f₂ ⊗' f₃)) . obviously) -- left unitor: (left_unitor : Π X : C, 𝟙_ ⊗ X ≅ X) (notation `λ_` := left_unitor) (left_unitor_naturality' : ∀ {X Y : C} (f : X ⟶ Y), ((𝟙 𝟙_) ⊗' f) ≫ (λ_ Y).hom = (λ_ X).hom ≫ f . obviously) -- right unitor: (right_unitor : Π X : C, X ⊗ 𝟙_ ≅ X) (notation `ρ_` := right_unitor) (right_unitor_naturality' : ∀ {X Y : C} (f : X ⟶ Y), (f ⊗' (𝟙 𝟙_)) ≫ (ρ_ Y).hom = (ρ_ X).hom ≫ f . obviously) -- pentagon identity: (pentagon' : ∀ W X Y Z : C, ((α_ W X Y).hom ⊗' (𝟙 Z)) ≫ (α_ W (X ⊗ Y) Z).hom ≫ ((𝟙 W) ⊗' (α_ X Y Z).hom) = (α_ (W ⊗ X) Y Z).hom ≫ (α_ W X (Y ⊗ Z)).hom . obviously) -- triangle identity: (triangle' : ∀ X Y : C, (α_ X 𝟙_ Y).hom ≫ ((𝟙 X) ⊗' (λ_ Y).hom) = (ρ_ X).hom ⊗' (𝟙 Y) . obviously) restate_axiom monoidal_category.tensor_id' attribute [simp] monoidal_category.tensor_id restate_axiom monoidal_category.tensor_comp' attribute [simp] monoidal_category.tensor_comp restate_axiom monoidal_category.associator_naturality' restate_axiom monoidal_category.left_unitor_naturality' restate_axiom monoidal_category.right_unitor_naturality' restate_axiom monoidal_category.pentagon' restate_axiom monoidal_category.triangle' attribute [simp] monoidal_category.triangle open monoidal_category infixr ` ⊗ `:70 := tensor_obj infixr ` ⊗ `:70 := tensor_hom notation `𝟙_` := tensor_unit notation `α_` := associator notation `λ_` := left_unitor notation `ρ_` := right_unitor /-- The tensor product of two isomorphisms is an isomorphism. -/ def tensor_iso {C : Type u} {X Y X' Y' : C} [category.{v} C] [monoidal_category.{v} C] (f : X ≅ Y) (g : X' ≅ Y') : X ⊗ X' ≅ Y ⊗ Y' := { hom := f.hom ⊗ g.hom, inv := f.inv ⊗ g.inv, hom_inv_id' := by rw [←tensor_comp, iso.hom_inv_id, iso.hom_inv_id, ←tensor_id], inv_hom_id' := by rw [←tensor_comp, iso.inv_hom_id, iso.inv_hom_id, ←tensor_id] } infixr ` ⊗ `:70 := tensor_iso namespace monoidal_category section variables {C : Type u} [category.{v} C] [𝒞 : monoidal_category.{v} C] include 𝒞 instance tensor_is_iso {W X Y Z : C} (f : W ⟶ X) [is_iso f] (g : Y ⟶ Z) [is_iso g] : is_iso (f ⊗ g) := { ..(as_iso f ⊗ as_iso g) } @[simp] lemma inv_tensor {W X Y Z : C} (f : W ⟶ X) [is_iso f] (g : Y ⟶ Z) [is_iso g] : inv (f ⊗ g) = inv f ⊗ inv g := rfl variables {U V W X Y Z : C} -- When `rewrite_search` lands, add @[search] attributes to -- monoidal_category.tensor_id monoidal_category.tensor_comp monoidal_category.associator_naturality -- monoidal_category.left_unitor_naturality monoidal_category.right_unitor_naturality -- monoidal_category.pentagon monoidal_category.triangle -- tensor_comp_id tensor_id_comp comp_id_tensor_tensor_id -- triangle_assoc_comp_left triangle_assoc_comp_right triangle_assoc_comp_left_inv triangle_assoc_comp_right_inv -- left_unitor_tensor left_unitor_tensor_inv -- right_unitor_tensor right_unitor_tensor_inv -- pentagon_inv -- associator_inv_naturality -- left_unitor_inv_naturality -- right_unitor_inv_naturality @[simp] lemma comp_tensor_id (f : W ⟶ X) (g : X ⟶ Y) : (f ≫ g) ⊗ (𝟙 Z) = (f ⊗ (𝟙 Z)) ≫ (g ⊗ (𝟙 Z)) := by { rw ←tensor_comp, simp } @[simp] lemma id_tensor_comp (f : W ⟶ X) (g : X ⟶ Y) : (𝟙 Z) ⊗ (f ≫ g) = (𝟙 Z ⊗ f) ≫ (𝟙 Z ⊗ g) := by { rw ←tensor_comp, simp } @[simp] lemma id_tensor_comp_tensor_id (f : W ⟶ X) (g : Y ⟶ Z) : ((𝟙 Y) ⊗ f) ≫ (g ⊗ (𝟙 X)) = g ⊗ f := by { rw [←tensor_comp], simp } @[simp] lemma tensor_id_comp_id_tensor (f : W ⟶ X) (g : Y ⟶ Z) : (g ⊗ (𝟙 W)) ≫ ((𝟙 Z) ⊗ f) = g ⊗ f := by { rw [←tensor_comp], simp } lemma left_unitor_inv_naturality {X X' : C} (f : X ⟶ X') : f ≫ (λ_ X').inv = (λ_ X).inv ≫ (𝟙 _ ⊗ f) := begin apply (cancel_mono (λ_ X').hom).1, simp only [assoc, comp_id, iso.inv_hom_id], rw [left_unitor_naturality, ←category.assoc, iso.inv_hom_id, category.id_comp] end lemma right_unitor_inv_naturality {X X' : C} (f : X ⟶ X') : f ≫ (ρ_ X').inv = (ρ_ X).inv ≫ (f ⊗ 𝟙 _) := begin apply (cancel_mono (ρ_ X').hom).1, simp only [assoc, comp_id, iso.inv_hom_id], rw [right_unitor_naturality, ←category.assoc, iso.inv_hom_id, category.id_comp] end @[simp] lemma tensor_left_iff {X Y : C} (f g : X ⟶ Y) : ((𝟙 (𝟙_ C)) ⊗ f = (𝟙 (𝟙_ C)) ⊗ g) ↔ (f = g) := begin split, { intro h, have h' := congr_arg (λ k, (λ_ _).inv ≫ k) h, dsimp at h', rw [←left_unitor_inv_naturality, ←left_unitor_inv_naturality] at h', exact (cancel_mono _).1 h', }, { intro h, subst h, } end @[simp] lemma tensor_right_iff {X Y : C} (f g : X ⟶ Y) : (f ⊗ (𝟙 (𝟙_ C)) = g ⊗ (𝟙 (𝟙_ C))) ↔ (f = g) := begin split, { intro h, have h' := congr_arg (λ k, (ρ_ _).inv ≫ k) h, dsimp at h', rw [←right_unitor_inv_naturality, ←right_unitor_inv_naturality] at h', exact (cancel_mono _).1 h' }, { intro h, subst h, } end -- We now prove: -- ((α_ (𝟙_ C) X Y).hom) ≫ -- ((λ_ (X ⊗ Y)).hom) -- = ((λ_ X).hom ⊗ (𝟙 Y)) -- (and the corresponding fact for right unitors) -- following the proof on nLab: -- Lemma 2.2 at <https://ncatlab.org/nlab/revision/monoidal+category/115> lemma left_unitor_product_aux_perimeter (X Y : C) : ((α_ (𝟙_ C) (𝟙_ C) X).hom ⊗ (𝟙 Y)) ≫ (α_ (𝟙_ C) ((𝟙_ C) ⊗ X) Y).hom ≫ ((𝟙 (𝟙_ C)) ⊗ (α_ (𝟙_ C) X Y).hom) ≫ ((𝟙 (𝟙_ C)) ⊗ (λ_ (X ⊗ Y)).hom) = (((ρ_ (𝟙_ C)).hom ⊗ (𝟙 X)) ⊗ (𝟙 Y)) ≫ (α_ (𝟙_ C) X Y).hom := begin conv_lhs { congr, skip, rw [←category.assoc] }, rw [←category.assoc, monoidal_category.pentagon, associator_naturality, tensor_id, ←monoidal_category.triangle, ←category.assoc] end lemma left_unitor_product_aux_triangle (X Y : C) : ((α_ (𝟙_ C) (𝟙_ C) X).hom ⊗ (𝟙 Y)) ≫ (((𝟙 (𝟙_ C)) ⊗ (λ_ X).hom) ⊗ (𝟙 Y)) = ((ρ_ (𝟙_ C)).hom ⊗ (𝟙 X)) ⊗ (𝟙 Y) := by rw [←comp_tensor_id, ←monoidal_category.triangle] lemma left_unitor_product_aux_square (X Y : C) : (α_ (𝟙_ C) ((𝟙_ C) ⊗ X) Y).hom ≫ ((𝟙 (𝟙_ C)) ⊗ (λ_ X).hom ⊗ (𝟙 Y)) = (((𝟙 (𝟙_ C)) ⊗ (λ_ X).hom) ⊗ (𝟙 Y)) ≫ (α_ (𝟙_ C) X Y).hom := by rw associator_naturality lemma left_unitor_product_aux (X Y : C) : ((𝟙 (𝟙_ C)) ⊗ (α_ (𝟙_ C) X Y).hom) ≫ ((𝟙 (𝟙_ C)) ⊗ (λ_ (X ⊗ Y)).hom) = (𝟙 (𝟙_ C)) ⊗ ((λ_ X).hom ⊗ (𝟙 Y)) := begin rw ←(cancel_epi (α_ (𝟙_ C) ((𝟙_ C) ⊗ X) Y).hom), rw left_unitor_product_aux_square, rw ←(cancel_epi ((α_ (𝟙_ C) (𝟙_ C) X).hom ⊗ (𝟙 Y))), slice_rhs 1 2 { rw left_unitor_product_aux_triangle }, conv_lhs { rw [left_unitor_product_aux_perimeter] } end lemma right_unitor_product_aux_perimeter (X Y : C) : ((α_ X Y (𝟙_ C)).hom ⊗ (𝟙 (𝟙_ C))) ≫ (α_ X (Y ⊗ (𝟙_ C)) (𝟙_ C)).hom ≫ ((𝟙 X) ⊗ (α_ Y (𝟙_ C) (𝟙_ C)).hom) ≫ ((𝟙 X) ⊗ (𝟙 Y) ⊗ (λ_ (𝟙_ C)).hom) = ((ρ_ (X ⊗ Y)).hom ⊗ (𝟙 (𝟙_ C))) ≫ (α_ X Y (𝟙_ C)).hom := begin transitivity (((α_ X Y _).hom ⊗ 𝟙 _) ≫ (α_ X _ _).hom ≫ (𝟙 X ⊗ (α_ Y _ _).hom)) ≫ (𝟙 X ⊗ 𝟙 Y ⊗ (λ_ _).hom), { conv_lhs { congr, skip, rw [←category.assoc] }, conv_rhs { rw [category.assoc] } }, { conv_lhs { congr, rw [monoidal_category.pentagon] }, conv_rhs { congr, rw [←monoidal_category.triangle] }, conv_rhs { rw [category.assoc] }, conv_rhs { congr, skip, congr, congr, rw [←tensor_id] }, conv_rhs { congr, skip, rw [associator_naturality] }, conv_rhs { rw [←category.assoc] } } end lemma right_unitor_product_aux_triangle (X Y : C) : ((𝟙 X) ⊗ (α_ Y (𝟙_ C) (𝟙_ C)).hom) ≫ ((𝟙 X) ⊗ (𝟙 Y) ⊗ (λ_ (𝟙_ C)).hom) = (𝟙 X) ⊗ (ρ_ Y).hom ⊗ (𝟙 (𝟙_ C)) := by rw [←id_tensor_comp, ←monoidal_category.triangle] lemma right_unitor_product_aux_square (X Y : C) : (α_ X (Y ⊗ (𝟙_ C)) (𝟙_ C)).hom ≫ ((𝟙 X) ⊗ (ρ_ Y).hom ⊗ (𝟙 (𝟙_ C))) = (((𝟙 X) ⊗ (ρ_ Y).hom) ⊗ (𝟙 (𝟙_ C))) ≫ (α_ X Y (𝟙_ C)).hom := by rw [associator_naturality] lemma right_unitor_product_aux (X Y : C) : ((α_ X Y (𝟙_ C)).hom ⊗ (𝟙 (𝟙_ C))) ≫ (((𝟙 X) ⊗ (ρ_ Y).hom) ⊗ (𝟙 (𝟙_ C))) = ((ρ_ (X ⊗ Y)).hom ⊗ (𝟙 (𝟙_ C))) := begin rw ←(cancel_mono (α_ X Y (𝟙_ C)).hom), slice_lhs 2 3 { rw ←right_unitor_product_aux_square }, rw [←right_unitor_product_aux_triangle, ←right_unitor_product_aux_perimeter], end -- See Proposition 2.2.4 of <http://www-math.mit.edu/~etingof/egnobookfinal.pdf> @[simp] lemma left_unitor_tensor (X Y : C) : ((α_ (𝟙_ C) X Y).hom) ≫ ((λ_ (X ⊗ Y)).hom) = ((λ_ X).hom ⊗ (𝟙 Y)) := by rw [←tensor_left_iff, id_tensor_comp, left_unitor_product_aux] @[simp] lemma left_unitor_tensor_inv (X Y : C) : ((λ_ (X ⊗ Y)).inv) ≫ ((α_ (𝟙_ C) X Y).inv) = ((λ_ X).inv ⊗ (𝟙 Y)) := eq_of_inv_eq_inv (by simp) @[simp] lemma right_unitor_tensor (X Y : C) : ((α_ X Y (𝟙_ C)).hom) ≫ ((𝟙 X) ⊗ (ρ_ Y).hom) = ((ρ_ (X ⊗ Y)).hom) := by rw [←tensor_right_iff, comp_tensor_id, right_unitor_product_aux] @[simp] lemma right_unitor_tensor_inv (X Y : C) : ((𝟙 X) ⊗ (ρ_ Y).inv) ≫ ((α_ X Y (𝟙_ C)).inv) = ((ρ_ (X ⊗ Y)).inv) := eq_of_inv_eq_inv (by simp) lemma associator_inv_naturality {X Y Z X' Y' Z' : C} (f : X ⟶ X') (g : Y ⟶ Y') (h : Z ⟶ Z') : (f ⊗ (g ⊗ h)) ≫ (α_ X' Y' Z').inv = (α_ X Y Z).inv ≫ ((f ⊗ g) ⊗ h) := begin apply (cancel_mono (α_ X' Y' Z').hom).1, simp only [assoc, comp_id, iso.inv_hom_id], rw [associator_naturality, ←category.assoc, iso.inv_hom_id, category.id_comp] end lemma pentagon_inv (W X Y Z : C) : ((𝟙 W) ⊗ (α_ X Y Z).inv) ≫ (α_ W (X ⊗ Y) Z).inv ≫ ((α_ W X Y).inv ⊗ (𝟙 Z)) = (α_ W X (Y ⊗ Z)).inv ≫ (α_ (W ⊗ X) Y Z).inv := begin apply category_theory.eq_of_inv_eq_inv, dsimp, rw [category.assoc, monoidal_category.pentagon] end @[simp] lemma triangle_assoc_comp_left (X Y : C) : (α_ X (𝟙_ C) Y).hom ≫ ((𝟙 X) ⊗ (λ_ Y).hom) = (ρ_ X).hom ⊗ 𝟙 Y := monoidal_category.triangle C X Y @[simp] lemma triangle_assoc_comp_right (X Y : C) : (α_ X (𝟙_ C) Y).inv ≫ ((ρ_ X).hom ⊗ 𝟙 Y) = ((𝟙 X) ⊗ (λ_ Y).hom) := by rw [←triangle_assoc_comp_left, ←category.assoc, iso.inv_hom_id, category.id_comp] @[simp] lemma triangle_assoc_comp_right_inv (X Y : C) : ((ρ_ X).inv ⊗ 𝟙 Y) ≫ (α_ X (𝟙_ C) Y).hom = ((𝟙 X) ⊗ (λ_ Y).inv) := begin apply (cancel_mono (𝟙 X ⊗ (λ_ Y).hom)).1, simp only [assoc, triangle_assoc_comp_left], rw [←comp_tensor_id, iso.inv_hom_id, ←id_tensor_comp, iso.inv_hom_id] end @[simp] lemma triangle_assoc_comp_left_inv (X Y : C) : ((𝟙 X) ⊗ (λ_ Y).inv) ≫ (α_ X (𝟙_ C) Y).inv = ((ρ_ X).inv ⊗ 𝟙 Y) := begin apply (cancel_mono ((ρ_ X).hom ⊗ 𝟙 Y)).1, simp only [triangle_assoc_comp_right, assoc], rw [←id_tensor_comp, iso.inv_hom_id, ←comp_tensor_id, iso.inv_hom_id] end end section variables (C : Type u) [category.{v} C] [𝒞 : monoidal_category.{v} C] include 𝒞 /-- The tensor product expressed as a functor. -/ def tensor : (C × C) ⥤ C := { obj := λ X, X.1 ⊗ X.2, map := λ {X Y : C × C} (f : X ⟶ Y), f.1 ⊗ f.2 } /-- The left-associated triple tensor product as a functor. -/ def left_assoc_tensor : (C × C × C) ⥤ C := { obj := λ X, (X.1 ⊗ X.2.1) ⊗ X.2.2, map := λ {X Y : C × C × C} (f : X ⟶ Y), (f.1 ⊗ f.2.1) ⊗ f.2.2 } @[simp] lemma left_assoc_tensor_obj (X) : (left_assoc_tensor C).obj X = (X.1 ⊗ X.2.1) ⊗ X.2.2 := rfl @[simp] lemma left_assoc_tensor_map {X Y} (f : X ⟶ Y) : (left_assoc_tensor C).map f = (f.1 ⊗ f.2.1) ⊗ f.2.2 := rfl /-- The right-associated triple tensor product as a functor. -/ def right_assoc_tensor : (C × C × C) ⥤ C := { obj := λ X, X.1 ⊗ (X.2.1 ⊗ X.2.2), map := λ {X Y : C × C × C} (f : X ⟶ Y), f.1 ⊗ (f.2.1 ⊗ f.2.2) } @[simp] lemma right_assoc_tensor_obj (X) : (right_assoc_tensor C).obj X = X.1 ⊗ (X.2.1 ⊗ X.2.2) := rfl @[simp] lemma right_assoc_tensor_map {X Y} (f : X ⟶ Y) : (right_assoc_tensor C).map f = f.1 ⊗ (f.2.1 ⊗ f.2.2) := rfl /-- The functor `λ X, 𝟙_ C ⊗ X`. -/ def tensor_unit_left : C ⥤ C := { obj := λ X, 𝟙_ C ⊗ X, map := λ {X Y : C} (f : X ⟶ Y), (𝟙 (𝟙_ C)) ⊗ f } /-- The functor `λ X, X ⊗ 𝟙_ C`. -/ def tensor_unit_right : C ⥤ C := { obj := λ X, X ⊗ 𝟙_ C, map := λ {X Y : C} (f : X ⟶ Y), f ⊗ (𝟙 (𝟙_ C)) } -- We can express the associator and the unitors, given componentwise above, -- as natural isomorphisms. /-- The associator as a natural isomorphism. -/ def associator_nat_iso : left_assoc_tensor C ≅ right_assoc_tensor C := nat_iso.of_components (by { intros, apply monoidal_category.associator }) (by { intros, apply monoidal_category.associator_naturality }) /-- The left unitor as a natural isomorphism. -/ def left_unitor_nat_iso : tensor_unit_left C ≅ 𝟭 C := nat_iso.of_components (by { intros, apply monoidal_category.left_unitor }) (by { intros, apply monoidal_category.left_unitor_naturality }) /-- The right unitor as a natural isomorphism. -/ def right_unitor_nat_iso : tensor_unit_right C ≅ 𝟭 C := nat_iso.of_components (by { intros, apply monoidal_category.right_unitor }) (by { intros, apply monoidal_category.right_unitor_naturality }) end end monoidal_category end category_theory