Timings for Products.v
Require Import Basics.Equivalences Basics.Overture Basics.Tactics.
Require Import Types.Bool Types.Prod Types.Forall.
Require Import WildCat.Bifunctor WildCat.Core WildCat.Equiv WildCat.EquivGpd
WildCat.Forall WildCat.NatTrans WildCat.Opposite
WildCat.Universe WildCat.Yoneda WildCat.ZeroGroupoid
WildCat.Monoidal WildCat.MonoidalTwistConstruction
WildCat.FunctorCat.
(** * Categories with products *)
Definition cat_prod_corec_inv {I A : Type} `{Is1Cat A}
(prod : A) (x : I -> A) (z : A) (pr : forall i, prod $-> x i)
: yon_0gpd prod z $-> prod_0gpd I (fun i => yon_0gpd (x i) z).
snapply equiv_prod_0gpd_corec.
exact (fmap (fun x => yon_0gpd x z) (pr i)).
(* A product of an [I]-indexed family of objects of a category is an object of the category with an [I]-indexed family of projections such that the induced map is an equivalence. *)
Class Product (I : Type) {A : Type} `{Is1Cat A} {x : I -> A} := Build_Product' {
cat_prod : A;
cat_pr : forall i : I, cat_prod $-> x i;
cat_isequiv_cat_prod_corec_inv
:: forall z : A, CatIsEquiv (cat_prod_corec_inv cat_prod x z cat_pr);
}.
Arguments Product I {A _ _ _ _} x.
Arguments cat_prod I {A _ _ _ _} x {product} : rename.
(** A convenience wrapper for building products *)
Definition Build_Product (I : Type) {A : Type} `{Is1Cat A} {x : I -> A}
(cat_prod : A) (cat_pr : forall i : I, cat_prod $-> x i)
(cat_prod_corec : forall z : A,
(forall i : I, z $-> x i) -> (z $-> cat_prod))
(cat_prod_beta_pr : forall (z : A) (f : forall i, z $-> x i) (i : I),
cat_pr i $o cat_prod_corec z f $== f i)
(cat_prod_eta_pr : forall (z : A) (f g : z $-> cat_prod),
(forall i : I, cat_pr i $o f $== cat_pr i $o g) -> f $== g)
: Product I x.
snapply (Build_Product' I A _ _ _ _ _ cat_prod cat_pr).
napply isequiv_0gpd_issurjinj.
exists (cat_prod_corec z f).
by napply cat_prod_eta_pr.
Context (I : Type) {A : Type} {x : I -> A} `{Product I _ x}.
Definition cate_cat_prod_corec_inv {z : A}
: (yon_0gpd (cat_prod I x) z) $<~> prod_0gpd I (fun i => yon_0gpd (x i) z)
:= Build_CatEquiv (cat_prod_corec_inv (cat_prod I x) x z cat_pr).
Definition cate_cat_prod_corec {z : A}
: prod_0gpd I (fun i => yon_0gpd (x i) z) $<~> (yon_0gpd (cat_prod I x) z)
:= cate_cat_prod_corec_inv^-1$.
Definition cat_prod_corec {z : A}
: (forall i, z $-> x i) -> (z $-> cat_prod I x).
apply cate_cat_prod_corec.
(** Applying the [i]th projection after a tuple of maps gives the [ith] map. *)
Lemma cat_prod_beta {z : A} (f : forall i, z $-> x i)
: forall i, cat_pr i $o cat_prod_corec f $== f i.
exact (cate_isretr cate_cat_prod_corec_inv f).
(** The pairing map is the unique map that makes the following diagram commute. *)
Lemma cat_prod_eta {z : A} (f : z $-> cat_prod I x)
: cat_prod_corec (fun i => cat_pr i $o f) $== f.
exact (cate_issect cate_cat_prod_corec_inv f).
Local Instance is0functor_prod_0gpd_helper
: Is0Functor (fun z : A^op => prod_0gpd I (fun i => yon_0gpd (x i) z)).
snapply Build_Is0Functor.
snapply Build_Is0Functor.
Local Instance is1functor_prod_0gpd_helper
: Is1Functor (fun z : A^op => prod_0gpd I (fun i => yon_0gpd (x i) z)).
snapply Build_Is1Functor.
napply cat_assoc; exact _.
Definition natequiv_cat_prod_corec_inv
: NatEquiv (yon_0gpd (cat_prod I x))
(fun z : A^op => prod_0gpd I (fun i => yon_0gpd (x i) z)).
1: intro; exact cate_cat_prod_corec_inv.
exact (is1natural_yoneda_0gpd
(cat_prod I x)
(fun z => prod_0gpd I (fun i => yon_0gpd (x i) z))
cat_pr).
Lemma cat_prod_corec_eta {z : A} {f f' : forall i, z $-> x i}
: (forall i, f i $== f' i) -> cat_prod_corec f $== cat_prod_corec f'.
napply (moveL_equiv_V_0gpd cate_cat_prod_corec_inv).
nrefine (cate_isretr cate_cat_prod_corec_inv _ $@ _).
Lemma cat_prod_pr_eta {z : A} {f f' : z $-> cat_prod I x}
: (forall i, cat_pr i $o f $== cat_pr i $o f') -> f $== f'.
refine ((cat_prod_eta _)^$ $@ _ $@ cat_prod_eta _).
by napply cat_prod_corec_eta.
Definition cat_prod_diag {I : Type} {A : Type} (x : A)
`{Product I _ (fun _ => x)}
: x $-> cat_prod I (fun _ => x)
:= cat_prod_corec I (fun _ => Id x).
(** *** Uniqueness of products *)
Definition cate_cat_prod {I J : Type} (ie : I <~> J) {A : Type} `{HasEquivs A}
(x : I -> A) `{!Product I x} (y : J -> A) `{!Product J y}
(e : forall i : I, x i $<~> y (ie i))
: cat_prod I x $<~> cat_prod J y.
nrefine (natequiv_compose _ (natequiv_cat_prod_corec_inv _)).
nrefine (natequiv_compose
(natequiv_inverse (natequiv_cat_prod_corec_inv _)) _).
napply (cate_prod_0gpd ie).
exact (natequiv_yon_equiv_0gpd (e i) _).
snapply Build_Is1Natural.
exact (cat_assoc_opp _ _ _).
(** [I]-indexed products are unique no matter how they are constructed. *)
Definition cat_prod_unique {I A : Type} `{HasEquivs A}
(x : I -> A) `{!Product I x} (y : I -> A) `{!Product I y}
(e : forall i : I, x i $<~> y i)
: cat_prod I x $<~> cat_prod I y.
exact (cate_cat_prod 1 x y e).
(** *** Existence of products *)
Class HasProducts (I A : Type) `{Is1Cat A}
:= has_products :: forall x : I -> A, Product I x.
Class HasAllProducts (A : Type) `{Is1Cat A}
:= has_all_products :: forall I : Type, HasProducts I A.
(** *** Product functor *)
Instance is0functor_cat_prod (I : Type) (A : Type) `{HasProducts I A}
: Is0Functor (fun x : I -> A => cat_prod I x).
exact (cat_prod_corec I (fun i => f i $o cat_pr i)).
Instance is1functor_cat_prod (I : Type) (A : Type) `{HasProducts I A}
: Is1Functor (fun x : I -> A => cat_prod I x).
exact (cat_prod_corec_eta I (fun i => p i $@R cat_pr i)).
nrefine (_ $@ (cat_prod_eta I (Id _))).
exact (cat_prod_corec_eta I (fun i => cat_idl _ $@ (cat_idr _)^$)).
nrefine (cat_prod_beta _ _ _ $@ _).
nrefine (_ $@ cat_assoc _ _ _).
nrefine (cat_prod_beta _ _ _ $@R _ $@ _).
nrefine (cat_assoc _ _ _ $@ _).
nrefine (_ $@L cat_prod_beta _ _ _ $@ _).
(** *** Categories with specific kinds of products *)
Definition isterminal_prodempty {A : Type} {z : A}
`{Product Empty A (fun _ => z)}
: IsTerminal (cat_prod Empty (fun _ => z)).
snrefine (cat_prod_corec _ _; fun f => cat_prod_pr_eta _ _); intros [].
(** *** Binary products *)
Class BinaryProduct {A : Type} `{Is1Cat A} (x y : A)
:= binary_product :: Product Bool (fun b => if b then x else y).
(** A category with binary products is a category with a binary product for each pair of objects. *)
Class HasBinaryProducts (A : Type) `{Is1Cat A}
:= has_binary_products :: forall x y : A, BinaryProduct x y.
Instance hasbinaryproducts_hasproductsbool {A : Type} `{HasProducts Bool A}
: HasBinaryProducts A
:= fun x y => has_products (fun b : Bool => if b then x else y).
Context {A : Type} `{Is1Cat A} {x y : A} `{!BinaryProduct x y}.
Definition cat_binprod' : A
:= cat_prod Bool (fun b : Bool => if b then x else y).
Definition cat_pr1 : cat_binprod' $-> x := cat_pr true.
Definition cat_pr2 : cat_binprod' $-> y := cat_pr false.
Definition cat_binprod_corec {z : A} (f : z $-> x) (g : z $-> y)
: z $-> cat_binprod'.
napply (cat_prod_corec Bool).
Definition cat_binprod_beta_pr1 {z : A} (f : z $-> x) (g : z $-> y)
: cat_pr1 $o cat_binprod_corec f g $== f
:= cat_prod_beta _ _ true.
Definition cat_binprod_beta_pr2 {z : A} (f : z $-> x) (g : z $-> y)
: cat_pr2 $o cat_binprod_corec f g $== g
:= cat_prod_beta _ _ false.
Definition cat_binprod_eta {z : A} (f : z $-> cat_binprod')
: cat_binprod_corec (cat_pr1 $o f) (cat_pr2 $o f) $== f.
unfold cat_binprod_corec.
exact (cat_binprod_beta_pr1 _ _).
exact (cat_binprod_beta_pr2 _ _).
Definition cat_binprod_eta_pr {z : A} (f g : z $-> cat_binprod')
: cat_pr1 $o f $== cat_pr1 $o g -> cat_pr2 $o f $== cat_pr2 $o g -> f $== g.
Definition cat_binprod_corec_eta {z : A} (f f' : z $-> x) (g g' : z $-> y)
: f $== f' -> g $== g' -> cat_binprod_corec f g $== cat_binprod_corec f' g'.
rapply cat_prod_corec_eta.
Arguments cat_binprod' {A _ _ _ _} x y {_}.
(** A convenience wrapper for building binary products *)
Definition Build_BinaryProduct {A : Type} `{Is1Cat A} {x y : A}
(cat_binprod' : A) (cat_pr1 : cat_binprod' $-> x) (cat_pr2 : cat_binprod' $-> y)
(cat_binprod_corec : forall z : A, z $-> x -> z $-> y -> z $-> cat_binprod')
(cat_binprod_beta_pr1 : forall (z : A) (f : z $-> x) (g : z $-> y),
cat_pr1 $o cat_binprod_corec z f g $== f)
(cat_binprod_beta_pr2 : forall (z : A) (f : z $-> x) (g : z $-> y),
cat_pr2 $o cat_binprod_corec z f g $== g)
(cat_binprod_eta_pr : forall (z : A) (f g : z $-> cat_binprod'),
cat_pr1 $o f $== cat_pr1 $o g -> cat_pr2 $o f $== cat_pr2 $o g -> f $== g)
: Product Bool (fun b => if b then x else y).
snapply (Build_Product _ cat_binprod').
napply cat_binprod_corec.
napply cat_binprod_beta_pr1.
napply cat_binprod_beta_pr2.
napply cat_binprod_eta_pr.
Definition cat_binprod {A: Type} `{HasBinaryProducts A} x y := cat_binprod' x y.
Definition cat_binprod_eta_pr_x_xx {A : Type} `{HasBinaryProducts A} {w x y z : A}
(f g : w $-> cat_binprod x (cat_binprod y z))
: cat_pr1 $o f $== cat_pr1 $o g
-> cat_pr1 $o cat_pr2 $o f $== cat_pr1 $o cat_pr2 $o g
-> cat_pr2 $o cat_pr2 $o f $== cat_pr2 $o cat_pr2 $o g
-> f $== g.
snapply cat_binprod_eta_pr.
snapply cat_binprod_eta_pr.
exact (cat_assoc_opp _ _ _ $@ q $@ cat_assoc _ _ _).
exact (cat_assoc_opp _ _ _ $@ r $@ cat_assoc _ _ _).
Definition cat_binprod_eta_pr_xx_x {A : Type} `{HasBinaryProducts A} {w x y z : A}
(f g : w $-> cat_binprod (cat_binprod x y) z)
: cat_pr1 $o cat_pr1 $o f $== cat_pr1 $o cat_pr1 $o g
-> cat_pr2 $o cat_pr1 $o f $== cat_pr2 $o cat_pr1 $o g
-> cat_pr2 $o f $== cat_pr2 $o g
-> f $== g.
snapply cat_binprod_eta_pr.
snapply cat_binprod_eta_pr.
1,2: refine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _).
Definition cat_binprod_eta_pr_x_xx_id {A : Type} `{HasBinaryProducts A} {x y z : A}
(f : cat_binprod x (cat_binprod y z) $-> cat_binprod x (cat_binprod y z))
: cat_pr1 $o f $== cat_pr1
-> cat_pr1 $o cat_pr2 $o f $== cat_pr1 $o cat_pr2
-> cat_pr2 $o cat_pr2 $o f $== cat_pr2 $o cat_pr2
-> f $== Id _.
snapply cat_binprod_eta_pr_x_xx.
exact (p $@ (cat_idr _)^$).
exact (q $@ (cat_idr _)^$).
exact (r $@ (cat_idr _)^$).
(** From binary products, all [Bool]-shaped products can be constructed. This should not be an instance to avoid a cycle with [hasbinaryproducts_hasproductsbool]. *)
Definition hasproductsbool_hasbinaryproducts {A : Type} `{HasBinaryProducts A}
: HasProducts Bool A.
exact (cat_binprod (x true) (x false)).
exact (cat_binprod_corec (f true) (f false)).
exact (cat_binprod_beta_pr1 (f true) (f false)).
exact (cat_binprod_beta_pr2 (f true) (f false)).
napply cat_binprod_eta_pr.
(** *** Operations on indexed products *)
(** We can take the disjoint union of the index set of an indexed product if we have all binary products. This is useful for associating products in a canonical way. This leads to symmetry and associativity of binary products. *)
Definition cat_prod_index_sum {I J : Type} {A : Type} `{HasBinaryProducts A}
(x : I -> A) (y : J -> A)
: Product I x -> Product J y -> Product (I + J) (sum_ind _ x y).
exact (cat_binprod (cat_prod I x) (cat_prod J y)).
exact (cat_pr _ $o cat_pr1).
exact (cat_pr _ $o cat_pr2).
napply cat_binprod_corec.
nrefine (cat_assoc _ _ _ $@ _).
nrefine ((_ $@L cat_binprod_beta_pr1 _ _) $@ _).
nrefine (cat_assoc _ _ _ $@ _).
nrefine ((_ $@L cat_binprod_beta_pr2 _ _) $@ _).
rapply cat_binprod_eta_pr.
exact ((cat_assoc _ _ _)^$ $@ r (inl i) $@ cat_assoc _ _ _).
exact ((cat_assoc _ _ _)^$ $@ r (inr j) $@ cat_assoc _ _ _).
(** *** Binary product functor *)
(** We prove bifunctoriality of [cat_binprod : A -> A -> A] by factoring it as [cat_prod Bool o Bool_rec A]. First, we prove that [Bool_rec A : A -> A -> (Bool -> A)] is a bifunctor. *)
Local Instance is0bifunctor_boolrec {A : Type} `{Is1Cat A}
: Is0Bifunctor (Bool_rec A).
snapply Build_Is0Bifunctor'.
snapply Build_Is0Functor.
intros [a b] [a' b'] [f g] [ | ].
Local Instance is1bifunctor_boolrec {A : Type} `{Is1Cat A}
: Is1Bifunctor (Bool_rec A).
snapply Build_Is1Bifunctor'.
snapply Build_Is1Functor.
intros [a b] [a' b'] [f g] [f' g'] [p q] [ | ].
intros [a b] [ | ]; reflexivity.
intros [a b] [a' b'] [a'' b''] [f f'] [g g'] [ | ]; reflexivity.
(** As a special case of the product functor, restriction along [Bool_rec A] yields bifunctoriality of [cat_binprod]. *)
Instance is0bifunctor_cat_binprod {A : Type} `{HasBinaryProducts A}
: Is0Bifunctor (fun x y => cat_binprod x y).
pose (p:=@has_products _ _ _ _ _ _ hasproductsbool_hasbinaryproducts).
exact (is0bifunctor_postcompose
(Bool_rec A) (fun x => cat_prod Bool x (product:=p x))).
Instance is1bifunctor_cat_binprod {A : Type} `{HasBinaryProducts A}
: Is1Bifunctor (fun x y => cat_binprod x y).
pose (p:=@has_products _ _ _ _ _ _ hasproductsbool_hasbinaryproducts).
exact (is1bifunctor_postcompose
(Bool_rec A) (fun x => cat_prod Bool x (product:=p x))).
(** Binary products are functorial in each argument. *)
Instance is0functor_cat_binprod_l {A : Type} `{HasBinaryProducts A}
(y : A)
: Is0Functor (fun x => cat_binprod x y).
exact (is0functor10_bifunctor (fun x y => cat_binprod x y) y).
Instance is1functor_cat_binprod_l {A : Type} `{HasBinaryProducts A}
(y : A)
: Is1Functor (fun x => cat_binprod x y).
exact (is1functor10_bifunctor _ y).
Instance is0functor_cat_binprod_r {A : Type} `{HasBinaryProducts A}
(x : A)
: Is0Functor (fun y => cat_binprod x y).
exact (is0functor01_bifunctor (fun x y => cat_binprod x y) x).
Instance is1functor_cat_binprod_r {A : Type} `{HasBinaryProducts A}
(x : A)
: Is1Functor (fun y => cat_binprod x y).
exact (is1functor01_bifunctor _ x).
(** [cat_binprod_corec] is also functorial in each morphism. *)
Instance is0functor_cat_binprod_corec_l {A : Type}
`{HasBinaryProducts A} {x y z : A} (g : z $-> y)
: Is0Functor (fun f : z $-> y => cat_binprod_corec f g).
snapply Build_Is0Functor.
by napply cat_binprod_corec_eta.
Instance is0functor_cat_binprod_corec_r {A : Type}
`{HasBinaryProducts A} {x y z : A} (f : z $-> x)
: Is0Functor (fun g : z $-> x => cat_binprod_corec f g).
snapply Build_Is0Functor.
by napply cat_binprod_corec_eta.
Definition cat_pr1_fmap01_binprod {A : Type} `{HasBinaryProducts A}
(a : A) {x y : A} (g : x $-> y)
: cat_pr1 $o fmap01 (fun x y => cat_binprod x y) a g $== cat_pr1
:= cat_binprod_beta_pr1 _ _ $@ cat_idl _.
Definition cat_pr1_fmap10_binprod {A : Type} `{HasBinaryProducts A}
{x y : A} (f : x $-> y) (a : A)
: cat_pr1 $o fmap10 (fun x y => cat_binprod x y) f a $== f $o cat_pr1
:= cat_binprod_beta_pr1 _ _.
Definition cat_pr1_fmap11_binprod {A : Type} `{HasBinaryProducts A}
{w x y z : A} (f : w $-> y) (g : x $-> z)
: cat_pr1 $o fmap11 (fun x y => cat_binprod x y) f g $== f $o cat_pr1
:= cat_binprod_beta_pr1 _ _.
Definition cat_pr2_fmap01_binprod {A : Type} `{HasBinaryProducts A}
(a : A) {x y : A} (g : x $-> y)
: cat_pr2 $o fmap01 (fun x y => cat_binprod x y) a g $== g $o cat_pr2
:= cat_binprod_beta_pr2 _ _.
Definition cat_pr2_fmap10_binprod {A : Type} `{HasBinaryProducts A}
{x y : A} (f : x $-> y) (a : A)
: cat_pr2 $o fmap10 (fun x y => cat_binprod x y) f a $== cat_pr2
:= cat_binprod_beta_pr2 _ _ $@ cat_idl _.
Definition cat_pr2_fmap11_binprod {A : Type} `{HasBinaryProducts A}
{w x y z : A} (f : w $-> y) (g : x $-> z)
: cat_pr2 $o fmap11 (fun x y => cat_binprod x y) f g $== g $o cat_pr2
:= cat_binprod_beta_pr2 _ _.
(** *** Diagonal *)
(** Annoyingly this doesn't follow directly from the general diagonal since [fun b => if b then x else x] is not definitionally equal to [fun _ => x]. *)
Definition cat_binprod_diag {A : Type}
`{Is1Cat A} (x : A) `{!BinaryProduct x x}
: x $-> cat_binprod' x x.
snapply cat_binprod_corec; exact (Id _).
(** *** Lemmas about [cat_binprod_corec] *)
Definition cat_binprod_fmap01_corec {A : Type}
`{Is1Cat A, !HasBinaryProducts A} {w x y z : A}
(f : w $-> z) (g : x $-> y) (h : w $-> x)
: fmap01 (fun x y => cat_binprod x y) z g $o cat_binprod_corec f h
$== cat_binprod_corec f (g $o h).
snapply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ cat_idl _ $@ _ $@ _^$).
1-3: rapply cat_binprod_beta_pr1.
nrefine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L _) $@ _^$).
1-3: rapply cat_binprod_beta_pr2.
Definition cat_binprod_fmap10_corec {A : Type}
`{Is1Cat A, !HasBinaryProducts A} {w x y z : A}
(f : x $-> y) (g : w $-> x) (h : w $-> z)
: fmap10 (fun x y => cat_binprod x y) f z $o cat_binprod_corec g h
$== cat_binprod_corec (f $o g) h.
snapply cat_binprod_eta_pr.
refine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L _) $@ _^$).
1-3: napply cat_binprod_beta_pr1.
refine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ cat_idl _ $@ _ $@ _^$).
1-3: napply cat_binprod_beta_pr2.
Definition cat_binprod_fmap11_corec {A : Type}
`{Is1Cat A, !HasBinaryProducts A} {v w x y z : A}
(f : w $-> y) (g : x $-> z) (h : v $-> w) (i : v $-> x)
: fmap11 (fun x y => cat_binprod x y) f g $o cat_binprod_corec h i
$== cat_binprod_corec (f $o h) (g $o i).
snapply cat_binprod_eta_pr.
refine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L _) $@ _^$).
1-3: napply cat_binprod_beta_pr1.
nrefine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L _) $@ _^$).
1-3: rapply cat_binprod_beta_pr2.
(** *** Symmetry of binary products *)
(** The requirement of having all binary products can be weakened further to having specific binary products, but it is not clear this is a useful generality. *)
Context {A : Type} `{HasEquivs A} `{!HasBinaryProducts A}.
Definition cat_binprod_swap (x y : A) : cat_binprod x y $-> cat_binprod y x
:= cat_binprod_corec cat_pr2 cat_pr1.
Lemma cat_binprod_swap_cat_binprod_swap (x y : A)
: cat_binprod_swap x y $o cat_binprod_swap y x $== Id _.
napply cat_binprod_eta_pr.
refine ((cat_assoc _ _ _)^$ $@ _).
nrefine (cat_binprod_beta_pr1 _ _ $@R _ $@ _).
exact (cat_binprod_beta_pr2 _ _ $@ (cat_idr _)^$).
refine ((cat_assoc _ _ _)^$ $@ _).
nrefine (cat_binprod_beta_pr2 _ _ $@R _ $@ _).
exact (cat_binprod_beta_pr1 _ _ $@ (cat_idr _)^$).
Lemma cate_binprod_swap (x y : A)
: cat_binprod x y $<~> cat_binprod y x.
1,2: napply cat_binprod_swap.
all: napply cat_binprod_swap_cat_binprod_swap.
Definition cat_binprod_swap_corec {a b c : A} (f : a $-> b) (g : a $-> c)
: cat_binprod_swap b c $o cat_binprod_corec f g $== cat_binprod_corec g f.
napply cat_binprod_eta_pr.
refine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ (_ $@ _^$)).
1,3: napply cat_binprod_beta_pr1.
napply cat_binprod_beta_pr2.
refine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ (_ $@ _^$)).
1,3: napply cat_binprod_beta_pr2.
napply cat_binprod_beta_pr1.
Definition cat_binprod_swap_nat {a b c d : A} (f : a $-> c) (g : b $-> d)
: cat_binprod_swap c d $o fmap11 (fun x y : A => cat_binprod x y) f g
$== fmap11 (fun x y : A => cat_binprod x y) g f $o cat_binprod_swap a b
:= cat_binprod_swap_corec _ _ $@ (cat_binprod_fmap11_corec _ _ _ _)^$.
Local Instance symmetricbraiding_binprod
: SymmetricBraiding (fun x y => cat_binprod x y).
snapply Build_SymmetricBraiding.
exact (cat_binprod_swap x y).
snapply Build_Is1Natural.
intros [a b] [c d] [f g]; cbn in f, g.
exact(cat_binprod_swap_nat f g).
exact cat_binprod_swap_cat_binprod_swap.
(** *** Associativity of binary products *)
Context {A : Type} `{HasEquivs A} `{!HasBinaryProducts A}.
Definition cat_binprod_twist (x y z : A)
: cat_binprod x (cat_binprod y z) $-> cat_binprod y (cat_binprod x z).
napply cat_binprod_corec.
exact (cat_pr1 $o cat_pr2).
exact (fmap01 cat_binprod x cat_pr2).
Definition cat_binprod_pr1_twist (x y z : A)
: cat_pr1 $o cat_binprod_twist x y z $== cat_pr1 $o cat_pr2
:= cat_binprod_beta_pr1 _ _.
Definition cat_binprod_pr1_pr2_twist (x y z : A)
: cat_pr1 $o cat_pr2 $o cat_binprod_twist x y z $== cat_pr1.
nrefine (cat_assoc _ _ _ $@ _).
nrefine ((_ $@L cat_binprod_beta_pr2 _ _) $@ _).
napply cat_pr1_fmap01_binprod.
Definition cat_binprod_pr2_pr2_twist (x y z : A)
: cat_pr2 $o cat_pr2 $o cat_binprod_twist x y z $== cat_pr2 $o cat_pr2.
nrefine (cat_assoc _ _ _ $@ _).
nrefine ((_ $@L cat_binprod_beta_pr2 _ _) $@ _).
napply cat_pr2_fmap01_binprod.
Definition cat_binprod_twist_corec {w x y z : A}
(f : w $-> x) (g : w $-> y) (h : w $-> z)
: cat_binprod_twist x y z $o cat_binprod_corec f (cat_binprod_corec g h)
$== cat_binprod_corec g (cat_binprod_corec f h).
napply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ _).
refine ((_ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L _) $@ (_ $@ _^$)).
1: napply cat_binprod_pr1_twist.
1: napply cat_binprod_beta_pr2.
1,2: napply cat_binprod_beta_pr1.
refine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ _ $@ (cat_binprod_beta_pr2 _ _)^$).
1: napply cat_binprod_beta_pr2.
nrefine (cat_binprod_fmap01_corec _ _ _ $@ _).
napply cat_binprod_corec_eta.
napply cat_binprod_beta_pr2.
Lemma cat_binprod_twist_cat_binprod_twist (x y z : A)
: cat_binprod_twist x y z $o cat_binprod_twist y x z $== Id _.
napply cat_binprod_eta_pr_x_xx_id.
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_pr1_twist _ _ _ $@R _) $@ _).
napply cat_binprod_pr1_pr2_twist.
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_pr1_pr2_twist _ _ _ $@R _) $@ _).
napply cat_binprod_pr1_twist.
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_pr2_pr2_twist _ _ _ $@R _) $@ _).
napply cat_binprod_pr2_pr2_twist.
Definition cate_binprod_twist (x y z : A)
: cat_binprod x (cat_binprod y z) $<~> cat_binprod y (cat_binprod x z).
1,2: napply cat_binprod_twist.
1,2: napply cat_binprod_twist_cat_binprod_twist.
Definition cat_binprod_twist_nat {a a' b b' c c' : A}
(f : a $-> a') (g : b $-> b') (h : c $-> c')
: cat_binprod_twist a' b' c'
$o fmap11 cat_binprod f (fmap11 cat_binprod g h)
$== fmap11 cat_binprod g (fmap11 cat_binprod f h)
$o cat_binprod_twist a b c.
napply cat_binprod_eta_pr.
refine (cat_assoc_opp _ _ _ $@ _).
nrefine ((cat_binprod_beta_pr1 _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ _).
nrefine ((_ $@L _) $@ _).
1: napply cat_pr2_fmap11_binprod.
nrefine (cat_assoc_opp _ _ _ $@ _).
nrefine ((_ $@R _) $@ _).
1: napply cat_pr1_fmap11_binprod.
nrefine (_ $@ cat_assoc _ _ _).
refine (_ $@ (_^$ $@R _)).
2: napply cat_pr1_fmap11_binprod.
refine (cat_assoc _ _ _ $@ (_ $@L _^$) $@ (cat_assoc _ _ _)^$).
napply cat_binprod_beta_pr1.
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr2 _ _ $@R _) $@ _).
nrefine (_ $@ cat_assoc _ _ _).
refine (_ $@ (_^$ $@R _)).
2: napply cat_pr2_fmap11_binprod.
refine (_ $@ (_ $@L _^$) $@ (cat_assoc _ _ _)^$).
2: napply cat_binprod_beta_pr2.
1: exact (cat_idl _ $@ (cat_idr _)^$).
napply cat_binprod_beta_pr2.
Local Existing Instance symmetricbraiding_binprod.
Local Instance associator_cat_binprod : Associator cat_binprod.
snapply associator_twist.
exact cat_binprod_twist_cat_binprod_twist.
intros ? ? ? ? ? ?; exact cat_binprod_twist_nat.
Definition cat_pr1_pr1_associator_binprod x y z
: cat_pr1 $o cat_pr1 $o associator_cat_binprod x y z $== cat_pr1.
nrefine ((_ $@L associator_twist'_unfold _ _ _ _ _ _ _ _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L (cat_assoc_opp _ _ _ $@ (_ $@R _))) $@ _).
1: napply cat_binprod_beta_pr1.
do 2 nrefine (cat_assoc_opp _ _ _ $@ _).
nrefine ((cat_binprod_pr1_pr2_twist _ _ _ $@R _) $@ _).
napply cat_pr1_fmap01_binprod.
Definition cat_pr2_pr1_associator_binprod x y z
: cat_pr2 $o cat_pr1 $o associator_cat_binprod x y z $== cat_pr1 $o cat_pr2.
nrefine ((_ $@L associator_twist'_unfold _ _ _ _ _ _ _ _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L (cat_assoc_opp _ _ _ $@ (_ $@R _))) $@ _).
1: napply cat_binprod_beta_pr1.
do 2 nrefine (cat_assoc_opp _ _ _ $@ _).
nrefine ((cat_binprod_pr2_pr2_twist _ _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L cat_pr2_fmap01_binprod _ _) $@ _).
exact (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr2 _ _ $@R _)).
Definition cat_pr2_associator_binprod x y z
: cat_pr2 $o associator_cat_binprod x y z $== cat_pr2 $o cat_pr2.
nrefine ((_ $@L associator_twist'_unfold _ _ _ _ _ _ _ _) $@ _).
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr2 _ _ $@R _) $@ _).
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_pr1_twist _ _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L cat_pr2_fmap01_binprod _ _) $@ _).
exact (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr1 _ _ $@R _)).
Definition cat_binprod_associator_corec {w x y z}
(f : w $-> x) (g : w $-> y) (h : w $-> z)
: associator_cat_binprod x y z $o cat_binprod_corec f (cat_binprod_corec g h)
$== cat_binprod_corec (cat_binprod_corec f g) h.
nrefine ((associator_twist'_unfold _ _ _ _ _ _ _ _ $@R _) $@ _).
nrefine ((cat_assoc_opp _ _ _ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L (_ $@ _)) $@ _).
1: napply cat_binprod_fmap01_corec.
1: rapply (cat_binprod_corec_eta _ _ _ _ (Id _)).
1: napply cat_binprod_swap_corec.
nrefine (cat_assoc _ _ _ $@ (_ $@L _) $@ _).
1: napply cat_binprod_twist_corec.
napply cat_binprod_swap_corec.
Context (unit : A) `{!IsTerminal unit}.
Local Instance right_unitor_binprod
: RightUnitor (fun x y => cat_binprod x y) unit.
exact (cat_binprod_corec (Id _) (mor_terminal _ _)).
exact (cat_binprod_beta_pr1 _ _).
napply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr1 _ _ $@R _) $@ _).
exact (cat_idl _ $@ (cat_idr _)^$).
nrefine (cat_assoc_opp _ _ _ $@ (cat_binprod_beta_pr2 _ _ $@R _) $@ _).
exact ((mor_terminal_unique _ _ _)^$ $@ mor_terminal_unique _ _ _).
snapply Build_Is1Natural.
refine ((_ $@R _) $@ _ $@ (_ $@L _^$)).
1,3: napply cate_buildequiv_fun.
napply cat_binprod_beta_pr1.
Local Existing Instance left_unitor_twist.
Local Instance triangle_binprod
: TriangleIdentity (fun x y => cat_binprod x y) unit.
refine (fmap02 _ _ _ $@ _ $@ ((_ $@L fmap02 _ _ _^$) $@R _)).
1,3: napply cate_buildequiv_fun.
napply cat_binprod_eta_pr.
nrefine (cat_pr1_fmap01_binprod _ _ $@ _ $@ cat_assoc _ _ _).
refine (_ $@ (((_^$ $@R _) $@ cat_assoc _ _ _) $@R _)).
2: napply cat_binprod_beta_pr1.
refine ((_ $@R _) $@ _)^$.
1: napply cat_pr2_fmap01_binprod.
napply cat_binprod_pr1_pr2_twist.
nrefine (cat_pr2_fmap01_binprod _ _ $@ _ $@ cat_assoc _ _ _).
refine (_ $@ (((cat_binprod_beta_pr2 _ _)^$ $@R _) $@ cat_assoc _ _ _ $@R _)).
refine ((_ $@R _) $@ _)^$.
1: napply cat_pr1_fmap01_binprod.
napply cat_binprod_beta_pr1.
Local Instance pentagon_binprod
: PentagonIdentity (fun x y => cat_binprod x y).
napply cat_binprod_eta_pr_xx_x.
nrefine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ _).
1: napply cat_pr1_pr1_associator_binprod.
refine (_ $@ (_ $@L ((((_^$ $@R _) $@ cat_assoc _ _ _) $@R _)
$@ cat_assoc _ _ _)) $@ cat_assoc_opp _ _ _).
2: napply cat_pr1_fmap10_binprod.
do 2 nrefine (_ $@ (_ $@L cat_assoc_opp _ _ _)).
napply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _).
refine (_ $@ _ $@ (_^$ $@R _) $@ cat_assoc _ _ _).
1,3: napply cat_pr1_pr1_associator_binprod.
do 2 nrefine (_ $@ cat_assoc _ _ _).
refine (_^$ $@ (_^$ $@R _)).
2: napply cat_pr1_pr1_associator_binprod.
napply cat_pr1_fmap01_binprod.
nrefine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _).
refine (_ $@ _ $@ (_^$ $@R _) $@ cat_assoc _ _ _).
1,3: napply cat_pr2_pr1_associator_binprod.
do 2 nrefine (_ $@ cat_assoc _ _ _).
refine (_ $@ ((cat_assoc _ _ _ $@ (_ $@L (_^$ $@ cat_assoc _ _ _))
$@ cat_assoc_opp _ _ _ $@ cat_assoc_opp _ _ _) $@R _)).
2: napply cat_pr2_pr1_associator_binprod.
refine (_^$ $@ (_ $@L _^$) $@ cat_assoc_opp _ _ _).
2: napply cat_pr2_fmap01_binprod.
nrefine (cat_assoc_opp _ _ _ $@ (_ $@R _)).
napply cat_pr1_pr1_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ _).
1: napply cat_pr2_pr1_associator_binprod.
nrefine (cat_assoc _ _ _ $@ _ $@ cat_assoc_opp _ _ _).
nrefine ((_ $@L cat_pr2_associator_binprod _ _ _) $@ _).
refine (_ $@ (_ $@L ((((_^$ $@R _) $@ cat_assoc _ _ _) $@R _) $@ cat_assoc _ _ _))).
2: napply cat_pr1_fmap10_binprod.
nrefine (_ $@ (_ $@L (cat_assoc_opp _ _ _ $@ cat_assoc_opp _ _ _))).
refine (_ $@ (_^$ $@R _) $@ cat_assoc _ _ _).
2: napply cat_pr2_associator_binprod.
refine (_ $@ (_ $@L ((_^$ $@R _) $@ cat_assoc _ _ _ $@ cat_assoc _ _ _)) $@ cat_assoc_opp _ _ _).
2: napply cat_pr2_pr1_associator_binprod.
refine (_ $@ (_ $@L ((_ $@L _^$) $@ cat_assoc_opp _ _ _))).
2: napply cat_pr2_fmap01_binprod.
refine (cat_assoc_opp _ _ _ $@ (_^$ $@R _) $@ cat_assoc _ _ _ $@ cat_assoc _ _ _).
napply cat_pr2_pr1_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ (cat_pr2_associator_binprod _ _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L (cat_pr2_associator_binprod _ _ _)) $@ _).
refine (_ $@ (_^$ $@R _) $@ cat_assoc _ _ _ $@ (_ $@L (cat_assoc_opp _ _ _))).
2: napply cat_pr2_fmap10_binprod.
refine (_ $@ cat_assoc_opp _ _ _ $@ (_^$ $@R _) $@ cat_assoc _ _ _).
2: napply cat_pr2_associator_binprod.
refine (cat_assoc_opp _ _ _ $@ (_^$ $@R _) $@ cat_assoc _ _ _
$@ (_ $@L (cat_pr2_fmap01_binprod _ _)^$)).
napply cat_pr2_associator_binprod.
Local Instance hexagon_identity
: HexagonIdentity (fun x y => cat_binprod x y).
nrefine (cat_assoc _ _ _ $@ _ $@ cat_assoc_opp _ _ _).
napply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ (cat_pr1_fmap10_binprod _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ _).
napply cat_binprod_eta_pr.
nrefine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _ $@ cat_assoc _ _ _).
refine ((_ $@R _) $@ _ $@ (_^$ $@R _)).
1: napply cat_binprod_beta_pr1.
2: napply cat_pr1_pr1_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _).
refine ((_ $@R _) $@ _ $@ (_^$ $@R _)).
1: napply cat_pr2_pr1_associator_binprod.
2: napply cat_binprod_beta_pr1.
refine (cat_assoc _ _ _ $@ (_ $@L _) $@ cat_assoc_opp _ _ _ $@ (_ $@R _) $@ _^$).
1: napply cat_pr2_fmap01_binprod.
2: napply cat_pr2_associator_binprod.
napply cat_binprod_beta_pr1.
nrefine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _ $@ cat_assoc _ _ _).
refine ((_ $@R _) $@ _ $@ (_^$ $@R _)).
1: napply cat_binprod_beta_pr2.
2: napply cat_pr2_pr1_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _).
refine ((_ $@R _) $@ _ $@ (((_ $@L _^$) $@ cat_assoc_opp _ _ _) $@R _)).
1: napply cat_pr1_pr1_associator_binprod.
2: napply cat_binprod_beta_pr2.
refine (cat_pr1_fmap01_binprod _ _ $@ _^$).
napply cat_pr1_pr1_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ _ $@ cat_assoc _ _ _ $@ cat_assoc _ _ _).
refine ((_ $@R _) $@ _ $@ ((_^$ $@R _) $@R _)).
1: napply cat_pr2_fmap10_binprod.
2: napply cat_pr2_associator_binprod.
nrefine (cat_assoc_opp _ _ _ $@ (cat_pr2_associator_binprod _ _ _ $@R _) $@ _).
nrefine (cat_assoc _ _ _ $@ (_ $@L _) $@ _ $@ (cat_assoc_opp _ _ _ $@R _)).
1: napply cat_pr2_fmap01_binprod.
refine (cat_assoc_opp _ _ _ $@ (_ $@R _) $@ _^$ $@ ((_ $@L _^$) $@R _)).
1,3: napply cat_binprod_beta_pr2.
napply cat_pr2_pr1_associator_binprod.
#[export] Instance ismonoidal_cat_binprod
: IsMonoidal A (fun x y => cat_binprod x y) unit
:= {}.
#[export] Instance issymmetricmonoidal_cat_binprod
: IsSymmetricMonoidal A (fun x y => cat_binprod x y) unit
:= {}.
(** *** Products in Type *)
(** Since we use the Yoneda lemma in this file, we therefore depend on WildCat.Universe which means these instances have to live here. *)
Instance hasbinaryproducts_type : HasBinaryProducts Type.
snapply Build_BinaryProduct.
(** Assuming [Funext], [Type] has all products. *)
Instance hasallproducts_type `{Funext} : HasAllProducts Type.
exact (forall (i : I), x i).
exact (path_forall _ _ (fun i => p i a)).