1 | module Data.RRBVector.Unsized.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
23 | bitSizeOf : (ty : Type)
26 | bitSizeOf ty = bitSize {a = ty}
44 | blocksize = integerToNat $
1 `shiftL` blockshift
49 | blockmask = minus blocksize 1
54 | up sh = plus sh blockshift
59 | down sh = minus sh blockshift
65 | radixIndex i sh = integerToNat ((natToInteger i) `shiftR` sh .&. (natToInteger blockmask))
68 | relaxedRadixIndex : Array Nat
72 | relaxedRadixIndex sizes i sh =
73 | let guess = radixIndex i sh
74 | idx = loop sizes guess
75 | subIdx = case idx == 0 of
79 | let idx' = case tryNatToFin $
minus idx 1 of
81 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.relaxedRadixIndex: index out of bounds"
84 | in minus i (at sizes.arr idx')
91 | let current = case tryNatToFin idx of
93 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.relaxedRadixIndex.loop: index out of bounds"
96 | in case i < current of
100 | assert_total $
loop sizes (plus idx 1)
108 | data Tree a = Balanced (Array (Tree a))
109 | | Unbalanced (Array (Tree a)) (Array Nat)
120 | null (Balanced arr) =
122 | null (Unbalanced arr _) =
132 | foldl : (b -> a -> b)
142 | foldlTree acc' (Balanced arr) =
143 | assert_total $
foldl foldlTree acc' arr
144 | foldlTree acc' (Unbalanced arr _) =
145 | assert_total $
foldl foldlTree acc' arr
146 | foldlTree acc' (Leaf arr) =
147 | assert_total $
foldl f acc' arr
150 | foldr : (a -> b -> b)
160 | foldrTree (Balanced arr) acc' =
161 | assert_total $
foldr foldrTree acc' arr
162 | foldrTree (Unbalanced arr _) acc' =
163 | assert_total $
foldr foldrTree acc' arr
164 | foldrTree (Leaf arr) acc' =
165 | assert_total $
foldr f acc' arr
174 | toList (Balanced arr) =
175 | assert_total $
concat (map toList (toList arr))
176 | toList (Unbalanced arr _) =
177 | assert_total $
concat (map toList (toList arr))
178 | toList (Leaf arr) =
186 | Show a => Show (Tree a) where
187 | show (Balanced arr) =
188 | assert_total $
"Balanced " ++ show arr
189 | show (Unbalanced arr _) =
190 | assert_total $
"Unbalanced " ++ show arr
192 | "Leaf " ++ show arr
195 | Foldable Tree where
196 | foldl f z = Data.RRBVector.Unsized.Internal.foldl f z
197 | foldr f z = Data.RRBVector.Unsized.Internal.foldr f z
198 | toList = Data.RRBVector.Unsized.Internal.toList
199 | null = Data.RRBVector.Unsized.Internal.null
202 | Eq a => Eq (Tree a) where
203 | (Balanced arr1) == (Balanced arr2) =
204 | assert_total $
arr1 == arr2
205 | (Unbalanced arr1 _) == (Unbalanced arr2 _) =
206 | assert_total $
arr1 == arr2
207 | (Leaf arr1) == (Leaf arr2) =
213 | Ord a => Ord (Tree a) where
214 | compare tree1 tree2 =
215 | compare (Data.RRBVector.Unsized.Internal.toList tree1) (Data.RRBVector.Unsized.Internal.toList tree2)
222 | showTreeRep : Show a
226 | showTreeRep (Balanced trees) =
227 | assert_total $
"Balanced " ++ (show $
toList trees)
228 | showTreeRep (Unbalanced trees _) =
229 | assert_total $
"Unbalanced " ++ (show $
toList trees)
230 | showTreeRep (Leaf elems) =
231 | assert_total $
"Leaf " ++ (show $
toList elems)
244 | treeToArray : Tree a
246 | treeToArray (Balanced arr) =
248 | treeToArray (Unbalanced arr _) =
250 | treeToArray (Leaf _) =
251 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.treeToArray: leaf"
254 | treeBalanced : Tree a
256 | treeBalanced (Balanced _) =
258 | treeBalanced (Unbalanced _ _) =
260 | treeBalanced (Leaf _) =
274 | go acc _ (Leaf arr) =
276 | go acc _ (Unbalanced arr sizes) =
277 | let i = case tryNatToFin $
minus arr.size 1 of
279 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.treeSize: index out of bounds"
282 | in plus acc (at sizes.arr i)
283 | go acc sh (Balanced arr) =
284 | let i = minus arr.size 1
285 | i' = case tryNatToFin i of
287 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.treeSize: index out of bounds"
290 | in go (plus acc (mult i (integerToNat (1 `shiftL` sh))))
292 | (assert_smaller arr (at arr.arr i'))
297 | computeSizes : Shift
300 | computeSizes sh arr =
305 | let arrnat = unsafeAlloc arr.size (loop sh 0 0 arr.size (toList arr))
306 | in Unbalanced arr arrnat
308 | loop : (sh,cur,acc,n : Nat)
310 | -> WithMArray n Nat (Array Nat)
311 | loop sh _ acc n [] r = T1.do
312 | res <- unsafeFreeze r
314 | loop sh cur acc n (x :: xs) r =
315 | case tryNatToFin cur of
317 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.computeSizes.go: can't convert Nat to Fin"
319 | let acc' = plus acc (treeSize (down sh) x)
320 | in T1.do
set r cur' acc'
321 | assert_total $
loop sh (S cur) acc' n xs r
323 | maxsize = 1 `shiftL` sh
327 | lenM1 = minus len 1
334 | let subtree = case tryNatToFin i of
336 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.computeSizes.isBalanced: can't convert Nat to Fin"
339 | in case i < lenM1 of
341 | assert_total $
(natToInteger $
treeSize (down sh) subtree) == maxsize && go (plus i 1)
343 | treeBalanced subtree
346 | countTrailingZeros : Nat
348 | countTrailingZeros x =
359 | case tryNatToFin i of
361 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.countTrailingZeros: can't convert Nat to Fin"
363 | case testBit (the Int (cast x)) i' of
367 | assert_total $
go (plus i 1)
374 | let bitSizeMinus1 = minus (bitSizeOf Int) 1
375 | in minus bitSizeMinus1 (countLeadingZeros x)
377 | countLeadingZeros : Nat -> Nat
378 | countLeadingZeros x =
379 | minus (minus w 1) (go (minus w 1))
389 | case tryNatToFin i of
391 | assert_total $
idris_crash "Data.RRBVector.Unsized.Internal.log2: can't convert Nat to Fin"
393 | case testBit (the Int (cast x)) i' of
397 | assert_total $
go (minus i 1)
406 | data RRBVector a = Root Nat
411 | %runElab derive "RRBVector" [Show]