proofs/lib/lemmas/proofs/map_bridge.bend
bend-collections-laws-crypto@1.0.0.0 · 417 lines · 26 definitions
1import Base
2
3
4
5
6
7
8
9
10
11
12
13
14def routed_key(r: String & Bool) -> String:
15 (key, bit) = r
16 key
17
18law recursive_bit_key:
19 for c: Char
20 for r: String & Bool
21 {routed_key(Map.bit.go.rec(c, r)) == SCon{c, routed_key(r)} : String}
22def recursive_bit_key(c, r):
23 match r:
24 case Tuple{key, bit}:
25 {==}
26
27law bit_go_preserves_key:
28 for key: String
29 for +character: Nat
30 for +offset: Nat
31 {routed_key(Map.bit.go(key, character, offset)) == key : String}
32def bit_go_preserves_key(key, character, offset):
33 match key character offset:
34 case SNil{} ci off:
35 {==}
36 case SCon{Chr{x}, tail} 0n 0n:
37 {==}
38 case SCon{Chr{x}, tail} 0n 1n+off:
39 {==}
40 case SCon{Chr{x}, +tail} 1n+ci off:
41 +c = {Chr{x} : Char}
42 Equal.trans(String, routed_key(Map.bit.go.rec(c, Map.bit.go(tail, ci, off))),
43 SCon{c, routed_key(Map.bit.go(tail, ci, off))}, SCon{c, tail},
44 recursive_bit_key(c, Map.bit.go(tail, ci, off)),
45 Equal.cong(String, String, t => SCon{c, t}, routed_key(Map.bit.go(tail, ci, off)), tail, bit_go_preserves_key(tail, ci, off)))
46
47law bit_at_preserves_key:
48 for key: String
49 for coordinates: Nat & Nat
50 {routed_key(Map.bit.at(key, coordinates)) == key : String}
51def bit_at_preserves_key(key, coordinates):
52 match coordinates:
53 case Tuple{ci, off}:
54 bit_go_preserves_key(key, ci, off)
55
56law bit_preserves_key:
57 for key: String
58 for position: Nat
59 {routed_key(Map.bit(key, position)) == key : String}
60def bit_preserves_key(key, position):
61 bit_at_preserves_key(key, Nat.divmod(position, 33n))
62
63
64
65def get_bit(-V: Data, d: V, lo: Map<&2, V>, hi: Map<&2, V>, p2: Nat, kb: String & Bool) -> Map<&2, V> & V:
66 (key2, b) = kb
67 match b:
68 case False{}:
69 Map.lo(&2, V, V, p2, hi, Map.get(V, d, lo, key2))
70 case True{}:
71 Map.hi(&2, V, V, p2, lo, Map.get(V, d, hi, key2))
72
73def has_bit(-a: Quant, -V: Kind(a), lo: Map<a, V>, hi: Map<a, V>, p2: Nat, kb: String & Bool) -> Map<a, V> & Bool:
74 (key2, b) = kb
75 match b:
76 case False{}:
77 Map.lo(a, V, Bool, p2, hi, Map.has(a, V, lo, key2))
78 case True{}:
79 Map.hi(a, V, Bool, p2, lo, Map.has(a, V, hi, key2))
80
81def put_bit(-a: Quant, -V: Kind(a), x: V, p2: Nat, lo: Map<a, V>, hi: Map<a, V>, kb: String & Bool) -> Map<a, V>:
82 (key2, b) = kb
83 match b:
84 case False{}:
85 MNode{p2, Map.put(a, V, lo, key2, x), hi}
86 case True{}:
87 MNode{p2, lo, Map.put(a, V, hi, key2, x)}
88
89def pop_bit(-a: Quant, -V: Kind(a), lo: Map<a, V>, hi: Map<a, V>, p2: Nat, kb: String & Bool) -> Map<a, V> & Maybe<a, V>:
90 (key2, b) = kb
91 match b:
92 case False{}:
93 Map.pop.lo(a, V, p2, hi, Map.pop(a, V, lo, key2))
94 case True{}:
95 Map.pop.hi(a, V, p2, lo, Map.pop(a, V, hi, key2))
96
97def seek_bit(-a: Quant, -V: Kind(a), lo: Map<a, V>, hi: Map<a, V>, p2: Nat, kb: String & Bool) -> Map<a, V> & String & Maybe<&2, String>:
98 (key2, b) = kb
99 match b:
100 case False{}:
101 Map.lo(a, V, String & Maybe<&2, String>, p2, hi, Map.seek(a, V, lo, key2))
102 case True{}:
103 Map.hi(a, V, String & Maybe<&2, String>, p2, lo, Map.seek(a, V, hi, key2))
104
105def ins_deep(-a: Quant, -V: Kind(a), x: V, lo: Map<a, V>, hi: Map<a, V>, pb: Nat, qb: Nat, kb: String & Bool) -> Map<a, V>:
106 (key2, b) = kb
107 match b:
108 case False{}:
109 MNode{qb, Map.ins(a, V, lo, key2, x, pb), hi}
110 case True{}:
111 MNode{qb, lo, Map.ins(a, V, hi, key2, x, pb)}
112
113def ins_if(-a: Quant, -V: Kind(a), key: String, x: V, lo: Map<a, V>, hi: Map<a, V>, +p2: Nat, pb: Nat, t: Bool) -> Map<a, V>:
114 match t:
115 case False{}:
116 Map.ins.splice(a, V, pb, key, x, MNode{p2, lo, hi})
117 case True{}:
118 ins_deep(a, V, x, lo, hi, pb, p2, Map.bit(key, p2))
119
120
121
122law get_go_bridge:
123 for -V: Data
124 for d: V
125for +p: Nat
126 for lo: Map<&2, V>
127 for hi: Map<&2, V>
128 for kb: String & Bool
129 {Map.get.go(V, MNode{p, lo, hi}, d, kb) == get_bit(V, d, lo, hi, p, kb) : Map<&2, V> & V}
130def get_go_bridge(V, d, p, lo, hi, kb):
131 match lo hi kb:
132 case MTip{} _ Tuple{key2, False{}}:
133 {==}
134 case MLeaf{k, v} _ Tuple{key2, False{}}:
135 {==}
136 case MNode{q, c, e} _ Tuple{key2, False{}}:
137 {==}
138 case _ MTip{} Tuple{key2, True{}}:
139 {==}
140 case _ MLeaf{k, v} Tuple{key2, True{}}:
141 {==}
142 case _ MNode{q, c, e} Tuple{key2, True{}}:
143 {==}
144
145law get_node:
146 for -V: Data
147 for d: V
148for +p: Nat
149 for lo: Map<&2, V>
150 for hi: Map<&2, V>
151 for key: String
152 {Map.get(V, d, MNode{p, lo, hi}, key) == get_bit(V, d, lo, hi, p, Map.bit(key, p)) : Map<&2, V> & V}
153def get_node(V, d, p, lo, hi, key):
154 get_go_bridge(V, d, p, lo, hi, Map.bit(key, p))
155
156law has_go_bridge:
157 for -a: Quant
158 for -V: Kind(a)
159 for +p: Nat
160 for lo: Map<a, V>
161 for hi: Map<a, V>
162 for kb: String & Bool
163 {Map.has.go(a, V, MNode{p, lo, hi}, kb) == has_bit(a, V, lo, hi, p, kb) : Map<a, V> & Bool}
164def has_go_bridge(a, V, p, lo, hi, kb):
165 match lo hi kb:
166 case MTip{} _ Tuple{key2, False{}}:
167 {==}
168 case MLeaf{k, v} _ Tuple{key2, False{}}:
169 {==}
170 case MNode{q, c, e} _ Tuple{key2, False{}}:
171 {==}
172 case _ MTip{} Tuple{key2, True{}}:
173 {==}
174 case _ MLeaf{k, v} Tuple{key2, True{}}:
175 {==}
176 case _ MNode{q, c, e} Tuple{key2, True{}}:
177 {==}
178
179law has_node:
180 for -a: Quant
181 for -V: Kind(a)
182 for +p: Nat
183 for lo: Map<a, V>
184 for hi: Map<a, V>
185 for key: String
186 {Map.has(a, V, MNode{p, lo, hi}, key) == has_bit(a, V, lo, hi, p, Map.bit(key, p)) : Map<a, V> & Bool}
187def has_node(a, V, p, lo, hi, key):
188 has_go_bridge(a, V, p, lo, hi, Map.bit(key, p))
189
190law put_go_bridge:
191 for -a: Quant
192 for -V: Kind(a)
193 for x: V
194for +p: Nat
195 for lo: Map<a, V>
196 for hi: Map<a, V>
197 for kb: String & Bool
198 {Map.put.go(a, V, MNode{p, lo, hi}, x, kb) == put_bit(a, V, x, p, lo, hi, kb) : Map<a, V>}
199def put_go_bridge(a, V, x, p, lo, hi, kb):
200 match lo hi kb:
201 case MTip{} _ Tuple{key2, False{}}:
202 {==}
203 case MLeaf{k, v} _ Tuple{key2, False{}}:
204 {==}
205 case MNode{q, c, e} _ Tuple{key2, False{}}:
206 {==}
207 case _ MTip{} Tuple{key2, True{}}:
208 {==}
209 case _ MLeaf{k, v} Tuple{key2, True{}}:
210 {==}
211 case _ MNode{q, c, e} Tuple{key2, True{}}:
212 {==}
213
214law put_node:
215 for -a: Quant
216 for -V: Kind(a)
217 for x: V
218for +p: Nat
219 for lo: Map<a, V>
220 for hi: Map<a, V>
221 for key: String
222 {Map.put(a, V, MNode{p, lo, hi}, key, x) == put_bit(a, V, x, p, lo, hi, Map.bit(key, p)) : Map<a, V>}
223def put_node(a, V, x, p, lo, hi, key):
224 put_go_bridge(a, V, x, p, lo, hi, Map.bit(key, p))
225
226law pop_go_bridge:
227 for -a: Quant
228 for -V: Kind(a)
229 for +p: Nat
230 for lo: Map<a, V>
231 for hi: Map<a, V>
232 for kb: String & Bool
233 {Map.pop.go(a, V, MNode{p, lo, hi}, kb) == pop_bit(a, V, lo, hi, p, kb) : Map<a, V> & Maybe<a, V>}
234def pop_go_bridge(a, V, p, lo, hi, kb):
235 match lo hi kb:
236 case MTip{} _ Tuple{key2, False{}}:
237 {==}
238 case MLeaf{k, v} _ Tuple{key2, False{}}:
239 {==}
240 case MNode{q, c, e} _ Tuple{key2, False{}}:
241 {==}
242 case _ MTip{} Tuple{key2, True{}}:
243 {==}
244 case _ MLeaf{k, v} Tuple{key2, True{}}:
245 {==}
246 case _ MNode{q, c, e} Tuple{key2, True{}}:
247 {==}
248
249law pop_node:
250 for -a: Quant
251 for -V: Kind(a)
252 for +p: Nat
253 for lo: Map<a, V>
254 for hi: Map<a, V>
255 for key: String
256 {Map.pop(a, V, MNode{p, lo, hi}, key) == pop_bit(a, V, lo, hi, p, Map.bit(key, p)) : Map<a, V> & Maybe<a, V>}
257def pop_node(a, V, p, lo, hi, key):
258 pop_go_bridge(a, V, p, lo, hi, Map.bit(key, p))
259
260law seek_go_bridge:
261 for -a: Quant
262 for -V: Kind(a)
263 for +p: Nat
264 for lo: Map<a, V>
265 for hi: Map<a, V>
266 for kb: String & Bool
267 {Map.seek.go(a, V, MNode{p, lo, hi}, kb) == seek_bit(a, V, lo, hi, p, kb) : Map<a, V> & String & Maybe<&2, String>}
268def seek_go_bridge(a, V, p, lo, hi, kb):
269 match lo hi kb:
270 case MTip{} _ Tuple{key2, False{}}:
271 {==}
272 case MLeaf{k, v} _ Tuple{key2, False{}}:
273 {==}
274 case MNode{q, c, e} _ Tuple{key2, False{}}:
275 {==}
276 case _ MTip{} Tuple{key2, True{}}:
277 {==}
278 case _ MLeaf{k, v} Tuple{key2, True{}}:
279 {==}
280 case _ MNode{q, c, e} Tuple{key2, True{}}:
281 {==}
282
283law seek_node:
284 for -a: Quant
285 for -V: Kind(a)
286 for +p: Nat
287 for lo: Map<a, V>
288 for hi: Map<a, V>
289 for key: String
290 {Map.seek(a, V, MNode{p, lo, hi}, key) == seek_bit(a, V, lo, hi, p, Map.bit(key, p)) : Map<a, V> & String & Maybe<&2, String>}
291def seek_node(a, V, p, lo, hi, key):
292 seek_go_bridge(a, V, p, lo, hi, Map.bit(key, p))
293
294law ins_splice_bridge:
295 for -a: Quant
296 for -V: Kind(a)
297 for +q: Nat
298 for lo: Map<a, V>
299 for hi: Map<a, V>
300 for x: V
301 for +p: Nat
302 for key: String
303 for kb: String & Bool
304 for hk: {routed_key(kb) == key : String}
305 {Map.ins.go(a, V, MNode{q, lo, hi}, x, p, kb, False{}) == Map.ins.splice(a, V, p, key, x, MNode{q, lo, hi}) : Map<a, V>}
306def ins_splice_bridge(a, V, q, lo, hi, x, p, key, kb, hk):
307 match lo hi kb:
308 case MTip{} MTip{} Tuple{k2, False{}}:
309 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MTip{}}) : Map<a, V>}
310 {==}
311 case MTip{} MTip{} Tuple{k2, True{}}:
312 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MTip{}}) : Map<a, V>}
313 {==}
314 case MTip{} MLeaf{k3, v3} Tuple{k2, False{}}:
315 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MLeaf{k3, v3}}) : Map<a, V>}
316 {==}
317 case MTip{} MLeaf{k3, v3} Tuple{k2, True{}}:
318 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MLeaf{k3, v3}}) : Map<a, V>}
319 {==}
320 case MTip{} MNode{r3, c3, e3} Tuple{k2, False{}}:
321 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MNode{r3, c3, e3}}) : Map<a, V>}
322 {==}
323 case MTip{} MNode{r3, c3, e3} Tuple{k2, True{}}:
324 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MTip{}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MTip{}, MNode{r3, c3, e3}}) : Map<a, V>}
325 {==}
326 case MLeaf{k1, v1} MTip{} Tuple{k2, False{}}:
327 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MTip{}}) : Map<a, V>}
328 {==}
329 case MLeaf{k1, v1} MTip{} Tuple{k2, True{}}:
330 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MTip{}}) : Map<a, V>}
331 {==}
332 case MLeaf{k1, v1} MLeaf{k3, v3} Tuple{k2, False{}}:
333 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MLeaf{k3, v3}}) : Map<a, V>}
334 {==}
335 case MLeaf{k1, v1} MLeaf{k3, v3} Tuple{k2, True{}}:
336 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MLeaf{k3, v3}}) : Map<a, V>}
337 {==}
338 case MLeaf{k1, v1} MNode{r3, c3, e3} Tuple{k2, False{}}:
339 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MNode{r3, c3, e3}}) : Map<a, V>}
340 {==}
341 case MLeaf{k1, v1} MNode{r3, c3, e3} Tuple{k2, True{}}:
342 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MLeaf{k1, v1}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MLeaf{k1, v1}, MNode{r3, c3, e3}}) : Map<a, V>}
343 {==}
344 case MNode{r1, c1, e1} MTip{} Tuple{k2, False{}}:
345 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MTip{}}) : Map<a, V>}
346 {==}
347 case MNode{r1, c1, e1} MTip{} Tuple{k2, True{}}:
348 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MTip{}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MTip{}}) : Map<a, V>}
349 {==}
350 case MNode{r1, c1, e1} MLeaf{k3, v3} Tuple{k2, False{}}:
351 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MLeaf{k3, v3}}) : Map<a, V>}
352 {==}
353 case MNode{r1, c1, e1} MLeaf{k3, v3} Tuple{k2, True{}}:
354 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MLeaf{k3, v3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MLeaf{k3, v3}}) : Map<a, V>}
355 {==}
356 case MNode{r1, c1, e1} MNode{r3, c3, e3} Tuple{k2, False{}}:
357 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MNode{r3, c3, e3}}) : Map<a, V>}
358 {==}
359 case MNode{r1, c1, e1} MNode{r3, c3, e3} Tuple{k2, True{}}:
360 %Equal.sym(String, k2, key, hk) : {Map.ins.splice(a, V, p, _, x, MNode{q, MNode{r1, c1, e1}, MNode{r3, c3, e3}}) == Map.ins.splice(a, V, p, key, x, MNode{q, MNode{r1, c1, e1}, MNode{r3, c3, e3}}) : Map<a, V>}
361 {==}
362
363law ins_deep_bridge:
364 for -a: Quant
365 for -V: Kind(a)
366 for +q: Nat
367 for lo: Map<a, V>
368 for hi: Map<a, V>
369 for x: V
370 for +p: Nat
371 for kb: String & Bool
372 {Map.ins.go(a, V, MNode{q, lo, hi}, x, p, kb, True{}) == ins_deep(a, V, x, lo, hi, p, q, kb) : Map<a, V>}
373def ins_deep_bridge(a, V, q, lo, hi, x, p, kb):
374 match lo hi kb:
375 case MTip{} _ Tuple{key2, False{}}:
376 {==}
377 case MLeaf{k, v} _ Tuple{key2, False{}}:
378 {==}
379 case MNode{r, c, e} _ Tuple{key2, False{}}:
380 {==}
381 case _ MTip{} Tuple{key2, True{}}:
382 {==}
383 case _ MLeaf{k, v} Tuple{key2, True{}}:
384 {==}
385 case _ MNode{r, c, e} Tuple{key2, True{}}:
386 {==}
387
388law ins_t:
389 for -a: Quant
390 for -V: Kind(a)
391 for +pos: Nat
392 for lo: Map<a, V>
393 for hi: Map<a, V>
394 for +key: String
395 for x: V
396 for +p: Nat
397 for t: Bool
398 {Map.ins.go(a, V, MNode{pos, lo, hi}, x, p, Map.bit(key, pos), t) == ins_if(a, V, key, x, lo, hi, pos, p, t) : Map<a, V>}
399def ins_t(a, V, pos, lo, hi, key, x, p, t):
400 match t:
401 case False{}:
402 ins_splice_bridge(a, V, pos, lo, hi, x, p, key, Map.bit(key, pos), bit_preserves_key(key, pos))
403 case True{}:
404 ins_deep_bridge(a, V, pos, lo, hi, x, p, Map.bit(key, pos))
405
406law ins_node:
407 for -a: Quant
408 for -V: Kind(a)
409 for +pos: Nat
410 for lo: Map<a, V>
411 for hi: Map<a, V>
412 for +key: String
413 for x: V
414 for +p: Nat
415 {Map.ins(a, V, MNode{pos, lo, hi}, key, x, p) == ins_if(a, V, key, x, lo, hi, pos, p, Nat.is_lt(pos, p)) : Map<a, V>}
416def ins_node(a, V, pos, lo, hi, key, x, p):
417 ins_t(a, V, pos, lo, hi, key, x, p, Nat.is_lt(pos, p))