{-# OPTIONS --safe #-}

{-
This file contians a proof that the smash product turns the universe
of pointed types into a symmetric monoidal precategory. The pentagon
and hexagon are proved in separate files due to the length of the
proofs. The remaining identities and the main result are proved here.
-}

module Cubical.HITs.SmashProduct.SymmetricMonoidal where

open import Cubical.HITs.SmashProduct.Base
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Pointed
open import Cubical.Foundations.Isomorphism
open import Cubical.HITs.Pushout.Base
open import Cubical.Data.Unit
open import Cubical.Data.Sigma
open import Cubical.HITs.Wedge
open import Cubical.Foundations.GroupoidLaws
open import Cubical.Foundations.Pointed.Homogeneous
open import Cubical.Foundations.Path
open import Cubical.Foundations.Function
open import Cubical.Foundations.Equiv
open import Cubical.HITs.SmashProduct.Base
open import Cubical.HITs.SmashProduct.Pentagon
open import Cubical.HITs.SmashProduct.Hexagon
open import Cubical.Categories.Category.Precategory
  renaming (_×_ to _×'_)
open import Cubical.Data.Bool

open Precategory hiding (_∘_)
open Prefunctor
open isSymmetricPrecategory
open isMonoidalPrecategory
open PreNatIso
open PreNatTrans
open preIsIso


private
  variable
     ℓ' : Level
    A B : Pointed 

⋀→∙-idfun : {A : Pointed } {B : Pointed ℓ'}
   (_⋀→∙_ (idfun∙ A) (idfun∙ B))  idfun∙ (A ⋀∙ B)
⋀→∙-idfun =
  ΣPathP (funExt
    (⋀-fun≡ _ _ refl  _  refl)
       x  flipSquare (sym (rUnit (push (inl x)))))
      λ x  flipSquare (sym (rUnit (push (inr x)))))
                   , refl)

⋀→∙-comp : {A A' A'' B B' B'' : Pointed }
  (f : A →∙ A') (f' : A' →∙ A'')
  (g : B →∙ B') (g' : B' →∙ B'')
   ((f' ∘∙ f) ⋀→∙ (g' ∘∙ g))  ((f' ⋀→∙ g') ∘∙ (f ⋀→∙ g))
⋀→∙-comp f f' g g' =
  ΣPathP ((funExt
   (⋀-fun≡ _ _ refl  _  refl)
      x  flipSquare
       (cong (push (inl (fst f' (fst f x))) ∙_)
         ((λ i j  cong-∙  y  inr (fst f' (fst f x) , y))
                        (cong (fst g') (snd g)) (snd g') i (~ j))
         symDistr (cong  y  inr (fst f' (fst f x) , y))
                           i  fst g' (snd g i)))
                    (cong  y  inr (fst f' (fst f x) , y)) (snd g')))
        assoc _ _ _
       ∙∙  j  (push (inl (fst f' (fst f x)))
             j  inr (fst f' (fst f x) , snd g' (~ j))))
            λ j  inr (fst f' (f .fst x) , fst g' (snd g (~ j))))
       ∙∙ sym (cong-∙ (f' ⋀→ g') (push (inl (fst f x)))
         λ i  inr (fst f x , g .snd (~ i)))))
     λ x  flipSquare
       (cong (push (inr (fst g' (fst g x))) ∙_)
         ((λ i j  cong-∙  y  inr (y , fst g' (fst g x)))
                        (cong (fst f') (snd f)) (snd f') i (~ j))
         symDistr (cong  y  inr (y , fst g' (fst g x)))
                           i  fst f' (snd f i)))
                    (cong  y  inr (y , fst g' (fst g x))) (snd f')))
        assoc _ _ _
       ∙∙  j  (push (inr (fst g' (fst g x)))
             j  inr (snd f' (~ j) , fst g' (fst g x))))
            λ j  inr (fst f' (snd f (~ j)) , fst g' (g .fst x)))
       ∙∙ sym (cong-∙ (f' ⋀→ g') (push (inr (fst g x)))
                  λ i  inr ((snd f (~ i)) , fst g x)))))
        , (rUnit refl))

⋀assoc-⋀→∙ : {A A' B B' C C' : Pointed }
  (f : A →∙ A') (g : B →∙ B') (h : C →∙ C') 
      ≃∙map SmashAssocEquiv∙ ∘∙ (f ⋀→∙ (g ⋀→∙ h))
     ((f ⋀→∙ g) ⋀→∙ h) ∘∙ ≃∙map SmashAssocEquiv∙
⋀assoc-⋀→∙ {A = A} {A' = A'} {B = B} {B' = B'} {C = C} {C' = C'} f g h =
  ΣPathP
   ((funExt (⋀-fun≡'.main _ _
      x  mainᵣ (fst x) (snd x))
      x  p≡refl  flipSquare
       (cong (cong (SmashAssocIso .Iso.fun))
         (sym (rUnit (push (inl (fst f x))))))
          λ _  refl)
     (⋀→∙Homogeneous≡ (isHomogeneousPath _ _)
       λ y z   i  push-lem y z (~ i)
                    ∙∙ refl
                    ∙∙ sym (push-lem y z i0))
            ∙∙lCancel (sym (push-lem y z i0))
            sym p≡refl)))
  , λ i j  pt-lem-main i j)
  where
  mainᵣ : (x : fst A) (y : B  C)
     SmashAssocIso .Iso.fun (inr (fst f x , (g ⋀→ h) y))
      ((f ⋀→∙ g) ⋀→ h) (SmashAssocIso .Iso.fun (inr (x , y)))
  mainᵣ x =
    ⋀-fun≡ _ _ refl  _  refl)
       b  flipSquare
        (cong-∙  z  SmashAssocIso .Iso.fun (inr (fst f x , z)))
                (push (inl (fst g b)))
                 i₁  inr (fst g b , snd h (~ i₁)))))
      λ b  flipSquare
        (cong-∙  z  SmashAssocIso .Iso.fun (inr (fst f x , z)))
                (push (inr (fst h b)))
                 i₁  inr (snd g (~ i₁) , fst h b))
       ∙∙ cong₂ _∙_ ((λ j i  ⋀CommIso .Iso.fun
                   (compPath≡compPath'
                     (push (inl (fst h b)))
                      i  inr (fst h b , push (inl (fst f x)) i)) (~ j) i))
                     cong-∙ (⋀CommIso .Iso.fun)
                        (push (inl (fst h b)))
                        λ i  inr (fst h b , push (inl (fst f x)) i))
                    refl
         sym (assoc _ _ _)
         cong₂ _∙_ refl (sym (cong-∙  y  (inr (y , fst h b)))
                                (push (inl (fst f x)))
                                 i₁  inr (fst f x , snd g (~ i₁)))))
       ∙∙ sym (lem b))
     where
     lem : (b : _)  cong ((f ⋀→∙ g) ⋀→ h)
             (cong (SmashAssocIso .Iso.fun) λ i  inr (x , push (inr b) i))
           (push (inr (fst h b)))
           λ i  inr (((push (inl (fst f x))
           λ i₁  inr (fst f x , snd g (~ i₁))) i) , (fst h b))
     lem b =  j i  ((f ⋀→∙ g) ⋀→ h)
                 (⋀CommIso .Iso.fun
                   (compPath≡compPath' (push (inl b))
                      i  inr (b , push (inl x) i)) (~ j) i)))
           ∙∙ cong-∙ (((f ⋀→∙ g) ⋀→ h)  ⋀CommIso .Iso.fun)
                (push (inl b))  i  inr (b , push (inl x) i))
           ∙∙ cong₂ _∙_
               (sym (rUnit _))
               refl

  push-lem : (y : _) (z : _)
     cong (((f ⋀→∙ g) ⋀→ h)  (fst (fst SmashAssocEquiv∙)))
            (push (inr (inr (y , z))))
      cong (fst (≃∙map SmashAssocEquiv∙ ∘∙ (f ⋀→∙ (g ⋀→∙ h))))
            (push (inr (inr (y , z))))
  push-lem y z =
      cong (cong ((f ⋀→∙ g) ⋀→ h))
           (cong-∙∙ ⋀comm→ (push (inl z))
                             i  inr (z , push (inr y) i))
                            refl
          sym (compPath≡compPath' (push (inr z)) _))
   ∙∙ cong-∙ ((f ⋀→∙ g) ⋀→ h)
        (push (inr z))  i  inr (push (inr y) i , z))
   ∙∙ (cong₂ _∙_ (sym (rUnit (push (inr (fst h z)))))
                 (cong-∙  x  inr (x , fst h z))
                         (push (inr (fst g y)))
                          i  inr (snd f (~ i) , fst g y)))
      sym (cong-∙ (SmashAssocIso .Iso.fun)
             (push (inr (inr (fst g y , fst h z))))
              i  inr (snd f (~ i)
                        , inr (fst g y , fst h z)))
        ∙∙ cong (_∙  i  inr (inr (snd f (~ i) , fst g y) , fst h z)))
                (cong-∙∙ ⋀comm→
                         (push (inl (fst h z)))
                          i  inr (fst h z , push (inr (fst g y)) i))
                         refl
              sym (compPath≡compPath' (push (inr (fst h z))) _))
        ∙∙ sym (assoc _ _ _)))

  module N = ⋀-fun≡'
       z  SmashAssocIso .Iso.fun ((f ⋀→ (g ⋀→∙ h)) z))
       z  ((f ⋀→∙ g) ⋀→ h) (SmashAssocIso .Iso.fun z))
       x₁  mainᵣ (fst x₁) (snd x₁))

  p≡refl : N.p  refl
  p≡refl =  j  cong (SmashAssocIso .Iso.fun
                        ((f ⋀→ (g ⋀→∙ h))))
                         (push (inr (inl tt)))
                 ∙∙ refl
                 ∙∙ cong (((f ⋀→∙ g) ⋀→ h)
                          (SmashAssocIso .Iso.fun))
                         (sym (push (push tt j))))
           cong  x  x ∙∙ refl ∙∙ refl)
                  (cong-∙ (SmashAssocIso .Iso.fun)
                          (push (inr (inl tt)))
                           i  inr (snd f (~ i) , inl tt))
                  sym (rUnit refl))
           sym (rUnit refl)

  pt-lem : cong (fst (≃∙map SmashAssocEquiv∙ ∘∙ (f ⋀→∙ (g ⋀→∙ h))))
             (push (inr (inl tt)))
          cong (fst (((f ⋀→∙ g) ⋀→∙ h) ∘∙ ≃∙map SmashAssocEquiv∙))
             (push (inr (inl tt)))
  pt-lem i j =
    fst (≃∙map SmashAssocEquiv∙) (rUnit (push (inr (inl tt))) (~ i) j)

  pt-lem-main : I  I  _
  pt-lem-main i j =
    hcomp  k  λ {(i = i0)  rUnit (refl {x = inl tt}) k j
                   ; (i = i1)  rUnit (refl {x = inl tt}) k j
                   ; (j = i0)  (pt-lem i0 ∙∙ refl ∙∙ sym (pt-lem k)) i
                   ; (j = i1)  inl tt})
          (∙∙lCancel (sym (pt-lem i0)) j i)

⋀comm-sq : {A A' B B' : Pointed }
  (f : A →∙ A') (g : B →∙ B')
   (⋀comm→∙ ∘∙ (f ⋀→∙ g))  ((g ⋀→∙ f) ∘∙ ⋀comm→∙)
⋀comm-sq f g =
  ΣPathP ((funExt
    (⋀-fun≡ _ _ refl  _  refl)
       x  flipSquare
        (cong-∙ ⋀comm→
          (push (inl (fst f x)))  i  inr (fst f x , snd g (~ i)))))
      λ b  flipSquare (cong-∙ ⋀comm→
                         (push (inr (fst g b)))
                          i  inr (snd f (~ i) , fst g b)))))
    , refl)

⋀comm-sq' : {A A' B B' : Pointed }
  (f : A →∙ A') (g : B →∙ B')
   (f ⋀→∙ g)  (⋀comm→∙ ∘∙ ((g ⋀→∙ f) ∘∙ ⋀comm→∙))
⋀comm-sq' f g =
     sym (∘∙-idʳ (f ⋀→∙ g))
  ∙∙ cong (_∘∙ (f ⋀→∙ g)) (sym lem)
  ∙∙ ∘∙-assoc ⋀comm→∙ ⋀comm→∙ (f ⋀→∙ g)
    cong  w  ⋀comm→∙ ∘∙ w) (⋀comm-sq f g)
  where
  lem : ⋀comm→∙ ∘∙ ⋀comm→∙  idfun∙ _
  lem = ΣPathP ((funExt (Iso.rightInv ⋀CommIso)) , (sym (rUnit refl)))

Bool⋀→ : Bool*∙ {}  A  typ A
Bool⋀→ {A = A} (inl x) = pt A
Bool⋀→ (inr (lift false , a)) = a
Bool⋀→ {A = A} (inr (lift true , a)) = pt A
Bool⋀→ {A = A} (push (inl (lift false)) i) = pt A
Bool⋀→ {A = A} (push (inl (lift true)) i) = pt A
Bool⋀→ {A = A} (push (inr x) i) = pt A
Bool⋀→ {A = A} (push (push a i₁) i) = pt A

⋀lIdIso : Iso (Bool*∙ {}  A) (typ A)
Iso.fun (⋀lIdIso {A = A}) (inl x) = pt A
Iso.fun ⋀lIdIso = Bool⋀→
Iso.inv ⋀lIdIso a = inr (false* , a)
Iso.rightInv ⋀lIdIso a = refl
Iso.leftInv (⋀lIdIso {A = A}) =
  ⋀-fun≡ _ _ (sym (push (inl false*))) h hₗ
    λ x  compPath-filler (sym (push (inl false*))) (push (inr x))
  where
  h : (x : (Lift Bool) × fst A) 
      inr (false* , Bool⋀→ (inr x))  inr x
  h (lift false , a) = refl
  h (lift true , a) = sym (push (inl false*))  push (inr a)

  hₗ : (x : Lift Bool) 
      PathP
       i  inr (false* , Bool⋀→ (push (inl x) i))  push (inl x) i)
       i  push (inl false*) (~ i)) (h (x , pt A))
  hₗ (lift false) i j = push (inl false*) (~ j  i)
  hₗ (lift true) =
      compPath-filler (sym (push (inl false*))) (push (inl true*))
     (cong (sym (push (inl false*)) ∙_)
       λ j i  push (push tt j) i)

⋀lIdEquiv∙ : Bool*∙ {} ⋀∙ A ≃∙ A
fst ⋀lIdEquiv∙ = isoToEquiv ⋀lIdIso
snd ⋀lIdEquiv∙ = refl

⋀lId-sq : (f : A →∙ B) 
      (≃∙map (⋀lIdEquiv∙ {}) ∘∙ (idfun∙ Bool*∙ ⋀→∙ f))
     (f ∘∙ ≃∙map ⋀lIdEquiv∙)
⋀lId-sq {} {A = A} {B = B} f =
  ΣPathP ((funExt
    (⋀-fun≡ _ _ (sym (snd f))  x  h (fst x) (snd x)) hₗ hᵣ))
  , (sym (rUnit refl)   i j  snd f (~ i  j))
     lUnit (snd f)))
  where
  h : (x : Lift Bool) (a : fst A)
     Bool⋀→ (inr (x , fst f a))  fst f (Bool⋀→ (inr (x , a)))
  h (lift false) a = refl
  h (lift true) a = sym (snd f)

  hₗ : (x : Lift Bool)
     PathP  i  Bool⋀→ ((idfun∙ Bool*∙ ⋀→ f) (push (inl x) i))
                    fst f (Bool⋀→ (push (inl x) i)))
             (sym (snd f)) (h x (pt A))
  hₗ (lift false) =
    flipSquare ((cong-∙ (Bool⋀→ {})
                  (push (inl false*))
                   i  inr (lift false , snd f (~ i)))
               sym (lUnit (sym (snd f))))
              λ i j  snd f (~ i  ~ j))
  hₗ (lift true) =
    flipSquare
       ((cong-∙ (Bool⋀→ {})
         (push (inl true*))  i  inr (lift true , snd f (~ i)))
        sym (rUnit refl))
       λ i _  snd f (~ i))

  hᵣ : (x : fst A)
     PathP  i  Bool⋀→ {} ((idfun∙ Bool*∙ ⋀→ f) (push (inr x) i))
                    fst f (snd A))
             (sym (snd f)) (h true* x)
  hᵣ x = flipSquare ((cong-∙ (Bool⋀→ {})
                      (push (inr (fst f x)))
                       i  inr (true* , fst f x))
                     sym (rUnit refl))
       λ i _  snd f (~ i))

⋀lId-assoc : ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ⋀→∙ idfun∙ B)
             ∘∙ ≃∙map SmashAssocEquiv∙)
             ≃∙map ⋀lIdEquiv∙
⋀lId-assoc {} {A = A} {B = B} =
  ΣPathP (funExt
          (⋀-fun≡'.main _ _
             xy  mainᵣ (fst xy) (snd xy))
             x  sym (rUnit refl)  mainᵣ-pt-coh x)
            (⋀→∙Homogeneous≡ (isHomogeneousPath _ _) mainᵣ-coh))
        , (sym (rUnit refl)
           flipSquare (sym (rUnit refl))))
  where
  l₁ : (x : Lift Bool)  inl tt  Bool⋀→ (inr (x , inl tt))
  l₁ (lift true) = refl
  l₁ (lift false) = refl

  l₂ : (x : Lift Bool) (y : fst A × fst B)
     inr (Bool⋀→ (inr (x , fst y)) , snd y)
     Bool⋀→ (inr (x , inr y))
  l₂ (lift true) y = sym (push (inr (snd y)))
  l₂ (lift false) y = refl

  l₁≡l₂-left : (x : Lift Bool) (y : fst A) 
    PathP  i  l₁ x i  l₂ x (y , pt B) i)
          (push (inl (Bool⋀→ (inr (x , y)))))
          λ i  Bool⋀→ {} {A = A ⋀∙ B} (inr (x , push (inl y) i))
  l₁≡l₂-left (lift true) y =  i  push (push tt i))
                    λ i j  push (inr (pt B)) (~ i  j)
  l₁≡l₂-left (lift false) y = refl

  l₁≡l₂-right : (x : Lift Bool) (y : fst B)
     PathP  i  l₁ x i  l₂ x ((pt A) , y) i)
            (push (inr y)   i  inr (Bool⋀→ {A = A} (push (inl x) i) , y)))
             i  Bool⋀→ {A = A ⋀∙ B} (inr (x , push (inr y) i)))
  l₁≡l₂-right (lift false) y = sym (rUnit (push (inr y)))
  l₁≡l₂-right (lift true) y = sym (rUnit (push (inr y)))
                    λ i j  push (inr y) (j  ~ i)

  mainᵣ : (x : Lift Bool) (y : A  B)
     (≃∙map ⋀lIdEquiv∙ ⋀→ idfun∙ B)
        (SmashAssocIso .Iso.fun (inr (x , y)))
      Bool⋀→ {} (inr (x , y))
  mainᵣ x = ⋀-fun≡ _ _ (l₁ x) (l₂ x)
     y  flipSquare (sym (rUnit (push (inl (Bool⋀→ (inr (x , y))))))
           l₁≡l₂-left x y))
    λ y  flipSquare (
      (cong (cong (≃∙map ⋀lIdEquiv∙ ⋀→ idfun∙ B))
            (cong-∙∙ ⋀comm→
              (push (inl y))  i  inr (y , push (inl x) i)) refl
           sym (compPath≡compPath'
                  (push (inr y))  i  inr (push (inl x) i , y))))
         cong-∙ (≃∙map ⋀lIdEquiv∙ ⋀→ idfun∙ B)
            (push (inr y)) λ i  inr (push (inl x) i , y))
         (cong₂ _∙_ (sym (rUnit (push (inr y))))
                     refl
                    l₁≡l₂-right x y))

  mainᵣ-pt-coh : (x : Lift Bool)
     PathP  i  inl tt  Bool⋀→ (push (inl x) i))
             refl (mainᵣ x (inl tt))
  mainᵣ-pt-coh (lift false) = refl
  mainᵣ-pt-coh (lift true) = refl

  module N = ⋀-fun≡'
     z  (≃∙map ⋀lIdEquiv∙ ⋀→ idfun∙ B) (SmashAssocIso .Iso.fun z))
     z  ⋀lIdIso .Iso.fun z)
     xy  mainᵣ (fst xy) (snd xy))
  open N

  lem : (x : fst A) (y : fst B)
     cong ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ⋀→ idfun∙ B)
             SmashAssocIso .Iso.fun)
             (push (inr (inr (x , y))))
     push (inr y)
  lem x y =
      cong (cong (≃∙map (⋀lIdEquiv∙ {} {A = A}) ⋀→ idfun∙ B))
            (cong-∙∙ ⋀comm→
              (push (inl y))  i  inr (y , push (inr x) i)) refl
            sym (compPath≡compPath'
                  (push (inr y)) λ i  inr (push (inr x) i , y)))
    ∙∙ cong-∙ (≃∙map (⋀lIdEquiv∙ {} {A = A}) ⋀→ idfun∙ B)
              (push (inr y))
               i  inr (push (inr x) i , y))
    ∙∙ (sym (rUnit _)
      sym (rUnit _))

  mainᵣ-coh : (x : fst A) (y : fst B)
     Fₗ .fst (inr (x , y))  Fᵣ .fst (inr (x , y))
  mainᵣ-coh x y =
       i  lem x y i ∙∙ sym (lem x y i1) ∙∙ refl)
     sym (compPath≡compPath'
           (push (inr y)) (sym (push (inr y))))
     rCancel (push (inr y))
     rUnit refl

-- Triangle equality
⋀triang :  {} {A B : Pointed }
   (((≃∙map (⋀lIdEquiv∙ {}) ∘∙ ⋀comm→∙) ⋀→∙ idfun∙ B)
    ∘∙ ≃∙map SmashAssocEquiv∙)
     idfun∙ A ⋀→∙ ≃∙map (⋀lIdEquiv∙ {} {A = B})
⋀triang { = } {A = A} {B = B} =
  ΣPathP ((funExt (⋀-fun≡'.main _ _
     x  mainᵣ (fst x) (snd x))
     x  p≡refl
          flipSquare ((λ i j  push (inl x) (i  j))
          rUnit (push (inl x))))
    (⋀→∙Homogeneous≡ (isHomogeneousPath _ _)
      λ x y  Fₗ≡refl x y  sym (Fᵣ≡refl x y))))
    , (sym (rUnit refl)  flipSquare p≡refl))
  where
  mainᵣ-hom : (x : fst A) (y : Bool* {}) (z : fst B)
     Path (A  B) (inr (Bool⋀→ (inr (y , x)) , z))
                    (inr (x , Bool⋀→ (inr (y , z))))
  mainᵣ-hom x (lift false) z = refl
  mainᵣ-hom x (lift true) z = sym (push (inr z))  push (inl x)

  mainᵣ : (x : fst A) (y : Bool*∙ {}  B) 
    ((≃∙map (⋀lIdEquiv∙ {}) ∘∙ ⋀comm→∙) ⋀→ (idfun∙ B))
      (Iso.fun (SmashAssocIso {A = A} {B = Bool*∙ {}} {C = B}) (inr (x , y)))
     inr (x , ⋀lIdIso .Iso.fun y)
  mainᵣ x = ⋀-fun≡ _ _ (push (inl x))
     y  mainᵣ-hom x (fst y) (snd y))
     { (lift false)  flipSquare (sym (rUnit (push (inl x)))
                        λ i j  push (inl x) (j  i))
       ; (lift true)  flipSquare ((sym (rUnit (push (inl (pt A))))
                                    λ j i  push (push tt j) i)
                      λ i j  compPath-filler'
                                 (sym (push (inr (pt B)))) (push (inl x)) j i)})
     λ b  flipSquare
       ((cong (cong (((≃∙map (⋀lIdEquiv∙ {}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)))
         (cong-∙∙ ⋀comm→ (push (inl b))  i  inr (b , push (inl x) i)) refl
          sym (compPath≡compPath'
                 (push (inr b))  i  inr (push (inl x) i , b))))
        cong-∙ (((≃∙map (⋀lIdEquiv∙ {})  ∘∙ ⋀comm→∙) ⋀→ idfun∙ B))
                (push (inr b))  i  inr (push (inl x) i , b))
        sym (rUnit _)
         i  (push (inr b)   j  inr (rUnit  _  pt A) (~ i) j , b))))
        sym (rUnit (push (inr b))))
        λ i j  compPath-filler' (sym (push (inr b))) (push (inl x)) j i)

  lemₗ : cong (idfun∙ A ⋀→ ≃∙map (⋀lIdEquiv∙ {} {A = B}))
             (push (inr (inl tt)))
       (push (inl (snd A)))
  lemₗ = sym (rUnit _)  λ i  push (push tt (~ i))

  module K = ⋀-fun≡'  z 
          ((≃∙map ⋀lIdEquiv∙ ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)
          (SmashAssocIso .Iso.fun z))
        z  (idfun∙ A ⋀→ ≃∙map ⋀lIdEquiv∙) z)
        x₁  mainᵣ (fst x₁) (snd x₁))
  open K

  p≡refl : p  refl
  p≡refl = cong (push (inl (snd A)) ∙_) (cong sym lemₗ)
          rCancel (push (inl (pt A)))

  Fₗ-false : (y : fst B)
     cong ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)
        (cong ⋀comm→ (push (inl y)
                   ∙'  i  inr (y , push (inr (lift false)) i))))
       push (inr y)
  Fₗ-false y =
      cong (cong ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B))
         (cong (cong ⋀comm→)
           (sym (compPath≡compPath'
             (push (inl y))  i  inr (y , push (inr (lift false)) i))))
        cong-∙ ⋀comm→ (push (inl y))
                         i  inr (y , push (inr (lift false)) i)))
    ∙∙ cong-∙ ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)
              (push (inr y))  i  inr (push (inr (lift false)) i , y))
    ∙∙ (sym (rUnit _)
       i  push (inr y)   j  inr (rUnit  _  pt A) (~ i) j , y)))
      sym (rUnit _))

  Fₗ-true : (y : fst B)
     cong ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)
        (cong (SmashAssocIso .Iso.fun) (push (inr (inr (lift true , y)))))
       push (inr y)
  Fₗ-true y =
      cong (cong ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B))
        (cong-∙∙ ⋀comm→ (push (inl y))  i  inr (y , push (inr true*) i)) refl
         sym (compPath≡compPath' (push (inr y))
                                  λ i  inr (push (inr true*) i , y)))
    ∙∙ cong-∙ ((≃∙map (⋀lIdEquiv∙ {} {A = A}) ∘∙ ⋀comm→∙) ⋀→ idfun∙ B)
              (push (inr y))
               i  inr (push (inr true*) i , y))
    ∙∙ ((sym (rUnit _)
       i  push (inr y)   j  inr (rUnit  _  pt A) (~ i) j , y)))
      sym (rUnit _)))

  Fₗ≡refl : (x : Lift Bool) (y : fst B)  Fₗ .fst (inr (x , y))  refl
  Fₗ≡refl (lift false) y =
      i  Fₗ-false y i ∙∙ refl ∙∙ sym (rUnit (push (inr y)) (~ i)))
     ∙∙lCancel _
  Fₗ≡refl (lift true) y =
       j  Fₗ-true y j
          ∙∙ (sym (push (inr y))  push (push tt j))
          ∙∙ sym (rUnit (push (inr (pt B))) (~ j)))
      j   i  push (inr y) (i  ~ j))
           ∙∙  i  push (inr y) (~ j  ~ i))
             push (inr (pt B))
           ∙∙ sym (push (inr (pt B))))
     cong (_∙ sym (push (inr (pt B)))) (sym (lUnit (push (inr (pt B)))))
     rCancel _

  Fᵣ≡refl : (x : Lift Bool) (y : fst B)  Fᵣ .fst (inr (x , y))  refl
  Fᵣ≡refl x y =
    cong (push (inl (snd A)) ∙_)
      (sym (rUnit _)   i j  push (push tt (~ i)) (~ j)))
     rCancel _


-- ⋀ as a functor
⋀F :  {}  Prefunctor (PointedCat  ×' PointedCat ) (PointedCat )
F-ob ⋀F (A , B) = A ⋀∙ B
F-hom ⋀F (f , g) = f ⋀→∙ g
F-id ⋀F = ⋀→∙-idfun
F-seq ⋀F (f , g) (f' , g') = ⋀→∙-comp f f' g g'

⋀lUnitNatIso : PreNatIso (PointedCat ) (PointedCat )
      (restrFunctorₗ ⋀F Bool*∙) (idPrefunctor (PointedCat ))
N-ob (trans ⋀lUnitNatIso) X = ≃∙map ⋀lIdEquiv∙
N-hom (trans ⋀lUnitNatIso) f = ⋀lId-sq f
inv' (isIs ⋀lUnitNatIso c) = ≃∙map (invEquiv∙ ⋀lIdEquiv∙)
sect (isIs (⋀lUnitNatIso { = }) c) =
  ≃∙→ret/sec∙ (⋀lIdEquiv∙ { = } {A = c}) .snd
retr (isIs ⋀lUnitNatIso c) =
  ≃∙→ret/sec∙ ⋀lIdEquiv∙ .fst

makeIsIso-Pointed :  {} {A B : Pointed } {f : A →∙ B}
   isEquiv (fst f)  preIsIso {C = PointedCat } f
inv' (makeIsIso-Pointed {f = f} eq) = ≃∙map (invEquiv∙ ((fst f , eq) , snd f))
sect (makeIsIso-Pointed {f = f} eq) = ≃∙→ret/sec∙ ((fst f , eq) , snd f)  .snd
retr (makeIsIso-Pointed {f = f} eq) = ≃∙→ret/sec∙ ((fst f , eq) , snd f)  .fst

restrₗᵣ : PreNatIso (PointedCat ) (PointedCat )
      (restrFunctorᵣ ⋀F Bool*∙) (restrFunctorₗ ⋀F Bool*∙)
N-ob (trans restrₗᵣ) X = ⋀comm→∙
N-hom (trans restrₗᵣ) f = ⋀comm-sq f (idfun∙ Bool*∙)
isIs restrₗᵣ c = makeIsIso-Pointed (isoToIsEquiv ⋀CommIso)

-- main result
⋀Symm :  {}  isSymmetricPrecategory (PointedCat )
_⊗_ (isMonoidal ⋀Symm) = ⋀F
𝟙 (isMonoidal ⋀Symm) = Bool*∙
N-ob (trans (⊗assoc (isMonoidal ⋀Symm))) (A , B , C) = ≃∙map SmashAssocEquiv∙
N-hom (trans (⊗assoc (isMonoidal ⋀Symm))) (f , g , h) = ⋀assoc-⋀→∙ f g h
inv' (isIs (⊗assoc (isMonoidal ⋀Symm)) (A , B , C)) =
  ≃∙map (invEquiv∙ SmashAssocEquiv∙)
sect (isIs (⊗assoc (isMonoidal ⋀Symm)) (A , B , C)) =
  ≃∙→ret/sec∙ SmashAssocEquiv∙ .snd
retr (isIs (⊗assoc (isMonoidal ⋀Symm)) (A , B , C)) =
  ≃∙→ret/sec∙ SmashAssocEquiv∙ .fst
⊗lUnit (isMonoidal ⋀Symm) = ⋀lUnitNatIso
⊗rUnit (isMonoidal ⋀Symm) = compPreNatIso _ _ _ restrₗᵣ ⋀lUnitNatIso
triang (isMonoidal (⋀Symm {})) X Y = ⋀triang
⊗pentagon (isMonoidal ⋀Symm) X Y Z W =
  (∘∙-assoc assc₅∙ assc₄∙ assc₃∙)  pentagon∙
N-ob (trans (Braid ⋀Symm)) X = ⋀comm→∙
N-hom (trans (Braid ⋀Symm)) (f , g) = ⋀comm-sq f g
isIs (Braid ⋀Symm) _ = makeIsIso-Pointed (isoToIsEquiv ⋀CommIso)
isSymmetricPrecategory.hexagon ⋀Symm a b c = hexagon∙
symBraiding ⋀Symm X Y =
  ΣPathP ((funExt (Iso.rightInv ⋀CommIso)) , (sym (rUnit refl)))