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.(|>)
50 | castIArray : {m, n : Nat}
54 | castIArray Refl arr =
62 | 0 lteReflNat : (n : Nat)
67 | LTESucc (lteReflNat n)
72 | 0 plusOneRight : (n : Nat)
76 | plusOneRight (S n) =
77 | cong S (plusOneRight n)
86 | childrenSnoc : {n : Nat}
87 | -> IArray n (Tree a)
90 | childrenSnoc {n} xs x =
91 | let arr : IArray (plus n 1) (Tree a)
92 | arr = append xs (fill 1 x)
93 | arr' : IArray (S n) (Tree a)
94 | arr' = castIArray (plusOneRight n) arr
95 | in MkChildren {n = S n} {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} arr'
106 | childrenCons : {n : Nat}
108 | -> IArray n (Tree a)
110 | childrenCons {n} x xs =
111 | MkChildren {n = S n} {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} (append (fill 1 x) xs)
120 | childrenFromArray : Array (Tree a)
122 | childrenFromArray (A Z _) =
123 | assert_total (idris_crash "Data.RRBVector.childrenFromArray: empty child array")
124 | childrenFromArray (A (S n) arr) =
125 | MkChildren {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} arr
130 | lastFin : {n : Nat}
134 | lastFin {n = S k} =
144 | empty : RRBVector a
152 | singleton x = Root 1 0 (Leaf $
A 1 $
fill 1 x)
169 | case nodes Leaf xs of
171 | Root (treeSize 0 tree) 0 tree
173 | assert_smaller xs (iterateNodes blockshift xs')
181 | nodes : (Array a -> Tree a)
185 | let (tree, rest) = unsafeAlloc blocksize (go {n = blocksize} blocksize f trees)
190 | tree :: nodes f (assert_smaller trees rest')
202 | -> (remaining : Nat)
203 | -> {auto pos : Ix remaining n}
204 | -> (Array a -> Tree a)
206 | -> WithMArray n a (Tree a, List a)
207 | go {n} remaining {pos} f [] r = T1.do
208 | res <- unsafeFreeze r
210 | written = ixToNat pos
218 | go {n} Z {pos} f xs r = T1.do
219 | res <- unsafeFreeze r
224 | go {n} (S k) {pos} f (x :: xs) r =
229 | assert_total (go {n} k {pos = IS pos} f xs r)
235 | nodes' : (Array (Tree a) -> Tree a)
240 | unsafeAlloc blocksize (go {n = blocksize} blocksize f trees)
245 | tree :: nodes' f (assert_smaller trees rest')
250 | -> (remaining : Nat)
251 | -> {auto pos : Ix remaining n}
252 | -> (Array (Tree a) -> Tree a)
254 | -> WithMArray n (Tree a) (Tree a, List (Tree a))
255 | go {n} remaining {pos} f [] r = T1.do
256 | res <- unsafeFreeze r
258 | written = ixToNat pos
266 | go {n} Z {pos} f xs r = T1.do
267 | res <- unsafeFreeze r
272 | go {n} (S k) {pos} f (x :: xs) r =
277 | assert_total (go {n} k {pos = IS pos} f xs r)
281 | iterateNodes : Shift
284 | iterateNodes sh trees =
285 | case nodes' (\arr => Balanced (childrenFromArray arr)) trees of
287 | Root (treeSize sh tree) sh tree
289 | iterateNodes (up sh) (assert_smaller trees trees')
298 | case compare n 0 of
304 | case compare n blocksize of
306 | Root n 0 (Leaf $
A n $
fill n x)
308 | Root n 0 (Leaf $
A n $
fill n x)
310 | let size' = integerToNat $
(natToInteger $
minus n 1) .&. (natToInteger $
plus blockmask 1)
311 | in iterateNodes blockshift (Leaf $
A blocksize $
fill blocksize x) (Leaf $
A size' $
fill size' x)
313 | iterateNodes : Shift
317 | iterateNodes sh full rest =
318 | let subtreesm1 = (natToInteger $
minus n 1) `shiftR` sh
319 | restsize = integerToNat $
subtreesm1 .&. natToInteger blockmask
320 | restchildren : Children a
321 | restchildren = childrenSnoc (fill restsize full) rest
323 | rest' = Balanced restchildren
324 | in case compare subtreesm1 (natToInteger blocksize) of
328 | let fullchildren : Children a
329 | fullchildren = MkChildren {n = blocksize} {nonEmpty = believe_me ()} {withinBlock = lteReflNat blocksize} (fill blocksize full)
330 | full' = Balanced fullchildren
331 | in iterateNodes (up sh) (assert_smaller full full') (assert_smaller rest rest')
333 | let fullchildren : Children a
334 | fullchildren = MkChildren {n = blocksize} {nonEmpty = believe_me ()} {withinBlock = lteReflNat blocksize} (fill blocksize full)
335 | full' = Balanced fullchildren
336 | in iterateNodes (up sh) (assert_smaller full full') (assert_smaller rest rest')
345 | toList : RRBVector a
349 | toList (Root _ _ tree) =
352 | treeToList : Tree a
354 | treeToList (Balanced (MkChildren {n} trees)) =
355 | assert_total (concat (map treeToList (toList (A n trees))))
356 | treeToList (Unbalanced (MkRelaxedChildren {n} trees _)) =
357 | assert_total (concat (map treeToList (toList (A n trees))))
358 | treeToList (Leaf arr) =
366 | foldl : (b -> a -> b)
375 | foldlTree acc' (Balanced (MkChildren {n} trees)) =
376 | assert_total (foldl foldlTree acc' (A n trees))
377 | foldlTree acc' (Unbalanced (MkRelaxedChildren {n} trees _)) =
378 | assert_total (foldl foldlTree acc' (A n trees))
379 | foldlTree acc' (Leaf arr) =
380 | assert_total (foldl f acc' arr)
385 | go (Root _ _ tree) =
386 | assert_total (foldlTree acc tree)
389 | foldr : (a -> b -> b)
398 | foldrTree (Balanced (MkChildren {n} trees)) acc' =
399 | assert_total (foldr foldrTree acc' (A n trees))
400 | foldrTree (Unbalanced (MkRelaxedChildren {n} trees _)) acc' =
401 | assert_total (foldr foldrTree acc' (A n trees))
402 | foldrTree (Leaf arr) acc' =
403 | assert_total (foldr f acc' arr)
408 | go (Root _ _ tree) =
409 | assert_total (foldrTree tree acc)
426 | length : RRBVector a
429 | length (Root s _ _) = s
443 | lookup i (Root size sh tree) =
448 | Just (lookupTree i sh tree)
454 | lookupTree i sh (Balanced (MkChildren {n} children)) =
456 | childidx = radixIndex i sh
457 | 0 childLT : LT childidx n
458 | childLT = believe_me ()
460 | child = natToFinLT childidx @{childLT}
461 | in assert_total (lookupTree i (down sh) (at children child))
462 | lookupTree i sh (Unbalanced (MkRelaxedChildren {n} {nonEmpty} children sizes)) =
463 | let MkRelaxedIndex child offset = relaxedRadixIndex {n} {nonEmpty} sizes i sh
464 | in assert_total (lookupTree offset (down sh) (at children child))
465 | lookupTree i _ (Leaf (A n elems)) =
467 | leafidx = integerToNat ((natToInteger i) .&. natToInteger blockmask)
468 | 0 leafLT : LT leafidx n
469 | leafLT = believe_me ()
470 | in atNat elems leafidx @{leafLT}
491 | update i x v@(Root size sh tree) =
496 | Root size sh (updateTree i sh tree)
502 | updateTree i sh (Balanced (MkChildren {n} {nonEmpty} {withinBlock} children)) =
504 | childidx = radixIndex i sh
505 | 0 childLT : LT childidx n
506 | childLT = believe_me ()
508 | child = natToFinLT childidx @{childLT}
509 | children' = updateAt child (updateTree i (down sh)) children
510 | in assert_total (Balanced (MkChildren {nonEmpty = nonEmpty} {withinBlock = withinBlock} children'))
511 | updateTree i sh (Unbalanced (MkRelaxedChildren {n} {nonEmpty} {withinBlock} children sizes)) =
512 | let MkRelaxedIndex child offset = relaxedRadixIndex {n} {nonEmpty} sizes i sh
513 | children' = updateAt child (updateTree offset (down sh)) children
514 | in assert_total (Unbalanced (MkRelaxedChildren {nonEmpty = nonEmpty} {withinBlock = withinBlock} children' sizes))
515 | updateTree i _ (Leaf (A n elems)) =
517 | leafidx = integerToNat ((natToInteger i) .&. natToInteger blockmask)
518 | 0 leafLT : LT leafIdx n
519 | leafLT = believe_me ()
521 | idx = natToFinLT leafidx @{leafLT}
522 | in Leaf (A n (setAt idx x elems))
535 | adjust i f v@(Root size sh tree) =
540 | Root size sh (adjustTree i sh tree)
546 | adjustTree i sh (Balanced (MkChildren {n} {nonEmpty} {withinBlock} children)) =
548 | childidx = radixIndex i sh
549 | 0 childLT : LT childidx n
550 | childLT = believe_me ()
552 | child = natToFinLT childidx @{childLT}
553 | children' = updateAt child (adjustTree i (down sh)) children
554 | in assert_total (Balanced (MkChildren {nonEmpty = nonEmpty} {withinBlock = withinBlock} children'))
555 | adjustTree i sh (Unbalanced (MkRelaxedChildren {n} {nonEmpty} {withinBlock} children sizes)) =
556 | let MkRelaxedIndex child offset = relaxedRadixIndex {n} {nonEmpty} sizes i sh
557 | children' = updateAt child (adjustTree offset (down sh)) children
558 | in assert_total (Unbalanced (MkRelaxedChildren {nonEmpty = nonEmpty} {withinBlock = withinBlock} children' sizes))
559 | adjustTree i _ (Leaf (A n elems)) =
561 | leafidx = integerToNat ((natToInteger i) .&. natToInteger blockmask)
562 | 0 leafLT : LT leafidx n
563 | leafLT = believe_me ()
565 | idx = natToFinLT leafidx @{leafLT}
566 | in Leaf (A n (updateAt idx f elems))
569 | normalize : RRBVector a
571 | normalize (Root size sh (Balanced (MkChildren {n = 1} children))) =
572 | assert_total (normalize (Root size (down sh) (at children FZ)))
573 | normalize (Root size sh (Unbalanced (MkRelaxedChildren {n = 1} children _))) =
574 | assert_total (normalize (Root size (down sh) (at children FZ)))
591 | takeTree i sh (Balanced (MkChildren {n} children)) =
593 | childidx = radixIndex i sh
594 | 0 childLT : LT childidx n
595 | childLT = believe_me ()
596 | prefix' : IArray (S childidx) (Tree a)
597 | prefix' = force (take (S childidx) children @{childLT})
598 | prefix'' : IArray (S childidx) (Tree a)
599 | prefix'' = updateAt (lastFin {n = childidx}) (takeTree i (down sh)) prefix'
600 | in assert_total (Balanced (MkChildren {n = S childidx} {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} prefix''))
601 | takeTree i sh (Unbalanced (MkRelaxedChildren {n} {nonEmpty} children sizes)) =
602 | let MkRelaxedIndex child subidx = relaxedRadixIndex {n} {nonEmpty} sizes i sh
604 | childidx = finToNat child
605 | 0 prefixLTE : LTE (S childidx) n
606 | prefixLTE = believe_me ()
607 | prefix' : IArray (S childidx) (Tree a)
608 | prefix' = force (take (S childidx) children @{prefixLTE})
609 | prefix'' : IArray (S childidx) (Tree a)
610 | prefix'' = updateAt (lastFin {n = childidx}) (takeTree subidx (down sh)) prefix'
611 | bounded : Children a
612 | bounded = MkChildren {n = S childidx} {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} prefix''
613 | in assert_total (computeSizes sh bounded)
614 | takeTree i _ (Leaf (A n elems)) =
616 | leafidx = integerToNat ((natToInteger i) .&. natToInteger blockmask)
619 | 0 countLTE : LTE count n
620 | countLTE = believe_me ()
621 | elems' : IArray count a
622 | elems' = force (take count elems @{countLTE})
623 | in Leaf (A count elems')
639 | dropTree i sh (Balanced (MkChildren {n} children)) =
641 | childidx = radixIndex i sh
643 | remaining = minus n childidx
644 | children' : IArray remaining (Tree a)
645 | children' = force (drop childidx children)
646 | 0 remainingpositive : LT 0 remaining
647 | remainingpositive = believe_me ()
648 | zero : Fin remaining
649 | zero = natToFinLT 0 @{remainingpositive}
650 | children'' : IArray remaining (Tree a)
651 | children'' = updateAt zero (dropTree i (down sh)) children'
652 | bounded : Children a
653 | bounded = MkChildren {n = remaining} {nonEmpty = remainingpositive} {withinBlock = believe_me ()} children''
654 | in assert_total (computeSizes sh bounded)
655 | dropTree i sh (Unbalanced (MkRelaxedChildren {n} {nonEmpty} children sizes)) =
656 | let MkRelaxedIndex child subidx = relaxedRadixIndex {n} {nonEmpty} sizes i sh
658 | childidx = finToNat child
660 | remaining = minus n childidx
661 | children' : IArray remaining (Tree a)
662 | children' = force (drop childidx children)
663 | 0 remainingpositive : LT 0 remaining
664 | remainingpositive = believe_me ()
665 | zero : Fin remaining
666 | zero = natToFinLT 0 @{remainingpositive}
667 | children'' : IArray remaining (Tree a)
668 | children'' = updateAt zero (dropTree subidx (down sh)) children'
669 | bounded : Children a
670 | bounded = MkChildren {n = remaining} {nonEmpty = remainingpositive} {withinBlock = believe_me ()} children''
671 | in assert_total (computeSizes sh bounded)
672 | dropTree i _ (Leaf (A n elems)) =
674 | offset = integerToNat ((natToInteger i) .&. natToInteger blockmask)
676 | remaining = minus n offset
677 | elems' : IArray remaining a
678 | elems' = force (drop offset elems)
679 | in Leaf (A remaining elems')
690 | take n v@(Root size sh tree) =
691 | case compare n 0 of
697 | case compare n size of
699 | normalize $
Root n sh (takeTree (minus n 1) sh tree)
714 | drop n v@(Root size sh tree) =
715 | case compare n 0 of
721 | case compare n size of
723 | normalize $
Root (minus size n) sh (dropTree n sh tree)
734 | -> (RRBVector a, RRBVector a)
735 | splitAt _ Empty = (Empty, Empty)
736 | splitAt n v@(Root size sh tree) =
737 | case compare n 0 of
743 | case compare n size of
745 | let left = normalize $
Root n sh (takeTree (minus n 1) sh tree)
746 | right = normalize $
Root (minus size n) sh (dropTree n sh tree)
760 | viewl : RRBVector a
761 | -> Maybe (a, RRBVector a)
764 | viewl v@(Root _ _ tree) =
765 | let tail = drop 1 v
766 | in Just ( headTree tree
772 | headTree (Balanced (MkChildren {n = S k} children)) =
773 | assert_total (headTree (at children FZ))
774 | headTree (Unbalanced (MkRelaxedChildren {n = S k} children _)) =
775 | assert_total (headTree (at children FZ))
776 | headTree (Leaf (A Z _)) =
777 | assert_total (idris_crash "Data.RRBVector.viewl: empty leaf")
778 | headTree (Leaf (A (S k) elems)) =
784 | viewr : RRBVector a
785 | -> Maybe (RRBVector a, a)
788 | viewr v@(Root size _ tree) =
789 | let init = take (minus size 1) v
796 | lastTree (Balanced (MkChildren {n = S k} children)) =
797 | assert_total (lastTree (at children lastFin))
798 | lastTree (Unbalanced (MkRelaxedChildren {n = S k} children _)) =
799 | assert_total (lastTree (at children lastFin))
800 | lastTree (Leaf (A Z _)) =
801 | assert_total (idris_crash "Data.RRBVector.viewr: empty leaf")
802 | lastTree (Leaf (A (S k) elems)) =
817 | map f (Root size sh tree) =
818 | Root size sh (mapTree tree)
822 | mapTree (Balanced (MkChildren {n} {nonEmpty} {withinBlock} children)) =
823 | assert_total (Balanced (MkChildren {n} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (map mapTree children)))
824 | mapTree (Unbalanced (MkRelaxedChildren {n} {nonEmpty} {withinBlock} children sizes)) =
825 | assert_total (Unbalanced (MkRelaxedChildren {n} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (map mapTree children) sizes))
826 | mapTree (Leaf arr) =
832 | reverse : RRBVector a
835 | case compare (length v) 1 of
841 | case fromList $
toList v of
843 | assert_total $
idris_crash "Data.RRBVector.reverse: can't convert to List1"
845 | fromList $
forget $
reverse v'
853 | -> RRBVector (a, b)
855 | case fromList $
toList v1 of
857 | assert_total $
idris_crash "Data.RRBVector.zip: can't convert to List1"
859 | case fromList $
toList v2 of
861 | assert_total $
idris_crash "Data.RRBVector.zip: can't convert to List1"
863 | fromList $
forget $
zip v1' v2'
878 | assert_total (Balanced (MkChildren {n = 1} {nonEmpty = LTESucc LTEZero} {withinBlock = believe_me ()} (fill 1 (newBranch x (down sh)))))
888 | x <| Root size sh tree =
889 | case compare insertshift sh of
891 | Root (S size) sh (consTree sh tree)
893 | Root (S size) sh (consTree sh tree)
895 | let children : IArray 2 (Tree a)
902 | rootChildren : Children a
904 | MkChildren {n = 2} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children
905 | in Root (S size) insertshift (computeSizes insertshift rootChildren)
914 | computeShift sz sh min (Balanced _) =
916 | let comp = mult (log2 (minus sz 1) `div` blockshift) blockshift
917 | in case compare comp 0 of
924 | hi = (natToInteger $
minus sz 1) `shiftR` hishift
925 | newshift = case compare hi (natToInteger blockmask) of
929 | plus hishift blockshift
931 | plus hishift blockshift
932 | in case compare newshift sh of
939 | computeShift _ sh min (Unbalanced (MkRelaxedChildren {n = S k} children sizes)) =
943 | newtree = at children FZ
945 | newmin = case compare (S k) blocksize of
952 | in assert_total (computeShift sz' (down sh) newmin newtree)
953 | computeShift _ _ min (Leaf arr) =
954 | case compare arr.size blocksize of
961 | insertshift : Shift
962 | insertshift = computeShift size sh (up sh) tree
966 | consTree sh (Balanced (MkChildren {n = S k} {nonEmpty} {withinBlock} children)) =
967 | case compare sh insertshift of
969 | assert_total (computeSizes sh (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt FZ (consTree $
down sh) children)))
971 | let children' = append (fill 1 (newBranch x $
down sh)) children
972 | in computeSizes sh (MkChildren {n = S (S k)} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children')
974 | assert_total (computeSizes sh (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt FZ (consTree $
down sh) children)))
975 | consTree sh (Unbalanced (MkRelaxedChildren {n = S k} {nonEmpty} {withinBlock} children _)) =
976 | case compare sh insertshift of
978 | assert_total (computeSizes sh (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt FZ (consTree $
down sh) children)))
980 | let children' = append (fill 1 (newBranch x $
down sh)) children
981 | in computeSizes sh (MkChildren {n = S (S k)} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children')
983 | assert_total (computeSizes sh (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt FZ (consTree $
down sh) children)))
984 | consTree _ (Leaf arr) =
985 | Leaf (A (S arr.size) (append (fill 1 x) arr.arr))
995 | Root size sh tree |> x =
996 | case compare insertshift sh of
998 | Root (S size) sh (snocTree sh tree)
1000 | Root (S size) sh (snocTree sh tree)
1002 | let children : IArray 2 (Tree a)
1003 | children = array ( fromList
1008 | rootChildren : Children a
1009 | rootChildren = MkChildren {n = 2} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children
1010 | in Root (S size) insertshift (computeSizes insertshift rootChildren)
1019 | computeShift sz sh min (Balanced _) =
1020 | let newshift = mult (countTrailingZeros sz `div` blockshift) blockshift
1021 | in case compare newshift sh of
1028 | computeShift _ sh min (Unbalanced (MkRelaxedChildren {n = 1} children sizes)) =
1032 | newtree = lastAt children
1034 | newmin = case compare 1 blocksize of
1041 | in assert_total (computeShift sz' (down sh) newmin newtree)
1042 | computeShift _ sh min (Unbalanced (MkRelaxedChildren {n = S (S k)} children sizes)) =
1044 | totalsize = lastAt sizes
1045 | previousidx : Fin (S (S k))
1046 | previousidx = weaken (lastFin {n = k})
1048 | previous = at sizes previousidx
1050 | sz' = minus totalsize previous
1052 | newtree = lastAt children
1054 | newmin = case compare (S (S k)) blocksize of
1061 | in assert_total (computeShift sz' (down sh) newmin newtree)
1062 | computeShift _ _ min (Leaf arr) =
1063 | case compare arr.size blocksize of
1071 | insertshift = computeShift size sh (up sh) tree
1075 | snocTree sh (Balanced (MkChildren {n = S k} {nonEmpty} {withinBlock} children)) =
1076 | case compare sh insertshift of
1078 | assert_total (Balanced (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt lastFin (snocTree $
down sh) children)))
1080 | let children' = append children (fill 1 (newBranch x (down sh)))
1081 | in Balanced (MkChildren {n = plus (S k) 1} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children')
1083 | assert_total (Balanced (MkChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt lastFin (snocTree $
down sh) children)))
1084 | snocTree sh (Unbalanced (MkRelaxedChildren {n = S k} {nonEmpty} {withinBlock} children sizes)) =
1085 | case compare sh insertshift of
1088 | lastsize = plus (lastAt sizes) 1
1089 | in assert_total (Unbalanced (MkRelaxedChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt lastFin (snocTree $
down sh) children) (setAt lastFin lastsize sizes)))
1092 | lastsize = plus (lastAt sizes) 1
1093 | children' = append children (fill 1 (newBranch x (down sh)))
1094 | sizes' = append sizes (fill 1 lastsize)
1095 | in Unbalanced (MkRelaxedChildren {n = plus (S k) 1} {nonEmpty = believe_me ()} {withinBlock = believe_me ()} children' sizes')
1098 | lastsize = plus (lastAt sizes) 1
1099 | in assert_total (Unbalanced (MkRelaxedChildren {n = S k} {nonEmpty = nonEmpty} {withinBlock = withinBlock} (updateAt lastFin (snocTree $
down sh) children) (setAt lastFin lastsize sizes)))
1100 | snocTree _ (Leaf arr) =
1101 | Leaf (A (plus arr.size 1) (append arr.arr (fill 1 x)))
1111 | Root size1 sh1 tree1 >< Root size2 sh2 tree2 =
1112 | let upmaxshift = case compare sh1 sh2 of
1119 | newarr = mergeTrees tree1 sh1 tree2 sh2
1120 | rootchildren : Children a
1121 | rootchildren = childrenFromArray newarr
1122 | in normalize (Root (plus size1 size2) upmaxshift (computeSizes upmaxshift rootchildren))
1129 | viewlArr : Array (Tree a)
1130 | -> (Tree a, Array (Tree a))
1132 | assert_total (idris_crash "Data.RRBVector.(><).viewlArr: empty internal array")
1133 | viewlArr (A (S n) arr) =
1134 | let tail : IArray (minus n 0) (Tree a)
1135 | tail = force (drop 1 arr)
1144 | viewrArr : Array (Tree b)
1145 | -> (Array (Tree b), Tree b)
1147 | assert_total (idris_crash "Data.RRBVector.(><).viewrArr: empty internal array")
1148 | viewrArr (A (S n) arr) =
1149 | let 0 initLTE : LTE n (S n)
1150 | initLTE = believe_me ()
1151 | init : IArray n (Tree b)
1152 | init = force (take n arr @{initLTE})
1156 | mergeRebalance' : Shift
1160 | -> (Tree a -> Array (Tree a))
1161 | -> (Array (Tree a) -> Tree a)
1163 | mergeRebalance' sh left center right extract construct =
1165 | let nodecounter # t := ref1 Z t
1166 | subtreecounter # t := ref1 Z t
1167 | newnode # t := ref1 Lin t
1168 | newsubtree # t := ref1 Lin t
1169 | newroot # t := ref1 Lin t
1170 | () # t := mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct (toList left ++ toList center ++ toList right) t
1171 | newnode' # t := read1 newnode t
1172 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1175 | newsubtree' # t := read1 newsubtree t
1176 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (childrenFromArray (fromList (cast {to=List (Tree a)} newsubtree'))))
1178 | newroot' # t := read1 newroot t
1179 | in fromList (cast {to=List (Tree a)} newroot') # t
1181 | mergeRebalanceSubtreeNodeCounter : Ref s Nat
1183 | -> Ref s (SnocList (Array (Tree a)))
1184 | -> Ref s (SnocList (Tree a))
1185 | -> (Array (Tree a) -> Tree a)
1187 | mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct t =
1188 | let newnode' # t := read1 newnode t
1189 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1192 | () # t := write1 newnode Lin t
1193 | () # t := write1 nodecounter Z t
1194 | in casmod1 subtreecounter (\y => y + 1) t
1195 | mergeRebalanceRootSubtreeCounter : Shift
1197 | -> Ref s (SnocList (Tree a))
1198 | -> Ref s (SnocList (Tree a))
1200 | mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot t =
1201 | let newsubtree' # t := read1 newsubtree t
1202 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (childrenFromArray (fromList (cast {to=List (Tree a)} newsubtree'))))
1204 | () # t := write1 newsubtree Lin t
1205 | in write1 subtreecounter Z t
1206 | mergeRebalanceSubtree''' : Shift
1209 | -> Ref s (SnocList (Array (Tree a)))
1210 | -> Ref s (SnocList (Tree a))
1211 | -> Ref s (SnocList (Tree a))
1212 | -> (Array (Tree a) -> Tree a)
1215 | mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct extractedsubtree t =
1216 | let nodecounter' # t := read1 nodecounter t
1217 | () # t := when1 (nodecounter' == blocksize) (mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct) t
1218 | subtreecounter' # t := read1 subtreecounter t
1219 | () # t := when1 (subtreecounter' == blocksize) (mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot) t
1220 | () # t := casmod1 newnode (\y => y :< (fill 1 extractedsubtree)
1222 | in casmod1 nodecounter (\y => y + 1) t
1223 | mergeRebalanceSubtree'' : Shift
1226 | -> Ref s (SnocList (Array (Tree a)))
1227 | -> Ref s (SnocList (Tree a))
1228 | -> Ref s (SnocList (Tree a))
1229 | -> (Tree a -> Array (Tree a))
1230 | -> (Array (Tree a) -> Tree a)
1233 | mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct subtree t =
1234 | traverse1_ (mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct) (extract subtree) t
1235 | mergeRebalanceSubtree' : Shift
1238 | -> Ref s (SnocList (Array (Tree a)))
1239 | -> Ref s (SnocList (Tree a))
1240 | -> Ref s (SnocList (Tree a))
1241 | -> (Tree a -> Array (Tree a))
1242 | -> (Array (Tree a) -> Tree a)
1245 | mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct leftcenterright t =
1246 | traverse1_ (mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct) leftcenterright t
1247 | mergeRebalance'' : Shift
1254 | mergeRebalance'' sh left center right extract construct =
1256 | let nodecounter # t := ref1 Z t
1257 | subtreecounter # t := ref1 Z t
1258 | newnode # t := ref1 Lin t
1259 | newsubtree # t := ref1 Lin t
1260 | newroot # t := ref1 Lin t
1261 | () # t := mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct (toList left ++ toList center ++ toList right) t
1262 | newnode' # t := read1 newnode t
1263 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1266 | newsubtree' # t := read1 newsubtree t
1267 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (childrenFromArray (fromList (cast {to=List (Tree a)} newsubtree'))))
1269 | newroot' # t := read1 newroot t
1270 | in fromList (cast {to=List (Tree a)} newroot') # t
1272 | mergeRebalanceSubtreeNodeCounter : Ref s Nat
1274 | -> Ref s (SnocList (Array a))
1275 | -> Ref s (SnocList (Tree a))
1278 | mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct t =
1279 | let newnode' # t := read1 newnode t
1280 | () # t := casmod1 newsubtree (\y => y :< (construct $
A (SnocSize newnode')
1283 | () # t := write1 newnode Lin t
1284 | () # t := write1 nodecounter Z t
1285 | in casmod1 subtreecounter (\y => y + 1) t
1286 | mergeRebalanceRootSubtreeCounter : Shift
1288 | -> Ref s (SnocList (Tree a))
1289 | -> Ref s (SnocList (Tree a))
1291 | mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot t =
1292 | let newsubtree' # t := read1 newsubtree t
1293 | () # t := casmod1 newroot (\y => y :< (computeSizes sh (childrenFromArray (fromList (cast {to=List (Tree a)} newsubtree'))))
1295 | () # t := write1 newsubtree Lin t
1296 | in write1 subtreecounter Z t
1297 | mergeRebalanceSubtree''' : Shift
1300 | -> Ref s (SnocList (Array a))
1301 | -> Ref s (SnocList (Tree a))
1302 | -> Ref s (SnocList (Tree a))
1306 | mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct extractedsubtree t =
1307 | let nodecounter' # t := read1 nodecounter t
1308 | () # t := when1 (nodecounter' == blocksize) (mergeRebalanceSubtreeNodeCounter nodecounter subtreecounter newnode newsubtree construct) t
1309 | subtreecounter' # t := read1 subtreecounter t
1310 | () # t := when1 (subtreecounter' == blocksize) (mergeRebalanceRootSubtreeCounter sh subtreecounter newsubtree newroot) t
1311 | () # t := casmod1 newnode (\y => y :< (fill 1 extractedsubtree)
1313 | in casmod1 nodecounter (\y => y + 1) t
1314 | mergeRebalanceSubtree'' : Shift
1317 | -> Ref s (SnocList (Array a))
1318 | -> Ref s (SnocList (Tree a))
1319 | -> Ref s (SnocList (Tree a))
1324 | mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct subtree t =
1325 | traverse1_ (mergeRebalanceSubtree''' sh nodecounter subtreecounter newnode newsubtree newroot construct) (extract subtree) t
1326 | mergeRebalanceSubtree' : Shift
1329 | -> Ref s (SnocList (Array a))
1330 | -> Ref s (SnocList (Tree a))
1331 | -> Ref s (SnocList (Tree a))
1336 | mergeRebalanceSubtree' sh nodecounter subtreecounter newnode newsubtree newroot extract construct leftcenterright t =
1337 | traverse1_ (mergeRebalanceSubtree'' sh nodecounter subtreecounter newnode newsubtree newroot extract construct) leftcenterright t
1343 | mergeRebalance sh left center right =
1344 | case compare sh blockshift of
1346 | assert_total (mergeRebalance' sh left center right treeToArray (\arr => computeSizes (down sh) (childrenFromArray arr)))
1348 | assert_total (mergeRebalance'' sh left center right (\(Leaf arr) => arr) Leaf)
1350 | assert_total (mergeRebalance' sh left center right treeToArray (\arr => computeSizes (down sh) (childrenFromArray arr)))
1356 | mergeTrees tree1@(Leaf arr1) _ tree2@(Leaf arr2) _ =
1357 | case compare arr1.size blocksize of
1359 | let arr' = A (plus arr1.size arr2.size) (append arr1.arr arr2.arr)
1360 | in case compare arr'.size blocksize of
1366 | let (left, right) = (take blocksize arr',drop blocksize arr')
1369 | in A 2 $
fromPairs 2 lefttree [(1,righttree)]
1371 | A 2 $
fromPairs 2 tree1 [(1,tree2)]
1373 | let arr' = A (plus arr1.size arr2.size) (append arr1.arr arr2.arr)
1374 | in case compare arr'.size blocksize of
1380 | let (left, right) = (take blocksize arr',drop blocksize arr')
1383 | in A 2 $
fromPairs 2 lefttree [(1,righttree)]
1384 | mergeTrees tree1 sh1 tree2 sh2 =
1385 | case compare sh1 sh2 of
1387 | let right = treeToArray tree2
1388 | (righthead, righttail) = viewlArr right
1389 | merged = assert_total $
mergeTrees tree1 sh1 righthead (down sh2)
1390 | in mergeRebalance sh2 empty merged righttail
1392 | let left = treeToArray tree1
1393 | (leftinit, leftlast) = viewrArr left
1394 | merged = assert_total $
mergeTrees leftlast (down sh1) tree2 sh2
1395 | in mergeRebalance sh1 leftinit merged empty
1397 | let left = treeToArray tree1
1398 | right = treeToArray tree2
1399 | (leftinit, leftlast) = viewrArr left
1400 | (righthead, righttail) = viewlArr right
1401 | merged = assert_total $
mergeTrees leftlast (down sh1) righthead (down sh2)
1402 | in mergeRebalance sh1 leftinit merged righttail
1414 | let (left, right) = splitAt i v
1415 | in (left |> x) >< right
1425 | let (left, right) = splitAt (plus i 1) v
1426 | in take i left >< right
1435 | showRRBVectorRep : Show a
1440 | showRRBVectorRep Empty =
1442 | showRRBVectorRep (Root size sh t) =
1458 | Eq a => Eq (RRBVector a) where
1459 | xs == ys = length xs == length ys && Data.RRBVector.toList xs == Data.RRBVector.toList ys
1462 | Ord a => Ord (RRBVector a) where
1463 | compare xs ys = compare (Data.RRBVector.toList xs) (Data.RRBVector.toList ys)
1466 | Functor RRBVector where
1470 | Foldable RRBVector where
1471 | foldl f z = Data.RRBVector.foldl f z
1472 | foldr f z = Data.RRBVector.foldr f z
1476 | Applicative RRBVector where
1478 | fs <*> xs = Data.RRBVector.foldl (\acc, f => acc >< map f xs) empty fs
1481 | Semigroup (RRBVector a) where
1485 | Semigroup (RRBVector a) => Monoid (RRBVector a) where
1490 | xs >>= f = Data.RRBVector.foldl (\acc, x => acc >< f x) empty xs