-
Notifications
You must be signed in to change notification settings - Fork 24
/
Lists.hs
50 lines (38 loc) · 1.32 KB
/
Lists.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{-@ LIQUID "--reflection" @-}
{-@ LIQUID "--ple" @-}
module Lists where
import Prelude hiding ((++))
import ProofCombinators
-- data [a] = [] | a : List a
-- deriving (Eq, Show)
{-@ reflect cons @-}
cons :: a -> [a] -> [a]
cons x xs = x : xs
{-@ infixr ++ @-}
{-@ reflect ++ @-}
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
{-@ reflect rev @-}
rev :: [a] -> [a]
rev [] = []
rev (x:xs) = rev xs ++ [x]
{-@ lemma_app_assoc :: xs:_ -> ys:_ -> zs:_ ->
{ (xs ++ ys) ++ zs = xs ++ (ys ++ zs) } @-}
lemma_app_assoc :: [a] -> [a] -> [a] -> Proof
lemma_app_assoc [] _ _ = ()
lemma_app_assoc (_:xs) ys zs = lemma_app_assoc xs ys zs
{-@ lemma_app_Nil2 :: xs:_ -> { xs ++ [] = xs } @-}
lemma_app_Nil2 :: [a] -> Proof
lemma_app_Nil2 [] = ()
lemma_app_Nil2 (x:xs) = lemma_app_Nil2 xs
{-@ lemma_rev_app :: xs:_ -> ys:_ -> { rev (xs ++ ys) = rev ys ++ rev xs} @-}
lemma_rev_app :: [a] -> [a] -> Proof
lemma_rev_app [] ys = lemma_app_Nil2 (rev ys)
lemma_rev_app (x:xs) ys = lemma_rev_app xs ys
&&& lemma_app_assoc (rev ys) (rev xs) [x]
{-@ theorem_rev_rev :: xs:_ -> { rev (rev xs) = xs } @-}
theorem_rev_rev :: [a] -> Proof
theorem_rev_rev [] = ()
theorem_rev_rev (x:xs) = lemma_rev_app (rev xs) [x]
&&& theorem_rev_rev xs