packages feed

MiniAgda-0.2014.1.9: test/succeed/fibDeep.ma

-- 2012-01-22 parameters gone from constructors

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

fun add : Nat -> Nat -> Nat 
{ add zero     = \ y -> y
; add (succ x) = \ y -> succ (add x y)
}

sized codata Stream (+ A : Set) : Size -> Set {
  cons : [i : Size] -> A -> Stream A i -> Stream A ($ i)
}

fun head : [A : Set] -> [i : Size] -> Stream A ($ i) -> A 
{ head A i (cons .i a as) = a
}

fun tail : [A : Set] -> [i : Size] -> Stream A ($ i) -> Stream A i
{ tail A i (cons .i a as) = as
}

cofun zipWith : [A : Set] -> [B : Set] -> [C : Set] -> (A -> B -> C) -> 
                [i : Size] -> Stream A i -> Stream B i -> Stream C i 
{ zipWith A B C f ($ i) (cons .i a as) (cons .i b bs) = 
    cons i (f a b)  (zipWith A B C f i as bs) 
}

cofun adds : [i : Size] -> Stream Nat i -> Stream Nat i -> Stream Nat i 
{ adds ($ i) (cons .i a as) (cons .i b bs) = 
    cons i (add a b) (adds i as bs)
}

let one : Nat = succ zero

{- Size matching

at type  [i : Size] -> Co i  one can match i against ($ j) 
since for i = 0,  Co i is the set of all terms

type checking rule

    i:Size, j < i, i --> $ j |- e : Gamma -> Co ($ j)
    -------------------------------------------------
    case i { ($ j) -> e } : Gamma -> Co i 

basically, there is an analysis whether the type of the case is
"everything"  (opposite of empty).

 -}

cofun fib' : [i : Size] -> Stream Nat i
{
  fib' i = case i
   { ($ j) -> cons j zero (case j 
   { ($ k) -> cons k one (zipWith Nat Nat Nat add k 
                              (fib' k) 
                              (tail Nat k (fib' ($ k))))})}
}

{- we can pull one case into the pattern match, but not both -}

cofun fib : [i : Size] -> Stream Nat i
{ fib ($ i) = cons i zero (case i 
    { ($ j) -> cons j one (adds j (fib j) (tail Nat j (fib i)))})
} 

{- blueprint
cofun fib : [i : Size] -> Stream Nat i
{ fib ? = cons ? zero 
    (cons ? one (adds ? (fib ?) (tail Nat ? (fib ?))))
} 
-- UNSOUND
cofun fib : [i : Size] -> Stream Nat i
{ fib ($$ i) = cons ($ i) zero 
    (cons i one (adds i (fib i) (tail Nat ($ i) (fib ($ i)))))
} 
-}

{- the question is how to facilitate inference for this? 
   We need to insert case splits at the appropriate positions.
   Why not, this is a form of type reconstruction.
   Relies on bidirectional type checking.
   Currently, MiniAgda does not check constructors, but infers them, which is bad. 
 -}