proof_num.bend
lawful-fields@0.1.1.0 · 676 lines · 40 definitions
1import Base
2import lawful-bytes@0.1.1.0/defs.bend as D
3import lawful-bytes@0.1.1.0/bytes.bend as B
4import lawful-fields@0.1.1.0/defs.bend as F
5import lawful-fields@0.1.1.0/fields.bend as C
6import lawful-bytes@0.1.1.0/proof_seq.bend as Q
7import lawful-bytes@0.1.1.0/proof_core.bend as K
8import lawful-bytes@0.1.1.0/proof_append.bend as X
9import lawful-words@0.1.0.0/proof_nat.bend as N
10import lawful-words@0.1.0.0/proof_u32.bend as U
11import lawful-arrays@0.1.0.0/proof_base.bend as AB
12import lawful-arrays@0.1.0.0/proof_tree.bend as P
13
14
15
16
17
18
19
20
21
22
23
24law lift:
25 for +x: Nat
26 for +M: Nat
27 for +hm: {Nat.pow(2n, 32n) == M : Nat}
28 for +h: {Nat.is_lt(x, M) == True{} : Bool}
29 {Nat.is_lt(x, Nat.pow(2n, 32n)) == True{} : Bool}
30
31def lift(x, M, hm, h):
32 %Equal.sym(Nat, Nat.pow(2n, 32n), M, hm) : {Nat.is_lt(x, _) == True{} : Bool}
33 h
34
35law posM:
36 for +M: Nat
37 for +hm: {Nat.pow(2n, 32n) == M : Nat}
38 {Nat.is_lt(0n, M) == True{} : Bool}
39
40def posM(M, hm):
41 %hm : {Nat.is_lt(0n, _) == True{} : Bool}
42 AB.pow_pos(32n)
43
44law notM:
45 for +M: Nat
46 for +hm: {Nat.pow(2n, 32n) == M : Nat}
47 {U32.to_nat(U32.not(0)) == Nat.sub(Nat.sub(M, 1n), U32.to_nat(0)) : Nat}
48
49def notM(M, hm):
50 %hm : {U32.to_nat(U32.not(0)) == Nat.sub(Nat.sub(_, 1n), U32.to_nat(0)) : Nat}
51 U.to_nat_not_p(0)
52
53law ED:
54 {U32.div(U32.not(0), 10) == 429496729 : U32}
55
56def ED():
57 {==}
58
59law EM:
60 {U32.mod(U32.not(0), 10) == 5 : U32}
61
62def EM():
63 {==}
64
65law QD:
66 {Nat.div(U32.to_nat(U32.not(0)), U32.to_nat(10)) == U32.to_nat(429496729) : Nat}
67
68def QD():
69 %ED() : {Nat.div(U32.to_nat(U32.not(0)), U32.to_nat(10)) == U32.to_nat(_) : Nat}
70 Equal.sym(Nat, U32.to_nat(U32.div(U32.not(0), 10)), Nat.div(U32.to_nat(U32.not(0)), U32.to_nat(10)), U.to_nat_div(U32.not(0), 10))
71
72law QR:
73 {Nat.mod(U32.to_nat(U32.not(0)), U32.to_nat(10)) == U32.to_nat(5) : Nat}
74
75def QR():
76 %EM() : {Nat.mod(U32.to_nat(U32.not(0)), U32.to_nat(10)) == U32.to_nat(_) : Nat}
77 Equal.sym(Nat, U32.to_nat(U32.mod(U32.not(0), 10)), Nat.mod(U32.to_nat(U32.not(0)), U32.to_nat(10)), U.to_nat_mod(U32.not(0), 10))
78
79law succ_pred:
80 for +M: Nat
81 for +h: {Nat.is_lt(0n, M) == True{} : Bool}
82 {1n+Nat.sub(M, 1n) == M : Nat}
83
84def succ_pred(M, h):
85 match M:
86 case 0n:
87 Empty.absurd({1n+Nat.sub(0n, 1n) == 0n : Nat}, AB.false_ne_true(h))
88 case 1n+p:
89 %Equal.sym(Nat, Nat.sub(p, 0n), p, N.sub_zero(p)) : {1n+_ == 1n+p : Nat}
90 {==}
91
92law qg1:
93 for +N1: Nat
94 for +Qn: Nat
95 for +R: Nat
96 for +T: Nat
97 for +M: Nat
98 for +hdm: {Nat.add(Nat.mul(Nat.div(N1, T), T), Nat.mod(N1, T)) == N1 : Nat}
99 for +hd: {Nat.div(N1, T) == Qn : Nat}
100 for +hr: {Nat.mod(N1, T) == R : Nat}
101 for +hT: {T == 10n : Nat}
102 for +hR: {R == 5n : Nat}
103 for +eN: {N1 == Nat.sub(M, 1n) : Nat}
104 {Nat.add(Nat.mul(Qn, 10n), 5n) == Nat.sub(M, 1n) : Nat}
105
106def qg1(N1, Qn, R, T, M, hdm, hd, hr, hT, hR, eN):
107 %hd : {Nat.add(Nat.mul(_, 10n), 5n) == Nat.sub(M, 1n) : Nat}
108 %hT : {Nat.add(Nat.mul(Nat.div(N1, T), _), 5n) == Nat.sub(M, 1n) : Nat}
109 %Equal.trans(Nat, Nat.mod(N1, T), R, 5n, hr, hR) : {Nat.add(Nat.mul(Nat.div(N1, T), T), _) == Nat.sub(M, 1n) : Nat}
110 %eN : {Nat.add(Nat.mul(Nat.div(N1, T), T), Nat.mod(N1, T)) == _ : Nat}
111 hdm
112
113
114law QG:
115 for +N1: Nat
116 for +Qn: Nat
117 for +R: Nat
118 for +T: Nat
119 for +Z: Nat
120 for +M: Nat
121 for +hdm: {Nat.add(Nat.mul(Nat.div(N1, T), T), Nat.mod(N1, T)) == N1 : Nat}
122 for +hd: {Nat.div(N1, T) == Qn : Nat}
123 for +hr: {Nat.mod(N1, T) == R : Nat}
124 for +hT: {T == 10n : Nat}
125 for +hR: {R == 5n : Nat}
126 for +hZ: {Z == 0n : Nat}
127 for +hN: {N1 == Nat.sub(Nat.sub(M, 1n), Z) : Nat}
128 for +hM: {Nat.is_lt(0n, M) == True{} : Bool}
129 {Nat.add(Nat.mul(Qn, 10n), 6n) == M : Nat}
130
131def QG(N1, Qn, R, T, Z, M, hdm, hd, hr, hT, hR, hZ, hN, hM):
132 +eN = Equal.trans(Nat, N1, Nat.sub(Nat.sub(M, 1n), 0n), Nat.sub(M, 1n),
133 Equal.trans(Nat, N1, Nat.sub(Nat.sub(M, 1n), Z), Nat.sub(Nat.sub(M, 1n), 0n), hN,
134 Equal.cong(Nat, Nat, z => Nat.sub(Nat.sub(M, 1n), z), Z, 0n, hZ)),
135 N.sub_zero(Nat.sub(M, 1n)))
136 +e1 = qg1(N1, Qn, R, T, M, hdm, hd, hr, hT, hR, eN)
137 %Equal.sym(Nat, Nat.add(Nat.mul(Qn, 10n), 1n+5n), 1n+Nat.add(Nat.mul(Qn, 10n), 5n), N.add_succ(Nat.mul(Qn, 10n), 5n)) :
138 {_ == M : Nat}
139 %Equal.sym(Nat, Nat.add(Nat.mul(Qn, 10n), 5n), Nat.sub(M, 1n), e1) : {1n+_ == M : Nat}
140 succ_pred(M, hM)
141
142law QM:
143 for +M: Nat
144 for +hm: {Nat.pow(2n, 32n) == M : Nat}
145 {Nat.add(Nat.mul(U32.to_nat(429496729), 10n), 6n) == M : Nat}
146
147def QM(M, hm):
148 QG(U32.to_nat(U32.not(0)), U32.to_nat(429496729), U32.to_nat(5), U32.to_nat(10), U32.to_nat(0), M,
149 N.div_mod(U32.to_nat(U32.not(0)), U32.to_nat(10)), QD(), QR(), {==}, {==}, {==}, notM(M, hm), posM(M, hm))
150
151
152
153
154
155law FITS0:
156 for +a: Nat
157 for +q: Nat
158 for +k: Nat
159 for +hk: {Nat.is_le(k, 9n) == True{} : Bool}
160 {Bool.or(Nat.is_lt(a, q), Bool.and(Nat.is_eq(a, q), Nat.is_le(k, 5n))) == Nat.is_lt(Nat.add(Nat.mul(a, 10n), k), Nat.add(Nat.mul(q, 10n), 6n)) : Bool}
161
162def FITS0(a, q, k, hk):
163 match a q:
164 case 0n 0n:
165 Equal.sym(Bool, Nat.is_lt(k, 1n+5n), Nat.is_le(k, 5n), N.lt_succ_iff(k, 5n))
166 case 0n 1n+p:
167 +B = Nat.add(Nat.mul(1n+p, 10n), 6n)
168 Equal.sym(Bool, Nat.is_lt(k, B), True{},
169 N.lt_le_trans(k, 10n, B, Equal.trans(Bool, Nat.is_lt(k, 1n+9n), Nat.is_le(k, 9n), True{}, N.lt_succ_iff(k, 9n), hk),
170 N.le_add_r(10n, Nat.add(Nat.mul(p, 10n), 6n))))
171 case 1n+b 0n:
172 {==}
173 case 1n+b 1n+p:
174 FITS0(b, p, k, hk)
175
176law sub_mono:
177 for +a: Nat
178 for +b: Nat
179 for +c: Nat
180 for +h: {Nat.is_le(a, b) == True{} : Bool}
181 {Nat.is_le(Nat.sub(a, c), Nat.sub(b, c)) == True{} : Bool}
182
183def sub_mono(a, b, c, h):
184 match a b c:
185 case 0n _ _:
186 N.le_zero_l(Nat.sub(b, c))
187 case 1n+p 0n _:
188 Empty.absurd({Nat.is_le(Nat.sub(1n+p, c), Nat.sub(0n, c)) == True{} : Bool}, AB.false_ne_true(h))
189 case 1n+p 1n+r 0n:
190 h
191 case 1n+p 1n+r 1n+s:
192 sub_mono(p, r, s, h)
193
194
195law le48:
196 for +x: U32
197 for +hge: {U32.is_ge(x, 48) == True{} : Bool}
198 {U32.is_le(48, x) == True{} : Bool}
199
200def le48(x, hge):
201 %Equal.sym(Bool, U32.is_le(48, x), Nat.is_le(U32.to_nat(48), U32.to_nat(x)), U.is_le_to_nat(48, x)) : {_ == True{} : Bool}
202 %U.ge_le(U32.to_nat(x), U32.to_nat(48)) : {_ == True{} : Bool}
203 Equal.trans(Bool, Nat.is_ge(U32.to_nat(x), U32.to_nat(48)), U32.is_ge(x, 48), True{},
204 Equal.sym(Bool, U32.is_ge(x, 48), Nat.is_ge(U32.to_nat(x), U32.to_nat(48)), U.is_ge_to_nat(x, 48)), hge)
205
206law ed48:
207 for +x: U32
208 for +hge: {U32.is_ge(x, 48) == True{} : Bool}
209 {U32.to_nat(U32.sub(x, 48)) == Nat.sub(U32.to_nat(x), 48n) : Nat}
210
211def ed48(x, hge):
212 U.to_nat_sub_le(x, 48, le48(x, hge))
213
214law k9:
215 for +x: U32
216 for +hle: {U32.is_le(x, 57) == True{} : Bool}
217 {Nat.is_le(Nat.sub(U32.to_nat(x), 48n), 9n) == True{} : Bool}
218
219def k9(x, hle):
220 sub_mono(U32.to_nat(x), 57n, 48n,
221 Equal.trans(Bool, Nat.is_le(U32.to_nat(x), U32.to_nat(57)), U32.is_le(x, 57), True{},
222 Equal.sym(Bool, U32.is_le(x, 57), Nat.is_le(U32.to_nat(x), U32.to_nat(57)), U.is_le_to_nat(x, 57)), hle))
223
224
225law FITSU:
226 for +acc: U32
227 for +x: U32
228 for +c: U32
229 for +q: Nat
230 for +M: Nat
231 for +hcq: {U32.to_nat(c) == q : Nat}
232 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
233 for +hge: {U32.is_ge(x, 48) == True{} : Bool}
234 for +hle: {U32.is_le(x, 57) == True{} : Bool}
235 {Bool.or(U32.is_lt(acc, c), Bool.and(U32.is_eq(acc, c), U32.is_le(U32.sub(x, 48), 5))) == Nat.is_lt(Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n)), M) : Bool}
236
237def FITSU(acc, x, c, q, M, hcq, hq, hge, hle):
238 +A = U32.to_nat(acc)
239 +KK = Nat.sub(U32.to_nat(x), 48n)
240 +RHS = Nat.is_lt(Nat.add(Nat.mul(A, 10n), KK), M)
241 %Equal.sym(Bool, U32.is_lt(acc, c), Nat.is_lt(A, U32.to_nat(c)), U.is_lt_to_nat(acc, c)) :
242 {Bool.or(_, Bool.and(U32.is_eq(acc, c), U32.is_le(U32.sub(x, 48), 5))) == RHS : Bool}
243 %Equal.sym(Bool, U32.is_eq(acc, c), Nat.is_eq(A, U32.to_nat(c)), U.is_eq_to_nat(acc, c)) :
244 {Bool.or(Nat.is_lt(A, U32.to_nat(c)), Bool.and(_, U32.is_le(U32.sub(x, 48), 5))) == RHS : Bool}
245 %Equal.sym(Bool, U32.is_le(U32.sub(x, 48), 5), Nat.is_le(U32.to_nat(U32.sub(x, 48)), U32.to_nat(5)), U.is_le_to_nat(U32.sub(x, 48), 5)) :
246 {Bool.or(Nat.is_lt(A, U32.to_nat(c)), Bool.and(Nat.is_eq(A, U32.to_nat(c)), _)) == RHS : Bool}
247 %Equal.sym(Nat, U32.to_nat(U32.sub(x, 48)), KK, ed48(x, hge)) :
248 {Bool.or(Nat.is_lt(A, U32.to_nat(c)), Bool.and(Nat.is_eq(A, U32.to_nat(c)), Nat.is_le(_, U32.to_nat(5)))) == RHS : Bool}
249 %Equal.sym(Nat, U32.to_nat(c), q, hcq) :
250 {Bool.or(Nat.is_lt(A, _), Bool.and(Nat.is_eq(A, _), Nat.is_le(KK, U32.to_nat(5)))) == RHS : Bool}
251 %hq : {Bool.or(Nat.is_lt(A, q), Bool.and(Nat.is_eq(A, q), Nat.is_le(KK, U32.to_nat(5)))) == Nat.is_lt(Nat.add(Nat.mul(A, 10n), KK), _) : Bool}
252 FITS0(A, q, KK, k9(x, hle))
253
254
255
256
257
258def DG(+x: U32) -> Bool:
259 U32.is_ge(x, 48) && U32.is_le(x, 57)
260
261def FT(+acc: U32, +x: U32) -> Bool:
262 U32.is_lt(acc, 429496729) || (U32.is_eq(acc, 429496729) && U32.is_le((x - 48 : U32), 5))
263
264def NA(+acc: U32, +x: U32) -> U32:
265 ((acc * 10 : U32) + (x - 48 : U32) : U32)
266
267
268def Bad(m: Maybe<&2, Nat>, +M: Nat) -> Data:
269 match m:
270 case None{}:
271 Unit
272 case Some{v}:
273 {Nat.is_lt(v, M) == False{} : Bool}
274
275
276def Inv(ok: Bool, +acc: U32, +m: Maybe<&2, Nat>, +M: Nat) -> Data:
277 match ok:
278 case True{}:
279 Sigma<&2, &2, {m == Some{U32.to_nat(acc)} : Maybe<&2, Nat>}, e => {Nat.is_lt(U32.to_nat(acc), M) == True{} : Bool}>
280 case False{}:
281 Bad(m, M)
282
283law le_mul10:
284 for +v: Nat
285 {Nat.is_le(v, Nat.mul(v, 10n)) == True{} : Bool}
286
287def le_mul10(v):
288 match v:
289 case 0n:
290 {==}
291 case 1n+p:
292 N.le_trans(p, Nat.mul(p, 10n), Nat.add(9n, Nat.mul(p, 10n)), le_mul10(p), N.le_add_l(Nat.mul(p, 10n), 9n))
293
294law bad_step:
295 for +m: Maybe<&2, Nat>
296 for +dx: Maybe<&2, Nat>
297 for +M: Nat
298 for +hb: Bad(m, M)
299 Bad(F.dec.push(m, dx), M)
300
301def bad_step(m, dx, M, hb):
302 match m dx:
303 case None{} None{}:
304 Unit{}
305 case None{} Some{k}:
306 Unit{}
307 case Some{v} None{}:
308 Unit{}
309 case Some{+v} Some{+k}:
310 +S = Nat.add(Nat.mul(v, 10n), k)
311 N.le_not_lt(M, S,
312 N.le_trans(M, v, S, N.not_lt_le(v, M, hb),
313 N.le_trans(v, Nat.mul(v, 10n), S, le_mul10(v), N.le_add_r(Nat.mul(v, 10n), k))))
314
315law bad_none:
316 for +m: Maybe<&2, Nat>
317 for +M: Nat
318 for +hb: Bad(m, M)
319 {F.decb.of(m, M) == None{} : Maybe<&2, Nat>}
320
321def bad_none(m, M, hb):
322 match m:
323 case None{}:
324 {==}
325 case Some{+v}:
326 %Equal.sym(Bool, Nat.is_lt(v, M), False{}, hb) : {F.decb.if(v, _) == None{} : Maybe<&2, Nat>}
327 {==}
328
329law ena_add:
330 for +acc: U32
331 for +x: U32
332 for +M: Nat
333 for +emul: {U32.to_nat(U32.mul(acc, 10)) == Nat.mul(U32.to_nat(acc), U32.to_nat(10)) : Nat}
334 for +ed: {U32.to_nat(U32.sub(x, 48)) == Nat.sub(U32.to_nat(x), 48n) : Nat}
335 for +hb: {Nat.is_lt(Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n)), M) == True{} : Bool}
336 {Nat.is_lt(Nat.add(U32.to_nat(U32.mul(acc, 10)), U32.to_nat(U32.sub(x, 48))), M) == True{} : Bool}
337
338def ena_add(acc, x, M, emul, ed, hb):
339 %Equal.sym(Nat, U32.to_nat(U32.mul(acc, 10)), Nat.mul(U32.to_nat(acc), U32.to_nat(10)), emul) :
340 {Nat.is_lt(Nat.add(_, U32.to_nat(U32.sub(x, 48))), M) == True{} : Bool}
341 %Equal.sym(Nat, U32.to_nat(U32.sub(x, 48)), Nat.sub(U32.to_nat(x), 48n), ed) :
342 {Nat.is_lt(Nat.add(Nat.mul(U32.to_nat(acc), U32.to_nat(10)), _), M) == True{} : Bool}
343 hb
344
345
346law ena:
347 for +acc: U32
348 for +x: U32
349 for +M: Nat
350 for +hm: {Nat.pow(2n, 32n) == M : Nat}
351 for +hge: {U32.is_ge(x, 48) == True{} : Bool}
352 for +hb: {Nat.is_lt(Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n)), M) == True{} : Bool}
353 {U32.to_nat(NA(acc, x)) == Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n)) : Nat}
354
355def ena(acc, x, M, hm, hge, hb):
356 +A = U32.to_nat(acc)
357 +KK = Nat.sub(U32.to_nat(x), 48n)
358 +S = Nat.add(Nat.mul(A, 10n), KK)
359 +hmul = N.le_lt_trans(Nat.mul(A, U32.to_nat(10)), S, M, N.le_add_r(Nat.mul(A, 10n), KK), hb)
360 +emul = U.to_nat_mul_fits_p(acc, 10, lift(Nat.mul(U32.to_nat(acc), U32.to_nat(10)), M, hm, hmul))
361 +ed = ed48(x, hge)
362 +hadd = ena_add(acc, x, M, emul, ed, hb)
363 +eadd = U.to_nat_add_fits_p(U32.mul(acc, 10), U32.sub(x, 48), lift(Nat.add(U32.to_nat(U32.mul(acc, 10)), U32.to_nat(U32.sub(x, 48))), M, hm, hadd))
364 %Equal.sym(Nat, U32.to_nat(U32.add(U32.mul(acc, 10), U32.sub(x, 48))), Nat.add(U32.to_nat(U32.mul(acc, 10)), U32.to_nat(U32.sub(x, 48))), eadd) :
365 {_ == S : Nat}
366 %Equal.sym(Nat, U32.to_nat(U32.mul(acc, 10)), Nat.mul(A, U32.to_nat(10)), emul) : {Nat.add(_, U32.to_nat(U32.sub(x, 48))) == S : Nat}
367 %Equal.sym(Nat, U32.to_nat(U32.sub(x, 48)), KK, ed) : {Nat.add(Nat.mul(A, U32.to_nat(10)), _) == S : Nat}
368 {==}
369
370
371law step_fb:
372 for +acc: U32
373 for +x: U32
374 for +M: Nat
375 for +b: Bool
376 for +hm: {Nat.pow(2n, 32n) == M : Nat}
377 for +hge: {U32.is_ge(x, 48) == True{} : Bool}
378 for +hb: {Nat.is_lt(Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n)), M) == b : Bool}
379 Inv(b, NA(acc, x), Some{Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n))}, M)
380
381def step_fb(acc, x, M, b, hm, hge, hb):
382 match b:
383 case True{}:
384 +S = Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n))
385 +e = Equal.sym(Nat, U32.to_nat(NA(acc, x)), S, ena(acc, x, M, hm, hge, hb))
386 (Equal.cong(Nat, Maybe<&2, Nat>, v => Some{v}, S, U32.to_nat(NA(acc, x)), e),
387 AB.subst(Nat, y => {Nat.is_lt(y, M) == True{} : Bool}, S, U32.to_nat(NA(acc, x)), e, hb))
388 case False{}:
389 hb
390
391
392law step_dg:
393 for +acc: U32
394 for +x: U32
395 for +M: Nat
396 for +q: Nat
397 for +dg: Bool
398 for +hdg: {DG(x) == dg : Bool}
399 for +hm: {Nat.pow(2n, 32n) == M : Nat}
400 for +hcq: {U32.to_nat(429496729) == q : Nat}
401 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
402 Inv(Bool.and(dg, FT(acc, x)), NA(acc, x), F.dec.push(Some{U32.to_nat(acc)}, F.digit.if(x, dg)), M)
403
404def step_dg(acc, x, M, q, dg, hdg, hm, hcq, hq):
405 match dg:
406 case False{}:
407 Unit{}
408 case True{}:
409 +hge = AB.and_true_l(U32.is_ge(x, 48), U32.is_le(x, 57), hdg)
410 +hle = AB.and_true_r(U32.is_ge(x, 48), U32.is_le(x, 57), hdg)
411 +S = Nat.add(Nat.mul(U32.to_nat(acc), 10n), Nat.sub(U32.to_nat(x), 48n))
412 %Equal.sym(Bool, Bool.or(U32.is_lt(acc, 429496729), Bool.and(U32.is_eq(acc, 429496729), U32.is_le(U32.sub(x, 48), 5))), Nat.is_lt(S, M),
413 FITSU(acc, x, 429496729, q, M, hcq, hq, hge, hle)) :
414 Inv(_, NA(acc, x), Some{S}, M)
415 step_fb(acc, x, M, Nat.is_lt(S, M), hm, hge, {==})
416
417law inv_step:
418 for +ok: Bool
419 for +acc: U32
420 for +m: Maybe<&2, Nat>
421 for +x: U32
422 for +M: Nat
423 for +q: Nat
424 for +hm: {Nat.pow(2n, 32n) == M : Nat}
425 for +hcq: {U32.to_nat(429496729) == q : Nat}
426 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
427 for +hi: Inv(ok, acc, m, M)
428 Inv(Bool.and(ok, Bool.and(DG(x), FT(acc, x))), NA(acc, x), F.dec.push(m, F.digit(x)), M)
429
430def inv_step(ok, acc, m, x, M, q, hm, hcq, hq, hi):
431 match ok:
432 case False{}:
433 bad_step(m, F.digit(x), M, hi)
434 case True{}:
435 (e1, e2) = hi
436 %Equal.sym(Maybe<&2, Nat>, m, Some{U32.to_nat(acc)}, e1) :
437 Inv(Bool.and(DG(x), FT(acc, x)), NA(acc, x), F.dec.push(_, F.digit(x)), M)
438 step_dg(acc, x, M, q, DG(x), {==}, hm, hcq, hq)
439
440law base:
441 for +ok: Bool
442 for +acc: U32
443 for +m: Maybe<&2, Nat>
444 for +M: Nat
445 for +hi: Inv(ok, acc, m, M)
446 {F.nat_of(C.num.fin(acc, ok)) == F.decb.of(m, M) : Maybe<&2, Nat>}
447
448def base(ok, acc, m, M, hi):
449 match ok:
450 case True{}:
451 (+e1, +e2) = hi
452 %Equal.sym(Maybe<&2, Nat>, m, Some{U32.to_nat(acc)}, e1) : {F.nat_of(C.num.fin(acc, True{})) == F.decb.of(_, M) : Maybe<&2, Nat>}
453 %Equal.sym(Bool, Nat.is_lt(U32.to_nat(acc), M), True{}, e2) : {Some{U32.to_nat(acc)} == F.decb.if(U32.to_nat(acc), _) : Maybe<&2, Nat>}
454 {==}
455 case False{}:
456 Equal.sym(Maybe<&2, Nat>, F.decb.of(m, M), None{}, bad_none(m, M, hi))
457
458
459
460
461law np:
462 for +n: Nat
463 for +len: U32
464 for +t: P.Tree<U32>
465 for +j: U32
466 for +acc: U32
467 for +ok: Bool
468 {C.num.go(n, B.at(K.BT(len, t), j), j, acc, ok) == (K.BT(len, t), Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(n, B.at(K.BT(len, t), j), j, acc, ok))) : D.Bytes & Maybe<&2, U32>}
469
470def np(n, len, t, j, acc, ok):
471 match n:
472 case 0n:
473 %Equal.sym(D.Bytes & U32, B.at(K.BT(len, t), j), (K.BT(len, t), K.AT(len, t, j)), K.at_pair_t(len, t, j)) :
474 {C.num.go(0n, _, j, acc, ok) == (K.BT(len, t), Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(0n, _, j, acc, ok))) : D.Bytes & Maybe<&2, U32>}
475 {==}
476 case 1n+k:
477 +x = K.AT(len, t, j)
478 %Equal.sym(D.Bytes & U32, B.at(K.BT(len, t), j), (K.BT(len, t), x), K.at_pair_t(len, t, j)) :
479 {C.num.go(1n+k, _, j, acc, ok) == (K.BT(len, t), Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(1n+k, _, j, acc, ok))) : D.Bytes & Maybe<&2, U32>}
480 np(k, len, t, (j + 1 : U32), NA(acc, x), Bool.and(ok, Bool.and(DG(x), FT(acc, x))))
481
482law num_pair_t:
483 for +len: U32
484 for +t: P.Tree<U32>
485 for +from: U32
486 for +to: U32
487 {C.num(K.BT(len, t), from, to) == (K.BT(len, t), Pair.snd(D.Bytes, Maybe<&2, U32>, C.num(K.BT(len, t), from, to))) : D.Bytes & Maybe<&2, U32>}
488
489def num_pair_t(len, t, from, to):
490 np(Nat.sub(U32.to_nat(to), U32.to_nat(from)), len, t, from, 0, U32.is_lt(from, to))
491
492law nv:
493 for +n: Nat
494 for +len: U32
495 for +t: P.Tree<U32>
496 for +d: Nat
497 for +j: U32
498 for +ok: Bool
499 for +acc: U32
500 for +m: Maybe<&2, Nat>
501 for +M: Nat
502 for +q: Nat
503 for +hm: {Nat.pow(2n, 32n) == M : Nat}
504 for +hcq: {U32.to_nat(429496729) == q : Nat}
505 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
506 for +h: {D.ok(K.BT(len, t), d) == True{} : Bool}
507 for +hjn: {Nat.is_le(Nat.add(U32.to_nat(j), n), U32.to_nat(len)) == True{} : Bool}
508 for +hi: Inv(ok, acc, m, M)
509 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(n, B.at(K.BT(len, t), j), j, acc, ok))) == F.decb.of(F.dec.go(D.slice(D.view(K.BT(len, t)), U32.to_nat(j), n), m), M) : Maybe<&2, Nat>}
510
511def nv(n, len, t, d, j, ok, acc, m, M, q, hm, hcq, hq, h, hjn, hi):
512 match n:
513 case 0n:
514 +xs = D.view(K.BT(len, t))
515 %Equal.sym(D.Bytes & U32, B.at(K.BT(len, t), j), (K.BT(len, t), K.AT(len, t, j)), K.at_pair_t(len, t, j)) :
516 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(0n, _, j, acc, ok))) == F.decb.of(F.dec.go(D.slice(xs, U32.to_nat(j), 0n), m), M) : Maybe<&2, Nat>}
517 %Equal.sym(List<&2, U32>, D.slice(xs, U32.to_nat(j), 0n), Nil{}, X.slice_zero(xs, U32.to_nat(j))) :
518 {F.nat_of(C.num.fin(acc, ok)) == F.decb.of(F.dec.go(_, m), M) : Maybe<&2, Nat>}
519 base(ok, acc, m, M, hi)
520 case 1n+k:
521 +xs = D.view(K.BT(len, t))
522 +JJ = U32.to_nat(j)
523 +x = K.AT(len, t, j)
524 +j1 = (j + 1 : U32)
525 +ok1 = Bool.and(ok, Bool.and(DG(x), FT(acc, x)))
526 +hx = Equal.sym(Maybe<&2, U32>, Some{x}, List.get(&2, U32, xs, JJ),
527 K.at_view_t(len, t, d, j, K.ok_full(len, t, d, h), K.ok_d(len, t, d, h), K.ok_len(len, t, d, h), X.read_lt(len, j, k, hjn)))
528 %Equal.sym(D.Bytes & U32, B.at(K.BT(len, t), j), (K.BT(len, t), x), K.at_pair_t(len, t, j)) :
529 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(1n+k, _, j, acc, ok))) == F.decb.of(F.dec.go(D.slice(xs, JJ, 1n+k), m), M) : Maybe<&2, Nat>}
530 %Equal.sym(List<&2, U32>, D.slice(xs, JJ, 1n+k), x <> D.slice(xs, Nat.add(JJ, 1n), k), X.slice_cons(xs, JJ, k, x, hx)) :
531 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(k, B.at(K.BT(len, t), j1), j1, NA(acc, x), ok1))) == F.decb.of(F.dec.go(_, m), M) : Maybe<&2, Nat>}
532 %X.read_inc(len, t, d, j, k, h, hjn) :
533 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(k, B.at(K.BT(len, t), j1), j1, NA(acc, x), ok1))) == F.decb.of(F.dec.go(D.slice(xs, _, k), F.dec.push(m, F.digit(x))), M) : Maybe<&2, Nat>}
534 nv(k, len, t, d, j1, ok1, NA(acc, x), F.dec.push(m, F.digit(x)), M, q, hm, hcq, hq, h, X.read_next(len, t, d, j, k, h, hjn),
535 inv_step(ok, acc, m, x, M, q, hm, hcq, hq, hi))
536
537
538
539
540law sub0_nlt:
541 for +a: Nat
542 for +b: Nat
543 for +h: {Nat.sub(b, a) == 0n : Nat}
544 {Nat.is_lt(a, b) == False{} : Bool}
545
546def sub0_nlt(a, b, h):
547 match a b:
548 case 0n 0n:
549 {==}
550 case 0n 1n+r:
551 Empty.absurd({Nat.is_lt(0n, 1n+r) == False{} : Bool}, AB.succ_ne_zero(r, h))
552 case 1n+p 0n:
553 {==}
554 case 1n+p 1n+r:
555 sub0_nlt(p, r, h)
556
557law subs_lt:
558 for +a: Nat
559 for +b: Nat
560 for +k: Nat
561 for +h: {Nat.sub(b, a) == 1n+k : Nat}
562 {Nat.is_lt(a, b) == True{} : Bool}
563
564def subs_lt(a, b, k, h):
565 match a b:
566 case 0n 0n:
567 Empty.absurd({Nat.is_lt(0n, 0n) == True{} : Bool}, AB.succ_ne_zero(k, Equal.sym(Nat, 0n, 1n+k, h)))
568 case 0n 1n+r:
569 {==}
570 case 1n+p 0n:
571 Empty.absurd({Nat.is_lt(1n+p, 0n) == True{} : Bool}, AB.succ_ne_zero(k, Equal.sym(Nat, 0n, 1n+k, h)))
572 case 1n+p 1n+r:
573 subs_lt(p, r, k, h)
574
575law decs:
576 for +xs: List<&2, U32>
577 for +i: Nat
578 for +k: Nat
579 for +x: U32
580 for +M: Nat
581 for +hx: {List.get(&2, U32, xs, i) == Some{x} : Maybe<&2, U32>}
582 {F.decb(D.slice(xs, i, 1n+k), M) == F.decb.of(F.dec.go(D.slice(xs, i, 1n+k), Some{0n}), M) : Maybe<&2, Nat>}
583
584def decs(xs, i, k, x, M, hx):
585 %Equal.sym(List<&2, U32>, D.slice(xs, i, 1n+k), x <> D.slice(xs, Nat.add(i, 1n), k), X.slice_cons(xs, i, k, x, hx)) :
586 {F.decb(_, M) == F.decb.of(F.dec.go(_, Some{0n}), M) : Maybe<&2, Nat>}
587 {==}
588
589law nvt2:
590 for +n: Nat
591 for +len: U32
592 for +t: P.Tree<U32>
593 for +d: Nat
594 for +from: U32
595 for +to: U32
596 for +M: Nat
597 for +q: Nat
598 for +hm: {Nat.pow(2n, 32n) == M : Nat}
599 for +hcq: {U32.to_nat(429496729) == q : Nat}
600 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
601 for +h: {D.ok(K.BT(len, t), d) == True{} : Bool}
602 for +hft: {U32.is_le(from, to) == True{} : Bool}
603 for +ht: {Nat.is_le(U32.to_nat(to), D.size(K.BT(len, t))) == True{} : Bool}
604 for +hn: {Nat.sub(U32.to_nat(to), U32.to_nat(from)) == n : Nat}
605 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num(K.BT(len, t), from, to))) == F.decb(D.slice(D.view(K.BT(len, t)), U32.to_nat(from), Nat.sub(U32.to_nat(to), U32.to_nat(from))), M) : Maybe<&2, Nat>}
606
607def nvt2(n, len, t, d, from, to, M, q, hm, hcq, hq, h, hft, ht, hn):
608 match n:
609 case 0n:
610 +xs = D.view(K.BT(len, t))
611 +FF = U32.to_nat(from)
612 +TT = U32.to_nat(to)
613 +nlt = Equal.trans(Bool, U32.is_lt(from, to), Nat.is_lt(FF, TT), False{}, U.is_lt_to_nat(from, to), sub0_nlt(FF, TT, hn))
614 %Equal.sym(Nat, Nat.sub(TT, FF), 0n, hn) :
615 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(_, B.at(K.BT(len, t), from), from, 0, U32.is_lt(from, to)))) == F.decb(D.slice(xs, FF, _), M) : Maybe<&2, Nat>}
616 %Equal.sym(D.Bytes & U32, B.at(K.BT(len, t), from), (K.BT(len, t), K.AT(len, t, from)), K.at_pair_t(len, t, from)) :
617 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(0n, _, from, 0, U32.is_lt(from, to)))) == F.decb(D.slice(xs, FF, 0n), M) : Maybe<&2, Nat>}
618 %Equal.sym(Bool, U32.is_lt(from, to), False{}, nlt) :
619 {F.nat_of(C.num.fin(0, _)) == F.decb(D.slice(xs, FF, 0n), M) : Maybe<&2, Nat>}
620 %Equal.sym(List<&2, U32>, D.slice(xs, FF, 0n), Nil{}, X.slice_zero(xs, FF)) :
621 {F.nat_of(C.num.fin(0, False{})) == F.decb(_, M) : Maybe<&2, Nat>}
622 {==}
623 case 1n+k:
624 +xs = D.view(K.BT(len, t))
625 +FF = U32.to_nat(from)
626 +TT = U32.to_nat(to)
627 +LL = U32.to_nat(len)
628 +hlt = subs_lt(FF, TT, k, hn)
629 +lt1 = Equal.trans(Bool, U32.is_lt(from, to), Nat.is_lt(FF, TT), True{}, U.is_lt_to_nat(from, to), hlt)
630 +hFT = Equal.trans(Bool, Nat.is_le(FF, TT), U32.is_le(from, to), True{}, Equal.sym(Bool, U32.is_le(from, to), Nat.is_le(FF, TT), U.is_le_to_nat(from, to)), hft)
631 +eT = Equal.trans(Nat, Nat.add(FF, 1n+k), Nat.add(FF, Nat.sub(TT, FF)), TT,
632 Equal.cong(Nat, Nat, y => Nat.add(FF, y), 1n+k, Nat.sub(TT, FF), Equal.sym(Nat, Nat.sub(TT, FF), 1n+k, hn)), N.le_sub_add(FF, TT, hFT))
633 +hjn = AB.subst(Nat, y => {Nat.is_le(y, LL) == True{} : Bool}, TT, Nat.add(FF, 1n+k), Equal.sym(Nat, Nat.add(FF, 1n+k), TT, eT), ht)
634 +hx = Equal.sym(Maybe<&2, U32>, Some{K.AT(len, t, from)}, List.get(&2, U32, xs, FF),
635 K.at_view_t(len, t, d, from, K.ok_full(len, t, d, h), K.ok_d(len, t, d, h), K.ok_len(len, t, d, h), N.lt_le_trans(FF, TT, LL, hlt, ht)))
636 %Equal.sym(Nat, Nat.sub(TT, FF), 1n+k, hn) :
637 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(_, B.at(K.BT(len, t), from), from, 0, U32.is_lt(from, to)))) == F.decb(D.slice(xs, FF, _), M) : Maybe<&2, Nat>}
638 %Equal.sym(Bool, U32.is_lt(from, to), True{}, lt1) :
639 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(1n+k, B.at(K.BT(len, t), from), from, 0, _))) == F.decb(D.slice(xs, FF, 1n+k), M) : Maybe<&2, Nat>}
640 %Equal.sym(Maybe<&2, Nat>, F.decb(D.slice(xs, FF, 1n+k), M), F.decb.of(F.dec.go(D.slice(xs, FF, 1n+k), Some{0n}), M), decs(xs, FF, k, K.AT(len, t, from), M, hx)) :
641 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num.go(1n+k, B.at(K.BT(len, t), from), from, 0, True{}))) == _ : Maybe<&2, Nat>}
642 nv(1n+k, len, t, d, from, True{}, 0, Some{U32.to_nat(0)}, M, q, hm, hcq, hq, h, hjn, ({==}, posM(M, hm)))
643
644law nvt:
645 for +len: U32
646 for +t: P.Tree<U32>
647 for +d: Nat
648 for +from: U32
649 for +to: U32
650 for +M: Nat
651 for +q: Nat
652 for +hm: {Nat.pow(2n, 32n) == M : Nat}
653 for +hcq: {U32.to_nat(429496729) == q : Nat}
654 for +hq: {Nat.add(Nat.mul(q, 10n), 6n) == M : Nat}
655 for +h: {D.ok(K.BT(len, t), d) == True{} : Bool}
656 for +hft: {U32.is_le(from, to) == True{} : Bool}
657 for +ht: {Nat.is_le(U32.to_nat(to), D.size(K.BT(len, t))) == True{} : Bool}
658 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num(K.BT(len, t), from, to))) == F.decb(D.slice(D.view(K.BT(len, t)), U32.to_nat(from), Nat.sub(U32.to_nat(to), U32.to_nat(from))), M) : Maybe<&2, Nat>}
659
660def nvt(len, t, d, from, to, M, q, hm, hcq, hq, h, hft, ht):
661 nvt2(Nat.sub(U32.to_nat(to), U32.to_nat(from)), len, t, d, from, to, M, q, hm, hcq, hq, h, hft, ht, {==})
662
663
664law num_view_t:
665 for +len: U32
666 for +t: P.Tree<U32>
667 for +d: Nat
668 for +from: U32
669 for +to: U32
670 for +h: {D.ok(K.BT(len, t), d) == True{} : Bool}
671 for +hft: {U32.is_le(from, to) == True{} : Bool}
672 for +ht: {Nat.is_le(U32.to_nat(to), D.size(K.BT(len, t))) == True{} : Bool}
673 {F.nat_of(Pair.snd(D.Bytes, Maybe<&2, U32>, C.num(K.BT(len, t), from, to))) == F.decb(D.slice(D.view(K.BT(len, t)), U32.to_nat(from), Nat.sub(U32.to_nat(to), U32.to_nat(from))), Nat.pow(2n, 32n)) : Maybe<&2, Nat>}
674
675def num_view_t(len, t, d, from, to, h, hft, ht):
676 nvt(len, t, d, from, to, Nat.pow(2n, 32n), U32.to_nat(429496729), {==}, {==}, QM(Nat.pow(2n, 32n), {==}), h, hft, ht)