PROOF.bend
bend-kit-collections@0.1.3.0 · 4,125 lines · 0 definitions
1import Base
2import bend-mathlib@0.7.2.0/nat.bend as MNat
3import bend-mathlib@0.7.2.0/bool.bend as MBool
4import bend-kit-collections@0.1.3.0/LAWS.bend as Laws
5import bend-kit-collections@0.1.3.0/omap.bend as O
6import bend-kit-collections@0.1.3.0/hmap.bend as M
7import bend-kit-collections@0.1.3.0/nat_order.bend as Ord
8import bend-kit-collections@0.1.3.0/order.bend as Order
9import bend-kit-lemmas@0.1.0.0/lemmas.bend as Lemmas
10
11def Laws.omap_keys_ascending_puts():
12 {==}
13
14def Laws.omap_size_del():
15 {==}
16
17def Laws.omap_get_after_rotations():
18 {==}
19
20def Laws.omap_keys_del_root():
21 {==}
22
23def Laws.omap_get_put():
24 {==}
25
26def Laws.omap_get_put_replace():
27 {==}
28
29def Laws.omap_get_put_other():
30 {==}
31
32def Laws.omap_get_missing():
33 {==}
34
35def Laws.omap_keys_sorted():
36 {==}
37
38def Laws.omap_size_replace():
39 {==}
40
41def Laws.omap_get_del():
42 {==}
43
44def Laws.omap_get_del_other():
45 {==}
46
47def Laws.omap_keys_del():
48 {==}
49
50def Laws.omap_string_keys():
51 {==}
52
53def Laws.oset_to_list():
54 {==}
55
56def Laws.oset_has_del():
57 {==}
58
59def Laws.vec_from_list():
60 {==}
61
62def Laws.vec_get():
63 {==}
64
65def Laws.vec_get_past_len():
66 {==}
67
68def Laws.vec_set():
69 {==}
70
71def Laws.vec_pop():
72 {==}
73
74def Laws.vec_pop_empty():
75 {==}
76
77def Laws.vec_pop_to_list():
78 {==}
79
80def Laws.deque_ends():
81 {==}
82
83def Laws.heap_sort():
84 {==}
85
86def c4.a(
87 +a: Bool, +b: Bool, +c: Bool, +d: Bool,
88 e: {Bool.and(Bool.and(Bool.and(a, b), c), d) == True{} : Bool}
89) -> {a == True{} : Bool}:
90 MBool.eq_true_of_and_left(a, b, MBool.eq_true_of_and_left(Bool.and(a, b), c, MBool.eq_true_of_and_left(Bool.and(Bool.and(a, b), c), d, e)))
91
92def c4.b(
93 +a: Bool, +b: Bool, +c: Bool, +d: Bool,
94 e: {Bool.and(Bool.and(Bool.and(a, b), c), d) == True{} : Bool}
95) -> {b == True{} : Bool}:
96 MBool.eq_true_of_and_right(a, b, MBool.eq_true_of_and_left(Bool.and(a, b), c, MBool.eq_true_of_and_left(Bool.and(Bool.and(a, b), c), d, e)))
97
98def c4.c(
99 +a: Bool, +b: Bool, +c: Bool, +d: Bool,
100 e: {Bool.and(Bool.and(Bool.and(a, b), c), d) == True{} : Bool}
101) -> {c == True{} : Bool}:
102 MBool.eq_true_of_and_right(Bool.and(a, b), c, MBool.eq_true_of_and_left(Bool.and(Bool.and(a, b), c), d, e))
103
104def c4.d(
105 +a: Bool, +b: Bool, +c: Bool, +d: Bool,
106 e: {Bool.and(Bool.and(Bool.and(a, b), c), d) == True{} : Bool}
107) -> {d == True{} : Bool}:
108 MBool.eq_true_of_and_right(Bool.and(Bool.and(a, b), c), d, e)
109
110def c4.i(
111 +a: Bool, +b: Bool, +c: Bool, +d: Bool, ea: {a == True{} : Bool},
112 eb: {b == True{} : Bool}, ec: {c == True{} : Bool}, ed: {d == True{} : Bool}
113) -> {Bool.and(Bool.and(Bool.and(a, b), c), d) == True{} : Bool}:
114 MBool.and_eq_true(Bool.and(Bool.and(a, b), c), d, MBool.and_eq_true(Bool.and(a, b), c, MBool.and_eq_true(a, b, ea, eb), ec), ed)
115
116
117def c3.a(+a: Bool, +b: Bool, +c: Bool, e: {Bool.and(Bool.and(a, b), c) == True{} : Bool}) -> {a == True{} : Bool}:
118 MBool.eq_true_of_and_left(a, b, MBool.eq_true_of_and_left(Bool.and(a, b), c, e))
119
120def c3.b(+a: Bool, +b: Bool, +c: Bool, e: {Bool.and(Bool.and(a, b), c) == True{} : Bool}) -> {b == True{} : Bool}:
121 MBool.eq_true_of_and_right(a, b, MBool.eq_true_of_and_left(Bool.and(a, b), c, e))
122
123def c3.c(+a: Bool, +b: Bool, +c: Bool, e: {Bool.and(Bool.and(a, b), c) == True{} : Bool}) -> {c == True{} : Bool}:
124 MBool.eq_true_of_and_right(Bool.and(a, b), c, e)
125
126def c3.i(+a: Bool, +b: Bool, +c: Bool, ea: {a == True{} : Bool}, eb: {b == True{} : Bool}, ec: {c == True{} : Bool})
127 -> {Bool.and(Bool.and(a, b), c) == True{} : Bool}:
128 MBool.and_eq_true(Bool.and(a, b), c, MBool.and_eq_true(a, b, ea, eb), ec)
129
130def Laws.omap_new_searchtree(K, V, cmp):
131 {==}
132
133def head(-K: Data, xs: List<&2, K>) -> Maybe<&2, K>:
134 match xs:
135 case Nil{}:
136 None{}
137 case Con{h, t}:
138 Some{h}
139
140# The list is sorted and its first element lies above lb.
141def sfrom(~K: Data, ~cmp: K -> K -> Cmp, lb: Maybe<&2, K>, xs: List<&2, K>) -> Bool:
142 match lb:
143 case None{}:
144 Laws.sorted(~K, ~cmp, xs)
145 case Some{b}:
146 Laws.sorted.go(~K, ~cmp, xs, b)
147
148# lb lies below ub, when both exist.
149def lt_m(~K: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, ub: Maybe<&2, K>) -> Bool:
150 match ub:
151 case None{}:
152 True{}
153 case Some{u}:
154 Laws.above(~K, ~cmp, lb, u)
155
156def lt_m.some(
157 ~K: Data, ~cmp: K -> K -> Cmp, ub: Maybe<&2, K>, +k: K,
158 e: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool}
159) -> {lt_m(~K, ~cmp, Some{k}, ub) == True{} : Bool}:
160 match ub:
161 case None{}:
162 {==}
163 case Some{u}:
164 e
165
166def sfrom.base(
167 ~K: Data, ~cmp: K -> K -> Cmp, lb: Maybe<&2, K>, acc: List<&2, K>,
168 lt: {lt_m(~K, ~cmp, lb, head(K, acc)) == True{} : Bool},
169 sa: {Laws.sorted(~K, ~cmp, acc) == True{} : Bool}
170) -> {sfrom(~K, ~cmp, lb, acc) == True{} : Bool}:
171 match lb acc:
172 case None{} _:
173 sa
174 case Some{b} Nil{}:
175 {==}
176 case Some{+b} Con{+h, t}:
177 MBool.and_eq_true(Cmp.is_lt(cmp(b, h)), Laws.sorted.go(~K, ~cmp, t, h), lt, sa)
178
179def keys_sorted.go(
180 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, t: O.OMap<K, V>, +lb: Maybe<&2, K>,
181 +acc: List<&2, K>,
182 +bt: {Laws.bounded(~K, ~V, ~cmp, t, lb, head(K, acc)) == True{} : Bool},
183 lt: {lt_m(~K, ~cmp, lb, head(K, acc)) == True{} : Bool},
184 sa: {Laws.sorted(~K, ~cmp, acc) == True{} : Bool}
185) -> {sfrom(~K, ~cmp, lb, O.OMap.keys.go(K, V, t, acc)) == True{} : Bool}:
186 match t:
187 case O.OTip{}:
188 sfrom.base(~K, ~cmp, lb, acc, lt, sa)
189 case O.OBin{s, +k, v, +lo, +hi}:
190 +A = Laws.above(~K, ~cmp, lb, k)
191 +B = Laws.below(~K, ~cmp, head(K, acc), k)
192 +L = Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k})
193 +H = Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, head(K, acc))
194 ih = keys_sorted.go(~K, ~V, ~cmp, hi, Some{k}, acc, c4.d(A, B, L, H, bt),
195 lt_m.some(~K, ~cmp, head(K, acc), k, c4.b(A, B, L, H, bt)), sa)
196 keys_sorted.go(~K, ~V, ~cmp, lo, lb, k <> O.OMap.keys.go(K, V, hi, acc),
197 c4.c(A, B, L, H, bt), c4.a(A, B, L, H, bt), ih)
198
199def Laws.omap_searchtree_keys_sorted(K, V, cmp, m, tree):
200 keys_sorted.go(~K, ~V, ~cmp, m, None{}, Nil{}, tree, {==}, {==})
201
202def Trans(~K: Data, ~cmp: K -> K -> Cmp) -> Type:
203 @x: K -> @y: K -> @z: K -> {cmp(x, y) == LT{} : Cmp} -> {cmp(y, z) == LT{} : Cmp} -> {cmp(x, z) == LT{} : Cmp}
204
205def Flip(~K: Data, ~cmp: K -> K -> Cmp) -> Type:
206 @x: K -> @y: K -> {cmp(y, x) == Laws.flip(cmp(x, y)) : Cmp}
207
208def Refl(~K: Data, ~cmp: K -> K -> Cmp) -> Type:
209 @x: K -> {cmp(x, x) == EQ{} : Cmp}
210
211def Eq(~K: Data, ~cmp: K -> K -> Cmp) -> Type:
212 @x: K -> @y: K -> {cmp(x, y) == EQ{} : Cmp} -> {x == y : K}
213
214def lt_of(c: Cmp, e: {Cmp.is_lt(c) == True{} : Bool}) -> {c == LT{} : Cmp}:
215 match c:
216 case LT{}:
217 {==}
218 case EQ{}:
219 Empty.absurd({EQ{} == LT{} : Cmp}, MBool.false_ne_true()(e))
220 case GT{}:
221 Empty.absurd({GT{} == LT{} : Cmp}, MBool.false_ne_true()(e))
222
223def lt_true(-c: Cmp, e: {c == LT{} : Cmp}) -> {Cmp.is_lt(c) == True{} : Bool}:
224 Equal.cong(Cmp, Bool, x => Cmp.is_lt(x), c, LT{}, e)
225
226def gt_flip(
227 ~K: Data, ~cmp: K -> K -> Cmp, ~flip: Flip(~K, ~cmp), +x: K, +y: K,
228 e: {cmp(x, y) == GT{} : Cmp}
229) -> {cmp(y, x) == LT{} : Cmp}:
230 Equal.trans(Cmp, cmp(y, x), Laws.flip(cmp(x, y)), LT{}, flip(x, y),
231 Equal.cong(Cmp, Cmp, c => Laws.flip(c), cmp(x, y), GT{}, e))
232
233def lt_trans(
234 ~K: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp), +x: K, +y: K, +z: K,
235 e1: {Cmp.is_lt(cmp(x, y)) == True{} : Bool},
236 e2: {Cmp.is_lt(cmp(y, z)) == True{} : Bool}
237) -> {Cmp.is_lt(cmp(x, z)) == True{} : Bool}:
238 lt_true(cmp(x, z), trans(x, y, z, lt_of(cmp(x, y), e1), lt_of(cmp(y, z), e2)))
239
240def above_trans(
241 ~K: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp), lb: Maybe<&2, K>,
242 +k: K, +hk: K, ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
243 e: {Cmp.is_lt(cmp(k, hk)) == True{} : Bool}
244) -> {Laws.above(~K, ~cmp, lb, hk) == True{} : Bool}:
245 match lb:
246 case None{}:
247 {==}
248 case Some{+b}:
249 lt_trans(~K, ~cmp, ~trans, b, k, hk, ea, e)
250
251def below_trans(
252 ~K: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp), ub: Maybe<&2, K>,
253 +k: K, +hk: K, e: {Cmp.is_lt(cmp(k, hk)) == True{} : Bool},
254 eb: {Laws.below(~K, ~cmp, ub, hk) == True{} : Bool}
255) -> {Laws.below(~K, ~cmp, ub, k) == True{} : Bool}:
256 match ub:
257 case None{}:
258 {==}
259 case Some{+u}:
260 lt_trans(~K, ~cmp, ~trans, k, hk, u, e, eb)
261
262# Projections and introduction for bounded on one node.
263def bn.a(
264 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
265 +k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
266 e: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}
267) -> {Laws.above(~K, ~cmp, lb, k) == True{} : Bool}:
268 c4.a(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k),
269 Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}),
270 Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), e)
271
272def bn.b(
273 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
274 +k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
275 e: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}
276) -> {Laws.below(~K, ~cmp, ub, k) == True{} : Bool}:
277 c4.b(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k),
278 Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}),
279 Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), e)
280
281def bn.l(
282 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
283 +k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
284 e: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}
285) -> {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool}:
286 c4.c(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k),
287 Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}),
288 Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), e)
289
290def bn.h(
291 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
292 +k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
293 e: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}
294) -> {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}:
295 c4.d(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k),
296 Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}),
297 Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), e)
298
299def bn.i(
300 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
301 +k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
302 ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
303 eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
304 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
305 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
306) -> {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}:
307 c4.i(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k),
308 Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}),
309 Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), ea, eb, el, eh)
310
311def rot_lo.single.bnd(
312 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
313 +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V, +lo: O.OMap<K, V>,
314 +hk: K, +hv: V, +hl: O.OMap<K, V>, +hh: O.OMap<K, V>,
315 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
316 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
317 +eh: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, hk, hv, hl, hh}, Some{k}, ub) == True{} : Bool}
318) -> {Laws.bounded(~K, ~V, ~cmp,
319 O.OMap.bin(K, V, hk, hv, O.OMap.bin(K, V, k, v, lo, hl), hh), lb, ub) == True{} : Bool}:
320 +h_a = bn.a(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)
321 bn.i(~K, ~V, ~cmp, lb, ub, hk, hv, O.OMap.bin(K, V, k, v, lo, hl), hh,
322 above_trans(~K, ~cmp, ~trans, lb, k, hk, ea, h_a),
323 bn.b(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh),
324 bn.i(~K, ~V, ~cmp, lb, Some{hk}, k, v, lo, hl, ea, h_a, el,
325 bn.l(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)),
326 bn.h(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh))
327
328def rot_lo.double.bnd(
329 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
330 hl: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
331 +lo: O.OMap<K, V>, +hk: K, +hv: V, +hh: O.OMap<K, V>,
332 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
333 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
334 +eh: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, hk, hv, hl, hh}, Some{k}, ub) == True{} : Bool}
335) -> {Laws.bounded(~K, ~V, ~cmp,
336 O.OMap.rot_lo.double(K, V, k, v, lo, hk, hv, hl, hh), lb, ub) == True{} : Bool}:
337 match hl:
338 case O.OTip{}:
339 rot_lo.single.bnd(~K, ~V, ~cmp, ~trans, lb, ub, k, v, lo, hk, hv, O.OTip{}, hh,
340 ea, el, eh)
341 case O.OBin{s, +mk, +mv, +ml, +mh}:
342 +hl = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
343 +h_b = bn.b(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)
344 +h_l = bn.l(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)
345 +m_a = bn.a(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l)
346 +m_b = bn.b(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l)
347 bn.i(~K, ~V, ~cmp, lb, ub, mk, mv, O.OMap.bin(K, V, k, v, lo, ml),
348 O.OMap.bin(K, V, hk, hv, mh, hh),
349 above_trans(~K, ~cmp, ~trans, lb, k, mk, ea, m_a),
350 below_trans(~K, ~cmp, ~trans, ub, mk, hk, m_b, h_b),
351 bn.i(~K, ~V, ~cmp, lb, Some{mk}, k, v, lo, ml, ea, m_a, el,
352 bn.l(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l)),
353 bn.i(~K, ~V, ~cmp, Some{mk}, ub, hk, hv, mh, hh, m_b, h_b,
354 bn.h(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l),
355 bn.h(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)))
356
357def rot_lo.pick.bnd(
358 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
359 single: Bool, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
360 +lo: O.OMap<K, V>, +hk: K, +hv: V, +hl: O.OMap<K, V>, +hh: O.OMap<K, V>,
361 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
362 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
363 +eh: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, hk, hv, hl, hh}, Some{k}, ub) == True{} : Bool}
364) -> {Laws.bounded(~K, ~V, ~cmp,
365 O.OMap.rot_lo.pick(K, V, single, k, v, lo, hk, hv, hl, hh), lb, ub) == True{} : Bool}:
366 match single:
367 case True{}:
368 rot_lo.single.bnd(~K, ~V, ~cmp, ~trans, lb, ub, k, v, lo, hk, hv, hl, hh, ea, el, eh)
369 case False{}:
370 rot_lo.double.bnd(~K, ~V, ~cmp, ~trans, hl, lb, ub, k, v, lo, hk, hv, hh, ea, el, eh)
371
372def rot_lo.bnd(
373 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
374 hi: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
375 +lo: O.OMap<K, V>,
376 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
377 eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
378 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
379 +eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
380) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.rot_lo(K, V, k, v, lo, hi), lb, ub) == True{} : Bool}:
381 match hi:
382 case O.OTip{}:
383 bn.i(~K, ~V, ~cmp, lb, ub, k, v, lo, O.OTip{}, ea, eb, el, eh)
384 case O.OBin{s, +hk, +hv, +hl, +hh}:
385 rot_lo.pick.bnd(~K, ~V, ~cmp, ~trans,
386 U32.is_lt((O.OMap.size(K, V, hl) + 1 : U32),
387 (2 * (O.OMap.size(K, V, hh) + 1) : U32)),
388 lb, ub, k, v, lo, hk, hv, hl, hh, ea, el, eh)
389
390def rot_hi.single.bnd(
391 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
392 +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V, +lk: K, +lv: V,
393 +ll: O.OMap<K, V>, +lh: O.OMap<K, V>, +hi: O.OMap<K, V>,
394 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
395 +el: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, lk, lv, ll, lh}, lb, Some{k}) == True{} : Bool},
396 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
397) -> {Laws.bounded(~K, ~V, ~cmp,
398 O.OMap.bin(K, V, lk, lv, ll, O.OMap.bin(K, V, k, v, lh, hi)), lb, ub) == True{} : Bool}:
399 +l_b = bn.b(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el)
400 bn.i(~K, ~V, ~cmp, lb, ub, lk, lv, ll, O.OMap.bin(K, V, k, v, lh, hi),
401 bn.a(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el),
402 below_trans(~K, ~cmp, ~trans, ub, lk, k, l_b, eb),
403 bn.l(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el),
404 bn.i(~K, ~V, ~cmp, Some{lk}, ub, k, v, lh, hi, l_b, eb,
405 bn.h(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el), eh))
406
407def rot_hi.double.bnd(
408 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
409 lh: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
410 +lk: K, +lv: V, +ll: O.OMap<K, V>, +hi: O.OMap<K, V>,
411 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
412 +el: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, lk, lv, ll, lh}, lb, Some{k}) == True{} : Bool},
413 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
414) -> {Laws.bounded(~K, ~V, ~cmp,
415 O.OMap.rot_hi.double(K, V, k, v, lk, lv, ll, lh, hi), lb, ub) == True{} : Bool}:
416 match lh:
417 case O.OTip{}:
418 rot_hi.single.bnd(~K, ~V, ~cmp, ~trans, lb, ub, k, v, lk, lv, ll, O.OTip{}, hi,
419 eb, el, eh)
420 case O.OBin{s, +mk, +mv, +ml, +mh}:
421 +lh = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
422 +l_a = bn.a(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el)
423 +l_h = bn.h(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el)
424 +m_a = bn.a(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h)
425 +m_b = bn.b(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h)
426 bn.i(~K, ~V, ~cmp, lb, ub, mk, mv, O.OMap.bin(K, V, lk, lv, ll, ml),
427 O.OMap.bin(K, V, k, v, mh, hi),
428 above_trans(~K, ~cmp, ~trans, lb, lk, mk, l_a, m_a),
429 below_trans(~K, ~cmp, ~trans, ub, mk, k, m_b, eb),
430 bn.i(~K, ~V, ~cmp, lb, Some{mk}, lk, lv, ll, ml, l_a, m_a,
431 bn.l(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el),
432 bn.l(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h)),
433 bn.i(~K, ~V, ~cmp, Some{mk}, ub, k, v, mh, hi, m_b, eb,
434 bn.h(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h), eh))
435
436def rot_hi.pick.bnd(
437 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
438 single: Bool, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
439 +lk: K, +lv: V, +ll: O.OMap<K, V>, +lh: O.OMap<K, V>, +hi: O.OMap<K, V>,
440 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
441 +el: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, lk, lv, ll, lh}, lb, Some{k}) == True{} : Bool},
442 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
443) -> {Laws.bounded(~K, ~V, ~cmp,
444 O.OMap.rot_hi.pick(K, V, single, k, v, lk, lv, ll, lh, hi), lb, ub) == True{} : Bool}:
445 match single:
446 case True{}:
447 rot_hi.single.bnd(~K, ~V, ~cmp, ~trans, lb, ub, k, v, lk, lv, ll, lh, hi, eb, el, eh)
448 case False{}:
449 rot_hi.double.bnd(~K, ~V, ~cmp, ~trans, lh, lb, ub, k, v, lk, lv, ll, hi, eb, el, eh)
450
451def rot_hi.bnd(
452 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
453 lo: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
454 +hi: O.OMap<K, V>,
455 ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
456 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
457 +el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
458 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
459) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.rot_hi(K, V, k, v, lo, hi), lb, ub) == True{} : Bool}:
460 match lo:
461 case O.OTip{}:
462 bn.i(~K, ~V, ~cmp, lb, ub, k, v, O.OTip{}, hi, ea, eb, el, eh)
463 case O.OBin{s, +lk, +lv, +ll, +lh}:
464 rot_hi.pick.bnd(~K, ~V, ~cmp, ~trans,
465 U32.is_lt((O.OMap.size(K, V, lh) + 1 : U32),
466 (2 * (O.OMap.size(K, V, ll) + 1) : U32)),
467 lb, ub, k, v, lk, lv, ll, lh, hi, eb, el, eh)
468
469def balance.if.bnd(
470 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
471 heavy_hi: Bool, heavy_lo: Bool, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K,
472 +v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
473 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
474 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
475 +el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
476 +eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
477) -> {Laws.bounded(~K, ~V, ~cmp,
478 O.OMap.balance.if(K, V, heavy_hi, heavy_lo, k, v, lo, hi), lb, ub) == True{} : Bool}:
479 match heavy_hi heavy_lo:
480 case True{} _:
481 rot_lo.bnd(~K, ~V, ~cmp, ~trans, hi, lb, ub, k, v, lo, ea, eb, el, eh)
482 case False{} True{}:
483 rot_hi.bnd(~K, ~V, ~cmp, ~trans, lo, lb, ub, k, v, hi, ea, eb, el, eh)
484 case False{} False{}:
485 bn.i(~K, ~V, ~cmp, lb, ub, k, v, lo, hi, ea, eb, el, eh)
486
487def balance.bnd(
488 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
489 +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V, +lo: O.OMap<K, V>,
490 +hi: O.OMap<K, V>,
491 ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
492 eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
493 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
494 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
495) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.balance(K, V, k, v, lo, hi), lb, ub) == True{} : Bool}:
496 +wl = (O.OMap.size(K, V, lo) + 1 : U32)
497 +wh = (O.OMap.size(K, V, hi) + 1 : U32)
498 balance.if.bnd(~K, ~V, ~cmp, ~trans, U32.is_gt(wh, (3 * wl : U32)),
499 U32.is_gt(wl, (3 * wh : U32)), lb, ub, k, v, lo, hi, ea, eb, el, eh)
500
501# Proves a goal about O.Cmp.case by one case per comparison result.
502def cmp.split(
503 -A: Type, -B: Type, -F: A -> B, -G: B, c: Cmp, -f1: Unit -> A,
504 -f2: Unit -> A, -f3: Unit -> A,
505 hl: {c == LT{} : Cmp} -> {F(f1(Unit{})) == G : B},
506 he: {c == EQ{} : Cmp} -> {F(f2(Unit{})) == G : B},
507 hg: {c == GT{} : Cmp} -> {F(f3(Unit{})) == G : B}
508) -> {F(O.Cmp.case(A, c, f1, f2, f3)) == G : B}:
509 match c:
510 case LT{}:
511 hl({==})
512 case EQ{}:
513 he({==})
514 case GT{}:
515 hg({==})
516
517def put.bnd(
518 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~flip: Flip(~K, ~cmp),
519 ~trans: Trans(~K, ~cmp), t: O.OMap<K, V>, +lb: Maybe<&2, K>,
520 +ub: Maybe<&2, K>, +k: K, +v: V,
521 +bt: {Laws.bounded(~K, ~V, ~cmp, t, lb, ub) == True{} : Bool},
522 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
523 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool}
524) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.put(~K, ~V, ~cmp, t, k, v), lb, ub) == True{} : Bool}:
525 match t:
526 case O.OTip{}:
527 bn.i(~K, ~V, ~cmp, lb, ub, k, v, O.OTip{}, O.OTip{}, ea, eb, {==}, {==})
528 case O.OBin{+s, +key, +val, +lo, +hi}:
529 +b_a = bn.a(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
530 +b_b = bn.b(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
531 +b_l = bn.l(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
532 +b_h = bn.h(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
533 cmp.split(O.OMap<K, V>, Bool, x => Laws.bounded(~K, ~V, ~cmp, x, lb, ub), True{},
534 cmp(k, key),
535 u => O.OMap.balance(K, V, key, val, O.OMap.put(~K, ~V, ~cmp, lo, k, v), hi),
536 u => O.OBin{s, key, v, lo, hi},
537 u => O.OMap.balance(K, V, key, val, lo, O.OMap.put(~K, ~V, ~cmp, hi, k, v)),
538 e => balance.bnd(~K, ~V, ~cmp, ~trans, lb, ub, key, val,
539 O.OMap.put(~K, ~V, ~cmp, lo, k, v), hi, b_a, b_b,
540 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, lo, lb, Some{key}, k, v, b_l, ea,
541 lt_true(cmp(k, key), e)),
542 b_h),
543 e => bt,
544 e => balance.bnd(~K, ~V, ~cmp, ~trans, lb, ub, key, val, lo,
545 O.OMap.put(~K, ~V, ~cmp, hi, k, v), b_a, b_b, b_l,
546 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, hi, Some{key}, ub, k, v, b_h,
547 lt_true(cmp(key, k), gt_flip(~K, ~cmp, ~flip, k, key, e)), eb)))
548
549def Laws.omap_put_searchtree(K, V, cmp, refl, eq, flip, trans, m, tree, k, v):
550 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, m, None{}, None{}, k, v, tree, {==}, {==})
551
552def rw(-A: Type, -P: A -> Type, -a: A, -b: A, e: {a == b : A}, p: P(b)) -> P(a):
553 %Equal.sym(A, a, b, e) : P(_)
554 p
555
556def split(
557 -P: Cmp -> Type, c: Cmp, hl: {c == LT{} : Cmp} -> P(LT{}),
558 he: {c == EQ{} : Cmp} -> P(EQ{}), hg: {c == GT{} : Cmp} -> P(GT{})
559) -> P(c):
560 match c:
561 case LT{}:
562 hl({==})
563 case EQ{}:
564 he({==})
565 case GT{}:
566 hg({==})
567
568def gt_of_lt(
569 ~K: Data, ~cmp: K -> K -> Cmp, ~flip: Flip(~K, ~cmp), +x: K, +y: K,
570 e: {cmp(x, y) == LT{} : Cmp}
571) -> {cmp(y, x) == GT{} : Cmp}:
572 Equal.trans(Cmp, cmp(y, x), Laws.flip(cmp(x, y)), GT{}, flip(x, y),
573 Equal.cong(Cmp, Cmp, c => Laws.flip(c), cmp(x, y), LT{}, e))
574
575# get on one node, with the comparison result as a parameter.
576def getc(
577 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, c: Cmp, +x: K, +val: V,
578 lo: O.OMap<K, V>, hi: O.OMap<K, V>
579) -> Maybe<&2, V>:
580 O.Cmp.case(Maybe<&2, V>, c,
581 u => O.OMap.get(~K, ~V, ~cmp, lo, x),
582 u => Some{val},
583 u => O.OMap.get(~K, ~V, ~cmp, hi, x))
584
585# get finds key k itself in a node keyed by k.
586def get.here(
587 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), +k: K, +v: V,
588 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>
589) -> {O.OMap.get(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, k) == Some{v} : Maybe<&2, V>}:
590 rw(Cmp, c => {getc(~K, ~V, ~cmp, c, k, v, lo, hi) == Some{v} : Maybe<&2, V>},
591 cmp(k, k), EQ{}, refl(k), {==})
592
593# get on a node goes to lo when the comparison is LT.
594def get.lt(
595 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +x: K, +k: K, +v: V,
596 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>, e: {cmp(x, k) == LT{} : Cmp}
597) -> {O.OMap.get(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x)
598 == O.OMap.get(~K, ~V, ~cmp, lo, x) : Maybe<&2, V>}:
599 rw(Cmp, c => {getc(~K, ~V, ~cmp, c, x, v, lo, hi)
600 == O.OMap.get(~K, ~V, ~cmp, lo, x) : Maybe<&2, V>},
601 cmp(x, k), LT{}, e, {==})
602
603# get on a node goes to hi when the comparison is GT.
604def get.gt(
605 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +x: K, +k: K, +v: V,
606 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>, e: {cmp(x, k) == GT{} : Cmp}
607) -> {O.OMap.get(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x)
608 == O.OMap.get(~K, ~V, ~cmp, hi, x) : Maybe<&2, V>}:
609 rw(Cmp, c => {getc(~K, ~V, ~cmp, c, x, v, lo, hi)
610 == O.OMap.get(~K, ~V, ~cmp, hi, x) : Maybe<&2, V>},
611 cmp(x, k), GT{}, e, {==})
612
613def rot_lo.single.get(
614 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
615 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
616 +x: K, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K,
617 +hv: V, +hl: O.OMap<K, V>, +hh: O.OMap<K, V>, +khk: {cmp(k, hk) == LT{} : Cmp}
618) -> {O.OMap.get(~K, ~V, ~cmp,
619 O.OMap.bin(K, V, hk, hv, O.OMap.bin(K, V, k, v, lo, hl), hh), x)
620 == O.OMap.get(~K, ~V, ~cmp, O.OBin{0, k, v, lo, O.OBin{0, hk, hv, hl, hh}}, x)
621 : Maybe<&2, V>}:
622 +inner = {O.OBin{0, k, v, lo, hl} : O.OMap<K, V>}
623 +lhs = {O.OBin{0, hk, hv, inner, hh} : O.OMap<K, V>}
624 split(c => {O.OMap.get(~K, ~V, ~cmp, lhs, x)
625 == getc(~K, ~V, ~cmp, c, x, v, lo, O.OBin{0, hk, hv, hl, hh}) : Maybe<&2, V>},
626 cmp(x, k),
627 +e => Equal.trans(Maybe<&2, V>, O.OMap.get(~K, ~V, ~cmp, lhs, x),
628 O.OMap.get(~K, ~V, ~cmp, inner, x), O.OMap.get(~K, ~V, ~cmp, lo, x),
629 get.lt(~K, ~V, ~cmp, x, hk, hv, inner, hh, trans(x, k, hk, e, khk)),
630 get.lt(~K, ~V, ~cmp, x, k, v, lo, hl, e)),
631 e => rw(K, y => {O.OMap.get(~K, ~V, ~cmp, lhs, y) == Some{v} : Maybe<&2, V>},
632 x, k, eq(x, k, e),
633 Equal.trans(Maybe<&2, V>, O.OMap.get(~K, ~V, ~cmp, lhs, k),
634 O.OMap.get(~K, ~V, ~cmp, inner, k), Some{v},
635 get.lt(~K, ~V, ~cmp, k, hk, hv, inner, hh, khk),
636 get.here(~K, ~V, ~cmp, ~refl, k, v, lo, hl))),
637 e => split(c => {getc(~K, ~V, ~cmp, c, x, hv, inner, hh)
638 == getc(~K, ~V, ~cmp, c, x, hv, hl, hh) : Maybe<&2, V>},
639 cmp(x, hk),
640 e2 => get.gt(~K, ~V, ~cmp, x, k, v, lo, hl, e),
641 e2 => {==},
642 e2 => {==}))
643
644def g(~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, t: O.OMap<K, V>, +x: K) -> Maybe<&2, V>:
645 O.OMap.get(~K, ~V, ~cmp, t, x)
646
647def mtr(
648 -V: Data, -a: Maybe<&2, V>, -b: Maybe<&2, V>, -c: Maybe<&2, V>,
649 e1: {a == b : Maybe<&2, V>}, e2: {b == c : Maybe<&2, V>}
650) -> {a == c : Maybe<&2, V>}:
651 Equal.trans(Maybe<&2, V>, a, b, c, e1, e2)
652
653def rot_lo.double.get2(
654 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
655 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
656 +x: K, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V, +mk: K, +mv: V,
657 +ml: O.OMap<K, V>, +mh: O.OMap<K, V>, +hh: O.OMap<K, V>,
658 +khm: {cmp(k, mk) == LT{} : Cmp}, +mhk: {cmp(mk, hk) == LT{} : Cmp}
659) -> {g(~K, ~V, ~cmp, O.OMap.bin(K, V, mk, mv, O.OMap.bin(K, V, k, v, lo, ml),
660 O.OMap.bin(K, V, hk, hv, mh, hh)), x)
661 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, O.OBin{0, hk, hv, O.OBin{0, mk, mv, ml, mh}, hh}}, x)
662 : Maybe<&2, V>}:
663 +a = {O.OBin{0, k, v, lo, ml} : O.OMap<K, V>}
664 +b = {O.OBin{0, hk, hv, mh, hh} : O.OMap<K, V>}
665 +l = {O.OBin{0, mk, mv, a, b} : O.OMap<K, V>}
666 +m = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
667 +r1 = {O.OBin{0, hk, hv, m, hh} : O.OMap<K, V>}
668 split(c => {g(~K, ~V, ~cmp, l, x) == getc(~K, ~V, ~cmp, c, x, v, lo, r1) : Maybe<&2, V>},
669 cmp(x, k),
670 +e => mtr(V, g(~K, ~V, ~cmp, l, x), g(~K, ~V, ~cmp, a, x), g(~K, ~V, ~cmp, lo, x),
671 get.lt(~K, ~V, ~cmp, x, mk, mv, a, b, trans(x, k, mk, e, khm)),
672 get.lt(~K, ~V, ~cmp, x, k, v, lo, ml, e)),
673 e => rw(K, y => {g(~K, ~V, ~cmp, l, y) == Some{v} : Maybe<&2, V>}, x, k, eq(x, k, e),
674 mtr(V, g(~K, ~V, ~cmp, l, k), g(~K, ~V, ~cmp, a, k), Some{v},
675 get.lt(~K, ~V, ~cmp, k, mk, mv, a, b, khm),
676 get.here(~K, ~V, ~cmp, ~refl, k, v, lo, ml))),
677 +e => split(c => {g(~K, ~V, ~cmp, l, x) == getc(~K, ~V, ~cmp, c, x, hv, m, hh) : Maybe<&2, V>},
678 cmp(x, hk),
679 +e2 => split(c => {getc(~K, ~V, ~cmp, c, x, mv, a, b)
680 == getc(~K, ~V, ~cmp, c, x, mv, ml, mh) : Maybe<&2, V>},
681 cmp(x, mk),
682 e3 => get.gt(~K, ~V, ~cmp, x, k, v, lo, ml, e),
683 e3 => {==},
684 e3 => get.lt(~K, ~V, ~cmp, x, hk, hv, mh, hh, e2)),
685 e2 => rw(K, y => {g(~K, ~V, ~cmp, l, y) == Some{hv} : Maybe<&2, V>}, x, hk, eq(x, hk, e2),
686 mtr(V, g(~K, ~V, ~cmp, l, hk), g(~K, ~V, ~cmp, b, hk), Some{hv},
687 get.gt(~K, ~V, ~cmp, hk, mk, mv, a, b, gt_of_lt(~K, ~cmp, ~flip, mk, hk, mhk)),
688 get.here(~K, ~V, ~cmp, ~refl, hk, hv, mh, hh))),
689 +e2 => mtr(V, g(~K, ~V, ~cmp, l, x), g(~K, ~V, ~cmp, b, x), g(~K, ~V, ~cmp, hh, x),
690 get.gt(~K, ~V, ~cmp, x, mk, mv, a, b,
691 gt_of_lt(~K, ~cmp, ~flip, mk, x,
692 trans(mk, hk, x, mhk, gt_flip(~K, ~cmp, ~flip, x, hk, e2)))),
693 get.gt(~K, ~V, ~cmp, x, hk, hv, mh, hh, e2))))
694
695def rot_lo.double.get(
696 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
697 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
698 hl: O.OMap<K, V>, +x: K, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V,
699 +hh: O.OMap<K, V>, +khk: {cmp(k, hk) == LT{} : Cmp},
700 +h_l: {Laws.bounded(~K, ~V, ~cmp, hl, Some{k}, Some{hk}) == True{} : Bool}
701) -> {g(~K, ~V, ~cmp, O.OMap.rot_lo.double(K, V, k, v, lo, hk, hv, hl, hh), x)
702 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, O.OBin{0, hk, hv, hl, hh}}, x) : Maybe<&2, V>}:
703 match hl:
704 case O.OTip{}:
705 rot_lo.single.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lo, hk, hv,
706 O.OTip{}, hh, khk)
707 case O.OBin{s, +mk, +mv, +ml, +mh}:
708 rot_lo.double.get2(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lo, hk, hv,
709 mk, mv, ml, mh, hh,
710 lt_of(cmp(k, mk), bn.a(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l)),
711 lt_of(cmp(mk, hk), bn.b(~K, ~V, ~cmp, Some{k}, Some{hk}, mk, mv, ml, mh, h_l)))
712
713def rot_lo.pick.get(
714 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
715 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
716 single: Bool, +x: K, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V,
717 +hl: O.OMap<K, V>, +hh: O.OMap<K, V>, +khk: {cmp(k, hk) == LT{} : Cmp},
718 +h_l: {Laws.bounded(~K, ~V, ~cmp, hl, Some{k}, Some{hk}) == True{} : Bool}
719) -> {g(~K, ~V, ~cmp, O.OMap.rot_lo.pick(K, V, single, k, v, lo, hk, hv, hl, hh), x)
720 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, O.OBin{0, hk, hv, hl, hh}}, x) : Maybe<&2, V>}:
721 match single:
722 case True{}:
723 rot_lo.single.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lo, hk, hv,
724 hl, hh, khk)
725 case False{}:
726 rot_lo.double.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, hl, x, k, v, lo, hk, hv,
727 hh, khk, h_l)
728
729def rot_lo.get(
730 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
731 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
732 hi: O.OMap<K, V>, +ub: Maybe<&2, K>, +x: K, +k: K, +v: V, +lo: O.OMap<K, V>,
733 +eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
734) -> {g(~K, ~V, ~cmp, O.OMap.rot_lo(K, V, k, v, lo, hi), x)
735 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x) : Maybe<&2, V>}:
736 match hi:
737 case O.OTip{}:
738 {==}
739 case O.OBin{s, +hk, +hv, +hl, +hh}:
740 rot_lo.pick.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans,
741 U32.is_lt((O.OMap.size(K, V, hl) + 1 : U32),
742 (2 * (O.OMap.size(K, V, hh) + 1) : U32)),
743 x, k, v, lo, hk, hv, hl, hh,
744 lt_of(cmp(k, hk), bn.a(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh)),
745 bn.l(~K, ~V, ~cmp, Some{k}, ub, hk, hv, hl, hh, eh))
746
747def rot_hi.single.get(
748 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
749 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
750 +x: K, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>, +lh: O.OMap<K, V>,
751 +hi: O.OMap<K, V>, +lkk: {cmp(lk, k) == LT{} : Cmp}
752) -> {g(~K, ~V, ~cmp, O.OMap.bin(K, V, lk, lv, ll, O.OMap.bin(K, V, k, v, lh, hi)), x)
753 == g(~K, ~V, ~cmp, O.OBin{0, k, v, O.OBin{0, lk, lv, ll, lh}, hi}, x) : Maybe<&2, V>}:
754 +b = {O.OBin{0, k, v, lh, hi} : O.OMap<K, V>}
755 +l = {O.OBin{0, lk, lv, ll, b} : O.OMap<K, V>}
756 +ln = {O.OBin{0, lk, lv, ll, lh} : O.OMap<K, V>}
757 split(c => {g(~K, ~V, ~cmp, l, x) == getc(~K, ~V, ~cmp, c, x, v, ln, hi) : Maybe<&2, V>},
758 cmp(x, k),
759 e => split(c => {getc(~K, ~V, ~cmp, c, x, lv, ll, b)
760 == getc(~K, ~V, ~cmp, c, x, lv, ll, lh) : Maybe<&2, V>},
761 cmp(x, lk),
762 e2 => {==},
763 e2 => {==},
764 e2 => get.lt(~K, ~V, ~cmp, x, k, v, lh, hi, e)),
765 e => rw(K, y => {g(~K, ~V, ~cmp, l, y) == Some{v} : Maybe<&2, V>}, x, k, eq(x, k, e),
766 mtr(V, g(~K, ~V, ~cmp, l, k), g(~K, ~V, ~cmp, b, k), Some{v},
767 get.gt(~K, ~V, ~cmp, k, lk, lv, ll, b, gt_of_lt(~K, ~cmp, ~flip, lk, k, lkk)),
768 get.here(~K, ~V, ~cmp, ~refl, k, v, lh, hi))),
769 +e => mtr(V, g(~K, ~V, ~cmp, l, x), g(~K, ~V, ~cmp, b, x), g(~K, ~V, ~cmp, hi, x),
770 get.gt(~K, ~V, ~cmp, x, lk, lv, ll, b,
771 gt_of_lt(~K, ~cmp, ~flip, lk, x,
772 trans(lk, k, x, lkk, gt_flip(~K, ~cmp, ~flip, x, k, e)))),
773 get.gt(~K, ~V, ~cmp, x, k, v, lh, hi, e)))
774
775def rot_hi.double.get2(
776 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
777 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
778 +x: K, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>, +mk: K, +mv: V,
779 +ml: O.OMap<K, V>, +mh: O.OMap<K, V>, +hi: O.OMap<K, V>,
780 +lkm: {cmp(lk, mk) == LT{} : Cmp}, +mkk: {cmp(mk, k) == LT{} : Cmp}
781) -> {g(~K, ~V, ~cmp, O.OMap.bin(K, V, mk, mv, O.OMap.bin(K, V, lk, lv, ll, ml),
782 O.OMap.bin(K, V, k, v, mh, hi)), x)
783 == g(~K, ~V, ~cmp, O.OBin{0, k, v, O.OBin{0, lk, lv, ll, O.OBin{0, mk, mv, ml, mh}}, hi}, x)
784 : Maybe<&2, V>}:
785 +a = {O.OBin{0, lk, lv, ll, ml} : O.OMap<K, V>}
786 +b = {O.OBin{0, k, v, mh, hi} : O.OMap<K, V>}
787 +l = {O.OBin{0, mk, mv, a, b} : O.OMap<K, V>}
788 +m = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
789 +ln = {O.OBin{0, lk, lv, ll, m} : O.OMap<K, V>}
790 split(c => {g(~K, ~V, ~cmp, l, x) == getc(~K, ~V, ~cmp, c, x, v, ln, hi) : Maybe<&2, V>},
791 cmp(x, k),
792 +e => split(c => {g(~K, ~V, ~cmp, l, x) == getc(~K, ~V, ~cmp, c, x, lv, ll, m) : Maybe<&2, V>},
793 cmp(x, lk),
794 +e2 => mtr(V, g(~K, ~V, ~cmp, l, x), g(~K, ~V, ~cmp, a, x), g(~K, ~V, ~cmp, ll, x),
795 get.lt(~K, ~V, ~cmp, x, mk, mv, a, b, trans(x, lk, mk, e2, lkm)),
796 get.lt(~K, ~V, ~cmp, x, lk, lv, ll, ml, e2)),
797 e2 => rw(K, y => {g(~K, ~V, ~cmp, l, y) == Some{lv} : Maybe<&2, V>}, x, lk, eq(x, lk, e2),
798 mtr(V, g(~K, ~V, ~cmp, l, lk), g(~K, ~V, ~cmp, a, lk), Some{lv},
799 get.lt(~K, ~V, ~cmp, lk, mk, mv, a, b, lkm),
800 get.here(~K, ~V, ~cmp, ~refl, lk, lv, ll, ml))),
801 +e2 => split(c => {getc(~K, ~V, ~cmp, c, x, mv, a, b)
802 == getc(~K, ~V, ~cmp, c, x, mv, ml, mh) : Maybe<&2, V>},
803 cmp(x, mk),
804 e3 => get.gt(~K, ~V, ~cmp, x, lk, lv, ll, ml, e2),
805 e3 => {==},
806 e3 => get.lt(~K, ~V, ~cmp, x, k, v, mh, hi, e))),
807 e => rw(K, y => {g(~K, ~V, ~cmp, l, y) == Some{v} : Maybe<&2, V>}, x, k, eq(x, k, e),
808 mtr(V, g(~K, ~V, ~cmp, l, k), g(~K, ~V, ~cmp, b, k), Some{v},
809 get.gt(~K, ~V, ~cmp, k, mk, mv, a, b, gt_of_lt(~K, ~cmp, ~flip, mk, k, mkk)),
810 get.here(~K, ~V, ~cmp, ~refl, k, v, mh, hi))),
811 +e => mtr(V, g(~K, ~V, ~cmp, l, x), g(~K, ~V, ~cmp, b, x), g(~K, ~V, ~cmp, hi, x),
812 get.gt(~K, ~V, ~cmp, x, mk, mv, a, b,
813 gt_of_lt(~K, ~cmp, ~flip, mk, x,
814 trans(mk, k, x, mkk, gt_flip(~K, ~cmp, ~flip, x, k, e)))),
815 get.gt(~K, ~V, ~cmp, x, k, v, mh, hi, e)))
816
817def rot_hi.double.get(
818 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
819 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
820 lh: O.OMap<K, V>, +x: K, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>,
821 +hi: O.OMap<K, V>, +lkk: {cmp(lk, k) == LT{} : Cmp},
822 +l_h: {Laws.bounded(~K, ~V, ~cmp, lh, Some{lk}, Some{k}) == True{} : Bool}
823) -> {g(~K, ~V, ~cmp, O.OMap.rot_hi.double(K, V, k, v, lk, lv, ll, lh, hi), x)
824 == g(~K, ~V, ~cmp, O.OBin{0, k, v, O.OBin{0, lk, lv, ll, lh}, hi}, x) : Maybe<&2, V>}:
825 match lh:
826 case O.OTip{}:
827 rot_hi.single.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lk, lv, ll,
828 O.OTip{}, hi, lkk)
829 case O.OBin{s, +mk, +mv, +ml, +mh}:
830 rot_hi.double.get2(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lk, lv, ll,
831 mk, mv, ml, mh, hi,
832 lt_of(cmp(lk, mk), bn.a(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h)),
833 lt_of(cmp(mk, k), bn.b(~K, ~V, ~cmp, Some{lk}, Some{k}, mk, mv, ml, mh, l_h)))
834
835def rot_hi.pick.get(
836 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
837 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
838 single: Bool, +x: K, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>,
839 +lh: O.OMap<K, V>, +hi: O.OMap<K, V>, +lkk: {cmp(lk, k) == LT{} : Cmp},
840 +l_h: {Laws.bounded(~K, ~V, ~cmp, lh, Some{lk}, Some{k}) == True{} : Bool}
841) -> {g(~K, ~V, ~cmp, O.OMap.rot_hi.pick(K, V, single, k, v, lk, lv, ll, lh, hi), x)
842 == g(~K, ~V, ~cmp, O.OBin{0, k, v, O.OBin{0, lk, lv, ll, lh}, hi}, x) : Maybe<&2, V>}:
843 match single:
844 case True{}:
845 rot_hi.single.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, x, k, v, lk, lv, ll,
846 lh, hi, lkk)
847 case False{}:
848 rot_hi.double.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lh, x, k, v, lk, lv,
849 ll, hi, lkk, l_h)
850
851def rot_hi.get(
852 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
853 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
854 lo: O.OMap<K, V>, +lb: Maybe<&2, K>, +x: K, +k: K, +v: V, +hi: O.OMap<K, V>,
855 +el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool}
856) -> {g(~K, ~V, ~cmp, O.OMap.rot_hi(K, V, k, v, lo, hi), x)
857 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x) : Maybe<&2, V>}:
858 match lo:
859 case O.OTip{}:
860 {==}
861 case O.OBin{s, +lk, +lv, +ll, +lh}:
862 rot_hi.pick.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans,
863 U32.is_lt((O.OMap.size(K, V, lh) + 1 : U32),
864 (2 * (O.OMap.size(K, V, ll) + 1) : U32)),
865 x, k, v, lk, lv, ll, lh, hi,
866 lt_of(cmp(lk, k), bn.b(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el)),
867 bn.h(~K, ~V, ~cmp, lb, Some{k}, lk, lv, ll, lh, el))
868
869def balance.if.get(
870 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
871 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
872 heavy_hi: Bool, heavy_lo: Bool, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +x: K,
873 +k: K, +v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
874 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
875 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
876) -> {g(~K, ~V, ~cmp, O.OMap.balance.if(K, V, heavy_hi, heavy_lo, k, v, lo, hi), x)
877 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x) : Maybe<&2, V>}:
878 match heavy_hi heavy_lo:
879 case True{} _:
880 rot_lo.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, hi, ub, x, k, v, lo, eh)
881 case False{} True{}:
882 rot_hi.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lo, lb, x, k, v, hi, el)
883 case False{} False{}:
884 {==}
885
886def balance.get(
887 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
888 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
889 +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +x: K, +k: K, +v: V, +lo: O.OMap<K, V>,
890 +hi: O.OMap<K, V>,
891 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{k}) == True{} : Bool},
892 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
893) -> {g(~K, ~V, ~cmp, O.OMap.balance(K, V, k, v, lo, hi), x)
894 == g(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, x) : Maybe<&2, V>}:
895 +wl = (O.OMap.size(K, V, lo) + 1 : U32)
896 +wh = (O.OMap.size(K, V, hi) + 1 : U32)
897 balance.if.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, U32.is_gt(wh, (3 * wl : U32)),
898 U32.is_gt(wl, (3 * wh : U32)), lb, ub, x, k, v, lo, hi, el, eh)
899
900def get_put_same(
901 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
902 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
903 t: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
904 +bt: {Laws.bounded(~K, ~V, ~cmp, t, lb, ub) == True{} : Bool},
905 +ea: {Laws.above(~K, ~cmp, lb, k) == True{} : Bool},
906 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool}
907) -> {g(~K, ~V, ~cmp, O.OMap.put(~K, ~V, ~cmp, t, k, v), k) == Some{v} : Maybe<&2, V>}:
908 match t:
909 case O.OTip{}:
910 get.here(~K, ~V, ~cmp, ~refl, k, v, O.OTip{}, O.OTip{})
911 case O.OBin{+s, +key, +val, +lo, +hi}:
912 +b_l = bn.l(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
913 +b_h = bn.h(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
914 +plo = O.OMap.put(~K, ~V, ~cmp, lo, k, v)
915 +phi = O.OMap.put(~K, ~V, ~cmp, hi, k, v)
916 cmp.split(O.OMap<K, V>, Maybe<&2, V>, y => g(~K, ~V, ~cmp, y, k), Some{v},
917 cmp(k, key),
918 u => O.OMap.balance(K, V, key, val, O.OMap.put(~K, ~V, ~cmp, lo, k, v), hi),
919 u => O.OBin{s, key, v, lo, hi},
920 u => O.OMap.balance(K, V, key, val, lo, O.OMap.put(~K, ~V, ~cmp, hi, k, v)),
921 +e => mtr(V, g(~K, ~V, ~cmp, O.OMap.balance(K, V, key, val, plo, hi), k),
922 g(~K, ~V, ~cmp, O.OBin{0, key, val, plo, hi}, k), Some{v},
923 balance.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lb, ub, k, key, val, plo, hi,
924 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, lo, lb, Some{key}, k, v, b_l, ea,
925 lt_true(cmp(k, key), e)),
926 b_h),
927 mtr(V, g(~K, ~V, ~cmp, O.OBin{0, key, val, plo, hi}, k), g(~K, ~V, ~cmp, plo, k),
928 Some{v},
929 get.lt(~K, ~V, ~cmp, k, key, val, plo, hi, e),
930 get_put_same(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lo, lb, Some{key}, k, v,
931 b_l, ea, lt_true(cmp(k, key), e)))),
932 e => rw(Cmp, c => {getc(~K, ~V, ~cmp, c, k, v, lo, hi) == Some{v} : Maybe<&2, V>},
933 cmp(k, key), EQ{}, e, {==}),
934 +e => mtr(V, g(~K, ~V, ~cmp, O.OMap.balance(K, V, key, val, lo, phi), k),
935 g(~K, ~V, ~cmp, O.OBin{0, key, val, lo, phi}, k), Some{v},
936 balance.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lb, ub, k, key, val, lo, phi,
937 b_l,
938 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, hi, Some{key}, ub, k, v, b_h,
939 lt_true(cmp(key, k), gt_flip(~K, ~cmp, ~flip, k, key, e)), eb)),
940 mtr(V, g(~K, ~V, ~cmp, O.OBin{0, key, val, lo, phi}, k), g(~K, ~V, ~cmp, phi, k),
941 Some{v},
942 get.gt(~K, ~V, ~cmp, k, key, val, lo, phi, e),
943 get_put_same(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, hi, Some{key}, ub, k, v,
944 b_h, lt_true(cmp(key, k), gt_flip(~K, ~cmp, ~flip, k, key, e)), eb))))
945
946def Laws.omap_get_put_same(K, V, cmp, refl, eq, flip, trans, m, tree, k, v):
947 get_put_same(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, m, None{}, None{}, k, v, tree,
948 {==}, {==})
949
950def neq_false(c: Cmp, ne: {c != EQ{} : Cmp}) -> {Cmp.is_eq(c) == False{} : Bool}:
951 match c:
952 case LT{}:
953 {==}
954 case EQ{}:
955 Empty.absurd({Cmp.is_eq(EQ{}) == False{} : Bool}, ne({==}))
956 case GT{}:
957 {==}
958
959def ne_absurd(
960 -A: Type, -c: Cmp, nef: {Cmp.is_eq(c) == False{} : Bool}, e: {c == EQ{} : Cmp}
961) -> A:
962 +tf = Equal.trans(Bool, True{}, Cmp.is_eq(c), False{},
963 Equal.sym(Bool, Cmp.is_eq(c), True{}, Equal.cong(Cmp, Bool, x => Cmp.is_eq(x), c, EQ{}, e)),
964 nef)
965 Empty.absurd(A, MBool.false_ne_true()(Equal.sym(Bool, True{}, False{}, tf)))
966
967def eq_flip(
968 ~K: Data, ~cmp: K -> K -> Cmp, ~flip: Flip(~K, ~cmp), +x: K, +y: K,
969 e: {cmp(x, y) == EQ{} : Cmp}
970) -> {cmp(y, x) == EQ{} : Cmp}:
971 Equal.trans(Cmp, cmp(y, x), Laws.flip(cmp(x, y)), EQ{}, flip(x, y),
972 Equal.cong(Cmp, Cmp, c => Laws.flip(c), cmp(x, y), EQ{}, e))
973
974def get_put_other(
975 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~refl: Refl(~K, ~cmp), ~eq: Eq(~K, ~cmp),
976 ~flip: Flip(~K, ~cmp), ~trans: Trans(~K, ~cmp),
977 t: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k2: K, +k: K, +v: V,
978 +bt: {Laws.bounded(~K, ~V, ~cmp, t, lb, ub) == True{} : Bool},
979 +ea: {Laws.above(~K, ~cmp, lb, k2) == True{} : Bool},
980 +eb: {Laws.below(~K, ~cmp, ub, k2) == True{} : Bool},
981 +nef: {Cmp.is_eq(cmp(k2, k)) == False{} : Bool}
982) -> {g(~K, ~V, ~cmp, O.OMap.put(~K, ~V, ~cmp, t, k2, v), k)
983 == g(~K, ~V, ~cmp, t, k) : Maybe<&2, V>}:
984 match t:
985 case O.OTip{}:
986 split(c => {getc(~K, ~V, ~cmp, c, k, v, O.OTip{}, O.OTip{}) == None{} : Maybe<&2, V>},
987 cmp(k, k2),
988 e => {==},
989 e => ne_absurd({Some{v} == None{} : Maybe<&2, V>}, cmp(k2, k), nef,
990 eq_flip(~K, ~cmp, ~flip, k, k2, e)),
991 e => {==})
992 case O.OBin{+s, +key, +val, +lo, +hi}:
993 +b_l = bn.l(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
994 +b_h = bn.h(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
995 +plo = O.OMap.put(~K, ~V, ~cmp, lo, k2, v)
996 +phi = O.OMap.put(~K, ~V, ~cmp, hi, k2, v)
997 +old = {O.OBin{s, key, val, lo, hi} : O.OMap<K, V>}
998 cmp.split(O.OMap<K, V>, Maybe<&2, V>, y => g(~K, ~V, ~cmp, y, k),
999 g(~K, ~V, ~cmp, old, k), cmp(k2, key),
1000 u => O.OMap.balance(K, V, key, val, O.OMap.put(~K, ~V, ~cmp, lo, k2, v), hi),
1001 u => O.OBin{s, key, v, lo, hi},
1002 u => O.OMap.balance(K, V, key, val, lo, O.OMap.put(~K, ~V, ~cmp, hi, k2, v)),
1003 +e => mtr(V, g(~K, ~V, ~cmp, O.OMap.balance(K, V, key, val, plo, hi), k),
1004 g(~K, ~V, ~cmp, O.OBin{0, key, val, plo, hi}, k), g(~K, ~V, ~cmp, old, k),
1005 balance.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lb, ub, k, key, val, plo, hi,
1006 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, lo, lb, Some{key}, k2, v, b_l, ea,
1007 lt_true(cmp(k2, key), e)),
1008 b_h),
1009 split(c => {getc(~K, ~V, ~cmp, c, k, val, plo, hi)
1010 == getc(~K, ~V, ~cmp, c, k, val, lo, hi) : Maybe<&2, V>},
1011 cmp(k, key),
1012 e2 => get_put_other(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lo, lb, Some{key},
1013 k2, k, v, b_l, ea, lt_true(cmp(k2, key), e), nef),
1014 e2 => {==},
1015 e2 => {==})),
1016 +e => split(c => {getc(~K, ~V, ~cmp, c, k, v, lo, hi)
1017 == getc(~K, ~V, ~cmp, c, k, val, lo, hi) : Maybe<&2, V>},
1018 cmp(k, key),
1019 e2 => {==},
1020 e2 => ne_absurd({Some{v} == Some{val} : Maybe<&2, V>}, cmp(k2, k), nef,
1021 rw(K, y => {cmp(y, k) == EQ{} : Cmp}, k2, key, eq(k2, key, e),
1022 eq_flip(~K, ~cmp, ~flip, k, key, e2))),
1023 e2 => {==}),
1024 +e => mtr(V, g(~K, ~V, ~cmp, O.OMap.balance(K, V, key, val, lo, phi), k),
1025 g(~K, ~V, ~cmp, O.OBin{0, key, val, lo, phi}, k), g(~K, ~V, ~cmp, old, k),
1026 balance.get(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, lb, ub, k, key, val, lo, phi,
1027 b_l,
1028 put.bnd(~K, ~V, ~cmp, ~flip, ~trans, hi, Some{key}, ub, k2, v, b_h,
1029 lt_true(cmp(key, k2), gt_flip(~K, ~cmp, ~flip, k2, key, e)), eb)),
1030 split(c => {getc(~K, ~V, ~cmp, c, k, val, lo, phi)
1031 == getc(~K, ~V, ~cmp, c, k, val, lo, hi) : Maybe<&2, V>},
1032 cmp(k, key),
1033 e2 => {==},
1034 e2 => {==},
1035 e2 => get_put_other(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, hi, Some{key}, ub,
1036 k2, k, v, b_h, lt_true(cmp(key, k2), gt_flip(~K, ~cmp, ~flip, k2, key, e)),
1037 eb, nef))))
1038
1039def Laws.omap_get_put_other_key(K, V, cmp, refl, eq, flip, trans, m, tree, k2, k, ne, v):
1040 get_put_other(~K, ~V, ~cmp, ~refl, ~eq, ~flip, ~trans, m, None{}, None{}, k2, k, v, tree,
1041 {==}, {==}, neq_false(cmp(k2, k), ne))
1042
1043# A tree bounded above by a is bounded above by anything above a.
1044def weaken_hi(
1045 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1046 t: O.OMap<K, V>, +lb: Maybe<&2, K>, +a: K, +ub: Maybe<&2, K>,
1047 +e: {Laws.bounded(~K, ~V, ~cmp, t, lb, Some{a}) == True{} : Bool},
1048 +eab: {Laws.below(~K, ~cmp, ub, a) == True{} : Bool}
1049) -> {Laws.bounded(~K, ~V, ~cmp, t, lb, ub) == True{} : Bool}:
1050 match t:
1051 case O.OTip{}:
1052 {==}
1053 case O.OBin{s, +k, +v, +lo, +hi}:
1054 bn.i(~K, ~V, ~cmp, lb, ub, k, v, lo, hi,
1055 bn.a(~K, ~V, ~cmp, lb, Some{a}, k, v, lo, hi, e),
1056 below_trans(~K, ~cmp, ~trans, ub, k, a,
1057 bn.b(~K, ~V, ~cmp, lb, Some{a}, k, v, lo, hi, e), eab),
1058 bn.l(~K, ~V, ~cmp, lb, Some{a}, k, v, lo, hi, e),
1059 weaken_hi(~K, ~V, ~cmp, ~trans, hi, Some{k}, a, ub,
1060 bn.h(~K, ~V, ~cmp, lb, Some{a}, k, v, lo, hi, e), eab))
1061
1062# What pop_min answers: its key lies between the bounds, and the rest lies above it.
1063def PM(
1064 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
1065 r: K & V & O.OMap<K, V>
1066) -> Bool:
1067 (+mk, mv, t) = r
1068 Bool.and(Bool.and(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, ub, mk)),
1069 Laws.bounded(~K, ~V, ~cmp, t, Some{mk}, ub))
1070
1071def pm.fin.bnd.go(
1072 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1073 +mk: K, +mv: V, +t: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K,
1074 +v: V, +hi: O.OMap<K, V>,
1075 +ih: {PM(~K, ~V, ~cmp, lb, Some{k}, {(mk, mv, t) : K & V & O.OMap<K, V>}) == True{} : Bool},
1076 +eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
1077 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
1078) -> {PM(~K, ~V, ~cmp, lb, ub,
1079 O.OMap.pop_min.fin(K, V, k, v, hi, {(mk, mv, t) : K & V & O.OMap<K, V>})) == True{} : Bool}:
1080 +ab = Bool.and(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, Some{k}, mk))
1081 +c = Laws.bounded(~K, ~V, ~cmp, t, Some{mk}, Some{k})
1082 +eab = MBool.eq_true_of_and_left(ab, c, ih)
1083 +mkk = MBool.eq_true_of_and_right(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, Some{k}, mk), eab)
1084 MBool.and_eq_true(Bool.and(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, ub, mk)), Laws.bounded(~K, ~V, ~cmp, O.OMap.balance(K, V, k, v, t, hi), Some{mk}, ub), MBool.and_eq_true(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, ub, mk), MBool.eq_true_of_and_left(Laws.above(~K, ~cmp, lb, mk), Laws.below(~K, ~cmp, Some{k}, mk), eab), below_trans(~K, ~cmp, ~trans, ub, mk, k, mkk, eb)), balance.bnd(~K, ~V, ~cmp, ~trans, Some{mk}, ub, k, v, t, hi, mkk, eb,
1085 MBool.eq_true_of_and_right(ab, c, ih), eh))
1086
1087# Workaround for https://github.com/bendlang/bend/issues/1077: bind the tuple without +.
1088def pm.fin.bnd(
1089 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1090 r: K & V & O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
1091 +hi: O.OMap<K, V>,
1092 ih: {PM(~K, ~V, ~cmp, lb, Some{k}, r) == True{} : Bool},
1093 eb: {Laws.below(~K, ~cmp, ub, k) == True{} : Bool},
1094 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub) == True{} : Bool}
1095) -> {PM(~K, ~V, ~cmp, lb, ub, O.OMap.pop_min.fin(K, V, k, v, hi, r)) == True{} : Bool}:
1096 (mk, rest) = r
1097 (mv, t) = rest
1098 pm.fin.bnd.go(~K, ~V, ~cmp, ~trans, mk, mv, t, lb, ub, k, v, hi, ih, eb, eh)
1099
1100def pm.bnd(
1101 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1102 lo: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K, +v: V,
1103 +hi: O.OMap<K, V>,
1104 +e: {Laws.bounded(~K, ~V, ~cmp, O.OBin{0, k, v, lo, hi}, lb, ub) == True{} : Bool}
1105) -> {PM(~K, ~V, ~cmp, lb, ub, O.OMap.pop_min(K, V, lo, k, v, hi)) == True{} : Bool}:
1106 match lo:
1107 case O.OTip{}:
1108 MBool.and_eq_true(Bool.and(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k)), Laws.bounded(~K, ~V, ~cmp, hi, Some{k}, ub), MBool.and_eq_true(Laws.above(~K, ~cmp, lb, k), Laws.below(~K, ~cmp, ub, k), bn.a(~K, ~V, ~cmp, lb, ub, k, v, O.OTip{}, hi, e), bn.b(~K, ~V, ~cmp, lb, ub, k, v, O.OTip{}, hi, e)), bn.h(~K, ~V, ~cmp, lb, ub, k, v, O.OTip{}, hi, e))
1109 case O.OBin{s, +lk, +lv, +ll, +lh}:
1110 +lo = {O.OBin{0, lk, lv, ll, lh} : O.OMap<K, V>}
1111 pm.fin.bnd(~K, ~V, ~cmp, ~trans, O.OMap.pop_min(K, V, ll, lk, lv, lh), lb, ub, k, v, hi,
1112 pm.bnd(~K, ~V, ~cmp, ~trans, ll, lb, Some{k}, lk, lv, lh,
1113 bn.l(~K, ~V, ~cmp, lb, ub, k, v, lo, hi, e)),
1114 bn.b(~K, ~V, ~cmp, lb, ub, k, v, lo, hi, e),
1115 bn.h(~K, ~V, ~cmp, lb, ub, k, v, lo, hi, e))
1116
1117def glue.fin.bnd.go(
1118 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1119 +mk: K, +mv: V, +t: O.OMap<K, V>, +lo: O.OMap<K, V>, +lb: Maybe<&2, K>,
1120 +ub: Maybe<&2, K>, +key: K,
1121 eka: {Laws.above(~K, ~cmp, lb, key) == True{} : Bool},
1122 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{key}) == True{} : Bool},
1123 +pmr: {PM(~K, ~V, ~cmp, Some{key}, ub, {(mk, mv, t) : K & V & O.OMap<K, V>}) == True{} : Bool}
1124) -> {Laws.bounded(~K, ~V, ~cmp,
1125 O.OMap.glue.fin(K, V, lo, {(mk, mv, t) : K & V & O.OMap<K, V>}), lb, ub) == True{} : Bool}:
1126 +ab = Bool.and(Laws.above(~K, ~cmp, Some{key}, mk), Laws.below(~K, ~cmp, ub, mk))
1127 +c = Laws.bounded(~K, ~V, ~cmp, t, Some{mk}, ub)
1128 +eab = MBool.eq_true_of_and_left(ab, c, pmr)
1129 +km = MBool.eq_true_of_and_left(Laws.above(~K, ~cmp, Some{key}, mk), Laws.below(~K, ~cmp, ub, mk), eab)
1130 balance.bnd(~K, ~V, ~cmp, ~trans, lb, ub, mk, mv, lo, t,
1131 above_trans(~K, ~cmp, ~trans, lb, key, mk, eka, km),
1132 MBool.eq_true_of_and_right(Laws.above(~K, ~cmp, Some{key}, mk), Laws.below(~K, ~cmp, ub, mk), eab),
1133 weaken_hi(~K, ~V, ~cmp, ~trans, lo, lb, key, Some{mk}, el, km),
1134 MBool.eq_true_of_and_right(ab, c, pmr))
1135
1136# Workaround for https://github.com/bendlang/bend/issues/1077: bind the tuple without +.
1137def glue.fin.bnd(
1138 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1139 r: K & V & O.OMap<K, V>, +lo: O.OMap<K, V>, +lb: Maybe<&2, K>,
1140 +ub: Maybe<&2, K>, +key: K,
1141 eka: {Laws.above(~K, ~cmp, lb, key) == True{} : Bool},
1142 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{key}) == True{} : Bool},
1143 pmr: {PM(~K, ~V, ~cmp, Some{key}, ub, r) == True{} : Bool}
1144) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.glue.fin(K, V, lo, r), lb, ub) == True{} : Bool}:
1145 (mk, rest) = r
1146 (mv, t) = rest
1147 glue.fin.bnd.go(~K, ~V, ~cmp, ~trans, mk, mv, t, lo, lb, ub, key, eka, el, pmr)
1148
1149def glue.bnd(
1150 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1151 hi: O.OMap<K, V>, +lo: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>,
1152 +key: K,
1153 eka: {Laws.above(~K, ~cmp, lb, key) == True{} : Bool},
1154 ekb: {Laws.below(~K, ~cmp, ub, key) == True{} : Bool},
1155 el: {Laws.bounded(~K, ~V, ~cmp, lo, lb, Some{key}) == True{} : Bool},
1156 eh: {Laws.bounded(~K, ~V, ~cmp, hi, Some{key}, ub) == True{} : Bool}
1157) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.glue(K, V, lo, hi), lb, ub) == True{} : Bool}:
1158 match hi:
1159 case O.OTip{}:
1160 weaken_hi(~K, ~V, ~cmp, ~trans, lo, lb, key, ub, el, ekb)
1161 case O.OBin{s, +k, +v, +hl, +hh}:
1162 glue.fin.bnd(~K, ~V, ~cmp, ~trans, O.OMap.pop_min(K, V, hl, k, v, hh), lo, lb, ub, key,
1163 eka, el, pm.bnd(~K, ~V, ~cmp, ~trans, hl, Some{key}, ub, k, v, hh, eh))
1164
1165def del.bnd(
1166 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, ~trans: Trans(~K, ~cmp),
1167 t: O.OMap<K, V>, +lb: Maybe<&2, K>, +ub: Maybe<&2, K>, +k: K,
1168 +bt: {Laws.bounded(~K, ~V, ~cmp, t, lb, ub) == True{} : Bool}
1169) -> {Laws.bounded(~K, ~V, ~cmp, O.OMap.del(~K, ~V, ~cmp, t, k), lb, ub) == True{} : Bool}:
1170 match t:
1171 case O.OTip{}:
1172 {==}
1173 case O.OBin{+s, +key, +val, +lo, +hi}:
1174 +b_a = bn.a(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
1175 +b_b = bn.b(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
1176 +b_l = bn.l(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
1177 +b_h = bn.h(~K, ~V, ~cmp, lb, ub, key, val, lo, hi, bt)
1178 cmp.split(O.OMap<K, V>, Bool, y => Laws.bounded(~K, ~V, ~cmp, y, lb, ub), True{},
1179 cmp(k, key),
1180 u => O.OMap.balance(K, V, key, val, O.OMap.del(~K, ~V, ~cmp, lo, k), hi),
1181 u => O.OMap.glue(K, V, lo, hi),
1182 u => O.OMap.balance(K, V, key, val, lo, O.OMap.del(~K, ~V, ~cmp, hi, k)),
1183 e => balance.bnd(~K, ~V, ~cmp, ~trans, lb, ub, key, val,
1184 O.OMap.del(~K, ~V, ~cmp, lo, k), hi, b_a, b_b,
1185 del.bnd(~K, ~V, ~cmp, ~trans, lo, lb, Some{key}, k, b_l), b_h),
1186 e => glue.bnd(~K, ~V, ~cmp, ~trans, hi, lo, lb, ub, key, b_a, b_b, b_l, b_h),
1187 e => balance.bnd(~K, ~V, ~cmp, ~trans, lb, ub, key, val, lo,
1188 O.OMap.del(~K, ~V, ~cmp, hi, k), b_a, b_b, b_l,
1189 del.bnd(~K, ~V, ~cmp, ~trans, hi, Some{key}, ub, k, b_h)))
1190
1191def Laws.omap_del_searchtree(K, V, cmp, refl, eq, flip, trans, m, tree, k):
1192 del.bnd(~K, ~V, ~cmp, ~trans, m, None{}, None{}, k, tree)
1193
1194def Laws.omap_new_weight_balanced(K, V):
1195 {==}
1196
1197# --- weight balance -------------------------------------------------------------
1198
1199def W(-K: Data, -V: Data, t: O.OMap<K, V>) -> Nat:
1200 Laws.omap_weight(K, V, t)
1201
1202def WB(-K: Data, -V: Data, t: O.OMap<K, V>) -> Bool:
1203 Laws.weight_balanced(K, V, t)
1204
1205# t is balanced and its weight is within one of n.
1206def PW(-K: Data, -V: Data, +n: Nat, +t: O.OMap<K, V>) -> Bool:
1207 Bool.and(WB(K, V, t), Ord.near(n, W(K, V, t)))
1208
1209def PMW(-K: Data, -V: Data, +n: Nat, r: K & V & O.OMap<K, V>) -> Bool:
1210 (mk, mv, t) = r
1211 PW(K, V, n, t)
1212
1213def pos_add(a: Nat, +b: Nat, e: Ord.LE(1n, a)) -> Ord.LE(1n, Nat.add(a, b)):
1214 match a:
1215 case 0n:
1216 Empty.absurd(Ord.LE(1n, b), MBool.false_ne_true()(e))
1217 case 1n+p:
1218 MNat.zero_le(Nat.add(p, b))
1219
1220def w_pos(-K: Data, -V: Data, t: O.OMap<K, V>) -> Ord.LE(1n, W(K, V, t)):
1221 match t:
1222 case O.OTip{}:
1223 {==}
1224 case O.OBin{s, k, v, +lo, +hi}:
1225 pos_add(W(K, V, lo), W(K, V, hi), w_pos(K, V, lo))
1226
1227def wb.ok(
1228 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1229 e: {WB(K, V, O.OBin{0, k, v, lo, hi}) == True{} : Bool}
1230) -> {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool}:
1231 c3.a(Laws.weight_ok(W(K, V, lo), W(K, V, hi)), WB(K, V, lo), WB(K, V, hi), e)
1232
1233def wb.l(
1234 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1235 e: {WB(K, V, O.OBin{0, k, v, lo, hi}) == True{} : Bool}
1236) -> {WB(K, V, lo) == True{} : Bool}:
1237 c3.b(Laws.weight_ok(W(K, V, lo), W(K, V, hi)), WB(K, V, lo), WB(K, V, hi), e)
1238
1239def wb.h(
1240 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1241 e: {WB(K, V, O.OBin{0, k, v, lo, hi}) == True{} : Bool}
1242) -> {WB(K, V, hi) == True{} : Bool}:
1243 c3.c(Laws.weight_ok(W(K, V, lo), W(K, V, hi)), WB(K, V, lo), WB(K, V, hi), e)
1244
1245def wb.i(
1246 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1247 eo: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1248 el: {WB(K, V, lo) == True{} : Bool}, eh: {WB(K, V, hi) == True{} : Bool}
1249) -> {WB(K, V, O.OBin{0, k, v, lo, hi}) == True{} : Bool}:
1250 c3.i(Laws.weight_ok(W(K, V, lo), W(K, V, hi)), WB(K, V, lo), WB(K, V, hi), eo, el, eh)
1251
1252# Rotations toward lo, after hi grew or lo shrank by one.
1253def rls.wb(
1254 -K: Data, -V: Data, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V,
1255 +hl: O.OMap<K, V>, +hh: O.OMap<K, V>,
1256 wbl: {WB(K, V, lo) == True{} : Bool},
1257 +wbh: {WB(K, V, O.OBin{0, hk, hv, hl, hh}) == True{} : Bool},
1258 +heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, lo)), Nat.add(W(K, V, hl), W(K, V, hh))),
1259 +alm: Ord.LE(Nat.add(W(K, V, hl), W(K, V, hh)), Nat.add(3n, Nat.mul(3n, W(K, V, lo)))),
1260 +hs: Ord.LE(1n+W(K, V, hl), Nat.mul(2n, W(K, V, hh)))
1261) -> {WB(K, V, O.OMap.bin(K, V, hk, hv, O.OMap.bin(K, V, k, v, lo, hl), hh)) == True{} : Bool}:
1262 +l = W(K, V, lo)
1263 +a = W(K, V, hl)
1264 +b = W(K, V, hh)
1265 +okh = wb.ok(K, V, hk, hv, hl, hh, wbh)
1266 +h1 = Ord.wok_r(a, b, okh)
1267 +h2 = Ord.wok_l(a, b, okh)
1268 +pl = w_pos(K, V, lo)
1269 +pa = w_pos(K, V, hl)
1270 +pb = w_pos(K, V, hh)
1271 wb.i(K, V, hk, hv, O.OMap.bin(K, V, k, v, lo, hl), hh,
1272 Ord.rls.w1(l, a, b, h1, h2, heavy, alm, hs, pl, pa, pb),
1273 wb.i(K, V, k, v, lo, hl, Ord.rls.w0(l, a, b, h1, h2, heavy, alm, hs, pl, pa, pb), wbl,
1274 wb.l(K, V, hk, hv, hl, hh, wbh)),
1275 wb.h(K, V, hk, hv, hl, hh, wbh))
1276
1277def rld.wb(
1278 -K: Data, -V: Data, hl: O.OMap<K, V>, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V,
1279 +hh: O.OMap<K, V>,
1280 wbl: {WB(K, V, lo) == True{} : Bool},
1281 +wbh: {WB(K, V, O.OBin{0, hk, hv, hl, hh}) == True{} : Bool},
1282 +heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, lo)), Nat.add(W(K, V, hl), W(K, V, hh))),
1283 +alm: Ord.LE(Nat.add(W(K, V, hl), W(K, V, hh)), Nat.add(3n, Nat.mul(3n, W(K, V, lo)))),
1284 +hd: Ord.LE(Nat.mul(2n, W(K, V, hh)), W(K, V, hl))
1285) -> {WB(K, V, O.OMap.rot_lo.double(K, V, k, v, lo, hk, hv, hl, hh)) == True{} : Bool}:
1286 match hl:
1287 case O.OTip{}:
1288 Empty.absurd({WB(K, V, O.OMap.rot_lo.double(K, V, k, v, lo, hk, hv, O.OTip{}, hh)) == True{} : Bool}, Ord.dtip(W(K, V, hh), hd, w_pos(K, V, hh)))
1289 case O.OBin{s, +mk, +mv, +ml, +mh}:
1290 +hl = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
1291 +l = W(K, V, lo)
1292 +x = W(K, V, ml)
1293 +y = W(K, V, mh)
1294 +b = W(K, V, hh)
1295 +okh = wb.ok(K, V, hk, hv, hl, hh, wbh)
1296 +h1 = Ord.wok_r(Nat.add(x, y), b, okh)
1297 +h2 = Ord.wok_l(Nat.add(x, y), b, okh)
1298 +wbm = wb.l(K, V, hk, hv, hl, hh, wbh)
1299 +okm = wb.ok(K, V, mk, mv, ml, mh, wbm)
1300 +h5 = Ord.wok_r(x, y, okm)
1301 +h6 = Ord.wok_l(x, y, okm)
1302 +pl = w_pos(K, V, lo)
1303 +px = w_pos(K, V, ml)
1304 +py = w_pos(K, V, mh)
1305 +pb = w_pos(K, V, hh)
1306 wb.i(K, V, mk, mv, O.OMap.bin(K, V, k, v, lo, ml), O.OMap.bin(K, V, hk, hv, mh, hh),
1307 Ord.rld.w0(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1308 wb.i(K, V, k, v, lo, ml, Ord.rld.w1(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1309 wbl, wb.l(K, V, mk, mv, ml, mh, wbm)),
1310 wb.i(K, V, hk, hv, mh, hh, Ord.rld.w2(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1311 wb.h(K, V, mk, mv, ml, mh, wbm), wb.h(K, V, hk, hv, hl, hh, wbh)))
1312
1313def rlp.wb(
1314 -K: Data, -V: Data, single: Bool, +k: K, +v: V, +lo: O.OMap<K, V>, +hk: K, +hv: V,
1315 +hl: O.OMap<K, V>, +hh: O.OMap<K, V>,
1316 es: {Nat.is_lt(W(K, V, hl), Nat.mul(2n, W(K, V, hh))) == single : Bool},
1317 wbl: {WB(K, V, lo) == True{} : Bool},
1318 wbh: {WB(K, V, O.OBin{0, hk, hv, hl, hh}) == True{} : Bool},
1319 heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, lo)), Nat.add(W(K, V, hl), W(K, V, hh))),
1320 alm: Ord.LE(Nat.add(W(K, V, hl), W(K, V, hh)), Nat.add(3n, Nat.mul(3n, W(K, V, lo))))
1321) -> {WB(K, V, O.OMap.rot_lo.pick(K, V, single, k, v, lo, hk, hv, hl, hh)) == True{} : Bool}:
1322 match single:
1323 case True{}:
1324 rls.wb(K, V, k, v, lo, hk, hv, hl, hh, wbl, wbh, heavy, alm,
1325 MNat.succ_le_of_lt(W(K, V, hl), Nat.mul(2n, W(K, V, hh)), es))
1326 case False{}:
1327 rld.wb(K, V, hl, k, v, lo, hk, hv, hh, wbl, wbh, heavy, alm,
1328 MNat.le_of_not_lt(W(K, V, hl), Nat.mul(2n, W(K, V, hh)), es))
1329
1330def rl.wb(
1331 -K: Data, -V: Data, hi: O.OMap<K, V>, +k: K, +v: V, +lo: O.OMap<K, V>,
1332 wbl: {WB(K, V, lo) == True{} : Bool}, +wbh: {WB(K, V, hi) == True{} : Bool},
1333 heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, lo)), W(K, V, hi)),
1334 alm: Ord.LE(W(K, V, hi), Nat.add(3n, Nat.mul(3n, W(K, V, lo))))
1335) -> {WB(K, V, Laws.g_rot_lo(K, V, k, v, lo, hi)) == True{} : Bool}:
1336 match hi:
1337 case O.OTip{}:
1338 Empty.absurd({WB(K, V, Laws.g_rot_lo(K, V, k, v, lo, O.OTip{})) == True{} : Bool}, Ord.tiph(W(K, V, lo), heavy, w_pos(K, V, lo)))
1339 case O.OBin{s, +hk, +hv, +hl, +hh}:
1340 rlp.wb(K, V, Nat.is_lt(W(K, V, hl), Nat.mul(2n, W(K, V, hh))), k, v, lo, hk, hv, hl, hh,
1341 {==}, wbl, wbh, heavy, alm)
1342
1343# Rotations toward hi, after lo grew or hi shrank by one.
1344def rhs.wb(
1345 -K: Data, -V: Data, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>,
1346 +lh: O.OMap<K, V>, +hi: O.OMap<K, V>,
1347 +wbl: {WB(K, V, O.OBin{0, lk, lv, ll, lh}) == True{} : Bool},
1348 wbh: {WB(K, V, hi) == True{} : Bool},
1349 +heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, hi)), Nat.add(W(K, V, ll), W(K, V, lh))),
1350 +alm: Ord.LE(Nat.add(W(K, V, ll), W(K, V, lh)), Nat.add(3n, Nat.mul(3n, W(K, V, hi)))),
1351 +hs: Ord.LE(1n+W(K, V, lh), Nat.mul(2n, W(K, V, ll)))
1352) -> {WB(K, V, O.OMap.bin(K, V, lk, lv, ll, O.OMap.bin(K, V, k, v, lh, hi))) == True{} : Bool}:
1353 +l = W(K, V, hi)
1354 +a = W(K, V, lh)
1355 +b = W(K, V, ll)
1356 +okl = wb.ok(K, V, lk, lv, ll, lh, wbl)
1357 +h1 = Ord.wok_l(b, a, okl)
1358 +h2 = Ord.wok_r(b, a, okl)
1359 +pl = w_pos(K, V, hi)
1360 +pa = w_pos(K, V, lh)
1361 +pb = w_pos(K, V, ll)
1362 wb.i(K, V, lk, lv, ll, O.OMap.bin(K, V, k, v, lh, hi),
1363 Ord.rhs.w0(l, a, b, h1, h2, heavy, alm, hs, pl, pa, pb),
1364 wb.l(K, V, lk, lv, ll, lh, wbl),
1365 wb.i(K, V, k, v, lh, hi, Ord.rhs.w1(l, a, b, h1, h2, heavy, alm, hs, pl, pa, pb),
1366 wb.h(K, V, lk, lv, ll, lh, wbl), wbh))
1367
1368def rhd.wb(
1369 -K: Data, -V: Data, lh: O.OMap<K, V>, +k: K, +v: V, +lk: K, +lv: V,
1370 +ll: O.OMap<K, V>, +hi: O.OMap<K, V>,
1371 +wbl: {WB(K, V, O.OBin{0, lk, lv, ll, lh}) == True{} : Bool},
1372 wbh: {WB(K, V, hi) == True{} : Bool},
1373 +heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, hi)), Nat.add(W(K, V, ll), W(K, V, lh))),
1374 +alm: Ord.LE(Nat.add(W(K, V, ll), W(K, V, lh)), Nat.add(3n, Nat.mul(3n, W(K, V, hi)))),
1375 +hd: Ord.LE(Nat.mul(2n, W(K, V, ll)), W(K, V, lh))
1376) -> {WB(K, V, O.OMap.rot_hi.double(K, V, k, v, lk, lv, ll, lh, hi)) == True{} : Bool}:
1377 match lh:
1378 case O.OTip{}:
1379 Empty.absurd({WB(K, V, O.OMap.rot_hi.double(K, V, k, v, lk, lv, ll, O.OTip{}, hi)) == True{} : Bool}, Ord.dtip(W(K, V, ll), hd, w_pos(K, V, ll)))
1380 case O.OBin{s, +mk, +mv, +ml, +mh}:
1381 +lh = {O.OBin{0, mk, mv, ml, mh} : O.OMap<K, V>}
1382 +l = W(K, V, hi)
1383 +x = W(K, V, mh)
1384 +y = W(K, V, ml)
1385 +b = W(K, V, ll)
1386 +okl = wb.ok(K, V, lk, lv, ll, lh, wbl)
1387 +h1 = Ord.wok_l(b, Nat.add(y, x), okl)
1388 +h2 = Ord.wok_r(b, Nat.add(y, x), okl)
1389 +wbm = wb.h(K, V, lk, lv, ll, lh, wbl)
1390 +okm = wb.ok(K, V, mk, mv, ml, mh, wbm)
1391 +h5 = Ord.wok_l(y, x, okm)
1392 +h6 = Ord.wok_r(y, x, okm)
1393 +pl = w_pos(K, V, hi)
1394 +px = w_pos(K, V, mh)
1395 +py = w_pos(K, V, ml)
1396 +pb = w_pos(K, V, ll)
1397 wb.i(K, V, mk, mv, O.OMap.bin(K, V, lk, lv, ll, ml), O.OMap.bin(K, V, k, v, mh, hi),
1398 Ord.rhd.w0(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1399 wb.i(K, V, lk, lv, ll, ml, Ord.rhd.w1(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1400 wb.l(K, V, lk, lv, ll, lh, wbl), wb.l(K, V, mk, mv, ml, mh, wbm)),
1401 wb.i(K, V, k, v, mh, hi, Ord.rhd.w2(l, x, y, b, h1, h2, heavy, alm, hd, h5, h6, pl, px, py, pb),
1402 wb.h(K, V, mk, mv, ml, mh, wbm), wbh))
1403
1404def rhp.wb(
1405 -K: Data, -V: Data, single: Bool, +k: K, +v: V, +lk: K, +lv: V, +ll: O.OMap<K, V>,
1406 +lh: O.OMap<K, V>, +hi: O.OMap<K, V>,
1407 es: {Nat.is_lt(W(K, V, lh), Nat.mul(2n, W(K, V, ll))) == single : Bool},
1408 wbl: {WB(K, V, O.OBin{0, lk, lv, ll, lh}) == True{} : Bool},
1409 wbh: {WB(K, V, hi) == True{} : Bool},
1410 heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, hi)), Nat.add(W(K, V, ll), W(K, V, lh))),
1411 alm: Ord.LE(Nat.add(W(K, V, ll), W(K, V, lh)), Nat.add(3n, Nat.mul(3n, W(K, V, hi))))
1412) -> {WB(K, V, O.OMap.rot_hi.pick(K, V, single, k, v, lk, lv, ll, lh, hi)) == True{} : Bool}:
1413 match single:
1414 case True{}:
1415 rhs.wb(K, V, k, v, lk, lv, ll, lh, hi, wbl, wbh, heavy, alm,
1416 MNat.succ_le_of_lt(W(K, V, lh), Nat.mul(2n, W(K, V, ll)), es))
1417 case False{}:
1418 rhd.wb(K, V, lh, k, v, lk, lv, ll, hi, wbl, wbh, heavy, alm,
1419 MNat.le_of_not_lt(W(K, V, lh), Nat.mul(2n, W(K, V, ll)), es))
1420
1421def rh.wb(
1422 -K: Data, -V: Data, lo: O.OMap<K, V>, +k: K, +v: V, +hi: O.OMap<K, V>,
1423 +wbl: {WB(K, V, lo) == True{} : Bool}, wbh: {WB(K, V, hi) == True{} : Bool},
1424 heavy: Ord.LE(1n+Nat.mul(3n, W(K, V, hi)), W(K, V, lo)),
1425 alm: Ord.LE(W(K, V, lo), Nat.add(3n, Nat.mul(3n, W(K, V, hi))))
1426) -> {WB(K, V, Laws.g_rot_hi(K, V, k, v, lo, hi)) == True{} : Bool}:
1427 match lo:
1428 case O.OTip{}:
1429 Empty.absurd({WB(K, V, Laws.g_rot_hi(K, V, k, v, O.OTip{}, hi)) == True{} : Bool}, Ord.tiph(W(K, V, hi), heavy, w_pos(K, V, hi)))
1430 case O.OBin{s, +lk, +lv, +ll, +lh}:
1431 rhp.wb(K, V, Nat.is_lt(W(K, V, lh), Nat.mul(2n, W(K, V, ll))), k, v, lk, lv, ll, lh, hi,
1432 {==}, wbl, wbh, heavy, alm)
1433
1434def bif.wb(
1435 -K: Data, -V: Data, heavy_hi: Bool, heavy_lo: Bool, +k: K, +v: V,
1436 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1437 eh: {Laws.g_heavy_hi(K, V, lo, hi) == heavy_hi : Bool},
1438 el: {Laws.g_heavy_lo(K, V, lo, hi) == heavy_lo : Bool},
1439 wbl: {WB(K, V, lo) == True{} : Bool}, wbh: {WB(K, V, hi) == True{} : Bool},
1440 +alm: {Ord.alm(W(K, V, lo), W(K, V, hi)) == True{} : Bool}
1441) -> {WB(K, V, Laws.g_balance.if(K, V, heavy_hi, heavy_lo, k, v, lo, hi)) == True{} : Bool}:
1442 match heavy_hi heavy_lo:
1443 case True{} _:
1444 rl.wb(K, V, hi, k, v, lo, wbl, wbh,
1445 Ord.gt_le(W(K, V, hi), Nat.mul(3n, W(K, V, lo)), eh), MBool.eq_true_of_and_left(Nat.is_le(W(K, V, hi), Nat.add(3n, Nat.mul(3n, W(K, V, lo)))), Nat.is_le(W(K, V, lo), Nat.add(3n, Nat.mul(3n, W(K, V, hi)))), alm))
1446 case False{} True{}:
1447 rh.wb(K, V, lo, k, v, hi, wbl, wbh,
1448 Ord.gt_le(W(K, V, lo), Nat.mul(3n, W(K, V, hi)), el), MBool.eq_true_of_and_right(Nat.is_le(W(K, V, hi), Nat.add(3n, Nat.mul(3n, W(K, V, lo)))), Nat.is_le(W(K, V, lo), Nat.add(3n, Nat.mul(3n, W(K, V, hi)))), alm))
1449 case False{} False{}:
1450 wb.i(K, V, k, v, lo, hi,
1451 MBool.and_eq_true(Nat.is_le(W(K, V, hi), Nat.mul(3n, W(K, V, lo))), Nat.is_le(W(K, V, lo), Nat.mul(3n, W(K, V, hi))), Ord.ngt_le(W(K, V, hi), Nat.mul(3n, W(K, V, lo)), eh), Ord.ngt_le(W(K, V, lo), Nat.mul(3n, W(K, V, hi)), el)),
1452 wbl, wbh)
1453
1454def bal.wb(
1455 -K: Data, -V: Data, +k: K, +v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1456 wbl: {WB(K, V, lo) == True{} : Bool}, wbh: {WB(K, V, hi) == True{} : Bool},
1457 alm: {Ord.alm(W(K, V, lo), W(K, V, hi)) == True{} : Bool}
1458) -> {WB(K, V, Laws.g_balance(K, V, k, v, lo, hi)) == True{} : Bool}:
1459 bif.wb(K, V, Laws.g_heavy_hi(K, V, lo, hi), Laws.g_heavy_lo(K, V, lo, hi), k, v, lo, hi,
1460 {==}, {==}, wbl, wbh, alm)
1461
1462# Balancing keeps the weight.
1463def rlp.w(
1464 -K: Data, -V: Data, single: Bool, -k: K, -v: V, +lo: O.OMap<K, V>, -hk: K, -hv: V,
1465 hl: O.OMap<K, V>, +hh: O.OMap<K, V>
1466) -> {Nat.add(W(K, V, lo), Nat.add(W(K, V, hl), W(K, V, hh)))
1467 == W(K, V, O.OMap.rot_lo.pick(K, V, single, k, v, lo, hk, hv, hl, hh)) : Nat}:
1468 match single hl:
1469 case True{} +hl:
1470 Ord.sy(Nat.add(Nat.add(W(K, V, lo), W(K, V, hl)), W(K, V, hh)),
1471 Nat.add(W(K, V, lo), Nat.add(W(K, V, hl), W(K, V, hh))),
1472 MNat.add_assoc(W(K, V, lo), W(K, V, hl), W(K, V, hh)))
1473 case False{} O.OTip{}:
1474 Ord.sy(Nat.add(Nat.add(W(K, V, lo), 1n), W(K, V, hh)), Nat.add(W(K, V, lo), Nat.add(1n, W(K, V, hh))),
1475 MNat.add_assoc(W(K, V, lo), 1n, W(K, V, hh)))
1476 case False{} O.OBin{s, mk, mv, +ml, +mh}:
1477 +l = W(K, V, lo)
1478 +x = W(K, V, ml)
1479 +y = W(K, V, mh)
1480 +b = W(K, V, hh)
1481 Ord.tr(Nat.add(l, Nat.add(Nat.add(x, y), b)), Nat.add(l, Nat.add(x, Nat.add(y, b))),
1482 Nat.add(Nat.add(l, x), Nat.add(y, b)),
1483 Ord.cong_add(l, l, Nat.add(Nat.add(x, y), b), Nat.add(x, Nat.add(y, b)), {==}, MNat.add_assoc(x, y, b)),
1484 Ord.sy(Nat.add(Nat.add(l, x), Nat.add(y, b)), Nat.add(l, Nat.add(x, Nat.add(y, b))),
1485 MNat.add_assoc(l, x, Nat.add(y, b))))
1486
1487def rhp.w(
1488 -K: Data, -V: Data, single: Bool, -k: K, -v: V, -lk: K, -lv: V, +ll: O.OMap<K, V>,
1489 lh: O.OMap<K, V>, +hi: O.OMap<K, V>
1490) -> {Nat.add(Nat.add(W(K, V, ll), W(K, V, lh)), W(K, V, hi))
1491 == W(K, V, O.OMap.rot_hi.pick(K, V, single, k, v, lk, lv, ll, lh, hi)) : Nat}:
1492 match single lh:
1493 case True{} +lh:
1494 MNat.add_assoc(W(K, V, ll), W(K, V, lh), W(K, V, hi))
1495 case False{} O.OTip{}:
1496 MNat.add_assoc(W(K, V, ll), 1n, W(K, V, hi))
1497 case False{} O.OBin{s, mk, mv, +ml, +mh}:
1498 +l = W(K, V, hi)
1499 +x = W(K, V, mh)
1500 +y = W(K, V, ml)
1501 +b = W(K, V, ll)
1502 Ord.tr(Nat.add(Nat.add(b, Nat.add(y, x)), l), Nat.add(Nat.add(Nat.add(b, y), x), l),
1503 Nat.add(Nat.add(b, y), Nat.add(x, l)),
1504 Ord.cong_add(Nat.add(b, Nat.add(y, x)), Nat.add(Nat.add(b, y), x), l, l,
1505 Ord.sy(Nat.add(Nat.add(b, y), x), Nat.add(b, Nat.add(y, x)), MNat.add_assoc(b, y, x)), {==}),
1506 MNat.add_assoc(Nat.add(b, y), x, l))
1507
1508def rl.w(-K: Data, -V: Data, hi: O.OMap<K, V>, -k: K, -v: V, +lo: O.OMap<K, V>)
1509 -> {Nat.add(W(K, V, lo), W(K, V, hi)) == W(K, V, Laws.g_rot_lo(K, V, k, v, lo, hi)) : Nat}:
1510 match hi:
1511 case O.OTip{}:
1512 {==}
1513 case O.OBin{s, hk, hv, +hl, +hh}:
1514 rlp.w(K, V, Nat.is_lt(W(K, V, hl), Nat.mul(2n, W(K, V, hh))), k, v, lo, hk, hv, hl, hh)
1515
1516def rh.w(-K: Data, -V: Data, lo: O.OMap<K, V>, -k: K, -v: V, +hi: O.OMap<K, V>)
1517 -> {Nat.add(W(K, V, lo), W(K, V, hi)) == W(K, V, Laws.g_rot_hi(K, V, k, v, lo, hi)) : Nat}:
1518 match lo:
1519 case O.OTip{}:
1520 {==}
1521 case O.OBin{s, lk, lv, +ll, +lh}:
1522 rhp.w(K, V, Nat.is_lt(W(K, V, lh), Nat.mul(2n, W(K, V, ll))), k, v, lk, lv, ll, lh, hi)
1523
1524def bif.w(
1525 -K: Data, -V: Data, heavy_hi: Bool, heavy_lo: Bool, -k: K, -v: V,
1526 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>
1527) -> {Nat.add(W(K, V, lo), W(K, V, hi))
1528 == W(K, V, Laws.g_balance.if(K, V, heavy_hi, heavy_lo, k, v, lo, hi)) : Nat}:
1529 match heavy_hi heavy_lo:
1530 case True{} _:
1531 rl.w(K, V, hi, k, v, lo)
1532 case False{} True{}:
1533 rh.w(K, V, lo, k, v, hi)
1534 case False{} False{}:
1535 {==}
1536
1537def bal.w(-K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>)
1538 -> {Nat.add(W(K, V, lo), W(K, V, hi)) == W(K, V, Laws.g_balance(K, V, k, v, lo, hi)) : Nat}:
1539 bif.w(K, V, Laws.g_heavy_hi(K, V, lo, hi), Laws.g_heavy_lo(K, V, lo, hi), k, v, lo, hi)
1540
1541def bal.lo.near(
1542 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +lo2: O.OMap<K, V>, +hi: O.OMap<K, V>,
1543 n1: Ord.LE(W(K, V, lo), 1n+W(K, V, lo2)), n2: Ord.LE(W(K, V, lo2), 1n+W(K, V, lo))
1544) -> {Ord.near(Nat.add(W(K, V, lo), W(K, V, hi)), W(K, V, Laws.g_balance(K, V, k, v, lo2, hi))) == True{} : Bool}:
1545 %bal.w(K, V, k, v, lo2, hi) : {Ord.near(Nat.add(W(K, V, lo), W(K, V, hi)), _) == True{} : Bool}
1546 Ord.nearlo.w0(W(K, V, lo), W(K, V, lo2), W(K, V, hi), n1, n2)
1547
1548def bal.hi.near(
1549 -K: Data, -V: Data, -k: K, -v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>, +hi2: O.OMap<K, V>,
1550 n1: Ord.LE(W(K, V, hi), 1n+W(K, V, hi2)), n2: Ord.LE(W(K, V, hi2), 1n+W(K, V, hi))
1551) -> {Ord.near(Nat.add(W(K, V, lo), W(K, V, hi)), W(K, V, Laws.g_balance(K, V, k, v, lo, hi2))) == True{} : Bool}:
1552 %bal.w(K, V, k, v, lo, hi2) : {Ord.near(Nat.add(W(K, V, lo), W(K, V, hi)), _) == True{} : Bool}
1553 Ord.nearhi.w0(W(K, V, lo), W(K, V, hi), W(K, V, hi2), n1, n2)
1554
1555# lo became lo2, one lighter or heavier at most: rebalance the node.
1556def bal.lo(
1557 -K: Data, -V: Data, +k: K, +v: V, +lo: O.OMap<K, V>, +lo2: O.OMap<K, V>, +hi: O.OMap<K, V>,
1558 +ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1559 wbh: {WB(K, V, hi) == True{} : Bool},
1560 +pw: {PW(K, V, W(K, V, lo), lo2) == True{} : Bool}
1561) -> {PW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_balance(K, V, k, v, lo2, hi)) == True{} : Bool}:
1562 +a = W(K, V, lo)
1563 +a2 = W(K, V, lo2)
1564 +c = W(K, V, hi)
1565 +nr = MBool.eq_true_of_and_right(WB(K, V, lo2), Ord.near(a, a2), pw)
1566 +n1 = MBool.eq_true_of_and_left(Nat.is_le(a, 1n+a2), Nat.is_le(a2, 1n+a), nr)
1567 +n2 = MBool.eq_true_of_and_right(Nat.is_le(a, 1n+a2), Nat.is_le(a2, 1n+a), nr)
1568 MBool.and_eq_true(WB(K, V, Laws.g_balance(K, V, k, v, lo2, hi)), Ord.near(Nat.add(a, c), W(K, V, Laws.g_balance(K, V, k, v, lo2, hi))), bal.wb(K, V, k, v, lo2, hi, MBool.eq_true_of_and_left(WB(K, V, lo2), Ord.near(a, a2), pw), wbh,
1569 Ord.almlo.w0(a, c, a2, Ord.wok_l(a, c, ok), Ord.wok_r(a, c, ok), n1, n2)), bal.lo.near(K, V, k, v, lo, lo2, hi, n1, n2))
1570
1571def bal.hi(
1572 -K: Data, -V: Data, +k: K, +v: V, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>, +hi2: O.OMap<K, V>,
1573 +ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1574 wbl: {WB(K, V, lo) == True{} : Bool},
1575 +pw: {PW(K, V, W(K, V, hi), hi2) == True{} : Bool}
1576) -> {PW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_balance(K, V, k, v, lo, hi2)) == True{} : Bool}:
1577 +a = W(K, V, lo)
1578 +c = W(K, V, hi)
1579 +c2 = W(K, V, hi2)
1580 +nr = MBool.eq_true_of_and_right(WB(K, V, hi2), Ord.near(c, c2), pw)
1581 +n1 = MBool.eq_true_of_and_left(Nat.is_le(c, 1n+c2), Nat.is_le(c2, 1n+c), nr)
1582 +n2 = MBool.eq_true_of_and_right(Nat.is_le(c, 1n+c2), Nat.is_le(c2, 1n+c), nr)
1583 MBool.and_eq_true(WB(K, V, Laws.g_balance(K, V, k, v, lo, hi2)), Ord.near(Nat.add(a, c), W(K, V, Laws.g_balance(K, V, k, v, lo, hi2))), bal.wb(K, V, k, v, lo, hi2, wbl, MBool.eq_true_of_and_left(WB(K, V, hi2), Ord.near(c, c2), pw),
1584 Ord.almhi.w0(a, c, c2, Ord.wok_l(a, c, ok), Ord.wok_r(a, c, ok), n1, n2)), bal.hi.near(K, V, k, v, lo, hi, hi2, n1, n2))
1585
1586def put.wb(
1587 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, t: O.OMap<K, V>, +k: K, +v: V,
1588 +wb: {WB(K, V, t) == True{} : Bool}
1589) -> {PW(K, V, W(K, V, t), Laws.g_put(~K, ~V, ~cmp, t, k, v)) == True{} : Bool}:
1590 match t:
1591 case O.OTip{}:
1592 {==}
1593 case O.OBin{+s, +key, +val, +lo, +hi}:
1594 +ok = wb.ok(K, V, key, val, lo, hi, wb)
1595 +wbl = wb.l(K, V, key, val, lo, hi, wb)
1596 +wbh = wb.h(K, V, key, val, lo, hi, wb)
1597 +n = Nat.add(W(K, V, lo), W(K, V, hi))
1598 cmp.split(O.OMap<K, V>, Bool, x => PW(K, V, n, x), True{}, cmp(k, key),
1599 u => Laws.g_balance(K, V, key, val, Laws.g_put(~K, ~V, ~cmp, lo, k, v), hi),
1600 u => O.OBin{s, key, v, lo, hi},
1601 u => Laws.g_balance(K, V, key, val, lo, Laws.g_put(~K, ~V, ~cmp, hi, k, v)),
1602 e => bal.lo(K, V, key, val, lo, Laws.g_put(~K, ~V, ~cmp, lo, k, v), hi, ok, wbh,
1603 put.wb(~K, ~V, ~cmp, lo, k, v, wbl)),
1604 e => MBool.and_eq_true(WB(K, V, O.OBin{s, key, v, lo, hi}), Ord.near(n, n), wb, Ord.nearrf.w0(n)),
1605 e => bal.hi(K, V, key, val, lo, hi, Laws.g_put(~K, ~V, ~cmp, hi, k, v), ok, wbl,
1606 put.wb(~K, ~V, ~cmp, hi, k, v, wbh)))
1607
1608def Laws.omap_put_weight_balanced(K, V, cmp, m, wb, k, v):
1609 MBool.eq_true_of_and_left(WB(K, V, Laws.g_put(~K, ~V, ~cmp, m, k, v)), Ord.near(W(K, V, m), W(K, V, Laws.g_put(~K, ~V, ~cmp, m, k, v))), put.wb(~K, ~V, ~cmp, m, k, v, wb))
1610
1611def pm.fin.wb.go(
1612 -K: Data, -V: Data, +mk: K, +mv: V, +t: O.OMap<K, V>, +k: K, +v: V,
1613 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1614 ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1615 wbh: {WB(K, V, hi) == True{} : Bool},
1616 ih: {PMW(K, V, W(K, V, lo), {(mk, mv, t) : K & V & O.OMap<K, V>}) == True{} : Bool}
1617) -> {PMW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)),
1618 Laws.g_pop_min.fin(K, V, k, v, hi, {(mk, mv, t) : K & V & O.OMap<K, V>})) == True{} : Bool}:
1619 bal.lo(K, V, k, v, lo, t, hi, ok, wbh, ih)
1620
1621# Workaround for https://github.com/bendlang/bend/issues/1077: bind the tuple without +.
1622def pm.fin.wb(
1623 -K: Data, -V: Data, r: K & V & O.OMap<K, V>, +k: K, +v: V,
1624 +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1625 ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1626 wbh: {WB(K, V, hi) == True{} : Bool},
1627 ih: {PMW(K, V, W(K, V, lo), r) == True{} : Bool}
1628) -> {PMW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_pop_min.fin(K, V, k, v, hi, r)) == True{} : Bool}:
1629 (mk, rest) = r
1630 (mv, t) = rest
1631 pm.fin.wb.go(K, V, mk, mv, t, k, v, lo, hi, ok, wbh, ih)
1632
1633def pm.wb(
1634 -K: Data, -V: Data, lo: O.OMap<K, V>, +k: K, +v: V, +hi: O.OMap<K, V>,
1635 +e: {WB(K, V, O.OBin{0, k, v, lo, hi}) == True{} : Bool}
1636) -> {PMW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_pop_min(K, V, lo, k, v, hi)) == True{} : Bool}:
1637 match lo:
1638 case O.OTip{}:
1639 MBool.and_eq_true(WB(K, V, hi), Ord.near(1n+W(K, V, hi), W(K, V, hi)), wb.h(K, V, k, v, O.OTip{}, hi, e), Ord.nearpm.w0(W(K, V, hi)))
1640 case O.OBin{s, +lk, +lv, +ll, +lh}:
1641 +lo = {O.OBin{0, lk, lv, ll, lh} : O.OMap<K, V>}
1642 pm.fin.wb(K, V, Laws.g_pop_min(K, V, ll, lk, lv, lh), k, v, lo, hi,
1643 wb.ok(K, V, k, v, lo, hi, e), wb.h(K, V, k, v, lo, hi, e),
1644 pm.wb(K, V, ll, lk, lv, lh, wb.l(K, V, k, v, lo, hi, e)))
1645
1646def glue.fin.wb.go(
1647 -K: Data, -V: Data, +mk: K, +mv: V, +t: O.OMap<K, V>, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1648 ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1649 wbl: {WB(K, V, lo) == True{} : Bool},
1650 pmr: {PMW(K, V, W(K, V, hi), {(mk, mv, t) : K & V & O.OMap<K, V>}) == True{} : Bool}
1651) -> {PW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)),
1652 Laws.g_glue.fin(K, V, lo, {(mk, mv, t) : K & V & O.OMap<K, V>})) == True{} : Bool}:
1653 bal.hi(K, V, mk, mv, lo, hi, t, ok, wbl, pmr)
1654
1655# Workaround for https://github.com/bendlang/bend/issues/1077: bind the tuple without +.
1656def glue.fin.wb(
1657 -K: Data, -V: Data, r: K & V & O.OMap<K, V>, +lo: O.OMap<K, V>, +hi: O.OMap<K, V>,
1658 ok: {Laws.weight_ok(W(K, V, lo), W(K, V, hi)) == True{} : Bool},
1659 wbl: {WB(K, V, lo) == True{} : Bool},
1660 pmr: {PMW(K, V, W(K, V, hi), r) == True{} : Bool}
1661) -> {PW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_glue.fin(K, V, lo, r)) == True{} : Bool}:
1662 (mk, rest) = r
1663 (mv, t) = rest
1664 glue.fin.wb.go(K, V, mk, mv, t, lo, hi, ok, wbl, pmr)
1665
1666def glue.wb(
1667 -K: Data, -V: Data, hi: O.OMap<K, V>, +lo: O.OMap<K, V>, -key: K, -val: V,
1668 +e: {WB(K, V, O.OBin{0, key, val, lo, hi}) == True{} : Bool}
1669) -> {PW(K, V, Nat.add(W(K, V, lo), W(K, V, hi)), Laws.g_glue(K, V, lo, hi)) == True{} : Bool}:
1670 match hi:
1671 case O.OTip{}:
1672 MBool.and_eq_true(WB(K, V, lo), Ord.near(Nat.add(W(K, V, lo), 1n), W(K, V, lo)), wb.l(K, V, key, val, lo, O.OTip{}, e), Ord.neargt.w0(W(K, V, lo)))
1673 case O.OBin{s, +k, +v, +hl, +hh}:
1674 +hi = {O.OBin{0, k, v, hl, hh} : O.OMap<K, V>}
1675 glue.fin.wb(K, V, Laws.g_pop_min(K, V, hl, k, v, hh), lo, hi,
1676 wb.ok(K, V, key, val, lo, hi, e), wb.l(K, V, key, val, lo, hi, e),
1677 pm.wb(K, V, hl, k, v, hh, wb.h(K, V, key, val, lo, hi, e)))
1678
1679def del.wb(
1680 ~K: Data, ~V: Data, ~cmp: K -> K -> Cmp, t: O.OMap<K, V>, +k: K,
1681 +wb: {WB(K, V, t) == True{} : Bool}
1682) -> {PW(K, V, W(K, V, t), Laws.g_del(~K, ~V, ~cmp, t, k)) == True{} : Bool}:
1683 match t:
1684 case O.OTip{}:
1685 {==}
1686 case O.OBin{+s, +key, +val, +lo, +hi}:
1687 +ok = wb.ok(K, V, key, val, lo, hi, wb)
1688 +wbl = wb.l(K, V, key, val, lo, hi, wb)
1689 +wbh = wb.h(K, V, key, val, lo, hi, wb)
1690 +n = Nat.add(W(K, V, lo), W(K, V, hi))
1691 cmp.split(O.OMap<K, V>, Bool, x => PW(K, V, n, x), True{}, cmp(k, key),
1692 u => Laws.g_balance(K, V, key, val, Laws.g_del(~K, ~V, ~cmp, lo, k), hi),
1693 u => Laws.g_glue(K, V, lo, hi),
1694 u => Laws.g_balance(K, V, key, val, lo, Laws.g_del(~K, ~V, ~cmp, hi, k)),
1695 e => bal.lo(K, V, key, val, lo, Laws.g_del(~K, ~V, ~cmp, lo, k), hi, ok, wbh,
1696 del.wb(~K, ~V, ~cmp, lo, k, wbl)),
1697 e => glue.wb(K, V, hi, lo, key, val, wb),
1698 e => bal.hi(K, V, key, val, lo, hi, Laws.g_del(~K, ~V, ~cmp, hi, k), ok, wbl,
1699 del.wb(~K, ~V, ~cmp, hi, k, wbh)))
1700
1701def Laws.omap_del_weight_balanced(K, V, cmp, m, wb, k):
1702 MBool.eq_true_of_and_left(WB(K, V, Laws.g_del(~K, ~V, ~cmp, m, k)), Ord.near(W(K, V, m), W(K, V, Laws.g_del(~K, ~V, ~cmp, m, k))), del.wb(~K, ~V, ~cmp, m, k, wb))
1703
1704def Laws.omap_g_put_matches():
1705 {==}
1706
1707def Laws.omap_g_del_matches():
1708 {==}
1709
1710def Laws.hmap_get_put():
1711 {==}
1712
1713def Laws.hmap_get_put_other():
1714 {==}
1715
1716def Laws.hmap_collision():
1717 {==}
1718
1719def Laws.hmap_replace_collision():
1720 {==}
1721
1722def Laws.hmap_high_bit():
1723 {==}
1724
1725def Laws.hmap_missing_collision():
1726 {==}
1727
1728# --- hmap ------------------------------------------------------------------------
1729
1730def h.sb(-a: Bool, -b: Bool, e: {a == b : Bool}) -> {b == a : Bool}:
1731 Equal.sym(Bool, a, b, e)
1732
1733def h.tf(-A: Type, -b: Bool, et: {b == True{} : Bool}, ef: {b == False{} : Bool}) -> A:
1734 Empty.absurd(A, MBool.false_ne_true()(Equal.trans(Bool, False{}, b, True{}, Equal.sym(Bool, b, False{}, ef), et)))
1735
1736def h.isS(-V: Data, m: Maybe<&2, V>) -> Type:
1737 match m:
1738 case None{}:
1739 Empty
1740 case Some{x}:
1741 Unit
1742
1743def h.some_none.e(-V: Data, -x: V, e: {Some{x} == None{} : Maybe<&2, V>}) -> Empty:
1744 %e : h.isS(V, _)
1745 Unit{}
1746
1747def h.some_none(-A: Type, -V: Data, -x: V, e: {Some{x} == None{} : Maybe<&2, V>}) -> A:
1748 Empty.absurd(A, h.some_none.e(V, x, e))
1749
1750def h.none_some(-A: Type, -V: Data, -x: V, e: {None{} == Some{x} : Maybe<&2, V>}) -> A:
1751 Empty.absurd(A, h.some_none.e(V, x, Equal.sym(Maybe<&2, V>, None{}, Some{x}, e)))
1752
1753# U32 equality is Word equality, so is_eq is reflexive and sound.
1754def h.wcmp_refl(n: Nat, w: Word(n)) -> {Word.cmp(n, w, w) == EQ{} : Cmp}:
1755 match n:
1756 case 0n:
1757 {==}
1758 case 1n+p:
1759 match w:
1760 case WCon{+b, +t}:
1761 %Equal.sym(Cmp, Word.cmp(p, t, t), EQ{}, h.wcmp_refl(p, t)) : {Word.cmp.fin(b, b, _) == EQ{} : Cmp}
1762 MBool.cmp_refl(b)
1763
1764def h.u_refl(x: U32) -> {U32.is_eq(x, x) == True{} : Bool}:
1765 match x:
1766 case U32{+w}:
1767 %Equal.sym(Cmp, Word.cmp(32n, w, w), EQ{}, h.wcmp_refl(32n, w)) : {Cmp.is_eq(_) == True{} : Bool}
1768 {==}
1769
1770def h.fin_eq(t: Cmp, -x: Bool, -y: Bool, e: {Cmp.is_eq(Word.cmp.fin(x, y, t)) == True{} : Bool})
1771 -> {Cmp.is_eq(t) == True{} : Bool}:
1772 match t:
1773 case LT{}:
1774 Empty.absurd({Cmp.is_eq(LT{}) == True{} : Bool}, MBool.false_ne_true()(e))
1775 case EQ{}:
1776 {==}
1777 case GT{}:
1778 Empty.absurd({Cmp.is_eq(GT{}) == True{} : Bool}, MBool.false_ne_true()(e))
1779
1780def h.fin_hd(t: Cmp, x: Bool, y: Bool, e: {Cmp.is_eq(Word.cmp.fin(x, y, t)) == True{} : Bool})
1781 -> {x == y : Bool}:
1782 match t:
1783 case LT{}:
1784 Empty.absurd({x == y : Bool}, MBool.false_ne_true()(e))
1785 case EQ{}:
1786 match x y:
1787 case False{} False{}:
1788 {==}
1789 case False{} True{}:
1790 Empty.absurd({False{} == True{} : Bool}, MBool.false_ne_true()(e))
1791 case True{} False{}:
1792 Empty.absurd({True{} == False{} : Bool}, MBool.false_ne_true()(e))
1793 case True{} True{}:
1794 {==}
1795 case GT{}:
1796 Empty.absurd({x == y : Bool}, MBool.false_ne_true()(e))
1797
1798def h.wcmp_sound(+n: Nat, a: Word(n), b: Word(n), +e: {Cmp.is_eq(Word.cmp(n, a, b)) == True{} : Bool})
1799 -> {a == b : Word(n)}:
1800 match n:
1801 case 0n:
1802 match a b:
1803 case WNil{} WNil{}:
1804 {==}
1805 case 1n+p:
1806 match a b:
1807 case WCon{+x, +at} WCon{+y, +bt}:
1808 +e1 = h.fin_hd(Word.cmp(p, at, bt), x, y, e)
1809 +e2 = h.wcmp_sound(p, at, bt, h.fin_eq(Word.cmp(p, at, bt), x, y, e))
1810 %e1 : {WCon{x, at} == WCon{_, bt} : Word(1n+p)}
1811 %e2 : {WCon{x, at} == WCon{x, _} : Word(1n+p)}
1812 {==}
1813
1814def h.u_sound(a: U32, b: U32, e: {U32.is_eq(a, b) == True{} : Bool}) -> {a == b : U32}:
1815 match a b:
1816 case U32{+x} U32{+y}:
1817 %h.wcmp_sound(32n, x, y, e) : {U32{x} == U32{_} : U32}
1818 {==}
1819
1820# A mask with at most one set bit routes every hash to one of two sides.
1821def h.isz(n: Nat, w: Word(n)) -> Bool:
1822 match n:
1823 case 0n:
1824 True{}
1825 case 1n+p:
1826 match w:
1827 case WCon{b, t}:
1828 Bool.not(b) && h.isz(p, t)
1829
1830def h.at1(n: Nat, w: Word(n)) -> Bool:
1831 match n:
1832 case 0n:
1833 True{}
1834 case 1n+p:
1835 match w:
1836 case WCon{b, t}:
1837 match b:
1838 case True{}:
1839 h.isz(p, t)
1840 case False{}:
1841 h.at1(p, t)
1842
1843def h.onebit(m: U32) -> Bool:
1844 match m:
1845 case U32{w}:
1846 h.at1(32n, w)
1847
1848def h.and_z(+n: Nat, x: Word(n), m: Word(n), e: {h.isz(n, m) == True{} : Bool})
1849 -> {Word.and(n, x, m) == Word.zero(n) : Word(n)}:
1850 match n:
1851 case 0n:
1852 match x m:
1853 case WNil{} WNil{}:
1854 {==}
1855 case 1n+p:
1856 match x m:
1857 case WCon{+a, +xt} WCon{True{}, +mt}:
1858 Empty.absurd({Word.and(1n+p, WCon{a, xt}, WCon{True{}, mt}) == Word.zero(1n+p) : Word(1n+p)}, MBool.false_ne_true()(e))
1859 case WCon{True{}, +xt} WCon{False{}, +mt}:
1860 Equal.cong(Word(p), Word(1n+p), w => WCon{False{}, w}, Word.and(p, xt, mt), Word.zero(p),
1861 h.and_z(p, xt, mt, e))
1862 case WCon{False{}, +xt} WCon{False{}, +mt}:
1863 Equal.cong(Word(p), Word(1n+p), w => WCon{False{}, w}, Word.and(p, xt, mt), Word.zero(p),
1864 h.and_z(p, xt, mt, e))
1865
1866def h.zc(+n: Nat, +x: Word(n), +m: Word(n), +e: {h.isz(n, m) == True{} : Bool})
1867 -> {Word.cmp(n, Word.and(n, x, m), Word.zero(n)) == EQ{} : Cmp}:
1868 %Equal.sym(Word(n), Word.and(n, x, m), Word.zero(n), h.and_z(n, x, m, e)) : {Word.cmp(n, _, Word.zero(n)) == EQ{} : Cmp}
1869 h.wcmp_refl(n, Word.zero(n))
1870
1871def h.zc2(+n: Nat, +x: Word(n), +y: Word(n), +m: Word(n), +e: {h.isz(n, m) == True{} : Bool})
1872 -> {Word.cmp(n, Word.and(n, x, m), Word.and(n, y, m)) == EQ{} : Cmp}:
1873 %Equal.sym(Word(n), Word.and(n, x, m), Word.zero(n), h.and_z(n, x, m, e)) : {Word.cmp(n, _, Word.and(n, y, m)) == EQ{} : Cmp}
1874 %Equal.sym(Word(n), Word.and(n, y, m), Word.zero(n), h.and_z(n, y, m, e)) : {Word.cmp(n, Word.zero(n), _) == EQ{} : Cmp}
1875 h.wcmp_refl(n, Word.zero(n))
1876
1877# A head bit under a set mask bit, with the rest masked to zero, is set when the word is not zero.
1878def h.hd_true(
1879 a: Bool, +p: Nat, +xt: Word(p), +mt: Word(p), +em: {h.isz(p, mt) == True{} : Bool},
1880 ex: {Cmp.is_eq(Word.cmp.fin(Bool.and(a, True{}), False{}, Word.cmp(p, Word.and(p, xt, mt), Word.zero(p)))) == False{} : Bool}
1881) -> {a == True{} : Bool}:
1882 match a:
1883 case True{}:
1884 {==}
1885 case False{}:
1886 Equal.sym(Bool, True{}, False{},
1887 rw(Cmp, t => {Cmp.is_eq(Word.cmp.fin(False{}, False{}, t)) == False{} : Bool},
1888 EQ{}, Word.cmp(p, Word.and(p, xt, mt), Word.zero(p)),
1889 Equal.sym(Cmp, Word.cmp(p, Word.and(p, xt, mt), Word.zero(p)), EQ{}, h.zc(p, xt, mt, em)), ex))
1890
1891def h.low(a: Bool, t: Cmp, e: {Cmp.is_eq(Word.cmp.fin(Bool.and(a, False{}), False{}, t)) == False{} : Bool})
1892 -> {Cmp.is_eq(t) == False{} : Bool}:
1893 match a:
1894 case True{}:
1895 match t:
1896 case LT{}:
1897 e
1898 case EQ{}:
1899 e
1900 case GT{}:
1901 e
1902 case False{}:
1903 match t:
1904 case LT{}:
1905 e
1906 case EQ{}:
1907 e
1908 case GT{}:
1909 e
1910
1911def h.lift0(t: Cmp, ih: {Cmp.is_eq(t) == True{} : Bool})
1912 -> {Cmp.is_eq(Word.cmp.fin(False{}, False{}, t)) == True{} : Bool}:
1913 match t:
1914 case LT{}:
1915 ih
1916 case EQ{}:
1917 {==}
1918 case GT{}:
1919 ih
1920
1921def h.lift(a: Bool, c: Bool, t: Cmp, ih: {Cmp.is_eq(t) == True{} : Bool})
1922 -> {Cmp.is_eq(Word.cmp.fin(Bool.and(a, False{}), Bool.and(c, False{}), t)) == True{} : Bool}:
1923 match a c:
1924 case True{} True{}:
1925 h.lift0(t, ih)
1926 case True{} False{}:
1927 h.lift0(t, ih)
1928 case False{} True{}:
1929 h.lift0(t, ih)
1930 case False{} False{}:
1931 h.lift0(t, ih)
1932
1933def h.route_t(
1934 +a: Bool, +c: Bool, +p: Nat, +xt: Word(p), +yt: Word(p), +mt: Word(p),
1935 +em: {h.isz(p, mt) == True{} : Bool},
1936 ex: {Cmp.is_eq(Word.cmp.fin(Bool.and(a, True{}), False{}, Word.cmp(p, Word.and(p, xt, mt), Word.zero(p)))) == False{} : Bool},
1937 ey: {Cmp.is_eq(Word.cmp.fin(Bool.and(c, True{}), False{}, Word.cmp(p, Word.and(p, yt, mt), Word.zero(p)))) == False{} : Bool}
1938) -> {Cmp.is_eq(Word.cmp.fin(Bool.and(a, True{}), Bool.and(c, True{}),
1939 Word.cmp(p, Word.and(p, xt, mt), Word.and(p, yt, mt)))) == True{} : Bool}:
1940 %Equal.sym(Bool, a, True{}, h.hd_true(a, p, xt, mt, em, ex))
1941 : {Cmp.is_eq(Word.cmp.fin(Bool.and(_, True{}), Bool.and(c, True{}), Word.cmp(p, Word.and(p, xt, mt), Word.and(p, yt, mt)))) == True{} : Bool}
1942 %Equal.sym(Bool, c, True{}, h.hd_true(c, p, yt, mt, em, ey))
1943 : {Cmp.is_eq(Word.cmp.fin(True{}, Bool.and(_, True{}), Word.cmp(p, Word.and(p, xt, mt), Word.and(p, yt, mt)))) == True{} : Bool}
1944 %Equal.sym(Cmp, Word.cmp(p, Word.and(p, xt, mt), Word.and(p, yt, mt)), EQ{}, h.zc2(p, xt, yt, mt, em))
1945 : {Cmp.is_eq(Word.cmp.fin(True{}, True{}, _)) == True{} : Bool}
1946 {==}
1947
1948def h.route_w(
1949 +n: Nat, x: Word(n), y: Word(n), m: Word(n),
1950 em: {h.at1(n, m) == True{} : Bool},
1951 ex: {Cmp.is_eq(Word.cmp(n, Word.and(n, x, m), Word.zero(n))) == False{} : Bool},
1952 ey: {Cmp.is_eq(Word.cmp(n, Word.and(n, y, m), Word.zero(n))) == False{} : Bool}
1953) -> {Cmp.is_eq(Word.cmp(n, Word.and(n, x, m), Word.and(n, y, m))) == True{} : Bool}:
1954 match n:
1955 case 0n:
1956 {==}
1957 case 1n+p:
1958 match x y m:
1959 case WCon{+a, +xt} WCon{+c, +yt} WCon{True{}, +mt}:
1960 h.route_t(a, c, p, xt, yt, mt, em, ex, ey)
1961 case WCon{+a, +xt} WCon{+c, +yt} WCon{False{}, +mt}:
1962 h.lift(a, c, Word.cmp(p, Word.and(p, xt, mt), Word.and(p, yt, mt)),
1963 h.route_w(p, xt, yt, mt, em,
1964 h.low(a, Word.cmp(p, Word.and(p, xt, mt), Word.zero(p)), ex),
1965 h.low(c, Word.cmp(p, Word.and(p, yt, mt), Word.zero(p)), ey)))
1966
1967def h.route(
1968 x: U32, y: U32, m: U32, em: {h.onebit(m) == True{} : Bool},
1969 ex: {U32.is_eq((x .&. m : U32), 0) == False{} : Bool},
1970 ey: {U32.is_eq((y .&. m : U32), 0) == False{} : Bool}
1971) -> {U32.is_eq((x .&. m : U32), (y .&. m : U32)) == True{} : Bool}:
1972 match x y m:
1973 case U32{xw} U32{yw} U32{+mw}:
1974 h.route_w(32n, xw, yw, mw, em, ex, ey)
1975
1976def h.isz_put(n: Nat, t: Word(n), e: {h.isz(n, t) == True{} : Bool})
1977 -> {h.isz(n, Word.shl.put(n, False{}, t)) == True{} : Bool}:
1978 match n:
1979 case 0n:
1980 {==}
1981 case 1n+p:
1982 match t:
1983 case WCon{True{}, t2}:
1984 Empty.absurd({h.isz(1n+p, Word.shl.put(1n+p, False{}, WCon{True{}, t2})) == True{} : Bool}, MBool.false_ne_true()(e))
1985 case WCon{False{}, t2}:
1986 h.isz_put(p, t2, e)
1987
1988def h.at1_put.t(q: Nat, b: Bool, t2: Word(q), e: {h.isz(1n+q, WCon{b, t2}) == True{} : Bool})
1989 -> {h.isz(q, Word.shl.put(q, b, t2)) == True{} : Bool}:
1990 match b:
1991 case True{}:
1992 Empty.absurd({h.isz(q, Word.shl.put(q, True{}, t2)) == True{} : Bool}, MBool.false_ne_true()(e))
1993 case False{}:
1994 h.isz_put(q, t2, e)
1995
1996def h.at1_put(p: Nat, t: Word(p), c: Bool, e: {h.at1(1n+p, WCon{c, t}) == True{} : Bool})
1997 -> {h.at1(p, Word.shl.put(p, c, t)) == True{} : Bool}:
1998 match p:
1999 case 0n:
2000 {==}
2001 case 1n+q:
2002 match t:
2003 case WCon{b, t2}:
2004 match c:
2005 case True{}:
2006 h.at1_put.t(q, b, t2, e)
2007 case False{}:
2008 h.at1_put(q, t2, b, e)
2009
2010def h.at1_shl(n: Nat, w: Word(n), e: {h.at1(n, w) == True{} : Bool})
2011 -> {h.at1(n, Word.shl(n, w)) == True{} : Bool}:
2012 match n:
2013 case 0n:
2014 {==}
2015 case 1n+p:
2016 match w:
2017 case WCon{b, t}:
2018 h.at1_put(p, t, b, e)
2019
2020def h.onebit_shl(m: U32, e: {h.onebit(m) == True{} : Bool}) -> {h.onebit((m << 1n : U32)) == True{} : Bool}:
2021 match m:
2022 case U32{w}:
2023 h.at1_shl(32n, w, e)
2024
2025# --- buckets ---------------------------------------------------------------------
2026
2027def h.egc(
2028 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +val: V,
2029 rest: List<&2, M.Entry<K, V>>, +k: K
2030) -> Maybe<&2, V>:
2031 M.HMap.bool(Maybe<&2, V>, b, u => Some{val}, u => M.HMap.entries.get(~K, ~V, ~eq, rest, k))
2032
2033def h.epc(
2034 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +key: K, +val: V,
2035 +rest: List<&2, M.Entry<K, V>>, +k: K, +v: V
2036) -> List<&2, M.Entry<K, V>>:
2037 M.HMap.bool(List<&2, M.Entry<K, V>>, b,
2038 u => M.Entry{key, v} <> rest,
2039 u => M.Entry{key, val} <> M.HMap.entries.put(~K, ~V, ~eq, rest, k, v))
2040
2041def h.edc(
2042 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +key: K, +val: V,
2043 +rest: List<&2, M.Entry<K, V>>, +k: K
2044) -> List<&2, M.Entry<K, V>>:
2045 M.HMap.bool(List<&2, M.Entry<K, V>>, b,
2046 u => rest,
2047 u => M.Entry{key, val} <> M.HMap.entries.del(~K, ~V, ~eq, rest, k))
2048
2049def h.egc2(
2050 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, c: Bool, +val: V,
2051 +xs: List<&2, M.Entry<K, V>>, +ys: List<&2, M.Entry<K, V>>, +k: K,
2052 e: {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == M.HMap.entries.get(~K, ~V, ~eq, ys, k) : Maybe<&2, V>}
2053) -> {h.egc(~K, ~V, ~eq, c, val, xs, k) == h.egc(~K, ~V, ~eq, c, val, ys, k) : Maybe<&2, V>}:
2054 match c:
2055 case True{}:
2056 {==}
2057 case False{}:
2058 e
2059
2060# eq(k, k2) is False when k2 != k.
2061def h.ne_f.c(
2062 ~K: Data, ~eq: K -> K -> Bool,
2063 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2064 +k2: K, +k: K, ne: {k2 != k : K}, b: Bool, eb: {b == eq(k, k2) : Bool}
2065) -> {b == False{} : Bool}:
2066 match b:
2067 case True{}:
2068 Empty.absurd({True{} == False{} : Bool}, ne(Equal.sym(K, k, k2, sound(k, k2, h.sb(True{}, eq(k, k2), eb)))))
2069 case False{}:
2070 {==}
2071
2072def h.ne_f(
2073 ~K: Data, ~eq: K -> K -> Bool,
2074 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2075 +k2: K, +k: K, ne: {k2 != k : K}
2076) -> {eq(k, k2) == False{} : Bool}:
2077 h.ne_f.c(~K, ~eq, ~sound, k2, k, ne, eq(k, k2), {==})
2078
2079# eq(k, key) is False when key is equal to k2 and eq(k, k2) is False.
2080def h.nk(
2081 ~K: Data, ~eq: K -> K -> Bool,
2082 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2083 +k2: K, +key: K, +k: K, e: {eq(k2, key) == True{} : Bool}, ne: {eq(k, k2) == False{} : Bool}
2084) -> {eq(k, key) == False{} : Bool}:
2085 rw(K, z => {eq(k, z) == False{} : Bool}, key, k2, Equal.sym(K, k2, key, sound(k2, key, e)), ne)
2086
2087def h.eg_put_same.c(
2088 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2089 +rest: List<&2, M.Entry<K, V>>, +k: K, +v: V, b: Bool, eb: {b == eq(k, key) : Bool},
2090 ih: {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), k) == Some{v} : Maybe<&2, V>}
2091) -> {M.HMap.entries.get(~K, ~V, ~eq, h.epc(~K, ~V, ~eq, b, key, val, rest, k, v), k) == Some{v} : Maybe<&2, V>}:
2092 match b:
2093 case True{}:
2094 %eb : {h.egc(~K, ~V, ~eq, _, v, rest, k) == Some{v} : Maybe<&2, V>}
2095 {==}
2096 case False{}:
2097 %eb : {h.egc(~K, ~V, ~eq, _, val, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), k) == Some{v} : Maybe<&2, V>}
2098 ih
2099
2100def h.eg_put_same(
2101 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2102 xs: List<&2, M.Entry<K, V>>, +k: K, +v: V
2103) -> {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v), k) == Some{v} : Maybe<&2, V>}:
2104 match xs:
2105 case Nil{}:
2106 %h.sb(eq(k, k), True{}, refl(k)) : {h.egc(~K, ~V, ~eq, _, v, Nil{}, k) == Some{v} : Maybe<&2, V>}
2107 {==}
2108 case Con{M.Entry{+key, +val}, +rest}:
2109 h.eg_put_same.c(~K, ~V, ~eq, key, val, rest, k, v, eq(k, key), {==},
2110 h.eg_put_same(~K, ~V, ~eq, ~refl, rest, k, v))
2111
2112def h.eg_put_other.c(
2113 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2114 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2115 +key: K, +val: V, +rest: List<&2, M.Entry<K, V>>, +k2: K, +k: K, +v: V,
2116 +ne: {eq(k, k2) == False{} : Bool}, b: Bool, eb: {b == eq(k2, key) : Bool},
2117 ih: {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k2, v), k)
2118 == M.HMap.entries.get(~K, ~V, ~eq, rest, k) : Maybe<&2, V>}
2119) -> {M.HMap.entries.get(~K, ~V, ~eq, h.epc(~K, ~V, ~eq, b, key, val, rest, k2, v), k)
2120 == h.egc(~K, ~V, ~eq, eq(k, key), val, rest, k) : Maybe<&2, V>}:
2121 match b:
2122 case True{}:
2123 +nk = h.nk(~K, ~eq, ~sound, k2, key, k, h.sb(True{}, eq(k2, key), eb), ne)
2124 %h.sb(eq(k, key), False{}, nk)
2125 : {h.egc(~K, ~V, ~eq, _, v, rest, k) == h.egc(~K, ~V, ~eq, eq(k, key), val, rest, k) : Maybe<&2, V>}
2126 %h.sb(eq(k, key), False{}, nk)
2127 : {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == h.egc(~K, ~V, ~eq, _, val, rest, k) : Maybe<&2, V>}
2128 {==}
2129 case False{}:
2130 h.egc2(~K, ~V, ~eq, eq(k, key), val, M.HMap.entries.put(~K, ~V, ~eq, rest, k2, v), rest, k, ih)
2131
2132def h.eg_put_other(
2133 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2134 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2135 xs: List<&2, M.Entry<K, V>>, +k2: K, +k: K, +v: V, +ne: {eq(k, k2) == False{} : Bool}
2136) -> {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, xs, k2, v), k)
2137 == M.HMap.entries.get(~K, ~V, ~eq, xs, k) : Maybe<&2, V>}:
2138 match xs:
2139 case Nil{}:
2140 %h.sb(eq(k, k2), False{}, ne) : {h.egc(~K, ~V, ~eq, _, v, Nil{}, k) == None{} : Maybe<&2, V>}
2141 {==}
2142 case Con{M.Entry{+key, +val}, +rest}:
2143 h.eg_put_other.c(~K, ~V, ~eq, ~sound, key, val, rest, k2, k, v, ne, eq(k2, key), {==},
2144 h.eg_put_other(~K, ~V, ~eq, ~sound, rest, k2, k, v, ne))
2145
2146# A bucket whose keys all hash to o holds no key hashing elsewhere.
2147def h.eg_none_hashed.c(
2148 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
2149 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2150 +key: K, +val: V, +rest: List<&2, M.Entry<K, V>>, +o: U32, +k: K,
2151 hk: {U32.is_eq(o, hash(k)) == False{} : Bool}, hh: {U32.is_eq(o, hash(key)) == True{} : Bool},
2152 b: Bool, eb: {b == eq(k, key) : Bool},
2153 ih: {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == None{} : Maybe<&2, V>}
2154) -> {h.egc(~K, ~V, ~eq, b, val, rest, k) == None{} : Maybe<&2, V>}:
2155 match b:
2156 case True{}:
2157 h.tf({h.egc(~K, ~V, ~eq, True{}, val, rest, k) == None{} : Maybe<&2, V>}, U32.is_eq(o, hash(k)),
2158 rw(K, z => {U32.is_eq(o, hash(z)) == True{} : Bool}, k, key,
2159 sound(k, key, h.sb(True{}, eq(k, key), eb)), hh),
2160 hk)
2161 case False{}:
2162 ih
2163
2164def h.eg_none_hashed(
2165 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
2166 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2167 xs: List<&2, M.Entry<K, V>>, +o: U32, +k: K, +hk: {U32.is_eq(o, hash(k)) == False{} : Bool},
2168 hs: {Laws.hmap_hashed(~K, ~V, ~hash, xs, o) == True{} : Bool}
2169) -> {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == None{} : Maybe<&2, V>}:
2170 match xs:
2171 case Nil{}:
2172 {==}
2173 case Con{M.Entry{+key, +val}, +rest}:
2174 +hs = hs
2175 h.eg_none_hashed.c(~K, ~V, ~hash, ~eq, ~sound, key, val, rest, o, k, hk,
2176 MBool.eq_true_of_and_left(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs),
2177 eq(k, key), {==},
2178 h.eg_none_hashed(~K, ~V, ~hash, ~eq, ~sound, rest, o, k, hk,
2179 MBool.eq_true_of_and_right(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs)))
2180
2181def h.len(-K: Data, -V: Data, xs: List<&2, M.Entry<K, V>>) -> Nat:
2182 List.length(&2, M.Entry<K, V>, xs)
2183
2184def h.elen_put_new.c(
2185 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2186 +rest: List<&2, M.Entry<K, V>>, +k: K, +v: V, b: Bool,
2187 miss: {h.egc(~K, ~V, ~eq, b, val, rest, k) == None{} : Maybe<&2, V>},
2188 ih: {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == None{} : Maybe<&2, V>}
2189 -> {h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)) == 1n+h.len(K, V, rest) : Nat}
2190) -> {h.len(K, V, h.epc(~K, ~V, ~eq, b, key, val, rest, k, v)) == 1n+1n+h.len(K, V, rest) : Nat}:
2191 match b:
2192 case True{}:
2193 h.some_none({h.len(K, V, M.Entry{key, v} <> rest) == 1n+1n+h.len(K, V, rest) : Nat}, V, val, miss)
2194 case False{}:
2195 Equal.cong(Nat, Nat, x => 1n+x, h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)),
2196 1n+h.len(K, V, rest), ih(miss))
2197
2198def h.elen_put_new(
2199 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K, +v: V,
2200 miss: {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == None{} : Maybe<&2, V>}
2201) -> {h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v)) == 1n+h.len(K, V, xs) : Nat}:
2202 match xs:
2203 case Nil{}:
2204 {==}
2205 case Con{M.Entry{+key, +val}, +rest}:
2206 h.elen_put_new.c(~K, ~V, ~eq, key, val, rest, k, v, eq(k, key), miss,
2207 e => h.elen_put_new(~K, ~V, ~eq, rest, k, v, e))
2208
2209def h.elen_put_hit.c(
2210 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2211 +rest: List<&2, M.Entry<K, V>>, +k: K, +v: V, -w: V, b: Bool,
2212 hit: {h.egc(~K, ~V, ~eq, b, val, rest, k) == Some{w} : Maybe<&2, V>},
2213 ih: {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == Some{w} : Maybe<&2, V>}
2214 -> {h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)) == h.len(K, V, rest) : Nat}
2215) -> {h.len(K, V, h.epc(~K, ~V, ~eq, b, key, val, rest, k, v)) == 1n+h.len(K, V, rest) : Nat}:
2216 match b:
2217 case True{}:
2218 {==}
2219 case False{}:
2220 Equal.cong(Nat, Nat, x => 1n+x, h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)),
2221 h.len(K, V, rest), ih(hit))
2222
2223def h.elen_put_hit(
2224 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K, +v: V, -w: V,
2225 hit: {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == Some{w} : Maybe<&2, V>}
2226) -> {h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v)) == h.len(K, V, xs) : Nat}:
2227 match xs:
2228 case Nil{}:
2229 h.none_some({h.len(K, V, M.HMap.entries.put(~K, ~V, ~eq, Nil{}, k, v)) == 0n : Nat}, V, w, hit)
2230 case Con{M.Entry{+key, +val}, +rest}:
2231 h.elen_put_hit.c(~K, ~V, ~eq, key, val, rest, k, v, w, eq(k, key), hit,
2232 e => h.elen_put_hit(~K, ~V, ~eq, rest, k, v, w, e))
2233
2234def h.elen_del_hit.c(
2235 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2236 +rest: List<&2, M.Entry<K, V>>, +k: K, -w: V, b: Bool,
2237 hit: {h.egc(~K, ~V, ~eq, b, val, rest, k) == Some{w} : Maybe<&2, V>},
2238 ih: {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == Some{w} : Maybe<&2, V>}
2239 -> {1n+h.len(K, V, M.HMap.entries.del(~K, ~V, ~eq, rest, k)) == h.len(K, V, rest) : Nat}
2240) -> {1n+h.len(K, V, h.edc(~K, ~V, ~eq, b, key, val, rest, k)) == 1n+h.len(K, V, rest) : Nat}:
2241 match b:
2242 case True{}:
2243 {==}
2244 case False{}:
2245 Equal.cong(Nat, Nat, x => 1n+x, 1n+h.len(K, V, M.HMap.entries.del(~K, ~V, ~eq, rest, k)),
2246 h.len(K, V, rest), ih(hit))
2247
2248def h.elen_del_hit(
2249 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K, -w: V,
2250 hit: {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == Some{w} : Maybe<&2, V>}
2251) -> {1n+h.len(K, V, M.HMap.entries.del(~K, ~V, ~eq, xs, k)) == h.len(K, V, xs) : Nat}:
2252 match xs:
2253 case Nil{}:
2254 h.none_some({1n == 0n : Nat}, V, w, hit)
2255 case Con{M.Entry{+key, +val}, +rest}:
2256 h.elen_del_hit.c(~K, ~V, ~eq, key, val, rest, k, w, eq(k, key), hit,
2257 e => h.elen_del_hit(~K, ~V, ~eq, rest, k, w, e))
2258
2259def h.edel_miss.c(
2260 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2261 +rest: List<&2, M.Entry<K, V>>, +k: K, b: Bool,
2262 miss: {h.egc(~K, ~V, ~eq, b, val, rest, k) == None{} : Maybe<&2, V>},
2263 ih: {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == None{} : Maybe<&2, V>}
2264 -> {M.HMap.entries.del(~K, ~V, ~eq, rest, k) == rest : List<&2, M.Entry<K, V>>}
2265) -> {h.edc(~K, ~V, ~eq, b, key, val, rest, k) == M.Entry{key, val} <> rest : List<&2, M.Entry<K, V>>}:
2266 match b:
2267 case True{}:
2268 h.some_none({rest == M.Entry{key, val} <> rest : List<&2, M.Entry<K, V>>}, V, val, miss)
2269 case False{}:
2270 Equal.cong(List<&2, M.Entry<K, V>>, List<&2, M.Entry<K, V>>, t => M.Entry{key, val} <> t,
2271 M.HMap.entries.del(~K, ~V, ~eq, rest, k), rest, ih(miss))
2272
2273def h.edel_miss(
2274 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K,
2275 miss: {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == None{} : Maybe<&2, V>}
2276) -> {M.HMap.entries.del(~K, ~V, ~eq, xs, k) == xs : List<&2, M.Entry<K, V>>}:
2277 match xs:
2278 case Nil{}:
2279 {==}
2280 case Con{M.Entry{+key, +val}, +rest}:
2281 h.edel_miss.c(~K, ~V, ~eq, key, val, rest, k, eq(k, key), miss,
2282 e => h.edel_miss(~K, ~V, ~eq, rest, k, e))
2283
2284def h.absent_none(
2285 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K,
2286 ab: {Laws.hmap_absent(~K, ~V, ~eq, xs, k) == True{} : Bool}
2287) -> {M.HMap.entries.get(~K, ~V, ~eq, xs, k) == None{} : Maybe<&2, V>}:
2288 match xs:
2289 case Nil{}:
2290 {==}
2291 case Con{M.Entry{+key, +val}, +rest}:
2292 +ab = ab
2293 %h.sb(eq(k, key), False{},
2294 MBool.eq_false_of_not_eq_true(eq(k, key), MBool.eq_true_of_and_left(Bool.not(eq(k, key)), Laws.hmap_absent(~K, ~V, ~eq, rest, k), ab)))
2295 : {h.egc(~K, ~V, ~eq, _, val, rest, k) == None{} : Maybe<&2, V>}
2296 h.absent_none(~K, ~V, ~eq, rest, k,
2297 MBool.eq_true_of_and_right(Bool.not(eq(k, key)), Laws.hmap_absent(~K, ~V, ~eq, rest, k), ab))
2298
2299def h.eg_del_same.c(
2300 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2301 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2302 +key: K, +val: V, +rest: List<&2, M.Entry<K, V>>, +k: K, b: Bool, eb: {b == eq(k, key) : Bool},
2303 ab: {Laws.hmap_absent(~K, ~V, ~eq, rest, key) == True{} : Bool},
2304 ih: {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k), k) == None{} : Maybe<&2, V>}
2305) -> {M.HMap.entries.get(~K, ~V, ~eq, h.edc(~K, ~V, ~eq, b, key, val, rest, k), k) == None{} : Maybe<&2, V>}:
2306 match b:
2307 case True{}:
2308 h.absent_none(~K, ~V, ~eq, rest, k,
2309 rw(K, z => {Laws.hmap_absent(~K, ~V, ~eq, rest, z) == True{} : Bool}, k, key,
2310 sound(k, key, h.sb(True{}, eq(k, key), eb)), ab))
2311 case False{}:
2312 %eb : {h.egc(~K, ~V, ~eq, _, val, M.HMap.entries.del(~K, ~V, ~eq, rest, k), k) == None{} : Maybe<&2, V>}
2313 ih
2314
2315def h.eg_del_same(
2316 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2317 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2318 xs: List<&2, M.Entry<K, V>>, +k: K,
2319 ds: {Laws.hmap_distinct(~K, ~V, ~eq, xs) == True{} : Bool}
2320) -> {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, xs, k), k) == None{} : Maybe<&2, V>}:
2321 match xs:
2322 case Nil{}:
2323 {==}
2324 case Con{M.Entry{+key, +val}, +rest}:
2325 +ds = ds
2326 h.eg_del_same.c(~K, ~V, ~eq, ~sound, key, val, rest, k, eq(k, key), {==},
2327 MBool.eq_true_of_and_left(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds),
2328 h.eg_del_same(~K, ~V, ~eq, ~sound, rest, k,
2329 MBool.eq_true_of_and_right(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds)))
2330
2331def h.eg_del_other.c(
2332 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2333 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2334 +key: K, +val: V, +rest: List<&2, M.Entry<K, V>>, +k2: K, +k: K,
2335 +ne: {eq(k, k2) == False{} : Bool}, b: Bool, eb: {b == eq(k2, key) : Bool},
2336 ih: {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k2), k)
2337 == M.HMap.entries.get(~K, ~V, ~eq, rest, k) : Maybe<&2, V>}
2338) -> {M.HMap.entries.get(~K, ~V, ~eq, h.edc(~K, ~V, ~eq, b, key, val, rest, k2), k)
2339 == h.egc(~K, ~V, ~eq, eq(k, key), val, rest, k) : Maybe<&2, V>}:
2340 match b:
2341 case True{}:
2342 %h.sb(eq(k, key), False{}, h.nk(~K, ~eq, ~sound, k2, key, k, h.sb(True{}, eq(k2, key), eb), ne))
2343 : {M.HMap.entries.get(~K, ~V, ~eq, rest, k) == h.egc(~K, ~V, ~eq, _, val, rest, k) : Maybe<&2, V>}
2344 {==}
2345 case False{}:
2346 h.egc2(~K, ~V, ~eq, eq(k, key), val, M.HMap.entries.del(~K, ~V, ~eq, rest, k2), rest, k, ih)
2347
2348def h.eg_del_other(
2349 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
2350 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2351 xs: List<&2, M.Entry<K, V>>, +k2: K, +k: K, +ne: {eq(k, k2) == False{} : Bool}
2352) -> {M.HMap.entries.get(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, xs, k2), k)
2353 == M.HMap.entries.get(~K, ~V, ~eq, xs, k) : Maybe<&2, V>}:
2354 match xs:
2355 case Nil{}:
2356 {==}
2357 case Con{M.Entry{+key, +val}, +rest}:
2358 h.eg_del_other.c(~K, ~V, ~eq, ~sound, key, val, rest, k2, k, ne, eq(k2, key), {==},
2359 h.eg_del_other(~K, ~V, ~eq, ~sound, rest, k2, k, ne))
2360
2361# eq is symmetric on False, given refl and sound.
2362def h.eq_sym_f.c(
2363 ~K: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2364 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2365 +k: K, +key: K, e: {eq(k, key) == False{} : Bool}, b: Bool, eb: {b == eq(key, k) : Bool}
2366) -> {b == False{} : Bool}:
2367 match b:
2368 case True{}:
2369 h.tf({True{} == False{} : Bool}, eq(k, k), refl(k),
2370 rw(K, z => {eq(k, z) == False{} : Bool}, k, key,
2371 Equal.sym(K, key, k, sound(key, k, h.sb(True{}, eq(key, k), eb))), e))
2372 case False{}:
2373 {==}
2374
2375def h.eq_sym_f(
2376 ~K: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2377 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2378 +k: K, +key: K, e: {eq(k, key) == False{} : Bool}
2379) -> {eq(key, k) == False{} : Bool}:
2380 h.eq_sym_f.c(~K, ~eq, ~refl, ~sound, k, key, e, eq(key, k), {==})
2381
2382def h.absent_put.c(
2383 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key2: K, +val: V,
2384 +rest: List<&2, M.Entry<K, V>>, +key: K, +k: K, +v: V, b: Bool,
2385 +ab: {Laws.hmap_absent(~K, ~V, ~eq, M.Entry{key2, val} <> rest, key) == True{} : Bool},
2386 ih: {Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), key) == True{} : Bool}
2387) -> {Laws.hmap_absent(~K, ~V, ~eq, h.epc(~K, ~V, ~eq, b, key2, val, rest, k, v), key) == True{} : Bool}:
2388 match b:
2389 case True{}:
2390 ab
2391 case False{}:
2392 MBool.and_eq_true(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), key), MBool.eq_true_of_and_left(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, rest, key), ab), ih)
2393
2394def h.absent_put(
2395 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2396 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2397 xs: List<&2, M.Entry<K, V>>, +key: K, +k: K, +v: V,
2398 ab: {Laws.hmap_absent(~K, ~V, ~eq, xs, key) == True{} : Bool},
2399 +nk: {eq(k, key) == False{} : Bool}
2400) -> {Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v), key) == True{} : Bool}:
2401 match xs:
2402 case Nil{}:
2403 %h.sb(eq(key, k), False{}, h.eq_sym_f(~K, ~eq, ~refl, ~sound, k, key, nk))
2404 : {Bool.and(Bool.not(_), True{}) == True{} : Bool}
2405 {==}
2406 case Con{M.Entry{+key2, +val}, +rest}:
2407 +ab = ab
2408 h.absent_put.c(~K, ~V, ~eq, key2, val, rest, key, k, v, eq(k, key2), ab,
2409 h.absent_put(~K, ~V, ~eq, ~refl, ~sound, rest, key, k, v,
2410 MBool.eq_true_of_and_right(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, rest, key), ab), nk))
2411
2412def h.distinct_put.c(
2413 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2414 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2415 +key: K, +val: V, +rest: List<&2, M.Entry<K, V>>, +k: K, +v: V, b: Bool, eb: {b == eq(k, key) : Bool},
2416 +ds: {Laws.hmap_distinct(~K, ~V, ~eq, M.Entry{key, val} <> rest) == True{} : Bool},
2417 ih: {Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)) == True{} : Bool}
2418) -> {Laws.hmap_distinct(~K, ~V, ~eq, h.epc(~K, ~V, ~eq, b, key, val, rest, k, v)) == True{} : Bool}:
2419 match b:
2420 case True{}:
2421 ds
2422 case False{}:
2423 MBool.and_eq_true(Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), key), Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v)), h.absent_put(~K, ~V, ~eq, ~refl, ~sound, rest, key, k, v,
2424 MBool.eq_true_of_and_left(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds),
2425 h.sb(False{}, eq(k, key), eb)), ih)
2426
2427def h.distinct_put(
2428 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2429 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
2430 xs: List<&2, M.Entry<K, V>>, +k: K, +v: V,
2431 ds: {Laws.hmap_distinct(~K, ~V, ~eq, xs) == True{} : Bool}
2432) -> {Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v)) == True{} : Bool}:
2433 match xs:
2434 case Nil{}:
2435 {==}
2436 case Con{M.Entry{+key, +val}, +rest}:
2437 +ds = ds
2438 h.distinct_put.c(~K, ~V, ~eq, ~refl, ~sound, key, val, rest, k, v, eq(k, key), {==}, ds,
2439 h.distinct_put(~K, ~V, ~eq, ~refl, ~sound, rest, k, v,
2440 MBool.eq_true_of_and_right(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds)))
2441
2442def h.hashed_put.c(
2443 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +key: K, +val: V,
2444 +rest: List<&2, M.Entry<K, V>>, +o: U32, +k: K, +v: V, b: Bool,
2445 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, M.Entry{key, val} <> rest, o) == True{} : Bool},
2446 ih: {Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), o) == True{} : Bool}
2447) -> {Laws.hmap_hashed(~K, ~V, ~hash, h.epc(~K, ~V, ~eq, b, key, val, rest, k, v), o) == True{} : Bool}:
2448 match b:
2449 case True{}:
2450 hs
2451 case False{}:
2452 MBool.and_eq_true(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.put(~K, ~V, ~eq, rest, k, v), o), MBool.eq_true_of_and_left(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs), ih)
2453
2454def h.hashed_put(
2455 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
2456 xs: List<&2, M.Entry<K, V>>, +o: U32, +k: K, +v: V,
2457 +hk: {U32.is_eq(o, hash(k)) == True{} : Bool},
2458 hs: {Laws.hmap_hashed(~K, ~V, ~hash, xs, o) == True{} : Bool}
2459) -> {Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.put(~K, ~V, ~eq, xs, k, v), o) == True{} : Bool}:
2460 match xs:
2461 case Nil{}:
2462 %h.sb(U32.is_eq(o, hash(k)), True{}, hk) : {Bool.and(_, True{}) == True{} : Bool}
2463 {==}
2464 case Con{M.Entry{+key, +val}, +rest}:
2465 +hs = hs
2466 h.hashed_put.c(~K, ~V, ~hash, ~eq, key, val, rest, o, k, v, eq(k, key), hs,
2467 h.hashed_put(~K, ~V, ~hash, ~eq, rest, o, k, v, hk,
2468 MBool.eq_true_of_and_right(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs)))
2469
2470def h.absent_del.c(
2471 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key2: K, +val: V,
2472 +rest: List<&2, M.Entry<K, V>>, +key: K, +k: K, b: Bool,
2473 +ab: {Laws.hmap_absent(~K, ~V, ~eq, M.Entry{key2, val} <> rest, key) == True{} : Bool},
2474 ih: {Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k), key) == True{} : Bool}
2475) -> {Laws.hmap_absent(~K, ~V, ~eq, h.edc(~K, ~V, ~eq, b, key2, val, rest, k), key) == True{} : Bool}:
2476 match b:
2477 case True{}:
2478 MBool.eq_true_of_and_right(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, rest, key), ab)
2479 case False{}:
2480 MBool.and_eq_true(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k), key), MBool.eq_true_of_and_left(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, rest, key), ab), ih)
2481
2482def h.absent_del(
2483 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +key: K, +k: K,
2484 ab: {Laws.hmap_absent(~K, ~V, ~eq, xs, key) == True{} : Bool}
2485) -> {Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, xs, k), key) == True{} : Bool}:
2486 match xs:
2487 case Nil{}:
2488 {==}
2489 case Con{M.Entry{+key2, +val}, +rest}:
2490 +ab = ab
2491 h.absent_del.c(~K, ~V, ~eq, key2, val, rest, key, k, eq(k, key2), ab,
2492 h.absent_del(~K, ~V, ~eq, rest, key, k,
2493 MBool.eq_true_of_and_right(Bool.not(eq(key, key2)), Laws.hmap_absent(~K, ~V, ~eq, rest, key), ab)))
2494
2495def h.distinct_del.c(
2496 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +key: K, +val: V,
2497 +rest: List<&2, M.Entry<K, V>>, +k: K, b: Bool,
2498 +ds: {Laws.hmap_distinct(~K, ~V, ~eq, M.Entry{key, val} <> rest) == True{} : Bool},
2499 ih: {Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k)) == True{} : Bool}
2500) -> {Laws.hmap_distinct(~K, ~V, ~eq, h.edc(~K, ~V, ~eq, b, key, val, rest, k)) == True{} : Bool}:
2501 match b:
2502 case True{}:
2503 MBool.eq_true_of_and_right(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds)
2504 case False{}:
2505 MBool.and_eq_true(Laws.hmap_absent(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k), key), Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, rest, k)), h.absent_del(~K, ~V, ~eq, rest, key, k,
2506 MBool.eq_true_of_and_left(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds)), ih)
2507
2508def h.distinct_del(
2509 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K,
2510 ds: {Laws.hmap_distinct(~K, ~V, ~eq, xs) == True{} : Bool}
2511) -> {Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, xs, k)) == True{} : Bool}:
2512 match xs:
2513 case Nil{}:
2514 {==}
2515 case Con{M.Entry{+key, +val}, +rest}:
2516 +ds = ds
2517 h.distinct_del.c(~K, ~V, ~eq, key, val, rest, k, eq(k, key), ds,
2518 h.distinct_del(~K, ~V, ~eq, rest, k,
2519 MBool.eq_true_of_and_right(Laws.hmap_absent(~K, ~V, ~eq, rest, key), Laws.hmap_distinct(~K, ~V, ~eq, rest), ds)))
2520
2521def h.hashed_del.c(
2522 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +key: K, +val: V,
2523 +rest: List<&2, M.Entry<K, V>>, +o: U32, +k: K, b: Bool,
2524 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, M.Entry{key, val} <> rest, o) == True{} : Bool},
2525 ih: {Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.del(~K, ~V, ~eq, rest, k), o) == True{} : Bool}
2526) -> {Laws.hmap_hashed(~K, ~V, ~hash, h.edc(~K, ~V, ~eq, b, key, val, rest, k), o) == True{} : Bool}:
2527 match b:
2528 case True{}:
2529 MBool.eq_true_of_and_right(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs)
2530 case False{}:
2531 MBool.and_eq_true(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.del(~K, ~V, ~eq, rest, k), o), MBool.eq_true_of_and_left(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs), ih)
2532
2533def h.hashed_del(
2534 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
2535 xs: List<&2, M.Entry<K, V>>, +o: U32, +k: K,
2536 hs: {Laws.hmap_hashed(~K, ~V, ~hash, xs, o) == True{} : Bool}
2537) -> {Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.del(~K, ~V, ~eq, xs, k), o) == True{} : Bool}:
2538 match xs:
2539 case Nil{}:
2540 {==}
2541 case Con{M.Entry{+key, +val}, +rest}:
2542 +hs = hs
2543 h.hashed_del.c(~K, ~V, ~hash, ~eq, key, val, rest, o, k, eq(k, key), hs,
2544 h.hashed_del(~K, ~V, ~hash, ~eq, rest, o, k,
2545 MBool.eq_true_of_and_right(U32.is_eq(o, hash(key)), Laws.hmap_hashed(~K, ~V, ~hash, rest, o), hs)))
2546
2547# --- tries -----------------------------------------------------------------------
2548
2549def h.G(~K: Data, ~V: Data, ~eq: K -> K -> Bool, +n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K) -> Maybe<&2, V>:
2550 M.HMap.get.go(~K, ~V, ~eq, n, mask, m, hk, k)
2551
2552def h.P(~K: Data, ~V: Data, ~eq: K -> K -> Bool, +n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K, +v: V) -> M.HMap<K, V>:
2553 M.HMap.put.go(~K, ~V, ~eq, n, mask, m, hk, k, v)
2554
2555def h.D(~K: Data, ~V: Data, ~eq: K -> K -> Bool, +n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K) -> M.HMap<K, V>:
2556 M.HMap.del.go(~K, ~V, ~eq, n, mask, m, hk, k)
2557
2558def h.S(
2559 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +n: Nat, +mask: U32, +o: U32,
2560 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V
2561) -> M.HMap<K, V>:
2562 M.HMap.split(~K, ~V, ~eq, n, mask, o, es, hk, k, v)
2563
2564def h.EG(~K: Data, ~V: Data, ~eq: K -> K -> Bool, xs: List<&2, M.Entry<K, V>>, +k: K) -> Maybe<&2, V>:
2565 M.HMap.entries.get(~K, ~V, ~eq, xs, k)
2566
2567def h.WF(~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +n: Nat, m: M.HMap<K, V>) -> Bool:
2568 Laws.hmap_wf.go(~K, ~V, ~hash, ~eq, n, m)
2569
2570def h.Sz(-K: Data, -V: Data, m: M.HMap<K, V>) -> Nat:
2571 M.HMap.size(K, V, m)
2572
2573# The branches of put.go, split, and del.go, with their test as a parameter.
2574def h.pl(
2575 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +p: Nat, +mask: U32, +o: U32,
2576 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V
2577) -> M.HMap<K, V>:
2578 M.HMap.bool(M.HMap<K, V>, b,
2579 u => M.HLeaf{o, M.HMap.entries.put(~K, ~V, ~eq, es, k, v)},
2580 u => M.HMap.split(~K, ~V, ~eq, 1n+p, mask, o, es, hk, k, v))
2581
2582def h.pb(
2583 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +p: Nat, +mask: U32,
2584 +lo: M.HMap<K, V>, +hi: M.HMap<K, V>, +hk: U32, +k: K, +v: V
2585) -> M.HMap<K, V>:
2586 M.HMap.bool(M.HMap<K, V>, b,
2587 u => M.HBranch{M.HMap.put.go(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v), hi},
2588 u => M.HBranch{lo, M.HMap.put.go(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)})
2589
2590def h.sp(
2591 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b1: Bool, +b2: Bool, +p: Nat, +mask: U32, +o: U32,
2592 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V
2593) -> M.HMap<K, V>:
2594 M.HMap.bool(M.HMap<K, V>, b1,
2595 u => M.HMap.bool(M.HMap<K, V>, b2,
2596 x => M.HBranch{M.HMap.split(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v), M.HNil{}},
2597 x => M.HBranch{M.HNil{}, M.HMap.split(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v)}),
2598 u => M.HMap.split.side(K, V, b2, M.HLeaf{o, es}, M.HLeaf{hk, [M.Entry{k, v}]}))
2599
2600def h.dl(
2601 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K
2602) -> M.HMap<K, V>:
2603 M.HMap.bool(M.HMap<K, V>, b,
2604 u => M.HMap.leaf(K, V, o, M.HMap.entries.del(~K, ~V, ~eq, es, k)),
2605 u => M.HLeaf{o, es})
2606
2607def h.db(
2608 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, b: Bool, +p: Nat, +mask: U32,
2609 +lo: M.HMap<K, V>, +hi: M.HMap<K, V>, +hk: U32, +k: K
2610) -> M.HMap<K, V>:
2611 M.HMap.bool(M.HMap<K, V>, b,
2612 u => M.HMap.join(K, V, M.HMap.del.go(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k), hi),
2613 u => M.HMap.join(K, V, lo, M.HMap.del.go(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)))
2614
2615# get on a bucket, as get.go sees it above the last level.
2616def h.R(
2617 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +o: U32,
2618 +es: List<&2, M.Entry<K, V>>, +k: K
2619) -> Maybe<&2, V>:
2620 M.HMap.bool(Maybe<&2, V>, U32.is_eq(o, hash(k)), u => M.HMap.entries.get(~K, ~V, ~eq, es, k), u => None{})
2621
2622def h.bool_none(-V: Data, b: Bool, -x: Maybe<&2, V>, e: {x == None{} : Maybe<&2, V>})
2623 -> {M.HMap.bool(Maybe<&2, V>, b, u => x, u => None{}) == None{} : Maybe<&2, V>}:
2624 match b:
2625 case True{}:
2626 e
2627 case False{}:
2628 {==}
2629
2630def h.bnn(-V: Data, b: Bool, -x: Maybe<&2, V>, +e: {x == None{} : Maybe<&2, V>})
2631 -> {None{} == M.HMap.bool(Maybe<&2, V>, b, u => x, u => x) : Maybe<&2, V>}:
2632 match b:
2633 case True{}:
2634 Equal.sym(Maybe<&2, V>, x, None{}, e)
2635 case False{}:
2636 Equal.sym(Maybe<&2, V>, x, None{}, e)
2637
2638def h.bool_l(-A: Type, b: Bool, -x1: A, -x2: A, -y: A, e: {x1 == x2 : A})
2639 -> {M.HMap.bool(A, b, u => x1, u => y) == M.HMap.bool(A, b, u => x2, u => y) : A}:
2640 match b:
2641 case True{}:
2642 e
2643 case False{}:
2644 {==}
2645
2646def h.bool_r(-A: Type, b: Bool, -x: A, -y1: A, -y2: A, e: {y1 == y2 : A})
2647 -> {M.HMap.bool(A, b, u => x, u => y1) == M.HMap.bool(A, b, u => x, u => y2) : A}:
2648 match b:
2649 case True{}:
2650 {==}
2651 case False{}:
2652 e
2653
2654def h.bsel(
2655 -A: Type, b: Bool, -x: A, -y: A, -z: A,
2656 ht: {b == True{} : Bool} -> {x == z : A}, hf: {b == False{} : Bool} -> {y == z : A}
2657) -> {M.HMap.bool(A, b, u => x, u => y) == z : A}:
2658 match b:
2659 case True{}:
2660 ht({==})
2661 case False{}:
2662 hf({==})
2663
2664def h.cnc(c: Bool, e: {c == Bool.not(c) : Bool}) -> Empty:
2665 match c:
2666 case True{}:
2667 MBool.false_ne_true()(Equal.sym(Bool, True{}, False{}, e))
2668 case False{}:
2669 MBool.false_ne_true()(e)
2670
2671# Routing facts about hashes and a mask.
2672def h.u_ne0.c(
2673 +x: U32, +y: U32, e1: {U32.is_eq(x, y) == False{} : Bool}, e2: {U32.is_eq(x, 0) == True{} : Bool},
2674 b: Bool, eb: {b == U32.is_eq(y, 0) : Bool}
2675) -> {b == False{} : Bool}:
2676 match b:
2677 case True{}:
2678 h.tf({True{} == False{} : Bool}, U32.is_eq(x, y),
2679 rw(U32, z => {U32.is_eq(x, z) == True{} : Bool}, y, 0,
2680 h.u_sound(y, 0, h.sb(True{}, U32.is_eq(y, 0), eb)), e2),
2681 e1)
2682 case False{}:
2683 {==}
2684
2685def h.u_ne0(
2686 +x: U32, +y: U32, e1: {U32.is_eq(x, y) == False{} : Bool}, e2: {U32.is_eq(x, 0) == True{} : Bool}
2687) -> {U32.is_eq(y, 0) == False{} : Bool}:
2688 h.u_ne0.c(x, y, e1, e2, U32.is_eq(y, 0), {==})
2689
2690def h.u_route_t.c(
2691 +o: U32, +hk: U32, +mask: U32, ob: {h.onebit(mask) == True{} : Bool},
2692 e1: {U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)) == False{} : Bool},
2693 e2: {U32.is_eq((o .&. mask : U32), 0) == False{} : Bool},
2694 b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool}
2695) -> {b == True{} : Bool}:
2696 match b:
2697 case True{}:
2698 {==}
2699 case False{}:
2700 h.tf({False{} == True{} : Bool}, U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)),
2701 h.route(o, hk, mask, ob, e2, h.sb(False{}, U32.is_eq((hk .&. mask : U32), 0), eb)),
2702 e1)
2703
2704def h.u_route_t(
2705 +o: U32, +hk: U32, +mask: U32, ob: {h.onebit(mask) == True{} : Bool},
2706 e1: {U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)) == False{} : Bool},
2707 e2: {U32.is_eq((o .&. mask : U32), 0) == False{} : Bool}
2708) -> {U32.is_eq((hk .&. mask : U32), 0) == True{} : Bool}:
2709 h.u_route_t.c(o, hk, mask, ob, e1, e2, U32.is_eq((hk .&. mask : U32), 0), {==})
2710
2711def h.u_same0(
2712 +o: U32, +hk: U32, +mask: U32, -c: Bool,
2713 e1: {U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)) == True{} : Bool},
2714 e2: {U32.is_eq((o .&. mask : U32), 0) == c : Bool}
2715) -> {U32.is_eq((hk .&. mask : U32), 0) == c : Bool}:
2716 rw(U32, z => {U32.is_eq(z, 0) == c : Bool}, (hk .&. mask : U32), (o .&. mask : U32),
2717 Equal.sym(U32, (o .&. mask : U32), (hk .&. mask : U32),
2718 h.u_sound((o .&. mask : U32), (hk .&. mask : U32), e1)),
2719 e2)
2720
2721def h.u_diff.c(
2722 +o: U32, +hk: U32, +mask: U32, +c: Bool,
2723 e2: {U32.is_eq((o .&. mask : U32), 0) == c : Bool},
2724 ed: {U32.is_eq((hk .&. mask : U32), 0) == Bool.not(c) : Bool},
2725 b: Bool, eb: {b == U32.is_eq(o, hk) : Bool}
2726) -> {b == False{} : Bool}:
2727 match b:
2728 case True{}:
2729 +e3 = rw(U32, z => {U32.is_eq((z .&. mask : U32), 0) == c : Bool}, hk, o,
2730 Equal.sym(U32, o, hk, h.u_sound(o, hk, h.sb(True{}, U32.is_eq(o, hk), eb))), e2)
2731 Empty.absurd({True{} == False{} : Bool}, h.cnc(c, Equal.trans(Bool, c, U32.is_eq((hk .&. mask : U32), 0), Bool.not(c),
2732 Equal.sym(Bool, U32.is_eq((hk .&. mask : U32), 0), c, e3), ed)))
2733 case False{}:
2734 {==}
2735
2736def h.u_diff(
2737 +o: U32, +hk: U32, +mask: U32, +c: Bool,
2738 e2: {U32.is_eq((o .&. mask : U32), 0) == c : Bool},
2739 ed: {U32.is_eq((hk .&. mask : U32), 0) == Bool.not(c) : Bool}
2740) -> {U32.is_eq(o, hk) == False{} : Bool}:
2741 h.u_diff.c(o, hk, mask, c, e2, ed, U32.is_eq(o, hk), {==})
2742
2743# Unfolding get.go by a known test, simple side first.
2744def h.g_lo(
2745 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
2746 +hi: M.HMap<K, V>, +hk: U32, +k: K, e: {U32.is_eq((hk .&. mask : U32), 0) == True{} : Bool}
2747) -> {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
2748 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}:
2749 %h.sb(U32.is_eq((hk .&. mask : U32), 0), True{}, e)
2750 : {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
2751 == M.HMap.bool(Maybe<&2, V>, _, u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
2752 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) : Maybe<&2, V>}
2753 {==}
2754
2755def h.g_hi(
2756 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
2757 +hi: M.HMap<K, V>, +hk: U32, +k: K, e: {U32.is_eq((hk .&. mask : U32), 0) == False{} : Bool}
2758) -> {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
2759 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}:
2760 %h.sb(U32.is_eq((hk .&. mask : U32), 0), False{}, e)
2761 : {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
2762 == M.HMap.bool(Maybe<&2, V>, _, u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
2763 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) : Maybe<&2, V>}
2764 {==}
2765
2766def h.g_lf_t(
2767 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
2768 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, e: {U32.is_eq(o, hk) == True{} : Bool}
2769) -> {h.EG(~K, ~V, ~eq, es, k) == h.G(~K, ~V, ~eq, 1n+p, mask, M.HLeaf{o, es}, hk, k) : Maybe<&2, V>}:
2770 %h.sb(U32.is_eq(o, hk), True{}, e)
2771 : {h.EG(~K, ~V, ~eq, es, k)
2772 == M.HMap.bool(Maybe<&2, V>, _, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) : Maybe<&2, V>}
2773 {==}
2774
2775def h.gnil(~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, +hk: U32, +k: K)
2776 -> {h.G(~K, ~V, ~eq, n, mask, M.HNil{}, hk, k) == None{} : Maybe<&2, V>}:
2777 match n:
2778 case 0n:
2779 {==}
2780 case 1n+p:
2781 {==}
2782
2783def h.g_nil_leaf(~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, +o: U32, +hk: U32, +k: K)
2784 -> {h.G(~K, ~V, ~eq, n, mask, M.HLeaf{o, Nil{}}, hk, k) == h.G(~K, ~V, ~eq, n, mask, M.HNil{}, hk, k) : Maybe<&2, V>}:
2785 match n:
2786 case 0n:
2787 {==}
2788 case 1n+p:
2789 h.bool_none(V, U32.is_eq(o, hk), None{}, {==})
2790
2791def h.get_leaf(
2792 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +n: Nat, +mask: U32, +o: U32,
2793 xs: List<&2, M.Entry<K, V>>, +hk: U32, +k: K
2794) -> {h.G(~K, ~V, ~eq, n, mask, M.HLeaf{o, xs}, hk, k)
2795 == h.G(~K, ~V, ~eq, n, mask, M.HMap.leaf(K, V, o, xs), hk, k) : Maybe<&2, V>}:
2796 match xs:
2797 case Nil{}:
2798 h.g_nil_leaf(~K, ~V, ~eq, n, mask, o, hk, k)
2799 case Con{e, rest}:
2800 {==}
2801
2802def h.size_leaf(-K: Data, -V: Data, +o: U32, xs: List<&2, M.Entry<K, V>>)
2803 -> {h.len(K, V, xs) == h.Sz(K, V, M.HMap.leaf(K, V, o, xs)) : Nat}:
2804 match xs:
2805 case Nil{}:
2806 {==}
2807 case Con{e, rest}:
2808 {==}
2809
2810def h.get_join(
2811 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, lo: M.HMap<K, V>,
2812 hi: M.HMap<K, V>, +hk: U32, +k: K
2813) -> {h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k)
2814 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HMap.join(K, V, lo, hi), hk, k) : Maybe<&2, V>}:
2815 match lo:
2816 case M.HNil{}:
2817 match hi:
2818 case M.HNil{}:
2819 Equal.sym(Maybe<&2, V>, None{},
2820 M.HMap.bool(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
2821 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), M.HNil{}, hk, k),
2822 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), M.HNil{}, hk, k)),
2823 h.bnn(V, U32.is_eq((hk .&. mask : U32), 0),
2824 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), M.HNil{}, hk, k),
2825 h.gnil(~K, ~V, ~eq, p, (mask << 1n : U32), hk, k)))
2826 case M.HLeaf{a, b}:
2827 {==}
2828 case M.HBranch{a, b}:
2829 {==}
2830 case M.HLeaf{a, b}:
2831 {==}
2832 case M.HBranch{a, b}:
2833 {==}
2834
2835def h.size_join(-K: Data, -V: Data, lo: M.HMap<K, V>, hi: M.HMap<K, V>)
2836 -> {Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) == h.Sz(K, V, M.HMap.join(K, V, lo, hi)) : Nat}:
2837 match lo:
2838 case M.HNil{}:
2839 match hi:
2840 case M.HNil{}:
2841 {==}
2842 case M.HLeaf{a, b}:
2843 {==}
2844 case M.HBranch{a, b}:
2845 {==}
2846 case M.HLeaf{a, b}:
2847 {==}
2848 case M.HBranch{a, b}:
2849 {==}
2850
2851def h.wf_nil(~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, n: Nat)
2852 -> {h.WF(~K, ~V, ~hash, ~eq, n, M.HNil{}) == True{} : Bool}:
2853 match n:
2854 case 0n:
2855 {==}
2856 case 1n+p:
2857 {==}
2858
2859def h.wf_leaf(
2860 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +n: Nat, +o: U32,
2861 xs: List<&2, M.Entry<K, V>>, w: {h.WF(~K, ~V, ~hash, ~eq, n, M.HLeaf{o, xs}) == True{} : Bool}
2862) -> {h.WF(~K, ~V, ~hash, ~eq, n, M.HMap.leaf(K, V, o, xs)) == True{} : Bool}:
2863 match xs:
2864 case Nil{}:
2865 h.wf_nil(~K, ~V, ~hash, ~eq, n)
2866 case Con{e, rest}:
2867 w
2868
2869def h.wf_join(
2870 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +p: Nat, lo: M.HMap<K, V>,
2871 hi: M.HMap<K, V>, wl: {h.WF(~K, ~V, ~hash, ~eq, p, lo) == True{} : Bool},
2872 wh: {h.WF(~K, ~V, ~hash, ~eq, p, hi) == True{} : Bool}
2873) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, M.HMap.join(K, V, lo, hi)) == True{} : Bool}:
2874 match lo:
2875 case M.HNil{}:
2876 match hi:
2877 case M.HNil{}:
2878 {==}
2879 case M.HLeaf{+a, +b}:
2880 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HNil{}), h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{a, b}), wl, wh)
2881 case M.HBranch{+a, +b}:
2882 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HNil{}), h.WF(~K, ~V, ~hash, ~eq, p, M.HBranch{a, b}), wl, wh)
2883 case M.HLeaf{+a, +b}:
2884 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{a, b}), h.WF(~K, ~V, ~hash, ~eq, p, hi), wl, wh)
2885 case M.HBranch{+a, +b}:
2886 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HBranch{a, b}), h.WF(~K, ~V, ~hash, ~eq, p, hi), wl, wh)
2887
2888# get after put, same key.
2889def h.fresh_get(
2890 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2891 p: Nat, +mm: U32, +hk: U32, +k: K, +v: V
2892) -> {h.G(~K, ~V, ~eq, p, mm, M.HLeaf{hk, [M.Entry{k, v}]}, hk, k) == Some{v} : Maybe<&2, V>}:
2893 match p:
2894 case 0n:
2895 h.eg_put_same(~K, ~V, ~eq, ~refl, Nil{}, k, v)
2896 case 1n+q:
2897 %h.g_lf_t(~K, ~V, ~eq, q, mm, hk, [M.Entry{k, v}], hk, k, h.u_refl(hk)) : {_ == Some{v} : Maybe<&2, V>}
2898 h.eg_put_same(~K, ~V, ~eq, ~refl, Nil{}, k, v)
2899
2900def h.split_same.b(
2901 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
2902 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V, ob: {h.onebit(mask) == True{} : Bool},
2903 b1: Bool, b2: Bool,
2904 e1: {b1 == U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)) : Bool},
2905 e2: {b2 == U32.is_eq((o .&. mask : U32), 0) : Bool},
2906 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>},
2907 fr: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), M.HLeaf{hk, [M.Entry{k, v}]}, hk, k) == Some{v} : Maybe<&2, V>}
2908) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.sp(~K, ~V, ~eq, b1, b2, p, mask, o, es, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}:
2909 match b1 b2:
2910 case True{} True{}:
2911 %h.g_lo(~K, ~V, ~eq, p, mask, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v), M.HNil{}, hk, k,
2912 h.u_same0(o, hk, mask, True{},
2913 h.sb(True{}, U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), e1),
2914 h.sb(True{}, U32.is_eq((o .&. mask : U32), 0), e2)))
2915 : {_ == Some{v} : Maybe<&2, V>}
2916 ih
2917 case True{} False{}:
2918 %h.g_hi(~K, ~V, ~eq, p, mask, M.HNil{}, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v), hk, k,
2919 h.u_same0(o, hk, mask, False{},
2920 h.sb(True{}, U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), e1),
2921 h.sb(False{}, U32.is_eq((o .&. mask : U32), 0), e2)))
2922 : {_ == Some{v} : Maybe<&2, V>}
2923 ih
2924 case False{} True{}:
2925 %h.g_hi(~K, ~V, ~eq, p, mask, M.HLeaf{o, es}, M.HLeaf{hk, [M.Entry{k, v}]}, hk, k,
2926 h.u_ne0((o .&. mask : U32), (hk .&. mask : U32),
2927 h.sb(False{}, U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), e1),
2928 h.sb(True{}, U32.is_eq((o .&. mask : U32), 0), e2)))
2929 : {_ == Some{v} : Maybe<&2, V>}
2930 fr
2931 case False{} False{}:
2932 %h.g_lo(~K, ~V, ~eq, p, mask, M.HLeaf{hk, [M.Entry{k, v}]}, M.HLeaf{o, es}, hk, k,
2933 h.u_route_t(o, hk, mask, ob,
2934 h.sb(False{}, U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), e1),
2935 h.sb(False{}, U32.is_eq((o .&. mask : U32), 0), e2)))
2936 : {_ == Some{v} : Maybe<&2, V>}
2937 fr
2938
2939def h.split_same(
2940 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2941 n: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V,
2942 +ob: {h.onebit(mask) == True{} : Bool}
2943) -> {h.G(~K, ~V, ~eq, n, mask, h.S(~K, ~V, ~eq, n, mask, o, es, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}:
2944 match n:
2945 case 0n:
2946 h.eg_put_same(~K, ~V, ~eq, ~refl, es, k, v)
2947 case 1n+(+p):
2948 h.split_same.b(~K, ~V, ~eq, p, mask, o, es, hk, k, v, ob,
2949 U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), U32.is_eq((o .&. mask : U32), 0), {==}, {==},
2950 h.split_same(~K, ~V, ~eq, ~refl, p, (mask << 1n : U32), o, es, hk, k, v, h.onebit_shl(mask, ob)),
2951 h.fresh_get(~K, ~V, ~eq, ~refl, p, (mask << 1n : U32), hk, k, v))
2952
2953def h.gp_same.lf(
2954 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2955 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V,
2956 b: Bool, eb: {b == U32.is_eq(o, hk) : Bool},
2957 sp: {h.G(~K, ~V, ~eq, 1n+p, mask, h.S(~K, ~V, ~eq, 1n+p, mask, o, es, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}
2958) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.pl(~K, ~V, ~eq, b, p, mask, o, es, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}:
2959 match b:
2960 case True{}:
2961 %h.g_lf_t(~K, ~V, ~eq, p, mask, o, M.HMap.entries.put(~K, ~V, ~eq, es, k, v), hk, k,
2962 h.sb(True{}, U32.is_eq(o, hk), eb)) : {_ == Some{v} : Maybe<&2, V>}
2963 h.eg_put_same(~K, ~V, ~eq, ~refl, es, k, v)
2964 case False{}:
2965 sp
2966
2967def h.gp_same.br(
2968 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
2969 +hi: M.HMap<K, V>, +hk: U32, +k: K, +v: V,
2970 b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
2971 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>},
2972 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}
2973) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.pb(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}:
2974 match b:
2975 case True{}:
2976 %h.g_lo(~K, ~V, ~eq, p, mask, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v), hi, hk, k,
2977 h.sb(True{}, U32.is_eq((hk .&. mask : U32), 0), eb)) : {_ == Some{v} : Maybe<&2, V>}
2978 il
2979 case False{}:
2980 %h.g_hi(~K, ~V, ~eq, p, mask, lo, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v), hk, k,
2981 h.sb(False{}, U32.is_eq((hk .&. mask : U32), 0), eb)) : {_ == Some{v} : Maybe<&2, V>}
2982 ih
2983
2984def h.gp_same(
2985 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
2986 n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K, +v: V,
2987 +ob: {h.onebit(mask) == True{} : Bool}, +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool}
2988) -> {h.G(~K, ~V, ~eq, n, mask, h.P(~K, ~V, ~eq, n, mask, m, hk, k, v), hk, k) == Some{v} : Maybe<&2, V>}:
2989 match n:
2990 case 0n:
2991 match m:
2992 case M.HNil{}:
2993 h.eg_put_same(~K, ~V, ~eq, ~refl, Nil{}, k, v)
2994 case M.HLeaf{o, es}:
2995 h.eg_put_same(~K, ~V, ~eq, ~refl, es, k, v)
2996 case M.HBranch{lo, hi}:
2997 Empty.absurd({h.G(~K, ~V, ~eq, 0n, mask, M.HBranch{lo, hi}, hk, k) == Some{v} : Maybe<&2, V>}, MBool.false_ne_true()(wf))
2998 case 1n+(+p):
2999 match m:
3000 case M.HNil{}:
3001 %h.g_lf_t(~K, ~V, ~eq, p, mask, hk, [M.Entry{k, v}], hk, k, h.u_refl(hk)) : {_ == Some{v} : Maybe<&2, V>}
3002 h.eg_put_same(~K, ~V, ~eq, ~refl, Nil{}, k, v)
3003 case M.HLeaf{+o, +es}:
3004 h.gp_same.lf(~K, ~V, ~eq, ~refl, p, mask, o, es, hk, k, v, U32.is_eq(o, hk), {==},
3005 h.split_same(~K, ~V, ~eq, ~refl, 1n+p, mask, o, es, hk, k, v, ob))
3006 case M.HBranch{+lo, +hi}:
3007 h.gp_same.br(~K, ~V, ~eq, p, mask, lo, hi, hk, k, v, U32.is_eq((hk .&. mask : U32), 0), {==},
3008 h.gp_same(~K, ~V, ~hash, ~eq, ~refl, p, (mask << 1n : U32), lo, hk, k, v, h.onebit_shl(mask, ob),
3009 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)),
3010 h.gp_same(~K, ~V, ~hash, ~eq, ~refl, p, (mask << 1n : U32), hi, hk, k, v, h.onebit_shl(mask, ob),
3011 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)))
3012
3013# get after put, other key.
3014def h.r_eg.c(
3015 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3016 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3017 +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K,
3018 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3019 b: Bool, eb: {b == U32.is_eq(o, hash(k)) : Bool}
3020) -> {h.EG(~K, ~V, ~eq, es, k)
3021 == M.HMap.bool(Maybe<&2, V>, b, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) : Maybe<&2, V>}:
3022 match b:
3023 case True{}:
3024 {==}
3025 case False{}:
3026 h.eg_none_hashed(~K, ~V, ~hash, ~eq, ~sound, es, o, k, h.sb(False{}, U32.is_eq(o, hash(k)), eb), hs)
3027
3028def h.r_eg(
3029 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3030 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3031 +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K,
3032 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool}
3033) -> {h.EG(~K, ~V, ~eq, es, k) == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}:
3034 h.r_eg.c(~K, ~V, ~hash, ~eq, ~sound, o, es, k, hs, U32.is_eq(o, hash(k)), {==})
3035
3036def h.r_none(
3037 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +o: U32,
3038 +es: List<&2, M.Entry<K, V>>, +k: K, ne: {U32.is_eq(o, hash(k)) == False{} : Bool}
3039) -> {None{} == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}:
3040 %h.sb(U32.is_eq(o, hash(k)), False{}, ne)
3041 : {None{} == M.HMap.bool(Maybe<&2, V>, _, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) : Maybe<&2, V>}
3042 {==}
3043
3044def h.g_leaf_r(
3045 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3046 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3047 p: Nat, +mm: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K,
3048 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool}
3049) -> {h.G(~K, ~V, ~eq, p, mm, M.HLeaf{o, es}, hash(k), k) == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}:
3050 match p:
3051 case 0n:
3052 h.r_eg(~K, ~V, ~hash, ~eq, ~sound, o, es, k, hs)
3053 case 1n+q:
3054 {==}
3055
3056def h.g_fresh_none(
3057 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
3058 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3059 p: Nat, +mm: U32, +h2: U32, +k2: K, +hk: U32, +k: K, +v: V, +nk: {eq(k, k2) == False{} : Bool}
3060) -> {h.G(~K, ~V, ~eq, p, mm, M.HLeaf{h2, [M.Entry{k2, v}]}, hk, k) == None{} : Maybe<&2, V>}:
3061 match p:
3062 case 0n:
3063 h.eg_put_other(~K, ~V, ~eq, ~sound, Nil{}, k2, k, v, nk)
3064 case 1n+q:
3065 h.bool_none(V, U32.is_eq(h2, hk), h.EG(~K, ~V, ~eq, [M.Entry{k2, v}], k),
3066 h.eg_put_other(~K, ~V, ~eq, ~sound, Nil{}, k2, k, v, nk))
3067
3068def h.split_other.b(
3069 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3070 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3071 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +h2: U32, +k2: K, +k: K, +v: V,
3072 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3073 +nk: {eq(k, k2) == False{} : Bool},
3074 b1: Bool, b2: Bool,
3075 e2: {b2 == U32.is_eq((o .&. mask : U32), 0) : Bool},
3076 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, h2, k2, v), hash(k), k)
3077 == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}
3078) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.sp(~K, ~V, ~eq, b1, b2, p, mask, o, es, h2, k2, v), hash(k), k)
3079 == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}:
3080 match b1 b2:
3081 case True{} True{}:
3082 +mm = (mask << 1n : U32)
3083 +d = U32.is_eq((hash(k) .&. mask : U32), 0)
3084 +sub = h.S(~K, ~V, ~eq, p, mm, o, es, h2, k2, v)
3085 +old = {M.HLeaf{o, es} : M.HMap<K, V>}
3086 +fresh = {M.HLeaf{h2, [M.Entry{k2, v}]} : M.HMap<K, V>}
3087 +r = h.R(~K, ~V, ~hash, ~eq, o, es, k)
3088 h.bsel(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, mm, sub, hash(k), k),
3089 h.G(~K, ~V, ~eq, p, mm, M.HNil{}, hash(k), k), r,
3090 ed => ih,
3091 ed => Equal.trans(Maybe<&2, V>, h.G(~K, ~V, ~eq, p, mm, M.HNil{}, hash(k), k), None{}, r,
3092 h.gnil(~K, ~V, ~eq, p, mm, hash(k), k),
3093 h.r_none(~K, ~V, ~hash, ~eq, o, es, k,
3094 h.u_diff(o, hash(k), mask, True{}, h.sb(True{}, U32.is_eq((o .&. mask : U32), 0), e2), ed))))
3095 case True{} False{}:
3096 +mm = (mask << 1n : U32)
3097 +d = U32.is_eq((hash(k) .&. mask : U32), 0)
3098 +sub = h.S(~K, ~V, ~eq, p, mm, o, es, h2, k2, v)
3099 +old = {M.HLeaf{o, es} : M.HMap<K, V>}
3100 +fresh = {M.HLeaf{h2, [M.Entry{k2, v}]} : M.HMap<K, V>}
3101 +r = h.R(~K, ~V, ~hash, ~eq, o, es, k)
3102 h.bsel(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, mm, M.HNil{}, hash(k), k),
3103 h.G(~K, ~V, ~eq, p, mm, sub, hash(k), k), r,
3104 ed => Equal.trans(Maybe<&2, V>, h.G(~K, ~V, ~eq, p, mm, M.HNil{}, hash(k), k), None{}, r,
3105 h.gnil(~K, ~V, ~eq, p, mm, hash(k), k),
3106 h.r_none(~K, ~V, ~hash, ~eq, o, es, k,
3107 h.u_diff(o, hash(k), mask, False{}, h.sb(False{}, U32.is_eq((o .&. mask : U32), 0), e2), ed))),
3108 ed => ih)
3109 case False{} True{}:
3110 +mm = (mask << 1n : U32)
3111 +d = U32.is_eq((hash(k) .&. mask : U32), 0)
3112 +sub = h.S(~K, ~V, ~eq, p, mm, o, es, h2, k2, v)
3113 +old = {M.HLeaf{o, es} : M.HMap<K, V>}
3114 +fresh = {M.HLeaf{h2, [M.Entry{k2, v}]} : M.HMap<K, V>}
3115 +r = h.R(~K, ~V, ~hash, ~eq, o, es, k)
3116 h.bsel(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, mm, old, hash(k), k),
3117 h.G(~K, ~V, ~eq, p, mm, fresh, hash(k), k), r,
3118 ed => h.g_leaf_r(~K, ~V, ~hash, ~eq, ~sound, p, mm, o, es, k, hs),
3119 ed => Equal.trans(Maybe<&2, V>, h.G(~K, ~V, ~eq, p, mm, fresh, hash(k), k), None{}, r,
3120 h.g_fresh_none(~K, ~V, ~eq, ~sound, p, mm, h2, k2, hash(k), k, v, nk),
3121 h.r_none(~K, ~V, ~hash, ~eq, o, es, k,
3122 h.u_diff(o, hash(k), mask, True{}, h.sb(True{}, U32.is_eq((o .&. mask : U32), 0), e2), ed))))
3123 case False{} False{}:
3124 +mm = (mask << 1n : U32)
3125 +d = U32.is_eq((hash(k) .&. mask : U32), 0)
3126 +sub = h.S(~K, ~V, ~eq, p, mm, o, es, h2, k2, v)
3127 +old = {M.HLeaf{o, es} : M.HMap<K, V>}
3128 +fresh = {M.HLeaf{h2, [M.Entry{k2, v}]} : M.HMap<K, V>}
3129 +r = h.R(~K, ~V, ~hash, ~eq, o, es, k)
3130 h.bsel(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, mm, fresh, hash(k), k),
3131 h.G(~K, ~V, ~eq, p, mm, old, hash(k), k), r,
3132 ed => Equal.trans(Maybe<&2, V>, h.G(~K, ~V, ~eq, p, mm, fresh, hash(k), k), None{}, r,
3133 h.g_fresh_none(~K, ~V, ~eq, ~sound, p, mm, h2, k2, hash(k), k, v, nk),
3134 h.r_none(~K, ~V, ~hash, ~eq, o, es, k,
3135 h.u_diff(o, hash(k), mask, False{}, h.sb(False{}, U32.is_eq((o .&. mask : U32), 0), e2), ed))),
3136 ed => h.g_leaf_r(~K, ~V, ~hash, ~eq, ~sound, p, mm, o, es, k, hs))
3137
3138def h.split_other(
3139 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3140 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3141 n: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +h2: U32, +k2: K, +k: K, +v: V,
3142 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3143 +nk: {eq(k, k2) == False{} : Bool}
3144) -> {h.G(~K, ~V, ~eq, n, mask, h.S(~K, ~V, ~eq, n, mask, o, es, h2, k2, v), hash(k), k)
3145 == h.R(~K, ~V, ~hash, ~eq, o, es, k) : Maybe<&2, V>}:
3146 match n:
3147 case 0n:
3148 Equal.trans(Maybe<&2, V>, h.EG(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, es, k2, v), k),
3149 h.EG(~K, ~V, ~eq, es, k), h.R(~K, ~V, ~hash, ~eq, o, es, k),
3150 h.eg_put_other(~K, ~V, ~eq, ~sound, es, k2, k, v, nk),
3151 h.r_eg(~K, ~V, ~hash, ~eq, ~sound, o, es, k, hs))
3152 case 1n+(+p):
3153 h.split_other.b(~K, ~V, ~hash, ~eq, ~sound, p, mask, o, es, h2, k2, k, v, hs, nk,
3154 U32.is_eq((o .&. mask : U32), (h2 .&. mask : U32)), U32.is_eq((o .&. mask : U32), 0), {==},
3155 h.split_other(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), o, es, h2, k2, k, v, hs, nk))
3156
3157def h.gp_other.lf(
3158 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3159 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3160 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +h2: U32, +k2: K, +k: K, +v: V,
3161 +nk: {eq(k, k2) == False{} : Bool}, b: Bool,
3162 sp: {h.G(~K, ~V, ~eq, 1n+p, mask, h.S(~K, ~V, ~eq, 1n+p, mask, o, es, h2, k2, v), hash(k), k)
3163 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HLeaf{o, es}, hash(k), k) : Maybe<&2, V>}
3164) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.pl(~K, ~V, ~eq, b, p, mask, o, es, h2, k2, v), hash(k), k)
3165 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HLeaf{o, es}, hash(k), k) : Maybe<&2, V>}:
3166 match b:
3167 case True{}:
3168 h.bool_l(Maybe<&2, V>, U32.is_eq(o, hash(k)),
3169 h.EG(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, es, k2, v), k), h.EG(~K, ~V, ~eq, es, k), None{},
3170 h.eg_put_other(~K, ~V, ~eq, ~sound, es, k2, k, v, nk))
3171 case False{}:
3172 sp
3173
3174def h.gp_other.br(
3175 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3176 +hi: M.HMap<K, V>, +h2: U32, +k2: K, +hk: U32, +k: K, +v: V, b: Bool,
3177 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, h2, k2, v), hk, k)
3178 == h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) : Maybe<&2, V>},
3179 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, h2, k2, v), hk, k)
3180 == h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) : Maybe<&2, V>}
3181) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.pb(~K, ~V, ~eq, b, p, mask, lo, hi, h2, k2, v), hk, k)
3182 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}:
3183 match b:
3184 case True{}:
3185 h.bool_l(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3186 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, h2, k2, v), hk, k),
3187 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3188 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), il)
3189 case False{}:
3190 h.bool_r(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3191 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3192 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, h2, k2, v), hk, k),
3193 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), ih)
3194
3195def h.gp_other(
3196 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3197 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3198 n: Nat, +mask: U32, m: M.HMap<K, V>, +h2: U32, +k2: K, +k: K, +v: V,
3199 +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool}, +nk: {eq(k, k2) == False{} : Bool}
3200) -> {h.G(~K, ~V, ~eq, n, mask, h.P(~K, ~V, ~eq, n, mask, m, h2, k2, v), hash(k), k)
3201 == h.G(~K, ~V, ~eq, n, mask, m, hash(k), k) : Maybe<&2, V>}:
3202 match n:
3203 case 0n:
3204 match m:
3205 case M.HNil{}:
3206 h.eg_put_other(~K, ~V, ~eq, ~sound, Nil{}, k2, k, v, nk)
3207 case M.HLeaf{o, es}:
3208 h.eg_put_other(~K, ~V, ~eq, ~sound, es, k2, k, v, nk)
3209 case M.HBranch{lo, hi}:
3210 {==}
3211 case 1n+(+p):
3212 match m:
3213 case M.HNil{}:
3214 h.bool_none(V, U32.is_eq(h2, hash(k)), h.EG(~K, ~V, ~eq, [M.Entry{k2, v}], k),
3215 h.eg_put_other(~K, ~V, ~eq, ~sound, Nil{}, k2, k, v, nk))
3216 case M.HLeaf{+o, +es}:
3217 h.gp_other.lf(~K, ~V, ~hash, ~eq, ~sound, p, mask, o, es, h2, k2, k, v, nk, U32.is_eq(o, h2),
3218 h.split_other(~K, ~V, ~hash, ~eq, ~sound, 1n+p, mask, o, es, h2, k2, k, v,
3219 MBool.eq_true_of_and_left(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf), nk))
3220 case M.HBranch{+lo, +hi}:
3221 h.gp_other.br(~K, ~V, ~eq, p, mask, lo, hi, h2, k2, hash(k), k, v, U32.is_eq((h2 .&. mask : U32), 0),
3222 h.gp_other(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), lo, h2, k2, k, v,
3223 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf), nk),
3224 h.gp_other(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), hi, h2, k2, k, v,
3225 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf), nk))
3226
3227# get after del.
3228def h.gd_same.lf(
3229 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
3230 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, b: Bool, eb: {b == U32.is_eq(o, hk) : Bool},
3231 ed: {h.EG(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, es, k), k) == None{} : Maybe<&2, V>}
3232) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.dl(~K, ~V, ~eq, b, o, es, k), hk, k) == None{} : Maybe<&2, V>}:
3233 match b:
3234 case True{}:
3235 %h.get_leaf(~K, ~V, ~eq, 1n+p, mask, o, M.HMap.entries.del(~K, ~V, ~eq, es, k), hk, k) : {_ == None{} : Maybe<&2, V>}
3236 h.bool_none(V, U32.is_eq(o, hk), h.EG(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, es, k), k), ed)
3237 case False{}:
3238 %eb : {M.HMap.bool(Maybe<&2, V>, _, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == None{} : Maybe<&2, V>}
3239 {==}
3240
3241def h.gd_same.br(
3242 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3243 +hi: M.HMap<K, V>, +hk: U32, +k: K, b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
3244 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k), hk, k) == None{} : Maybe<&2, V>},
3245 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), hk, k) == None{} : Maybe<&2, V>}
3246) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.db(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k), hk, k) == None{} : Maybe<&2, V>}:
3247 match b:
3248 case True{}:
3249 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
3250 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
3251 %h.get_join(~K, ~V, ~eq, p, mask, dlo, hi, hk, k) : {_ == None{} : Maybe<&2, V>}
3252 %h.g_lo(~K, ~V, ~eq, p, mask, dlo, hi, hk, k, h.sb(True{}, U32.is_eq((hk .&. mask : U32), 0), eb))
3253 : {_ == None{} : Maybe<&2, V>}
3254 il
3255 case False{}:
3256 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
3257 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
3258 %h.get_join(~K, ~V, ~eq, p, mask, lo, dhi, hk, k) : {_ == None{} : Maybe<&2, V>}
3259 %h.g_hi(~K, ~V, ~eq, p, mask, lo, dhi, hk, k, h.sb(False{}, U32.is_eq((hk .&. mask : U32), 0), eb))
3260 : {_ == None{} : Maybe<&2, V>}
3261 ih
3262
3263def h.gd_same(
3264 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3265 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3266 n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K,
3267 +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool}
3268) -> {h.G(~K, ~V, ~eq, n, mask, h.D(~K, ~V, ~eq, n, mask, m, hk, k), hk, k) == None{} : Maybe<&2, V>}:
3269 match n:
3270 case 0n:
3271 match m:
3272 case M.HNil{}:
3273 {==}
3274 case M.HLeaf{+o, +es}:
3275 %h.get_leaf(~K, ~V, ~eq, 0n, mask, o, M.HMap.entries.del(~K, ~V, ~eq, es, k), hk, k) : {_ == None{} : Maybe<&2, V>}
3276 h.eg_del_same(~K, ~V, ~eq, ~sound, es, k, wf)
3277 case M.HBranch{lo, hi}:
3278 {==}
3279 case 1n+(+p):
3280 match m:
3281 case M.HNil{}:
3282 {==}
3283 case M.HLeaf{+o, +es}:
3284 h.gd_same.lf(~K, ~V, ~eq, p, mask, o, es, hk, k, U32.is_eq(o, hk), {==},
3285 h.eg_del_same(~K, ~V, ~eq, ~sound, es, k,
3286 MBool.eq_true_of_and_right(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf)))
3287 case M.HBranch{+lo, +hi}:
3288 h.gd_same.br(~K, ~V, ~eq, p, mask, lo, hi, hk, k, U32.is_eq((hk .&. mask : U32), 0), {==},
3289 h.gd_same(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), lo, hk, k,
3290 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)),
3291 h.gd_same(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), hi, hk, k,
3292 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)))
3293
3294def h.gd_other.lf(
3295 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
3296 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3297 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +k2: K, +hk: U32, +k: K,
3298 +nk: {eq(k, k2) == False{} : Bool}, b: Bool
3299) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.dl(~K, ~V, ~eq, b, o, es, k2), hk, k)
3300 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HLeaf{o, es}, hk, k) : Maybe<&2, V>}:
3301 match b:
3302 case True{}:
3303 %h.get_leaf(~K, ~V, ~eq, 1n+p, mask, o, M.HMap.entries.del(~K, ~V, ~eq, es, k2), hk, k)
3304 : {_ == h.G(~K, ~V, ~eq, 1n+p, mask, M.HLeaf{o, es}, hk, k) : Maybe<&2, V>}
3305 h.bool_l(Maybe<&2, V>, U32.is_eq(o, hk),
3306 h.EG(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, es, k2), k), h.EG(~K, ~V, ~eq, es, k), None{},
3307 h.eg_del_other(~K, ~V, ~eq, ~sound, es, k2, k, nk))
3308 case False{}:
3309 {==}
3310
3311def h.gd_other.br(
3312 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3313 +hi: M.HMap<K, V>, +h2: U32, +k2: K, +hk: U32, +k: K, b: Bool,
3314 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, h2, k2), hk, k)
3315 == h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) : Maybe<&2, V>},
3316 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, h2, k2), hk, k)
3317 == h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) : Maybe<&2, V>}
3318) -> {h.G(~K, ~V, ~eq, 1n+p, mask, h.db(~K, ~V, ~eq, b, p, mask, lo, hi, h2, k2), hk, k)
3319 == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}:
3320 match b:
3321 case True{}:
3322 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, h2, k2)
3323 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, h2, k2)
3324 +d = U32.is_eq((hk .&. mask : U32), 0)
3325 %h.get_join(~K, ~V, ~eq, p, mask, dlo, hi, hk, k)
3326 : {_ == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}
3327 h.bool_l(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, (mask << 1n : U32), dlo, hk, k),
3328 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k), h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), il)
3329 case False{}:
3330 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, h2, k2)
3331 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, h2, k2)
3332 +d = U32.is_eq((hk .&. mask : U32), 0)
3333 %h.get_join(~K, ~V, ~eq, p, mask, lo, dhi, hk, k)
3334 : {_ == h.G(~K, ~V, ~eq, 1n+p, mask, M.HBranch{lo, hi}, hk, k) : Maybe<&2, V>}
3335 h.bool_r(Maybe<&2, V>, d, h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3336 h.G(~K, ~V, ~eq, p, (mask << 1n : U32), dhi, hk, k), h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), ih)
3337
3338def h.gd_other(
3339 ~K: Data, ~V: Data, ~eq: K -> K -> Bool,
3340 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3341 n: Nat, +mask: U32, m: M.HMap<K, V>, +h2: U32, +k2: K, +hk: U32, +k: K,
3342 +nk: {eq(k, k2) == False{} : Bool}
3343) -> {h.G(~K, ~V, ~eq, n, mask, h.D(~K, ~V, ~eq, n, mask, m, h2, k2), hk, k)
3344 == h.G(~K, ~V, ~eq, n, mask, m, hk, k) : Maybe<&2, V>}:
3345 match n:
3346 case 0n:
3347 match m:
3348 case M.HNil{}:
3349 {==}
3350 case M.HLeaf{+o, +es}:
3351 %h.get_leaf(~K, ~V, ~eq, 0n, mask, o, M.HMap.entries.del(~K, ~V, ~eq, es, k2), hk, k)
3352 : {_ == h.EG(~K, ~V, ~eq, es, k) : Maybe<&2, V>}
3353 h.eg_del_other(~K, ~V, ~eq, ~sound, es, k2, k, nk)
3354 case M.HBranch{lo, hi}:
3355 {==}
3356 case 1n+(+p):
3357 match m:
3358 case M.HNil{}:
3359 {==}
3360 case M.HLeaf{+o, +es}:
3361 h.gd_other.lf(~K, ~V, ~eq, ~sound, p, mask, o, es, k2, hk, k, nk, U32.is_eq(o, h2))
3362 case M.HBranch{+lo, +hi}:
3363 h.gd_other.br(~K, ~V, ~eq, p, mask, lo, hi, h2, k2, hk, k, U32.is_eq((h2 .&. mask : U32), 0),
3364 h.gd_other(~K, ~V, ~eq, ~sound, p, (mask << 1n : U32), lo, h2, k2, hk, k, nk),
3365 h.gd_other(~K, ~V, ~eq, ~sound, p, (mask << 1n : U32), hi, h2, k2, hk, k, nk))
3366
3367
3368# size after put and del.
3369def h.split_size.b(
3370 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
3371 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V, b1: Bool, b2: Bool,
3372 ih: {h.Sz(K, V, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v)) == 1n+h.len(K, V, es) : Nat}
3373) -> {h.Sz(K, V, h.sp(~K, ~V, ~eq, b1, b2, p, mask, o, es, hk, k, v)) == 1n+h.len(K, V, es) : Nat}:
3374 match b1 b2:
3375 case True{} True{}:
3376 Ord.tr(Nat.add(h.Sz(K, V, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v)), 0n),
3377 h.Sz(K, V, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v)), 1n+h.len(K, V, es),
3378 MNat.add_zero(h.Sz(K, V, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v))), ih)
3379 case True{} False{}:
3380 ih
3381 case False{} True{}:
3382 Ord.tr(Nat.add(h.len(K, V, es), 1n), 1n+Nat.add(h.len(K, V, es), 0n), 1n+h.len(K, V, es),
3383 MNat.add_succ(h.len(K, V, es), 0n),
3384 Equal.cong(Nat, Nat, x => 1n+x, Nat.add(h.len(K, V, es), 0n), h.len(K, V, es),
3385 MNat.add_zero(h.len(K, V, es))))
3386 case False{} False{}:
3387 {==}
3388
3389def h.split_size(
3390 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, +o: U32,
3391 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V,
3392 +miss: {h.EG(~K, ~V, ~eq, es, k) == None{} : Maybe<&2, V>}
3393) -> {h.Sz(K, V, h.S(~K, ~V, ~eq, n, mask, o, es, hk, k, v)) == 1n+h.len(K, V, es) : Nat}:
3394 match n:
3395 case 0n:
3396 h.elen_put_new(~K, ~V, ~eq, es, k, v, miss)
3397 case 1n+(+p):
3398 h.split_size.b(~K, ~V, ~eq, p, mask, o, es, hk, k, v,
3399 U32.is_eq((o .&. mask : U32), (hk .&. mask : U32)), U32.is_eq((o .&. mask : U32), 0),
3400 h.split_size(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hk, k, v, miss))
3401
3402def h.sz_put_new.lf(
3403 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3404 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3405 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K, +v: V,
3406 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3407 b: Bool, eb: {b == U32.is_eq(o, hash(k)) : Bool},
3408 miss: {h.R(~K, ~V, ~hash, ~eq, o, es, k) == None{} : Maybe<&2, V>}
3409) -> {h.Sz(K, V, h.pl(~K, ~V, ~eq, b, p, mask, o, es, hash(k), k, v)) == 1n+h.len(K, V, es) : Nat}:
3410 match b:
3411 case True{}:
3412 h.elen_put_new(~K, ~V, ~eq, es, k, v,
3413 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == None{} : Maybe<&2, V>},
3414 True{}, U32.is_eq(o, hash(k)), eb, miss))
3415 case False{}:
3416 h.split_size(~K, ~V, ~eq, 1n+p, mask, o, es, hash(k), k, v,
3417 h.eg_none_hashed(~K, ~V, ~hash, ~eq, ~sound, es, o, k, h.sb(False{}, U32.is_eq(o, hash(k)), eb), hs))
3418
3419def h.sz_put_new.br(
3420 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3421 +hi: M.HMap<K, V>, +hk: U32, +k: K, +v: V, b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
3422 miss: {M.HMap.bool(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3423 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3424 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3425 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) == None{} : Maybe<&2, V>}
3426 -> {h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)) == 1n+h.Sz(K, V, lo) : Nat},
3427 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) == None{} : Maybe<&2, V>}
3428 -> {h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)) == 1n+h.Sz(K, V, hi) : Nat}
3429) -> {h.Sz(K, V, h.pb(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k, v))
3430 == 1n+Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}:
3431 match b:
3432 case True{}:
3433 Ord.cong_add(h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)), 1n+h.Sz(K, V, lo),
3434 h.Sz(K, V, hi), h.Sz(K, V, hi),
3435 il(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3436 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3437 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3438 True{}, U32.is_eq((hk .&. mask : U32), 0), eb, miss)),
3439 {==})
3440 case False{}:
3441 Ord.tr(Nat.add(h.Sz(K, V, lo), h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v))),
3442 Nat.add(h.Sz(K, V, lo), 1n+h.Sz(K, V, hi)), 1n+Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)),
3443 Ord.cong_add(h.Sz(K, V, lo), h.Sz(K, V, lo),
3444 h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)), 1n+h.Sz(K, V, hi), {==},
3445 ih(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3446 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3447 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3448 False{}, U32.is_eq((hk .&. mask : U32), 0), eb, miss))),
3449 MNat.add_succ(h.Sz(K, V, lo), h.Sz(K, V, hi)))
3450
3451def h.sz_put_new(
3452 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3453 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3454 n: Nat, +mask: U32, m: M.HMap<K, V>, +k: K, +v: V,
3455 +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool},
3456 miss: {h.G(~K, ~V, ~eq, n, mask, m, hash(k), k) == None{} : Maybe<&2, V>}
3457) -> {h.Sz(K, V, h.P(~K, ~V, ~eq, n, mask, m, hash(k), k, v)) == 1n+h.Sz(K, V, m) : Nat}:
3458 match n:
3459 case 0n:
3460 match m:
3461 case M.HNil{}:
3462 {==}
3463 case M.HLeaf{o, es}:
3464 h.elen_put_new(~K, ~V, ~eq, es, k, v, miss)
3465 case M.HBranch{lo, hi}:
3466 Empty.absurd({h.Sz(K, V, M.HBranch{lo, hi}) == 1n+h.Sz(K, V, M.HBranch{lo, hi}) : Nat}, MBool.false_ne_true()(wf))
3467 case 1n+(+p):
3468 match m:
3469 case M.HNil{}:
3470 {==}
3471 case M.HLeaf{+o, +es}:
3472 h.sz_put_new.lf(~K, ~V, ~hash, ~eq, ~sound, p, mask, o, es, k, v,
3473 MBool.eq_true_of_and_left(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3474 U32.is_eq(o, hash(k)), {==}, miss)
3475 case M.HBranch{+lo, +hi}:
3476 h.sz_put_new.br(~K, ~V, ~eq, p, mask, lo, hi, hash(k), k, v, U32.is_eq((hash(k) .&. mask : U32), 0), {==},
3477 miss,
3478 e => h.sz_put_new(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), lo, k, v,
3479 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf), e),
3480 e => h.sz_put_new(~K, ~V, ~hash, ~eq, ~sound, p, (mask << 1n : U32), hi, k, v,
3481 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf), e))
3482
3483def h.sz_put_hit.lf(
3484 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
3485 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, +v: V, -w: V,
3486 b: Bool, eb: {b == U32.is_eq(o, hk) : Bool},
3487 hit: {M.HMap.bool(Maybe<&2, V>, U32.is_eq(o, hk), u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>}
3488) -> {h.Sz(K, V, h.pl(~K, ~V, ~eq, b, p, mask, o, es, hk, k, v)) == h.len(K, V, es) : Nat}:
3489 match b:
3490 case True{}:
3491 h.elen_put_hit(~K, ~V, ~eq, es, k, v, w,
3492 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>},
3493 True{}, U32.is_eq(o, hk), eb, hit))
3494 case False{}:
3495 h.none_some({h.Sz(K, V, h.S(~K, ~V, ~eq, 1n+p, mask, o, es, hk, k, v)) == h.len(K, V, es) : Nat}, V, w,
3496 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>},
3497 False{}, U32.is_eq(o, hk), eb, hit))
3498
3499def h.sz_put_hit.br(
3500 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3501 +hi: M.HMap<K, V>, +hk: U32, +k: K, +v: V, -w: V, b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
3502 hit: {M.HMap.bool(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3503 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3504 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3505 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) == Some{w} : Maybe<&2, V>}
3506 -> {h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)) == h.Sz(K, V, lo) : Nat},
3507 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) == Some{w} : Maybe<&2, V>}
3508 -> {h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)) == h.Sz(K, V, hi) : Nat}
3509) -> {h.Sz(K, V, h.pb(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k, v))
3510 == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}:
3511 match b:
3512 case True{}:
3513 Ord.cong_add(h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)), h.Sz(K, V, lo),
3514 h.Sz(K, V, hi), h.Sz(K, V, hi),
3515 il(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3516 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3517 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3518 True{}, U32.is_eq((hk .&. mask : U32), 0), eb, hit)),
3519 {==})
3520 case False{}:
3521 Ord.cong_add(h.Sz(K, V, lo), h.Sz(K, V, lo),
3522 h.Sz(K, V, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)), h.Sz(K, V, hi), {==},
3523 ih(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3524 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3525 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3526 False{}, U32.is_eq((hk .&. mask : U32), 0), eb, hit)))
3527
3528def h.sz_put_hit(
3529 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K, +v: V, -w: V,
3530 hit: {h.G(~K, ~V, ~eq, n, mask, m, hk, k) == Some{w} : Maybe<&2, V>}
3531) -> {h.Sz(K, V, h.P(~K, ~V, ~eq, n, mask, m, hk, k, v)) == h.Sz(K, V, m) : Nat}:
3532 match n:
3533 case 0n:
3534 match m:
3535 case M.HNil{}:
3536 h.none_some({h.Sz(K, V, M.HLeaf{hk, [M.Entry{k, v}]}) == 0n : Nat}, V, w, hit)
3537 case M.HLeaf{o, es}:
3538 h.elen_put_hit(~K, ~V, ~eq, es, k, v, w, hit)
3539 case M.HBranch{lo, hi}:
3540 {==}
3541 case 1n+(+p):
3542 match m:
3543 case M.HNil{}:
3544 h.none_some({h.Sz(K, V, M.HLeaf{hk, [M.Entry{k, v}]}) == 0n : Nat}, V, w, hit)
3545 case M.HLeaf{+o, +es}:
3546 h.sz_put_hit.lf(~K, ~V, ~eq, p, mask, o, es, hk, k, v, w, U32.is_eq(o, hk), {==}, hit)
3547 case M.HBranch{+lo, +hi}:
3548 h.sz_put_hit.br(~K, ~V, ~eq, p, mask, lo, hi, hk, k, v, w, U32.is_eq((hk .&. mask : U32), 0), {==}, hit,
3549 e => h.sz_put_hit(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v, w, e),
3550 e => h.sz_put_hit(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v, w, e))
3551
3552def h.sz_del_hit.lf(
3553 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +o: U32,
3554 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K, -w: V,
3555 b: Bool, eb: {b == U32.is_eq(o, hk) : Bool},
3556 hit: {M.HMap.bool(Maybe<&2, V>, U32.is_eq(o, hk), u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>}
3557) -> {1n+h.Sz(K, V, h.dl(~K, ~V, ~eq, b, o, es, k)) == h.len(K, V, es) : Nat}:
3558 match b:
3559 case True{}:
3560 %h.size_leaf(K, V, o, M.HMap.entries.del(~K, ~V, ~eq, es, k)) : {1n+_ == h.len(K, V, es) : Nat}
3561 h.elen_del_hit(~K, ~V, ~eq, es, k, w,
3562 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>},
3563 True{}, U32.is_eq(o, hk), eb, hit))
3564 case False{}:
3565 h.none_some({1n+h.len(K, V, es) == h.len(K, V, es) : Nat}, V, w,
3566 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == Some{w} : Maybe<&2, V>},
3567 False{}, U32.is_eq(o, hk), eb, hit))
3568
3569def h.sz_del_hit.br(
3570 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3571 +hi: M.HMap<K, V>, +hk: U32, +k: K, -w: V, b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
3572 hit: {M.HMap.bool(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3573 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3574 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3575 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) == Some{w} : Maybe<&2, V>}
3576 -> {1n+h.Sz(K, V, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)) == h.Sz(K, V, lo) : Nat},
3577 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) == Some{w} : Maybe<&2, V>}
3578 -> {1n+h.Sz(K, V, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == h.Sz(K, V, hi) : Nat}
3579) -> {1n+h.Sz(K, V, h.db(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k))
3580 == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}:
3581 match b:
3582 case True{}:
3583 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
3584 %h.size_join(K, V, dlo, hi) : {1n+_ == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}
3585 Ord.cong_add(1n+h.Sz(K, V, dlo), h.Sz(K, V, lo), h.Sz(K, V, hi), h.Sz(K, V, hi),
3586 il(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3587 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3588 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3589 True{}, U32.is_eq((hk .&. mask : U32), 0), eb, hit)),
3590 {==})
3591 case False{}:
3592 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
3593 %h.size_join(K, V, lo, dhi) : {1n+_ == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}
3594 %MNat.add_succ(h.Sz(K, V, lo), h.Sz(K, V, dhi)) : {_ == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}
3595 Ord.cong_add(h.Sz(K, V, lo), h.Sz(K, V, lo), 1n+h.Sz(K, V, dhi), h.Sz(K, V, hi), {==},
3596 ih(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3597 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3598 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == Some{w} : Maybe<&2, V>},
3599 False{}, U32.is_eq((hk .&. mask : U32), 0), eb, hit)))
3600
3601def h.sz_del_hit(
3602 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K, -w: V,
3603 hit: {h.G(~K, ~V, ~eq, n, mask, m, hk, k) == Some{w} : Maybe<&2, V>}
3604) -> {1n+h.Sz(K, V, h.D(~K, ~V, ~eq, n, mask, m, hk, k)) == h.Sz(K, V, m) : Nat}:
3605 match n:
3606 case 0n:
3607 match m:
3608 case M.HNil{}:
3609 h.none_some({1n == 0n : Nat}, V, w, hit)
3610 case M.HLeaf{+o, +es}:
3611 %h.size_leaf(K, V, o, M.HMap.entries.del(~K, ~V, ~eq, es, k)) : {1n+_ == h.len(K, V, es) : Nat}
3612 h.elen_del_hit(~K, ~V, ~eq, es, k, w, hit)
3613 case M.HBranch{+lo, +hi}:
3614 h.none_some({1n+h.Sz(K, V, M.HBranch{lo, hi}) == h.Sz(K, V, M.HBranch{lo, hi}) : Nat}, V, w, hit)
3615 case 1n+(+p):
3616 match m:
3617 case M.HNil{}:
3618 h.none_some({1n == 0n : Nat}, V, w, hit)
3619 case M.HLeaf{+o, +es}:
3620 h.sz_del_hit.lf(~K, ~V, ~eq, o, es, hk, k, w, U32.is_eq(o, hk), {==}, hit)
3621 case M.HBranch{+lo, +hi}:
3622 h.sz_del_hit.br(~K, ~V, ~eq, p, mask, lo, hi, hk, k, w, U32.is_eq((hk .&. mask : U32), 0), {==}, hit,
3623 e => h.sz_del_hit(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, w, e),
3624 e => h.sz_del_hit(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, w, e))
3625
3626def h.sz_del_miss.lf(
3627 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +o: U32,
3628 +es: List<&2, M.Entry<K, V>>, +hk: U32, +k: K,
3629 b: Bool, eb: {b == U32.is_eq(o, hk) : Bool},
3630 miss: {M.HMap.bool(Maybe<&2, V>, U32.is_eq(o, hk), u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == None{} : Maybe<&2, V>}
3631) -> {h.Sz(K, V, h.dl(~K, ~V, ~eq, b, o, es, k)) == h.len(K, V, es) : Nat}:
3632 match b:
3633 case True{}:
3634 %h.size_leaf(K, V, o, M.HMap.entries.del(~K, ~V, ~eq, es, k)) : {_ == h.len(K, V, es) : Nat}
3635 Equal.cong(List<&2, M.Entry<K, V>>, Nat, xs => h.len(K, V, xs), M.HMap.entries.del(~K, ~V, ~eq, es, k), es,
3636 h.edel_miss(~K, ~V, ~eq, es, k,
3637 rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z, u => h.EG(~K, ~V, ~eq, es, k), u => None{}) == None{} : Maybe<&2, V>},
3638 True{}, U32.is_eq(o, hk), eb, miss)))
3639 case False{}:
3640 {==}
3641
3642def h.sz_del_miss.br(
3643 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3644 +hi: M.HMap<K, V>, +hk: U32, +k: K, b: Bool, eb: {b == U32.is_eq((hk .&. mask : U32), 0) : Bool},
3645 miss: {M.HMap.bool(Maybe<&2, V>, U32.is_eq((hk .&. mask : U32), 0),
3646 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3647 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3648 il: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k) == None{} : Maybe<&2, V>}
3649 -> {h.Sz(K, V, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)) == h.Sz(K, V, lo) : Nat},
3650 ih: {h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k) == None{} : Maybe<&2, V>}
3651 -> {h.Sz(K, V, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == h.Sz(K, V, hi) : Nat}
3652) -> {h.Sz(K, V, h.db(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k))
3653 == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}:
3654 match b:
3655 case True{}:
3656 +dlo = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)
3657 %h.size_join(K, V, dlo, hi) : {_ == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}
3658 Ord.cong_add(h.Sz(K, V, dlo), h.Sz(K, V, lo), h.Sz(K, V, hi), h.Sz(K, V, hi),
3659 il(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3660 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3661 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3662 True{}, U32.is_eq((hk .&. mask : U32), 0), eb, miss)),
3663 {==})
3664 case False{}:
3665 +dhi = h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)
3666 %h.size_join(K, V, lo, dhi) : {_ == Nat.add(h.Sz(K, V, lo), h.Sz(K, V, hi)) : Nat}
3667 Ord.cong_add(h.Sz(K, V, lo), h.Sz(K, V, lo), h.Sz(K, V, dhi), h.Sz(K, V, hi), {==},
3668 ih(rw(Bool, z => {M.HMap.bool(Maybe<&2, V>, z,
3669 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k),
3670 u => h.G(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == None{} : Maybe<&2, V>},
3671 False{}, U32.is_eq((hk .&. mask : U32), 0), eb, miss)))
3672
3673def h.sz_del_miss(
3674 ~K: Data, ~V: Data, ~eq: K -> K -> Bool, n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K,
3675 miss: {h.G(~K, ~V, ~eq, n, mask, m, hk, k) == None{} : Maybe<&2, V>}
3676) -> {h.Sz(K, V, h.D(~K, ~V, ~eq, n, mask, m, hk, k)) == h.Sz(K, V, m) : Nat}:
3677 match n:
3678 case 0n:
3679 match m:
3680 case M.HNil{}:
3681 {==}
3682 case M.HLeaf{+o, +es}:
3683 %h.size_leaf(K, V, o, M.HMap.entries.del(~K, ~V, ~eq, es, k)) : {_ == h.len(K, V, es) : Nat}
3684 Equal.cong(List<&2, M.Entry<K, V>>, Nat, xs => h.len(K, V, xs), M.HMap.entries.del(~K, ~V, ~eq, es, k), es,
3685 h.edel_miss(~K, ~V, ~eq, es, k, miss))
3686 case M.HBranch{lo, hi}:
3687 {==}
3688 case 1n+(+p):
3689 match m:
3690 case M.HNil{}:
3691 {==}
3692 case M.HLeaf{+o, +es}:
3693 h.sz_del_miss.lf(~K, ~V, ~eq, o, es, hk, k, U32.is_eq(o, hk), {==}, miss)
3694 case M.HBranch{+lo, +hi}:
3695 h.sz_del_miss.br(~K, ~V, ~eq, p, mask, lo, hi, hk, k, U32.is_eq((hk .&. mask : U32), 0), {==}, miss,
3696 e => h.sz_del_miss(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, e),
3697 e => h.sz_del_miss(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, e))
3698
3699# put and del keep the map well formed.
3700def h.wf_fresh(~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, p: Nat, +k: K, +v: V)
3701 -> {h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{hash(k), [M.Entry{k, v}]}) == True{} : Bool}:
3702 match p:
3703 case 0n:
3704 {==}
3705 case 1n+q:
3706 %h.sb(U32.is_eq(hash(k), hash(k)), True{}, h.u_refl(hash(k)))
3707 : {Bool.and(Bool.and(_, True{}), True{}) == True{} : Bool}
3708 {==}
3709
3710def h.wf_leaf_o(
3711 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, p: Nat, +o: U32,
3712 +es: List<&2, M.Entry<K, V>>,
3713 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3714 ds: {Laws.hmap_distinct(~K, ~V, ~eq, es) == True{} : Bool}
3715) -> {h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{o, es}) == True{} : Bool}:
3716 match p:
3717 case 0n:
3718 ds
3719 case 1n+q:
3720 MBool.and_eq_true(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), hs, ds)
3721
3722def h.split_wf.b(
3723 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +o: U32,
3724 +es: List<&2, M.Entry<K, V>>, +k: K, +v: V,
3725 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3726 +ds: {Laws.hmap_distinct(~K, ~V, ~eq, es) == True{} : Bool},
3727 b1: Bool, b2: Bool,
3728 ih: {h.WF(~K, ~V, ~hash, ~eq, p, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hash(k), k, v)) == True{} : Bool}
3729) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.sp(~K, ~V, ~eq, b1, b2, p, mask, o, es, hash(k), k, v)) == True{} : Bool}:
3730 match b1 b2:
3731 case True{} True{}:
3732 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hash(k), k, v)), h.WF(~K, ~V, ~hash, ~eq, p, M.HNil{}), ih, h.wf_nil(~K, ~V, ~hash, ~eq, p))
3733 case True{} False{}:
3734 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HNil{}), h.WF(~K, ~V, ~hash, ~eq, p, h.S(~K, ~V, ~eq, p, (mask << 1n : U32), o, es, hash(k), k, v)), h.wf_nil(~K, ~V, ~hash, ~eq, p), ih)
3735 case False{} True{}:
3736 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{o, es}), h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{hash(k), [M.Entry{k, v}]}), h.wf_leaf_o(~K, ~V, ~hash, ~eq, p, o, es, hs, ds), h.wf_fresh(~K, ~V, ~hash, ~eq, p, k, v))
3737 case False{} False{}:
3738 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{hash(k), [M.Entry{k, v}]}), h.WF(~K, ~V, ~hash, ~eq, p, M.HLeaf{o, es}), h.wf_fresh(~K, ~V, ~hash, ~eq, p, k, v), h.wf_leaf_o(~K, ~V, ~hash, ~eq, p, o, es, hs, ds))
3739
3740def h.split_wf(
3741 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
3742 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3743 n: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K, +v: V,
3744 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3745 +ds: {Laws.hmap_distinct(~K, ~V, ~eq, es) == True{} : Bool}
3746) -> {h.WF(~K, ~V, ~hash, ~eq, n, h.S(~K, ~V, ~eq, n, mask, o, es, hash(k), k, v)) == True{} : Bool}:
3747 match n:
3748 case 0n:
3749 h.distinct_put(~K, ~V, ~eq, ~refl, ~sound, es, k, v, ds)
3750 case 1n+(+p):
3751 h.split_wf.b(~K, ~V, ~hash, ~eq, p, mask, o, es, k, v, hs, ds,
3752 U32.is_eq((o .&. mask : U32), (hash(k) .&. mask : U32)), U32.is_eq((o .&. mask : U32), 0),
3753 h.split_wf(~K, ~V, ~hash, ~eq, ~refl, ~sound, p, (mask << 1n : U32), o, es, k, v, hs, ds))
3754
3755def h.wf_put.lf(
3756 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
3757 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3758 +p: Nat, +mask: U32, +o: U32, +es: List<&2, M.Entry<K, V>>, +k: K, +v: V,
3759 hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3760 ds: {Laws.hmap_distinct(~K, ~V, ~eq, es) == True{} : Bool},
3761 b: Bool, eb: {b == U32.is_eq(o, hash(k)) : Bool},
3762 sp: {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.S(~K, ~V, ~eq, 1n+p, mask, o, es, hash(k), k, v)) == True{} : Bool}
3763) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.pl(~K, ~V, ~eq, b, p, mask, o, es, hash(k), k, v)) == True{} : Bool}:
3764 match b:
3765 case True{}:
3766 MBool.and_eq_true(Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.put(~K, ~V, ~eq, es, k, v), o), Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.put(~K, ~V, ~eq, es, k, v)), h.hashed_put(~K, ~V, ~hash, ~eq, es, o, k, v, h.sb(True{}, U32.is_eq(o, hash(k)), eb), hs), h.distinct_put(~K, ~V, ~eq, ~refl, ~sound, es, k, v, ds))
3767 case False{}:
3768 sp
3769
3770def h.wf_put.br(
3771 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3772 +hi: M.HMap<K, V>, +hk: U32, +k: K, +v: V, b: Bool,
3773 wl: {h.WF(~K, ~V, ~hash, ~eq, p, lo) == True{} : Bool},
3774 wh: {h.WF(~K, ~V, ~hash, ~eq, p, hi) == True{} : Bool},
3775 il: {h.WF(~K, ~V, ~hash, ~eq, p, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)) == True{} : Bool},
3776 ih: {h.WF(~K, ~V, ~hash, ~eq, p, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)) == True{} : Bool}
3777) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.pb(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k, v)) == True{} : Bool}:
3778 match b:
3779 case True{}:
3780 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k, v)), h.WF(~K, ~V, ~hash, ~eq, p, hi), il, wh)
3781 case False{}:
3782 MBool.and_eq_true(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, h.P(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k, v)), wl, ih)
3783
3784def h.wf_put(
3785 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, ~refl: @x: K -> {eq(x, x) == True{} : Bool},
3786 ~sound: @x: K -> @y: K -> {eq(x, y) == True{} : Bool} -> {x == y : K},
3787 n: Nat, +mask: U32, m: M.HMap<K, V>, +k: K, +v: V,
3788 +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool}
3789) -> {h.WF(~K, ~V, ~hash, ~eq, n, h.P(~K, ~V, ~eq, n, mask, m, hash(k), k, v)) == True{} : Bool}:
3790 match n:
3791 case 0n:
3792 match m:
3793 case M.HNil{}:
3794 {==}
3795 case M.HLeaf{o, es}:
3796 h.distinct_put(~K, ~V, ~eq, ~refl, ~sound, es, k, v, wf)
3797 case M.HBranch{lo, hi}:
3798 wf
3799 case 1n+(+p):
3800 match m:
3801 case M.HNil{}:
3802 h.wf_fresh(~K, ~V, ~hash, ~eq, 1n+p, k, v)
3803 case M.HLeaf{+o, +es}:
3804 h.wf_put.lf(~K, ~V, ~hash, ~eq, ~refl, ~sound, p, mask, o, es, k, v,
3805 MBool.eq_true_of_and_left(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3806 MBool.eq_true_of_and_right(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3807 U32.is_eq(o, hash(k)), {==},
3808 h.split_wf(~K, ~V, ~hash, ~eq, ~refl, ~sound, 1n+p, mask, o, es, k, v,
3809 MBool.eq_true_of_and_left(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3810 MBool.eq_true_of_and_right(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf)))
3811 case M.HBranch{+lo, +hi}:
3812 h.wf_put.br(~K, ~V, ~hash, ~eq, p, mask, lo, hi, hash(k), k, v, U32.is_eq((hash(k) .&. mask : U32), 0),
3813 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf),
3814 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf),
3815 h.wf_put(~K, ~V, ~hash, ~eq, ~refl, ~sound, p, (mask << 1n : U32), lo, k, v,
3816 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)),
3817 h.wf_put(~K, ~V, ~hash, ~eq, ~refl, ~sound, p, (mask << 1n : U32), hi, k, v,
3818 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)))
3819
3820def h.wf_del.lf(
3821 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +p: Nat, +o: U32,
3822 +es: List<&2, M.Entry<K, V>>, +k: K,
3823 +hs: {Laws.hmap_hashed(~K, ~V, ~hash, es, o) == True{} : Bool},
3824 +ds: {Laws.hmap_distinct(~K, ~V, ~eq, es) == True{} : Bool}, b: Bool
3825) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.dl(~K, ~V, ~eq, b, o, es, k)) == True{} : Bool}:
3826 match b:
3827 case True{}:
3828 h.wf_leaf(~K, ~V, ~hash, ~eq, 1n+p, o, M.HMap.entries.del(~K, ~V, ~eq, es, k),
3829 MBool.and_eq_true(Laws.hmap_hashed(~K, ~V, ~hash, M.HMap.entries.del(~K, ~V, ~eq, es, k), o), Laws.hmap_distinct(~K, ~V, ~eq, M.HMap.entries.del(~K, ~V, ~eq, es, k)), h.hashed_del(~K, ~V, ~hash, ~eq, es, o, k, hs), h.distinct_del(~K, ~V, ~eq, es, k, ds)))
3830 case False{}:
3831 MBool.and_eq_true(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), hs, ds)
3832
3833def h.wf_del.br(
3834 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool, +p: Nat, +mask: U32, +lo: M.HMap<K, V>,
3835 +hi: M.HMap<K, V>, +hk: U32, +k: K, b: Bool,
3836 wl: {h.WF(~K, ~V, ~hash, ~eq, p, lo) == True{} : Bool},
3837 wh: {h.WF(~K, ~V, ~hash, ~eq, p, hi) == True{} : Bool},
3838 il: {h.WF(~K, ~V, ~hash, ~eq, p, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k)) == True{} : Bool},
3839 ih: {h.WF(~K, ~V, ~hash, ~eq, p, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k)) == True{} : Bool}
3840) -> {h.WF(~K, ~V, ~hash, ~eq, 1n+p, h.db(~K, ~V, ~eq, b, p, mask, lo, hi, hk, k)) == True{} : Bool}:
3841 match b:
3842 case True{}:
3843 h.wf_join(~K, ~V, ~hash, ~eq, p, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), lo, hk, k), hi, il, wh)
3844 case False{}:
3845 h.wf_join(~K, ~V, ~hash, ~eq, p, lo, h.D(~K, ~V, ~eq, p, (mask << 1n : U32), hi, hk, k), wl, ih)
3846
3847def h.wf_del(
3848 ~K: Data, ~V: Data, ~hash: K -> U32, ~eq: K -> K -> Bool,
3849 n: Nat, +mask: U32, m: M.HMap<K, V>, +hk: U32, +k: K,
3850 +wf: {h.WF(~K, ~V, ~hash, ~eq, n, m) == True{} : Bool}
3851) -> {h.WF(~K, ~V, ~hash, ~eq, n, h.D(~K, ~V, ~eq, n, mask, m, hk, k)) == True{} : Bool}:
3852 match n:
3853 case 0n:
3854 match m:
3855 case M.HNil{}:
3856 {==}
3857 case M.HLeaf{+o, +es}:
3858 h.wf_leaf(~K, ~V, ~hash, ~eq, 0n, o, M.HMap.entries.del(~K, ~V, ~eq, es, k),
3859 h.distinct_del(~K, ~V, ~eq, es, k, wf))
3860 case M.HBranch{lo, hi}:
3861 wf
3862 case 1n+(+p):
3863 match m:
3864 case M.HNil{}:
3865 {==}
3866 case M.HLeaf{+o, +es}:
3867 h.wf_del.lf(~K, ~V, ~hash, ~eq, p, o, es, k,
3868 MBool.eq_true_of_and_left(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3869 MBool.eq_true_of_and_right(Laws.hmap_hashed(~K, ~V, ~hash, es, o), Laws.hmap_distinct(~K, ~V, ~eq, es), wf),
3870 U32.is_eq(o, hk))
3871 case M.HBranch{+lo, +hi}:
3872 h.wf_del.br(~K, ~V, ~hash, ~eq, p, mask, lo, hi, hk, k, U32.is_eq((hk .&. mask : U32), 0),
3873 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf),
3874 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf),
3875 h.wf_del(~K, ~V, ~hash, ~eq, p, (mask << 1n : U32), lo, hk, k,
3876 MBool.eq_true_of_and_left(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)),
3877 h.wf_del(~K, ~V, ~hash, ~eq, p, (mask << 1n : U32), hi, hk, k,
3878 MBool.eq_true_of_and_right(h.WF(~K, ~V, ~hash, ~eq, p, lo), h.WF(~K, ~V, ~hash, ~eq, p, hi), wf)))
3879
3880# --- hmap laws -------------------------------------------------------------------
3881
3882def Laws.hmap_new_wf(K, V, hash, eq):
3883 {==}
3884
3885def Laws.hmap_put_wf(K, V, hash, eq, refl, sound, m, wf, k, v):
3886 h.wf_put(~K, ~V, ~hash, ~eq, ~refl, ~sound, 32n, 1, m, k, v, wf)
3887
3888def Laws.hmap_del_wf(K, V, hash, eq, m, wf, k):
3889 h.wf_del(~K, ~V, ~hash, ~eq, 32n, 1, m, hash(k), k, wf)
3890
3891def Laws.hmap_get_put_same(K, V, hash, eq, refl, m, wf, k, v):
3892 h.gp_same(~K, ~V, ~hash, ~eq, ~refl, 32n, 1, m, hash(k), k, v, {==}, wf)
3893
3894def Laws.hmap_get_put_other_key(K, V, hash, eq, sound, m, wf, k2, k, ne, v):
3895 h.gp_other(~K, ~V, ~hash, ~eq, ~sound, 32n, 1, m, hash(k2), k2, k, v, wf,
3896 h.ne_f(~K, ~eq, ~sound, k2, k, ne))
3897
3898def Laws.hmap_get_del_same(K, V, hash, eq, sound, m, wf, k):
3899 h.gd_same(~K, ~V, ~hash, ~eq, ~sound, 32n, 1, m, hash(k), k, wf)
3900
3901def Laws.hmap_get_del_other_key(K, V, hash, eq, sound, m, k2, k, ne):
3902 h.gd_other(~K, ~V, ~eq, ~sound, 32n, 1, m, hash(k2), k2, hash(k), k, h.ne_f(~K, ~eq, ~sound, k2, k, ne))
3903
3904def Laws.hmap_size_put_new(K, V, hash, eq, sound, m, wf, k, v, miss):
3905 h.sz_put_new(~K, ~V, ~hash, ~eq, ~sound, 32n, 1, m, k, v, wf, miss)
3906
3907def Laws.hmap_size_put_replace(K, V, hash, eq, m, k, v, w, hit):
3908 h.sz_put_hit(~K, ~V, ~eq, 32n, 1, m, hash(k), k, v, w, hit)
3909
3910def Laws.hmap_size_del(K, V, hash, eq, m, k, w, hit):
3911 h.sz_del_hit(~K, ~V, ~eq, 32n, 1, m, hash(k), k, w, hit)
3912
3913def Laws.hmap_size_del_missing(K, V, hash, eq, m, k, miss):
3914 h.sz_del_miss(~K, ~V, ~eq, 32n, 1, m, hash(k), k, miss)
3915
3916def Laws.hmap_collision_get(K, V, hash, eq, refl, sound, m, wf, k1, k2, ne, same, v1, v2):
3917 +m1 = M.HMap.put(~K, ~V, ~hash, ~eq, m, k1, v1)
3918 Equal.trans(Maybe<&2, V>,
3919 M.HMap.get(~K, ~V, ~hash, ~eq, M.HMap.put(~K, ~V, ~hash, ~eq, m1, k2, v2), k1),
3920 M.HMap.get(~K, ~V, ~hash, ~eq, m1, k1), Some{v1},
3921 h.gp_other(~K, ~V, ~hash, ~eq, ~sound, 32n, 1, m1, hash(k2), k2, k1, v2,
3922 h.wf_put(~K, ~V, ~hash, ~eq, ~refl, ~sound, 32n, 1, m, k1, v1, wf),
3923 h.ne_f(~K, ~eq, ~sound, k2, k1, ne)),
3924 h.gp_same(~K, ~V, ~hash, ~eq, ~refl, 32n, 1, m, hash(k1), k1, v1, {==}, wf))
3925
3926def Laws.hmap_collision_size(K, V, hash, eq, refl, sound, m, wf, k1, k2, ne, same, v1, v2, miss1, miss2):
3927 +m1 = M.HMap.put(~K, ~V, ~hash, ~eq, m, k1, v1)
3928 Equal.trans(Nat, M.HMap.size(K, V, M.HMap.put(~K, ~V, ~hash, ~eq, m1, k2, v2)),
3929 1n+M.HMap.size(K, V, m1), 2n+M.HMap.size(K, V, m),
3930 Laws.hmap_size_put_new(~K, ~V, ~hash, ~eq, ~sound, m1,
3931 Laws.hmap_put_wf(~K, ~V, ~hash, ~eq, ~refl, ~sound, m, wf, k1, v1), k2, v2,
3932 Equal.trans(Maybe<&2, V>, M.HMap.get(~K, ~V, ~hash, ~eq, m1, k2),
3933 M.HMap.get(~K, ~V, ~hash, ~eq, m, k2), None{},
3934 Laws.hmap_get_put_other_key(~K, ~V, ~hash, ~eq, ~sound, m, wf, k1, k2, ne, v1), miss2)),
3935 Equal.cong(Nat, Nat, x => 1n+x, M.HMap.size(K, V, m1), 1n+M.HMap.size(K, V, m),
3936 Laws.hmap_size_put_new(~K, ~V, ~hash, ~eq, ~sound, m, wf, k1, v1, miss1)))
3937
3938# --- string order ----------------------------------------------------------------
3939
3940# A comparison equal to LT is not one whose is_lt is False.
3941def lt_absurd(-A: Type, -c: Cmp, f: {Cmp.is_lt(c) == False{} : Bool}, e: {c == LT{} : Cmp}) -> A:
3942 Empty.absurd(A, MBool.false_ne_true()(Equal.trans(Bool, False{}, Cmp.is_lt(c), True{},
3943 Equal.sym(Bool, Cmp.is_lt(c), False{}, f), lt_true(c, e))))
3944
3945def ncmp_refl(n: Nat) -> {Nat.cmp(n, n) == EQ{} : Cmp}:
3946 match n:
3947 case 0n:
3948 {==}
3949 case 1n+p:
3950 ncmp_refl(p)
3951
3952def ncmp_eq(a: Nat, b: Nat, e: {Nat.cmp(a, b) == EQ{} : Cmp}) -> {a == b : Nat}:
3953 match a b:
3954 case 0n 0n:
3955 {==}
3956 case 0n 1n+q:
3957 ne_absurd({0n == 1n+q : Nat}, LT{}, {==}, e)
3958 case 1n+p 0n:
3959 ne_absurd({1n+p == 0n : Nat}, GT{}, {==}, e)
3960 case 1n+p 1n+q:
3961 %ncmp_eq(p, q, e) : {1n+p == 1n+_ : Nat}
3962 {==}
3963
3964def ncmp_flip(a: Nat, b: Nat) -> {Nat.cmp(b, a) == Laws.flip(Nat.cmp(a, b)) : Cmp}:
3965 match a b:
3966 case 0n 0n:
3967 {==}
3968 case 0n 1n+q:
3969 {==}
3970 case 1n+p 0n:
3971 {==}
3972 case 1n+p 1n+q:
3973 ncmp_flip(p, q)
3974
3975def ncmp_trans(
3976 a: Nat, b: Nat, c: Nat, e1: {Nat.cmp(a, b) == LT{} : Cmp}, e2: {Nat.cmp(b, c) == LT{} : Cmp}
3977) -> {Nat.cmp(a, c) == LT{} : Cmp}:
3978 match a b c:
3979 case 0n 0n _:
3980 lt_absurd({Nat.cmp(0n, c) == LT{} : Cmp}, EQ{}, {==}, e1)
3981 case 1n+p 0n _:
3982 lt_absurd({Nat.cmp(1n+p, c) == LT{} : Cmp}, GT{}, {==}, e1)
3983 case _ 1n+q 0n:
3984 lt_absurd({Nat.cmp(a, 0n) == LT{} : Cmp}, GT{}, {==}, e2)
3985 case 0n 1n+q 1n+r:
3986 {==}
3987 case 1n+p 1n+q 1n+r:
3988 ncmp_trans(p, q, r, e1, e2)
3989
3990def ucmp_nat(+a: U32, +b: U32) -> {Nat.cmp(U32.to_nat(a), U32.to_nat(b)) == U32.cmp(a, b) : Cmp}:
3991 Equal.sym(Cmp, U32.cmp(a, b), Nat.cmp(U32.to_nat(a), U32.to_nat(b)), Lemmas.u32_cmp_nat(a, b))
3992
3993def ucmp_refl(+x: U32) -> {U32.cmp(x, x) == EQ{} : Cmp}:
3994 %ucmp_nat(x, x) : {_ == EQ{} : Cmp}
3995 ncmp_refl(U32.to_nat(x))
3996
3997def ucmp_eq(+x: U32, +y: U32, e: {U32.cmp(x, y) == EQ{} : Cmp}) -> {x == y : U32}:
3998 Lemmas.u32_to_nat_inj(x, y, ncmp_eq(U32.to_nat(x), U32.to_nat(y),
3999 Equal.trans(Cmp, Nat.cmp(U32.to_nat(x), U32.to_nat(y)), U32.cmp(x, y), EQ{}, ucmp_nat(x, y), e)))
4000
4001def ucmp_flip(+x: U32, +y: U32) -> {U32.cmp(y, x) == Laws.flip(U32.cmp(x, y)) : Cmp}:
4002 %ucmp_nat(y, x) : {_ == Laws.flip(U32.cmp(x, y)) : Cmp}
4003 %ucmp_nat(x, y) : {Nat.cmp(U32.to_nat(y), U32.to_nat(x)) == Laws.flip(_) : Cmp}
4004 ncmp_flip(U32.to_nat(x), U32.to_nat(y))
4005
4006def ucmp_lt(+x: U32, +y: U32, e: {U32.cmp(x, y) == LT{} : Cmp}) -> {Nat.cmp(U32.to_nat(x), U32.to_nat(y)) == LT{} : Cmp}:
4007 Equal.trans(Cmp, Nat.cmp(U32.to_nat(x), U32.to_nat(y)), U32.cmp(x, y), LT{}, ucmp_nat(x, y), e)
4008
4009def ucmp_trans(
4010 +x: U32, +y: U32, +z: U32, e1: {U32.cmp(x, y) == LT{} : Cmp}, e2: {U32.cmp(y, z) == LT{} : Cmp}
4011) -> {U32.cmp(x, z) == LT{} : Cmp}:
4012 %ucmp_nat(x, z) : {_ == LT{} : Cmp}
4013 ncmp_trans(U32.to_nat(x), U32.to_nat(y), U32.to_nat(z), ucmp_lt(x, y, e1), ucmp_lt(y, z, e2))
4014
4015def Laws.order_string_refl(x):
4016 match x:
4017 case SNil{}:
4018 {==}
4019 case SCon{Chr{+c}, t}:
4020 %Equal.sym(Cmp, U32.cmp(c, c), EQ{}, ucmp_refl(c)) : {Order.string.fin(_, Order.string(t, t)) == EQ{} : Cmp}
4021 Laws.order_string_refl(t)
4022
4023# One step of eq on the heads a and b, with the tails' result as ih.
4024def seq.step(
4025 +a: U32, +b: U32, +s: String, +t: String, c: Cmp, h: {U32.cmp(a, b) == c : Cmp},
4026 e: {Order.string.fin(c, Order.string(s, t)) == EQ{} : Cmp},
4027 ih: {Order.string(s, t) == EQ{} : Cmp} -> {s == t : String}
4028) -> {SCon{Chr{a}, s} == SCon{Chr{b}, t} : String}:
4029 match c:
4030 case LT{}:
4031 ne_absurd({SCon{Chr{a}, s} == SCon{Chr{b}, t} : String}, LT{}, {==}, e)
4032 case EQ{}:
4033 +ea = ucmp_eq(a, b, h)
4034 +es = ih(e)
4035 %ea : {SCon{Chr{a}, s} == SCon{Chr{_}, t} : String}
4036 %es : {SCon{Chr{a}, s} == SCon{Chr{a}, _} : String}
4037 {==}
4038 case GT{}:
4039 ne_absurd({SCon{Chr{a}, s} == SCon{Chr{b}, t} : String}, GT{}, {==}, e)
4040
4041def Laws.order_string_eq(x, y, e):
4042 match x y:
4043 case SNil{} SNil{}:
4044 {==}
4045 case SNil{} SCon{Chr{b}, t}:
4046 ne_absurd({SNil{} == SCon{Chr{b}, t} : String}, LT{}, {==}, e)
4047 case SCon{Chr{a}, s} SNil{}:
4048 ne_absurd({SCon{Chr{a}, s} == SNil{} : String}, GT{}, {==}, e)
4049 case SCon{Chr{+a}, +s} SCon{Chr{+b}, +t}:
4050 seq.step(a, b, s, t, U32.cmp(a, b), {==}, e, p => Laws.order_string_eq(s, t, p))
4051
4052def sfin_flip(c: Cmp, -r: Cmp) -> {Order.string.fin(Laws.flip(c), Laws.flip(r)) == Laws.flip(Order.string.fin(c, r)) : Cmp}:
4053 match c:
4054 case LT{}:
4055 {==}
4056 case EQ{}:
4057 {==}
4058 case GT{}:
4059 {==}
4060
4061def Laws.order_string_flip(x, y):
4062 match x y:
4063 case SNil{} SNil{}:
4064 {==}
4065 case SNil{} SCon{Chr{b}, t}:
4066 {==}
4067 case SCon{Chr{a}, s} SNil{}:
4068 {==}
4069 case SCon{Chr{+a}, +s} SCon{Chr{+b}, +t}:
4070 %Equal.sym(Cmp, U32.cmp(b, a), Laws.flip(U32.cmp(a, b)), ucmp_flip(a, b)) :
4071 {Order.string.fin(_, Order.string(t, s)) == Laws.flip(Order.string.fin(U32.cmp(a, b), Order.string(s, t))) : Cmp}
4072 %Equal.sym(Cmp, Order.string(t, s), Laws.flip(Order.string(s, t)), Laws.order_string_flip(s, t)) :
4073 {Order.string.fin(Laws.flip(U32.cmp(a, b)), _) == Laws.flip(Order.string.fin(U32.cmp(a, b), Order.string(s, t))) : Cmp}
4074 sfin_flip(U32.cmp(a, b), Order.string(s, t))
4075
4076# One step of transitivity on the heads a < b < c, with the tails' result as ih.
4077def strans.step(
4078 +a: U32, +b: U32, +c: U32, -s: String, -t: String, -u: String, c1: Cmp, c2: Cmp,
4079 h1: {U32.cmp(a, b) == c1 : Cmp}, h2: {U32.cmp(b, c) == c2 : Cmp},
4080 e1: {Order.string.fin(c1, Order.string(s, t)) == LT{} : Cmp},
4081 e2: {Order.string.fin(c2, Order.string(t, u)) == LT{} : Cmp},
4082 ih: {Order.string(s, t) == LT{} : Cmp} -> {Order.string(t, u) == LT{} : Cmp} -> {Order.string(s, u) == LT{} : Cmp}
4083) -> {Order.string.fin(U32.cmp(a, c), Order.string(s, u)) == LT{} : Cmp}:
4084 match c1 c2:
4085 case LT{} LT{}:
4086 %Equal.sym(Cmp, U32.cmp(a, c), LT{}, ucmp_trans(a, b, c, h1, h2)) : {Order.string.fin(_, Order.string(s, u)) == LT{} : Cmp}
4087 {==}
4088 case LT{} EQ{}:
4089 +ebc = ucmp_eq(b, c, h2)
4090 +eac = rw(U32, w => {U32.cmp(a, w) == LT{} : Cmp}, c, b, Equal.sym(U32, b, c, ebc), h1)
4091 %Equal.sym(Cmp, U32.cmp(a, c), LT{}, eac) : {Order.string.fin(_, Order.string(s, u)) == LT{} : Cmp}
4092 {==}
4093 case EQ{} LT{}:
4094 +eab = ucmp_eq(a, b, h1)
4095 +eac = rw(U32, w => {U32.cmp(w, c) == LT{} : Cmp}, a, b, eab, h2)
4096 %Equal.sym(Cmp, U32.cmp(a, c), LT{}, eac) : {Order.string.fin(_, Order.string(s, u)) == LT{} : Cmp}
4097 {==}
4098 case EQ{} EQ{}:
4099 +eca = Equal.sym(U32, a, c, Equal.trans(U32, a, b, c, ucmp_eq(a, b, h1), ucmp_eq(b, c, h2)))
4100 +eac = rw(U32, w => {U32.cmp(a, w) == EQ{} : Cmp}, c, a, eca, ucmp_refl(a))
4101 %Equal.sym(Cmp, U32.cmp(a, c), EQ{}, eac) : {Order.string.fin(_, Order.string(s, u)) == LT{} : Cmp}
4102 ih(e1, e2)
4103 case GT{} _:
4104 lt_absurd({Order.string.fin(U32.cmp(a, c), Order.string(s, u)) == LT{} : Cmp}, GT{}, {==}, e1)
4105 case _ GT{}:
4106 lt_absurd({Order.string.fin(U32.cmp(a, c), Order.string(s, u)) == LT{} : Cmp}, GT{}, {==}, e2)
4107
4108def Laws.order_string_trans(x, y, z, e1, e2):
4109 match x y z:
4110 case SNil{} SNil{} _:
4111 lt_absurd({Order.string(SNil{}, z) == LT{} : Cmp}, EQ{}, {==}, e1)
4112 case SCon{Chr{a}, s} SNil{} _:
4113 lt_absurd({Order.string(SCon{Chr{a}, s}, z) == LT{} : Cmp}, GT{}, {==}, e1)
4114 case SNil{} SCon{Chr{b}, t} SNil{}:
4115 lt_absurd({Order.string(SNil{}, SNil{}) == LT{} : Cmp}, GT{}, {==}, e2)
4116 case SCon{Chr{a}, s} SCon{Chr{b}, t} SNil{}:
4117 lt_absurd({Order.string(SCon{Chr{a}, s}, SNil{}) == LT{} : Cmp}, GT{}, {==}, e2)
4118 case SNil{} SCon{Chr{b}, t} SCon{Chr{c}, u}:
4119 {==}
4120 case SCon{Chr{+a}, +s} SCon{Chr{+b}, +t} SCon{Chr{+c}, +u}:
4121 strans.step(a, b, c, s, t, u, U32.cmp(a, b), U32.cmp(b, c), {==}, {==}, e1, e2,
4122 p => q => Laws.order_string_trans(s, t, u, p, q))
4123
4124def Laws.order_string_fixtures():
4125 {==}