Nottingham FP Lab Blog

A finite universe in Agda

by Thorsten on May 9, 2008.
Tagged as: Lunches.

In exercise 3 of our lecture notes on generic programming we suggest to show that the universe of finite types is closed under coproducts, products and exponentials and implement views allowing to do pattern matching over the derived structure. I though that (re)doing this in Agda may be a good way to explore views in Agda and play with the with-rule (local case). Indeed, I discovered that our remark that it is not possible to implement a view for function types due to lack of extensionality was wrong, since we only have to show that every code is generated by a function.

Exercises: show that the categorical properties of coproducts, products and exponentials hold and implement Pi and Sigma-types.

module funi where

  {- Defining a universe of finite types with +, × and =>
     and accompanying views -}

  data ℕ : Set where
    zero : ℕ
    succ : ℕ -> ℕ

  _+_ : ℕ -> ℕ -> ℕ
  zero   + m   = m
  succ n + m   = succ (n + m)

  data Fin : ℕ -> Set where
    fz : forall {n} -> Fin (succ n)
    fs : forall {n} -> Fin n -> Fin (succ n)

  {- coproducts -}

  finl : forall {m n} -> Fin m -> Fin (m + n)
  finl fz     = fz
  finl (fs i) = fs (finl i)

  finr : forall {m n} -> Fin n -> Fin (m + n)
  finr {zero}   {n} i = i
  finr {succ m} {n} i = fs (finr {m} i)

  data PlusView : forall {m n} -> Fin (m + n) -> Set where
    inl : forall {m n} -> (i : Fin m) -> PlusView {m} {n} (finl i)
    inr : forall {m n} -> (i : Fin n) -> PlusView {m} {n} (finr {m} i)

  plusView : forall {m n} -> (i : Fin (m + n)) -> PlusView {m} {n} i
  plusView {zero}   i      = inr i
  plusView {succ m} fz     = inl (fz {m})
  plusView {succ m} (fs i) with plusView {m} i
  plusView {succ m} (fs ._) | (inl j) = inl {succ m} (fs j)
  plusView {succ m} (fs ._) | (inr j) = inr j

  fcase : forall {m n} -> {A : Set}
          -> ((i : Fin m) -> A)
          -> ((j : Fin n) -> A)
          -> ( k : Fin (m + n) ) -> A
  fcase {m} minl minr k with plusView {m} k
  fcase {m} minl minr ._ | inl i = minl i
  fcase {m} minl minr ._ | inr j = minr j

  {- products -}

  _×_ : ℕ -> ℕ -> ℕ
  zero     × n = zero
  (succ m) × n = n + (m × n)

  fpair : forall {m n} -> Fin m -> Fin n -> Fin (m × n)
  fpair {zero}   {n} ()     _
  fpair {succ m} {n} fz     i = finl {n} {m × n} i
  fpair {succ m} {n} (fs j) i = finr {n} {m × n} (fpair j i) 

  data PairView : forall {m n} -> Fin (m × n) -> Set where
     pair : forall {m n} -> (i : Fin m)(j : Fin n) -> PairView {m} {n} (fpair i j)

  pairView : forall {m n} -> (i : Fin (m × n) ) -> PairView {m} {n} i
  pairView {zero}   {n} ()
  pairView {succ m} {n} i with plusView {n} {m × n} i
  pairView {succ m} {n} ._ | inl j =  pair fz j
  pairView {succ m} {n} ._ | inr k  with pairView {m} {n} k
  pairView {succ m} {n} ._ | inr ._  |  pair k0 k1 =  pair (fs k0) k1  

  fst : forall {m n} -> (i : Fin (m × n) ) -> Fin m
  fst {m} i with pairView {m} i
  fst {m} ._ | pair j k = j 

  snd : forall {m n} -> (i : Fin (m × n) ) -> Fin n
  snd {m} i with pairView {m} i
  snd {m} ._ | pair j k = k 

  {- exponentials -}

  _=>_ : ℕ -> ℕ -> ℕ
  zero     => n = succ zero
  (succ m) => n = n × (m => n)

  flam : forall {m n} -> ((Fin m) -> (Fin n)) -> Fin (m => n)
  flam {zero}   {n} f = fz
  flam {succ m} {n} f = fpair {n} {m => n} (f fz) (flam {m} {n} (\ i -> f (fs i) ) ) 

  data FunView : forall {m n} -> Fin (m => n) -> Set where
     lam : forall {m n} -> (f : (Fin m) -> (Fin n)) -> FunView {m} {n} (flam f)

  fzero : {A : Set} -> Fin zero -> A
  fzero () 

  fsucc : forall {m} -> {A : Set} -> A -> ((Fin m) -> A) -> Fin (succ m) -> A
  fsucc a f fz     = a
  fsucc a f (fs i) = f i

  funView : forall {m n} -> (i : Fin (m => n)) -> FunView {m} {n} i
  funView {zero}   {n} fz      = lam fzero
  funView {zero}   {n} (fs ())
  funView {succ m} {n} i       with pairView {n} {m => n} i
  funView {succ m} {n} ._      |    pair f0 ff  with funView {m} ff
  funView {succ m} {n} ._      |    pair f0 ._  |    lam g = lam (fsucc f0 g)

  fapp : forall {m n} -> Fin (m => n) -> Fin m -> Fin n
  fapp {m} {n} f  i with funView {m} {n} f
  fapp {m} {n} ._ i  |   lam g  = g i

comments powered by Disqus