-- File by Andrea Vezzosi (https://github.com/Saizan/cubical-demo)

{-# OPTIONS --cubical  #-}

module Id where

open import PathPrelude
open import Sub

module _ {} {A : Set } where
  reflId : {x : A}  Id x x
  reflId {x} = conid i1  _  x)

  transId : {x y z : A}  Id x y  Id y z  Id x z
  transId {x} {y} p = J  y _  Id x y) p

  pathToId : {x y : A}  x  y  Id x y
  pathToId p = conid i0  i  p i)

module _ { ℓ'} {A : Set } where
  congId : {B : Set ℓ'} (f : A  B)   {x y}  Id x y  Id (f x) (f y)
  congId f {x} {y} = J  y _  Id (f x) (f y)) reflId

  Jdef : {x : A} (P :  y  Id x y  Set ℓ') (d : P x reflId)  J P d reflId  d
  Jdef P d = refl

conid' :  {} {A : Set } {x : A} φ {y : Sub A φ  { _  x})}
            (w : Sub (x  ouc y) _ λ { (φ = i1)   _  x)})  Id x (ouc y)
conid' φ {y} w = conid φ  i  ouc w i)

primitive
  primIdElim :  { ℓ'} {A : Set }{x : A} (P :  y  Id x y  Set ℓ') 
    (∀ φ (y : Sub A φ (λ{_  x})) -- y : A [ φ ↦ x ]
     (w : Sub _ φ  { (φ = i1)   i  x)}))  P (ouc y) (conid φ (ouc w)))
      (y : A) (w : Id x y)  P y w

elimId = primIdElim

module _ { ℓ'} {A : Set } {x : A} (P :  y  Id x y  Set ℓ')
         (d : P x (conid' i1 {inc x} (inc  i  x)))) where
  myJ :  y w  P y w
  myJ = elimId _  φ y w  primComp  i 
    P (ouc w i) (conid' (φ  ~ i) {inc (ouc w i)} (inc  j  ouc w (i  j)))))
    φ  i  λ { (φ = i1)  d}) d) where

  myJdef : myJ _ reflId  d
  myJdef = refl


congI :  {} {A B : Set } (f : A  B) (x y : A)  Id x y  Id (f x) (f y)
congI f x = elimId  y _  Id (f x) (f y))
               φ y w  conid φ  i  f (ouc w i)))

transI :  {} {A : Set } {x} (y : A)  Id x y  (z : A)  Id y z  Id x z
transI {A = A} {x} = elimId _ λ φp y p  elimId _ λ φq z q 
      primComp  i  Id x (ouc q i)) (φp  φq)
                i  λ { (φp = i1)  conid (φq  ~ i)  k  ouc q (k  i))
                        ; (φq = i1)  conid φp         (ouc p) })
               (conid φp (ouc p))


module Test {} {A : Set } {x : A} φ {y : Sub A φ (λ{_  x})}
            (w : Sub (x  ouc y) φ λ { (φ = i1)   _  x) }) where
  eq : Id x (ouc y)
  eq = (conid' φ {y} w)

  testl : transI _ reflId _ eq  eq
  testl = refl

  testr : transI _ eq _ reflId  eq
  testr = refl

-- idPath : ∀ {ℓ} {A : Set ℓ}{x y : A} → Id x y → Path x y
-- idPath {x = x} {y = y} = elimId (λ y _ → Path x y) (λ φ y₁ w → ouc w) _

-- test∨ : ∀ {a b}(P : I → Set) → P (a ∨ b) → P (a ∨ b)
-- test∨ P x = x

-- ap-with-J : ∀ {ℓ} {A B : Set ℓ} (f : A → B) (x y : A) → Id x y → Id (f x) (f y)
-- ap-with-J f x = myJ (λ y _ → Id (f x) (f y)) (conid i1 _)

-- apI : ∀ {ℓ} {A B : Set ℓ} (f : A → B) (x y : A) → Id x y → Id (f x) (f y)
-- apI {ℓ} {A} {B} f x = elimId (λ y _ → Id (f x) (f y))
--   (λ φ y w →
--      conid φ
--        (λ j →
--        primComp (λ i → B) (φ ∨ ((~ j) ∨ j))
--        (λ i' →
--          primPOr φ ((~ j) ∨ j) (λ o → f x)
--          (primPOr (~ j) j (λ _ → f x) (λ _ → f (ouc w i'))))
--            (f x)))

-- test-apI : ∀ {ℓ} {A B : Set ℓ} (f : A → B) (x y : A) (p : Id x y) → ap-with-J f x y p ≡ apI f x y p
-- test-apI f x y p = {!!}