{-# OPTIONS --without-K --rewriting #-}

open import HoTT

{- Proof that if [A] and [B] are two propositions, then so is [A * B]. -}

module homotopy.PropJoinProp
  {i} {A : Type i} (pA : is-prop A)
  {j} {B : Type j} (pB : is-prop B) where

contr-left : (a : A)  is-contr (A * B)
contr-left a = left a , Pushout-elim
   a'  ap left (prop-has-all-paths pA a a'))
   b'  glue (a , b'))
   {(a' , b')  ↓-cst=idf-in' $ ! $
    ↓-app=cst-out (apd  a  glue (a , b')) (prop-has-all-paths pA a a'))})

contr-right : (b : B)  is-contr (A * B)
contr-right b = right b , Pushout-elim
   a'  ! (glue (a' , b)))
   b'  ap right (prop-has-all-paths pB b b'))
   {(a' , b')  ↓-cst=idf-in' $
    ! (glue (a' , b))  glue (a' , b')
      =⟨ ! (↓-cst=app-out' $ apd  b  glue (a' , b)) (prop-has-all-paths pB b b'))
        |in-ctx ! (glue (a' , b)) ∙_ 
    ! (glue (a' , b))  glue (a' , b)  ap right (prop-has-all-paths pB b b')
      =⟨ ! $ ∙-assoc (! (glue (a' , b))) (glue (a' , b)) (ap right (prop-has-all-paths pB b b')) 
    (! (glue (a' , b))  glue (a' , b))  ap right (prop-has-all-paths pB b b')
      =⟨ !-inv-l (glue (a' , b)) |in-ctx _∙ ap right (prop-has-all-paths pB b b') 
    ap right (prop-has-all-paths pB b b')
      =∎})

prop*prop-is-prop : is-prop (A * B)
prop*prop-is-prop = inhab-to-contr-is-prop $
  Pushout-rec contr-left contr-right  _  prop-has-all-paths is-contr-is-prop _ _)