|
| 1 | +||| General purpose linear two-end finite sequences, |
| 2 | +||| with length in its type. |
| 3 | +||| |
| 4 | +||| This is implemented by finger tree. |
| 5 | +module Data.Seq1.Sized |
| 6 | + |
| 7 | +import Control.WellFounded |
| 8 | + |
| 9 | +import public Data.Fin |
| 10 | +import Data.Linear.Ref1 |
| 11 | +import public Data.Nat |
| 12 | +import public Data.Vect |
| 13 | +import public Data.Zippable |
| 14 | + |
| 15 | +import Data.Seq.Internal |
| 16 | + |
| 17 | +%default total |
| 18 | + |
| 19 | +||| A linear two-end finite sequence, with length in its type. |
| 20 | +export |
| 21 | +data Seq1 : (s : Type) -> (n : Nat) -> (e : Type) -> Type where |
| 22 | + MkSeq1 : Ref s (FingerTree (Elem e)) |
| 23 | + -> Seq1 s n e |
| 24 | + |
| 25 | +||| The empty sequence. O(1) |
| 26 | +export |
| 27 | +empty : F1 s (Seq1 s 0 e) |
| 28 | +empty t = |
| 29 | + let seq # t := ref1 Empty t |
| 30 | + in (MkSeq1 seq) # t |
| 31 | + |
| 32 | +||| A singleton sequence. O(1) |
| 33 | +export |
| 34 | +singleton : e |
| 35 | + -> F1 s (Seq1 s 1 e) |
| 36 | +singleton a t = |
| 37 | + let seq # t := ref1 (Single (MkElem a)) t |
| 38 | + in (MkSeq1 seq) # t |
| 39 | + |
| 40 | +||| A sequence of length n with a the value of every element. O(n) |
| 41 | +export |
| 42 | +replicate : (n : Nat) |
| 43 | + -> (a : e) |
| 44 | + -> F1 s (Seq1 s n e) |
| 45 | +replicate n a t = |
| 46 | + let seq # t := ref1 (replicate' n a) t |
| 47 | + in (MkSeq1 seq) # t |
| 48 | + |
| 49 | +||| The number of elements in the sequence. O(1) |
| 50 | +export |
| 51 | +length : {n : Nat} |
| 52 | + -> Seq1 s n e |
| 53 | + -> F1 s Nat |
| 54 | +length _ t = |
| 55 | + n # t |
| 56 | + |
| 57 | +||| Reverse the sequence. O(n) |
| 58 | +export |
| 59 | +reverse : Seq1 s n e |
| 60 | + -> F1' s |
| 61 | +reverse (MkSeq1 tr) t = |
| 62 | + let tr' # t := read1 tr t |
| 63 | + in casswap1 tr (reverseTree id tr') t |
| 64 | + |
| 65 | +export infixr 5 `cons` |
| 66 | +||| Add an element to the left end of a sequence. O(1) |
| 67 | +export |
| 68 | +cons : e |
| 69 | + -> Seq1 s n e |
| 70 | + -> F1 s (Seq1 s (S n) e) |
| 71 | +(a `cons` MkSeq1 tr) t = |
| 72 | + let tr' # t := read1 tr t |
| 73 | + () # t := casswap1 tr (MkElem a `consTree` tr') t |
| 74 | + in (MkSeq1 tr) # t |
| 75 | + |
| 76 | +export infixl 5 `snoc` |
| 77 | +||| Add an element to the right end of a sequence. O(1) |
| 78 | +export |
| 79 | +snoc : Seq1 s n e |
| 80 | + -> e |
| 81 | + -> F1 s (Seq1 s (S n) e) |
| 82 | +(MkSeq1 tr `snoc` a) t = |
| 83 | + let tr' # t := read1 tr t |
| 84 | + () # t := casswap1 tr (tr' `snocTree` MkElem a) t |
| 85 | + in (MkSeq1 tr) # t |
| 86 | + |
| 87 | +||| Concatenate two sequences. O(log(min(m, n))) |
| 88 | +export |
| 89 | +(++) : Seq1 s m e |
| 90 | + -> Seq1 s n e |
| 91 | + -> F1 s (Seq1 s (m + n) e) |
| 92 | +(MkSeq1 t1 ++ MkSeq1 t2) t = |
| 93 | + let t1' # t := read1 t1 t |
| 94 | + t2' # t := read1 t2 t |
| 95 | + t1t2 # t := ref1 (addTree0 t1' t2') t |
| 96 | + in (MkSeq1 t1t2) # t |
| 97 | + |
| 98 | +||| View from the left of the sequence. O(1) |
| 99 | +export |
| 100 | +viewl : Seq1 s (S n) e |
| 101 | + -> F1 s (Maybe (e, Seq1 s n e)) |
| 102 | +viewl (MkSeq1 tr) t = |
| 103 | + let tr' # t := read1 tr t |
| 104 | + in case viewLTree tr' of |
| 105 | + Just (MkElem a, tr'') => |
| 106 | + let () # t := casswap1 tr tr'' t |
| 107 | + in (Just (a, MkSeq1 tr)) # t |
| 108 | + Nothing => |
| 109 | + Nothing # t |
| 110 | +
|
| 111 | +||| The first element of the sequence. O(1) |
| 112 | +export |
| 113 | +head : Seq1 s (S n) e |
| 114 | + -> F1 s (Maybe e) |
| 115 | +head seq t = |
| 116 | + let seq' # t := viewl seq t |
| 117 | + in case seq' of |
| 118 | + Nothing => |
| 119 | + Nothing # t |
| 120 | + Just (h, _) => |
| 121 | + (Just h) # t |
| 122 | + |
| 123 | +||| The elements after the head of the sequence. O(1) |
| 124 | +export |
| 125 | +tail : Seq1 s (S n) e |
| 126 | + -> F1 s (Maybe (Seq1 s n e)) |
| 127 | +tail seq t = |
| 128 | + let seq' # t := viewl seq t |
| 129 | + in case seq' of |
| 130 | + Nothing => |
| 131 | + Nothing # t |
| 132 | + Just (_, seq'') => |
| 133 | + (Just seq'') # t |
| 134 | +
|
| 135 | +||| View from the right of the sequence. O(1) |
| 136 | +export |
| 137 | +viewr : Seq1 s (S n) e |
| 138 | + -> F1 s (Maybe (Seq1 s n e, e)) |
| 139 | +viewr (MkSeq1 tr) t = |
| 140 | + let tr' # t := read1 tr t |
| 141 | + in case viewRTree tr' of |
| 142 | + Just (tr'', MkElem a) => |
| 143 | + let () # t := casswap1 tr tr'' t |
| 144 | + in (Just (MkSeq1 tr, a)) # t |
| 145 | + Nothing => |
| 146 | + Nothing # t |
| 147 | +
|
| 148 | +||| The elements before the last element of the sequence. O(1) |
| 149 | +export |
| 150 | +init : Seq1 s (S n) e |
| 151 | + -> F1 s (Maybe (Seq1 s n e)) |
| 152 | +init seq t = |
| 153 | + let seq' # t := viewr seq t |
| 154 | + in case seq' of |
| 155 | + Nothing => |
| 156 | + Nothing # t |
| 157 | + Just (seq'', _) => |
| 158 | + (Just seq'') # t |
| 159 | +
|
| 160 | +||| The last element of the sequence. O(1) |
| 161 | +export |
| 162 | +last : Seq1 s (S n) e |
| 163 | + -> F1 s (Maybe e) |
| 164 | +last seq t = |
| 165 | + let seq' # t := viewr seq t |
| 166 | + in case seq' of |
| 167 | + Nothing => |
| 168 | + Nothing # t |
| 169 | + Just (_, l) => |
| 170 | + (Just l) # t |
| 171 | + |
| 172 | +||| Turn a vector into a sequence. O(n) |
| 173 | +export |
| 174 | +fromVect : Vect n e |
| 175 | + -> F1 s (Seq1 s n e) |
| 176 | +fromVect xs t = |
| 177 | + let seq # t := ref1 (foldr (\x, tr => MkElem x `consTree` tr) Empty xs) t |
| 178 | + in (MkSeq1 seq) # t |
| 179 | + |
| 180 | +||| Turn a list into a sequence. O(n) |
| 181 | +export |
| 182 | +fromList : (xs : List e) |
| 183 | + -> F1 s (Seq1 s (length xs) e) |
| 184 | +fromList xs t = |
| 185 | + let vect := Vect.fromList xs |
| 186 | + in fromVect vect t |
| 187 | + |
| 188 | +||| Turn a sequence into a list. O(n) |
| 189 | +export |
| 190 | +toList : {n : Nat} |
| 191 | + -> Seq1 s n e |
| 192 | + -> F1 s (List e) |
| 193 | +toList _ {n = 0} t = |
| 194 | + [] # t |
| 195 | +toList seq {n = S _} t = |
| 196 | + go seq Lin t |
| 197 | + where |
| 198 | + go : {n : Nat} |
| 199 | + -> Seq1 s n e |
| 200 | + -> (sl : SnocList e) |
| 201 | + -> F1 s (List e) |
| 202 | + go _ sl {n = 0} t = |
| 203 | + (sl <>> []) # t |
| 204 | + go seq sl {n = S _} t = |
| 205 | + let seq' # t := viewl seq t |
| 206 | + in case seq' of |
| 207 | + Nothing => |
| 208 | + (sl <>> []) # t |
| 209 | + Just (x, seq'') => |
| 210 | + go seq'' (sl :< x) t |
| 211 | +
|
| 212 | +||| The element at the specified position. O(log(min(i, n-i))) |
| 213 | +export |
| 214 | +index : (i : Nat) |
| 215 | + -> (t : Seq1 s n e) |
| 216 | + -> {auto ok : LT i n} |
| 217 | + -> F1 s e |
| 218 | +index i (MkSeq1 tr) t = |
| 219 | + let tr' # t := read1 tr t |
| 220 | + (_, MkElem a) := lookupTree i tr' |
| 221 | + in a # t |
| 222 | + |
| 223 | +||| The element at the specified position. |
| 224 | +||| Use Fin n to index instead. O(log(min(i, n-i))) |
| 225 | +export |
| 226 | +index' : (t : Seq1 s n e) |
| 227 | + -> (i : Fin n) |
| 228 | + -> F1 s e |
| 229 | +index' (MkSeq1 tr) fn t = |
| 230 | + let tr' # t := read1 tr t |
| 231 | + (_, MkElem a) := lookupTree (finToNat fn) tr' |
| 232 | + in a # t |
| 233 | + |
| 234 | +||| Update the element at the specified position. O(log(min(i, n-i))) |
| 235 | +export |
| 236 | +adjust : (f : e -> e) |
| 237 | + -> (i : Nat) |
| 238 | + -> (t : Seq1 s n e) |
| 239 | + -> {auto ok : LT i n} |
| 240 | + -> F1' s |
| 241 | +adjust f i (MkSeq1 tr) t = |
| 242 | + let tr' # t := read1 tr t |
| 243 | + in casswap1 tr (adjustTree (const (map f)) i tr') t |
| 244 | + |
| 245 | +||| Replace the element at the specified position. O(log(min(i, n-i))) |
| 246 | +export |
| 247 | +update : (i : Nat) |
| 248 | + -> e |
| 249 | + -> (seq : Seq1 s n e) |
| 250 | + -> {auto ok : LT i n} |
| 251 | + -> F1' s |
| 252 | +update i a seq t = |
| 253 | + adjust (const a) i seq t |
| 254 | + |
| 255 | +||| Split a sequence at a given position. O(log(min(i, n-i))) |
| 256 | +export |
| 257 | +splitAt : (i : Nat) |
| 258 | + -> Seq1 s (i + j) e |
| 259 | + -> F1 s (Seq1 s i e, Seq1 s j e) |
| 260 | +splitAt i (MkSeq1 tr) t = |
| 261 | + let tr' # t := read1 tr t |
| 262 | + (l, r) := split i tr' |
| 263 | + l' # t := ref1 l t |
| 264 | + r' # t := ref1 r t |
| 265 | + in (MkSeq1 l', MkSeq1 r') # t |
| 266 | + |
| 267 | +||| The first i elements of a sequence. O(log(min(i, n-i))) |
| 268 | +export |
| 269 | +take : (i : Nat) |
| 270 | + -> Seq1 s (i + j) e |
| 271 | + -> F1 s (Seq1 s i e) |
| 272 | +take i seq t = |
| 273 | + let (seq1, _) # t := Data.Seq1.Sized.splitAt i seq t |
| 274 | + in seq1 # t |
| 275 | + |
| 276 | +||| Elements of a sequence after the first i. O(log(min(i, n-i))) |
| 277 | +export |
| 278 | +drop : (i : Nat) |
| 279 | + -> Seq1 s (i + j) e |
| 280 | + -> F1 s (Seq1 s j e) |
| 281 | +drop i seq t = |
| 282 | + let (_, seq2) # t := Data.Seq1.Sized.splitAt i seq t |
| 283 | + in seq2 # t |
| 284 | + |
| 285 | +||| Dump the internal structure of the finger tree. |
| 286 | +export |
| 287 | +show' : Show e |
| 288 | + => Seq1 s n e |
| 289 | + -> F1 s String |
| 290 | +show' (MkSeq1 tr) t = |
| 291 | + let tr' # t := read1 tr t |
| 292 | + in (showPrec Open tr') # t |
0 commit comments