packages feed

MiniAgda-0.2014.1.9: test/succeed/SolverBugStreamFixed.ma

-- Booleans ----------------------------------------------------------

data Bool : Set 
{ tt : Bool
; ff : Bool
}

fun ifthenelse : Bool -> [A : Set] -> A -> A -> A
{ ifthenelse tt A a1 a2 = a1
; ifthenelse ff A a1 a2 = a2
}

-- Nat ---------------------------------------------------------------

sized data SNat : Size -> Set 
{ zero : [i : Size] -> SNat ($ i)
; succ : [i : Size] -> SNat i -> SNat ($ i) 
}

let Nat : Set = SNat #

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

fun leq : Nat -> Nat -> Bool
{ leq (zero .#)    y          = tt
; leq (succ .# x) (zero .#)   = ff 
; leq (succ .# x) (succ .# y) = leq x y 
}

-- Stream ------------------------------------------------------------

sized codata Stream (+ A : Set) : Size -> Set 
{ cons : [i : Size] -> A -> Stream A i -> Stream A ($ i)
}
 
fun tail : [A : Set] -> [i : Size] -> Stream A ($ i) -> Stream A i
{ tail A i (cons .i x xs) = xs
}

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

fun nth : [A : Set] -> [i : Size] -> SNat i -> Stream A i -> A 
{ nth A i (zero (i > j))   xs = head A j xs
; nth A i (succ (i > j) n) xs = nth  A j n (tail A j xs) 
}

-- map, zip, merge ---------------------------------------------------

cofun map : [A : Set] -> [B : Set] -> [i : Size] -> 
            (A -> B) -> Stream A i -> Stream B i 
{
map A B ($ i) f (cons .i x xl) = cons _ (f x) (map A B _ f xl)
}

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 merge : [i : Size] -> (Nat -> Nat -> Bool) -> 
              Stream Nat i -> Stream Nat i -> Stream Nat i
{
merge ($ i) le (cons .i x xs) (cons .i y ys) = 
      ifthenelse (le x y) (Stream Nat _)
         (cons _ x (merge _ le xs (cons _ y ys)))
	 (cons _ y (merge _ le (cons _ x xs) ys))     
}

{-
cofun merge : [i : Size] -> (Nat -> Nat -> Bool) -> 
              Stream Nat i -> Stream Nat i -> Stream Nat i
{
merge .($ i) le (cons .i x xs) (cons i y ys) = 
      ifthenelse (le x y) (Stream Nat _)
         (cons _ x (merge _ le xs (cons _ y ys)))
	 (cons _ y (merge _ le (cons _ x xs) ys))     
}
-}

-- Hamming function --------------------------------------------------

let n0 : Nat = zero #
let n1 : Nat = succ # n0
let n2 : Nat = succ # n1
let n3 : Nat = succ # n2
let n4 : Nat = succ # n3
let n5 : Nat = succ # n4

let double : Nat -> Nat
           = \ n -> add n n
let triple : Nat -> Nat
           = \ n -> add n (double n)

cofun ham : [i : Size] -> Stream Nat i
{
  ham ($ i) = cons _ n1 (merge i leq (map Nat Nat i double (ham i)) 
                                    (map Nat Nat i triple (ham i)))
}


{-
-- THIS SHOULD NOT TYPECHECK!!
cofun map2 : [i : Size] -> (Nat -> Nat) -> Stream Nat i -> Stream Nat i 
{
map2 .($ ($ i)) f (cons .($ i) u (cons i x xl)) = 
  cons _ (f u) (cons _ (f x) (map2 _ f xl))
}

cofun ham2 : [i : Size] -> Stream Nat i
{
  ham2 ($ i) = cons _ n1 (merge i leq (map2 i double (ham2 i)) 
                                     (map2 i triple (ham2 i)))
}

-- THIS LOOPS!!!
eval let bla : Nat = nth n1 (ham2 #)
-}

-- Fibonacci stream --------------------------------------------------

{- NOT YET IMPLEMENTED: rational sizes
   WILL NOT IMPLEMENT -- see fibDeep.ma

cofun fib : [i : Size] -> Stream Nat (i + i)
{
  fib (i + 1) = cons _ n0 (cons _ n1 (zipWith Nat Nat Nat add
    i (fib i) (tail Nat i (fib (i + 1/2)))))
}

-}

{- distinguish fib from the following

cofun bad : [i : Size] -> Stream Nat i
{
  bad ($ ($ i)) = cons _ n0 (tail Nat _ (bad ($ i)))
}

-}

cofun fib : [i : Size] -> Stream Nat i
{
  fib ($ i) = cons _ n0 (zipWith Nat Nat Nat add i 
    (cons _ n1 (fib i)) (fib i))
}



cofun fibIter' : (x : Nat) -> (y : Nat) -> [i : Size] -> Stream Nat i 
{
  fibIter' x y ($ i) = cons _ x (fibIter' y (add x y) _)
} 
let fibIter : Stream Nat # = (fibIter' n1 n1 _)


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

-- fibIter(4) = 5 
eval let fibIter4 : Nat = nth Nat # n4 fibIter 

eval let fib1 : Nat = nth Nat # n1 (fib #)
eval let fib2 : Nat = nth Nat # n2 (fib #)
eval let fib3 : Nat = nth Nat # n3 (fib #)
eval let fib4 : Nat = nth Nat # n4 (fib #)
eval let fib5 : Nat = nth Nat # n5 (fib #)


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

data Leq : Nat -> Nat -> Set
{ lqz : (x : Nat) -> Leq (zero #) x 
; lqs : (x : Nat) -> (y : Nat) -> Leq x y -> Leq (succ # x) (succ # y)
}

sized codata Increasing : Size -> Stream Nat # -> Set
{
inc : [i : Size] -> (x : Nat) -> (y : Nat) -> Leq x y -> (tl : Stream Nat #) -> 
      Increasing i (cons # y tl) ->
      Increasing ($ i) (cons # x (cons # y tl)) 
}


data Eq (+ A : Set) : A -> A -> Set
{
refl : [a : A] -> Eq A a a
}

let proof : Eq (Stream Nat #) (tail Nat # fibIter) (tail Nat # fibIter) = 
  refl (tail Nat # fibIter)


-- 2010-07-07 this is just "nats" it should termination check
-- not so evil

let succ_ : [i : Size] -> SNat i -> SNat $i = \ i x -> succ i x

cofun evil : [i : Size] -> Stream Nat i
{
evil ($ i) = map Nat Nat _ (succ_ _) (cons _ (zero _) (evil _))
}

-- eval const zzz : Nat = head # (z #) 



-- convolution (Shin-Cheng Mu)
 
let cons_ : [A : Set] -> [i : Size] -> A -> Stream A i -> Stream A $i
   = \ A i a as -> cons i a as

cofun dmerge : [A : Set] -> [i : Size] -> Stream (Stream A i) i -> Stream A i
{
dmerge A ($ i) (cons .i ys yss) = 
  cons i (head A _ ys) (dmerge A i
    (zipWith A (Stream A _) (Stream A _) (cons_ A _) i 
            (tail A _ ys) yss))
}