0 | module Data.List.Views.Extra
3 | import Data.List.Reverse
4 | import Data.List.Views
6 | import Data.List.Equalities
12 | data Balanced : Nat -> Nat -> Type where
13 | BalancedZ : Balanced Z Z
14 | BalancedL : Balanced (S Z) Z
15 | BalancedRec : Balanced n m -> Balanced (S n) (S m)
17 | %name Balanced
bal, b
19 | Uninhabited (Balanced Z (S k)) where
20 | uninhabited BalancedZ
impossible
21 | uninhabited BalancedL
impossible
22 | uninhabited (BalancedRec rec
) impossible
25 | balancedPred : Balanced (S x) (S y) -> Balanced x y
26 | balancedPred (BalancedRec pred) = pred
29 | mkBalancedEq : {n, m : Nat} -> n = m -> Balanced n m
30 | mkBalancedEq {n = 0} Refl = BalancedZ
31 | mkBalancedEq {n = (S k)} Refl = BalancedRec $
mkBalancedEq {n = k} Refl
34 | mkBalancedL : {n, m : Nat} -> n = S m -> Balanced n m
35 | mkBalancedL {m = 0} Refl = BalancedL
36 | mkBalancedL {m = S k} Refl = BalancedRec (mkBalancedL Refl)
42 | data SplitBalanced : List a -> Type where
45 | -> Balanced (length xs) (length ys)
46 | -> SplitBalanced (xs ++ ys)
52 | -> (doubleSkip : List a)
53 | -> (length rs = length revLs + length doubleSkip)
54 | -> SplitBalanced (reverse revLs ++ rs)
55 | splitBalancedHelper revLs rs [] prf = MkSplitBal balancedLeftsAndRights
57 | lengthsEqual : length rs = length revLs
59 | rewrite sym (plusZeroRightNeutral (length revLs)) in prf
60 | balancedLeftsAndRights : Balanced (length (reverse revLs)) (length rs)
61 | balancedLeftsAndRights =
62 | rewrite reverseLength revLs in
63 | rewrite lengthsEqual in
65 | splitBalancedHelper revLs [] (x :: xs) prf =
67 | the (0 = S (plus (length revLs) (length xs))) $
68 | rewrite plusSuccRightSucc (length revLs) (length xs) in
70 | splitBalancedHelper revLs (x :: rs) [lastItem] prf =
71 | rewrite appendAssociative (reverse revLs) [x] rs in
72 | rewrite sym (reverseCons x revLs) in
74 | the (Balanced (length (reverseOnto [x] revLs)) (length rs)) $
75 | rewrite reverseCons x revLs in
76 | rewrite lengthSnoc x (reverse revLs) in
77 | rewrite reverseLength revLs in
78 | rewrite lengthsEqual in
81 | lengthsEqual : length rs = length revLs
84 | the (S (length rs) = S (length revLs)) $
85 | rewrite plusCommutative 1 (length revLs) in prf
86 | splitBalancedHelper revLs (x :: oneFurther) (_ :: (_ :: twoFurther)) prf =
87 | rewrite appendAssociative (reverse revLs) [x] oneFurther in
88 | rewrite sym (reverseCons x revLs) in
89 | splitBalancedHelper (x :: revLs) oneFurther twoFurther $
91 | the (S (length oneFurther) = S (S (plus (length revLs) (length twoFurther)))) $
92 | rewrite plusSuccRightSucc (length revLs) (length twoFurther) in
93 | rewrite plusSuccRightSucc (length revLs) (S (length twoFurther)) in
100 | splitBalanced : (input : List a) -> SplitBalanced input
101 | splitBalanced input = splitBalancedHelper [] input input Refl
106 | data VList : List a -> Type where
109 | VCons : {x, y : a} -> {xs : List a} -> (rec : Lazy (VList xs)) -> VList (x :: xs ++ [y])
115 | -> Balanced (length xs) (length ys)
116 | -> VList (xs ++ ys)
117 | toVList [] Empty BalancedZ = VNil
118 | toVList [x] Empty BalancedL = VOne
119 | toVList [] (Snoc x zs rec) prf =
121 | the (Balanced 0 (S (length zs))) $
122 | rewrite sym (lengthSnoc x zs) in prf
123 | toVList (x :: xs) (Snoc y ys srec) prf =
124 | rewrite appendAssociative xs ys [y] in
128 | rewrite sym (lengthSnoc y ys) in prf
133 | vList : (xs : List a) -> VList xs
134 | vList xs with (splitBalanced xs)
135 | vList (ys ++ zs) | (MkSplitBal prf) = toVList ys (snocList zs) prf
139 | data LazyFilterRec : List a -> Type where
140 | Exhausted : (skip : List a) -> LazyFilterRec skip
141 | Found : (skip : List a)
143 | -> Lazy (LazyFilterRec rest)
144 | -> LazyFilterRec (skip ++ (head :: rest))
149 | lazyFilterRec : (pred : (a -> Bool)) -> (xs : List a) -> LazyFilterRec xs
150 | lazyFilterRec pred [] = Exhausted []
151 | lazyFilterRec pred (x :: xs) with (pred x)
152 | lazyFilterRec pred (x :: xs) | True = Found [] x (lazyFilterRec pred xs)
153 | lazyFilterRec pred (x :: []) | False = Exhausted [x]
154 | lazyFilterRec pred (x :: rest@(_ :: xs)) | False = filterHelper [x] rest
157 | : (reverseOfSkipped : List a)
158 | -> {auto prf1 : NonEmpty reverseOfSkipped}
160 | -> {auto prf2 : NonEmpty rest}
161 | -> LazyFilterRec (reverse reverseOfSkipped ++ rest)
162 | filterHelper revSkipped (y :: xs) with (pred y)
163 | filterHelper revSkipped (y :: xs) | True =
164 | Found (reverse revSkipped) y (lazyFilterRec pred xs)
165 | filterHelper revSkipped (y :: []) | False =
166 | rewrite sym (reverseOntoSpec [y] revSkipped) in
167 | Exhausted $
reverse (y :: revSkipped)
168 | filterHelper revSkipped (y :: (z :: zs)) | False =
169 | rewrite appendAssociative (reverse revSkipped) [y] (z :: zs) in
170 | rewrite sym (reverseOntoSpec [y] revSkipped) in
171 | filterHelper (y :: revSkipped) (z :: zs)