3 | module Data.SnocList.Operations
8 | import Syntax.PreorderReasoning
9 | import Syntax.PreorderReasoning.Generic
19 | takeTail : (n : Nat) -> (sx : SnocList a) -> SnocList a
20 | takeTail (S n) (sx :< x) = takeTail n sx :< x
29 | dropTail : (n : Nat) -> (sx : SnocList a) -> SnocList a
31 | dropTail (S n) [<] = [<]
32 | dropTail (S n) (sx :< x) = dropTail n sx
35 | concatDropTailTakeTail : (n : Nat) -> (sx : SnocList a) ->
36 | dropTail n sx ++ takeTail n sx === sx
37 | concatDropTailTakeTail 0 (sx :< x) = Refl
38 | concatDropTailTakeTail (S n) (sx :< x) = cong (:< x) $
concatDropTailTakeTail n sx
39 | concatDropTailTakeTail 0 [<] = Refl
40 | concatDropTailTakeTail (S k) [<] = Refl
54 | splitOntoLeft : (n : Nat) -> (sx : SnocList a) -> (xs : List a) -> (SnocList a, List a)
55 | splitOntoLeft (S n) sx (x :: xs) = splitOntoLeft n (sx :< x) xs
56 | splitOntoLeft _ sx xs = (sx, xs)
65 | splitOntoRight : (n : Nat) -> (sx : SnocList a) -> (xs : List a) -> (SnocList a, List a)
66 | splitOntoRight (S n) (sx :< x) xs = splitOntoRight n sx (x :: xs)
67 | splitOntoRight _ sx xs = (sx, xs)
70 | splitOntoRightInvariant : (n : Nat) -> (sx : SnocList a) -> (xs : List a) ->
71 | fst (splitOntoRight n sx xs) <>< snd (splitOntoRight n sx xs) === sx <>< xs
72 | splitOntoRightInvariant (S n) (sx :< x) xs = splitOntoRightInvariant n sx (x :: xs)
73 | splitOntoRightInvariant 0 sx xs = Refl
74 | splitOntoRightInvariant (S k) [<] xs = Refl
77 | splitOntoRightSpec : (n : Nat) -> (sx : SnocList a) -> (xs : List a) ->
78 | (fst (splitOntoRight n sx xs) === dropTail n sx, snd (splitOntoRight n sx xs) = takeTail n sx <>> xs)
79 | splitOntoRightSpec (S k) (sx :< x) xs = splitOntoRightSpec k sx (x :: xs)
80 | splitOntoRightSpec 0 sx xs = (Refl, Refl)
81 | splitOntoRightSpec (S k) [<] xs = (Refl, Refl)
84 | splitOntoLeftSpec : (n : Nat) -> (sx : SnocList a) -> (xs : List a) ->
85 | (fst (splitOntoLeft n sx xs) === sx <>< take n xs, snd (splitOntoLeft n sx xs) = drop n xs)
86 | splitOntoLeftSpec (S k) sx (x :: xs) = splitOntoLeftSpec k (sx :< x) xs
87 | splitOntoLeftSpec 0 sx xs = (Refl, Refl)
88 | splitOntoLeftSpec (S k) sx [] = (Refl, Refl)
91 | lengthHomomorphism : (sx,sy : SnocList a) -> length (sx ++ sy) === length sx + length sy
92 | lengthHomomorphism sx [<] = sym $
plusZeroRightNeutral _
93 | lengthHomomorphism sx (sy :< x) = Calc $
94 | |~ 1 + (length (sx ++ sy))
95 | ~~ 1 + (length sx + length sy) ...(cong (1+) $
lengthHomomorphism _ _)
96 | ~~ length sx + (1 + length sy) ...(plusSuccRightSucc _ _)
99 | lengthDistributesOverFish : (sx : SnocList a) -> (ys : List a) ->
100 | length (sx <>< ys) === length sx + length ys
101 | lengthDistributesOverFish sx [] = sym $
plusZeroRightNeutral _
102 | lengthDistributesOverFish sx (y :: ys) = Calc $
103 | |~ length ((sx :< y) <>< ys)
104 | ~~ length (sx :< y) + length ys ...( lengthDistributesOverFish (sx :< y) ys)
105 | ~~ S (length sx) + length ys ...( Refl )
106 | ~~ length sx + S (length ys) ...( plusSuccRightSucc _ _ )
107 | ~~ length sx + length (y :: ys) ...( Refl )
120 | take : (n : Nat) -> (sx : SnocList a) -> SnocList a
121 | take n sx = dropTail (length sx `minus` n) sx
132 | drop : (n : Nat) -> (sx : SnocList a) -> SnocList a
133 | drop n sx = takeTail (length sx `minus` n) sx
136 | data NonEmpty : SnocList a -> Type where
137 | IsSnoc : NonEmpty (sx :< x)
140 | last : (sx : SnocList a) -> {auto 0 nonEmpty : NonEmpty sx} -> a
141 | last (sx :< x) {nonEmpty = IsSnoc} = x
144 | intersectBy : (a -> a -> Bool) -> SnocList a -> SnocList a -> SnocList a
145 | intersectBy eq xs ys = [x | x <- xs, any (eq x) ys]
148 | intersect : Eq a => SnocList a -> SnocList a -> SnocList a
149 | intersect = intersectBy (==)