packages feed

MiniAgda-0.2014.1.9: test/succeed/singleton.ma

-- 2009-11-29  A few examples about singleton types

let id : (A : Set) -> (x : A) -> <x : A>
       = \ A -> \ x -> x

data Nat : Set 
{ zero : Nat
; succ : Nat -> Nat
}

let zero' 
    : <zero : Nat>
    = zero

let succ'
    : (x : Nat) -> <succ x : Nat>
    = \ x -> succ x

fun pred : [x : Nat] -> <succ x : Nat> -> <x : Nat>
{ pred .x (succ x) = x
} 

-- the recursive constant zero function
fun kzero : (x : Nat) -> <zero : Nat>
{ kzero zero     = zero
; kzero (succ x) = kzero x 
}
-- eta-expansion turns this into the non-recursive
--   kzero x = zero 

data IsZero : Nat -> Set
{ isZero : IsZero zero
} 

let p : (x : Nat) -> IsZero (kzero x)
      = \ x -> isZero
{- Checking works as follows:
  ? x : Nat |- isZero : IsZero (kzero x)
  ? IsZero zero <= IsZero (kzero x)
  ? zero = kzero x : Nat
  . zero = zero : Nat
-}


fun pzero : (<zero : Nat> -> Nat) -> Nat -> <zero : Nat>
{ pzero f zero     = zero
; pzero f (succ x) = kzero (f (pzero f x)) 
}
{- type checking the second clause succees with bidirectional t.c.
   Gamma = f : <zero> -> Nat
           pzero f : Nat -> <zero>
           x : Nat

   ? Gamma |- f (pzero f x) : Nat
   ? Gamma |- pzero f x : <zero>
 -}

fun qzero : ((n : Nat) -> IsZero n -> Nat) -> Nat -> <zero : Nat>
{ qzero f zero     = zero
; qzero f (succ x) = kzero (f (qzero f x) isZero) 
}
{- type checking the second clause FAILS with bidirectional t.c.
   Gamma = f       : (n : Nat) -> IsZero n -> Nat
           qzero f : Nat -> <zero>
           x       : Nat

   ? Gamma |- f (qzero f x) isZero : Nat
     ?1 Gamma |- qzero f x : Nat
     ?2 Gamma |- isZero : IsZero (qzero f x) 

  Here we fail, since we just substituted the value (qzero f x) for n.
  The information qzero f x = 0 is lost.

One solution here world be to use the eta-expanded form of qzero also
when checking the body of qzero.  -}

-- simplified example

data Unit  : Set { unit : Unit }
data Empty : Set {}

fun Zero : (n : Nat) -> Set
{ Zero zero = Unit
; Zero (succ x) = Empty
}

let bla : ((n : Nat) -> Zero n -> Nat) -> (Nat -> <zero : Nat>) -> Nat -> Nat
        = \ f -> \ g -> \ x -> f (g x) unit
-- THIS DOES NOT DO the job, since g x is eta-expanded to zero.