1 | module Data.RRBVector.Internal
4 | import Data.Array.Core
5 | import Data.Array.Index
6 | import Data.Array.Indexed
11 | import Derive.Prelude
12 | import Syntax.T1 as T1
15 | %language ElabReflection
24 | bitSizeOf : (ty : Type)
27 | bitSizeOf ty = bitSize {a = ty}
47 | blocksize = integerToNat $
1 `shiftL` blockshift
53 | blockmask = minus blocksize 1
58 | up sh = plus sh blockshift
63 | down sh = minus sh blockshift
69 | radixIndex i sh = integerToNat ((natToInteger i) `shiftR` sh .&. (natToInteger blockmask))
72 | relaxedRadixIndex : Array Nat
76 | relaxedRadixIndex sizes i sh =
77 | let guess = radixIndex i sh
78 | idx = loop sizes guess
79 | subIdx = case idx == 0 of
83 | let idx' = case tryNatToFin $
minus idx 1 of
85 | assert_total $
idris_crash "Data.RRBVector.Internal.relaxedRadixIndex: index out of bounds"
88 | in minus i (at sizes.arr idx')
95 | let current = case tryNatToFin idx of
97 | assert_total $
idris_crash "Data.RRBVector.Internal.relaxedRadixIndex.loop: index out of bounds"
100 | in case i < current of
104 | assert_total $
loop sizes (plus idx 1)
114 | = Balanced (Array (Tree a))
115 | | Unbalanced (Array (Tree a)) (Array Nat)
127 | null (Balanced arr) =
129 | null (Unbalanced arr _) =
139 | foldl : (b -> a -> b)
149 | foldlTree acc' (Balanced arr) =
150 | assert_total $
foldl foldlTree acc' arr
151 | foldlTree acc' (Unbalanced arr _) =
152 | assert_total $
foldl foldlTree acc' arr
153 | foldlTree acc' (Leaf arr) =
154 | assert_total $
foldl f acc' arr
157 | foldr : (a -> b -> b)
167 | foldrTree (Balanced arr) acc' =
168 | assert_total $
foldr foldrTree acc' arr
169 | foldrTree (Unbalanced arr _) acc' =
170 | assert_total $
foldr foldrTree acc' arr
171 | foldrTree (Leaf arr) acc' =
172 | assert_total $
foldr f acc' arr
181 | toList (Balanced arr) =
182 | assert_total $
concat (map toList (toList arr))
183 | toList (Unbalanced arr _) =
184 | assert_total $
concat (map toList (toList arr))
185 | toList (Leaf arr) =
193 | Show a => Show (Tree a) where
194 | show (Balanced arr) =
195 | assert_total $
"Balanced " ++ show arr
196 | show (Unbalanced arr _) =
197 | assert_total $
"Unbalanced " ++ show arr
199 | "Leaf " ++ show arr
202 | Foldable Tree where
203 | foldl f z = Data.RRBVector.Internal.foldl f z
204 | foldr f z = Data.RRBVector.Internal.foldr f z
205 | toList = Data.RRBVector.Internal.toList
206 | null = Data.RRBVector.Internal.null
209 | Eq a => Eq (Tree a) where
210 | (Balanced arr1) == (Balanced arr2) =
211 | assert_total $
arr1 == arr2
212 | (Unbalanced arr1 _) == (Unbalanced arr2 _) =
213 | assert_total $
arr1 == arr2
214 | (Leaf arr1) == (Leaf arr2) =
220 | Ord a => Ord (Tree a) where
221 | compare tree1 tree2 =
222 | compare (Data.RRBVector.Internal.toList tree1) (Data.RRBVector.Internal.toList tree2)
229 | showTreeRep : Show a
233 | showTreeRep (Balanced trees) =
234 | assert_total $
"Balanced " ++ (show $
toList trees)
235 | showTreeRep (Unbalanced trees _) =
236 | assert_total $
"Unbalanced " ++ (show $
toList trees)
237 | showTreeRep (Leaf elems) =
238 | assert_total $
"Leaf " ++ (show $
toList elems)
251 | treeToArray : Tree a
253 | treeToArray (Balanced arr) =
255 | treeToArray (Unbalanced arr _) =
257 | treeToArray (Leaf _) =
258 | assert_total $
idris_crash "Data.RRBVector.Internal.treeToArray: leaf"
261 | treeBalanced : Tree a
263 | treeBalanced (Balanced _) =
265 | treeBalanced (Unbalanced _ _) =
267 | treeBalanced (Leaf _) =
282 | go acc _ (Leaf arr) =
284 | go acc _ (Unbalanced arr sizes) =
285 | let i = case tryNatToFin $
minus arr.size 1 of
287 | assert_total $
idris_crash "Data.RRBVector.Internal.treeSize: index out of bounds"
290 | in plus acc (at sizes.arr i)
291 | go acc sh (Balanced arr) =
292 | let i = minus arr.size 1
293 | i' = case tryNatToFin i of
295 | assert_total $
idris_crash "Data.RRBVector.Internal.treeSize: index out of bounds"
298 | in go (plus acc (mult i (integerToNat (1 `shiftL` sh))))
300 | (assert_smaller arr (at arr.arr i'))
306 | computeSizes : Shift
309 | computeSizes sh arr =
314 | let arrnat = unsafeAlloc arr.size (loop sh 0 0 arr.size (toList arr))
315 | in Unbalanced arr arrnat
317 | loop : (sh,cur,acc,n : Nat)
319 | -> WithMArray n Nat (Array Nat)
320 | loop sh _ acc n [] r = T1.do
321 | res <- unsafeFreeze r
323 | loop sh cur acc n (x :: xs) r =
324 | case tryNatToFin cur of
326 | assert_total $
idris_crash "Data.RRBVector.Internal.computeSizes.go: can't convert Nat to Fin"
328 | let acc' = plus acc (treeSize (down sh) x)
329 | in T1.do
set r cur' acc'
330 | assert_total $
loop sh (S cur) acc' n xs r
332 | maxsize = 1 `shiftL` sh
336 | lenM1 = minus len 1
343 | let subtree = case tryNatToFin i of
345 | assert_total $
idris_crash "Data.RRBVector.Internal.computeSizes.isBalanced: can't convert Nat to Fin"
348 | in case i < lenM1 of
350 | assert_total $
(natToInteger $
treeSize (down sh) subtree) == maxsize && go (plus i 1)
352 | treeBalanced subtree
355 | countTrailingZeros : Nat
357 | countTrailingZeros x =
368 | case tryNatToFin i of
370 | assert_total $
idris_crash "Data.RRBVector.Internal.countTrailingZeros: can't convert Nat to Fin"
372 | case testBit (the Int (cast x)) i' of
376 | assert_total $
go (plus i 1)
384 | let bitSizeMinus1 = minus (bitSizeOf Int) 1
385 | in minus bitSizeMinus1 (countLeadingZeros x)
387 | countLeadingZeros : Nat -> Nat
388 | countLeadingZeros x =
389 | minus (minus w 1) (go (minus w 1))
399 | case tryNatToFin i of
401 | assert_total $
idris_crash "Data.RRBVector.Internal.log2: can't convert Nat to Fin"
403 | case testBit (the Int (cast x)) i' of
407 | assert_total $
go (minus i 1)
423 | %runElab derive "RRBVector" [Show]