0 | module Structures.PriorityQueue.SkewBinomialQueue
6 | import Decidable.Equality
8 | import Structures.PriorityQueue
17 | data SkewBinomialTree : (e : Type) -> (rank : Nat) -> Type where
18 | Singleton : (element : e)
19 | -> SkewBinomialTree e 0
20 | SimpleLink : (root : SkewBinomialTree e rank) -> (leftmost_child : SkewBinomialTree e rank)
21 | -> SkewBinomialTree e (S rank)
22 | SkewLinkA : (root : SkewBinomialTree e 0) -> (lefter, left : SkewBinomialTree e rank)
23 | -> SkewBinomialTree e (S rank)
24 | SkewLinkB : (root : SkewBinomialTree e rank) ->
25 | (lefter : SkewBinomialTree e 0) -> (left : SkewBinomialTree e rank)
26 | -> SkewBinomialTree e (S rank)
27 | %name SkewBinomialTree
bt, ct, dt
29 | SkewBinomialPair : Type -> Type
30 | SkewBinomialPair e = (rank : Nat ** SkewBinomialTree e rank)
33 | root : (tree : SkewBinomialTree e n) -> e
34 | root (Singleton element) = element
35 | root (SimpleLink bt _) = root bt
36 | root (SkewLinkA bt _ _) = root bt
37 | root (SkewLinkB bt _ _) = root bt
42 | simpleLink : Ord e => (x, y : SkewBinomialTree e n) -> SkewBinomialTree e (S n)
44 | let (x_val, y_val) = (root x, root y)
52 | skewLink : Ord e => (zero : SkewBinomialTree e 0) -> (x, y : SkewBinomialTree e rank)
53 | -> SkewBinomialTree e (S rank)
55 | let (z_root, x_root, y_root) = (root zero, root x, root y)
56 | min_s_root = min x_root y_root
57 | min_root = min z_root min_s_root
58 | in if min_root == z_root
59 | then SkewLinkA zero x y
60 | else if min_root == x_root
61 | then SkewLinkB x zero y
62 | else SkewLinkB y zero x
65 | rank : (tree : SkewBinomialTree e n) -> Nat
66 | rank (Singleton _) = 0
67 | rank (SimpleLink root _) = S (rank root)
68 | rank (SkewLinkA _ right _) = S (rank right)
69 | rank (SkewLinkB root _ _) = S (rank root)
71 | rankEq : (tree : SkewBinomialTree e n) -> n = rank tree
72 | rankEq (Singleton element) = Refl
73 | rankEq (SimpleLink root leftmost_child) =
74 | let rest = rankEq root
76 | rankEq (SkewLinkA root right left) =
77 | let rest = rankEq right
79 | rankEq (SkewLinkB root lefter left) =
80 | let rest = rankEq root
83 | toPair : (tree : SkewBinomialTree e n) -> SkewBinomialPair e
86 | rewrite sym $
rankEq tree in tree)
89 | extractRoot : (tree : SkewBinomialTree e n) -> (e, List (SkewBinomialPair e))
90 | extractRoot (Singleton element) = (element, [])
91 | extractRoot (SimpleLink root leftmost_child) =
92 | let (element, rest) = extractRoot root
93 | in (element, toPair leftmost_child :: rest)
94 | extractRoot (SkewLinkA root lefter left) =
95 | let (element, rest) = extractRoot root
96 | in (element, toPair lefter :: toPair left :: rest)
97 | extractRoot (SkewLinkB root lefter left) =
98 | let (element, rest) = extractRoot root
99 | in (element, toPair lefter :: toPair left :: rest)
102 | skewLen : {n : _} -> (tree : SkewBinomialTree e n) -> Nat
103 | skewLen tree = skewLen' tree 0 []
105 | skewLen' : {n : _} -> (tree : SkewBinomialTree e n) -> (acc : Nat) ->
106 | (stack : List (m : Nat ** SkewBinomialTree e m))
108 | skewLen' (Singleton element) acc [] =
110 | skewLen' (Singleton element) acc ((
m ** next)
:: xs) =
111 | skewLen' next (1 + acc) xs
112 | skewLen' (SimpleLink root leftmost_child) acc stack =
114 | skewLen' root acc (assert_smaller stack ((
_ ** leftmost_child)
:: stack))
115 | skewLen' (SkewLinkA root lefter left) acc stack =
117 | (assert_smaller stack $
118 | (
_ ** lefter)
:: (
_ ** left)
:: stack)
119 | skewLen' (SkewLinkB root lefter left) acc stack =
121 | (assert_smaller stack $
122 | (
_ ** lefter)
:: (
_ ** left)
:: stack)
130 | record SkewBinomialQueue (e : Type) where
134 | forest : Vect forest_size (SkewBinomialPair e)
135 | %name SkewBinomialQueue
sq, tq, uq
139 | Ord e => {n : Nat} ->
140 | (x : SkewBinomialPair e) ->
141 | (xs : Vect n (SkewBinomialPair e))
142 | -> (m : Nat ** Vect m (SkewBinomialPair e))
143 | insertTree x [] = (
1 ** [x])
144 | insertTree (
x_n ** x)
((
y_n ** y)
:: xs) =
145 | case decEq x_n y_n of
146 | Yes Refl => insertTree (
S x_n ** simpleLink x y)
xs
149 | then (
_ ** (
x_n ** x)
:: (
y_n ** y)
:: xs)
151 | let (
rest_len ** rest)
= insertTree (
x_n **x)
xs
152 | in (
_ ** (
y_n ** y)
:: rest)
156 | Ord e => {n, m : Nat} ->
157 | (xs : Vect n (SkewBinomialPair e)) ->
158 | (ys : Vect m (SkewBinomialPair e))
159 | -> (o : Nat ** Vect o (SkewBinomialPair e))
160 | meld' xs [] = (
length xs ** rewrite lengthCorrect xs in xs)
161 | meld' xs (y :: ys) =
162 | let (
_ ** res)
= insertTree y xs
166 | processTree : SkewBinomialPair e -> Either e (SkewBinomialPair e)
167 | processTree (
0 ** (Singleton element))
= Left element
168 | processTree pair@(
(S k) ** tree)
= Right pair
171 | PriorityQueue SkewBinomialQueue where
172 | empty = MkSBQ o 0 []
174 | singleton element = MkSBQ o 1 [(
0 ** Singleton element)
]
176 | isNull bq = null bq.forest
178 | length (MkSBQ o forest_size forest) =
179 | let lens = map (\(_ ** x) => skewLen x) forest
182 | findMin (MkSBQ o forest_size forest) =
185 | ((
_ ** x)
:: xs) =>
187 | xs = map (\(_ ** y) => root y) xs
188 | in Just $
foldl min x xs
191 | let (
new_size ** new_forest)
= meld' @{x.o} x.forest y.forest
192 | in MkSBQ x.o new_size new_forest
194 | insert element (MkSBQ o forest_size forest) =
196 | [] => MkSBQ o 1 [(
0 ** Singleton element)
]
197 | [x] => MkSBQ o 2 [(
0 ** Singleton element)
, x]
198 | (
x_rank ** x)
:: (
y_rank ** y)
:: xs =>
199 | case decEq x_rank y_rank of
201 | let rest = skewLink (Singleton element) x y
202 | in MkSBQ o _ $ (
S y_rank ** rest)
:: xs
203 | No _ => MkSBQ o _ $ (
0 ** Singleton element)
:: forest
205 | deleteMin (MkSBQ o forest_size forest) with (forest)
206 | deleteMin (MkSBQ o 0 forest) | ([]) =
208 | deleteMin (MkSBQ o (S 0) forest) | ((
x_rank ** x)
:: []) =
209 | let (singlets, rest) =
210 | partitionEithers . map processTree . reverse . snd . extractRoot
212 | new_queue = MkSBQ o (length rest) (fromList rest)
213 | in foldl (\acc, e => insert e acc) new_queue singlets
214 | deleteMin (MkSBQ o (S (S len)) forest) | (x :: y :: xs) =
215 | let (idx, (
min_n ** min_tree)
) = findMin (y :: xs) (0, x) 1
216 | without_min = deleteAt idx forest
218 | partitionEithers . map processTree . reverse . snd . extractRoot
220 | (
rest_len ** rest)
= listToVect rest
221 | (
new_size ** new_forest)
= meld' without_min rest
222 | new_queue = MkSBQ o new_size new_forest
223 | in foldl (\acc, e => insert e acc) new_queue singlets
225 | listToVect : List a -> (n : Nat ** Vect n a)
226 | listToVect xs = (
length xs ** fromList xs)
229 | (xs : Vect n (SkewBinomialPair e)) ->
230 | (acc : (Fin m, SkewBinomialPair e)) ->
232 | -> (Fin m, SkewBinomialPair e)
233 | findMin [] acc idx = acc
234 | findMin ((
x_rank ** x)
:: xs) orig_acc@(acc_idx, (
acc_rank ** acc)
) idx =
235 | if root x < root acc
236 | then findMin xs (idx, (
x_rank ** x)
) (finS idx)
237 | else findMin xs orig_acc (finS idx)