1 | module Data.RRBVector
3 | import public Data.RRBVector.Internal
6 | import Data.Array.Core
7 | import Data.Array.Index
8 | import Data.Array.Indexed
10 | import Data.Linear.Ref1
11 | import Data.Linear.Traverse1
15 | import Data.SnocList
17 | import Data.Zippable
18 | import Syntax.T1 as T1
21 | %hide Prelude.Ops.infixr.(<|)
22 | %hide Prelude.Ops.infixl.(|>)
54 | singleton x = Root 1 0 (Leaf $
A 1 $
fill 1 x)
62 | fromList [x] = singleton x
64 | case nodes Leaf xs of
66 | Root (treeSize 0 tree) 0 tree
68 | assert_smaller xs (iterateNodes blockshift xs')
70 | nodes : (Array a -> Tree a)
74 | let (trees', rest) = unsafeAlloc blocksize (go 0 blocksize f trees)
79 | (trees' :: nodes f (assert_smaller trees rest'))
82 | -> (Array a -> Tree a)
84 | -> WithMArray n a (Tree a,List a)
85 | go cur n f [] r = T1.do
86 | res <- unsafeFreeze r
87 | pure $
(f $
force $
take cur $
A n res,[])
88 | go cur n f (x :: xs) r =
91 | res <- unsafeFreeze r
92 | pure $
(f $
A n res, x :: xs)
94 | case tryNatToFin cur of
96 | assert_total $
idris_crash "Data.RRBVector.fromList.node: can't convert Nat to Fin"
100 | nodes' : (Array (Tree a) -> Tree a)
104 | let (trees', rest) = unsafeAlloc blocksize (go 0 blocksize f trees)
109 | (trees' :: nodes' f (assert_smaller trees rest'))
112 | -> (Array (Tree a) -> Tree a)
114 | -> WithMArray n (Tree a) (Tree a,List (Tree a))
115 | go cur n f [] r = T1.do
116 | res <- unsafeFreeze r
117 | pure $
(f $
force $
take cur $
A n res,[])
118 | go cur n f (x :: xs) r =
121 | res <- unsafeFreeze r
122 | pure $
(f $
A n res, x :: xs)
124 | case tryNatToFin cur of
126 | assert_total $
idris_crash "Data.RRBVector.fromList.node': can't convert Nat to Fin"
129 | go (S cur) n f xs r
133 | iterateNodes sh trees =
134 | case nodes' Balanced trees of
136 | Root (treeSize sh tree) sh tree
138 | iterateNodes (up sh) (assert_smaller trees trees')
147 | case compare n 0 of
153 | case compare n blocksize of
155 | Root n 0 (Leaf $
A n $
fill n x)
157 | Root n 0 (Leaf $
A n $
fill n x)
159 | let size' = integerToNat ((natToInteger $
minus n 1) .&. (natToInteger $
plus blockmask 1))
160 | in iterateNodes blockshift
161 | (Leaf $
A blocksize $
fill blocksize x)
162 | (Leaf $
A size' $
fill size' x)
164 | iterateNodes : Shift
168 | iterateNodes sh full rest =
169 | let subtreesm1 = (natToInteger $
minus n 1) `shiftR` sh
170 | restsize = integerToNat (subtreesm1 .&. (natToInteger blockmask))
171 | rest' = Balanced $
A (plus restsize 1) $
append (fill restsize full) (fill 1 rest)
172 | in case compare subtreesm1 (natToInteger blocksize) of
176 | let full' = Balanced (A blocksize $
fill blocksize full)
177 | in iterateNodes (up sh) (assert_smaller full full') (assert_smaller rest rest')
179 | let full' = Balanced (A blocksize $
fill blocksize full)
180 | in iterateNodes (up sh) (assert_smaller full full') (assert_smaller rest rest')
189 | toList : RRBVector a
192 | toList (Root _ _ tree) = treeToList tree
194 | treeToList : Tree a
196 | treeToList (Balanced trees) = assert_total $
concat (map treeToList (toList trees))
197 | treeToList (Unbalanced trees _) = assert_total $
concat (map treeToList (toList trees))
198 | treeToList (Leaf arr) = toList arr
205 | foldl : (b -> a -> b)
214 | foldlTree acc' (Balanced arr) = assert_total $
foldl foldlTree acc' arr
215 | foldlTree acc' (Unbalanced arr _) = assert_total $
foldl foldlTree acc' arr
216 | foldlTree acc' (Leaf arr) = assert_total $
foldl f acc' arr
220 | go (Root _ _ tree) = assert_total $
foldlTree acc tree
223 | foldr : (a -> b -> b)
232 | foldrTree (Balanced arr) acc' = assert_total $
foldr foldrTree acc' arr
233 | foldrTree (Unbalanced arr _) acc' = assert_total $
foldr foldrTree acc' arr
234 | foldrTree (Leaf arr) acc' = assert_total $
foldr f acc' arr
238 | go (Root _ _ tree) = assert_total $
foldrTree tree acc
255 | length : RRBVector a
258 | length (Root s _ _) = s
270 | lookup _ Empty = Nothing
271 | lookup i (Root size sh tree) =
272 | case compare i 0 of
276 | case compare i size of
282 | Just $
lookupTree i sh tree
284 | case compare i size of
290 | Just $
lookupTree i sh tree
296 | lookupTree i sh (Balanced arr) =
297 | case tryNatToFin (radixIndex i sh) of
299 | assert_total $
idris_crash "Data.RRBVector.lookup: can't convert Nat to Fin"
301 | assert_total $
lookupTree i (down sh) (at arr.arr i')
302 | lookupTree i sh (Unbalanced arr sizes) =
303 | let (idx, subidx) = relaxedRadixIndex sizes i sh
304 | in case tryNatToFin idx of
306 | assert_total $
idris_crash "Data.RRBVector.lookup: can't convert Nat to Fin"
308 | assert_total $
lookupTree subidx (down sh) (at arr.arr idx')
309 | lookupTree i _ (Leaf arr) =
310 | let i' = integerToNat ((natToInteger i) .&. (natToInteger blockmask))
311 | in case tryNatToFin i' of
313 | assert_total $
idris_crash "Data.RRBVector.lookup: can't convert Nat to Fin"
324 | index i = fromMaybe (assert_total $
idris_crash "Data.RRBVector.index: index out of range") . lookup i
350 | update _ _ Empty = Empty
351 | update i x v@(Root size sh tree) =
352 | case compare i 0 of
356 | case compare i size of
362 | Root size sh (updateTree i sh tree)
364 | case compare i size of
370 | Root size sh (updateTree i sh tree)
376 | updateTree i sh (Balanced arr) =
377 | case tryNatToFin (radixIndex i sh) of
379 | assert_total $
idris_crash "Data.RRBVector.update: can't convert Nat to Fin"
381 | assert_total $
Balanced (A arr.size (updateAt i' (updateTree i (down sh)) arr.arr))
382 | updateTree i sh (Unbalanced arr sizes) =
383 | let (idx, subidx) = relaxedRadixIndex sizes i sh
384 | in case tryNatToFin idx of
386 | assert_total $
idris_crash "Data.RRBVector.update: can't convert Nat to Fin"
388 | assert_total $
Unbalanced (A arr.size (updateAt idx' (updateTree subidx (down sh)) arr.arr)) sizes
389 | updateTree i _ (Leaf arr) =
390 | let i' = integerToNat ((natToInteger i) .&. (natToInteger blockmask))
391 | in case tryNatToFin i' of
393 | assert_total $
idris_crash "Data.RRBVector.update: can't convert Nat to Fin"
395 | Leaf (A arr.size (setAt i'' x arr.arr))
405 | adjust _ _ Empty = Empty
406 | adjust i f v@(Root size sh tree) =
407 | case compare i 0 of
411 | case compare i size of
417 | Root size sh (adjustTree i sh tree)
419 | case compare i size of
425 | Root size sh (adjustTree i sh tree)
431 | adjustTree i sh (Balanced arr) =
432 | case tryNatToFin (radixIndex i sh) of
434 | assert_total $
idris_crash "Data.RRBVector.adjust: can't convert Nat to Fin"
436 | assert_total $
Balanced (A arr.size (updateAt i' (adjustTree i (down sh)) arr.arr))
437 | adjustTree i sh (Unbalanced arr sizes) =
438 | let (idx, subidx) = relaxedRadixIndex sizes i sh
439 | in case tryNatToFin idx of
441 | assert_total $
idris_crash "Data.RRBVector.adjust: can't convert Nat to Fin"
443 | assert_total $
Unbalanced (A arr.size (updateAt idx' (adjustTree subidx (down sh)) arr.arr)) sizes
444 | adjustTree i _ (Leaf arr) =
445 | let i' = integerToNat ((natToInteger i) .&. (natToInteger blockmask))
446 | in case tryNatToFin i' of
448 | assert_total $
idris_crash "Data.RRBVector.adjust: can't convert Nat to Fin"
450 | Leaf (A arr.size (updateAt i'' f arr.arr))
453 | normalize : RRBVector a
455 | normalize v@(Root size sh (Balanced arr)) =
456 | case compare arr.size 1 of
460 | case tryNatToFin 0 of
462 | assert_total $
idris_crash "Data.RRBVector.normalize: can't convert Nat to Fin"
464 | assert_total $
normalize $
Root size (down sh) (at arr.arr i)
467 | normalize v@(Root size sh (Unbalanced arr _)) =
468 | case compare arr.size 1 of
472 | case tryNatToFin 0 of
474 | assert_total $
idris_crash "Data.RRBVector.normalize: can't convert Nat to Fin"
476 | assert_total $
normalize $
Root size (down sh) (at arr.arr i)
489 | takeTree i sh (Balanced arr) with (radixIndex i sh) | ((plus (radixIndex i sh) 1) <= arr.size) proof eq
491 | case tryNatToFin i' of
493 | assert_total $
idris_crash "Data.RRBVector.takeTree: can't convert Nat to Fin"
495 | let newarr = force $
take (plus (radixIndex i sh) 1) arr.arr @{lteOpReflectsLTE _ _ eq}
496 | in assert_total $
Balanced (A (plus (radixIndex i sh) 1) (updateAt i'' (takeTree i (down sh)) newarr))
498 | assert_total $
idris_crash "Data.RRBVector.takeTree: index out of bounds"
499 | takeTree i sh (Unbalanced arr sizes) with (relaxedRadixIndex sizes i sh) | ((plus (fst (relaxedRadixIndex sizes i sh)) 1) <= arr.size) proof eq
500 | _ | (idx, subidx) | True =
501 | case tryNatToFin idx of
503 | assert_total $
idris_crash "Data.RRBVector.takeTree: can't convert Nat to Fin"
505 | let newarr = force $
take (plus (fst (relaxedRadixIndex sizes i sh)) 1) arr.arr @{lteOpReflectsLTE _ _ eq}
506 | in assert_total $
computeSizes sh (A (plus (fst (relaxedRadixIndex sizes i sh)) 1) (updateAt idx' (takeTree subidx (down sh)) newarr))
508 | assert_total $
idris_crash "Data.RRBVector.takeTree: index out of bounds"
509 | takeTree i _ (Leaf arr) with (integerToNat (((natToInteger i) .&. (natToInteger blockmask)) + 1) <= arr.size) proof eq
511 | let newarr = force $
take (integerToNat (((natToInteger i) .&. (natToInteger blockmask)) + 1)) arr.arr @{lteOpReflectsLTE _ _ eq}
512 | in Leaf (A (integerToNat (((natToInteger i) .&. (natToInteger blockmask)) + 1)) newarr)
514 | assert_total $
idris_crash "Data.RRBVector.takeTree: index out of bounds"
521 | dropTree n sh (Balanced arr) =
522 | case tryNatToFin 0 of
524 | assert_total $
idris_crash "Data.RRBVector.dropTree: can't convert Nat to Fin"
526 | let newarr = force $
drop (radixIndex n sh) arr.arr
527 | in assert_total $
computeSizes sh (A (minus arr.size (radixIndex n sh)) (updateAt zero (dropTree n (down sh)) newarr))
528 | dropTree n sh (Unbalanced arr sizes) =
529 | case tryNatToFin 0 of
531 | assert_total $
idris_crash "Data.RRBVector.dropTree: can't convert Nat to Fin"
533 | let newarr = force $
drop (fst $
relaxedRadixIndex sizes n sh) arr.arr
534 | in assert_total $
computeSizes sh (A (minus arr.size (fst $
relaxedRadixIndex sizes n sh)) (updateAt zero (dropTree (snd $
relaxedRadixIndex sizes n sh) (down sh)) newarr))
535 | dropTree n _ (Leaf arr) =
536 | let n = integerToNat ((natToInteger n) .&. (natToInteger blockmask))
537 | newarr = force $
drop n arr.arr
538 | in Leaf (A (minus arr.size n) newarr)
547 | take _ Empty = Empty
548 | take n v@(Root size sh tree) =
549 | case compare n 0 of
555 | case compare n size of
557 | normalize $
Root n sh (takeTree (minus n 1) sh tree)
570 | drop _ Empty = Empty
571 | drop n v@(Root size sh tree) =
572 | case compare n 0 of
578 | case compare n size of
580 | normalize $
Root (minus size n) sh (dropTree n sh tree)
591 | -> (RRBVector a, RRBVector a)
592 | splitAt _ Empty = (Empty, Empty)
593 | splitAt n v@(Root size sh tree) =
594 | case compare n 0 of
600 | case compare n size of
602 | let left = normalize $
Root n sh (takeTree (minus n 1) sh tree)
603 | right = normalize $
Root (minus size n) sh (dropTree n sh tree)
617 | viewl : RRBVector a
618 | -> Maybe (a, RRBVector a)
619 | viewl Empty = Nothing
620 | viewl v@(Root _ _ tree) =
621 | let tail = drop 1 v
622 | in Just (headTree tree, tail)
624 | headTree : Tree a -> a
625 | headTree (Balanced arr) =
626 | case tryNatToFin 0 of
628 | assert_total $
idris_crash "Data.RRBVector.viewl: can't convert Nat to Fin"
630 | assert_total $
headTree (at arr.arr zero)
631 | headTree (Unbalanced arr _) =
632 | case tryNatToFin 0 of
634 | assert_total $
idris_crash "Data.RRBVector.viewl: can't convert Nat to Fin"
636 | assert_total $
headTree (at arr.arr zero)
637 | headTree (Leaf arr) =
638 | case tryNatToFin 0 of
640 | assert_total $
idris_crash "Data.RRBVector.viewl: can't convert Nat to Fin"
647 | viewr : RRBVector a
648 | -> Maybe (RRBVector a, a)
649 | viewr Empty = Nothing
650 | viewr v@(Root size _ tree) =
651 | let init = take (minus size 1) v
652 | in Just (init, lastTree tree)
654 | lastTree : Tree a -> a
655 | lastTree (Balanced arr) =
656 | case tryNatToFin (minus size 1) of
658 | assert_total $
idris_crash "Data.RRBVector.viewr: can't convert Nat to Fin"
660 | assert_total $
lastTree (at arr.arr last)
661 | lastTree (Unbalanced arr _) =
662 | case tryNatToFin (minus size 1) of
664 | assert_total $
idris_crash "Data.RRBVector.viewr: can't convert Nat to Fin"
666 | assert_total $
lastTree (at arr.arr last)
667 | lastTree (Leaf arr) =
668 | case tryNatToFin (minus size 1) of
670 | assert_total $
idris_crash "Data.RRBVector.viewr: can't convert Nat to Fin"
684 | map _ Empty = Empty
685 | map f (Root size sh tree) = Root size sh (mapTree tree)
687 | mapTree : Tree a -> Tree b
688 | mapTree (Balanced arr) =
689 | assert_total $
Balanced (map mapTree arr)
690 | mapTree (Unbalanced arr sizes) =
691 | assert_total $
Unbalanced (map mapTree arr) sizes
692 | mapTree (Leaf arr) =
698 | reverse : RRBVector a
701 | case compare (length v) 1 of
707 | case fromList $
toList v of
709 | assert_total $
idris_crash "Data.RRBVector.reverse: can't convert to List1"
711 | fromList $
forget $
reverse v'
719 | -> RRBVector (a, b)
721 | case fromList $
toList v1 of
723 | assert_total $
idris_crash "Data.RRBVector.zip: can't convert to List1"
725 | case fromList $
toList v2 of
727 | assert_total $
idris_crash "Data.RRBVector.zip: can't convert to List1"
729 | fromList $
forget $
zip v1' v2'
741 | newBranch x 0 = Leaf (singleton x)
742 | newBranch x sh = assert_total $
Balanced (singleton $
newBranch x (down sh))
750 | x <| Empty = singleton x
751 | x <| Root size sh tree =
752 | case compare insertshift sh of
754 | Root (plus size 1) sh (consTree sh tree)
756 | Root (plus size 1) sh (consTree sh tree)
758 | let new = A 2 $
array $
fromList [(newBranch x sh), tree]
759 | in Root (plus size 1) insertshift (computeSizes insertshift new)
768 | computeShift sz sh min (Balanced _) =
770 | let hishift = let comp = mult (log2 (minus sz 1) `div` blockshift) blockshift
771 | in case compare comp 0 of
778 | hi = (natToInteger $
minus sz 1) `shiftR` hishift
779 | newshift = case compare hi (natToInteger blockmask) of
783 | plus hishift blockshift
785 | plus hishift blockshift
786 | in case compare newshift sh of
793 | computeShift _ sh min (Unbalanced arr sizes) =
794 | let sz' = case tryNatToFin 0 of
796 | assert_total $
idris_crash "Data.RRBVector.(<|).computeShift.Unbalanced: can't convert Nat to Fin"
799 | newtree = case tryNatToFin 0 of
801 | assert_total $
idris_crash "Data.RRBVector.(<|).computeShift.Unbalanced: can't convert Nat to Fin"
804 | newmin = case compare arr.size blocksize of
811 | in assert_total $
computeShift sz' (down sh) newmin newtree
812 | computeShift _ _ min (Leaf arr) =
813 | case compare arr.size blocksize of
821 | insertshift = computeShift size sh (up sh) tree
825 | consTree sh (Balanced arr) =
826 | case compare sh insertshift of
828 | case tryNatToFin 0 of
830 | assert_total $
idris_crash "Data.RRBVector.(<|).consTree.Balanced: can't convert Nat to Fin"
832 | assert_total $
computeSizes sh (A arr.size $
updateAt zero (consTree (down sh)) arr.arr)
834 | computeSizes sh (A (S arr.size) (append (fill 1 (newBranch x (down sh))) arr.arr))
836 | case tryNatToFin 0 of
838 | assert_total $
idris_crash "Data.RRBVector.(<|).consTree.Balanced: can't convert Nat to Fin"
840 | assert_total $
computeSizes sh (A arr.size $
updateAt zero (consTree (down sh)) arr.arr)
841 | consTree sh (Unbalanced arr _) =
842 | case compare sh insertshift of
844 | case tryNatToFin 0 of
846 | assert_total $
idris_crash "Data.RRBVector.(<|).consTree.Unbalanced: can't convert Nat to Fin"
848 | assert_total $
computeSizes sh (A arr.size $
updateAt zero (consTree (down sh)) arr.arr)
850 | computeSizes sh (A (S arr.size) (append (fill 1 (newBranch x (down sh))) arr.arr))
852 | case tryNatToFin 0 of
854 | assert_total $
idris_crash "Data.RRBVector.(<|).consTree.Unbalanced: can't convert Nat to Fin"
856 | assert_total $
computeSizes sh (A arr.size $
updateAt zero (consTree (down sh)) arr.arr)
857 | consTree _ (Leaf arr) =
858 | Leaf (A (S arr.size) (append (fill 1 x) arr.arr))
866 | Empty |> x = singleton x
867 | Root size sh tree |> x =
868 | case compare insertshift sh of
870 | Root (plus size 1) sh (snocTree sh tree)
872 | Root (plus size 1) sh (snocTree sh tree)
874 | let new = A 2 $
array $
fromList [tree,(newBranch x sh)]
875 | in Root (plus size 1) insertshift (computeSizes insertshift new)
884 | computeShift sz sh min (Balanced _) =
886 | let newshift = mult (countTrailingZeros sz `div` blockshift) blockshift
887 | in case compare newshift sh of
894 | computeShift _ sh min (Unbalanced arr sizes) =
895 | let lastidx = minus arr.size 1
896 | sz' = case tryNatToFin lastidx of
898 | assert_total $
idris_crash "Data.RRBVector.(|>).computeShift.Unbalanced: can't convert Nat to Fin"
900 | case tryNatToFin $
minus lastidx 1 of
902 | assert_total $
idris_crash "Data.RRBVector.(|>).computeShift.Unbalanced: can't convert Nat to Fin"
904 | minus (at sizes.arr lastidx') (at sizes.arr lastidx'')
905 | newtree = case tryNatToFin lastidx of
907 | assert_total $
idris_crash "Data.RRBVector.(|>).computeShift.Unbalanced: can't convert Nat to Fin"
909 | at arr.arr lastidx'
910 | newmin = case compare arr.size blocksize of
917 | in assert_total $
computeShift sz' (down sh) newmin newtree
918 | computeShift _ _ min (Leaf arr) =
919 | case compare arr.size blocksize of
927 | insertshift = computeShift size sh (up sh) tree
931 | snocTree sh (Balanced arr) =
932 | case compare sh insertshift of
934 | case tryNatToFin $
minus arr.size 1 of
936 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Balanced: can't convert Nat to Fin"
938 | assert_total $
Balanced (A arr.size $
updateAt lastidx (snocTree (down sh)) arr.arr)
940 | Balanced (A (plus arr.size 1) (append arr.arr (fill 1 (newBranch x (down sh)))))
942 | case tryNatToFin $
minus arr.size 1 of
944 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Balanced: can't convert Nat to Fin"
946 | assert_total $
Balanced (A arr.size $
updateAt lastidx (snocTree (down sh)) arr.arr)
947 | snocTree sh (Unbalanced arr sizes) =
948 | case compare sh insertshift of
950 | case tryNatToFin $
minus arr.size 1 of
952 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Unbalanced: can't convert Nat to Fin"
954 | case tryNatToFin $
minus sizes.size 1 of
956 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Unbalanced: can't convert Nat to Fin"
958 | let lastsize = plus (at sizes.arr lastidxs) 1
959 | in assert_total $
Unbalanced (A arr.size (updateAt lastidxa (snocTree (down sh)) arr.arr))
960 | (A sizes.size (setAt lastidxs lastsize sizes.arr))
962 | case tryNatToFin $
minus sizes.size 1 of
964 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Unbalanced: can't convert Nat to Fin"
966 | let lastsize = plus (at sizes.arr lastidx) 1
967 | in assert_total $
Unbalanced (A (plus arr.size 1) (append arr.arr (fill 1 (newBranch x (down sh)))))
968 | (A (plus sizes.size 1) (append sizes.arr (fill 1 lastsize)))
970 | case tryNatToFin $
minus arr.size 1 of
972 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Unbalanced: can't convert Nat to Fin"
974 | case tryNatToFin $
minus sizes.size 1 of
976 | assert_total $
idris_crash "Data.RRBVector.(|>).snocTree.Unbalanced: can't convert Nat to Fin"
978 | let lastsize = plus (at sizes.arr lastidxs) 1
979 | in assert_total $
Unbalanced (A arr.size (updateAt lastidxa (snocTree (down sh)) arr.arr))
980 | (A sizes.size (setAt lastidxs lastsize sizes.arr))
981 | snocTree _ (Leaf arr) = Leaf (A (plus arr.size 1) (append arr.arr (fill 1 x)))
991 | Root size1 sh1 tree1 >< Root size2 sh2 tree2 =
992 | let upmaxshift = case compare sh1 sh2 of
999 | newarr = mergeTrees tree1 sh1 tree2 sh2
1000 | in normalize $
Root (plus size1 size2) upmaxshift (computeSizes upmaxshift newarr)
1002 | viewlArr : Array (Tree a) -> (Tree a, Array (Tree a))
1006 | assert_total $
idris_crash "Data.RRBVector.(><).viewlArr: can't convert Nat to Fin"
1008 | (at arr.arr zero, drop 1 arr)
1009 | viewrArr : Array (Tree b) -> (Array (Tree b), Tree b)
1011 | case tryNatToFin $
minus arr.size 1 of
1013 | assert_total $
idris_crash "Data.RRBVector.(><).viewrArr: can't convert Nat to Fin"
1015 | (take (minus arr.size 1) arr, at arr.arr last)
1016 | mergeRebalance' : Shift
1020 | -> (Tree a -> Array (Tree a))
1021 | -> (Array (Tree a) -> Tree a)
1023 | mergeRebalance' sh left center right extract construct =
1025 | let nodecounter # t := ref1 Z t
1026 | subtreecounter # t := ref1 Z t
1027 | newnode # t := ref1 Lin t
1028 | newsubtree # t := ref1 Lin t
1029 | newroot # t := ref1 Lin t
1030 | () # t := mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct (toList left ++ toList center ++ toList right) t
1031 | newnode' # t := read1 newnode t
1032 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1035 | newsubtree' # t := read1 newsubtree t
1036 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (fromList (cast {to=List (Tree a)} newsubtree')))
1038 | newroot' # t := read1 newroot t
1039 | in fromList (cast {to=List (Tree a)} newroot') # t
1041 | mergeRebalanceSubtreeNodeCounter : Ref s Nat
1043 | -> Ref s (SnocList (Array (Tree a)))
1044 | -> Ref s (SnocList (Tree a))
1045 | -> (Array (Tree a) -> Tree a)
1047 | mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct t =
1048 | let newnode' # t := read1 newnode t
1049 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1052 | () # t := write1 newnode Lin t
1053 | () # t := write1 nodecounter Z t
1054 | in casmod1 subtreecounter (\y => y + 1) t
1055 | mergeRebalanceRootSubtreeCounter : Shift
1057 | -> Ref s (SnocList (Tree a))
1058 | -> Ref s (SnocList (Tree a))
1060 | mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot t =
1061 | let newsubtree' # t := read1 newsubtree t
1062 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (fromList (cast {to=List (Tree a)} newsubtree')))
1064 | () # t := write1 newsubtree Lin t
1065 | in write1 subtreecounter Z t
1066 | mergeRebalanceSubtree''' : Shift
1069 | -> Ref s (SnocList (Array (Tree a)))
1070 | -> Ref s (SnocList (Tree a))
1071 | -> Ref s (SnocList (Tree a))
1072 | -> (Array (Tree a) -> Tree a)
1075 | mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct extractedsubtree t =
1076 | let nodecounter' # t := read1 nodecounter t
1077 | () # t := when1 (nodecounter' == blocksize) (mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct) t
1078 | subtreecounter' # t := read1 subtreecounter t
1079 | () # t := when1 (subtreecounter' == blocksize) (mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot) t
1080 | () # t := casmod1 newnode (\y => y :< (fill 1 extractedsubtree)
1082 | in casmod1 nodecounter (\y => y + 1) t
1083 | mergeRebalanceSubtree'' : Shift
1086 | -> Ref s (SnocList (Array (Tree a)))
1087 | -> Ref s (SnocList (Tree a))
1088 | -> Ref s (SnocList (Tree a))
1089 | -> (Tree a -> Array (Tree a))
1090 | -> (Array (Tree a) -> Tree a)
1093 | mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct subtree t =
1094 | traverse1_ (mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct) (extract subtree) t
1095 | mergeRebalanceSubtree' : Shift
1098 | -> Ref s (SnocList (Array (Tree a)))
1099 | -> Ref s (SnocList (Tree a))
1100 | -> Ref s (SnocList (Tree a))
1101 | -> (Tree a -> Array (Tree a))
1102 | -> (Array (Tree a) -> Tree a)
1105 | mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct leftcenterright t =
1106 | traverse1_ (mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct) leftcenterright t
1107 | mergeRebalance'' : Shift
1114 | mergeRebalance'' sh left center right extract construct =
1116 | let nodecounter # t := ref1 Z t
1117 | subtreecounter # t := ref1 Z t
1118 | newnode # t := ref1 Lin t
1119 | newsubtree # t := ref1 Lin t
1120 | newroot # t := ref1 Lin t
1121 | () # t := mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct (toList left ++ toList center ++ toList right) t
1122 | newnode' # t := read1 newnode t
1123 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1126 | newsubtree' # t := read1 newsubtree t
1127 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (fromList (cast {to=List (Tree a)} newsubtree')))
1129 | newroot' # t := read1 newroot t
1130 | in fromList (cast {to=List (Tree a)} newroot') # t
1132 | mergeRebalanceSubtreeNodeCounter : Ref s Nat
1134 | -> Ref s (SnocList (Array a))
1135 | -> Ref s (SnocList (Tree a))
1138 | mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct t =
1139 | let newnode' # t := read1 newnode t
1140 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1143 | () # t := write1 newnode Lin t
1144 | () # t := write1 nodecounter Z t
1145 | in casmod1 subtreecounter (\y => y + 1) t
1146 | mergeRebalanceRootSubtreeCounter : Shift
1148 | -> Ref s (SnocList (Tree a))
1149 | -> Ref s (SnocList (Tree a))
1151 | mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot t =
1152 | let newsubtree' # t := read1 newsubtree t
1153 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (fromList (cast {to=List (Tree a)} newsubtree')))
1155 | () # t := write1 newsubtree Lin t
1156 | in write1 subtreecounter Z t
1157 | mergeRebalanceSubtree''' : Shift
1160 | -> Ref s (SnocList (Array a))
1161 | -> Ref s (SnocList (Tree a))
1162 | -> Ref s (SnocList (Tree a))
1166 | mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct extractedsubtree t =
1167 | let nodecounter' # t := read1 nodecounter t
1168 | () # t := when1 (nodecounter' == blocksize) (mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct) t
1169 | subtreecounter' # t := read1 subtreecounter t
1170 | () # t := when1 (subtreecounter' == blocksize) (mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot) t
1171 | () # t := casmod1 newnode (\y => y :< (fill 1 extractedsubtree)
1173 | in casmod1 nodecounter (\y => y + 1) t
1174 | mergeRebalanceSubtree'' : Shift
1177 | -> Ref s (SnocList (Array a))
1178 | -> Ref s (SnocList (Tree a))
1179 | -> Ref s (SnocList (Tree a))
1184 | mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct subtree t =
1185 | traverse1_ (mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct) (extract subtree) t
1186 | mergeRebalanceSubtree' : Shift
1189 | -> Ref s (SnocList (Array a))
1190 | -> Ref s (SnocList (Tree a))
1191 | -> Ref s (SnocList (Tree a))
1196 | mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct leftcenterright t =
1197 | traverse1_ (mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct) leftcenterright t
1203 | mergeRebalance sh left center right =
1204 | case compare sh blockshift of
1206 | assert_total $
mergeRebalance' sh left center right treeToArray (computeSizes (down sh))
1208 | assert_total $
mergeRebalance'' sh left center right (\(Leaf arr) => arr) Leaf
1210 | assert_total $
mergeRebalance' sh left center right treeToArray (computeSizes (down sh))
1216 | mergeTrees tree1@(Leaf arr1) _ tree2@(Leaf arr2) _ =
1217 | case compare arr1.size blocksize of
1219 | let arr' = A (plus arr1.size arr2.size) (append arr1.arr arr2.arr)
1220 | in case compare arr'.size blocksize of
1226 | let (left, right) = (take blocksize arr',drop blocksize arr')
1229 | in A 2 $
fromPairs 2 lefttree [(1,righttree)]
1231 | A 2 $
fromPairs 2 tree1 [(1,tree2)]
1233 | let arr' = A (plus arr1.size arr2.size) (append arr1.arr arr2.arr)
1234 | in case compare arr'.size blocksize of
1240 | let (left, right) = (take blocksize arr',drop blocksize arr')
1243 | in A 2 $
fromPairs 2 lefttree [(1,righttree)]
1244 | mergeTrees tree1 sh1 tree2 sh2 =
1245 | case compare sh1 sh2 of
1247 | let right = treeToArray tree2
1248 | (righthead, righttail) = viewlArr right
1249 | merged = assert_total $
mergeTrees tree1 sh1 righthead (down sh2)
1250 | in mergeRebalance sh2 empty merged righttail
1252 | let left = treeToArray tree1
1253 | (leftinit, leftlast) = viewrArr left
1254 | merged = assert_total $
mergeTrees leftlast (down sh1) tree2 sh2
1255 | in mergeRebalance sh1 leftinit merged empty
1257 | let left = treeToArray tree1
1258 | right = treeToArray tree2
1259 | (leftinit, leftlast) = viewrArr left
1260 | (righthead, righttail) = viewlArr right
1261 | merged = assert_total $
mergeTrees leftlast (down sh1) righthead (down sh2)
1262 | in mergeRebalance sh1 leftinit merged righttail
1274 | let (left, right) = splitAt i v
1275 | in (left |> x) >< right
1285 | let (left, right) = splitAt (plus i 1) v
1286 | in take i left >< right
1295 | showRRBVectorRep : Show a
1300 | showRRBVectorRep Empty =
1302 | showRRBVectorRep (Root size sh t) =
1318 | Eq a => Eq (RRBVector a) where
1319 | xs == ys = length xs == length ys && Data.RRBVector.toList xs == Data.RRBVector.toList ys
1322 | Ord a => Ord (RRBVector a) where
1323 | compare xs ys = compare (Data.RRBVector.toList xs) (Data.RRBVector.toList ys)
1326 | Functor RRBVector where
1330 | Foldable RRBVector where
1331 | foldl f z = Data.RRBVector.foldl f z
1332 | foldr f z = Data.RRBVector.foldr f z
1336 | Applicative RRBVector where
1338 | fs <*> xs = Data.RRBVector.foldl (\acc, f => acc >< map f xs) empty fs
1341 | Semigroup (RRBVector a) where
1345 | Semigroup (RRBVector a) => Monoid (RRBVector a) where
1350 | xs >>= f = Data.RRBVector.foldl (\acc, x => acc >< f x) empty xs