packages feed

pisigma-0.2: examples/Streams.pi

Unit : Type;
Unit = { unit };

Empty : Type;
Empty = { };

Bool : Type;
Bool = { true false };

T : Bool -> Type;
T = \ b -> case b of {
             true -> Unit
	   | false -> Empty };


Nat : Type;
Nat = (l : { z s }) * case l of {
                           z -> Unit
			 | s -> Rec [Nat] };

zero : Nat;
zero = ('z,'unit);

succ : Nat -> Nat;
succ = \ n -> ('s, fold n);

one : Nat;
one = succ zero;

two : Nat;
two = succ one;

add : Nat -> Nat -> Nat;
add = \ m n -> split m with (lm , m') ->
                 ! case lm of {
		     z -> [n]
 		   | s -> [succ (add (unfold m') n)] };

eqbNat : Nat -> Nat -> Bool;
eqbNat = \ m n -> split m with (lm , m') ->
                  split n with (ln , n') ->
                  ! case lm of {
		     z -> case ln of {
		             z -> ['true]
			   | s -> ['false] }
	           | s -> case ln of {
		             z -> ['false]
			   | s -> [eqbNat (unfold m') (unfold n')] } };

eqNat : Nat -> Nat -> Type;
eqNat = \ m n -> T (eqbNat m n);

reflNat : (n:Nat) -> eqNat n n;
reflNat = \ n -> split n with (ln , n') ->
       	        ! case ln of {
		     z -> ['unit]
		   | s -> [reflNat (unfold n')] };


Stream : Type -> Type;
Stream = \ a -> a * Rec [^ (Stream a)];

put : (a : Type) -> a -> Stream a -> Stream a;
put = \ a x xs -> (x, fold [xs]);

from : Nat -> Stream Nat;
from = \ n -> (n, fold [from (succ n)]);

tail : (a:Type) -> Stream a -> Stream a;
tail = \ a xs -> split xs with (x , xs') -> ! (unfold xs');

head : (a:Type) -> Stream a -> a;
head = \ a xs -> split xs with (x , xs') -> x;

map : (a : Type) -> (b : Type) -> (a -> b) -> Stream a -> Stream b;
map = \ a b f xs -> split xs with (x , xs') -> (f x, fold [map a b f (! (unfold xs'))]);

eqStream : (a : Type) -> (a -> a -> Type) -> Stream a -> Stream a -> Type;
eqStream = \ a eq xs ys ->
  split xs with (x , xs') ->
  split ys with (y , ys') ->
    eq x y * Rec [^ (eqStream a eq (! (unfold xs')) (! (unfold ys')))];

reflStream :  (a : Type) -> (eq : a -> a -> Type)
	   -> ((x : a) -> eq x x)
	   -> (xs : Stream a) -> eqStream a eq xs xs;
reflStream = \ a eq refl xs -> split xs with (x , xs') ->
	       	    	         (refl x, fold [reflStream a eq refl (! (unfold xs'))]);

lemma : (n : Nat) -> eqStream Nat eqNat (from (succ n))
                                        (map Nat Nat succ (from n));
lemma = \ n -> ((reflNat (succ n)), fold [lemma (succ n)]);