Files
newt/playground/samples/Concat.newt

61 lines
1.7 KiB
Agda

module Concat
data Nat : U where
Z : Nat
S : Nat -> Nat
infixl 7 _+_
_+_ : Nat -> Nat -> Nat
Z + m = m
S n + m = S (n + m)
infixr 3 _::_
data List : U -> U where
Nil : {A : U} -> List A
_::_ : {A : U} -> A -> List A -> List A
length : {A : U} -> List A -> Nat
length Nil = Z
length (x :: xs) = S (length xs)
infixl 2 _++_
_++_ : {A : U} -> List A -> List A -> List A
Nil ++ ys = ys
x :: xs ++ ys = x :: (xs ++ ys)
infixl 1 _≡_
data _≡_ : {A : U} -> A -> A -> U where
Refl : {A : U} {a : A} -> a a
sym : {A : U} {a b : A} -> a b -> b a
sym Refl = Refl
replace : {A : U} {a b : A} -> (P : A -> U) -> a b -> P a -> P b
replace p Refl x = x
cong : {A B : U} {a b : A} -> (f : A -> B) -> a b -> f a f b
length-++ : {A : U} (xs ys : List A) -> length (xs ++ ys) length xs + length ys
length-++ Nil ys = Refl
length-++ (x :: xs) ys = cong S (length-++ xs ys)
-- PLFA definition
reverse : {A : U} -> (xs : List A) -> List A
reverse Nil = Nil
reverse (x :: xs) = reverse xs ++ (x :: Nil)
++-identity : {A : U} -> (xs : List A) -> xs ++ Nil xs
++-identity Nil = Refl
++-identity (x :: xs) = cong (_::_ x) (++-identity xs)
++-associative : {A : U} (xs ys zs : List A) -> xs ++ (ys ++ zs) (xs ++ ys) ++ zs
-- TODO port equational reasoning
reverse-++-distrib : {A : U} -> (xs ys : List A) -> reverse (xs ++ ys) reverse ys ++ reverse xs
reverse-++-distrib Nil ys = replace (\ z => reverse ys z) (sym (++-identity (reverse ys))) Refl
reverse-++-distrib {A} (x :: xs) ys =
replace (\ z => (reverse (xs ++ ys) ++ (x :: Nil)) z)
(sym (++-associative (reverse ys) (reverse xs) (x :: Nil)))
(replace (\ z => (reverse (xs ++ ys)) ++ (x :: Nil) z ++ (x :: Nil)) (reverse-++-distrib xs ys) Refl)