module Intro where

------------------------------------------------------------------------------

open import Cubical.Data.Equality hiding (sym ; _∙_ ; assoc)

variable
   ℓ' ℓ'' : Level
  A B C : Type 
infixr 30 _∙_

------------------------------------------------------------------------------

















------------------------------------------------------------------------------
-- Dependent Types
------------------------------------------------------------------------------

module _ where
  open import Cubical.Data.Unit renaming (Unit to 𝟙 ; tt to )
  open import Cubical.Data.Sum
  open import Cubical.Data.Nat
  open import Cubical.Data.Bool

  f :   Bool
  f n = true

  g : (n : )  if isEven n then  else Bool
  g zero = zero
  g (suc zero) = true
  g (suc (suc n)) = g n

  module Lists where

    data List {} (A : Type ) : Type  where
      []  : List A
      _∷_ : A  List A  List A

    head : {A : Type }  List A  𝟙  A
    head [] = inl 
    head (x  xs) = inr x

  module Vectors where

    data Vec {} (A : Type ) :   Type  where
      []  : Vec A zero
      _∷_ : {n : }  A  Vec A n  Vec A (suc n)

    head : {A : Type } {n : }  Vec A (suc n)  A
    head (x  xs) = x


{-

Π-type:   (x : A) → B x       "for all x : A, a term of B x"
Σ-type:   Σ (x : A) B x       "an x : A, together with a term of B x"
=-type:   x ≡ y               "given x, y : A, an identification of x with y"

-}













------------------------------------------------------------------------------
-- Equality types
------------------------------------------------------------------------------

{-

Formation              a b : A    ⊢    a ≡ b : Type

Introduction             a : A    ⊢    refl : a ≡ a

Elimination                       J

J : (P : (x y : A) → x ≡ y → Type)    -- Motive P transforming equality into target type
  → (d : (x : A) → P x x refl)        -- Proof that P holds for refl
  → (p : a ≡ b) → P a b p             -- Returns a function that eliminates from equality types

To prove something (P) about a general equality (p : a ≡ b),
it suffices to prove it for the reflexivity case.

-}

reflexivity : {a : A}  a  a
reflexivity = refl

sym : {a b : A}  a  b  b  a
sym refl = refl
-- sym {a = a} {b} = J (λ x y p → y ≡ x) (λ x → refl) a b

_∙_ :  {} {A : Type }  {a b c : A}  a  b  b  c  a  c
refl  p = p
-- trans {A = A} {a = a} {b} {c} p = J (λ x y q → (c : A) → y ≡ c → x ≡ c) (λ x c p → p) a b p c

------------------------------------------------------------------------------


------------------------------------------------------------------------------
-- Homotopy Type Theory
------------------------------------------------------------------------------

{-

The Homotopy Interpretation:

 A : Type         <->        Topological space
 a : A            <->        Points in A
 p : a ≡ b        <->        Paths from a to b
 α : p ≡ q        <->        Homotopies between paths
...               <->        Higher homotopies

Types are infinity groupoids:

-}

module _ {a b : A} where

  unitr : (p : a  b)  (p  refl)  p
  unitr refl = refl

  sym² : (p : a  b)  sym (sym p)  p
  sym² refl = refl

module _ {a b c d : A} where

  assoc : (p : a  b) (q : b  c) (r : c  d)
         p  (q  r)  (p  q)  r
  assoc refl q r = refl

module _ {a b c d e : A} where

  pentagon : (p : a  b)  (q : b  c)  (r : c  d)  (s : d  e) 
            (assoc p q (r  s)  assoc (p  q) r s)
                              
    (ap (p ∙_) (assoc q r s))  assoc p (q  r) s  ap (_∙ s) (assoc p q r)
  pentagon refl refl r s = refl


------------------------------------------------------------------------------