Timings for Smash.v
Require Import Basics.Overture Basics.PathGroupoids Basics.Tactics Basics.Equivalences.
Require Import Types.Sum Types.Bool Types.Paths Types.Forall.
Require Import WildCat.Core WildCat.Bifunctor WildCat.Equiv.
Require Import Colimits.Pushout.
Require Import Cubical.DPath.
Require Import Pointed.Core.
Local Open Scope pointed_scope.
Local Open Scope dpath_scope.
Local Open Scope path_scope.
(* Definition of smash product *)
Definition sum_to_prod (X Y : pType) : X + Y -> X * Y
:= sum_ind _ (fun x => (x, point Y)) (fun y => (point X, y)).
Definition sum_to_bool X Y : X + Y -> Bool
:= sum_ind _ (fun _ => false) (fun _ => true).
Definition Smash@{u v w | u <= w, v <= w} (X : pType@{u}) (Y : pType@{v}) : pType@{w}
:= [Pushout@{w w w w} (sum_to_prod@{w w w} X Y) (sum_to_bool@{u v w} X Y), pushl (point X, point Y)].
Definition sm (x : X) (y : Y) : Smash X Y := pushl (x, y).
Definition auxl : Smash X Y := pushr false.
Definition auxr : Smash X Y := pushr true.
Definition gluel (x : X) : sm x pt = auxl
:= pglue (f:=sum_to_prod X Y) (g:=sum_to_bool X Y) (inl x).
Definition gluer (y : Y) : sm pt y = auxr
:= pglue (f:=sum_to_prod X Y) (g:=sum_to_bool X Y) (inr y).
Definition gluel' (x x' : X) : sm x pt = sm x' pt
:= gluel x @ (gluel x')^.
Definition gluer' (y y' : Y) : sm pt y = sm pt y'
:= gluer y @ (gluer y')^.
Definition glue (x : X) (y : Y) : sm x pt = sm pt y
:= gluel' x pt @ gluer' pt y.
Definition glue_pt_left (y : Y) : glue pt y = gluer' pt y.
refine (_ @ concat_1p _).
apply whiskerR, concat_pV.
Definition glue_pt_right (x : X) : glue x pt = gluel' x pt.
refine (_ @ concat_p1 _).
apply whiskerL, concat_pV.
Definition ap_sm_left {x x' : X} (p : x = x')
: ap (fun t => sm t pt) p = gluel' x x'.
Definition ap_sm_right {y y' : Y} (p : y = y')
: ap (sm pt) p = gluer' y y'.
Definition Smash_ind {P : Smash X Y -> Type}
(Psm : forall a b, P (sm a b)) (Pl : P auxl) (Pr : P auxr)
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr)
: forall x : Smash X Y, P x.
exact (Bool_ind _ Pr Pl).
Definition Smash_ind_beta_gluel {P : Smash X Y -> Type}
{Psm : forall a b, P (sm a b)} {Pl : P auxl} {Pr : P auxr}
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr) (a : X)
: apD (Smash_ind Psm Pl Pr Pgl Pgr) (gluel a) = Pgl a
:= Pushout_ind_beta_pglue P _ _ _ (inl a).
Definition Smash_ind_beta_gluer {P : Smash X Y -> Type}
{Psm : forall a b, P (sm a b)} {Pl : P auxl} {Pr : P auxr}
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr) (b : Y)
: apD (Smash_ind Psm Pl Pr Pgl Pgr) (gluer b) = Pgr b
:= Pushout_ind_beta_pglue P _ _ _ (inr b).
Definition Smash_ind_beta_gluel' {P : Smash X Y -> Type}
{Psm : forall a b, P (sm a b)} {Pl : P auxl} {Pr : P auxr}
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr) (a b : X)
: apD (Smash_ind Psm Pl Pr Pgl Pgr) (gluel' a b)
= (Pgl a) @Dp ((Pgl b)^D).
1: apply Smash_ind_beta_gluel.
apply Smash_ind_beta_gluel.
Definition Smash_ind_beta_gluer' {P : Smash X Y -> Type}
{Psm : forall a b, P (sm a b)} {Pl : P auxl} {Pr : P auxr}
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr) (a b : Y)
: apD (Smash_ind Psm Pl Pr Pgl Pgr) (gluer' a b)
= (Pgr a) @Dp ((Pgr b)^D).
1: apply Smash_ind_beta_gluer.
apply Smash_ind_beta_gluer.
Definition Smash_ind_beta_glue {P : Smash X Y -> Type}
{Psm : forall a b, P (sm a b)} {Pl : P auxl} {Pr : P auxr}
(Pgl : forall a, DPath P (gluel a) (Psm a pt) Pl)
(Pgr : forall b, DPath P (gluer b) (Psm pt b) Pr) (a : X) (b : Y)
: apD (Smash_ind Psm Pl Pr Pgl Pgr) (glue a b)
= ((Pgl a) @Dp ((Pgl pt)^D)) @Dp ((Pgr pt) @Dp ((Pgr b)^D)).
apply Smash_ind_beta_gluel'.
apply Smash_ind_beta_gluer'.
Definition Smash_rec {P : Type} (Psm : X -> Y -> P) (Pl Pr : P)
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr)
: Smash X Y -> P
:= Smash_ind Psm Pl Pr (fun x => dp_const (Pgl x)) (fun x => dp_const (Pgr x)).
(* Version of smash_rec that forces (Pgl pt) and (Pgr pt) to be idpath *)
Definition Smash_rec' {P : Type} {Psm : X -> Y -> P}
(Pgl : forall a, Psm a pt = Psm pt pt) (Pgr : forall b, Psm pt b = Psm pt pt)
(ql : Pgl pt = 1) (qr : Pgr pt = 1)
: Smash X Y -> P
:= Smash_rec Psm (Psm pt pt) (Psm pt pt) Pgl Pgr.
Definition Smash_rec_beta_gluel {P : Type} {Psm : X -> Y -> P} {Pl Pr : P}
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr) (a : X)
: ap (Smash_rec Psm Pl Pr Pgl Pgr) (gluel a) = Pgl a.
rhs_V napply (eissect dp_const).
lhs_V napply dp_apD_const.
napply Smash_ind_beta_gluel.
Definition Smash_rec_beta_gluer {P : Type} {Psm : X -> Y -> P} {Pl Pr : P}
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr) (b : Y)
: ap (Smash_rec Psm Pl Pr Pgl Pgr) (gluer b) = Pgr b.
rhs_V napply (eissect dp_const).
lhs_V napply dp_apD_const.
napply Smash_ind_beta_gluer.
Definition Smash_rec_beta_gluel' {P : Type} {Psm : X -> Y -> P} {Pl Pr : P}
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr) (a b : X)
: ap (Smash_rec Psm Pl Pr Pgl Pgr) (gluel' a b) = Pgl a @ (Pgl b)^.
1: apply Smash_rec_beta_gluel.
apply Smash_rec_beta_gluel.
Definition Smash_rec_beta_gluer' {P : Type} {Psm : X -> Y -> P} {Pl Pr : P}
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr) (a b : Y)
: ap (Smash_rec Psm Pl Pr Pgl Pgr) (gluer' a b) = Pgr a @ (Pgr b)^.
1: apply Smash_rec_beta_gluer.
apply Smash_rec_beta_gluer.
Definition Smash_rec_beta_glue {P : Type} {Psm : X -> Y -> P} {Pl Pr : P}
(Pgl : forall a, Psm a pt = Pl) (Pgr : forall b, Psm pt b = Pr) (a : X)
(b : Y) : ap (Smash_rec Psm Pl Pr Pgl Pgr) (glue a b)
= ((Pgl a) @ (Pgl pt)^) @ (Pgr pt @ (Pgr b)^).
apply Smash_rec_beta_gluel'.
apply Smash_rec_beta_gluer'.
Arguments sm : simpl never.
Arguments auxl : simpl never.
Arguments gluel : simpl never.
Arguments gluer : simpl never.
(** ** Miscellaneous lemmas about Smash *)
(** A version of [Smash_ind] specifically for proving that two functions from a [Smash] are homotopic. *)
Definition Smash_ind_FlFr {A B : pType} {P : Type} (f g : Smash A B -> P)
(Hsm : forall a b, f (sm a b) = g (sm a b))
(Hl : f auxl = g auxl) (Hr : f auxr = g auxr)
(Hgluel : forall a, ap f (gluel a) @ Hl = Hsm a pt @ ap g (gluel a))
(Hgluer : forall b, ap f (gluer b) @ Hr = Hsm pt b @ ap g (gluer b))
: f == g.
snapply (Smash_ind Hsm Hl Hr).
(** A version of [Smash_ind]j specifically for proving that the composition of two functions is the identity map. *)
Definition Smash_ind_FFlr {A B : pType} {P : Type}
(f : Smash A B -> P) (g : P -> Smash A B)
(Hsm : forall a b, g (f (sm a b)) = sm a b)
(Hl : g (f auxl) = auxl) (Hr : g (f auxr) = auxr)
(Hgluel : forall a, ap g (ap f (gluel a)) @ Hl = Hsm a pt @ gluel a)
(Hgluer : forall b, ap g (ap f (gluer b)) @ Hr = Hsm pt b @ gluer b)
: g o f == idmap.
snapply (Smash_ind Hsm Hl Hr).
(** ** Functoriality of the smash product *)
Definition functor_smash {A B X Y : pType} (f : A $-> X) (g : B $-> Y)
: Smash A B $-> Smash X Y.
snapply (Smash_rec (fun a b => sm (f a) (g b)) auxl auxr).
rhs_V napply (gluel (f a)).
exact (ap011 _ 1 (point_eq g)).
rhs_V napply (gluer (g b)).
exact (ap011 _ (point_eq f) 1).
exact (ap011 _ (point_eq f) (point_eq g)).
Definition functor_smash_idmap (X Y : pType)
: functor_smash (@pmap_idmap X) (@pmap_idmap Y) $== pmap_idmap.
lhs napply Smash_rec_beta_gluel.
lhs napply Smash_rec_beta_gluer.
Definition functor_smash_compose {X Y A B C D : pType}
(f : X $-> A) (g : Y $-> B) (h : A $-> C) (k : B $-> D)
: functor_smash (h $o f) (k $o g) $== functor_smash h k $o functor_smash f g.
lhs napply Smash_rec_beta_gluel.
lhs napply (ap_compose (functor_smash _ _) _ (gluel x)).
2: napply Smash_rec_beta_gluel.
lhs napply Smash_rec_beta_gluel.
lhs napply Smash_rec_beta_gluer.
lhs napply (ap_compose (functor_smash _ _) _ (gluer y)).
2: napply Smash_rec_beta_gluer.
lhs napply Smash_rec_beta_gluer.
Definition functor_smash_homotopic {X Y A B : pType}
{f h : X $-> A} {g k : Y $-> B}
(p : f $== h) (q : g $== k)
: functor_smash f g $== functor_smash h k.
1: exact (fun x y => ap011 _ (p x) (q y)).
lhs napply Smash_rec_beta_gluel.
2: napply Smash_rec_beta_gluel.
simpl; induction (p x); simpl.
rhs_V napply concat_pp_p.
lhs napply Smash_rec_beta_gluer.
2: napply Smash_rec_beta_gluer.
simpl; induction (q y); simpl.
rhs_V napply concat_pp_p.
exact (ap011_pp _ _ _ 1 1).
exact (ap022 _ (concat_p1 (p pt))^ (concat_p1 (q pt))^ @ (concat_p1 _)^).
#[export] Instance is0bifunctor_smash : Is0Bifunctor Smash.
snapply Build_Is0Bifunctor'.
intros [X Y] [A B] [f g].
exact (functor_smash f g).
#[export] Instance is1bifunctor_smash : Is1Bifunctor Smash.
snapply Build_Is1Bifunctor'.
snapply Build_Is1Functor.
intros [X Y] [A B] [f g] [h i] [p q].
exact (functor_smash_homotopic p q).
exact (functor_smash_idmap X Y).
intros [X Y] [A B] [C D] [f g] [h i].
exact (functor_smash_compose f g h i).
(** ** Symmetry of the smash product *)
Definition pswap (X Y : pType) : Smash X Y $-> Smash Y X
:= Build_pMap (Smash_rec (flip sm) auxr auxl gluer gluel) 1.
Definition pswap_pswap {X Y : pType}
: pswap X Y $o pswap Y X $== pmap_idmap.
1: apply Smash_rec_beta_gluel.
napply Smash_rec_beta_gluer.
1: apply Smash_rec_beta_gluer.
napply Smash_rec_beta_gluel.
Definition pequiv_pswap {X Y : pType} : Smash X Y $<~> Smash Y X.
Definition pswap_natural {A B X Y : pType} (f : A $-> X) (g : B $-> Y)
: pswap X Y $o functor_smash f g $== functor_smash g f $o pswap A B.
rhs napply (ap_compose (pswap _ _) _ (gluel a)).
2: apply Smash_rec_beta_gluel.
rhs napply Smash_rec_beta_gluer.
lhs napply (ap_compose (functor_smash _ _) (pswap _ _) (gluel a)).
1: apply Smash_rec_beta_gluel.
napply Smash_rec_beta_gluel.
rhs napply (ap_compose (pswap _ _) (functor_smash _ _) (gluer b)).
2: apply Smash_rec_beta_gluer.
rhs napply Smash_rec_beta_gluel.
lhs napply (ap_compose (functor_smash _ _) (pswap _ _) (gluer b)).
1: apply Smash_rec_beta_gluer.
napply Smash_rec_beta_gluer.