0 | module Data.List.Equalities
2 | import Control.Function
3 | import Syntax.PreorderReasoning
6 | import Data.List.Reverse
12 | snocNonEmpty : {x : a} -> {xs : List a} -> Not (xs ++ [x] = [])
13 | snocNonEmpty {xs = []} prf = uninhabited prf
14 | snocNonEmpty {xs = y :: ys} prf = uninhabited prf
18 | SnocNonEmpty : (xs : List a) -> (x : a) -> NonEmpty (xs `snoc` x)
19 | SnocNonEmpty [] _ = IsNonEmpty
20 | SnocNonEmpty (_::_) _ = IsNonEmpty
24 | consCong2 : {x : a} -> {xs : List a} -> {y : b} -> {ys : List b} ->
25 | x = y -> xs = ys -> x :: xs = y :: ys
26 | consCong2 Refl Refl = Refl
30 | snocInjective : {x : a} -> {xs : List a} -> {y : a} -> {ys : List a} ->
31 | (xs `snoc` x) = (ys `snoc` y) -> (xs = ys, x = y)
32 | snocInjective {xs = []} {ys = []} Refl = (Refl, Refl)
33 | snocInjective {xs = []} {ys = z :: zs} prf =
34 | let nilIsSnoc = snd $
consInjective {xs = []} {ys = zs ++ [y]} prf
35 | in void $
snocNonEmpty (sym nilIsSnoc)
36 | snocInjective {xs = z :: xs} {ys = []} prf =
37 | let snocIsNil = snd $
consInjective {x = z} {xs = xs ++ [x]} {ys = []} prf
38 | in void $
snocNonEmpty snocIsNil
39 | snocInjective {xs = w :: xs} {ys = z :: ys} prf =
40 | let (wEqualsZ, xsSnocXEqualsYsSnocY) = biinjective prf
41 | (xsEqualsYS, xEqualsY) = snocInjective xsSnocXEqualsYsSnocY
42 | in (consCong2 wEqualsZ xsEqualsYS, xEqualsY)
46 | appendCong2 : {x1 : List a} -> {x2 : List a} ->
47 | {y1 : List b} -> {y2 : List b} ->
48 | x1 = y1 -> x2 = y2 -> x1 ++ x2 = y1 ++ y2
49 | appendCong2 {x1=[]
} {y1=(_ ::
_)} Refl
_ impossible
50 | appendCong2 {x1=(_ ::
_)} {y1=[]
} Refl
_ impossible
51 | appendCong2 {x1=[]} {y1=[]} _ eq2 = eq2
52 | appendCong2 {x1=(_ :: _)} {y1=(_ :: _)} eq1 eq2 =
53 | let (hdEqual, tlEqual) = consInjective eq1
54 | in consCong2 hdEqual (appendCong2 tlEqual eq2)
58 | mapDistributesOverAppend
62 | -> map f (xs ++ ys) = map f xs ++ map f ys
63 | mapDistributesOverAppend _ [] _ = Refl
64 | mapDistributesOverAppend f (x :: xs) ys =
65 | cong (f x ::) $
mapDistributesOverAppend f xs ys
69 | lengthDistributesOverAppend
71 | -> length (xs ++ ys) = length xs + length ys
72 | lengthDistributesOverAppend [] ys = Refl
73 | lengthDistributesOverAppend (x :: xs) ys =
74 | cong S $
lengthDistributesOverAppend xs ys
78 | lengthSnoc : (x : _) -> (xs : List a) -> length (snoc xs x) = S (length xs)
79 | lengthSnoc x [] = Refl
80 | lengthSnoc x (_ :: xs) = cong S (lengthSnoc x xs)
84 | appendSameLeftInjective : (xs, ys, zs : List a) -> zs ++ xs = zs ++ ys -> xs = ys
85 | appendSameLeftInjective xs ys [] = id
86 | appendSameLeftInjective xs ys (_::zs) = appendSameLeftInjective xs ys zs . snd . biinjective
90 | appendSameRightInjective : (xs, ys, zs : List a) -> xs ++ zs = ys ++ zs -> xs = ys
91 | appendSameRightInjective xs ys [] = rewrite appendNilRightNeutral xs in
92 | rewrite appendNilRightNeutral ys in
94 | appendSameRightInjective xs ys (z::zs) = rewrite appendAssociative xs [z] zs in
95 | rewrite appendAssociative ys [z] zs in
96 | fst . snocInjective . appendSameRightInjective (xs ++ [z]) (ys ++ [z]) zs
99 | {zs : List a} -> Injective (zs ++) where
100 | injective = appendSameLeftInjective _ _ zs
103 | {zs : List a} -> Injective (++ zs) where
104 | injective = appendSameRightInjective _ _ zs
108 | appendNonEmptyLeftNotEq : (zs, xs : List a) -> NonEmpty xs => Not (zs = xs ++ zs)
109 | appendNonEmptyLeftNotEq [] (_::_) Refl impossible
110 | appendNonEmptyLeftNotEq (z::zs) (_::xs) prf
111 | = appendNonEmptyLeftNotEq zs (xs ++ [z]) @{SnocNonEmpty xs z}
112 | $
rewrite sym $
appendAssociative xs [z] zs in snd $
biinjective prf
116 | appendNonEmptyRightNotEq : (zs, xs : List a) -> NonEmpty xs => Not (zs = zs ++ xs)
117 | appendNonEmptyRightNotEq [] (_::_) Refl impossible
118 | appendNonEmptyRightNotEq (_::zs) (x::xs) prf = appendNonEmptyRightNotEq zs (x::xs) $
snd $
biinjective prf
120 | listBindOntoPrf : (xs: List a)
121 | -> (f: a -> List b)
122 | -> (zs, ys: List b)
123 | -> listBindOnto f (reverse zs ++ reverse ys) xs = ys ++ listBindOnto f (reverse zs) xs
124 | listBindOntoPrf [] f zs ys =
126 | |~ reverse (reverse zs ++ reverse ys)
127 | ~~ reverse (reverse (ys ++ zs)) ... cong reverse (revAppend ys zs)
128 | ~~ ys ++ zs ... reverseInvolutive _
129 | ~~ ys ++ reverse (reverse zs) ... cong (ys ++) (sym $
reverseInvolutive _)
130 | listBindOntoPrf (x::xs) f zs ys =
132 | |~ listBindOnto f (reverseOnto (reverse zs ++ reverse ys) (f x)) xs
133 | ~~ listBindOnto f (reverse (f x) ++ reverse zs ++ reverse ys) xs
134 | ... cong (\n => listBindOnto f n xs)
135 | (reverseOntoSpec _ _)
136 | ~~ listBindOnto f ((reverse (f x) ++ reverse zs) ++ reverse ys) xs
137 | ... cong (\n => listBindOnto f n xs)
138 | (appendAssociative _ _ _)
139 | ~~ listBindOnto f (reverse (zs ++ f x) ++ reverse ys) xs
140 | ... cong (\n => listBindOnto f (n ++ reverse ys) xs)
142 | ~~ ys ++ listBindOnto f (reverse (zs ++ f x)) xs ... listBindOntoPrf _ _ _ _
143 | ~~ ys ++ listBindOnto f (reverse (f x) ++ reverse zs) xs
144 | ... cong (\n => ys ++ listBindOnto f n xs)
145 | (sym $
revAppend _ _)
146 | ~~ ys ++ listBindOnto f (reverseOnto (reverse zs) (f x)) xs
147 | ... cong (\n => ys ++ listBindOnto f n xs)
148 | (sym $
reverseOntoSpec _ _)
152 | bindConcatPrf : (xs: List a)
154 | -> (f: a -> List b)
155 | -> ((x::xs >>= f) = (f x) ++ (xs >>= f))
156 | bindConcatPrf xs x f =
158 | |~ listBindOnto f ([] ++ reverse (f x)) xs
159 | ~~ listBindOnto f (reverse [] ++ reverse (f x)) xs
160 | ... cong (\n => listBindOnto f (n ++ reverse (f x)) xs)
162 | ~~ f x ++ listBindOnto f [] xs ... listBindOntoPrf xs f [] (f x)