1 | module Data.RRBVector.Internal
4 | import Data.Array.Core
5 | import Data.Array.Index
6 | import Data.Array.Indexed
12 | import Derive.Prelude
13 | import Syntax.T1 as T1
16 | %language ElabReflection
25 | bitSizeOf : (ty : Type)
28 | bitSizeOf ty = bitSize {a = ty}
58 | record RelaxedIndex (count : Nat) where
59 | constructor MkRelaxedIndex
81 | blocksize = integerToNat $
1 `shiftL` blockshift
87 | blockmask = minus blocksize 1
92 | up sh = plus sh blockshift
97 | down sh = minus sh blockshift
103 | radixIndex i sh = integerToNat ((natToInteger i) `shiftR` sh .&. (natToInteger blockmask))
124 | data Children : Type -> Type where
125 | MkChildren : {n : Nat}
126 | -> {auto 0 nonEmpty : LT 0 n}
127 | -> {auto 0 withinBlock : LTE n Data.RRBVector.Internal.blocksize}
128 | -> IArray n (Tree a)
145 | data RelaxedChildren : Type -> Type where
146 | MkRelaxedChildren : {n : Nat}
147 | -> {auto 0 nonEmpty : LT 0 n}
148 | -> {auto 0 withinBlock : LTE n Data.RRBVector.Internal.blocksize}
149 | -> IArray n (Tree a)
151 | -> RelaxedChildren a
168 | data Tree : Type -> Type where
169 | Balanced : Children a
171 | Unbalanced : RelaxedChildren a
187 | childrenToArray : Children a
189 | childrenToArray (MkChildren {n} arr) =
199 | relaxedChildrenToArray : RelaxedChildren a
201 | relaxedChildrenToArray (MkRelaxedChildren {n} children _) =
208 | relaxedSizesToArray : RelaxedChildren a
210 | relaxedSizesToArray (MkRelaxedChildren {n} _ sizes) =
222 | null (Balanced _) =
224 | null (Unbalanced _) =
234 | foldl : (b -> a -> b)
244 | foldlTree acc' (Balanced (MkChildren {n} arr)) =
245 | assert_total (foldl foldlTree acc' (A n arr))
246 | foldlTree acc' (Unbalanced (MkRelaxedChildren {n} arr _)) =
247 | assert_total (foldl foldlTree acc' (A n arr))
248 | foldlTree acc' (Leaf arr) =
249 | assert_total (foldl f acc' arr)
252 | foldr : (a -> b -> b)
262 | foldrTree (Balanced (MkChildren {n} arr)) acc' =
263 | assert_total (foldr foldrTree acc' (A n arr))
264 | foldrTree (Unbalanced (MkRelaxedChildren {n} arr _)) acc' =
265 | assert_total (foldr foldrTree acc' (A n arr))
266 | foldrTree (Leaf arr) acc' =
267 | assert_total (foldr f acc' arr)
276 | toList (Balanced (MkChildren {n} arr)) =
277 | assert_total (concat $
map toList $
toList (A n arr))
278 | toList (Unbalanced (MkRelaxedChildren {n} arr _)) =
279 | assert_total (concat $
map toList $
toList (A n arr))
280 | toList (Leaf arr) =
288 | Show a => Show (Tree a) where
289 | show (Balanced children) =
290 | assert_total ("Balanced " ++ show (childrenToArray children))
291 | show (Unbalanced children) =
292 | assert_total ("Unbalanced " ++ show (relaxedChildrenToArray children))
294 | "Leaf " ++ show arr
297 | Foldable Tree where
298 | foldl f z = Data.RRBVector.Internal.foldl f z
299 | foldr f z = Data.RRBVector.Internal.foldr f z
300 | toList = Data.RRBVector.Internal.toList
301 | null = Data.RRBVector.Internal.null
304 | Eq a => Eq (Tree a) where
305 | Balanced xs == Balanced ys =
306 | assert_total (childrenToArray xs == childrenToArray ys)
307 | Unbalanced xs == Unbalanced ys =
308 | assert_total (relaxedChildrenToArray xs == relaxedChildrenToArray ys)
309 | Leaf xs == Leaf ys =
315 | Ord a => Ord (Tree a) where
316 | compare tree1 tree2 =
317 | compare (Data.RRBVector.Internal.toList tree1) (Data.RRBVector.Internal.toList tree2)
324 | showTreeRep : Show a
328 | showTreeRep (Balanced children) =
329 | assert_total ("Balanced " ++ show (toList $
childrenToArray children))
330 | showTreeRep (Unbalanced children) =
331 | assert_total ("Unbalanced " ++ show (toList $
relaxedChildrenToArray children))
332 | showTreeRep (Leaf elems) =
333 | assert_total ("Leaf " ++ show (toList elems))
346 | treeToArray : Tree a
348 | treeToArray (Balanced children) =
349 | childrenToArray children
350 | treeToArray (Unbalanced children) =
351 | relaxedChildrenToArray children
352 | treeToArray (Leaf _) =
353 | assert_total (idris_crash "Data.RRBVector.Internal.treeToArray: leaf")
356 | treeBalanced : Tree a
358 | treeBalanced (Balanced _) =
360 | treeBalanced (Unbalanced _) =
362 | treeBalanced (Leaf _) =
378 | go acc _ (Leaf arr) =
380 | go acc _ (Unbalanced (MkRelaxedChildren {n = S k} _ sizes)) =
381 | plus acc (lastAt sizes)
382 | go acc sh (Balanced (MkChildren {n = S k} children)) =
383 | let subtreeSize : Nat
384 | subtreeSize = integerToNat (1 `shiftL` sh)
386 | acc' = plus acc (mult k subtreeSize)
388 | child = lastAt children
389 | in go acc' (down sh) (assert_smaller children child)
414 | relaxedRadixIndex : {n : Nat}
415 | -> {auto 0 nonEmpty : LT 0 n}
420 | relaxedRadixIndex {n = Z} {nonEmpty} sizes i sh impossible
421 | relaxedRadixIndex {n = S k} sizes i sh =
423 | guess = radixIndex i sh
424 | 0 guessLT : LT guess (S k)
425 | guessLT = believe_me ()
427 | child = natToFinLT guess @{guessLT}
428 | in assert_total (loop child)
436 | childOffset : Fin (S k)
440 | childOffset (FS previous) =
441 | minus i (at sizes (weaken previous))
449 | -> RelaxedIndex (S k)
452 | current = at sizes child
453 | in case i < current of
455 | MkRelaxedIndex child (childOffset child)
458 | next = S (finToNat child)
459 | 0 nextLT : LT next (S k)
460 | nextLT = believe_me ()
461 | nextchild : Fin (S k)
462 | nextchild = natToFinLT next @{nextLT}
463 | in assert_total (loop nextchild)
475 | computeSizes : Shift
478 | computeSizes sh children@(MkChildren {n} {nonEmpty} {withinBlock} trees) =
479 | case isBalanced n of
483 | let sizes : IArray n Nat
484 | sizes = unsafeAlloc n (loop n 0)
485 | in Unbalanced (MkRelaxedChildren {nonEmpty = nonEmpty} {withinBlock = withinBlock} trees sizes)
492 | loop : (remaining : Nat)
493 | -> {auto pos : Ix remaining n}
495 | -> WithMArray n Nat (IArray n Nat)
496 | loop Z acc r = T1.do
498 | loop (S k) {pos} acc r =
499 | let subtree : Tree a
500 | subtree = ix trees k
502 | acc' = plus acc (treeSize (down sh) subtree)
507 | assert_total $
loop k acc' r
511 | maxsize = 1 `shiftL` sh
515 | isBalanced : (remaining : Nat)
516 | -> {auto pos : Ix remaining n}
521 | treeBalanced (ix trees Z)
522 | isBalanced (S (S k)) =
523 | let subtree : Tree a
524 | subtree = ix trees (S k)
525 | in assert_total ((natToInteger $
treeSize (down sh) subtree) == maxsize && isBalanced (S k))
537 | countTrailingZeros : Nat
539 | countTrailingZeros x =
546 | go : (remaining : Nat)
547 | -> {auto pos : Ix remaining (bitSizeOf Int)}
552 | let bit : Fin (bitSizeOf Int)
554 | in case testBit value bit of
558 | assert_total (go k)
587 | go : (remaining : Nat)
588 | -> {auto 0 valid : LTE remaining (bitSizeOf Int)}
593 | let bit : Fin (bitSizeOf Int)
594 | bit = natToFinLT k @{valid}
595 | in case testBit value bit of
599 | assert_total (go k {valid = lteSuccLeft valid})
615 | %runElab derive "RRBVector" [Show]