PROOF.bend

bend-osdev-u32@0.1.0.0 · 2,345 lines · 173 definitions

1# Proofs of bend-osdev-u32's laws: by induction over the bits of Base's
2# Word(n), for every width n. The lemmas generalise those bend-osdev-algo
3# (proof_u32.bend) and bend-osdev-array (PROOF.bend) proved for their own
4# use. Every bound is a word's value or U32Nat.dbl(n, 1n) for a width n
5# that is a variable, so no closed power of two is ever computed.
6import Base
7import bend-osdev-u32@0.1.0.0/u32.bend as U
8import bend-osdev-u32@0.1.0.0/LAWS.bend as Laws
9
10# Contradictions
11
12def un.bt(b: Bool) -> Type:
13  match b:
14    case True{}:
15      Unit
16    case False{}:
17      Empty
18
19def un.ft(e: {False{} == True{} : Bool}) -> Empty:
20  %Equal.sym(Bool, False{}, True{}, e) : un.bt(_)
21  Unit{}
22
23def un.tf(e: {True{} == False{} : Bool}) -> Empty:
24  %e : un.bt(_)
25  Unit{}
26
27def un.cbt(c: Cmp) -> Type:
28  match c:
29    case EQ{}:
30      Unit
31    case o:
32      Empty
33
34def un.lt_eq(e: {LT{} == EQ{} : Cmp}) -> Empty:
35  %Equal.sym(Cmp, LT{}, EQ{}, e) : un.cbt(_)
36  Unit{}
37
38def un.gt_eq(e: {GT{} == EQ{} : Cmp}) -> Empty:
39  %Equal.sym(Cmp, GT{}, EQ{}, e) : un.cbt(_)
40  Unit{}
41
42# Nat
43
44def un.pred(n: Nat) -> Nat:
45  match n:
46    case 0n:
47      0n
48    case 1n+p:
49      p
50
51def un.succ_cong(-a: Nat, -b: Nat, e: {a == b : Nat}) -> {1n+a == 1n+b : Nat}:
52  %e : {1n+a == 1n+_ : Nat}
53  {==}
54
55def un.succ_inj(-a: Nat, -b: Nat, e: {1n+a == 1n+b : Nat}) -> {a == b : Nat}:
56  Equal.cong(Nat, Nat, z => un.pred(z), 1n+a, 1n+b, e)
57
58def un.double_cong(-a: Nat, -b: Nat, e: {a == b : Nat}) -> {Nat.double(a) == Nat.double(b) : Nat}:
59  %e : {Nat.double(a) == Nat.double(_) : Nat}
60  {==}
61
62def un.add_zero(x: Nat) -> {Nat.add(x, 0n) == x : Nat}:
63  match x:
64    case 0n:
65      {==}
66    case 1n+p:
67      un.succ_cong(Nat.add(p, 0n), p, un.add_zero(p))
68
69def un.add_succ(x: Nat, -y: Nat) -> {Nat.add(x, 1n+y) == 1n+Nat.add(x, y) : Nat}:
70  match x:
71    case 0n:
72      {==}
73    case 1n+p:
74      un.succ_cong(Nat.add(p, 1n+y), 1n+Nat.add(p, y), un.add_succ(p, y))
75
76def un.add_comm(x: Nat, +y: Nat) -> {Nat.add(x, y) == Nat.add(y, x) : Nat}:
77  match x:
78    case 0n:
79      Equal.sym(Nat, Nat.add(y, 0n), y, un.add_zero(y))
80    case 1n+p:
81      Equal.trans(Nat, 1n+Nat.add(p, y), 1n+Nat.add(y, p), Nat.add(y, 1n+p), un.succ_cong(Nat.add(p, y), Nat.add(y, p), un.add_comm(p, y)), Equal.sym(Nat, Nat.add(y, 1n+p), 1n+Nat.add(y, p), un.add_succ(y, p)))
82
83def un.double_add(x: Nat, -y: Nat) -> {Nat.double(Nat.add(x, y)) == Nat.add(Nat.double(x), Nat.double(y)) : Nat}:
84  match x:
85    case 0n:
86      {==}
87    case 1n+p:
88      un.succ_cong(1n+Nat.double(Nat.add(p, y)), 1n+Nat.add(Nat.double(p), Nat.double(y)), un.succ_cong(Nat.double(Nat.add(p, y)), Nat.add(Nat.double(p), Nat.double(y)), un.double_add(p, y)))
89
90def un.sub_add_l(y: Nat, +r: Nat) -> {Nat.sub(Nat.add(y, r), y) == r : Nat}:
91  match y:
92    case 0n:
93      match r:
94        case 0n:
95          {==}
96        case 1n+q:
97          {==}
98    case 1n+q:
99      un.sub_add_l(q, r)
100
101def un.sub_add(+r: Nat, +y: Nat) -> {Nat.sub(Nat.add(r, y), y) == r : Nat}:
102  %un.add_comm(y, r) : {Nat.sub(_, y) == r : Nat}
103  un.sub_add_l(y, r)
104
105# x + k = y + k: x = y
106def un.add_cancel_r(+x: Nat, +y: Nat, k: Nat, e: {Nat.add(x, k) == Nat.add(y, k) : Nat}) -> {x == y : Nat}:
107  match k:
108    case 0n:
109      Equal.trans(Nat, x, Nat.add(x, 0n), y, Equal.sym(Nat, Nat.add(x, 0n), x, un.add_zero(x)), Equal.trans(Nat, Nat.add(x, 0n), Nat.add(y, 0n), y, e, un.add_zero(y)))
110    case 1n+q:
111      un.add_cancel_r(x, y, q, un.succ_inj(Nat.add(x, q), Nat.add(y, q), Equal.trans(Nat, 1n+Nat.add(x, q), Nat.add(x, 1n+q), 1n+Nat.add(y, q), Equal.sym(Nat, Nat.add(x, 1n+q), 1n+Nat.add(x, q), un.add_succ(x, q)), Equal.trans(Nat, Nat.add(x, 1n+q), Nat.add(y, 1n+q), 1n+Nat.add(y, q), e, un.add_succ(y, q)))))
112
113# Order
114
115def un.lt_rw(-x: Nat, -x2: Nat, -y: Nat, e: {x == x2 : Nat}, h: {Nat.is_lt(x, y) == True{} : Bool}) -> {Nat.is_lt(x2, y) == True{} : Bool}:
116  %e : {Nat.is_lt(_, y) == True{} : Bool}
117  h
118
119def un.lt_rw2(-x: Nat, -y: Nat, -y2: Nat, e: {y == y2 : Nat}, h: {Nat.is_lt(x, y) == True{} : Bool}) -> {Nat.is_lt(x, y2) == True{} : Bool}:
120  %e : {Nat.is_lt(x, _) == True{} : Bool}
121  h
122
123def un.le_succ(y: Nat, x: Nat) -> {Nat.is_le(1n+y, x) == Nat.is_lt(y, x) : Bool}:
124  match y x:
125    case 0n 0n:
126      {==}
127    case 0n 1n+p:
128      match p:
129        case 0n:
130          {==}
131        case 1n+q:
132          {==}
133    case 1n+q 0n:
134      {==}
135    case 1n+q 1n+p:
136      un.le_succ(q, p)
137
138def un.lt_dbl(x: Nat, y: Nat) -> {Nat.is_lt(Nat.double(x), Nat.double(y)) == Nat.is_lt(x, y) : Bool}:
139  match x y:
140    case 0n 0n:
141      {==}
142    case 0n 1n+q:
143      {==}
144    case 1n+p 0n:
145      {==}
146    case 1n+p 1n+q:
147      un.lt_dbl(p, q)
148
149def un.lt_dbl1(x: Nat, y: Nat) -> {Nat.is_lt(1n+Nat.double(x), Nat.double(y)) == Nat.is_lt(x, y) : Bool}:
150  match x y:
151    case 0n 0n:
152      {==}
153    case 0n 1n+q:
154      {==}
155    case 1n+p 0n:
156      {==}
157    case 1n+p 1n+q:
158      un.lt_dbl1(p, q)
159
160def un.le_dbl(x: Nat, y: Nat) -> {Nat.is_le(Nat.double(x), Nat.double(y)) == Nat.is_le(x, y) : Bool}:
161  match x y:
162    case 0n 0n:
163      {==}
164    case 0n 1n+q:
165      {==}
166    case 1n+p 0n:
167      {==}
168    case 1n+p 1n+q:
169      un.le_dbl(p, q)
170
171def un.lt_succ_r(x: Nat, y: Nat, h: {Nat.is_lt(x, y) == True{} : Bool}) -> {Nat.is_lt(x, 1n+y) == True{} : Bool}:
172  match x y:
173    case 0n _:
174      {==}
175    case 1n+xp 0n:
176      Empty.absurd({Nat.is_lt(1n+xp, 1n) == True{} : Bool}, un.ft(h))
177    case 1n+xp 1n+yp:
178      un.lt_succ_r(xp, yp, h)
179
180def un.le_lt_trans(x: Nat, y: Nat, z: Nat, h1: {Nat.is_le(x, y) == True{} : Bool}, h2: {Nat.is_lt(y, z) == True{} : Bool}) -> {Nat.is_lt(x, z) == True{} : Bool}:
181  match x y z:
182    case 0n 0n 0n:
183      Empty.absurd({Nat.is_lt(0n, 0n) == True{} : Bool}, un.ft(h2))
184    case 0n 0n 1n+zp:
185      {==}
186    case 0n 1n+yp 0n:
187      Empty.absurd({Nat.is_lt(0n, 0n) == True{} : Bool}, un.ft(h2))
188    case 0n 1n+yp 1n+zp:
189      {==}
190    case 1n+xp 0n _:
191      Empty.absurd({Nat.is_lt(1n+xp, z) == True{} : Bool}, un.ft(h1))
192    case 1n+xp 1n+yp 0n:
193      Empty.absurd({Nat.is_lt(1n+xp, 0n) == True{} : Bool}, un.ft(h2))
194    case 1n+xp 1n+yp 1n+zp:
195      un.le_lt_trans(xp, yp, zp, h1, h2)
196
197def un.le_trans(x: Nat, y: Nat, z: Nat, h1: {Nat.is_le(x, y) == True{} : Bool}, h2: {Nat.is_le(y, z) == True{} : Bool}) -> {Nat.is_le(x, z) == True{} : Bool}:
198  match x y z:
199    case 0n _ _:
200      match z:
201        case 0n:
202          {==}
203        case 1n+zp:
204          {==}
205    case 1n+xp 0n _:
206      Empty.absurd({Nat.is_le(1n+xp, z) == True{} : Bool}, un.ft(h1))
207    case 1n+xp 1n+yp 0n:
208      Empty.absurd({Nat.is_le(1n+xp, 0n) == True{} : Bool}, un.ft(h2))
209    case 1n+xp 1n+yp 1n+zp:
210      un.le_trans(xp, yp, zp, h1, h2)
211
212def un.le_succ_self(x: Nat) -> {Nat.is_le(x, 1n+x) == True{} : Bool}:
213  match x:
214    case 0n:
215      {==}
216    case 1n+p:
217      un.le_succ_self(p)
218
219def un.le_double(x: Nat) -> {Nat.is_le(x, Nat.double(x)) == True{} : Bool}:
220  match x:
221    case 0n:
222      {==}
223    case 1n+ +p:
224      un.le_trans(p, Nat.double(p), 1n+Nat.double(p), un.le_double(p), un.le_succ_self(Nat.double(p)))
225
226
227# A + X < A + Y exactly when X < Y, on either side
228def un.lt_add_l(a: Nat, -x: Nat, -y: Nat) -> {Nat.is_lt(Nat.add(a, x), Nat.add(a, y)) == Nat.is_lt(x, y) : Bool}:
229  match a:
230    case 0n:
231      {==}
232    case 1n+p:
233      un.lt_add_l(p, x, y)
234
235def un.lt_add_r(+x: Nat, +y: Nat, +a: Nat) -> {Nat.is_lt(Nat.add(x, a), Nat.add(y, a)) == Nat.is_lt(x, y) : Bool}:
236  %un.add_comm(a, x) : {Nat.is_lt(_, Nat.add(y, a)) == Nat.is_lt(x, y) : Bool}
237  %un.add_comm(a, y) : {Nat.is_lt(Nat.add(a, x), _) == Nat.is_lt(x, y) : Bool}
238  un.lt_add_l(a, x, y)
239
240# A + B < A never holds
241def un.not_lt_add(a: Nat, b: Nat) -> {Nat.is_lt(Nat.add(a, b), a) == False{} : Bool}:
242  match a:
243    case 0n:
244      match b:
245        case 0n:
246          {==}
247        case 1n+q:
248          {==}
249    case 1n+p:
250      un.not_lt_add(p, b)
251
252def un.not_lt_add_l(+s: Nat, +b: Nat) -> {Nat.is_lt(Nat.add(s, b), b) == False{} : Bool}:
253  %un.add_comm(b, s) : {Nat.is_lt(_, b) == False{} : Bool}
254  un.not_lt_add(b, s)
255
256# x + k < k never holds
257def un.add_lt_absurd(+s: Nat, +k: Nat, h: {Nat.is_lt(Nat.add(s, k), k) == True{} : Bool}) -> Empty:
258  un.ft(Equal.trans(Bool, False{}, Nat.is_lt(Nat.add(s, k), k), True{}, Equal.sym(Bool, Nat.is_lt(Nat.add(s, k), k), False{}, un.not_lt_add_l(s, k)), h))
259
260def un.le_not_lt(b: Nat, a: Nat, h: {Nat.is_le(b, a) == True{} : Bool}) -> {Nat.is_lt(a, b) == False{} : Bool}:
261  match b a:
262    case 0n 0n:
263      {==}
264    case 0n 1n+q:
265      {==}
266    case 1n+p 0n:
267      Empty.absurd({Nat.is_lt(0n, 1n+p) == False{} : Bool}, un.ft(h))
268    case 1n+p 1n+q:
269      un.le_not_lt(p, q, h)
270
271def un.cmp_refl(a: Nat) -> {Nat.cmp(a, a) == EQ{} : Cmp}:
272  match a:
273    case 0n:
274      {==}
275    case 1n+p:
276      un.cmp_refl(p)
277
278# The Nat functions: x * 2^n, 0 or 1, halving
279
280def Laws.dbl_zero(n):
281  match n:
282    case 0n:
283      {==}
284    case 1n+p:
285      un.double_cong(U.U32Nat.dbl(p, 0n), 0n, Laws.dbl_zero(p))
286
287def Laws.dbl_add(n, x, y):
288  match n:
289    case 0n:
290      {==}
291    case 1n+p:
292      Equal.trans(Nat, Nat.double(U.U32Nat.dbl(p, Nat.add(x, y))), Nat.double(Nat.add(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y))), Nat.add(Nat.double(U.U32Nat.dbl(p, x)), Nat.double(U.U32Nat.dbl(p, y))), un.double_cong(U.U32Nat.dbl(p, Nat.add(x, y)), Nat.add(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)), Laws.dbl_add(p, x, y)), un.double_add(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)))
293
294def Laws.dbl_dbl(m, k, x):
295  match m:
296    case 0n:
297      {==}
298    case 1n+p:
299      un.double_cong(U.U32Nat.dbl(p, U.U32Nat.dbl(k, x)), U.U32Nat.dbl(Nat.add(p, k), x), Laws.dbl_dbl(p, k, x))
300
301def Laws.dbl_lt(n, x, y):
302  match n:
303    case 0n:
304      {==}
305    case 1n+p:
306      Equal.trans(Bool, Nat.is_lt(Nat.double(U.U32Nat.dbl(p, x)), Nat.double(U.U32Nat.dbl(p, y))), Nat.is_lt(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)), Nat.is_lt(x, y), un.lt_dbl(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)), Laws.dbl_lt(p, x, y))
307
308def Laws.dbl_le(n, x, y):
309  match n:
310    case 0n:
311      {==}
312    case 1n+p:
313      Equal.trans(Bool, Nat.is_le(Nat.double(U.U32Nat.dbl(p, x)), Nat.double(U.U32Nat.dbl(p, y))), Nat.is_le(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)), Nat.is_le(x, y), un.le_dbl(U.U32Nat.dbl(p, x), U.U32Nat.dbl(p, y)), Laws.dbl_le(p, x, y))
314
315def Laws.half_double(x):
316  match x:
317    case 0n:
318      {==}
319    case 1n+p:
320      un.succ_cong(U.U32Nat.half(Nat.double(p)), p, Laws.half_double(p))
321
322def Laws.half_double_one(x):
323  match x:
324    case 0n:
325      {==}
326    case 1n+p:
327      un.succ_cong(U.U32Nat.half(1n+Nat.double(p)), p, Laws.half_double_one(p))
328
329# Words: the value of the lowest bit and the rest
330
331def un.bv(b: Bool, x: Nat) -> Nat:
332  match b:
333    case False{}:
334      Nat.double(x)
335    case True{}:
336      1n+Nat.double(x)
337
338def un.vc(-p: Nat, b: Bool, -t: Word(p)) -> {un.bv(b, Word.to_nat(p, t)) == Word.to_nat(1n+p, WCon{b, t}) : Nat}:
339  match b:
340    case False{}:
341      {==}
342    case True{}:
343      {==}
344
345def Laws.word_zero_value(n):
346  match n:
347    case 0n:
348      {==}
349    case 1n+p:
350      un.double_cong(Word.to_nat(p, Word.zero(p)), 0n, Laws.word_zero_value(p))
351
352# Bounds: every word is below 2^n
353
354def Laws.word_value_lt(n, w):
355  match n:
356    case 0n:
357      {==}
358    case 1n+ +p:
359      match w:
360        case WCon{False{}, +t}:
361          Equal.trans(Bool, Nat.is_lt(Nat.double(Word.to_nat(p, t)), Nat.double(U.U32Nat.dbl(p, 1n))), Nat.is_lt(Word.to_nat(p, t), U.U32Nat.dbl(p, 1n)), True{}, un.lt_dbl(Word.to_nat(p, t), U.U32Nat.dbl(p, 1n)), Laws.word_value_lt(p, t))
362        case WCon{True{}, +t}:
363          Equal.trans(Bool, Nat.is_lt(1n+Nat.double(Word.to_nat(p, t)), Nat.double(U.U32Nat.dbl(p, 1n))), Nat.is_lt(Word.to_nat(p, t), U.U32Nat.dbl(p, 1n)), True{}, un.lt_dbl1(Word.to_nat(p, t), U.U32Nat.dbl(p, 1n)), Laws.word_value_lt(p, t))
364
365# Comparison: Word.cmp is the order of the values
366
367def un.nc(x: Nat, y: Nat, a: Bool, b: Bool) -> {Nat.cmp(un.bv(a, x), un.bv(b, y)) == Word.cmp.fin(a, b, Nat.cmp(x, y)) : Cmp}:
368  match x y:
369    case 0n 0n:
370      match a b:
371        case False{} False{}:
372          {==}
373        case False{} True{}:
374          {==}
375        case True{} False{}:
376          {==}
377        case True{} True{}:
378          {==}
379    case 0n 1n+q:
380      match a b:
381        case False{} False{}:
382          {==}
383        case False{} True{}:
384          {==}
385        case True{} False{}:
386          {==}
387        case True{} True{}:
388          {==}
389    case 1n+p 0n:
390      match a b:
391        case False{} False{}:
392          {==}
393        case False{} True{}:
394          {==}
395        case True{} False{}:
396          {==}
397        case True{} True{}:
398          {==}
399    case 1n+p 1n+q:
400      match a b:
401        case False{} False{}:
402          un.nc(p, q, False{}, False{})
403        case False{} True{}:
404          un.nc(p, q, False{}, True{})
405        case True{} False{}:
406          un.nc(p, q, True{}, False{})
407        case True{} True{}:
408          un.nc(p, q, True{}, True{})
409
410def Laws.word_cmp_value(n, a, b):
411  match n:
412    case 0n:
413      {==}
414    case 1n+ +p:
415      match a b:
416        case WCon{+x, +at} WCon{+y, +bt}:
417          +xv = Word.to_nat(p, at)
418          +yv = Word.to_nat(p, bt)
419          %Equal.sym(Cmp, Word.cmp(p, at, bt), Nat.cmp(xv, yv), Laws.word_cmp_value(p, at, bt)) : {Word.cmp.fin(x, y, _) == Nat.cmp(Word.to_nat(1n+p, WCon{x, at}), Word.to_nat(1n+p, WCon{y, bt})) : Cmp}
420          %un.vc(p, x, at) : {Word.cmp.fin(x, y, Nat.cmp(xv, yv)) == Nat.cmp(_, Word.to_nat(1n+p, WCon{y, bt})) : Cmp}
421          %un.vc(p, y, bt) : {Word.cmp.fin(x, y, Nat.cmp(xv, yv)) == Nat.cmp(un.bv(x, xv), _) : Cmp}
422          Equal.sym(Cmp, Nat.cmp(un.bv(x, xv), un.bv(y, yv)), Word.cmp.fin(x, y, Nat.cmp(xv, yv)), un.nc(xv, yv, x, y))
423
424# Equal values: equal words (Word.cmp answers EQ only for equal words)
425
426def un.fin_eq_tail(c: Cmp, -x: Bool, -y: Bool, e: {Word.cmp.fin(x, y, c) == EQ{} : Cmp}) -> {c == EQ{} : Cmp}:
427  match c:
428    case LT{}:
429      Empty.absurd({LT{} == EQ{} : Cmp}, un.lt_eq(e))
430    case EQ{}:
431      {==}
432    case GT{}:
433      Empty.absurd({GT{} == EQ{} : Cmp}, un.gt_eq(e))
434
435def un.bool_eq(x: Bool, y: Bool, e: {Bool.cmp(x, y) == EQ{} : Cmp}) -> {x == y : Bool}:
436  match x y:
437    case False{} False{}:
438      {==}
439    case False{} True{}:
440      Empty.absurd({False{} == True{} : Bool}, un.lt_eq(e))
441    case True{} False{}:
442      Empty.absurd({True{} == False{} : Bool}, un.gt_eq(e))
443    case True{} True{}:
444      {==}
445
446def un.fin_eq_head(c: Cmp, x: Bool, y: Bool, e: {Word.cmp.fin(x, y, c) == EQ{} : Cmp}) -> {x == y : Bool}:
447  match c:
448    case LT{}:
449      Empty.absurd({x == y : Bool}, un.lt_eq(e))
450    case EQ{}:
451      un.bool_eq(x, y, e)
452    case GT{}:
453      Empty.absurd({x == y : Bool}, un.gt_eq(e))
454
455def un.wcon_eq(-p: Nat, -x: Bool, -y: Bool, -s: Word(p), -t: Word(p), e1: {x == y : Bool}, e2: {s == t : Word(p)}) -> {WCon{x, s} == WCon{y, t} : Word(1n+p)}:
456  %e1 : {WCon{x, s} == WCon{_, t} : Word(1n+p)}
457  %e2 : {WCon{x, s} == WCon{x, _} : Word(1n+p)}
458  {==}
459
460def un.word_eq(n: Nat, a: Word(n), b: Word(n), +e: {Word.cmp(n, a, b) == EQ{} : Cmp}) -> {a == b : Word(n)}:
461  match n:
462    case 0n:
463      match a b:
464        case WNil{} WNil{}:
465          {==}
466    case 1n+ +p:
467      match a b:
468        case WCon{+x, +at} WCon{+y, +bt}:
469          un.wcon_eq(p, x, y, at, bt, un.fin_eq_head(Word.cmp(p, at, bt), x, y, e), un.word_eq(p, at, bt, un.fin_eq_tail(Word.cmp(p, at, bt), x, y, e)))
470
471def Laws.word_value_eq(n, a, b, e):
472  un.word_eq(n, a, b, Equal.trans(Cmp, Word.cmp(n, a, b), Nat.cmp(Word.to_nat(n, a), Word.to_nat(n, b)), EQ{}, Laws.word_cmp_value(n, a, b), Equal.trans(Cmp, Nat.cmp(Word.to_nat(n, a), Word.to_nat(n, b)), Nat.cmp(Word.to_nat(n, b), Word.to_nat(n, b)), EQ{}, Equal.cong(Nat, Cmp, v => Nat.cmp(v, Word.to_nat(n, b)), Word.to_nat(n, a), Word.to_nat(n, b), e), un.cmp_refl(Word.to_nat(n, b)))))
473
474# The complement: not(w) + w = 2^n - 1
475
476# 2 + (2N + 2T) = 2 * K, from 1 + (N + T) = K
477def un.not_tail(+nv: Nat, +tv: Nat, -k: Nat, ih: {1n+Nat.add(nv, tv) == k : Nat}) -> {2n+Nat.add(Nat.double(nv), Nat.double(tv)) == Nat.double(k) : Nat}:
478  Equal.trans(Nat, 2n+Nat.add(Nat.double(nv), Nat.double(tv)), Nat.double(1n+Nat.add(nv, tv)), Nat.double(k), un.succ_cong(1n+Nat.add(Nat.double(nv), Nat.double(tv)), 1n+Nat.double(Nat.add(nv, tv)), un.succ_cong(Nat.add(Nat.double(nv), Nat.double(tv)), Nat.double(Nat.add(nv, tv)), Equal.sym(Nat, Nat.double(Nat.add(nv, tv)), Nat.add(Nat.double(nv), Nat.double(tv)), un.double_add(nv, tv)))), un.double_cong(1n+Nat.add(nv, tv), k, ih))
479
480def Laws.word_not_value(n, w):
481  match n:
482    case 0n:
483      {==}
484    case 1n+ +p:
485      match w:
486        case WCon{False{}, +t}:
487          un.not_tail(Word.to_nat(p, Word.not(p, t)), Word.to_nat(p, t), U.U32Nat.dbl(p, 1n), Laws.word_not_value(p, t))
488        case WCon{True{}, +t}:
489          +nv = Word.to_nat(p, Word.not(p, t))
490          +tv = Word.to_nat(p, t)
491          Equal.trans(Nat, 1n+Nat.add(Nat.double(nv), 1n+Nat.double(tv)), 2n+Nat.add(Nat.double(nv), Nat.double(tv)), Nat.double(U.U32Nat.dbl(p, 1n)), un.succ_cong(Nat.add(Nat.double(nv), 1n+Nat.double(tv)), 1n+Nat.add(Nat.double(nv), Nat.double(tv)), un.add_succ(Nat.double(nv), Nat.double(tv))), un.not_tail(nv, tv, U.U32Nat.dbl(p, 1n), Laws.word_not_value(p, t)))
492
493# Addition with a carry in: the value of Word.adc
494
495# the carry out of Word.adc(n, a, b, False, c)
496def un.maj(x: Bool, y: Bool, c: Bool) -> Bool:
497  match x:
498    case False{}:
499      Bool.and(y, c)
500    case True{}:
501      Bool.or(y, c)
502
503def un.sum(x: Bool, y: Bool, c: Bool) -> Bool:
504  match x:
505    case False{}:
506      Bool.xor(y, c)
507    case True{}:
508      Bool.not(Bool.xor(y, c))
509
510def un.co(n: Nat, a: Word(n), b: Word(n), c: Bool) -> Bool:
511  match n:
512    case 0n:
513      c
514    case 1n+p:
515      match a b:
516        case WCon{x, at} WCon{y, bt}:
517          un.co(p, at, bt, un.maj(x, y, c))
518
519# double R + double D, from R + D
520def un.dd(+r: Nat, +d: Nat, +a: Nat, +b: Nat, e: {Nat.add(r, d) == Nat.add(a, b) : Nat}) -> {Nat.add(Nat.double(r), Nat.double(d)) == Nat.add(Nat.double(a), Nat.double(b)) : Nat}:
521  Equal.trans(Nat, Nat.add(Nat.double(r), Nat.double(d)), Nat.double(Nat.add(r, d)), Nat.add(Nat.double(a), Nat.double(b)), Equal.sym(Nat, Nat.double(Nat.add(r, d)), Nat.add(Nat.double(r), Nat.double(d)), un.double_add(r, d)), Equal.trans(Nat, Nat.double(Nat.add(r, d)), Nat.double(Nat.add(a, b)), Nat.add(Nat.double(a), Nat.double(b)), un.double_cong(Nat.add(r, d), Nat.add(a, b), e), un.double_add(a, b)))
522
523def un.dd1(+r: Nat, +d: Nat, +a: Nat, +b: Nat, e: {Nat.add(r, d) == 1n+Nat.add(a, b) : Nat}) -> {Nat.add(Nat.double(r), Nat.double(d)) == 2n+Nat.add(Nat.double(a), Nat.double(b)) : Nat}:
524  Equal.trans(Nat, Nat.add(Nat.double(r), Nat.double(d)), Nat.double(Nat.add(r, d)), 2n+Nat.add(Nat.double(a), Nat.double(b)), Equal.sym(Nat, Nat.double(Nat.add(r, d)), Nat.add(Nat.double(r), Nat.double(d)), un.double_add(r, d)), Equal.trans(Nat, Nat.double(Nat.add(r, d)), Nat.double(1n+Nat.add(a, b)), 2n+Nat.add(Nat.double(a), Nat.double(b)), un.double_cong(Nat.add(r, d), 1n+Nat.add(a, b), e), un.succ_cong(1n+Nat.double(Nat.add(a, b)), 1n+Nat.add(Nat.double(a), Nat.double(b)), un.succ_cong(Nat.double(Nat.add(a, b)), Nat.add(Nat.double(a), Nat.double(b)), un.double_add(a, b)))))
525
526# 1 + (2A + (1 + 2B)) = 2 + (2A + 2B)
527def un.sh(+a: Nat, +b: Nat) -> {2n+Nat.add(Nat.double(a), Nat.double(b)) == 1n+Nat.add(Nat.double(a), 1n+Nat.double(b)) : Nat}:
528  un.succ_cong(1n+Nat.add(Nat.double(a), Nat.double(b)), Nat.add(Nat.double(a), 1n+Nat.double(b)), Equal.sym(Nat, Nat.add(Nat.double(a), 1n+Nat.double(b)), 1n+Nat.add(Nat.double(a), Nat.double(b)), un.add_succ(Nat.double(a), Nat.double(b))))
529
530# one bit position of the adder
531def un.cell(x: Bool, y: Bool, c: Bool, +r: Nat, +d: Nat, +a: Nat, +b: Nat, ih: {Nat.add(r, d) == Nat.add(U.U32Nat.bit(un.maj(x, y, c)), Nat.add(a, b)) : Nat}) -> {Nat.add(un.bv(un.sum(x, y, c), r), Nat.double(d)) == Nat.add(U.U32Nat.bit(c), Nat.add(un.bv(x, a), un.bv(y, b))) : Nat}:
532  match x y c:
533    case False{} False{} False{}:
534      un.dd(r, d, a, b, ih)
535    case True{} False{} False{}:
536      un.succ_cong(Nat.add(Nat.double(r), Nat.double(d)), Nat.add(Nat.double(a), Nat.double(b)), un.dd(r, d, a, b, ih))
537    case False{} True{} False{}:
538      Equal.trans(Nat, 1n+Nat.add(Nat.double(r), Nat.double(d)), 1n+Nat.add(Nat.double(a), Nat.double(b)), Nat.add(Nat.double(a), 1n+Nat.double(b)), un.succ_cong(Nat.add(Nat.double(r), Nat.double(d)), Nat.add(Nat.double(a), Nat.double(b)), un.dd(r, d, a, b, ih)), Equal.sym(Nat, Nat.add(Nat.double(a), 1n+Nat.double(b)), 1n+Nat.add(Nat.double(a), Nat.double(b)), un.add_succ(Nat.double(a), Nat.double(b))))
539    case False{} False{} True{}:
540      un.succ_cong(Nat.add(Nat.double(r), Nat.double(d)), Nat.add(Nat.double(a), Nat.double(b)), un.dd(r, d, a, b, ih))
541    case True{} True{} False{}:
542      Equal.trans(Nat, Nat.add(Nat.double(r), Nat.double(d)), 2n+Nat.add(Nat.double(a), Nat.double(b)), 1n+Nat.add(Nat.double(a), 1n+Nat.double(b)), un.dd1(r, d, a, b, ih), un.sh(a, b))
543    case True{} False{} True{}:
544      un.dd1(r, d, a, b, ih)
545    case False{} True{} True{}:
546      Equal.trans(Nat, Nat.add(Nat.double(r), Nat.double(d)), 2n+Nat.add(Nat.double(a), Nat.double(b)), 1n+Nat.add(Nat.double(a), 1n+Nat.double(b)), un.dd1(r, d, a, b, ih), un.sh(a, b))
547    case True{} True{} True{}:
548      un.succ_cong(Nat.add(Nat.double(r), Nat.double(d)), 1n+Nat.add(Nat.double(a), 1n+Nat.double(b)), Equal.trans(Nat, Nat.add(Nat.double(r), Nat.double(d)), 2n+Nat.add(Nat.double(a), Nat.double(b)), 1n+Nat.add(Nat.double(a), 1n+Nat.double(b)), un.dd1(r, d, a, b, ih), un.sh(a, b)))
549
550# adc(a, b, False, c) + 2^n * carry out = c + a + b
551def un.add_v(n: Nat, a: Word(n), b: Word(n), c: Bool) -> {Nat.add(Word.to_nat(n, Word.adc(n, a, b, False{}, c)), U.U32Nat.dbl(n, U.U32Nat.bit(un.co(n, a, b, c)))) == Nat.add(U.U32Nat.bit(c), Nat.add(Word.to_nat(n, a), Word.to_nat(n, b))) : Nat}:
552  match n:
553    case 0n:
554      match a b c:
555        case WNil{} WNil{} False{}:
556          {==}
557        case WNil{} WNil{} True{}:
558          {==}
559    case 1n+ +p:
560      match a b c:
561        case WCon{False{}, +at} WCon{False{}, +bt} False{}:
562          un.cell(False{}, False{}, False{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, False{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, False{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, False{}))
563        case WCon{True{}, +at} WCon{False{}, +bt} False{}:
564          un.cell(True{}, False{}, False{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, False{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, False{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, False{}))
565        case WCon{False{}, +at} WCon{True{}, +bt} False{}:
566          un.cell(False{}, True{}, False{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, False{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, False{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, False{}))
567        case WCon{False{}, +at} WCon{False{}, +bt} True{}:
568          un.cell(False{}, False{}, True{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, False{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, False{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, False{}))
569        case WCon{True{}, +at} WCon{True{}, +bt} False{}:
570          un.cell(True{}, True{}, False{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, True{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, True{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, True{}))
571        case WCon{True{}, +at} WCon{False{}, +bt} True{}:
572          un.cell(True{}, False{}, True{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, True{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, True{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, True{}))
573        case WCon{False{}, +at} WCon{True{}, +bt} True{}:
574          un.cell(False{}, True{}, True{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, True{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, True{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, True{}))
575        case WCon{True{}, +at} WCon{True{}, +bt} True{}:
576          un.cell(True{}, True{}, True{}, Word.to_nat(p, Word.adc(p, at, bt, False{}, True{})), U.U32Nat.dbl(p, U.U32Nat.bit(un.co(p, at, bt, True{}))), Word.to_nat(p, at), Word.to_nat(p, bt), un.add_v(p, at, bt, True{}))
577
578# Subtraction is addition of the complement
579
580def un.wcon_cong(-p: Nat, -s: Bool, -x: Word(p), -y: Word(p), e: {x == y : Word(p)}) -> {WCon{s, x} == WCon{s, y} : Word(1n+p)}:
581  %e : {WCon{s, x} == WCon{s, _} : Word(1n+p)}
582  {==}
583
584def un.adc_not(n: Nat, a: Word(n), b: Word(n), c: Bool) -> {Word.adc(n, a, b, True{}, c) == Word.adc(n, a, Word.not(n, b), False{}, c) : Word(n)}:
585  match n:
586    case 0n:
587      match a b:
588        case WNil{} WNil{}:
589          {==}
590    case 1n+ +p:
591      match a b c:
592        case WCon{False{}, +at} WCon{False{}, +bt} False{}:
593          un.wcon_cong(p, True{}, Word.adc(p, at, bt, True{}, False{}), Word.adc(p, at, Word.not(p, bt), False{}, False{}), un.adc_not(p, at, bt, False{}))
594        case WCon{False{}, +at} WCon{False{}, +bt} True{}:
595          un.wcon_cong(p, False{}, Word.adc(p, at, bt, True{}, True{}), Word.adc(p, at, Word.not(p, bt), False{}, True{}), un.adc_not(p, at, bt, True{}))
596        case WCon{False{}, +at} WCon{True{}, +bt} False{}:
597          un.wcon_cong(p, False{}, Word.adc(p, at, bt, True{}, False{}), Word.adc(p, at, Word.not(p, bt), False{}, False{}), un.adc_not(p, at, bt, False{}))
598        case WCon{False{}, +at} WCon{True{}, +bt} True{}:
599          un.wcon_cong(p, True{}, Word.adc(p, at, bt, True{}, False{}), Word.adc(p, at, Word.not(p, bt), False{}, False{}), un.adc_not(p, at, bt, False{}))
600        case WCon{True{}, +at} WCon{False{}, +bt} False{}:
601          un.wcon_cong(p, False{}, Word.adc(p, at, bt, True{}, True{}), Word.adc(p, at, Word.not(p, bt), False{}, True{}), un.adc_not(p, at, bt, True{}))
602        case WCon{True{}, +at} WCon{False{}, +bt} True{}:
603          un.wcon_cong(p, True{}, Word.adc(p, at, bt, True{}, True{}), Word.adc(p, at, Word.not(p, bt), False{}, True{}), un.adc_not(p, at, bt, True{}))
604        case WCon{True{}, +at} WCon{True{}, +bt} False{}:
605          un.wcon_cong(p, True{}, Word.adc(p, at, bt, True{}, False{}), Word.adc(p, at, Word.not(p, bt), False{}, False{}), un.adc_not(p, at, bt, False{}))
606        case WCon{True{}, +at} WCon{True{}, +bt} True{}:
607          un.wcon_cong(p, False{}, Word.adc(p, at, bt, True{}, True{}), Word.adc(p, at, Word.not(p, bt), False{}, True{}), un.adc_not(p, at, bt, True{}))
608
609# Carries and borrows, from the values
610
611# s + 2^n * C = A + B with B < 2^n: C is whether s < A
612def un.carry(c: Bool, +n: Nat, +s: Nat, +a: Nat, +b: Nat, e: {Nat.add(s, U.U32Nat.dbl(n, U.U32Nat.bit(c))) == Nat.add(a, b) : Nat}, hb: {Nat.is_lt(b, U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {Nat.is_lt(s, a) == c : Bool}:
613  match c:
614    case True{}:
615      +k = U.U32Nat.dbl(n, 1n)
616      +h1 = Equal.trans(Bool, Nat.is_lt(Nat.add(a, b), Nat.add(a, k)), Nat.is_lt(b, k), True{}, un.lt_add_l(a, b, k), hb)
617      +h2 = un.lt_rw(Nat.add(a, b), Nat.add(s, k), Nat.add(a, k), Equal.sym(Nat, Nat.add(s, k), Nat.add(a, b), e), h1)
618      Equal.trans(Bool, Nat.is_lt(s, a), Nat.is_lt(Nat.add(s, k), Nat.add(a, k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.add(s, k), Nat.add(a, k)), Nat.is_lt(s, a), un.lt_add_r(s, a, k)), h2)
619    case False{}:
620      +es = Equal.trans(Nat, s, Nat.add(s, 0n), Nat.add(a, b), Equal.sym(Nat, Nat.add(s, 0n), s, un.add_zero(s)), Equal.trans(Nat, Nat.add(s, 0n), Nat.add(s, U.U32Nat.dbl(n, 0n)), Nat.add(a, b), Equal.cong(Nat, Nat, v => Nat.add(s, v), 0n, U.U32Nat.dbl(n, 0n), Equal.sym(Nat, U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n))), e))
621      %Equal.sym(Nat, s, Nat.add(a, b), es) : {Nat.is_lt(_, a) == False{} : Bool}
622      un.not_lt_add(a, b)
623
624# s + B = A + 2^n * C with s < 2^n: C is whether A < B
625def un.borrow(c: Bool, +n: Nat, +s: Nat, +a: Nat, +b: Nat, e: {Nat.add(s, b) == Nat.add(a, U.U32Nat.dbl(n, U.U32Nat.bit(c))) : Nat}, hs: {Nat.is_lt(s, U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {Nat.is_lt(a, b) == c : Bool}:
626  match c:
627    case True{}:
628      +k = U.U32Nat.dbl(n, 1n)
629      +h1 = Equal.trans(Bool, Nat.is_lt(Nat.add(s, b), Nat.add(k, b)), Nat.is_lt(s, k), True{}, un.lt_add_r(s, k, b), hs)
630      +h2 = un.lt_rw(Nat.add(s, b), Nat.add(a, k), Nat.add(k, b), e, h1)
631      +h3 = un.lt_rw2(Nat.add(a, k), Nat.add(k, b), Nat.add(b, k), un.add_comm(k, b), h2)
632      Equal.trans(Bool, Nat.is_lt(a, b), Nat.is_lt(Nat.add(a, k), Nat.add(b, k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.add(a, k), Nat.add(b, k)), Nat.is_lt(a, b), un.lt_add_r(a, b, k)), h3)
633    case False{}:
634      +ea = Equal.trans(Nat, Nat.add(s, b), Nat.add(a, U.U32Nat.dbl(n, 0n)), a, e, Equal.trans(Nat, Nat.add(a, U.U32Nat.dbl(n, 0n)), Nat.add(a, 0n), a, Equal.cong(Nat, Nat, v => Nat.add(a, v), U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n)), un.add_zero(a)))
635      %ea : {Nat.is_lt(_, b) == False{} : Bool}
636      un.not_lt_add_l(s, b)
637
638# The laws on words
639
640def Laws.word_add_wrap(n, a, b):
641  +s = Word.to_nat(n, Word.adc(n, a, b, False{}, False{}))
642  +av = Word.to_nat(n, a)
643  +bv = Word.to_nat(n, b)
644  +c = un.co(n, a, b, False{})
645  +ec = un.carry(c, n, s, av, bv, un.add_v(n, a, b, False{}), Laws.word_value_lt(n, b))
646  %Equal.sym(Cmp, Word.cmp(n, Word.adc(n, a, b, False{}, False{}), a), Nat.cmp(s, av), Laws.word_cmp_value(n, Word.adc(n, a, b, False{}, False{}), a)) : {Nat.add(s, U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(_)))) == Nat.add(av, bv) : Nat}
647  %Equal.sym(Bool, Nat.is_lt(s, av), c, ec) : {Nat.add(s, U.U32Nat.dbl(n, U.U32Nat.bit(_))) == Nat.add(av, bv) : Nat}
648  un.add_v(n, a, b, False{})
649
650def un.add_nowrap(c: Bool, +n: Nat, +s: Nat, +a: Nat, +b: Nat, +z: Nat, e: {Nat.add(s, U.U32Nat.dbl(n, U.U32Nat.bit(c))) == Nat.add(a, b) : Nat}, h: {Nat.is_le(Nat.add(a, b), z) == True{} : Bool}, hz: {Nat.is_lt(z, U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {s == Nat.add(a, b) : Nat}:
651  match c:
652    case True{}:
653      +k = U.U32Nat.dbl(n, 1n)
654      Empty.absurd({s == Nat.add(a, b) : Nat}, un.add_lt_absurd(s, k, un.lt_rw(Nat.add(a, b), Nat.add(s, k), k, Equal.sym(Nat, Nat.add(s, k), Nat.add(a, b), e), un.le_lt_trans(Nat.add(a, b), z, k, h, hz))))
655    case False{}:
656      Equal.trans(Nat, s, Nat.add(s, 0n), Nat.add(a, b), Equal.sym(Nat, Nat.add(s, 0n), s, un.add_zero(s)), Equal.trans(Nat, Nat.add(s, 0n), Nat.add(s, U.U32Nat.dbl(n, 0n)), Nat.add(a, b), Equal.cong(Nat, Nat, v => Nat.add(s, v), 0n, U.U32Nat.dbl(n, 0n), Equal.sym(Nat, U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n))), e))
657
658def Laws.word_add_value(n, a, b, z, h):
659  +s = Word.to_nat(n, Word.adc(n, a, b, False{}, False{}))
660  +av = Word.to_nat(n, a)
661  +bv = Word.to_nat(n, b)
662  un.add_nowrap(un.co(n, a, b, False{}), n, s, av, bv, Word.to_nat(n, z), un.add_v(n, a, b, False{}), h, Laws.word_value_lt(n, z))
663
664
665# (s + b) + k = (s + k) + b
666def un.add_swap(s: Nat, +b: Nat, +k: Nat) -> {Nat.add(Nat.add(s, b), k) == Nat.add(Nat.add(s, k), b) : Nat}:
667  match s:
668    case 0n:
669      un.add_comm(b, k)
670    case 1n+p:
671      un.succ_cong(Nat.add(Nat.add(p, b), k), Nat.add(Nat.add(p, k), b), un.add_swap(p, b, k))
672
673# (1 + (a + nb)) + b = a + k when 1 + nb + b = k
674def un.sub_mid(a: Nat, -nb: Nat, -b: Nat, -k: Nat, en: {1n+Nat.add(nb, b) == k : Nat}) -> {Nat.add(1n+Nat.add(a, nb), b) == Nat.add(a, k) : Nat}:
675  match a:
676    case 0n:
677      en
678    case 1n+p:
679      un.succ_cong(Nat.add(1n+Nat.add(p, nb), b), Nat.add(p, k), un.sub_mid(p, nb, b, k, en))
680
681# s + B = A + 2^n * C, from adc(a, not b, True) + 2^n * carry = 1 + A + not B
682# and 1 + not B + B = 2^n
683def un.sub_v(c: Bool, +n: Nat, +s: Nat, +a: Nat, +b: Nat, +nb: Nat, e: {Nat.add(s, U.U32Nat.dbl(n, U.U32Nat.bit(c))) == 1n+Nat.add(a, nb) : Nat}, en: {1n+Nat.add(nb, b) == U.U32Nat.dbl(n, 1n) : Nat}) -> {Nat.add(s, b) == Nat.add(a, U.U32Nat.dbl(n, U.U32Nat.bit(Bool.not(c)))) : Nat}:
684  match c:
685    case True{}:
686      +k = U.U32Nat.dbl(n, 1n)
687      +e2 = Equal.trans(Nat, Nat.add(Nat.add(s, b), k), Nat.add(Nat.add(s, k), b), Nat.add(a, k), un.add_swap(s, b, k), Equal.trans(Nat, Nat.add(Nat.add(s, k), b), Nat.add(1n+Nat.add(a, nb), b), Nat.add(a, k), Equal.cong(Nat, Nat, v => Nat.add(v, b), Nat.add(s, k), 1n+Nat.add(a, nb), e), un.sub_mid(a, nb, b, k, en)))
688      +e3 = un.add_cancel_r(Nat.add(s, b), a, k, e2)
689      Equal.trans(Nat, Nat.add(s, b), a, Nat.add(a, U.U32Nat.dbl(n, 0n)), e3, Equal.trans(Nat, a, Nat.add(a, 0n), Nat.add(a, U.U32Nat.dbl(n, 0n)), Equal.sym(Nat, Nat.add(a, 0n), a, un.add_zero(a)), Equal.cong(Nat, Nat, v => Nat.add(a, v), 0n, U.U32Nat.dbl(n, 0n), Equal.sym(Nat, U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n)))))
690    case False{}:
691      +e0 = Equal.trans(Nat, s, Nat.add(s, 0n), 1n+Nat.add(a, nb), Equal.sym(Nat, Nat.add(s, 0n), s, un.add_zero(s)), Equal.trans(Nat, Nat.add(s, 0n), Nat.add(s, U.U32Nat.dbl(n, 0n)), 1n+Nat.add(a, nb), Equal.cong(Nat, Nat, v => Nat.add(s, v), 0n, U.U32Nat.dbl(n, 0n), Equal.sym(Nat, U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n))), e))
692      Equal.trans(Nat, Nat.add(s, b), Nat.add(1n+Nat.add(a, nb), b), Nat.add(a, U.U32Nat.dbl(n, 1n)), Equal.cong(Nat, Nat, v => Nat.add(v, b), s, 1n+Nat.add(a, nb), e0), un.sub_mid(a, nb, b, U.U32Nat.dbl(n, 1n), en))
693
694
695
696def Laws.word_sub_wrap(n, a, b):
697  +nb = Word.not(n, b)
698  +s = Word.to_nat(n, Word.adc(n, a, nb, False{}, True{}))
699  +av = Word.to_nat(n, a)
700  +bv = Word.to_nat(n, b)
701  +nv = Word.to_nat(n, nb)
702  +c = un.co(n, a, nb, True{})
703  +eb = un.borrow(Bool.not(c), n, s, av, bv, un.sub_v(c, n, s, av, bv, nv, un.add_v(n, a, nb, True{}), Laws.word_not_value(n, b)), Laws.word_value_lt(n, Word.adc(n, a, nb, False{}, True{})))
704  %Equal.sym(Word(n), Word.adc(n, a, b, True{}, True{}), Word.adc(n, a, Word.not(n, b), False{}, True{}), un.adc_not(n, a, b, True{})) : {Nat.add(Word.to_nat(n, _), bv) == Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, a, b))))) : Nat}
705  %Equal.sym(Cmp, Word.cmp(n, a, b), Nat.cmp(av, bv), Laws.word_cmp_value(n, a, b)) : {Nat.add(s, bv) == Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(_)))) : Nat}
706  %Equal.sym(Bool, Nat.is_lt(av, bv), Bool.not(c), eb) : {Nat.add(s, bv) == Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(_))) : Nat}
707  un.sub_v(c, n, s, av, bv, nv, un.add_v(n, a, nb, True{}), Laws.word_not_value(n, b))
708
709def Laws.word_sub_value(n, a, b, h):
710  +s = Word.to_nat(n, Word.sub(n, a, b))
711  +av = Word.to_nat(n, a)
712  +bv = Word.to_nat(n, b)
713  +w = Laws.word_sub_wrap(n, a, b)
714  +nl = un.le_not_lt(bv, av, h)
715  +el = Equal.trans(Bool, Cmp.is_lt(Word.cmp(n, a, b)), Nat.is_lt(av, bv), False{}, Equal.cong(Cmp, Bool, x => Cmp.is_lt(x), Word.cmp(n, a, b), Nat.cmp(av, bv), Laws.word_cmp_value(n, a, b)), nl)
716  +e1 = Equal.trans(Nat, Nat.add(s, bv), Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(False{}))), av, Equal.trans(Nat, Nat.add(s, bv), Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, a, b))))), Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(False{}))), w, Equal.cong(Bool, Nat, x => Nat.add(av, U.U32Nat.dbl(n, U.U32Nat.bit(x))), Cmp.is_lt(Word.cmp(n, a, b)), False{}, el)), Equal.trans(Nat, Nat.add(av, U.U32Nat.dbl(n, 0n)), Nat.add(av, 0n), av, Equal.cong(Nat, Nat, v => Nat.add(av, v), U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n)), un.add_zero(av)))
717  %e1 : {s == Nat.sub(_, bv) : Nat}
718  Equal.sym(Nat, Nat.sub(Nat.add(s, bv), bv), s, un.sub_add(s, bv))
719
720# Increment
721
722def un.inc_w(n: Nat, w: Word(n), h: {Nat.is_lt(1n+Word.to_nat(n, w), U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {Word.to_nat(n, Word.inc(n, w)) == 1n+Word.to_nat(n, w) : Nat}:
723  match n:
724    case 0n:
725      Empty.absurd({Word.to_nat(0n, Word.inc(0n, w)) == 1n+Word.to_nat(0n, w) : Nat}, un.ft(h))
726    case 1n+ +p:
727      match w:
728        case WCon{False{}, t}:
729          {==}
730        case WCon{True{}, +t}:
731          +x = Word.to_nat(p, t)
732          un.double_cong(Word.to_nat(p, Word.inc(p, t)), 1n+x, un.inc_w(p, t, Equal.trans(Bool, Nat.is_lt(1n+x, U.U32Nat.dbl(p, 1n)), Nat.is_lt(Nat.double(1n+x), Nat.double(U.U32Nat.dbl(p, 1n))), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(1n+x), Nat.double(U.U32Nat.dbl(p, 1n))), Nat.is_lt(1n+x, U.U32Nat.dbl(p, 1n)), un.lt_dbl(1n+x, U.U32Nat.dbl(p, 1n))), h)))
733
734def Laws.word_inc_value(n, w, z, h):
735  un.inc_w(n, w, un.le_lt_trans(1n+Word.to_nat(n, w), Word.to_nat(n, z), U.U32Nat.dbl(n, 1n), h, Laws.word_value_lt(n, z)))
736
737# Shifts left: bits move up by one, a bit c coming in at the bottom
738
739def un.shlput(n: Nat, c: Bool, w: Word(n), h: {Nat.is_lt(Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(n, w))), U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {Word.to_nat(n, Word.shl.put(n, c, w)) == Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(n, w))) : Nat}:
740  match n:
741    case 0n:
742      match c w:
743        case False{} WNil{}:
744          {==}
745        case True{} WNil{}:
746          Empty.absurd({0n == 1n : Nat}, un.ft(h))
747    case 1n+ +p:
748      match c w:
749        case False{} WCon{False{}, +t}:
750          +k = U.U32Nat.dbl(p, 1n)
751          +x = Word.to_nat(p, t)
752          un.double_cong(Word.to_nat(p, Word.shl.put(p, False{}, t)), Nat.double(x), un.shlput(p, False{}, t, Equal.trans(Bool, Nat.is_lt(Nat.double(x), k), Nat.is_lt(Nat.double(Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(Nat.double(x)), Nat.double(k)), Nat.is_lt(Nat.double(x), k), un.lt_dbl(Nat.double(x), k)), h)))
753        case False{} WCon{True{}, +t}:
754          +k = U.U32Nat.dbl(p, 1n)
755          +x = Word.to_nat(p, t)
756          un.double_cong(Word.to_nat(p, Word.shl.put(p, True{}, t)), 1n+Nat.double(x), un.shlput(p, True{}, t, Equal.trans(Bool, Nat.is_lt(1n+Nat.double(x), k), Nat.is_lt(Nat.double(1n+Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(1n+Nat.double(x)), Nat.double(k)), Nat.is_lt(1n+Nat.double(x), k), un.lt_dbl(1n+Nat.double(x), k)), h)))
757        case True{} WCon{False{}, +t}:
758          +k = U.U32Nat.dbl(p, 1n)
759          +x = Word.to_nat(p, t)
760          un.succ_cong(Nat.double(Word.to_nat(p, Word.shl.put(p, False{}, t))), Nat.double(Nat.double(x)), un.double_cong(Word.to_nat(p, Word.shl.put(p, False{}, t)), Nat.double(x), un.shlput(p, False{}, t, Equal.trans(Bool, Nat.is_lt(Nat.double(x), k), Nat.is_lt(1n+Nat.double(Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(1n+Nat.double(Nat.double(x)), Nat.double(k)), Nat.is_lt(Nat.double(x), k), un.lt_dbl1(Nat.double(x), k)), h))))
761        case True{} WCon{True{}, +t}:
762          +k = U.U32Nat.dbl(p, 1n)
763          +x = Word.to_nat(p, t)
764          un.succ_cong(Nat.double(Word.to_nat(p, Word.shl.put(p, True{}, t))), Nat.double(1n+Nat.double(x)), un.double_cong(Word.to_nat(p, Word.shl.put(p, True{}, t)), 1n+Nat.double(x), un.shlput(p, True{}, t, Equal.trans(Bool, Nat.is_lt(1n+Nat.double(x), k), Nat.is_lt(1n+Nat.double(1n+Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(1n+Nat.double(1n+Nat.double(x)), Nat.double(k)), Nat.is_lt(1n+Nat.double(x), k), un.lt_dbl1(1n+Nat.double(x), k)), h))))
765
766def un.shl_w(n: Nat, w: Word(n), h: {Nat.is_lt(Nat.double(Word.to_nat(n, w)), U.U32Nat.dbl(n, 1n)) == True{} : Bool}) -> {Word.to_nat(n, Word.shl(n, w)) == Nat.double(Word.to_nat(n, w)) : Nat}:
767  match n:
768    case 0n:
769      match w:
770        case WNil{}:
771          {==}
772    case 1n+ +p:
773      match w:
774        case WCon{False{}, +t}:
775          +k = U.U32Nat.dbl(p, 1n)
776          +x = Word.to_nat(p, t)
777          un.double_cong(Word.to_nat(p, Word.shl.put(p, False{}, t)), Nat.double(x), un.shlput(p, False{}, t, Equal.trans(Bool, Nat.is_lt(Nat.double(x), k), Nat.is_lt(Nat.double(Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(Nat.double(x)), Nat.double(k)), Nat.is_lt(Nat.double(x), k), un.lt_dbl(Nat.double(x), k)), h)))
778        case WCon{True{}, +t}:
779          +k = U.U32Nat.dbl(p, 1n)
780          +x = Word.to_nat(p, t)
781          un.double_cong(Word.to_nat(p, Word.shl.put(p, True{}, t)), 1n+Nat.double(x), un.shlput(p, True{}, t, Equal.trans(Bool, Nat.is_lt(1n+Nat.double(x), k), Nat.is_lt(Nat.double(1n+Nat.double(x)), Nat.double(k)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(1n+Nat.double(x)), Nat.double(k)), Nat.is_lt(1n+Nat.double(x), k), un.lt_dbl(1n+Nat.double(x), k)), h)))
782
783def Laws.word_shl_value(n, w, z, h):
784  un.shl_w(n, w, un.le_lt_trans(Nat.double(Word.to_nat(n, w)), Word.to_nat(n, z), U.U32Nat.dbl(n, 1n), h, Laws.word_value_lt(n, z)))
785
786# Shifts right: halving
787
788def un.pad(p: Nat, t: Word(p)) -> {Word.to_nat(1n+p, Word.shr.pad(p, t)) == Word.to_nat(p, t) : Nat}:
789  match p:
790    case 0n:
791      {==}
792    case 1n+ +q:
793      match t:
794        case WCon{False{}, +r}:
795          un.double_cong(Word.to_nat(1n+q, Word.shr.pad(q, r)), Word.to_nat(q, r), un.pad(q, r))
796        case WCon{True{}, +r}:
797          un.succ_cong(Nat.double(Word.to_nat(1n+q, Word.shr.pad(q, r))), Nat.double(Word.to_nat(q, r)), un.double_cong(Word.to_nat(1n+q, Word.shr.pad(q, r)), Word.to_nat(q, r), un.pad(q, r)))
798
799def Laws.word_shr_value(n, w):
800  match n:
801    case 0n:
802      {==}
803    case 1n+ +p:
804      match w:
805        case WCon{False{}, +t}:
806          Equal.trans(Nat, Word.to_nat(1n+p, Word.shr.pad(p, t)), Word.to_nat(p, t), U.U32Nat.half(Nat.double(Word.to_nat(p, t))), un.pad(p, t), Equal.sym(Nat, U.U32Nat.half(Nat.double(Word.to_nat(p, t))), Word.to_nat(p, t), Laws.half_double(Word.to_nat(p, t))))
807        case WCon{True{}, +t}:
808          Equal.trans(Nat, Word.to_nat(1n+p, Word.shr.pad(p, t)), Word.to_nat(p, t), U.U32Nat.half(1n+Nat.double(Word.to_nat(p, t))), un.pad(p, t), Equal.sym(Nat, U.U32Nat.half(1n+Nat.double(Word.to_nat(p, t))), Word.to_nat(p, t), Laws.half_double_one(Word.to_nat(p, t))))
809
810# U32: the laws on Word(32n)
811
812def Laws.u32_cmp_value(a, b):
813  match a b:
814    case U32{x} U32{y}:
815      Laws.word_cmp_value(32n, x, y)
816
817def Laws.u32_lt_value(a, b):
818  %Laws.u32_cmp_value(a, b) : {Cmp.is_lt(U32.cmp(a, b)) == Cmp.is_lt(_) : Bool}
819  {==}
820
821def Laws.u32_le_value(a, b):
822  %Laws.u32_cmp_value(a, b) : {Cmp.is_le(U32.cmp(a, b)) == Cmp.is_le(_) : Bool}
823  {==}
824
825def Laws.u32_eq_value(a, b):
826  %Laws.u32_cmp_value(a, b) : {Cmp.is_eq(U32.cmp(a, b)) == Cmp.is_eq(_) : Bool}
827  {==}
828
829def un.u32_cong(-x: Word(32n), -y: Word(32n), e: {x == y : Word(32n)}) -> {U32{x} == U32{y} : U32}:
830  %e : {U32{x} == U32{_} : U32}
831  {==}
832
833def Laws.u32_value_eq(a, b, e):
834  match a b:
835    case U32{x} U32{y}:
836      un.u32_cong(x, y, Laws.word_value_eq(32n, x, y, e))
837
838def Laws.u32_add_wrap(a, b):
839  match a b:
840    case U32{x} U32{y}:
841      Laws.word_add_wrap(32n, x, y)
842
843def Laws.u32_add_value(a, b, c, h):
844  match a b c:
845    case U32{x} U32{y} U32{z}:
846      Laws.word_add_value(32n, x, y, z, h)
847
848def Laws.u32_sub_wrap(a, b):
849  match a b:
850    case U32{x} U32{y}:
851      Laws.word_sub_wrap(32n, x, y)
852
853def Laws.u32_sub_value(a, b, h):
854  match a b:
855    case U32{x} U32{y}:
856      Laws.word_sub_value(32n, x, y, h)
857
858def Laws.u32_inc_value(a, c, h):
859  match a c:
860    case U32{w} U32{z}:
861      Laws.word_inc_value(32n, w, z, h)
862
863def Laws.u32_shl_value(a, c, h):
864  match a c:
865    case U32{w} U32{z}:
866      Laws.word_shl_value(32n, w, z, h)
867
868def Laws.u32_shln_value(a, k, c, h):
869  match k:
870    case 0n:
871      {==}
872    case 1n+ +p:
873      +av = U32.to_nat(a)
874      +cv = U32.to_nat(c)
875      +ih = Laws.u32_shln_value(a, p, c, un.le_trans(U.U32Nat.dbl(p, av), Nat.double(U.U32Nat.dbl(p, av)), cv, un.le_double(U.U32Nat.dbl(p, av)), h))
876      +h2 = Equal.trans(Bool, Nat.is_le(Nat.double(U32.to_nat(U32.shln(a, p))), cv), Nat.is_le(Nat.double(U.U32Nat.dbl(p, av)), cv), True{}, Equal.cong(Nat, Bool, v => Nat.is_le(Nat.double(v), cv), U32.to_nat(U32.shln(a, p)), U.U32Nat.dbl(p, av), ih), h)
877      Equal.trans(Nat, U32.to_nat(U32.shl(U32.shln(a, p))), Nat.double(U32.to_nat(U32.shln(a, p))), Nat.double(U.U32Nat.dbl(p, av)), Laws.u32_shl_value(U32.shln(a, p), c, h2), un.double_cong(U32.to_nat(U32.shln(a, p)), U.U32Nat.dbl(p, av), ih))
878
879def Laws.u32_shr_value(a):
880  match a:
881    case U32{w}:
882      Laws.word_shr_value(32n, w)
883
884# Witnesses and vectors
885
886def Laws.u32_wit():
887  {==}
888
889def Laws.dbl_vec():
890  {==}
891
892# ---- generated by gen/proof.py from here on: do not edit by hand ----
893
894# The Nat library
895
896def Laws.nat_add_zero(x):
897  un.add_zero(x)
898
899def Laws.nat_add_succ(x, y):
900  un.add_succ(x, y)
901
902def Laws.nat_add_comm(x, y):
903  un.add_comm(x, y)
904
905def Laws.nat_add_assoc(x, y, z):
906  match x:
907    case 0n:
908      {==}
909    case 1n+p:
910      un.succ_cong(Nat.add(Nat.add(p, y), z), Nat.add(p, Nat.add(y, z)), Laws.nat_add_assoc(p, y, z))
911
912def Laws.nat_add_left_comm(x, y, z):
913  Equal.trans(Nat, Nat.add(x, Nat.add(y, z)), Nat.add(Nat.add(y, x), z), Nat.add(y, Nat.add(x, z)), Equal.trans(Nat, Nat.add(x, Nat.add(y, z)), Nat.add(Nat.add(x, y), z), Nat.add(Nat.add(y, x), z), Equal.sym(Nat, Nat.add(Nat.add(x, y), z), Nat.add(x, Nat.add(y, z)), Laws.nat_add_assoc(x, y, z)), Equal.cong(Nat, Nat, zz => Nat.add(zz, z), Nat.add(x, y), Nat.add(y, x), Laws.nat_add_comm(x, y))), Laws.nat_add_assoc(y, x, z))
914
915def Laws.nat_add_cancel(k, x, y, e):
916  match k:
917    case 0n:
918      e
919    case 1n+p:
920      Laws.nat_add_cancel(p, x, y, un.succ_inj(Nat.add(p, x), Nat.add(p, y), e))
921
922def Laws.nat_mul_zero(x):
923  match x:
924    case 0n:
925      {==}
926    case 1n+p:
927      Laws.nat_mul_zero(p)
928
929def Laws.nat_one_mul(x):
930  un.add_zero(x)
931
932def Laws.nat_mul_succ(x, y):
933  match x:
934    case 0n:
935      {==}
936    case 1n+p:
937      un.succ_cong(Nat.add(y, Nat.mul(p, 1n+y)), Nat.add(p, Nat.add(y, Nat.mul(p, y))), Equal.trans(Nat, Nat.add(y, Nat.mul(p, 1n+y)), Nat.add(y, Nat.add(p, Nat.mul(p, y))), Nat.add(p, Nat.add(y, Nat.mul(p, y))), Equal.cong(Nat, Nat, zz => Nat.add(y, zz), Nat.mul(p, 1n+y), Nat.add(p, Nat.mul(p, y)), Laws.nat_mul_succ(p, y)), Laws.nat_add_left_comm(y, p, Nat.mul(p, y))))
938
939def Laws.nat_mul_comm(x, y):
940  match x:
941    case 0n:
942      Equal.sym(Nat, Nat.mul(y, 0n), 0n, Laws.nat_mul_zero(y))
943    case 1n+p:
944      Equal.trans(Nat, Nat.add(y, Nat.mul(p, y)), Nat.add(y, Nat.mul(y, p)), Nat.mul(y, 1n+p), Equal.cong(Nat, Nat, zz => Nat.add(y, zz), Nat.mul(p, y), Nat.mul(y, p), Laws.nat_mul_comm(p, y)), Equal.sym(Nat, Nat.mul(y, 1n+p), Nat.add(y, Nat.mul(y, p)), Laws.nat_mul_succ(y, p)))
945
946def Laws.nat_add_mul(x, y, z):
947  match x:
948    case 0n:
949      {==}
950    case 1n+p:
951      Equal.trans(Nat, Nat.add(z, Nat.mul(Nat.add(p, y), z)), Nat.add(z, Nat.add(Nat.mul(p, z), Nat.mul(y, z))), Nat.add(Nat.add(z, Nat.mul(p, z)), Nat.mul(y, z)), Equal.cong(Nat, Nat, zz => Nat.add(z, zz), Nat.mul(Nat.add(p, y), z), Nat.add(Nat.mul(p, z), Nat.mul(y, z)), Laws.nat_add_mul(p, y, z)), Equal.sym(Nat, Nat.add(Nat.add(z, Nat.mul(p, z)), Nat.mul(y, z)), Nat.add(z, Nat.add(Nat.mul(p, z), Nat.mul(y, z))), Laws.nat_add_assoc(z, Nat.mul(p, z), Nat.mul(y, z))))
952
953def Laws.nat_mul_add(x, y, z):
954  Equal.trans(Nat, Nat.mul(x, Nat.add(y, z)), Nat.add(Nat.mul(x, y), Nat.mul(z, x)), Nat.add(Nat.mul(x, y), Nat.mul(x, z)), Equal.trans(Nat, Nat.mul(x, Nat.add(y, z)), Nat.add(Nat.mul(y, x), Nat.mul(z, x)), Nat.add(Nat.mul(x, y), Nat.mul(z, x)), Equal.trans(Nat, Nat.mul(x, Nat.add(y, z)), Nat.mul(Nat.add(y, z), x), Nat.add(Nat.mul(y, x), Nat.mul(z, x)), Laws.nat_mul_comm(x, Nat.add(y, z)), Laws.nat_add_mul(y, z, x)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.mul(z, x)), Nat.mul(y, x), Nat.mul(x, y), Laws.nat_mul_comm(y, x))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.mul(x, y), zz), Nat.mul(z, x), Nat.mul(x, z), Laws.nat_mul_comm(z, x)))
955
956def Laws.nat_mul_assoc(x, y, z):
957  match x:
958    case 0n:
959      {==}
960    case 1n+p:
961      Equal.trans(Nat, Nat.mul(Nat.add(y, Nat.mul(p, y)), z), Nat.add(Nat.mul(y, z), Nat.mul(Nat.mul(p, y), z)), Nat.add(Nat.mul(y, z), Nat.mul(p, Nat.mul(y, z))), Laws.nat_add_mul(y, Nat.mul(p, y), z), Equal.cong(Nat, Nat, zz => Nat.add(Nat.mul(y, z), zz), Nat.mul(Nat.mul(p, y), z), Nat.mul(p, Nat.mul(y, z)), Laws.nat_mul_assoc(p, y, z)))
962
963def Laws.nat_mul_left_comm(x, y, z):
964  Equal.trans(Nat, Nat.mul(x, Nat.mul(y, z)), Nat.mul(Nat.mul(y, x), z), Nat.mul(y, Nat.mul(x, z)), Equal.trans(Nat, Nat.mul(x, Nat.mul(y, z)), Nat.mul(Nat.mul(x, y), z), Nat.mul(Nat.mul(y, x), z), Equal.sym(Nat, Nat.mul(Nat.mul(x, y), z), Nat.mul(x, Nat.mul(y, z)), Laws.nat_mul_assoc(x, y, z)), Equal.cong(Nat, Nat, zz => Nat.mul(zz, z), Nat.mul(x, y), Nat.mul(y, x), Laws.nat_mul_comm(x, y))), Laws.nat_mul_assoc(y, x, z))
965
966def Laws.nat_mul_one(x):
967  Equal.trans(Nat, Nat.mul(x, 1n), Nat.mul(1n, x), x, Laws.nat_mul_comm(x, 1n), Laws.nat_one_mul(x))
968
969def Laws.nat_double(x):
970  match x:
971    case 0n:
972      {==}
973    case 1n+p:
974      un.succ_cong(1n+Nat.double(p), Nat.add(p, 1n+p), Equal.trans(Nat, 1n+Nat.double(p), 1n+Nat.add(p, p), Nat.add(p, 1n+p), un.succ_cong(Nat.double(p), Nat.add(p, p), Laws.nat_double(p)), Equal.sym(Nat, Nat.add(p, 1n+p), 1n+Nat.add(p, p), un.add_succ(p, p))))
975
976def Laws.dbl_comm(j, k, x):
977  Equal.trans(Nat, U.U32Nat.dbl(j, U.U32Nat.dbl(k, x)), U.U32Nat.dbl(Nat.add(k, j), x), U.U32Nat.dbl(k, U.U32Nat.dbl(j, x)), Equal.trans(Nat, U.U32Nat.dbl(j, U.U32Nat.dbl(k, x)), U.U32Nat.dbl(Nat.add(j, k), x), U.U32Nat.dbl(Nat.add(k, j), x), Laws.dbl_dbl(j, k, x), Equal.cong(Nat, Nat, zz => U.U32Nat.dbl(zz, x), Nat.add(j, k), Nat.add(k, j), Laws.nat_add_comm(j, k))), Equal.sym(Nat, U.U32Nat.dbl(k, U.U32Nat.dbl(j, x)), U.U32Nat.dbl(Nat.add(k, j), x), Laws.dbl_dbl(k, j, x)))
978
979def un.double_mul(+x: Nat, +y: Nat) -> {Nat.mul(Nat.double(x), y) == Nat.double(Nat.mul(x, y)) : Nat}:
980  Equal.trans(Nat, Nat.mul(Nat.double(x), y), Nat.add(Nat.mul(x, y), Nat.mul(x, y)), Nat.double(Nat.mul(x, y)), Equal.trans(Nat, Nat.mul(Nat.double(x), y), Nat.mul(Nat.add(x, x), y), Nat.add(Nat.mul(x, y), Nat.mul(x, y)), Equal.cong(Nat, Nat, zz => Nat.mul(zz, y), Nat.double(x), Nat.add(x, x), Laws.nat_double(x)), Laws.nat_add_mul(x, x, y)), Equal.sym(Nat, Nat.double(Nat.mul(x, y)), Nat.add(Nat.mul(x, y), Nat.mul(x, y)), Laws.nat_double(Nat.mul(x, y))))
981
982def Laws.dbl_mul_l(k, x, y):
983  match k:
984    case 0n:
985      {==}
986    case 1n+p:
987      Equal.trans(Nat, Nat.mul(Nat.double(U.U32Nat.dbl(p, x)), y), Nat.double(Nat.mul(U.U32Nat.dbl(p, x), y)), Nat.double(U.U32Nat.dbl(p, Nat.mul(x, y))), un.double_mul(U.U32Nat.dbl(p, x), y), un.double_cong(Nat.mul(U.U32Nat.dbl(p, x), y), U.U32Nat.dbl(p, Nat.mul(x, y)), Laws.dbl_mul_l(p, x, y)))
988
989def Laws.dbl_mul_r(k, x, y):
990  Equal.trans(Nat, Nat.mul(x, U.U32Nat.dbl(k, y)), U.U32Nat.dbl(k, Nat.mul(y, x)), U.U32Nat.dbl(k, Nat.mul(x, y)), Equal.trans(Nat, Nat.mul(x, U.U32Nat.dbl(k, y)), Nat.mul(U.U32Nat.dbl(k, y), x), U.U32Nat.dbl(k, Nat.mul(y, x)), Laws.nat_mul_comm(x, U.U32Nat.dbl(k, y)), Laws.dbl_mul_l(k, y, x)), Equal.cong(Nat, Nat, zz => U.U32Nat.dbl(k, zz), Nat.mul(y, x), Nat.mul(x, y), Laws.nat_mul_comm(y, x)))
991
992def Laws.nat_le_refl(x):
993  match x:
994    case 0n:
995      {==}
996    case 1n+p:
997      Laws.nat_le_refl(p)
998
999def Laws.nat_le_add(x, w):
1000  match w:
1001    case 0n:
1002      Laws.nat_le_refl(x)
1003    case 1n+v:
1004      un.le_trans(x, Nat.add(v, x), 1n+Nat.add(v, x), Laws.nat_le_add(x, v), un.le_succ_self(Nat.add(v, x)))
1005
1006def Laws.nat_lt_add(x, w):
1007  Equal.trans(Bool, Nat.is_lt(x, Nat.add(w, 1n+x)), Nat.is_le(1n+x, Nat.add(w, 1n+x)), True{}, Equal.sym(Bool, Nat.is_le(1n+x, Nat.add(w, 1n+x)), Nat.is_lt(x, Nat.add(w, 1n+x)), un.le_succ(x, Nat.add(w, 1n+x))), Laws.nat_le_add(1n+x, w))
1008
1009def Laws.nat_le_witness(x, y, h):
1010  match x y:
1011    case 0n 0n:
1012      {==}
1013    case 0n 1n+yp:
1014      un.add_zero(1n+yp)
1015    case 1n+xp 0n:
1016      Empty.absurd({Nat.add(0n, 1n+xp) == 0n : Nat}, un.ft(h))
1017    case 1n+xp 1n+yp:
1018      Equal.trans(Nat, Nat.add(Nat.sub(yp, xp), 1n+xp), 1n+Nat.add(Nat.sub(yp, xp), xp), 1n+yp, un.add_succ(Nat.sub(yp, xp), xp), un.succ_cong(Nat.add(Nat.sub(yp, xp), xp), yp, Laws.nat_le_witness(xp, yp, h)))
1019
1020def Laws.nat_lt_witness(x, y, h):
1021  Laws.nat_le_witness(1n+x, y, Equal.trans(Bool, Nat.is_le(1n+x, y), Nat.is_lt(x, y), True{}, un.le_succ(x, y), h))
1022
1023def un.nz(x: Nat) -> Type:
1024  match x:
1025    case 0n:
1026      Empty
1027    case 1n+p:
1028      Unit
1029
1030def un.sz(-a: Nat, e: {1n+a == 0n : Nat}) -> Empty:
1031  %e : un.nz(_)
1032  Unit{}
1033
1034def Laws.nat_succ_add_absurd(w, x, e):
1035  match x:
1036    case 0n:
1037      un.sz(Nat.add(w, 0n), Equal.trans(Nat, 1n+Nat.add(w, 0n), Nat.add(w, 1n), 0n, Equal.sym(Nat, Nat.add(w, 1n), 1n+Nat.add(w, 0n), un.add_succ(w, 0n)), e))
1038    case 1n+p:
1039      Laws.nat_succ_add_absurd(w, p, un.succ_inj(Nat.add(w, 1n+p), p, Equal.trans(Nat, 1n+Nat.add(w, 1n+p), Nat.add(w, 2n+p), 1n+p, Equal.sym(Nat, Nat.add(w, 2n+p), 1n+Nat.add(w, 1n+p), un.add_succ(w, 1n+p)), e)))
1040
1041def ur.r0(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, Nat.add(Nat.mul(x1, x2), x3)), 1n+x2) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}:
1042  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(Nat.mul(x1, x2), x3)), Nat.add(1n, x2)), Nat.add(x0, Nat.add(Nat.add(Nat.mul(x1, x2), x3), Nat.add(1n, x2))), Laws.nat_add_assoc(x0, Nat.add(Nat.mul(x1, x2), x3), Nat.add(1n, x2))) : {_ == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1043  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x1, x2), x3), Nat.add(1n, x2)), Nat.add(Nat.mul(x1, x2), Nat.add(x3, Nat.add(1n, x2))), Laws.nat_add_assoc(Nat.mul(x1, x2), x3, Nat.add(1n, x2))) : {Nat.add(x0, _) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1044  %Equal.sym(Nat, Nat.add(x3, Nat.add(1n, x2)), Nat.add(1n, Nat.add(x3, x2)), Laws.nat_add_left_comm(x3, 1n, x2)) : {Nat.add(x0, Nat.add(Nat.mul(x1, x2), _)) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1045  %Equal.sym(Nat, Nat.add(x3, x2), Nat.add(x2, x3), Laws.nat_add_comm(x3, x2)) : {Nat.add(x0, Nat.add(Nat.mul(x1, x2), Nat.add(1n, _))) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1046  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), Nat.add(1n, Nat.add(x2, x3))), Nat.add(1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3))), Laws.nat_add_left_comm(Nat.mul(x1, x2), 1n, Nat.add(x2, x3))) : {Nat.add(x0, _) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1047  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))) : {_ == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1048  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Nat.add(x0, Nat.add(1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3))))) : {_ == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1049  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)), Nat.add(Nat.add(Nat.mul(x1, x2), x2), x3), Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x1, x2), x2), x3), Nat.add(Nat.mul(x1, x2), Nat.add(x2, x3)), Laws.nat_add_assoc(Nat.mul(x1, x2), x2, x3))) : {Nat.add(x0, Nat.add(1n, _)) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1050  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), x2), Nat.add(x2, Nat.mul(x1, x2)), Equal.sym(Nat, Nat.add(x2, Nat.mul(x1, x2)), Nat.add(Nat.mul(x1, x2), x2), Laws.nat_add_comm(x2, Nat.mul(x1, x2)))) : {Nat.add(x0, Nat.add(1n, Nat.add(_, x3))) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1051  %Equal.sym(Nat, x2, Nat.mul(1n, x2), Equal.sym(Nat, Nat.mul(1n, x2), x2, Laws.nat_one_mul(x2))) : {Nat.add(x0, Nat.add(1n, Nat.add(Nat.add(_, Nat.mul(x1, x2)), x3))) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1052  %Equal.sym(Nat, Nat.add(Nat.mul(1n, x2), Nat.mul(x1, x2)), Nat.mul(Nat.add(1n, x1), x2), Equal.sym(Nat, Nat.mul(Nat.add(1n, x1), x2), Nat.add(Nat.mul(1n, x2), Nat.mul(x1, x2)), Laws.nat_add_mul(1n, x1, x2))) : {Nat.add(x0, Nat.add(1n, Nat.add(_, x3))) == Nat.add(x0, 1n+Nat.add(Nat.mul(1n+x1, x2), x3)) : Nat}
1053  {==}
1054
1055def ur.r1(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(x0, Nat.add(Nat.mul(x1, x0), x2)) == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}:
1056  %Equal.sym(Nat, Nat.mul(x1, x0), Nat.mul(x0, x1), Laws.nat_mul_comm(x1, x0)) : {Nat.add(x0, Nat.add(_, x2)) == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}
1057  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.mul(x0, x1), x2)), Nat.add(Nat.add(x0, Nat.mul(x0, x1)), x2), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.mul(x0, x1)), x2), Nat.add(x0, Nat.add(Nat.mul(x0, x1), x2)), Laws.nat_add_assoc(x0, Nat.mul(x0, x1), x2))) : {_ == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}
1058  %Equal.sym(Nat, Nat.mul(x0, x1), Nat.mul(x1, x0), Equal.sym(Nat, Nat.mul(x1, x0), Nat.mul(x0, x1), Laws.nat_mul_comm(x1, x0))) : {Nat.add(Nat.add(x0, _), x2) == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}
1059  %Equal.sym(Nat, x0, Nat.mul(1n, x0), Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0))) : {Nat.add(Nat.add(_, Nat.mul(x1, x0)), x2) == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}
1060  %Equal.sym(Nat, Nat.add(Nat.mul(1n, x0), Nat.mul(x1, x0)), Nat.mul(Nat.add(1n, x1), x0), Equal.sym(Nat, Nat.mul(Nat.add(1n, x1), x0), Nat.add(Nat.mul(1n, x0), Nat.mul(x1, x0)), Laws.nat_add_mul(1n, x1, x0))) : {Nat.add(_, x2) == Nat.add(Nat.mul(1n+x1, x0), x2) : Nat}
1061  {==}
1062
1063def ur.r2(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.mul(1n+x0, x1), x2) == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}:
1064  %Equal.sym(Nat, Nat.mul(Nat.add(1n, x0), x1), Nat.add(Nat.mul(1n, x1), Nat.mul(x0, x1)), Laws.nat_add_mul(1n, x0, x1)) : {Nat.add(_, x2) == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}
1065  %Equal.sym(Nat, Nat.mul(1n, x1), x1, Laws.nat_one_mul(x1)) : {Nat.add(Nat.add(_, Nat.mul(x0, x1)), x2) == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}
1066  %Equal.sym(Nat, Nat.add(x1, Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), x1), Laws.nat_add_comm(x1, Nat.mul(x0, x1))) : {Nat.add(_, x2) == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}
1067  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), x1), x2), Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Laws.nat_add_assoc(Nat.mul(x0, x1), x1, x2)) : {_ == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}
1068  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)), Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)), Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, Nat.mul(x0, x1), x2))) : {_ == Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)) : Nat}
1069  {==}
1070
1071def un.dmu.s(-s: Nat, -t: Nat, -r1: Nat, -r2: Nat, pr: {s == t : Nat} & {r1 == r2 : Nat}) -> {1n+s == 1n+t : Nat} & {r1 == r2 : Nat}:
1072  (a, c) = pr
1073  (un.succ_cong(s, t, a), c)
1074
1075def un.dmu(+b: Nat, +q1: Nat, +r1: Nat, +q2: Nat, +r2: Nat, e: {Nat.add(Nat.mul(q1, b), r1) == Nat.add(Nat.mul(q2, b), r2) : Nat}, h1: {Nat.is_lt(r1, b) == True{} : Bool}, h2: {Nat.is_lt(r2, b) == True{} : Bool}) -> {q1 == q2 : Nat} & {r1 == r2 : Nat}:
1076  match q1 q2:
1077    case 0n 0n:
1078      ({==}, e)
1079    case 0n 1n+s:
1080      Empty.absurd({0n == 1n+s : Nat} & {r1 == r2 : Nat}, Laws.nat_succ_add_absurd(Nat.add(Nat.sub(b, 1n+r1), Nat.add(Nat.mul(s, b), r2)), b, Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r1), Nat.add(Nat.mul(s, b), r2)), 1n+b), Nat.add(Nat.sub(b, 1n+r1), 1n+r1), b, Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r1), Nat.add(Nat.mul(s, b), r2)), 1n+b), Nat.add(Nat.sub(b, 1n+r1), 1n+Nat.add(Nat.mul(0n, b), r1)), Nat.add(Nat.sub(b, 1n+r1), 1n+r1), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r1), Nat.add(Nat.mul(s, b), r2)), 1n+b), Nat.add(Nat.sub(b, 1n+r1), 1n+Nat.add(Nat.mul(1n+s, b), r2)), Nat.add(Nat.sub(b, 1n+r1), 1n+Nat.add(Nat.mul(0n, b), r1)), ur.r0(Nat.sub(b, 1n+r1), s, b, r2), Equal.cong(Nat, Nat, zz => Nat.add(Nat.sub(b, 1n+r1), 1n+zz), Nat.add(Nat.mul(1n+s, b), r2), Nat.add(Nat.mul(0n, b), r1), Equal.sym(Nat, Nat.add(Nat.mul(0n, b), r1), Nat.add(Nat.mul(1n+s, b), r2), e))), {==}), Laws.nat_lt_witness(r1, b, h1))))
1081    case 1n+s 1n+t:
1082      un.dmu.s(s, t, r1, r2, un.dmu(b, s, r1, t, r2, Laws.nat_add_cancel(b, Nat.add(Nat.mul(s, b), r1), Nat.add(Nat.mul(t, b), r2), Equal.trans(Nat, Nat.add(b, Nat.add(Nat.mul(s, b), r1)), Nat.add(Nat.mul(1n+t, b), r2), Nat.add(b, Nat.add(Nat.mul(t, b), r2)), Equal.trans(Nat, Nat.add(b, Nat.add(Nat.mul(s, b), r1)), Nat.add(Nat.mul(1n+s, b), r1), Nat.add(Nat.mul(1n+t, b), r2), ur.r1(b, s, r1), e), ur.r2(t, b, r2))), h1, h2))
1083    case 1n+s 0n:
1084      Empty.absurd({1n+s == 0n : Nat} & {r1 == r2 : Nat}, Laws.nat_succ_add_absurd(Nat.add(Nat.sub(b, 1n+r2), Nat.add(Nat.mul(s, b), r1)), b, Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r2), Nat.add(Nat.mul(s, b), r1)), 1n+b), Nat.add(Nat.sub(b, 1n+r2), 1n+r2), b, Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r2), Nat.add(Nat.mul(s, b), r1)), 1n+b), Nat.add(Nat.sub(b, 1n+r2), 1n+Nat.add(Nat.mul(0n, b), r2)), Nat.add(Nat.sub(b, 1n+r2), 1n+r2), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(b, 1n+r2), Nat.add(Nat.mul(s, b), r1)), 1n+b), Nat.add(Nat.sub(b, 1n+r2), 1n+Nat.add(Nat.mul(1n+s, b), r1)), Nat.add(Nat.sub(b, 1n+r2), 1n+Nat.add(Nat.mul(0n, b), r2)), ur.r0(Nat.sub(b, 1n+r2), s, b, r1), Equal.cong(Nat, Nat, zz => Nat.add(Nat.sub(b, 1n+r2), 1n+zz), Nat.add(Nat.mul(1n+s, b), r1), Nat.add(Nat.mul(0n, b), r2), e)), {==}), Laws.nat_lt_witness(r2, b, h2))))
1085
1086def un.dmu.q(-q1: Nat, -q2: Nat, -r1: Nat, -r2: Nat, pr: {q1 == q2 : Nat} & {r1 == r2 : Nat}) -> {q1 == q2 : Nat}:
1087  (a, c) = pr
1088  a
1089
1090def un.dmu.r(-q1: Nat, -q2: Nat, -r1: Nat, -r2: Nat, pr: {q1 == q2 : Nat} & {r1 == r2 : Nat}) -> {r1 == r2 : Nat}:
1091  (a, c) = pr
1092  c
1093
1094def Laws.nat_div_unique(b, q1, r1, q2, r2, e, h1, h2):
1095  un.dmu.q(q1, q2, r1, r2, un.dmu(b, q1, r1, q2, r2, e, h1, h2))
1096
1097def Laws.nat_mod_unique(b, q1, r1, q2, r2, e, h1, h2):
1098  un.dmu.r(q1, q2, r1, r2, un.dmu(b, q1, r1, q2, r2, e, h1, h2))
1099
1100def ur.r3(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat) -> {Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))), 1n+U.U32Nat.dbl(x3, 1n)) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}:
1101  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))), Nat.add(1n, U.U32Nat.dbl(x3, 1n))), Nat.add(x0, Nat.add(Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4))), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))), Laws.nat_add_assoc(x0, Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4))), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))) : {_ == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1102  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4))), Nat.add(1n, U.U32Nat.dbl(x3, 1n))), Nat.add(x1, Nat.add(Nat.add(x2, U.U32Nat.dbl(x3, x4)), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))), Laws.nat_add_assoc(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))) : {Nat.add(x0, _) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1103  %Equal.sym(Nat, Nat.add(Nat.add(x2, U.U32Nat.dbl(x3, x4)), Nat.add(1n, U.U32Nat.dbl(x3, 1n))), Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))), Laws.nat_add_assoc(x2, U.U32Nat.dbl(x3, x4), Nat.add(1n, U.U32Nat.dbl(x3, 1n)))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1104  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(1n, U.U32Nat.dbl(x3, 1n))), Nat.add(1n, Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, 1n))), Laws.nat_add_left_comm(U.U32Nat.dbl(x3, x4), 1n, U.U32Nat.dbl(x3, 1n))) : {Nat.add(x0, Nat.add(x1, Nat.add(x2, _))) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1105  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, 1n)), Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)), Laws.nat_add_comm(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, 1n))) : {Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(1n, _)))) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1106  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))), Nat.add(1n, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))), Laws.nat_add_left_comm(x2, 1n, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1107  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4))))), Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4))))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4))))) : {Nat.add(x0, _) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1108  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))) : {_ == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1109  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4))))))) : {_ == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1110  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)), U.U32Nat.dbl(x3, Nat.add(1n, x4)), Equal.sym(Nat, U.U32Nat.dbl(x3, Nat.add(1n, x4)), Nat.add(U.U32Nat.dbl(x3, 1n), U.U32Nat.dbl(x3, x4)), Laws.dbl_add(x3, 1n, x4))) : {Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(x0, 1n+Nat.add(x1, Nat.add(x2, U.U32Nat.dbl(x3, 1n+x4)))) : Nat}
1111  {==}
1112
1113def Laws.dbl_nowrap(n, k, r, p, z, e, h, hz):
1114  match k:
1115    case 0n:
1116      Equal.trans(Nat, r, Nat.add(r, U.U32Nat.dbl(n, 0n)), p, Equal.trans(Nat, r, Nat.add(r, 0n), Nat.add(r, U.U32Nat.dbl(n, 0n)), Equal.sym(Nat, Nat.add(r, 0n), r, Laws.nat_add_zero(r)), Equal.cong(Nat, Nat, zz => Nat.add(r, zz), 0n, U.U32Nat.dbl(n, 0n), Equal.sym(Nat, U.U32Nat.dbl(n, 0n), 0n, Laws.dbl_zero(n)))), e)
1117    case 1n+j:
1118      Empty.absurd({r == p : Nat}, Laws.nat_succ_add_absurd(Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), Nat.add(Nat.sub(z, p), Nat.add(r, U.U32Nat.dbl(n, j)))), U.U32Nat.dbl(n, 1n), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), Nat.add(Nat.sub(z, p), Nat.add(r, U.U32Nat.dbl(n, j)))), 1n+U.U32Nat.dbl(n, 1n)), Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+z), U.U32Nat.dbl(n, 1n), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), Nat.add(Nat.sub(z, p), Nat.add(r, U.U32Nat.dbl(n, j)))), 1n+U.U32Nat.dbl(n, 1n)), Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+Nat.add(Nat.sub(z, p), p)), Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+z), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), Nat.add(Nat.sub(z, p), Nat.add(r, U.U32Nat.dbl(n, j)))), 1n+U.U32Nat.dbl(n, 1n)), Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+Nat.add(Nat.sub(z, p), Nat.add(r, U.U32Nat.dbl(n, 1n+j)))), Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+Nat.add(Nat.sub(z, p), p)), ur.r3(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), Nat.sub(z, p), r, n, j), Equal.cong(Nat, Nat, zz => Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+Nat.add(Nat.sub(z, p), zz)), Nat.add(r, U.U32Nat.dbl(n, 1n+j)), p, e)), Equal.cong(Nat, Nat, zz => Nat.add(Nat.sub(U.U32Nat.dbl(n, 1n), 1n+z), 1n+zz), Nat.add(Nat.sub(z, p), p), z, Laws.nat_le_witness(p, z, h))), Laws.nat_lt_witness(z, U.U32Nat.dbl(n, 1n), hz))))
1119
1120# The low bits and the rest
1121
1122def un.wc(-p: Nat, b: Bool, -t: Word(p)) -> {Word.to_nat(1n+p, WCon{b, t}) == Nat.add(U.U32Nat.bit(b), Nat.double(Word.to_nat(p, t))) : Nat}:
1123  match b:
1124    case True{}:
1125      {==}
1126    case False{}:
1127      {==}
1128
1129def ur.r4(+x0: Nat, +x1: Nat) -> {Nat.add(x0, 2n+Nat.double(x1)) == 2n+Nat.add(x0, Nat.double(x1)) : Nat}:
1130  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(x0, Nat.add(1n, Nat.add(1n, _))) == 2n+Nat.add(x0, Nat.double(x1)) : Nat}
1131  %Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x1, x1))), Nat.add(Nat.add(1n, 1n), Nat.add(x1, x1)), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x1, x1)), Nat.add(1n, Nat.add(1n, Nat.add(x1, x1))), Laws.nat_add_assoc(1n, 1n, Nat.add(x1, x1)))) : {Nat.add(x0, _) == 2n+Nat.add(x0, Nat.double(x1)) : Nat}
1132  %Equal.sym(Nat, Nat.add(x0, Nat.add(2n, Nat.add(x1, x1))), Nat.add(2n, Nat.add(x0, Nat.add(x1, x1))), Laws.nat_add_left_comm(x0, 2n, Nat.add(x1, x1))) : {_ == 2n+Nat.add(x0, Nat.double(x1)) : Nat}
1133  %Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x1, x1))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x1, x1))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x1, x1))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, Nat.add(x1, x1)))))) : {_ == 2n+Nat.add(x0, Nat.double(x1)) : Nat}
1134  %Equal.sym(Nat, Nat.add(x1, x1), Nat.double(x1), Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1))) : {Nat.add(1n, Nat.add(1n, Nat.add(x0, _))) == 2n+Nat.add(x0, Nat.double(x1)) : Nat}
1135  {==}
1136
1137def Laws.nat_odd_half(x):
1138  match x:
1139    case 0n:
1140      {==}
1141    case 1n+ +p:
1142      match p:
1143        case 0n:
1144          {==}
1145        case 1n+ +q:
1146          Equal.trans(Nat, Nat.add(U.U32Nat.odd(q), 2n+Nat.double(U.U32Nat.half(q))), 2n+Nat.add(U.U32Nat.odd(q), Nat.double(U.U32Nat.half(q))), 2n+q, ur.r4(U.U32Nat.odd(q), U.U32Nat.half(q)), Equal.cong(Nat, Nat, zz => 2n+zz, Nat.add(U.U32Nat.odd(q), Nat.double(U.U32Nat.half(q))), q, Laws.nat_odd_half(q)))
1147
1148def Laws.nat_odd_le(x):
1149  match x:
1150    case 0n:
1151      {==}
1152    case 1n+ +p:
1153      match p:
1154        case 0n:
1155          {==}
1156        case 1n+ +q:
1157          Laws.nat_odd_le(q)
1158
1159def ur.r5(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, Nat.double(x1)), Nat.double(U.U32Nat.dbl(x2, x3))) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}:
1160  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(Nat.add(x0, _), Nat.double(U.U32Nat.dbl(x2, x3))) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1161  %Equal.sym(Nat, Nat.double(U.U32Nat.dbl(x2, x3)), Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3)), Laws.nat_double(U.U32Nat.dbl(x2, x3))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), _) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1162  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3))), Nat.add(x0, Nat.add(Nat.add(x1, x1), Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3)))), Laws.nat_add_assoc(x0, Nat.add(x1, x1), Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3)))) : {_ == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1163  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3))), Nat.add(x1, Nat.add(x1, Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3)))), Laws.nat_add_assoc(x1, x1, Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3)))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1164  %Equal.sym(Nat, Nat.add(x1, Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3))), Nat.add(U.U32Nat.dbl(x2, x3), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x2, x3), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Nat.add(x1, Nat.add(U.U32Nat.dbl(x2, x3), U.U32Nat.dbl(x2, x3))), Laws.nat_add_left_comm(U.U32Nat.dbl(x2, x3), x1, U.U32Nat.dbl(x2, x3)))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1165  %Equal.sym(Nat, Nat.add(x1, Nat.add(U.U32Nat.dbl(x2, x3), Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Nat.add(Nat.add(x1, U.U32Nat.dbl(x2, x3)), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Equal.sym(Nat, Nat.add(Nat.add(x1, U.U32Nat.dbl(x2, x3)), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Nat.add(x1, Nat.add(U.U32Nat.dbl(x2, x3), Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Laws.nat_add_assoc(x1, U.U32Nat.dbl(x2, x3), Nat.add(x1, U.U32Nat.dbl(x2, x3))))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1166  %Equal.sym(Nat, Nat.add(Nat.add(x1, U.U32Nat.dbl(x2, x3)), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3))), Equal.sym(Nat, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3))), Nat.add(Nat.add(x1, U.U32Nat.dbl(x2, x3)), Nat.add(x1, U.U32Nat.dbl(x2, x3))), Laws.nat_double(Nat.add(x1, U.U32Nat.dbl(x2, x3))))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : Nat}
1167  {==}
1168
1169def Laws.low_high(k, x):
1170  match k:
1171    case 0n:
1172      {==}
1173    case 1n+ +j:
1174      Equal.trans(Nat, Nat.add(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.double(U.U32Nat.dbl(j, U.U32Nat.high(j, U.U32Nat.half(x))))), Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.half(x))), x, Equal.trans(Nat, Nat.add(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.double(U.U32Nat.dbl(j, U.U32Nat.high(j, U.U32Nat.half(x))))), Nat.add(U.U32Nat.odd(x), Nat.double(Nat.add(U.U32Nat.low(j, U.U32Nat.half(x)), U.U32Nat.dbl(j, U.U32Nat.high(j, U.U32Nat.half(x)))))), Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.half(x))), ur.r5(U.U32Nat.odd(x), U.U32Nat.low(j, U.U32Nat.half(x)), j, U.U32Nat.high(j, U.U32Nat.half(x))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.odd(x), Nat.double(zz)), Nat.add(U.U32Nat.low(j, U.U32Nat.half(x)), U.U32Nat.dbl(j, U.U32Nat.high(j, U.U32Nat.half(x)))), U.U32Nat.half(x), Laws.low_high(j, U.U32Nat.half(x)))), Laws.nat_odd_half(x))
1175
1176def ur.r6(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(Nat.double(x0), x1), 1n+Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}:
1177  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(Nat.add(_, x1), 1n+Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1178  %Equal.sym(Nat, Nat.add(Nat.add(x0, x0), x1), Nat.add(x0, Nat.add(x0, x1)), Laws.nat_add_assoc(x0, x0, x1)) : {Nat.add(_, 1n+Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1179  %Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3)) : {Nat.add(Nat.add(x0, Nat.add(x0, x1)), Nat.add(1n, Nat.add(x2, _))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1180  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x0, x1)), Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x0, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(x0, Nat.add(x0, x1), Nat.add(1n, Nat.add(x2, Nat.add(x3, x3))))) : {_ == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1181  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x0, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(x0, x1, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(x0, _) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1182  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(x0, Nat.add(x0, _)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1183  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(x0, _) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1184  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))))) : {_ == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1185  %Equal.sym(Nat, Nat.add(x2, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x2, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x2, x3))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, _)))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1186  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, Nat.add(x2, x3))), Nat.add(x3, Nat.add(x1, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, Nat.add(x2, x3))), Nat.add(x1, Nat.add(x3, Nat.add(x2, x3))), Laws.nat_add_left_comm(x3, x1, Nat.add(x2, x3)))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1187  %Equal.sym(Nat, Nat.add(x2, x3), Nat.add(x3, x2), Equal.sym(Nat, Nat.add(x3, x2), Nat.add(x2, x3), Laws.nat_add_comm(x3, x2))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, Nat.add(x1, _))))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1188  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, x2)), Nat.add(x3, Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, x2)), Nat.add(x1, Nat.add(x3, x2)), Laws.nat_add_left_comm(x3, x1, x2))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, _)))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1189  %Equal.sym(Nat, Nat.add(x3, Nat.add(x3, Nat.add(x1, x2))), Nat.add(Nat.add(x3, x3), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2)), Nat.add(x3, Nat.add(x3, Nat.add(x1, x2))), Laws.nat_add_assoc(x3, x3, Nat.add(x1, x2)))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1190  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2))), Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)), Nat.add(x0, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2))), Laws.nat_add_assoc(x0, Nat.add(x3, x3), Nat.add(x1, x2)))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1191  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2))), Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)), Nat.add(x0, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2))), Laws.nat_add_assoc(x0, Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)))) : {Nat.add(1n, _) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1192  %Equal.sym(Nat, Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2))), Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3)))), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3)))), Nat.add(x1, x2)), Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2))), Laws.nat_add_assoc(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)))) : {_ == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1193  %Equal.sym(Nat, Nat.add(x0, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x0, x3)), Nat.add(x0, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x0, x3))) : {Nat.add(Nat.add(1n, Nat.add(x0, _)), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1194  %Equal.sym(Nat, Nat.add(x0, Nat.add(x3, Nat.add(x0, x3))), Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Nat.add(x0, Nat.add(x3, Nat.add(x0, x3))), Laws.nat_add_assoc(x0, x3, Nat.add(x0, x3)))) : {Nat.add(Nat.add(1n, _), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1195  %Equal.sym(Nat, Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Nat.double(Nat.add(x0, x3)), Equal.sym(Nat, Nat.double(Nat.add(x0, x3)), Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Laws.nat_double(Nat.add(x0, x3)))) : {Nat.add(Nat.add(1n, _), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1196  {==}
1197
1198def ur.r7(+x0: Nat, +x1: Nat) -> {Nat.add(1n+Nat.double(Nat.add(x0, x1)), 1n) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}:
1199  %Equal.sym(Nat, Nat.double(Nat.add(x0, x1)), Nat.add(Nat.add(x0, x1), Nat.add(x0, x1)), Laws.nat_double(Nat.add(x0, x1))) : {Nat.add(Nat.add(1n, _), 1n) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1200  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(x0, x1)), Nat.add(x0, Nat.add(x1, Nat.add(x0, x1))), Laws.nat_add_assoc(x0, x1, Nat.add(x0, x1))) : {Nat.add(Nat.add(1n, _), 1n) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1201  %Equal.sym(Nat, Nat.add(x1, Nat.add(x0, x1)), Nat.add(x0, Nat.add(x1, x1)), Laws.nat_add_left_comm(x1, x0, x1)) : {Nat.add(Nat.add(1n, Nat.add(x0, _)), 1n) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1202  %Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), 1n), Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))), 1n)), Laws.nat_add_assoc(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))), 1n)) : {_ == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1203  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))), 1n), Nat.add(x0, Nat.add(Nat.add(x0, Nat.add(x1, x1)), 1n)), Laws.nat_add_assoc(x0, Nat.add(x0, Nat.add(x1, x1)), 1n)) : {Nat.add(1n, _) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1204  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, x1)), 1n), Nat.add(x0, Nat.add(Nat.add(x1, x1), 1n)), Laws.nat_add_assoc(x0, Nat.add(x1, x1), 1n)) : {Nat.add(1n, Nat.add(x0, _)) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1205  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), 1n), Nat.add(x1, Nat.add(x1, 1n)), Laws.nat_add_assoc(x1, x1, 1n)) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1206  %Equal.sym(Nat, Nat.add(x1, 1n), Nat.add(1n, x1), Laws.nat_add_comm(x1, 1n)) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, _)))) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1207  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, x1)), Nat.add(1n, Nat.add(x1, x1)), Laws.nat_add_left_comm(x1, 1n, x1)) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1208  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, x1))), Nat.add(1n, Nat.add(x0, Nat.add(x1, x1))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, x1))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1209  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x0, Nat.add(x1, x1)))) : {Nat.add(1n, _) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1210  %Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))))) : {_ == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1211  %Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))), Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1))))))) : {_ == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1212  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(x0, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x0, Nat.add(x1, x1)))), Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, x1)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x0, Nat.add(x1, x1))))) : {Nat.add(1n, _) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1213  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, x1)), Nat.add(x1, Nat.add(x0, x1)), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, x1)), Nat.add(x0, Nat.add(x1, x1)), Laws.nat_add_left_comm(x1, x0, x1))) : {Nat.add(1n, Nat.add(x0, Nat.add(1n, _))) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1214  %Equal.sym(Nat, Nat.add(1n, Nat.add(x1, Nat.add(x0, x1))), Nat.add(x1, Nat.add(1n, Nat.add(x0, x1))), Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x0, x1))), Nat.add(1n, Nat.add(x1, Nat.add(x0, x1))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x0, x1)))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1215  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(1n, Nat.add(x0, x1)))), Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x0, x1))), Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x0, x1))), Nat.add(x0, Nat.add(x1, Nat.add(1n, Nat.add(x0, x1)))), Laws.nat_add_assoc(x0, x1, Nat.add(1n, Nat.add(x0, x1))))) : {Nat.add(1n, _) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1216  %Equal.sym(Nat, Nat.add(1n, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x0, x1)))), Nat.add(Nat.add(1n, Nat.add(x0, x1)), Nat.add(1n, Nat.add(x0, x1))), Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, x1)), Nat.add(1n, Nat.add(x0, x1))), Nat.add(1n, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x0, x1)))), Laws.nat_add_assoc(1n, Nat.add(x0, x1), Nat.add(1n, Nat.add(x0, x1))))) : {_ == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1217  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, x1)), Nat.add(x0, Nat.add(1n, x1)), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, x1)), Nat.add(1n, Nat.add(x0, x1)), Laws.nat_add_left_comm(x0, 1n, x1))) : {Nat.add(Nat.add(1n, Nat.add(x0, x1)), _) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1218  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, x1)), Nat.add(x0, Nat.add(1n, x1)), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, x1)), Nat.add(1n, Nat.add(x0, x1)), Laws.nat_add_left_comm(x0, 1n, x1))) : {Nat.add(_, Nat.add(x0, 1n+x1)) == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1219  %Equal.sym(Nat, Nat.add(Nat.add(x0, 1n+x1), Nat.add(x0, 1n+x1)), Nat.double(Nat.add(x0, 1n+x1)), Equal.sym(Nat, Nat.double(Nat.add(x0, 1n+x1)), Nat.add(Nat.add(x0, 1n+x1), Nat.add(x0, 1n+x1)), Laws.nat_double(Nat.add(x0, 1n+x1)))) : {_ == Nat.double(Nat.add(x0, 1n+x1)) : Nat}
1220  {==}
1221
1222def Laws.low_lt(k, x):
1223  match k:
1224    case 0n:
1225      {==}
1226    case 1n+ +j:
1227      Equal.trans(Bool, Nat.is_lt(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.double(U.U32Nat.dbl(j, 1n))), Nat.is_lt(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))))), True{}, Equal.sym(Bool, Nat.is_lt(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))))), Nat.is_lt(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.double(U.U32Nat.dbl(j, 1n))), Equal.cong(Nat, Bool, zz => Nat.is_lt(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), zz), Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x))))), Nat.double(U.U32Nat.dbl(j, 1n)), Equal.trans(Nat, Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x))))), Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.double(U.U32Nat.dbl(j, 1n)), Equal.trans(Nat, Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x))))), Nat.add(1n+Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.low(j, U.U32Nat.half(x)))), 1n), Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Equal.trans(Nat, Nat.add(Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x))), 1n+Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x))))), Nat.add(1n+Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.add(Nat.sub(1n, U.U32Nat.odd(x)), U.U32Nat.odd(x))), Nat.add(1n+Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.low(j, U.U32Nat.half(x)))), 1n), ur.r6(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), Nat.sub(1n, U.U32Nat.odd(x)), U.U32Nat.odd(x), U.U32Nat.low(j, U.U32Nat.half(x))), Equal.cong(Nat, Nat, zz => Nat.add(1n+Nat.double(Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.low(j, U.U32Nat.half(x)))), zz), Nat.add(Nat.sub(1n, U.U32Nat.odd(x)), U.U32Nat.odd(x)), 1n, Laws.nat_le_witness(U.U32Nat.odd(x), 1n, Laws.nat_odd_le(x)))), ur.r7(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.low(j, U.U32Nat.half(x)))), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), 1n+U.U32Nat.low(j, U.U32Nat.half(x))), U.U32Nat.dbl(j, 1n), Laws.nat_lt_witness(U.U32Nat.low(j, U.U32Nat.half(x)), U.U32Nat.dbl(j, 1n), Laws.low_lt(j, U.U32Nat.half(x))))))), Laws.nat_lt_add(Nat.add(U.U32Nat.odd(x), Nat.double(U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.add(Nat.double(Nat.sub(U.U32Nat.dbl(j, 1n), 1n+U.U32Nat.low(j, U.U32Nat.half(x)))), Nat.sub(1n, U.U32Nat.odd(x)))))
1228
1229def ur.r8(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.mul(x0, U.U32Nat.dbl(x1, 1n)), x2) == Nat.add(x2, U.U32Nat.dbl(x1, x0)) : Nat}:
1230  %Equal.sym(Nat, Nat.mul(x0, U.U32Nat.dbl(x1, 1n)), U.U32Nat.dbl(x1, Nat.mul(x0, 1n)), Laws.dbl_mul_r(x1, x0, 1n)) : {Nat.add(_, x2) == Nat.add(x2, U.U32Nat.dbl(x1, x0)) : Nat}
1231  %Equal.sym(Nat, Nat.mul(x0, 1n), Nat.mul(1n, x0), Laws.nat_mul_comm(x0, 1n)) : {Nat.add(U.U32Nat.dbl(x1, _), x2) == Nat.add(x2, U.U32Nat.dbl(x1, x0)) : Nat}
1232  %Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0)) : {Nat.add(U.U32Nat.dbl(x1, _), x2) == Nat.add(x2, U.U32Nat.dbl(x1, x0)) : Nat}
1233  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x1, x0), x2), Nat.add(x2, U.U32Nat.dbl(x1, x0)), Laws.nat_add_comm(U.U32Nat.dbl(x1, x0), x2)) : {_ == Nat.add(x2, U.U32Nat.dbl(x1, x0)) : Nat}
1234  {==}
1235
1236def ur.r9(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, x2)) == Nat.add(Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), x0) : Nat}:
1237  %Equal.sym(Nat, Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x2), x0), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x1, x2), x0), Nat.add(x0, U.U32Nat.dbl(x1, x2)), Laws.nat_add_comm(U.U32Nat.dbl(x1, x2), x0))) : {_ == Nat.add(Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), x0) : Nat}
1238  %Equal.sym(Nat, x2, Nat.mul(1n, x2), Equal.sym(Nat, Nat.mul(1n, x2), x2, Laws.nat_one_mul(x2))) : {Nat.add(U.U32Nat.dbl(x1, _), x0) == Nat.add(Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), x0) : Nat}
1239  %Equal.sym(Nat, Nat.mul(1n, x2), Nat.mul(x2, 1n), Equal.sym(Nat, Nat.mul(x2, 1n), Nat.mul(1n, x2), Laws.nat_mul_comm(x2, 1n))) : {Nat.add(U.U32Nat.dbl(x1, _), x0) == Nat.add(Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), x0) : Nat}
1240  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.mul(x2, 1n)), Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), Equal.sym(Nat, Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), U.U32Nat.dbl(x1, Nat.mul(x2, 1n)), Laws.dbl_mul_r(x1, x2, 1n))) : {Nat.add(_, x0) == Nat.add(Nat.mul(x2, U.U32Nat.dbl(x1, 1n)), x0) : Nat}
1241  {==}
1242
1243def Laws.low_unique(k, x, r, q, e, h):
1244  Laws.nat_mod_unique(U.U32Nat.dbl(k, 1n), q, r, U.U32Nat.high(k, x), U.U32Nat.low(k, x), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Nat.add(Nat.mul(U.U32Nat.high(k, x), U.U32Nat.dbl(k, 1n)), U.U32Nat.low(k, x)), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), x, Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), Nat.add(r, U.U32Nat.dbl(k, q)), x, ur.r8(q, k, r), e), Equal.sym(Nat, Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), x, Laws.low_high(k, x))), ur.r9(U.U32Nat.low(k, x), k, U.U32Nat.high(k, x))), h, Laws.low_lt(k, x))
1245
1246def Laws.high_unique(k, x, r, q, e, h):
1247  Laws.nat_div_unique(U.U32Nat.dbl(k, 1n), q, r, U.U32Nat.high(k, x), U.U32Nat.low(k, x), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Nat.add(Nat.mul(U.U32Nat.high(k, x), U.U32Nat.dbl(k, 1n)), U.U32Nat.low(k, x)), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), x, Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Equal.trans(Nat, Nat.add(Nat.mul(q, U.U32Nat.dbl(k, 1n)), r), Nat.add(r, U.U32Nat.dbl(k, q)), x, ur.r8(q, k, r), e), Equal.sym(Nat, Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), x, Laws.low_high(k, x))), ur.r9(U.U32Nat.low(k, x), k, U.U32Nat.high(k, x))), h, Laws.low_lt(k, x))
1248
1249def ur.r10(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, Nat.add(x2, x3))) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, x3)) : Nat}:
1250  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.add(x2, x3)), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x3)), Laws.dbl_add(x1, x2, x3)) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, x3)) : Nat}
1251  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x3))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, x3)), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, x3)), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x3))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x3)))) : {_ == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, x3)) : Nat}
1252  {==}
1253
1254def Laws.low_add_dbl(k, x, q):
1255  Equal.sym(Nat, U.U32Nat.low(k, x), U.U32Nat.low(k, Nat.add(x, U.U32Nat.dbl(k, q))), Laws.low_unique(k, Nat.add(x, U.U32Nat.dbl(k, q)), U.U32Nat.low(k, x), Nat.add(U.U32Nat.high(k, x), q), Equal.trans(Nat, Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, Nat.add(U.U32Nat.high(k, x), q))), Nat.add(Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), U.U32Nat.dbl(k, q)), Nat.add(x, U.U32Nat.dbl(k, q)), ur.r10(U.U32Nat.low(k, x), k, U.U32Nat.high(k, x), q), Equal.cong(Nat, Nat, zz => Nat.add(zz, U.U32Nat.dbl(k, q)), Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), x, Laws.low_high(k, x))), Laws.low_lt(k, x)))
1256
1257def ur.r11(+x0: Nat, +x1: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, 0n)) == x0 : Nat}:
1258  %Equal.sym(Nat, U.U32Nat.dbl(x1, 0n), 0n, Laws.dbl_zero(x1)) : {Nat.add(x0, _) == x0 : Nat}
1259  %Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0)) : {_ == x0 : Nat}
1260  {==}
1261
1262def Laws.low_small(k, x, h):
1263  Equal.sym(Nat, x, U.U32Nat.low(k, x), Laws.low_unique(k, x, x, 0n, ur.r11(x, k), h))
1264
1265def un.low_zero(k: Nat) -> {U.U32Nat.low(k, 0n) == 0n : Nat}:
1266  match k:
1267    case 0n:
1268      {==}
1269    case 1n+ +j:
1270      un.double_cong(U.U32Nat.low(j, 0n), 0n, un.low_zero(j))
1271
1272# high(k, x / 2) = high(k, x) / 2
1273def un.high_half(k: Nat, +x: Nat) -> {U.U32Nat.high(k, U.U32Nat.half(x)) == U.U32Nat.half(U.U32Nat.high(k, x)) : Nat}:
1274  match k:
1275    case 0n:
1276      {==}
1277    case 1n+ +j:
1278      un.high_half(j, U.U32Nat.half(x))
1279
1280def ur.r12(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.double(x0), U.U32Nat.dbl(x1, Nat.double(x2))) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}:
1281  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(_, U.U32Nat.dbl(x1, Nat.double(x2))) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1282  %Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2)) : {Nat.add(Nat.add(x0, x0), U.U32Nat.dbl(x1, _)) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1283  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.add(x2, x2)), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)), Laws.dbl_add(x1, x2, x2)) : {Nat.add(Nat.add(x0, x0), _) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1284  %Equal.sym(Nat, Nat.add(Nat.add(x0, x0), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)))), Laws.nat_add_assoc(x0, x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1285  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Laws.nat_add_left_comm(U.U32Nat.dbl(x1, x2), x0, U.U32Nat.dbl(x1, x2)))) : {Nat.add(x0, _) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1286  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2)))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2)))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1287  %Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Laws.nat_double(Nat.add(x0, U.U32Nat.dbl(x1, x2))))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1288  {==}
1289
1290def un.low_double_low(+n: Nat, +y: Nat) -> {U.U32Nat.low(n, Nat.double(U.U32Nat.low(n, y))) == U.U32Nat.low(n, Nat.double(y)) : Nat}:
1291  Equal.trans(Nat, U.U32Nat.low(n, Nat.double(U.U32Nat.low(n, y))), U.U32Nat.low(n, Nat.add(Nat.double(U.U32Nat.low(n, y)), U.U32Nat.dbl(n, Nat.double(U.U32Nat.high(n, y))))), U.U32Nat.low(n, Nat.double(y)), Equal.sym(Nat, U.U32Nat.low(n, Nat.add(Nat.double(U.U32Nat.low(n, y)), U.U32Nat.dbl(n, Nat.double(U.U32Nat.high(n, y))))), U.U32Nat.low(n, Nat.double(U.U32Nat.low(n, y))), Laws.low_add_dbl(n, Nat.double(U.U32Nat.low(n, y)), Nat.double(U.U32Nat.high(n, y)))), Equal.cong(Nat, Nat, zz => U.U32Nat.low(n, zz), Nat.add(Nat.double(U.U32Nat.low(n, y)), U.U32Nat.dbl(n, Nat.double(U.U32Nat.high(n, y)))), Nat.double(y), Equal.trans(Nat, Nat.add(Nat.double(U.U32Nat.low(n, y)), U.U32Nat.dbl(n, Nat.double(U.U32Nat.high(n, y)))), Nat.double(Nat.add(U.U32Nat.low(n, y), U.U32Nat.dbl(n, U.U32Nat.high(n, y)))), Nat.double(y), ur.r12(U.U32Nat.low(n, y), n, U.U32Nat.high(n, y)), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(U.U32Nat.low(n, y), U.U32Nat.dbl(n, U.U32Nat.high(n, y))), y, Laws.low_high(n, y)))))
1292
1293def un.odd_d(v: Nat) -> {U.U32Nat.odd(Nat.double(v)) == 0n : Nat}:
1294  match v:
1295    case 0n:
1296      {==}
1297    case 1n+ +p:
1298      un.odd_d(p)
1299
1300def un.odd_d1(v: Nat) -> {U.U32Nat.odd(1n+Nat.double(v)) == 1n : Nat}:
1301  match v:
1302    case 0n:
1303      {==}
1304    case 1n+ +p:
1305      un.odd_d1(p)
1306
1307def un.odd_bd(b: Bool, +v: Nat) -> {U.U32Nat.odd(Nat.add(U.U32Nat.bit(b), Nat.double(v))) == U.U32Nat.bit(b) : Nat}:
1308  match b:
1309    case True{}:
1310      un.odd_d1(v)
1311    case False{}:
1312      un.odd_d(v)
1313
1314def un.half_bd(b: Bool, +v: Nat) -> {U.U32Nat.half(Nat.add(U.U32Nat.bit(b), Nat.double(v))) == v : Nat}:
1315  match b:
1316    case True{}:
1317      Laws.half_double_one(v)
1318    case False{}:
1319      Laws.half_double(v)
1320
1321# Products: Word.mul is shift and add, one bit of a at a time
1322
1323def un.topc(n: Nat, c: Bool, w: Word(n)) -> Bool:
1324  match n:
1325    case 0n:
1326      c
1327    case 1n+ +p:
1328      match w:
1329        case WCon{b, t}:
1330          un.topc(p, b, t)
1331
1332def un.top(n: Nat, w: Word(n)) -> Bool:
1333  match n:
1334    case 0n:
1335      False{}
1336    case 1n+ +p:
1337      match w:
1338        case WCon{b, t}:
1339          un.topc(p, b, t)
1340
1341# a shift left by one bit, c coming in: twice the value plus c, less 2^n for
1342# the bit going out
1343def un.putv(n: Nat, +c: Bool, +w: Word(n)) -> {Nat.add(Word.to_nat(n, Word.shl.put(n, c, w)), U.U32Nat.dbl(n, U.U32Nat.bit(un.topc(n, c, w)))) == Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(n, w))) : Nat}:
1344  match n:
1345    case 0n:
1346      Equal.sym(Nat, Nat.add(U.U32Nat.bit(c), 0n), U.U32Nat.bit(c), Laws.nat_add_zero(U.U32Nat.bit(c)))
1347    case 1n+ +p:
1348      match w:
1349        case WCon{+x, +t}:
1350          Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{c, Word.shl.put(p, x, t)}), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.add(U.U32Nat.bit(c), Nat.double(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))))), Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(1n+p, WCon{x, t}))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{c, Word.shl.put(p, x, t)}), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.add(U.U32Nat.bit(c), Nat.double(Nat.add(Word.to_nat(p, Word.shl.put(p, x, t)), U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t)))))), Nat.add(U.U32Nat.bit(c), Nat.double(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{c, Word.shl.put(p, x, t)}), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.add(Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(p, Word.shl.put(p, x, t)))), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.add(U.U32Nat.bit(c), Nat.double(Nat.add(Word.to_nat(p, Word.shl.put(p, x, t)), U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t)))))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Word.to_nat(1n+p, WCon{c, Word.shl.put(p, x, t)}), Nat.add(U.U32Nat.bit(c), Nat.double(Word.to_nat(p, Word.shl.put(p, x, t)))), un.wc(p, c, Word.shl.put(p, x, t))), ur.r5(U.U32Nat.bit(c), Word.to_nat(p, Word.shl.put(p, x, t)), p, U.U32Nat.bit(un.topc(p, x, t)))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(c), Nat.double(zz)), Nat.add(Word.to_nat(p, Word.shl.put(p, x, t)), U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), un.putv(p, x, t))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(c), Nat.double(zz)), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), Word.to_nat(1n+p, WCon{x, t}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, t}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), un.wc(p, x, t))))
1351
1352def ur.r13(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.double(x0), Nat.double(U.U32Nat.dbl(x1, x2))) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}:
1353  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(_, Nat.double(U.U32Nat.dbl(x1, x2))) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1354  %Equal.sym(Nat, Nat.double(U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)), Laws.nat_double(U.U32Nat.dbl(x1, x2))) : {Nat.add(Nat.add(x0, x0), _) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1355  %Equal.sym(Nat, Nat.add(Nat.add(x0, x0), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)))), Laws.nat_add_assoc(x0, x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2)))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1356  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, x2))), Laws.nat_add_left_comm(U.U32Nat.dbl(x1, x2), x0, U.U32Nat.dbl(x1, x2)))) : {Nat.add(x0, _) == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1357  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2)))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2)))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x1, x2), Nat.add(x0, U.U32Nat.dbl(x1, x2))))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1358  %Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))), Equal.sym(Nat, Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(x0, U.U32Nat.dbl(x1, x2))), Laws.nat_double(Nat.add(x0, U.U32Nat.dbl(x1, x2))))) : {_ == Nat.double(Nat.add(x0, U.U32Nat.dbl(x1, x2))) : Nat}
1359  {==}
1360
1361def un.shlv(n: Nat, +w: Word(n)) -> {Nat.add(Word.to_nat(n, Word.shl(n, w)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, w)))) == Nat.double(Word.to_nat(n, w)) : Nat}:
1362  match n:
1363    case 0n:
1364      {==}
1365    case 1n+ +p:
1366      match w:
1367        case WCon{+x, +t}:
1368          Equal.trans(Nat, Nat.add(Nat.double(Word.to_nat(p, Word.shl.put(p, x, t))), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.double(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t)))), Nat.double(Word.to_nat(1n+p, WCon{x, t})), Equal.trans(Nat, Nat.add(Nat.double(Word.to_nat(p, Word.shl.put(p, x, t))), Nat.double(U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.double(Nat.add(Word.to_nat(p, Word.shl.put(p, x, t)), U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t))))), Nat.double(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t)))), ur.r13(Word.to_nat(p, Word.shl.put(p, x, t)), p, U.U32Nat.bit(un.topc(p, x, t))), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(Word.to_nat(p, Word.shl.put(p, x, t)), U.U32Nat.dbl(p, U.U32Nat.bit(un.topc(p, x, t)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), un.putv(p, x, t))), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), Word.to_nat(1n+p, WCon{x, t}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, t}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, t))), un.wc(p, x, t))))
1369
1370def un.shl_low(+n: Nat, +w: Word(n)) -> {Word.to_nat(n, Word.shl(n, w)) == U.U32Nat.low(n, Nat.double(Word.to_nat(n, w))) : Nat}:
1371  Laws.low_unique(n, Nat.double(Word.to_nat(n, w)), Word.to_nat(n, Word.shl(n, w)), U.U32Nat.bit(un.top(n, w)), un.shlv(n, w), Laws.word_value_lt(n, Word.shl(n, w)))
1372
1373def um.k(+n: Nat, m: Nat, a: Word(m), +b: Word(n), +acc: Word(n)) -> Nat:
1374  match m:
1375    case 0n:
1376      0n
1377    case 1n+ +mp:
1378      match a:
1379        case WCon{False{}, +at}:
1380          Nat.add(um.k(n, mp, at, Word.shl(n, b), acc), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))
1381        case WCon{True{}, +at}:
1382          Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))
1383
1384def ur.r14(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, Nat.add(x2, Nat.mul(x3, x4)))) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, Nat.mul(x3, x4))) : Nat}:
1385  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.add(x2, Nat.mul(x3, x4))), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, Nat.mul(x3, x4))), Laws.dbl_add(x1, x2, Nat.mul(x3, x4))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, Nat.mul(x3, x4))) : Nat}
1386  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, Nat.mul(x3, x4)))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, Nat.mul(x3, x4))), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, Nat.mul(x3, x4))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, Nat.mul(x3, x4)))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, Nat.mul(x3, x4))))) : {_ == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), U.U32Nat.dbl(x1, Nat.mul(x3, x4))) : Nat}
1387  {==}
1388
1389def ur.r15(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat) -> {Nat.add(Nat.add(x0, Nat.mul(x1, x2)), U.U32Nat.dbl(x3, Nat.mul(x1, x4))) == Nat.add(x0, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))) : Nat}:
1390  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.mul(x1, x2)), U.U32Nat.dbl(x3, Nat.mul(x1, x4))), Nat.add(x0, Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x4)))), Laws.nat_add_assoc(x0, Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x4)))) : {_ == Nat.add(x0, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))) : Nat}
1391  %Equal.sym(Nat, U.U32Nat.dbl(x3, Nat.mul(x1, x4)), Nat.mul(x1, U.U32Nat.dbl(x3, x4)), Equal.sym(Nat, Nat.mul(x1, U.U32Nat.dbl(x3, x4)), U.U32Nat.dbl(x3, Nat.mul(x1, x4)), Laws.dbl_mul_r(x3, x1, x4))) : {Nat.add(x0, Nat.add(Nat.mul(x1, x2), _)) == Nat.add(x0, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))) : Nat}
1392  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), Nat.mul(x1, U.U32Nat.dbl(x3, x4))), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4))), Equal.sym(Nat, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4))), Nat.add(Nat.mul(x1, x2), Nat.mul(x1, U.U32Nat.dbl(x3, x4))), Laws.nat_mul_add(x1, x2, U.U32Nat.dbl(x3, x4)))) : {Nat.add(x0, _) == Nat.add(x0, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x4)))) : Nat}
1393  {==}
1394
1395def ur.r16(+x0: Nat, +x1: Nat) -> {Nat.mul(x0, Nat.double(x1)) == Nat.mul(Nat.double(x0), x1) : Nat}:
1396  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.mul(x0, _) == Nat.mul(Nat.double(x0), x1) : Nat}
1397  %Equal.sym(Nat, Nat.mul(x0, Nat.add(x1, x1)), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_mul_add(x0, x1, x1)) : {_ == Nat.mul(Nat.double(x0), x1) : Nat}
1398  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Nat.mul(Nat.add(x0, x0), x1), Equal.sym(Nat, Nat.mul(Nat.add(x0, x0), x1), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_add_mul(x0, x0, x1))) : {_ == Nat.mul(Nat.double(x0), x1) : Nat}
1399  %Equal.sym(Nat, Nat.add(x0, x0), Nat.double(x0), Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0))) : {Nat.mul(_, x1) == Nat.mul(Nat.double(x0), x1) : Nat}
1400  {==}
1401
1402def ur.r17(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat, +x5: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, Nat.add(x2, Nat.add(x3, Nat.mul(x4, x5))))) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))) : Nat}:
1403  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.add(x2, Nat.add(x3, Nat.mul(x4, x5)))), Nat.add(U.U32Nat.dbl(x1, x2), U.U32Nat.dbl(x1, Nat.add(x3, Nat.mul(x4, x5)))), Laws.dbl_add(x1, x2, Nat.add(x3, Nat.mul(x4, x5)))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))) : Nat}
1404  %Equal.sym(Nat, U.U32Nat.dbl(x1, Nat.add(x3, Nat.mul(x4, x5))), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5))), Laws.dbl_add(x1, x3, Nat.mul(x4, x5))) : {Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), _)) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))) : Nat}
1405  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5))))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x1, x2), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5))))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x1, x2), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))))) : {_ == Nat.add(Nat.add(x0, U.U32Nat.dbl(x1, x2)), Nat.add(U.U32Nat.dbl(x1, x3), U.U32Nat.dbl(x1, Nat.mul(x4, x5)))) : Nat}
1406  {==}
1407
1408def ur.r18(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat, +x5: Nat) -> {Nat.add(Nat.add(x0, Nat.mul(x1, x2)), Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}:
1409  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5))), Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4)), Laws.nat_add_comm(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))) : {Nat.add(Nat.add(x0, Nat.mul(x1, x2)), _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1410  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.mul(x1, x2)), Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4))), Nat.add(x0, Nat.add(Nat.mul(x1, x2), Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4)))), Laws.nat_add_assoc(x0, Nat.mul(x1, x2), Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4)))) : {_ == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1411  %Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4)), Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5))), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5))), Nat.add(U.U32Nat.dbl(x3, Nat.mul(x1, x5)), U.U32Nat.dbl(x3, x4)), Laws.nat_add_comm(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5))))) : {Nat.add(x0, Nat.add(Nat.mul(x1, x2), _)) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1412  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Equal.sym(Nat, Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Nat.add(Nat.mul(x1, x2), Nat.add(U.U32Nat.dbl(x3, x4), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Laws.nat_add_left_comm(U.U32Nat.dbl(x3, x4), Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1413  %Equal.sym(Nat, Nat.add(x0, Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5))))), Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Equal.sym(Nat, Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))), Nat.add(x0, Nat.add(U.U32Nat.dbl(x3, x4), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5))))), Laws.nat_add_assoc(x0, U.U32Nat.dbl(x3, x4), Nat.add(Nat.mul(x1, x2), U.U32Nat.dbl(x3, Nat.mul(x1, x5)))))) : {_ == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1414  %Equal.sym(Nat, U.U32Nat.dbl(x3, Nat.mul(x1, x5)), Nat.mul(x1, U.U32Nat.dbl(x3, x5)), Equal.sym(Nat, Nat.mul(x1, U.U32Nat.dbl(x3, x5)), U.U32Nat.dbl(x3, Nat.mul(x1, x5)), Laws.dbl_mul_r(x3, x1, x5))) : {Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.add(Nat.mul(x1, x2), _)) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1415  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x2), Nat.mul(x1, U.U32Nat.dbl(x3, x5))), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5))), Equal.sym(Nat, Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5))), Nat.add(Nat.mul(x1, x2), Nat.mul(x1, U.U32Nat.dbl(x3, x5))), Laws.nat_mul_add(x1, x2, U.U32Nat.dbl(x3, x5)))) : {Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), _) == Nat.add(Nat.add(x0, U.U32Nat.dbl(x3, x4)), Nat.mul(x1, Nat.add(x2, U.U32Nat.dbl(x3, x5)))) : Nat}
1416  {==}
1417
1418def ur.r19(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.add(x0, x1), Nat.mul(x2, Nat.double(x1))) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}:
1419  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(Nat.add(x0, x1), Nat.mul(x2, _)) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1420  %Equal.sym(Nat, Nat.mul(x2, Nat.add(x1, x1)), Nat.add(Nat.mul(x2, x1), Nat.mul(x2, x1)), Laws.nat_mul_add(x2, x1, x1)) : {Nat.add(Nat.add(x0, x1), _) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1421  %Equal.sym(Nat, Nat.mul(x2, x1), Nat.mul(x1, x2), Laws.nat_mul_comm(x2, x1)) : {Nat.add(Nat.add(x0, x1), Nat.add(_, Nat.mul(x2, x1))) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1422  %Equal.sym(Nat, Nat.mul(x2, x1), Nat.mul(x1, x2), Laws.nat_mul_comm(x2, x1)) : {Nat.add(Nat.add(x0, x1), Nat.add(Nat.mul(x1, x2), _)) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1423  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(Nat.mul(x1, x2), Nat.mul(x1, x2))), Nat.add(x0, Nat.add(x1, Nat.add(Nat.mul(x1, x2), Nat.mul(x1, x2)))), Laws.nat_add_assoc(x0, x1, Nat.add(Nat.mul(x1, x2), Nat.mul(x1, x2)))) : {_ == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1424  %Equal.sym(Nat, Nat.mul(x1, x2), Nat.mul(x2, x1), Equal.sym(Nat, Nat.mul(x2, x1), Nat.mul(x1, x2), Laws.nat_mul_comm(x2, x1))) : {Nat.add(x0, Nat.add(x1, Nat.add(Nat.mul(x1, x2), _))) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1425  %Equal.sym(Nat, Nat.mul(x1, x2), Nat.mul(x2, x1), Equal.sym(Nat, Nat.mul(x2, x1), Nat.mul(x1, x2), Laws.nat_mul_comm(x2, x1))) : {Nat.add(x0, Nat.add(x1, Nat.add(_, Nat.mul(x2, x1)))) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1426  %Equal.sym(Nat, x1, Nat.mul(1n, x1), Equal.sym(Nat, Nat.mul(1n, x1), x1, Laws.nat_one_mul(x1))) : {Nat.add(x0, Nat.add(_, Nat.add(Nat.mul(x2, x1), Nat.mul(x2, x1)))) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1427  %Equal.sym(Nat, Nat.add(Nat.mul(x2, x1), Nat.mul(x2, x1)), Nat.mul(Nat.add(x2, x2), x1), Equal.sym(Nat, Nat.mul(Nat.add(x2, x2), x1), Nat.add(Nat.mul(x2, x1), Nat.mul(x2, x1)), Laws.nat_add_mul(x2, x2, x1))) : {Nat.add(x0, Nat.add(Nat.mul(1n, x1), _)) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1428  %Equal.sym(Nat, Nat.add(Nat.mul(1n, x1), Nat.mul(Nat.add(x2, x2), x1)), Nat.mul(Nat.add(1n, Nat.add(x2, x2)), x1), Equal.sym(Nat, Nat.mul(Nat.add(1n, Nat.add(x2, x2)), x1), Nat.add(Nat.mul(1n, x1), Nat.mul(Nat.add(x2, x2), x1)), Laws.nat_add_mul(1n, Nat.add(x2, x2), x1))) : {Nat.add(x0, _) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1429  %Equal.sym(Nat, Nat.add(x2, x2), Nat.double(x2), Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2))) : {Nat.add(x0, Nat.mul(Nat.add(1n, _), x1)) == Nat.add(x0, Nat.mul(1n+Nat.double(x2), x1)) : Nat}
1430  {==}
1431
1432def ur.r20(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, 0n)) == Nat.add(x0, Nat.mul(0n, x2)) : Nat}:
1433  %Equal.sym(Nat, U.U32Nat.dbl(x1, 0n), 0n, Laws.dbl_zero(x1)) : {Nat.add(x0, _) == Nat.add(x0, Nat.mul(0n, x2)) : Nat}
1434  %Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0)) : {_ == Nat.add(x0, Nat.mul(0n, x2)) : Nat}
1435  %Equal.sym(Nat, x0, Nat.add(x0, 0n), Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0))) : {_ == Nat.add(x0, Nat.mul(0n, x2)) : Nat}
1436  {==}
1437
1438def um.go(+n: Nat, m: Nat, a: Word(m), +b: Word(n), +acc: Word(n)) -> {Nat.add(Word.to_nat(n, Word.mul.go(n, m, a, b, acc)), U.U32Nat.dbl(n, um.k(n, m, a, b, acc))) == Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(m, a), Word.to_nat(n, b))) : Nat}:
1439  match m:
1440    case 0n:
1441      ur.r20(Word.to_nat(n, acc), n, Word.to_nat(n, b))
1442    case 1n+ +mp:
1443      match a:
1444        case WCon{False{}, +at}:
1445          Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), acc), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Nat.double(Word.to_nat(n, b)))), Nat.add(Word.to_nat(n, acc), Nat.mul(Nat.double(Word.to_nat(mp, at)), Word.to_nat(n, b))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), acc), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Nat.double(Word.to_nat(n, b)))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), acc), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))), Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), acc), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, um.k(n, mp, at, Word.shl(n, b), acc))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))), Nat.add(Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))), ur.r14(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), n, um.k(n, mp, at, Word.shl(n, b), acc), Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))), Equal.cong(Nat, Nat, zz => Nat.add(zz, U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))), Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), acc)), U.U32Nat.dbl(n, um.k(n, mp, at, Word.shl(n, b), acc))), Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), um.go(n, mp, at, Word.shl(n, b), acc))), ur.r15(Word.to_nat(n, acc), Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)), n, U.U32Nat.bit(un.top(n, b)))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(n, acc), Nat.mul(Word.to_nat(mp, at), zz)), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))), Nat.double(Word.to_nat(n, b)), un.shlv(n, b))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(n, acc), zz), Nat.mul(Word.to_nat(mp, at), Nat.double(Word.to_nat(n, b))), Nat.mul(Nat.double(Word.to_nat(mp, at)), Word.to_nat(n, b)), ur.r16(Word.to_nat(mp, at), Word.to_nat(n, b))))
1446        case WCon{True{}, +at}:
1447          Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))))), Nat.add(Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Nat.mul(Word.to_nat(mp, at), Nat.double(Word.to_nat(n, b)))), Nat.add(Word.to_nat(n, acc), Nat.mul(1n+Nat.double(Word.to_nat(mp, at)), Word.to_nat(n, b))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))))), Nat.add(Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Nat.mul(Word.to_nat(mp, at), Nat.double(Word.to_nat(n, b)))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))))), Nat.add(Nat.add(Word.to_nat(n, Word.add(n, acc, b)), U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))))), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))))), Nat.add(Nat.add(Word.to_nat(n, Word.add(n, acc, b)), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), Nat.add(U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, Word.add(n, acc, b)), U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))))), Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, Nat.add(um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), Nat.add(U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))))))), Nat.add(Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)))), Nat.add(U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Nat.add(Word.to_nat(n, Word.add(n, acc, b)), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), Nat.add(U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), ur.r17(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), n, um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)), U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.add(U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc)))), U.U32Nat.dbl(n, Nat.mul(Word.to_nat(mp, at), U.U32Nat.bit(un.top(n, b)))))), Nat.add(Word.to_nat(n, Word.mul.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b))), U.U32Nat.dbl(n, um.k(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)))), Nat.add(Word.to_nat(n, Word.add(n, acc, b)), Nat.mul(Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)))), um.go(n, mp, at, Word.shl(n, b), Word.add(n, acc, b)))), ur.r18(Word.to_nat(n, Word.add(n, acc, b)), Word.to_nat(mp, at), Word.to_nat(n, Word.shl(n, b)), n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))), U.U32Nat.bit(un.top(n, b)))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.mul(Word.to_nat(mp, at), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))))), Nat.add(Word.to_nat(n, Word.add(n, acc, b)), U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, Word.add(n, acc, b), acc))))), Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Laws.word_add_wrap(n, acc, b))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(Word.to_nat(n, acc), Word.to_nat(n, b)), Nat.mul(Word.to_nat(mp, at), zz)), Nat.add(Word.to_nat(n, Word.shl(n, b)), U.U32Nat.dbl(n, U.U32Nat.bit(un.top(n, b)))), Nat.double(Word.to_nat(n, b)), un.shlv(n, b))), ur.r19(Word.to_nat(n, acc), Word.to_nat(n, b), Word.to_nat(mp, at)))
1448
1449def um.e(+n: Nat, +a: Word(n), +b: Word(n)) -> {Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, um.k(n, n, a, b, Word.zero(n)))) == Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)) : Nat}:
1450  Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, um.k(n, n, a, b, Word.zero(n)))), Nat.add(0n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, um.k(n, n, a, b, Word.zero(n)))), Nat.add(Word.to_nat(n, Word.zero(n)), Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), Nat.add(0n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), um.go(n, n, a, b, Word.zero(n)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), Word.to_nat(n, Word.zero(n)), 0n, Laws.word_zero_value(n))), {==})
1451
1452def Laws.word_mul_low(n, a, b):
1453  Laws.low_unique(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)), Word.to_nat(n, Word.mul(n, a, b)), um.k(n, n, a, b, Word.zero(n)), um.e(n, a, b), Laws.word_value_lt(n, Word.mul(n, a, b)))
1454
1455def Laws.word_mul_wrap(n, a, b):
1456  Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, U.U32Nat.high(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))))), Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, um.k(n, n, a, b, Word.zero(n)))), Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(n, Word.mul(n, a, b)), U.U32Nat.dbl(n, zz)), U.U32Nat.high(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), um.k(n, n, a, b, Word.zero(n)), Equal.sym(Nat, um.k(n, n, a, b, Word.zero(n)), U.U32Nat.high(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), Laws.high_unique(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)), Word.to_nat(n, Word.mul(n, a, b)), um.k(n, n, a, b, Word.zero(n)), um.e(n, a, b), Laws.word_value_lt(n, Word.mul(n, a, b))))), um.e(n, a, b))
1457
1458def Laws.word_mul_value(n, a, b, z, h):
1459  Laws.dbl_nowrap(n, U.U32Nat.high(n, Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b))), Word.to_nat(n, Word.mul(n, a, b)), Nat.mul(Word.to_nat(n, a), Word.to_nat(n, b)), Word.to_nat(n, z), Laws.word_mul_wrap(n, a, b), h, Laws.word_value_lt(n, z))
1460
1461def Laws.u32_mul_wrap(a, b):
1462  match a b:
1463    case U32{+x} U32{+y}:
1464      Laws.word_mul_wrap(32n, x, y)
1465
1466def Laws.u32_mul_low(a, b):
1467  match a b:
1468    case U32{+x} U32{+y}:
1469      Laws.word_mul_low(32n, x, y)
1470
1471def Laws.u32_mul_value(a, b, c, h):
1472  match a b c:
1473    case U32{+x} U32{+y} U32{+z}:
1474      Laws.word_mul_value(32n, x, y, z, h)
1475
1476# Division: Base's U32.divmod.go, one quotient bit a step, keeps q b + r
1477# = the bits read so far, with r < b
1478
1479def ud.q(m: Nat, qr: Word(m) & U32) -> Nat:
1480  (q, r) = qr
1481  Word.to_nat(m, q)
1482
1483def ud.r(m: Nat, qr: Word(m) & U32) -> Nat:
1484  (q, r) = qr
1485  U32.to_nat(r)
1486
1487# Word.shl.out is the bit going out and the shifted word
1488def un.so(n: Nat, +c: Bool, +w: Word(n)) -> {Word.shl.out(n, c, w) == (un.topc(n, c, w), Word.shl.put(n, c, w)) : Bool & Word(n)}:
1489  match n:
1490    case 0n:
1491      {==}
1492    case 1n+ +p:
1493      match w:
1494        case WCon{+x, +t}:
1495          %Equal.sym(Bool & Word(p), Word.shl.out(p, x, t), (un.topc(p, x, t), Word.shl.put(p, x, t)), un.so(p, x, t)) : {Word.shl.out.con(p, c, _) == (un.topc(p, x, t), WCon{c, Word.shl.put(p, x, t)}) : Bool & Word(1n+p)}
1496          {==}
1497
1498def un.ge_lt(c: Cmp) -> {Cmp.is_ge(c) == Bool.not(Cmp.is_lt(c)) : Bool}:
1499  match c:
1500    case LT{}:
1501      {==}
1502    case EQ{}:
1503      {==}
1504    case GT{}:
1505      {==}
1506
1507def un.bit_le(b: Bool) -> {Nat.is_le(U.U32Nat.bit(b), 1n) == True{} : Bool}:
1508  match b:
1509    case True{}:
1510      {==}
1511    case False{}:
1512      {==}
1513
1514# not x < y: y <= x
1515def un.nlt_le(x: Nat, y: Nat, e: {Nat.is_lt(x, y) == False{} : Bool}) -> {Nat.is_le(y, x) == True{} : Bool}:
1516  match x y:
1517    case 0n 0n:
1518      {==}
1519    case 0n 1n+q:
1520      Empty.absurd({Nat.is_le(1n+q, 0n) == True{} : Bool}, un.tf(e))
1521    case 1n+p 0n:
1522      {==}
1523    case 1n+p 1n+q:
1524      un.nlt_le(p, q, e)
1525
1526def ur.r21() -> {Nat.mul(1n, 1n) == 1n : Nat}:
1527  {==}
1528
1529def ur.r22() -> {Nat.mul(1n, 0n) == 0n : Nat}:
1530  %Equal.sym(Nat, Nat.mul(1n, 0n), 0n, Laws.nat_mul_zero(1n)) : {_ == 0n : Nat}
1531  {==}
1532
1533def ur.r23() -> {Nat.mul(0n, 1n) == 0n : Nat}:
1534  {==}
1535
1536def ur.r24(+x0: Nat, +x1: Nat) -> {x0 == Nat.add(x0, Nat.mul(0n, x1)) : Nat}:
1537  %Equal.sym(Nat, x0, Nat.add(x0, 0n), Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0))) : {_ == Nat.add(x0, Nat.mul(0n, x1)) : Nat}
1538  {==}
1539
1540def ur.r25(+x0: Nat, +x1: Nat) -> {Nat.add(x0, U.U32Nat.dbl(x1, Nat.mul(0n, 1n))) == x0 : Nat}:
1541  %Equal.sym(Nat, U.U32Nat.dbl(x1, 0n), 0n, Laws.dbl_zero(x1)) : {Nat.add(x0, _) == x0 : Nat}
1542  %Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0)) : {_ == x0 : Nat}
1543  {==}
1544
1545def ur.r26(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat, +x4: Nat, +x5: Nat) -> {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(Nat.double(x2), 1n+x3)), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}:
1546  %Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2)) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(_, 1n+x3)), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1547  %Equal.sym(Nat, Nat.add(Nat.add(x2, x2), Nat.add(1n, x3)), Nat.add(x2, Nat.add(x2, Nat.add(1n, x3))), Laws.nat_add_assoc(x2, x2, Nat.add(1n, x3))) : {Nat.add(Nat.add(Nat.add(x0, x1), _), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1548  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, 1n, x3)) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(x2, _)), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1549  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x2, Nat.add(x2, x3))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x2, x3))) : {Nat.add(Nat.add(Nat.add(x0, x1), _), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1550  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x2, Nat.add(x2, x3)))), Nat.add(x0, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x2, x3))))), Laws.nat_add_assoc(x0, x1, Nat.add(1n, Nat.add(x2, Nat.add(x2, x3))))) : {Nat.add(_, 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1551  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3)))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, Nat.add(x2, x3)))) : {Nat.add(Nat.add(x0, _), 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1552  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))))) : {Nat.add(_, 1n+Nat.add(x4, Nat.double(x5))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1553  %Equal.sym(Nat, Nat.double(x5), Nat.add(x5, x5), Laws.nat_double(x5)) : {Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))))), Nat.add(1n, Nat.add(x4, _))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1554  %Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_assoc(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))) : {_ == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1555  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(x0, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_assoc(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))) : {Nat.add(1n, _) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1556  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(x1, Nat.add(Nat.add(x2, Nat.add(x2, x3)), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_assoc(x1, Nat.add(x2, Nat.add(x2, x3)), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1557  %Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x2, x3)), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(x2, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_assoc(x2, Nat.add(x2, x3), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))) : {Nat.add(1n, Nat.add(x0, Nat.add(x1, _))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1558  %Equal.sym(Nat, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(x2, Nat.add(x3, Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_assoc(x2, x3, Nat.add(1n, Nat.add(x4, Nat.add(x5, x5))))) : {Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1559  %Equal.sym(Nat, Nat.add(x3, Nat.add(1n, Nat.add(x4, Nat.add(x5, x5)))), Nat.add(1n, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))), Laws.nat_add_left_comm(x3, 1n, Nat.add(x4, Nat.add(x5, x5)))) : {Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, _))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1560  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))), Nat.add(1n, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))) : {Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1561  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))), Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))) : {Nat.add(1n, Nat.add(x0, Nat.add(x1, _))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1562  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))))), Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1563  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))) : {Nat.add(1n, _) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1564  %Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))))))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))), Nat.add(1n, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5))))))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x4, Nat.add(x5, x5)))))))))) : {_ == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1565  %Equal.sym(Nat, Nat.add(x4, Nat.add(x5, x5)), Nat.add(x5, Nat.add(x4, x5)), Equal.sym(Nat, Nat.add(x5, Nat.add(x4, x5)), Nat.add(x4, Nat.add(x5, x5)), Laws.nat_add_left_comm(x5, x4, x5))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, _)))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1566  %Equal.sym(Nat, Nat.add(x3, Nat.add(x5, Nat.add(x4, x5))), Nat.add(x5, Nat.add(x3, Nat.add(x4, x5))), Equal.sym(Nat, Nat.add(x5, Nat.add(x3, Nat.add(x4, x5))), Nat.add(x3, Nat.add(x5, Nat.add(x4, x5))), Laws.nat_add_left_comm(x5, x3, Nat.add(x4, x5)))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, _))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1567  %Equal.sym(Nat, Nat.add(x4, x5), Nat.add(x5, x4), Equal.sym(Nat, Nat.add(x5, x4), Nat.add(x4, x5), Laws.nat_add_comm(x5, x4))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, Nat.add(x3, _))))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1568  %Equal.sym(Nat, Nat.add(x3, Nat.add(x5, x4)), Nat.add(x5, Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(x5, Nat.add(x3, x4)), Nat.add(x3, Nat.add(x5, x4)), Laws.nat_add_left_comm(x5, x3, x4))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, _)))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1569  %Equal.sym(Nat, Nat.add(x5, Nat.add(x5, Nat.add(x3, x4))), Nat.add(Nat.add(x5, x5), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(x5, x5), Nat.add(x3, x4)), Nat.add(x5, Nat.add(x5, Nat.add(x3, x4))), Laws.nat_add_assoc(x5, x5, Nat.add(x3, x4)))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, _))))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1570  %Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.add(x5, x5), Nat.add(x3, x4))), Nat.add(Nat.add(x2, Nat.add(x5, x5)), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x5, x5)), Nat.add(x3, x4)), Nat.add(x2, Nat.add(Nat.add(x5, x5), Nat.add(x3, x4))), Laws.nat_add_assoc(x2, Nat.add(x5, x5), Nat.add(x3, x4)))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1571  %Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.add(x2, Nat.add(x5, x5)), Nat.add(x3, x4))), Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))), Nat.add(x3, x4)), Nat.add(x2, Nat.add(Nat.add(x2, Nat.add(x5, x5)), Nat.add(x3, x4))), Laws.nat_add_assoc(x2, Nat.add(x2, Nat.add(x5, x5)), Nat.add(x3, x4)))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, _))) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1572  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))), Nat.add(x3, x4))), Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(x3, x4)), Nat.add(x1, Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))), Nat.add(x3, x4))), Laws.nat_add_assoc(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))), Nat.add(x3, x4)))) : {Nat.add(2n, Nat.add(x0, _)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1573  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(x3, x4))), Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x3, x4)), Nat.add(x0, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(x3, x4))), Laws.nat_add_assoc(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(x3, x4)))) : {Nat.add(2n, _) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1574  %Equal.sym(Nat, Nat.add(2n, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x3, x4))), Nat.add(Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Nat.add(x3, x4)), Equal.sym(Nat, Nat.add(Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Nat.add(x3, x4)), Nat.add(2n, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x3, x4))), Laws.nat_add_assoc(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x3, x4)))) : {_ == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1575  %Equal.sym(Nat, Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Nat.add(x0, Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Equal.sym(Nat, Nat.add(x0, Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Laws.nat_add_left_comm(x0, 2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))))) : {Nat.add(_, Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1576  %Equal.sym(Nat, Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Equal.sym(Nat, Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Laws.nat_add_left_comm(x1, 2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))) : {Nat.add(Nat.add(x0, _), Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1577  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Nat.add(Nat.add(x0, x1), Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(x0, Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))))), Laws.nat_add_assoc(x0, x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))))) : {Nat.add(_, Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1578  %Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x5, x5)))), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x2, Nat.add(x2, Nat.add(x5, x5))))))) : {Nat.add(Nat.add(Nat.add(x0, x1), _), Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1579  %Equal.sym(Nat, Nat.add(x2, Nat.add(x5, x5)), Nat.add(x5, Nat.add(x2, x5)), Equal.sym(Nat, Nat.add(x5, Nat.add(x2, x5)), Nat.add(x2, Nat.add(x5, x5)), Laws.nat_add_left_comm(x5, x2, x5))) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, Nat.add(x2, _)))), Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1580  %Equal.sym(Nat, Nat.add(x2, Nat.add(x5, Nat.add(x2, x5))), Nat.add(Nat.add(x2, x5), Nat.add(x2, x5)), Equal.sym(Nat, Nat.add(Nat.add(x2, x5), Nat.add(x2, x5)), Nat.add(x2, Nat.add(x5, Nat.add(x2, x5))), Laws.nat_add_assoc(x2, x5, Nat.add(x2, x5)))) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))), Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1581  %Equal.sym(Nat, Nat.add(Nat.add(x2, x5), Nat.add(x2, x5)), Nat.double(Nat.add(x2, x5)), Equal.sym(Nat, Nat.double(Nat.add(x2, x5)), Nat.add(Nat.add(x2, x5), Nat.add(x2, x5)), Laws.nat_double(Nat.add(x2, x5)))) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))), Nat.add(x3, x4)) == Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x5))), Nat.add(x3, x4)) : Nat}
1582  {==}
1583
1584def ur.r27(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(Nat.add(x0, x1), 2n+Nat.double(Nat.add(x2, x3))), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}:
1585  %Equal.sym(Nat, Nat.double(Nat.add(x2, x3)), Nat.add(Nat.add(x2, x3), Nat.add(x2, x3)), Laws.nat_double(Nat.add(x2, x3))) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1586  %Equal.sym(Nat, Nat.add(Nat.add(x2, x3), Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, Nat.add(x2, x3))), Laws.nat_add_assoc(x2, x3, Nat.add(x2, x3))) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1587  %Equal.sym(Nat, Nat.add(x3, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x2, x3)) : {Nat.add(Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, Nat.add(x2, _)))), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1588  %Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))) : {Nat.add(Nat.add(Nat.add(x0, x1), _), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1589  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(x0, Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_assoc(x0, x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))) : {Nat.add(_, 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1590  %Equal.sym(Nat, Nat.add(x1, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_left_comm(x1, 2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(Nat.add(x0, _), 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1591  %Equal.sym(Nat, Nat.add(x0, Nat.add(2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x0, 2n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))) : {Nat.add(_, 1n) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1592  %Equal.sym(Nat, Nat.add(Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), 1n), Nat.add(2n, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), 1n)), Laws.nat_add_assoc(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), 1n)) : {_ == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1593  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), 1n), Nat.add(x0, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), 1n)), Laws.nat_add_assoc(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), 1n)) : {Nat.add(2n, _) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1594  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), 1n), Nat.add(x1, Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))), 1n)), Laws.nat_add_assoc(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))), 1n)) : {Nat.add(2n, Nat.add(x0, _)) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1595  %Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))), 1n), Nat.add(x2, Nat.add(Nat.add(x2, Nat.add(x3, x3)), 1n)), Laws.nat_add_assoc(x2, Nat.add(x2, Nat.add(x3, x3)), 1n)) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, _))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1596  %Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x3, x3)), 1n), Nat.add(x2, Nat.add(Nat.add(x3, x3), 1n)), Laws.nat_add_assoc(x2, Nat.add(x3, x3), 1n)) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1597  %Equal.sym(Nat, Nat.add(Nat.add(x3, x3), 1n), Nat.add(x3, Nat.add(x3, 1n)), Laws.nat_add_assoc(x3, x3, 1n)) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, _))))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1598  %Equal.sym(Nat, Nat.add(x3, 1n), Nat.add(1n, x3), Laws.nat_add_comm(x3, 1n)) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, _)))))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1599  %Equal.sym(Nat, Nat.add(x3, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, 1n, x3)) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, _))))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1600  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x3, x3))), Nat.add(1n, Nat.add(x2, Nat.add(x3, x3))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x3, x3))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, _)))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1601  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(2n, Nat.add(x0, Nat.add(x1, _))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1602  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(2n, Nat.add(x0, _)) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1603  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))) : {Nat.add(2n, _) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1604  %Equal.sym(Nat, Nat.add(2n, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))), Nat.add(1n, Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))), Laws.nat_add_left_comm(2n, 1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))) : {_ == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1605  %Equal.sym(Nat, Nat.add(1n, Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))), Nat.add(Nat.add(1n, 2n), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(Nat.add(1n, 2n), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(1n, Nat.add(2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))), Laws.nat_add_assoc(1n, 2n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))))) : {_ == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1606  %Equal.sym(Nat, Nat.add(3n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(x0, Nat.add(3n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(x0, Nat.add(3n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(3n, Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x0, 3n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))) : {_ == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1607  %Equal.sym(Nat, Nat.add(3n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(x1, Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Equal.sym(Nat, Nat.add(x1, Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(3n, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_left_comm(x1, 3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1608  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Nat.add(Nat.add(x0, x1), Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(x0, Nat.add(x1, Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))))), Laws.nat_add_assoc(x0, x1, Nat.add(3n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))) : {_ == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1609  %Equal.sym(Nat, Nat.add(Nat.add(1n, 2n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Equal.sym(Nat, Nat.add(1n, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(Nat.add(1n, 2n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 2n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(1n, 2n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))) : {Nat.add(Nat.add(x0, x1), _) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1610  %Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(1n, 1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, _)) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1611  %Equal.sym(Nat, Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x2, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(1n, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1612  %Equal.sym(Nat, Nat.add(x2, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x2, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x2, x3))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, Nat.add(x2, Nat.add(1n, _))))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1613  %Equal.sym(Nat, Nat.add(1n, Nat.add(x3, Nat.add(x2, x3))), Nat.add(x3, Nat.add(1n, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(x3, Nat.add(1n, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x3, Nat.add(x2, x3))), Laws.nat_add_left_comm(x3, 1n, Nat.add(x2, x3)))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, Nat.add(x2, _)))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1614  %Equal.sym(Nat, Nat.add(x2, Nat.add(x3, Nat.add(1n, Nat.add(x2, x3)))), Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x2, x3))), Nat.add(x2, Nat.add(x3, Nat.add(1n, Nat.add(x2, x3)))), Laws.nat_add_assoc(x2, x3, Nat.add(1n, Nat.add(x2, x3))))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(1n, _))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1615  %Equal.sym(Nat, Nat.add(1n, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x2, x3)))), Nat.add(Nat.add(1n, Nat.add(x2, x3)), Nat.add(1n, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x2, x3)), Nat.add(1n, Nat.add(x2, x3))), Nat.add(1n, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.add(x2, x3)))), Laws.nat_add_assoc(1n, Nat.add(x2, x3), Nat.add(1n, Nat.add(x2, x3))))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, _)) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1616  %Equal.sym(Nat, Nat.add(1n, Nat.add(x2, x3)), Nat.add(x2, Nat.add(1n, x3)), Equal.sym(Nat, Nat.add(x2, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, 1n, x3))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(Nat.add(1n, Nat.add(x2, x3)), _))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1617  %Equal.sym(Nat, Nat.add(1n, Nat.add(x2, x3)), Nat.add(x2, Nat.add(1n, x3)), Equal.sym(Nat, Nat.add(x2, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, 1n, x3))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(_, Nat.add(x2, 1n+x3)))) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1618  %Equal.sym(Nat, Nat.add(Nat.add(x2, 1n+x3), Nat.add(x2, 1n+x3)), Nat.double(Nat.add(x2, 1n+x3)), Equal.sym(Nat, Nat.double(Nat.add(x2, 1n+x3)), Nat.add(Nat.add(x2, 1n+x3), Nat.add(x2, 1n+x3)), Laws.nat_double(Nat.add(x2, 1n+x3)))) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, _)) == Nat.add(Nat.add(x0, x1), 1n+Nat.double(Nat.add(x2, 1n+x3))) : Nat}
1619  {==}
1620
1621def ur.r28(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.add(x0, x1), 1n+Nat.double(x2)) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}:
1622  %Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2)) : {Nat.add(Nat.add(x0, x1), Nat.add(1n, _)) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1623  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(1n, Nat.add(x2, x2))), Nat.add(x0, Nat.add(x1, Nat.add(1n, Nat.add(x2, x2)))), Laws.nat_add_assoc(x0, x1, Nat.add(1n, Nat.add(x2, x2)))) : {_ == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1624  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, x2))), Nat.add(1n, Nat.add(x1, Nat.add(x2, x2))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, x2))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1625  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, x2)))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, x2)))) : {_ == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1626  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2)))), Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, x2)))), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x2, x2)))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x2, x2))))) : {_ == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1627  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, x2)), Nat.add(x2, Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, x2)), Nat.add(x1, Nat.add(x2, x2)), Laws.nat_add_left_comm(x2, x1, x2))) : {Nat.add(x0, Nat.add(1n, _)) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1628  %Equal.sym(Nat, Nat.add(1n, Nat.add(x2, Nat.add(x1, x2))), Nat.add(x2, Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(x1, x2))), Nat.add(1n, Nat.add(x2, Nat.add(x1, x2))), Laws.nat_add_left_comm(x2, 1n, Nat.add(x1, x2)))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1629  %Equal.sym(Nat, Nat.add(x0, Nat.add(x2, Nat.add(1n, Nat.add(x1, x2)))), Nat.add(Nat.add(x0, x2), Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.add(Nat.add(x0, x2), Nat.add(1n, Nat.add(x1, x2))), Nat.add(x0, Nat.add(x2, Nat.add(1n, Nat.add(x1, x2)))), Laws.nat_add_assoc(x0, x2, Nat.add(1n, Nat.add(x1, x2))))) : {_ == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1630  %Equal.sym(Nat, Nat.add(1n, Nat.add(x1, x2)), Nat.add(x1, Nat.add(1n, x2)), Equal.sym(Nat, Nat.add(x1, Nat.add(1n, x2)), Nat.add(1n, Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, 1n, x2))) : {Nat.add(Nat.add(x0, x2), _) == Nat.add(Nat.add(x0, x2), Nat.add(x1, 1n+x2)) : Nat}
1631  {==}
1632
1633def ur.r29(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(x0, Nat.add(Nat.add(Nat.double(x1), x2), 1n+x3)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}:
1634  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(x0, Nat.add(Nat.add(_, x2), 1n+x3)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1635  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), x2), Nat.add(x1, Nat.add(x1, x2)), Laws.nat_add_assoc(x1, x1, x2)) : {Nat.add(x0, Nat.add(_, 1n+x3)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1636  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x1, x2)), Nat.add(1n, x3)), Nat.add(x1, Nat.add(Nat.add(x1, x2), Nat.add(1n, x3))), Laws.nat_add_assoc(x1, Nat.add(x1, x2), Nat.add(1n, x3))) : {Nat.add(x0, _) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1637  %Equal.sym(Nat, Nat.add(Nat.add(x1, x2), Nat.add(1n, x3)), Nat.add(x1, Nat.add(x2, Nat.add(1n, x3))), Laws.nat_add_assoc(x1, x2, Nat.add(1n, x3))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1638  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, 1n, x3)) : {Nat.add(x0, Nat.add(x1, Nat.add(x1, _))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1639  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x2, x3))), Nat.add(1n, Nat.add(x1, Nat.add(x2, x3))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x2, x3))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1640  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x1, Nat.add(x2, x3)))), Nat.add(1n, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3)))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x1, Nat.add(x2, x3)))) : {Nat.add(x0, _) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1641  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3))))), Nat.add(1n, Nat.add(x0, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3))))) : {_ == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1642  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3)))), Nat.add(x1, Nat.add(x0, Nat.add(x1, Nat.add(x2, x3)))), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, Nat.add(x1, Nat.add(x2, x3)))), Nat.add(x0, Nat.add(x1, Nat.add(x1, Nat.add(x2, x3)))), Laws.nat_add_left_comm(x1, x0, Nat.add(x1, Nat.add(x2, x3))))) : {Nat.add(1n, _) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1643  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(x2, x3))), Nat.add(x1, Nat.add(x0, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, Nat.add(x2, x3))), Nat.add(x0, Nat.add(x1, Nat.add(x2, x3))), Laws.nat_add_left_comm(x1, x0, Nat.add(x2, x3)))) : {Nat.add(1n, Nat.add(x1, _)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1644  %Equal.sym(Nat, Nat.add(x0, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(x2, Nat.add(x0, x3)), Nat.add(x0, Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, x0, x3))) : {Nat.add(1n, Nat.add(x1, Nat.add(x1, _))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1645  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x0, x3))), Nat.add(Nat.add(x1, x2), Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(Nat.add(x1, x2), Nat.add(x0, x3)), Nat.add(x1, Nat.add(x2, Nat.add(x0, x3))), Laws.nat_add_assoc(x1, x2, Nat.add(x0, x3)))) : {Nat.add(1n, Nat.add(x1, _)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1646  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.add(x1, x2), Nat.add(x0, x3))), Nat.add(Nat.add(x1, Nat.add(x1, x2)), Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x1, x2)), Nat.add(x0, x3)), Nat.add(x1, Nat.add(Nat.add(x1, x2), Nat.add(x0, x3))), Laws.nat_add_assoc(x1, Nat.add(x1, x2), Nat.add(x0, x3)))) : {Nat.add(1n, _) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1647  %Equal.sym(Nat, Nat.add(1n, Nat.add(Nat.add(x1, Nat.add(x1, x2)), Nat.add(x0, x3))), Nat.add(Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), Nat.add(x0, x3)), Nat.add(1n, Nat.add(Nat.add(x1, Nat.add(x1, x2)), Nat.add(x0, x3))), Laws.nat_add_assoc(1n, Nat.add(x1, Nat.add(x1, x2)), Nat.add(x0, x3)))) : {_ == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1648  %Equal.sym(Nat, Nat.add(x0, x3), Nat.add(x3, x0), Equal.sym(Nat, Nat.add(x3, x0), Nat.add(x0, x3), Laws.nat_add_comm(x3, x0))) : {Nat.add(Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), _) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1649  %Equal.sym(Nat, x0, Nat.mul(1n, x0), Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0))) : {Nat.add(Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), Nat.add(x3, _)) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1650  %Equal.sym(Nat, Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), Nat.add(x1, Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(x1, x2))), Nat.add(1n, Nat.add(x1, Nat.add(x1, x2))), Laws.nat_add_left_comm(x1, 1n, Nat.add(x1, x2)))) : {Nat.add(_, Nat.add(x3, Nat.mul(1n, x0))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1651  %Equal.sym(Nat, Nat.add(1n, Nat.add(x1, x2)), Nat.add(x1, Nat.add(1n, x2)), Equal.sym(Nat, Nat.add(x1, Nat.add(1n, x2)), Nat.add(1n, Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, 1n, x2))) : {Nat.add(Nat.add(x1, _), Nat.add(x3, Nat.mul(1n, x0))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1652  %Equal.sym(Nat, Nat.add(x1, Nat.add(x1, Nat.add(1n, x2))), Nat.add(Nat.add(x1, x1), Nat.add(1n, x2)), Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(1n, x2)), Nat.add(x1, Nat.add(x1, Nat.add(1n, x2))), Laws.nat_add_assoc(x1, x1, Nat.add(1n, x2)))) : {Nat.add(_, Nat.add(x3, Nat.mul(1n, x0))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1653  %Equal.sym(Nat, Nat.add(x1, x1), Nat.double(x1), Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1))) : {Nat.add(Nat.add(_, 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) == Nat.add(Nat.add(Nat.double(x1), 1n+x2), Nat.add(x3, Nat.mul(1n, x0))) : Nat}
1654  {==}
1655
1656def ur.r30(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(Nat.double(x0), 1n+x1), Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}:
1657  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(Nat.add(_, 1n+x1), Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1658  %Equal.sym(Nat, Nat.add(Nat.add(x0, x0), Nat.add(1n, x1)), Nat.add(x0, Nat.add(x0, Nat.add(1n, x1))), Laws.nat_add_assoc(x0, x0, Nat.add(1n, x1))) : {Nat.add(_, Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1659  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, x1)), Nat.add(1n, Nat.add(x0, x1)), Laws.nat_add_left_comm(x0, 1n, x1)) : {Nat.add(Nat.add(x0, _), Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1660  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x0, x1))), Nat.add(1n, Nat.add(x0, Nat.add(x0, x1))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x0, x1))) : {Nat.add(_, Nat.add(x2, Nat.double(x3))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1661  %Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3)) : {Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, x1))), Nat.add(x2, _)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1662  %Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, x1))), Nat.add(x2, Nat.add(x3, x3))), Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, x1)), Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(1n, Nat.add(x0, Nat.add(x0, x1)), Nat.add(x2, Nat.add(x3, x3)))) : {_ == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1663  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x0, x1)), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x0, Nat.add(Nat.add(x0, x1), Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x0, Nat.add(x0, x1), Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(1n, _) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1664  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x0, x1, Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1665  %Equal.sym(Nat, Nat.add(x2, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x2, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x2, x3))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x1, _)))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1666  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, Nat.add(x2, x3))), Nat.add(x3, Nat.add(x1, Nat.add(x2, x3))), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, Nat.add(x2, x3))), Nat.add(x1, Nat.add(x3, Nat.add(x2, x3))), Laws.nat_add_left_comm(x3, x1, Nat.add(x2, x3)))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1667  %Equal.sym(Nat, Nat.add(x2, x3), Nat.add(x3, x2), Equal.sym(Nat, Nat.add(x3, x2), Nat.add(x2, x3), Laws.nat_add_comm(x3, x2))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, Nat.add(x1, _))))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1668  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, x2)), Nat.add(x3, Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, x2)), Nat.add(x1, Nat.add(x3, x2)), Laws.nat_add_left_comm(x3, x1, x2))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, _)))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1669  %Equal.sym(Nat, Nat.add(x3, Nat.add(x3, Nat.add(x1, x2))), Nat.add(Nat.add(x3, x3), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2)), Nat.add(x3, Nat.add(x3, Nat.add(x1, x2))), Laws.nat_add_assoc(x3, x3, Nat.add(x1, x2)))) : {Nat.add(1n, Nat.add(x0, Nat.add(x0, _))) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1670  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2))), Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)), Nat.add(x0, Nat.add(Nat.add(x3, x3), Nat.add(x1, x2))), Laws.nat_add_assoc(x0, Nat.add(x3, x3), Nat.add(x1, x2)))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1671  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2))), Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)), Nat.add(x0, Nat.add(Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2))), Laws.nat_add_assoc(x0, Nat.add(x0, Nat.add(x3, x3)), Nat.add(x1, x2)))) : {Nat.add(1n, _) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1672  %Equal.sym(Nat, Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2))), Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3)))), Nat.add(x1, x2)), Equal.sym(Nat, Nat.add(Nat.add(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3)))), Nat.add(x1, x2)), Nat.add(1n, Nat.add(Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2))), Laws.nat_add_assoc(1n, Nat.add(x0, Nat.add(x0, Nat.add(x3, x3))), Nat.add(x1, x2)))) : {_ == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1673  %Equal.sym(Nat, Nat.add(x0, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x0, x3)), Nat.add(x0, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x0, x3))) : {Nat.add(Nat.add(1n, Nat.add(x0, _)), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1674  %Equal.sym(Nat, Nat.add(x0, Nat.add(x3, Nat.add(x0, x3))), Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Equal.sym(Nat, Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Nat.add(x0, Nat.add(x3, Nat.add(x0, x3))), Laws.nat_add_assoc(x0, x3, Nat.add(x0, x3)))) : {Nat.add(Nat.add(1n, _), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1675  %Equal.sym(Nat, Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Nat.double(Nat.add(x0, x3)), Equal.sym(Nat, Nat.double(Nat.add(x0, x3)), Nat.add(Nat.add(x0, x3), Nat.add(x0, x3)), Laws.nat_double(Nat.add(x0, x3)))) : {Nat.add(Nat.add(1n, _), Nat.add(x1, x2)) == Nat.add(1n+Nat.double(Nat.add(x0, x3)), Nat.add(x1, x2)) : Nat}
1676  {==}
1677
1678def ur.r31(+x0: Nat) -> {Nat.double(x0) == Nat.add(x0, x0) : Nat}:
1679  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {_ == Nat.add(x0, x0) : Nat}
1680  {==}
1681
1682# r' + g b = 2 r + a, r' < b: the remainder after one step, at a width N
1683def ud.k(+N: Nat, +S: Nat, +B: Nat, +R: Nat, +A: Nat, +R1: Nat, +T: Bool, +L: Bool, +g: Bool, +eput: {Nat.add(S, U.U32Nat.dbl(N, U.U32Nat.bit(T))) == Nat.add(A, Nat.double(R)) : Nat}, +eL: {Nat.is_lt(S, B) == L : Bool}, +eg: {Bool.or(T, Bool.not(L)) == g : Bool}, +er1: {Nat.add(R1, Nat.mul(U.U32Nat.bit(g), B)) == Nat.add(S, U.U32Nat.dbl(N, Nat.mul(U.U32Nat.bit(g), U.U32Nat.bit(L)))) : Nat}, +hA: {Nat.is_le(A, 1n) == True{} : Bool}, +hR: {Nat.is_lt(R, B) == True{} : Bool}, +hB: {Nat.is_lt(B, U.U32Nat.dbl(N, 1n)) == True{} : Bool}) -> {Nat.add(R1, Nat.mul(U.U32Nat.bit(g), B)) == Nat.add(A, Nat.double(R)) : Nat} & {Nat.is_lt(R1, B) == True{} : Bool}:
1684  match T L g:
1685    case True{} True{} True{}:
1686      (Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, 1n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(1n, 1n))), Nat.add(S, U.U32Nat.dbl(N, 1n)), er1, Equal.cong(Nat, Nat, zz => Nat.add(S, U.U32Nat.dbl(N, zz)), Nat.mul(1n, 1n), 1n, ur.r21())), eput), Equal.trans(Bool, Nat.is_lt(R1, B), Nat.is_lt(R1, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), True{}, Equal.sym(Bool, Nat.is_lt(R1, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.is_lt(R1, B), Equal.cong(Nat, Bool, zz => Nat.is_lt(R1, zz), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1), B, Laws.nat_add_cancel(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1), B, Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.double(B), Nat.add(B, B), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R)), Nat.double(B), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), 1n), Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R)), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), Nat.add(Nat.sub(1n, A), A)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), 1n), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(A, Nat.double(R))), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), Nat.add(Nat.sub(1n, A), A)), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(R1, Nat.mul(1n, B))), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(A, Nat.double(R))), ur.r29(B, Nat.sub(B, 1n+R), Nat.sub(1n, A), R1), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), zz), Nat.add(R1, Nat.mul(1n, B)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, 1n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(1n, 1n))), Nat.add(S, U.U32Nat.dbl(N, 1n)), er1, Equal.cong(Nat, Nat, zz => Nat.add(S, U.U32Nat.dbl(N, zz)), Nat.mul(1n, 1n), 1n, ur.r21())), eput))), ur.r30(Nat.sub(B, 1n+R), Nat.sub(1n, A), A, R)), Equal.cong(Nat, Nat, zz => Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), zz), Nat.add(Nat.sub(1n, A), A), 1n, Laws.nat_le_witness(A, 1n, hA))), ur.r7(Nat.sub(B, 1n+R), R)), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(Nat.sub(B, 1n+R), 1n+R), B, Laws.nat_lt_witness(R, B, hR))), ur.r31(B))))), Laws.nat_lt_add(R1, Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)))))
1687    case True{} False{} True{}:
1688      Empty.absurd({Nat.add(R1, Nat.mul(U.U32Nat.bit(True{}), B)) == Nat.add(A, Nat.double(R)) : Nat} & {Nat.is_lt(R1, B) == True{} : Bool}, Laws.nat_succ_add_absurd(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(S, U.U32Nat.dbl(N, 1n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(S, Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B)), Nat.add(S, U.U32Nat.dbl(N, 1n)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(Nat.add(Nat.sub(S, B), B), Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B)), Nat.add(S, Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 1n+Nat.double(B)), Nat.add(Nat.add(Nat.sub(S, B), B), Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R))), Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 1n+Nat.double(B)), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 2n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R))), 1n), Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R))), Equal.trans(Nat, Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A))), 1n+Nat.add(A, Nat.double(R))), Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 2n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R))), Nat.add(Nat.sub(1n, A), A)), Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 2n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R))), 1n), ur.r26(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), Nat.sub(B, 1n+R), Nat.sub(1n, A), A, R), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 2n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R))), zz), Nat.add(Nat.sub(1n, A), A), 1n, Laws.nat_le_witness(A, 1n, hA))), ur.r27(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), Nat.sub(B, 1n+R), R)), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B)), 1n+Nat.double(zz)), Nat.add(Nat.sub(B, 1n+R), 1n+R), B, Laws.nat_lt_witness(R, B, hR))), ur.r28(Nat.sub(S, B), Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), B)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B)), Nat.add(Nat.sub(S, B), B), S, Laws.nat_le_witness(B, S, un.nlt_le(S, B, eL)))), Equal.cong(Nat, Nat, zz => Nat.add(S, zz), Nat.add(Nat.sub(U.U32Nat.dbl(N, 1n), 1n+B), 1n+B), U.U32Nat.dbl(N, 1n), Laws.nat_lt_witness(B, U.U32Nat.dbl(N, 1n), hB))), eput)))
1689    case False{} False{} True{}:
1690      (Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, 0n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(1n, 0n))), Nat.add(S, U.U32Nat.dbl(N, 0n)), er1, Equal.cong(Nat, Nat, zz => Nat.add(S, U.U32Nat.dbl(N, zz)), Nat.mul(1n, 0n), 0n, ur.r22())), eput), Equal.trans(Bool, Nat.is_lt(R1, B), Nat.is_lt(R1, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), True{}, Equal.sym(Bool, Nat.is_lt(R1, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.is_lt(R1, B), Equal.cong(Nat, Bool, zz => Nat.is_lt(R1, zz), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1), B, Laws.nat_add_cancel(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1), B, Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.double(B), Nat.add(B, B), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R)), Nat.double(B), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), 1n), Nat.double(Nat.add(Nat.sub(B, 1n+R), 1n+R)), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), Nat.add(Nat.sub(1n, A), A)), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), 1n), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(A, Nat.double(R))), Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), Nat.add(Nat.sub(1n, A), A)), Equal.trans(Nat, Nat.add(B, Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)), 1n+R1)), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(R1, Nat.mul(1n, B))), Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), Nat.add(A, Nat.double(R))), ur.r29(B, Nat.sub(B, 1n+R), Nat.sub(1n, A), R1), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(Nat.double(Nat.sub(B, 1n+R)), 1n+Nat.sub(1n, A)), zz), Nat.add(R1, Nat.mul(1n, B)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, 0n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(1n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(1n, 0n))), Nat.add(S, U.U32Nat.dbl(N, 0n)), er1, Equal.cong(Nat, Nat, zz => Nat.add(S, U.U32Nat.dbl(N, zz)), Nat.mul(1n, 0n), 0n, ur.r22())), eput))), ur.r30(Nat.sub(B, 1n+R), Nat.sub(1n, A), A, R)), Equal.cong(Nat, Nat, zz => Nat.add(1n+Nat.double(Nat.add(Nat.sub(B, 1n+R), R)), zz), Nat.add(Nat.sub(1n, A), A), 1n, Laws.nat_le_witness(A, 1n, hA))), ur.r7(Nat.sub(B, 1n+R), R)), Equal.cong(Nat, Nat, zz => Nat.double(zz), Nat.add(Nat.sub(B, 1n+R), 1n+R), B, Laws.nat_lt_witness(R, B, hR))), ur.r31(B))))), Laws.nat_lt_add(R1, Nat.add(Nat.double(Nat.sub(B, 1n+R)), Nat.sub(1n, A)))))
1691    case False{} True{} False{}:
1692      (Equal.trans(Nat, Nat.add(R1, Nat.mul(0n, B)), Nat.add(S, U.U32Nat.dbl(N, 0n)), Nat.add(A, Nat.double(R)), Equal.trans(Nat, Nat.add(R1, Nat.mul(0n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(0n, 1n))), Nat.add(S, U.U32Nat.dbl(N, 0n)), er1, Equal.cong(Nat, Nat, zz => Nat.add(S, U.U32Nat.dbl(N, zz)), Nat.mul(0n, 1n), 0n, ur.r23())), eput), Equal.trans(Bool, Nat.is_lt(R1, B), Nat.is_lt(S, B), True{}, Equal.cong(Nat, Bool, zz => Nat.is_lt(zz, B), R1, S, Equal.trans(Nat, R1, Nat.add(S, U.U32Nat.dbl(N, Nat.mul(0n, 1n))), S, Equal.trans(Nat, R1, Nat.add(R1, Nat.mul(0n, B)), Nat.add(S, U.U32Nat.dbl(N, Nat.mul(0n, 1n))), ur.r24(R1, B), er1), ur.r25(S, N))), eL))
1693    case True{} _ False{}:
1694      Empty.absurd({Nat.add(R1, Nat.mul(U.U32Nat.bit(False{}), B)) == Nat.add(A, Nat.double(R)) : Nat} & {Nat.is_lt(R1, B) == True{} : Bool}, un.tf(eg))
1695    case False{} False{} False{}:
1696      Empty.absurd({Nat.add(R1, Nat.mul(U.U32Nat.bit(False{}), B)) == Nat.add(A, Nat.double(R)) : Nat} & {Nat.is_lt(R1, B) == True{} : Bool}, un.tf(eg))
1697    case False{} True{} True{}:
1698      Empty.absurd({Nat.add(R1, Nat.mul(U.U32Nat.bit(True{}), B)) == Nat.add(A, Nat.double(R)) : Nat} & {Nat.is_lt(R1, B) == True{} : Bool}, un.ft(eg))
1699
1700def ur.r32(+x0: Nat) -> {Nat.mul(1n, x0) == x0 : Nat}:
1701  %Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0)) : {_ == x0 : Nat}
1702  {==}
1703
1704def ur.r33(+x0: Nat) -> {x0 == Nat.mul(1n, x0) : Nat}:
1705  %Equal.sym(Nat, x0, Nat.mul(1n, x0), Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0))) : {_ == Nat.mul(1n, x0) : Nat}
1706  {==}
1707
1708def ur.r34(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(x0, Nat.mul(0n, x1)) == Nat.add(x0, U.U32Nat.dbl(32n, Nat.mul(0n, x2))) : Nat}:
1709  %Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0)) : {_ == Nat.add(x0, U.U32Nat.dbl(32n, Nat.mul(0n, x2))) : Nat}
1710  %Equal.sym(Nat, x0, Nat.add(x0, 0n), Equal.sym(Nat, Nat.add(x0, 0n), x0, Laws.nat_add_zero(x0))) : {_ == Nat.add(x0, U.U32Nat.dbl(32n, Nat.mul(0n, x2))) : Nat}
1711  %Equal.sym(Nat, 0n, U.U32Nat.dbl(32n, 0n), Equal.sym(Nat, U.U32Nat.dbl(32n, 0n), 0n, Laws.dbl_zero(32n))) : {Nat.add(x0, _) == Nat.add(x0, U.U32Nat.dbl(32n, Nat.mul(0n, x2))) : Nat}
1712  {==}
1713
1714def ur.r35(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.mul(1n+Nat.double(x0), x1), x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}:
1715  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(Nat.mul(Nat.add(1n, _), x1), x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1716  %Equal.sym(Nat, Nat.mul(Nat.add(1n, Nat.add(x0, x0)), x1), Nat.add(Nat.mul(1n, x1), Nat.mul(Nat.add(x0, x0), x1)), Laws.nat_add_mul(1n, Nat.add(x0, x0), x1)) : {Nat.add(_, x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1717  %Equal.sym(Nat, Nat.mul(Nat.add(x0, x0), x1), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_add_mul(x0, x0, x1)) : {Nat.add(Nat.add(Nat.mul(1n, x1), _), x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1718  %Equal.sym(Nat, Nat.mul(1n, x1), x1, Laws.nat_one_mul(x1)) : {Nat.add(Nat.add(_, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1719  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Nat.add(Nat.mul(x0, x1), Nat.add(x1, Nat.mul(x0, x1))), Laws.nat_add_left_comm(x1, Nat.mul(x0, x1), Nat.mul(x0, x1))) : {Nat.add(_, x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1720  %Equal.sym(Nat, Nat.add(x1, Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), x1), Laws.nat_add_comm(x1, Nat.mul(x0, x1))) : {Nat.add(Nat.add(Nat.mul(x0, x1), _), x2) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1721  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x1)), x2), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.add(Nat.mul(x0, x1), x1), x2)), Laws.nat_add_assoc(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x1), x2)) : {_ == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1722  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), x1), x2), Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Laws.nat_add_assoc(Nat.mul(x0, x1), x1, x2)) : {Nat.add(Nat.mul(x0, x1), _) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1723  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)), Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2)), Nat.add(Nat.mul(x0, x1), Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, Nat.mul(x0, x1), x2))) : {Nat.add(Nat.mul(x0, x1), _) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1724  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2))), Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x2))), Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x2))), Nat.add(Nat.mul(x0, x1), Nat.add(x1, Nat.add(Nat.mul(x0, x1), x2))), Laws.nat_add_left_comm(x1, Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x2)))) : {_ == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1725  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), x2), Nat.add(x2, Nat.mul(x0, x1)), Equal.sym(Nat, Nat.add(x2, Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), x2), Laws.nat_add_comm(x2, Nat.mul(x0, x1)))) : {Nat.add(x1, Nat.add(Nat.mul(x0, x1), _)) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1726  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.mul(x0, x1))), Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.mul(x0, x1))), Laws.nat_add_left_comm(x2, Nat.mul(x0, x1), Nat.mul(x0, x1)))) : {Nat.add(x1, _) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1727  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)))), Nat.add(Nat.add(x1, x2), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Equal.sym(Nat, Nat.add(Nat.add(x1, x2), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)))), Laws.nat_add_assoc(x1, x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))))) : {_ == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1728  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Nat.double(Nat.mul(x0, x1)), Equal.sym(Nat, Nat.double(Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_double(Nat.mul(x0, x1)))) : {Nat.add(Nat.add(x1, x2), _) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1729  %Equal.sym(Nat, Nat.add(x1, x2), Nat.add(x2, x1), Equal.sym(Nat, Nat.add(x2, x1), Nat.add(x1, x2), Laws.nat_add_comm(x2, x1))) : {Nat.add(_, Nat.double(Nat.mul(x0, x1))) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1730  %Equal.sym(Nat, x1, Nat.mul(1n, x1), Equal.sym(Nat, Nat.mul(1n, x1), x1, Laws.nat_one_mul(x1))) : {Nat.add(Nat.add(x2, _), Nat.double(Nat.mul(x0, x1))) == Nat.add(Nat.add(x2, Nat.mul(1n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1731  {==}
1732
1733def ur.r36(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, Nat.double(x1)), Nat.double(Nat.mul(x2, x3))) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}:
1734  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(Nat.add(x0, _), Nat.double(Nat.mul(x2, x3))) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1735  %Equal.sym(Nat, Nat.double(Nat.mul(x2, x3)), Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3)), Laws.nat_double(Nat.mul(x2, x3))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), _) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1736  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3))), Nat.add(x0, Nat.add(Nat.add(x1, x1), Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3)))), Laws.nat_add_assoc(x0, Nat.add(x1, x1), Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3)))) : {_ == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1737  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3))), Nat.add(x1, Nat.add(x1, Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3)))), Laws.nat_add_assoc(x1, x1, Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3)))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1738  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3))), Nat.add(Nat.mul(x2, x3), Nat.add(x1, Nat.mul(x2, x3))), Equal.sym(Nat, Nat.add(Nat.mul(x2, x3), Nat.add(x1, Nat.mul(x2, x3))), Nat.add(x1, Nat.add(Nat.mul(x2, x3), Nat.mul(x2, x3))), Laws.nat_add_left_comm(Nat.mul(x2, x3), x1, Nat.mul(x2, x3)))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1739  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x2, x3), Nat.add(x1, Nat.mul(x2, x3)))), Nat.add(Nat.add(x1, Nat.mul(x2, x3)), Nat.add(x1, Nat.mul(x2, x3))), Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.mul(x2, x3)), Nat.add(x1, Nat.mul(x2, x3))), Nat.add(x1, Nat.add(Nat.mul(x2, x3), Nat.add(x1, Nat.mul(x2, x3)))), Laws.nat_add_assoc(x1, Nat.mul(x2, x3), Nat.add(x1, Nat.mul(x2, x3))))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1740  %Equal.sym(Nat, Nat.add(x1, Nat.mul(x2, x3)), Nat.add(Nat.mul(x2, x3), x1), Equal.sym(Nat, Nat.add(Nat.mul(x2, x3), x1), Nat.add(x1, Nat.mul(x2, x3)), Laws.nat_add_comm(Nat.mul(x2, x3), x1))) : {Nat.add(x0, Nat.add(Nat.add(x1, Nat.mul(x2, x3)), _)) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1741  %Equal.sym(Nat, Nat.add(x1, Nat.mul(x2, x3)), Nat.add(Nat.mul(x2, x3), x1), Equal.sym(Nat, Nat.add(Nat.mul(x2, x3), x1), Nat.add(x1, Nat.mul(x2, x3)), Laws.nat_add_comm(Nat.mul(x2, x3), x1))) : {Nat.add(x0, Nat.add(_, Nat.add(Nat.mul(x2, x3), x1))) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1742  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x2, x3), x1), Nat.add(Nat.mul(x2, x3), x1)), Nat.double(Nat.add(Nat.mul(x2, x3), x1)), Equal.sym(Nat, Nat.double(Nat.add(Nat.mul(x2, x3), x1)), Nat.add(Nat.add(Nat.mul(x2, x3), x1), Nat.add(Nat.mul(x2, x3), x1)), Laws.nat_double(Nat.add(Nat.mul(x2, x3), x1)))) : {Nat.add(x0, _) == Nat.add(x0, Nat.double(Nat.add(Nat.mul(x2, x3), x1))) : Nat}
1743  {==}
1744
1745def ur.r37(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(Nat.mul(Nat.double(x0), x1), x2) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}:
1746  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(Nat.mul(_, x1), x2) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1747  %Equal.sym(Nat, Nat.mul(Nat.add(x0, x0), x1), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_add_mul(x0, x0, x1)) : {Nat.add(_, x2) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1748  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), x2), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x1), x2)), Laws.nat_add_assoc(Nat.mul(x0, x1), Nat.mul(x0, x1), x2)) : {_ == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1749  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), x2), Nat.add(x2, Nat.mul(x0, x1)), Equal.sym(Nat, Nat.add(x2, Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), x2), Laws.nat_add_comm(x2, Nat.mul(x0, x1)))) : {Nat.add(Nat.mul(x0, x1), _) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1750  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.mul(x0, x1))), Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1))), Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.mul(x0, x1))), Laws.nat_add_left_comm(x2, Nat.mul(x0, x1), Nat.mul(x0, x1)))) : {_ == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1751  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Nat.double(Nat.mul(x0, x1)), Equal.sym(Nat, Nat.double(Nat.mul(x0, x1)), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x1)), Laws.nat_double(Nat.mul(x0, x1)))) : {Nat.add(x2, _) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1752  %Equal.sym(Nat, x2, Nat.add(x2, 0n), Equal.sym(Nat, Nat.add(x2, 0n), x2, Laws.nat_add_zero(x2))) : {Nat.add(_, Nat.double(Nat.mul(x0, x1))) == Nat.add(Nat.add(x2, Nat.mul(0n, x1)), Nat.double(Nat.mul(x0, x1))) : Nat}
1753  {==}
1754
1755def ud.fin.t(+p: Nat, +q: Word(p), +bw: Word(32n), +a0: Bool, +rw: Word(32n), +x: Nat, +x2: Nat, +R1: Nat, +ex: {Nat.add(U.U32Nat.bit(a0), Nat.double(x)) == x2 : Nat}, +i1: {Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)) == x : Nat}, kp: {Nat.add(R1, Nat.mul(U.U32Nat.bit(True{}), Word.to_nat(32n, bw))) == Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))) : Nat} & {Nat.is_lt(R1, Word.to_nat(32n, bw)) == True{} : Bool}) -> {Nat.add(Nat.mul(1n+Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1) == x2 : Nat} & {Nat.is_lt(R1, Word.to_nat(32n, bw)) == True{} : Bool}:
1756  (+k1, +k2) = kp
1757  (Equal.trans(Nat, Nat.add(Nat.mul(1n+Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(U.U32Nat.bit(a0), Nat.double(x)), x2, Equal.trans(Nat, Nat.add(Nat.mul(1n+Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(U.U32Nat.bit(a0), Nat.double(Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)))), Nat.add(U.U32Nat.bit(a0), Nat.double(x)), Equal.trans(Nat, Nat.add(Nat.mul(1n+Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(U.U32Nat.bit(a0), Nat.double(Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)))), Equal.trans(Nat, Nat.add(Nat.mul(1n+Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(Nat.add(R1, Nat.mul(1n, Word.to_nat(32n, bw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), ur.r35(Word.to_nat(p, q), Word.to_nat(32n, bw), R1), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(R1, Nat.mul(1n, Word.to_nat(32n, bw))), Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), k1)), ur.r36(U.U32Nat.bit(a0), Word.to_nat(32n, rw), Word.to_nat(p, q), Word.to_nat(32n, bw))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(a0), Nat.double(zz)), Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)), x, i1)), ex), k2)
1758
1759def ud.fin.f(+p: Nat, +q: Word(p), +bw: Word(32n), +a0: Bool, +rw: Word(32n), +x: Nat, +x2: Nat, +R1: Nat, +ex: {Nat.add(U.U32Nat.bit(a0), Nat.double(x)) == x2 : Nat}, +i1: {Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)) == x : Nat}, kp: {Nat.add(R1, Nat.mul(U.U32Nat.bit(False{}), Word.to_nat(32n, bw))) == Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))) : Nat} & {Nat.is_lt(R1, Word.to_nat(32n, bw)) == True{} : Bool}) -> {Nat.add(Nat.mul(Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1) == x2 : Nat} & {Nat.is_lt(R1, Word.to_nat(32n, bw)) == True{} : Bool}:
1760  (+k1, +k2) = kp
1761  (Equal.trans(Nat, Nat.add(Nat.mul(Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(U.U32Nat.bit(a0), Nat.double(x)), x2, Equal.trans(Nat, Nat.add(Nat.mul(Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(U.U32Nat.bit(a0), Nat.double(Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)))), Nat.add(U.U32Nat.bit(a0), Nat.double(x)), Equal.trans(Nat, Nat.add(Nat.mul(Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(U.U32Nat.bit(a0), Nat.double(Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)))), Equal.trans(Nat, Nat.add(Nat.mul(Nat.double(Word.to_nat(p, q)), Word.to_nat(32n, bw)), R1), Nat.add(Nat.add(R1, Nat.mul(0n, Word.to_nat(32n, bw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), ur.r37(Word.to_nat(p, q), Word.to_nat(32n, bw), R1), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)))), Nat.add(R1, Nat.mul(0n, Word.to_nat(32n, bw))), Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))), k1)), ur.r36(U.U32Nat.bit(a0), Word.to_nat(32n, rw), Word.to_nat(p, q), Word.to_nat(32n, bw))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(a0), Nat.double(zz)), Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)), x, i1)), ex), k2)
1762
1763def ud.fin(+p: Nat, +q: Word(p), +s: Word(32n), +bw: Word(32n), +T: Bool, +g: Bool, +a0: Bool, +rw: Word(32n), +x: Nat, +x2: Nat, +eg: {Bool.or(T, U32.is_ge(U32{s}, U32{bw})) == g : Bool}, +eput: {Nat.add(Word.to_nat(32n, s), U.U32Nat.dbl(32n, U.U32Nat.bit(T))) == Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(32n, rw))) : Nat}, +ex: {Nat.add(U.U32Nat.bit(a0), Nat.double(x)) == x2 : Nat}, +i1: {Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)) == x : Nat}, +i2: {Nat.is_lt(Word.to_nat(32n, rw), Word.to_nat(32n, bw)) == True{} : Bool}) -> {Nat.add(Nat.mul(ud.q(1n+p, U32.divmod.go.fin(p, q, U32{s}, U32{bw}, g)), U32.to_nat(U32{bw})), ud.r(1n+p, U32.divmod.go.fin(p, q, U32{s}, U32{bw}, g))) == x2 : Nat} & {Nat.is_lt(ud.r(1n+p, U32.divmod.go.fin(p, q, U32{s}, U32{bw}, g)), U32.to_nat(U32{bw})) == True{} : Bool}:
1764  match g:
1765    case True{}:
1766      ud.fin.t(p, q, bw, a0, rw, x, x2, U32.to_nat(U32.sub(U32{s}, U32{bw})), ex, i1, ud.k(32n, Word.to_nat(32n, s), Word.to_nat(32n, bw), Word.to_nat(32n, rw), U.U32Nat.bit(a0), U32.to_nat(U32.sub(U32{s}, U32{bw})), T, U32.is_lt(U32{s}, U32{bw}), True{}, eput, Equal.sym(Bool, U32.is_lt(U32{s}, U32{bw}), Nat.is_lt(Word.to_nat(32n, s), Word.to_nat(32n, bw)), Laws.u32_lt_value(U32{s}, U32{bw})), Equal.trans(Bool, Bool.or(T, Bool.not(U32.is_lt(U32{s}, U32{bw}))), Bool.or(T, U32.is_ge(U32{s}, U32{bw})), True{}, Equal.cong(Bool, Bool, zz => Bool.or(T, zz), Bool.not(U32.is_lt(U32{s}, U32{bw})), U32.is_ge(U32{s}, U32{bw}), Equal.sym(Bool, U32.is_ge(U32{s}, U32{bw}), Bool.not(U32.is_lt(U32{s}, U32{bw})), un.ge_lt(U32.cmp(U32{s}, U32{bw})))), eg), Equal.trans(Nat, Nat.add(U32.to_nat(U32.sub(U32{s}, U32{bw})), Nat.mul(1n, Word.to_nat(32n, bw))), Nat.add(Word.to_nat(32n, s), U.U32Nat.dbl(32n, U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw})))), Nat.add(Word.to_nat(32n, s), U.U32Nat.dbl(32n, Nat.mul(1n, U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw}))))), Equal.trans(Nat, Nat.add(U32.to_nat(U32.sub(U32{s}, U32{bw})), Nat.mul(1n, Word.to_nat(32n, bw))), Nat.add(U32.to_nat(U32.sub(U32{s}, U32{bw})), Word.to_nat(32n, bw)), Nat.add(Word.to_nat(32n, s), U.U32Nat.dbl(32n, U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw})))), Equal.cong(Nat, Nat, zz => Nat.add(U32.to_nat(U32.sub(U32{s}, U32{bw})), zz), Nat.mul(1n, Word.to_nat(32n, bw)), Word.to_nat(32n, bw), ur.r32(Word.to_nat(32n, bw))), Laws.u32_sub_wrap(U32{s}, U32{bw})), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(32n, s), U.U32Nat.dbl(32n, zz)), U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw})), Nat.mul(1n, U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw}))), ur.r33(U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw}))))), un.bit_le(a0), i2, Laws.word_value_lt(32n, bw)))
1767    case False{}:
1768      ud.fin.f(p, q, bw, a0, rw, x, x2, Word.to_nat(32n, s), ex, i1, ud.k(32n, Word.to_nat(32n, s), Word.to_nat(32n, bw), Word.to_nat(32n, rw), U.U32Nat.bit(a0), Word.to_nat(32n, s), T, U32.is_lt(U32{s}, U32{bw}), False{}, eput, Equal.sym(Bool, U32.is_lt(U32{s}, U32{bw}), Nat.is_lt(Word.to_nat(32n, s), Word.to_nat(32n, bw)), Laws.u32_lt_value(U32{s}, U32{bw})), Equal.trans(Bool, Bool.or(T, Bool.not(U32.is_lt(U32{s}, U32{bw}))), Bool.or(T, U32.is_ge(U32{s}, U32{bw})), False{}, Equal.cong(Bool, Bool, zz => Bool.or(T, zz), Bool.not(U32.is_lt(U32{s}, U32{bw})), U32.is_ge(U32{s}, U32{bw}), Equal.sym(Bool, U32.is_ge(U32{s}, U32{bw}), Bool.not(U32.is_lt(U32{s}, U32{bw})), un.ge_lt(U32.cmp(U32{s}, U32{bw})))), eg), ur.r34(Word.to_nat(32n, s), Word.to_nat(32n, bw), U.U32Nat.bit(U32.is_lt(U32{s}, U32{bw}))), un.bit_le(a0), i2, Laws.word_value_lt(32n, bw)))
1769
1770def ud.step2(+p: Nat, +a0: Bool, +bw: Word(32n), +q: Word(p), +rw: Word(32n), +x: Nat, +x2: Nat, +ex: {Nat.add(U.U32Nat.bit(a0), Nat.double(x)) == x2 : Nat}, +i1: {Nat.add(Nat.mul(Word.to_nat(p, q), Word.to_nat(32n, bw)), Word.to_nat(32n, rw)) == x : Nat}, +i2: {Nat.is_lt(Word.to_nat(32n, rw), Word.to_nat(32n, bw)) == True{} : Bool}) -> {Nat.add(Nat.mul(ud.q(1n+p, U32.divmod.go.shl(p, q, U32{bw}, Word.shl.out(32n, a0, rw))), U32.to_nat(U32{bw})), ud.r(1n+p, U32.divmod.go.shl(p, q, U32{bw}, Word.shl.out(32n, a0, rw)))) == x2 : Nat} & {Nat.is_lt(ud.r(1n+p, U32.divmod.go.shl(p, q, U32{bw}, Word.shl.out(32n, a0, rw))), U32.to_nat(U32{bw})) == True{} : Bool}:
1771  %Equal.sym(Bool & Word(32n), Word.shl.out(32n, a0, rw), (un.topc(32n, a0, rw), Word.shl.put(32n, a0, rw)), un.so(32n, a0, rw)) : {Nat.add(Nat.mul(ud.q(1n+p, U32.divmod.go.shl(p, q, U32{bw}, _)), U32.to_nat(U32{bw})), ud.r(1n+p, U32.divmod.go.shl(p, q, U32{bw}, _))) == x2 : Nat} & {Nat.is_lt(ud.r(1n+p, U32.divmod.go.shl(p, q, U32{bw}, _)), U32.to_nat(U32{bw})) == True{} : Bool}
1772  ud.fin(p, q, Word.shl.put(32n, a0, rw), bw, un.topc(32n, a0, rw), Bool.or(un.topc(32n, a0, rw), U32.is_ge(U32{Word.shl.put(32n, a0, rw)}, U32{bw})), a0, rw, x, x2, {==}, un.putv(32n, a0, rw), ex, i1, i2)
1773
1774def ud.step(+p: Nat, +a0: Bool, +b: U32, qr: Word(p) & U32, +x: Nat, +x2: Nat, +ex: {Nat.add(U.U32Nat.bit(a0), Nat.double(x)) == x2 : Nat}, ih: {Nat.add(Nat.mul(ud.q(p, qr), U32.to_nat(b)), ud.r(p, qr)) == x : Nat} & {Nat.is_lt(ud.r(p, qr), U32.to_nat(b)) == True{} : Bool}) -> {Nat.add(Nat.mul(ud.q(1n+p, U32.divmod.go.rec(p, a0, b, qr)), U32.to_nat(b)), ud.r(1n+p, U32.divmod.go.rec(p, a0, b, qr))) == x2 : Nat} & {Nat.is_lt(ud.r(1n+p, U32.divmod.go.rec(p, a0, b, qr)), U32.to_nat(b)) == True{} : Bool}:
1775  match b:
1776    case U32{+bw}:
1777      match qr:
1778        case (+q, +r):
1779          match r:
1780            case U32{+rw}:
1781              (+i1, +i2) = ih
1782              ud.step2(p, a0, bw, q, rw, x, x2, ex, i1, i2)
1783
1784def ud.go(m: Nat, a: Word(m), +b: U32, +hb: {Nat.is_lt(0n, U32.to_nat(b)) == True{} : Bool}) -> {Nat.add(Nat.mul(ud.q(m, U32.divmod.go(m, a, b)), U32.to_nat(b)), ud.r(m, U32.divmod.go(m, a, b))) == Word.to_nat(m, a) : Nat} & {Nat.is_lt(ud.r(m, U32.divmod.go(m, a, b)), U32.to_nat(b)) == True{} : Bool}:
1785  match m a:
1786    case 0n WNil{}:
1787      ({==}, hb)
1788    case 1n+ +p WCon{+a0, +hi}:
1789      ud.step(p, a0, b, U32.divmod.go(p, hi, b), Word.to_nat(p, hi), Word.to_nat(1n+p, WCon{a0, hi}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{a0, hi}), Nat.add(U.U32Nat.bit(a0), Nat.double(Word.to_nat(p, hi))), un.wc(p, a0, hi)), ud.go(p, hi, b, hb))
1790
1791def ud.dq(G: Word(32n) & U32) -> {U32.to_nat(U32.div.fin(G)) == ud.q(32n, G) : Nat}:
1792  match G:
1793    case (q, r):
1794      {==}
1795
1796def ud.dr(G: Word(32n) & U32) -> {U32.to_nat(U32.mod.fin(G)) == ud.r(32n, G) : Nat}:
1797  match G:
1798    case (q, r):
1799      {==}
1800
1801def ud.nz(x: Nat, e: {Nat.is_eq(x, 0n) == False{} : Bool}) -> {Nat.is_lt(0n, x) == True{} : Bool}:
1802  match x:
1803    case 0n:
1804      Empty.absurd({Nat.is_lt(0n, 0n) == True{} : Bool}, un.tf(e))
1805    case 1n+ +p:
1806      {==}
1807
1808def ud.hb(+bw: Word(32n), h: {U32.is_zero(U32{bw}) == False{} : Bool}) -> {Nat.is_lt(0n, Word.to_nat(32n, bw)) == True{} : Bool}:
1809  ud.nz(Word.to_nat(32n, bw), Equal.trans(Bool, Nat.is_eq(Word.to_nat(32n, bw), 0n), U32.is_zero(U32{bw}), False{}, Equal.sym(Bool, U32.is_zero(U32{bw}), Nat.is_eq(Word.to_nat(32n, bw), 0n), Laws.u32_eq_value(U32{bw}, 0)), h))
1810
1811def ud.dz2(+aw: Word(32n), +bw: Word(32n), G: Word(32n) & U32, iv: {Nat.add(Nat.mul(ud.q(32n, G), U32.to_nat(U32{bw})), ud.r(32n, G)) == Word.to_nat(32n, aw) : Nat} & {Nat.is_lt(ud.r(32n, G), U32.to_nat(U32{bw})) == True{} : Bool}) -> {Nat.add(Nat.mul(U32.to_nat(U32.div.fin(G)), Word.to_nat(32n, bw)), U32.to_nat(U32.mod.fin(G))) == Word.to_nat(32n, aw) : Nat} & {Nat.is_lt(U32.to_nat(U32.mod.fin(G)), Word.to_nat(32n, bw)) == True{} : Bool}:
1812  match G:
1813    case (q, r):
1814      iv
1815
1816def ud.dz(+aw: Word(32n), +bw: Word(32n), z: Bool, ez: {U32.is_zero(U32{bw}) == z : Bool}, h: {U32.is_zero(U32{bw}) == False{} : Bool}) -> {Nat.add(Nat.mul(U32.to_nat(U32.div.if(aw, U32{bw}, z)), Word.to_nat(32n, bw)), U32.to_nat(U32.mod.if(aw, U32{bw}, z))) == Word.to_nat(32n, aw) : Nat} & {Nat.is_lt(U32.to_nat(U32.mod.if(aw, U32{bw}, z)), Word.to_nat(32n, bw)) == True{} : Bool}:
1817  match z:
1818    case True{}:
1819      Empty.absurd({Nat.add(Nat.mul(U32.to_nat(U32.div.if(aw, U32{bw}, True{})), Word.to_nat(32n, bw)), U32.to_nat(U32.mod.if(aw, U32{bw}, True{}))) == Word.to_nat(32n, aw) : Nat} & {Nat.is_lt(U32.to_nat(U32.mod.if(aw, U32{bw}, True{})), Word.to_nat(32n, bw)) == True{} : Bool}, un.tf(Equal.trans(Bool, True{}, U32.is_zero(U32{bw}), False{}, Equal.sym(Bool, U32.is_zero(U32{bw}), True{}, ez), h)))
1820    case False{}:
1821      ud.dz2(aw, bw, U32.divmod.go(32n, aw, U32{bw}), ud.go(32n, aw, U32{bw}, ud.hb(bw, h)))
1822
1823def ud.p1(-x: Nat, -y: Nat, -c: Nat, -d: Nat, pr: {x == y : Nat} & {Nat.is_lt(c, d) == True{} : Bool}) -> {x == y : Nat}:
1824  (+a, +b) = pr
1825  a
1826
1827def ud.p2(-x: Nat, -y: Nat, -c: Nat, -d: Nat, pr: {x == y : Nat} & {Nat.is_lt(c, d) == True{} : Bool}) -> {Nat.is_lt(c, d) == True{} : Bool}:
1828  (+a, +b) = pr
1829  b
1830
1831def Laws.u32_divmod(a, b, h):
1832  match a b:
1833    case U32{+aw} U32{+bw}:
1834      ud.p1(Nat.add(Nat.mul(U32.to_nat(U32.div.if(aw, U32{bw}, U32.is_zero(U32{bw}))), Word.to_nat(32n, bw)), U32.to_nat(U32.mod.if(aw, U32{bw}, U32.is_zero(U32{bw})))), Word.to_nat(32n, aw), U32.to_nat(U32.mod.if(aw, U32{bw}, U32.is_zero(U32{bw}))), Word.to_nat(32n, bw), ud.dz(aw, bw, U32.is_zero(U32{bw}), {==}, h))
1835
1836def Laws.u32_mod_lt(a, b, h):
1837  match a b:
1838    case U32{+aw} U32{+bw}:
1839      ud.p2(Nat.add(Nat.mul(U32.to_nat(U32.div.if(aw, U32{bw}, U32.is_zero(U32{bw}))), Word.to_nat(32n, bw)), U32.to_nat(U32.mod.if(aw, U32{bw}, U32.is_zero(U32{bw})))), Word.to_nat(32n, aw), U32.to_nat(U32.mod.if(aw, U32{bw}, U32.is_zero(U32{bw}))), Word.to_nat(32n, bw), ud.dz(aw, bw, U32.is_zero(U32{bw}), {==}, h))
1840
1841def Laws.u32_div_zero(a):
1842  match a:
1843    case U32{+aw}:
1844      {==}
1845
1846def Laws.u32_mod_zero(a):
1847  match a:
1848    case U32{+aw}:
1849      {==}
1850
1851# The bitwise operations
1852
1853def un.band_comm(x: Bool, y: Bool) -> {Bool.and(x, y) == Bool.and(y, x) : Bool}:
1854  match x y:
1855    case True{} True{}:
1856      {==}
1857    case True{} False{}:
1858      {==}
1859    case False{} True{}:
1860      {==}
1861    case False{} False{}:
1862      {==}
1863
1864def un.bor_comm(x: Bool, y: Bool) -> {Bool.or(x, y) == Bool.or(y, x) : Bool}:
1865  match x y:
1866    case True{} True{}:
1867      {==}
1868    case True{} False{}:
1869      {==}
1870    case False{} True{}:
1871      {==}
1872    case False{} False{}:
1873      {==}
1874
1875def un.bxor_comm(x: Bool, y: Bool) -> {Bool.xor(x, y) == Bool.xor(y, x) : Bool}:
1876  match x y:
1877    case True{} True{}:
1878      {==}
1879    case True{} False{}:
1880      {==}
1881    case False{} True{}:
1882      {==}
1883    case False{} False{}:
1884      {==}
1885
1886def un.bao(x: Bool, y: Bool) -> {Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))) == Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)) : Nat}:
1887  match x y:
1888    case True{} True{}:
1889      {==}
1890    case True{} False{}:
1891      {==}
1892    case False{} True{}:
1893      {==}
1894    case False{} False{}:
1895      {==}
1896
1897def un.bxa(x: Bool, y: Bool) -> {Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))) == Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)) : Nat}:
1898  match x y:
1899    case True{} True{}:
1900      {==}
1901    case True{} False{}:
1902      {==}
1903    case False{} True{}:
1904      {==}
1905    case False{} False{}:
1906      {==}
1907
1908def un.band_t(x: Bool) -> {Bool.and(x, True{}) == x : Bool}:
1909  match x:
1910    case True{}:
1911      {==}
1912    case False{}:
1913      {==}
1914
1915def un.band_f(x: Bool) -> {Bool.and(x, False{}) == False{} : Bool}:
1916  match x:
1917    case True{}:
1918      {==}
1919    case False{}:
1920      {==}
1921
1922def un.bor_f(x: Bool) -> {Bool.or(x, False{}) == x : Bool}:
1923  match x:
1924    case True{}:
1925      {==}
1926    case False{}:
1927      {==}
1928
1929def Laws.word_and_comm(n, a, b):
1930  match n:
1931    case 0n:
1932      {==}
1933    case 1n+ +p:
1934      match a b:
1935        case WCon{+x, +at} WCon{+y, +bt}:
1936          un.wcon_eq(p, Bool.and(x, y), Bool.and(y, x), Word.and(p, at, bt), Word.and(p, bt, at), un.band_comm(x, y), Laws.word_and_comm(p, at, bt))
1937
1938def Laws.u32_and_comm(a, b):
1939  match a b:
1940    case U32{+x} U32{+y}:
1941      un.u32_cong(Word.and(32n, x, y), Word.and(32n, y, x), Laws.word_and_comm(32n, x, y))
1942
1943def Laws.word_or_comm(n, a, b):
1944  match n:
1945    case 0n:
1946      {==}
1947    case 1n+ +p:
1948      match a b:
1949        case WCon{+x, +at} WCon{+y, +bt}:
1950          un.wcon_eq(p, Bool.or(x, y), Bool.or(y, x), Word.or(p, at, bt), Word.or(p, bt, at), un.bor_comm(x, y), Laws.word_or_comm(p, at, bt))
1951
1952def Laws.u32_or_comm(a, b):
1953  match a b:
1954    case U32{+x} U32{+y}:
1955      un.u32_cong(Word.or(32n, x, y), Word.or(32n, y, x), Laws.word_or_comm(32n, x, y))
1956
1957def Laws.word_xor_comm(n, a, b):
1958  match n:
1959    case 0n:
1960      {==}
1961    case 1n+ +p:
1962      match a b:
1963        case WCon{+x, +at} WCon{+y, +bt}:
1964          un.wcon_eq(p, Bool.xor(x, y), Bool.xor(y, x), Word.xor(p, at, bt), Word.xor(p, bt, at), un.bxor_comm(x, y), Laws.word_xor_comm(p, at, bt))
1965
1966def Laws.u32_xor_comm(a, b):
1967  match a b:
1968    case U32{+x} U32{+y}:
1969      un.u32_cong(Word.xor(32n, x, y), Word.xor(32n, y, x), Laws.word_xor_comm(32n, x, y))
1970
1971def ur.r38(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, Nat.double(x1)), Nat.add(x2, Nat.double(x3))) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}:
1972  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(Nat.add(x0, _), Nat.add(x2, Nat.double(x3))) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1973  %Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3)) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, _)) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1974  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x0, Nat.add(Nat.add(x1, x1), Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x0, Nat.add(x1, x1), Nat.add(x2, Nat.add(x3, x3)))) : {_ == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1975  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x1, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x1, x1, Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1976  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))), Nat.add(x2, Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3))), Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))), Laws.nat_add_left_comm(x2, x1, Nat.add(x3, x3)))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1977  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3)))), Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, x3)))), Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x2, x1, Nat.add(x1, Nat.add(x3, x3))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1978  %Equal.sym(Nat, Nat.add(x0, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, x3))))), Nat.add(Nat.add(x0, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(Nat.add(x0, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, x3)))), Nat.add(x0, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, x3))))), Laws.nat_add_assoc(x0, x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, x3)))))) : {_ == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1979  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, x3)), Nat.add(x3, Nat.add(x1, x3)), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, x3)), Nat.add(x1, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x1, x3))) : {Nat.add(Nat.add(x0, x2), Nat.add(x1, _)) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1980  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, Nat.add(x1, x3))), Nat.add(Nat.add(x1, x3), Nat.add(x1, x3)), Equal.sym(Nat, Nat.add(Nat.add(x1, x3), Nat.add(x1, x3)), Nat.add(x1, Nat.add(x3, Nat.add(x1, x3))), Laws.nat_add_assoc(x1, x3, Nat.add(x1, x3)))) : {Nat.add(Nat.add(x0, x2), _) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1981  %Equal.sym(Nat, Nat.add(Nat.add(x1, x3), Nat.add(x1, x3)), Nat.double(Nat.add(x1, x3)), Equal.sym(Nat, Nat.double(Nat.add(x1, x3)), Nat.add(Nat.add(x1, x3), Nat.add(x1, x3)), Laws.nat_double(Nat.add(x1, x3)))) : {Nat.add(Nat.add(x0, x2), _) == Nat.add(Nat.add(x0, x2), Nat.double(Nat.add(x1, x3))) : Nat}
1982  {==}
1983
1984def ur.r39(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, x1), Nat.double(Nat.add(x2, x3))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}:
1985  %Equal.sym(Nat, Nat.double(Nat.add(x2, x3)), Nat.add(Nat.add(x2, x3), Nat.add(x2, x3)), Laws.nat_double(Nat.add(x2, x3))) : {Nat.add(Nat.add(x0, x1), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1986  %Equal.sym(Nat, Nat.add(Nat.add(x2, x3), Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, Nat.add(x2, x3))), Laws.nat_add_assoc(x2, x3, Nat.add(x2, x3))) : {Nat.add(Nat.add(x0, x1), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1987  %Equal.sym(Nat, Nat.add(x3, Nat.add(x2, x3)), Nat.add(x2, Nat.add(x3, x3)), Laws.nat_add_left_comm(x3, x2, x3)) : {Nat.add(Nat.add(x0, x1), Nat.add(x2, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1988  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x0, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))), Laws.nat_add_assoc(x0, x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3))))) : {_ == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1989  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3)))), Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x2, x1, Nat.add(x2, Nat.add(x3, x3))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1990  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))), Nat.add(x2, Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3))), Nat.add(x1, Nat.add(x2, Nat.add(x3, x3))), Laws.nat_add_left_comm(x2, x1, Nat.add(x3, x3)))) : {Nat.add(x0, Nat.add(x2, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1991  %Equal.sym(Nat, Nat.add(x2, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3)))), Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x3, x3))), Nat.add(x2, Nat.add(x2, Nat.add(x1, Nat.add(x3, x3)))), Laws.nat_add_assoc(x2, x2, Nat.add(x1, Nat.add(x3, x3))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1992  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x3, x3)))), Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, Nat.add(x3, x3))), Nat.add(x0, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x3, x3)))), Laws.nat_add_assoc(x0, Nat.add(x2, x2), Nat.add(x1, Nat.add(x3, x3))))) : {_ == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1993  %Equal.sym(Nat, Nat.add(x3, x3), Nat.double(x3), Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1994  %Equal.sym(Nat, Nat.add(x2, x2), Nat.double(x2), Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2))) : {Nat.add(Nat.add(x0, _), Nat.add(x1, Nat.double(x3))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.add(x1, Nat.double(x3))) : Nat}
1995  {==}
1996
1997def Laws.word_and_or(n, a, b):
1998  match n:
1999    case 0n:
2000      {==}
2001    case 1n+ +p:
2002      match a b:
2003        case WCon{+x, +at} WCon{+y, +bt}:
2004          Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Word.to_nat(1n+p, WCon{y, bt})), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.double(Nat.add(Word.to_nat(p, Word.and(p, at, bt)), Word.to_nat(p, Word.or(p, at, bt))))), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), Nat.add(U.U32Nat.bit(Bool.or(x, y)), Nat.double(Word.to_nat(p, Word.or(p, at, bt))))), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.double(Nat.add(Word.to_nat(p, Word.and(p, at, bt)), Word.to_nat(p, Word.or(p, at, bt))))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), Nat.add(U.U32Nat.bit(Bool.or(x, y)), Nat.double(Word.to_nat(p, Word.or(p, at, bt))))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)})), Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), un.wc(p, Bool.and(x, y), Word.and(p, at, bt))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), zz), Word.to_nat(1n+p, WCon{Bool.or(x, y), Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(Bool.or(x, y)), Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), un.wc(p, Bool.or(x, y), Word.or(p, at, bt)))), ur.r38(U.U32Nat.bit(Bool.and(x, y)), Word.to_nat(p, Word.and(p, at, bt)), U.U32Nat.bit(Bool.or(x, y)), Word.to_nat(p, Word.or(p, at, bt)))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.double(zz)), Nat.add(Word.to_nat(p, Word.and(p, at, bt)), Word.to_nat(p, Word.or(p, at, bt))), Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)), Laws.word_and_or(p, at, bt))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(U.U32Nat.bit(Bool.and(x, y)), U.U32Nat.bit(Bool.or(x, y))), Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), un.bao(x, y))), ur.r39(U.U32Nat.bit(x), U.U32Nat.bit(y), Word.to_nat(p, at), Word.to_nat(p, bt))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Word.to_nat(1n+p, WCon{x, at}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), un.wc(p, x, at)))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(1n+p, WCon{x, at}), zz), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), un.wc(p, y, bt))))
2005
2006def ur.r40(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, Nat.double(x1)), Nat.double(Nat.add(x2, Nat.double(x3)))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}:
2007  %Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1)) : {Nat.add(Nat.add(x0, _), Nat.double(Nat.add(x2, Nat.double(x3)))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2008  %Equal.sym(Nat, Nat.double(Nat.add(x2, Nat.double(x3))), Nat.add(Nat.add(x2, Nat.double(x3)), Nat.add(x2, Nat.double(x3))), Laws.nat_double(Nat.add(x2, Nat.double(x3)))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2009  %Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3)) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(Nat.add(x2, _), Nat.add(x2, Nat.double(x3)))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2010  %Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3)) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(Nat.add(x2, Nat.add(x3, x3)), Nat.add(x2, _))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2011  %Equal.sym(Nat, Nat.add(Nat.add(x2, Nat.add(x3, x3)), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x2, Nat.add(Nat.add(x3, x3), Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x2, Nat.add(x3, x3), Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2012  %Equal.sym(Nat, Nat.add(Nat.add(x3, x3), Nat.add(x2, Nat.add(x3, x3))), Nat.add(x3, Nat.add(x3, Nat.add(x2, Nat.add(x3, x3)))), Laws.nat_add_assoc(x3, x3, Nat.add(x2, Nat.add(x3, x3)))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2013  %Equal.sym(Nat, Nat.add(x3, Nat.add(x2, Nat.add(x3, x3))), Nat.add(x2, Nat.add(x3, Nat.add(x3, x3))), Laws.nat_add_left_comm(x3, x2, Nat.add(x3, x3))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, Nat.add(x3, _))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2014  %Equal.sym(Nat, Nat.add(x3, Nat.add(x2, Nat.add(x3, Nat.add(x3, x3)))), Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x3, x2, Nat.add(x3, Nat.add(x3, x3)))) : {Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2015  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x1, x1)), Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x0, Nat.add(Nat.add(x1, x1), Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Laws.nat_add_assoc(x0, Nat.add(x1, x1), Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))) : {_ == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2016  %Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x1, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Laws.nat_add_assoc(x1, x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2017  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x1, Nat.add(x2, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x2, x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2018  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Laws.nat_add_left_comm(x2, x1, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2019  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))), Nat.add(x2, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))), Nat.add(x1, Nat.add(x2, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))), Laws.nat_add_left_comm(x2, x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))) : {Nat.add(x0, Nat.add(x2, Nat.add(x1, _))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2020  %Equal.sym(Nat, Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x1, Nat.add(x2, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Laws.nat_add_left_comm(x2, x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))) : {Nat.add(x0, Nat.add(x2, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2021  %Equal.sym(Nat, Nat.add(x2, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x2, Nat.add(x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Laws.nat_add_assoc(x2, x2, Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))))) : {Nat.add(x0, _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2022  %Equal.sym(Nat, Nat.add(x0, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))), Nat.add(x0, Nat.add(Nat.add(x2, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3))))))), Laws.nat_add_assoc(x0, Nat.add(x2, x2), Nat.add(x1, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))))))) : {_ == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2023  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))), Nat.add(x3, Nat.add(x1, Nat.add(x3, Nat.add(x3, x3)))), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, Nat.add(x3, Nat.add(x3, x3)))), Nat.add(x1, Nat.add(x3, Nat.add(x3, Nat.add(x3, x3)))), Laws.nat_add_left_comm(x3, x1, Nat.add(x3, Nat.add(x3, x3))))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2024  %Equal.sym(Nat, Nat.add(x1, Nat.add(x3, Nat.add(x3, x3))), Nat.add(x3, Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(x3, Nat.add(x1, Nat.add(x3, x3))), Nat.add(x1, Nat.add(x3, Nat.add(x3, x3))), Laws.nat_add_left_comm(x3, x1, Nat.add(x3, x3)))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, Nat.add(x3, _))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2025  %Equal.sym(Nat, Nat.add(x3, Nat.add(x3, Nat.add(x1, Nat.add(x3, x3)))), Nat.add(Nat.add(x3, x3), Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(Nat.add(x3, x3), Nat.add(x1, Nat.add(x3, x3))), Nat.add(x3, Nat.add(x3, Nat.add(x1, Nat.add(x3, x3)))), Laws.nat_add_assoc(x3, x3, Nat.add(x1, Nat.add(x3, x3))))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(x1, _)) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2026  %Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.add(x3, x3), Nat.add(x1, Nat.add(x3, x3)))), Nat.add(Nat.add(x1, Nat.add(x3, x3)), Nat.add(x1, Nat.add(x3, x3))), Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(x3, x3)), Nat.add(x1, Nat.add(x3, x3))), Nat.add(x1, Nat.add(Nat.add(x3, x3), Nat.add(x1, Nat.add(x3, x3)))), Laws.nat_add_assoc(x1, Nat.add(x3, x3), Nat.add(x1, Nat.add(x3, x3))))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2027  %Equal.sym(Nat, Nat.add(x3, x3), Nat.double(x3), Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(Nat.add(x1, Nat.add(x3, x3)), Nat.add(x1, _))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2028  %Equal.sym(Nat, Nat.add(x3, x3), Nat.double(x3), Equal.sym(Nat, Nat.double(x3), Nat.add(x3, x3), Laws.nat_double(x3))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), Nat.add(Nat.add(x1, _), Nat.add(x1, Nat.double(x3)))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2029  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.double(x3)), Nat.add(x1, Nat.double(x3))), Nat.double(Nat.add(x1, Nat.double(x3))), Equal.sym(Nat, Nat.double(Nat.add(x1, Nat.double(x3))), Nat.add(Nat.add(x1, Nat.double(x3)), Nat.add(x1, Nat.double(x3))), Laws.nat_double(Nat.add(x1, Nat.double(x3))))) : {Nat.add(Nat.add(x0, Nat.add(x2, x2)), _) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2030  %Equal.sym(Nat, Nat.add(x2, x2), Nat.double(x2), Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2))) : {Nat.add(Nat.add(x0, _), Nat.double(Nat.add(x1, Nat.double(x3)))) == Nat.add(Nat.add(x0, Nat.double(x2)), Nat.double(Nat.add(x1, Nat.double(x3)))) : Nat}
2031  {==}
2032
2033def Laws.word_xor_and(n, a, b):
2034  match n:
2035    case 0n:
2036      {==}
2037    case 1n+ +p:
2038      match a b:
2039        case WCon{+x, +at} WCon{+y, +bt}:
2040          Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Word.to_nat(1n+p, WCon{y, bt})), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.double(Nat.add(Word.to_nat(p, Word.xor(p, at, bt)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(Word.to_nat(p, Word.xor(p, at, bt)))), Nat.double(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.double(Nat.add(Word.to_nat(p, Word.xor(p, at, bt)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))))), Equal.trans(Nat, Nat.add(Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(Word.to_nat(p, Word.xor(p, at, bt)))), Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(Word.to_nat(p, Word.xor(p, at, bt)))), Nat.double(Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}))), Word.to_nat(1n+p, WCon{Bool.xor(x, y), Word.xor(p, at, bt)}), Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(Word.to_nat(p, Word.xor(p, at, bt)))), un.wc(p, Bool.xor(x, y), Word.xor(p, at, bt))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(Word.to_nat(p, Word.xor(p, at, bt)))), Nat.double(zz)), Word.to_nat(1n+p, WCon{Bool.and(x, y), Word.and(p, at, bt)}), Nat.add(U.U32Nat.bit(Bool.and(x, y)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), un.wc(p, Bool.and(x, y), Word.and(p, at, bt)))), ur.r40(U.U32Nat.bit(Bool.xor(x, y)), Word.to_nat(p, Word.xor(p, at, bt)), U.U32Nat.bit(Bool.and(x, y)), Word.to_nat(p, Word.and(p, at, bt)))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.double(zz)), Nat.add(Word.to_nat(p, Word.xor(p, at, bt)), Nat.double(Word.to_nat(p, Word.and(p, at, bt)))), Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)), Laws.word_xor_and(p, at, bt))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(U.U32Nat.bit(Bool.xor(x, y)), Nat.double(U.U32Nat.bit(Bool.and(x, y)))), Nat.add(U.U32Nat.bit(x), U.U32Nat.bit(y)), un.bxa(x, y))), ur.r39(U.U32Nat.bit(x), U.U32Nat.bit(y), Word.to_nat(p, at), Word.to_nat(p, bt))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Word.to_nat(1n+p, WCon{x, at}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), un.wc(p, x, at)))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(1n+p, WCon{x, at}), zz), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), un.wc(p, y, bt))))
2041
2042def Laws.u32_and_or(a, b):
2043  match a b:
2044    case U32{+x} U32{+y}:
2045      Laws.word_and_or(32n, x, y)
2046
2047def Laws.u32_xor_and(a, b):
2048  match a b:
2049    case U32{+x} U32{+y}:
2050      Laws.word_xor_and(32n, x, y)
2051
2052def un.lt1(x: Nat, h: {Nat.is_lt(x, 1n) == True{} : Bool}) -> {x == 0n : Nat}:
2053  match x:
2054    case 0n:
2055      {==}
2056    case 1n+ +p:
2057      match p:
2058        case 0n:
2059          Empty.absurd({1n == 0n : Nat}, un.ft(h))
2060        case 1n+ +q:
2061          Empty.absurd({2n+q == 0n : Nat}, un.ft(h))
2062
2063def un.dz0(v: Nat, e: {Nat.double(v) == 0n : Nat}) -> {v == 0n : Nat}:
2064  match v:
2065    case 0n:
2066      {==}
2067    case 1n+ +p:
2068      Empty.absurd({1n+p == 0n : Nat}, un.sz(1n+Nat.double(p), e))
2069
2070def un.double_inj(a: Nat, b: Nat, e: {Nat.double(a) == Nat.double(b) : Nat}) -> {a == b : Nat}:
2071  match a b:
2072    case 0n 0n:
2073      {==}
2074    case 0n 1n+ +q:
2075      Empty.absurd({0n == 1n+q : Nat}, un.sz(1n+Nat.double(q), Equal.sym(Nat, 0n, 2n+Nat.double(q), e)))
2076    case 1n+ +p 0n:
2077      Empty.absurd({1n+p == 0n : Nat}, un.sz(1n+Nat.double(p), e))
2078    case 1n+ +p 1n+ +q:
2079      un.succ_cong(p, q, un.double_inj(p, q, un.succ_inj(Nat.double(p), Nat.double(q), un.succ_inj(1n+Nat.double(p), 1n+Nat.double(q), e))))
2080
2081def un.odd_even(a: Nat, b: Nat, e: {1n+Nat.double(a) == Nat.double(b) : Nat}) -> Empty:
2082  match a b:
2083    case 0n 0n:
2084      un.sz(0n, e)
2085    case 0n 1n+ +q:
2086      un.sz(Nat.double(q), Equal.sym(Nat, 0n, 1n+Nat.double(q), un.succ_inj(0n, 1n+Nat.double(q), e)))
2087    case 1n+ +p 0n:
2088      un.sz(2n+Nat.double(p), e)
2089    case 1n+ +p 1n+ +q:
2090      un.odd_even(p, q, un.succ_inj(1n+Nat.double(p), Nat.double(q), un.succ_inj(2n+Nat.double(p), 1n+Nat.double(q), e)))
2091
2092def un.lt_half(y: Bool, +v: Nat, +d: Nat, h: {Nat.is_lt(Nat.add(U.U32Nat.bit(y), Nat.double(v)), Nat.double(d)) == True{} : Bool}) -> {Nat.is_lt(v, d) == True{} : Bool}:
2093  match y:
2094    case False{}:
2095      Equal.trans(Bool, Nat.is_lt(v, d), Nat.is_lt(Nat.double(v), Nat.double(d)), True{}, Equal.sym(Bool, Nat.is_lt(Nat.double(v), Nat.double(d)), Nat.is_lt(v, d), un.lt_dbl(v, d)), h)
2096    case True{}:
2097      Equal.trans(Bool, Nat.is_lt(v, d), Nat.is_lt(1n+Nat.double(v), Nat.double(d)), True{}, Equal.sym(Bool, Nat.is_lt(1n+Nat.double(v), Nat.double(d)), Nat.is_lt(v, d), un.lt_dbl1(v, d)), h)
2098
2099def un.or_zero(n: Nat, +a: Word(n), +b: Word(n), hb: {Word.to_nat(n, b) == 0n : Nat}) -> {Word.to_nat(n, Word.or(n, a, b)) == Word.to_nat(n, a) : Nat}:
2100  match n:
2101    case 0n:
2102      {==}
2103    case 1n+ +p:
2104      match a b:
2105        case WCon{+x, +at} WCon{True{}, +bt}:
2106          Empty.absurd({Word.to_nat(1n+p, Word.or(1n+p, WCon{x, at}, WCon{True{}, bt})) == Word.to_nat(1n+p, WCon{x, at}) : Nat}, un.sz(Nat.double(Word.to_nat(p, bt)), hb))
2107        case WCon{+x, +at} WCon{False{}, +bt}:
2108          Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.or(x, False{}), Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Word.to_nat(1n+p, WCon{x, at}), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.or(x, False{}), Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.or(x, False{}), Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(Bool.or(x, False{})), Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), un.wc(p, Bool.or(x, False{}), Word.or(p, at, bt)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), U.U32Nat.bit(Bool.or(x, False{})), U.U32Nat.bit(x), Equal.cong(Bool, Nat, zz => U.U32Nat.bit(zz), Bool.or(x, False{}), x, un.bor_f(x)))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(x), Nat.double(zz)), Word.to_nat(p, Word.or(p, at, bt)), Word.to_nat(p, at), un.or_zero(p, at, bt, un.dz0(Word.to_nat(p, bt), hb)))), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, at}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, at))), un.wc(p, x, at)))
2109
2110def ur.r41(+x0: Nat, +x1: Nat, +x2: Nat) -> {Nat.add(x0, Nat.double(Nat.add(x1, x2))) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}:
2111  %Equal.sym(Nat, Nat.double(Nat.add(x1, x2)), Nat.add(Nat.add(x1, x2), Nat.add(x1, x2)), Laws.nat_double(Nat.add(x1, x2))) : {Nat.add(x0, _) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2112  %Equal.sym(Nat, Nat.add(Nat.add(x1, x2), Nat.add(x1, x2)), Nat.add(x1, Nat.add(x2, Nat.add(x1, x2))), Laws.nat_add_assoc(x1, x2, Nat.add(x1, x2))) : {Nat.add(x0, _) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2113  %Equal.sym(Nat, Nat.add(x2, Nat.add(x1, x2)), Nat.add(x1, Nat.add(x2, x2)), Laws.nat_add_left_comm(x2, x1, x2)) : {Nat.add(x0, Nat.add(x1, _)) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2114  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(x1, Nat.add(x2, x2)))), Nat.add(x1, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2)))), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2)))), Nat.add(x0, Nat.add(x1, Nat.add(x1, Nat.add(x2, x2)))), Laws.nat_add_left_comm(x1, x0, Nat.add(x1, Nat.add(x2, x2))))) : {_ == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2115  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(x2, x2))), Nat.add(x1, Nat.add(x0, Nat.add(x2, x2))), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, Nat.add(x2, x2))), Nat.add(x0, Nat.add(x1, Nat.add(x2, x2))), Laws.nat_add_left_comm(x1, x0, Nat.add(x2, x2)))) : {Nat.add(x1, _) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2116  %Equal.sym(Nat, Nat.add(x1, Nat.add(x1, Nat.add(x0, Nat.add(x2, x2)))), Nat.add(Nat.add(x1, x1), Nat.add(x0, Nat.add(x2, x2))), Equal.sym(Nat, Nat.add(Nat.add(x1, x1), Nat.add(x0, Nat.add(x2, x2))), Nat.add(x1, Nat.add(x1, Nat.add(x0, Nat.add(x2, x2)))), Laws.nat_add_assoc(x1, x1, Nat.add(x0, Nat.add(x2, x2))))) : {_ == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2117  %Equal.sym(Nat, Nat.add(x2, x2), Nat.double(x2), Equal.sym(Nat, Nat.double(x2), Nat.add(x2, x2), Laws.nat_double(x2))) : {Nat.add(Nat.add(x1, x1), Nat.add(x0, _)) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2118  %Equal.sym(Nat, Nat.add(x1, x1), Nat.double(x1), Equal.sym(Nat, Nat.double(x1), Nat.add(x1, x1), Laws.nat_double(x1))) : {Nat.add(_, Nat.add(x0, Nat.double(x2))) == Nat.add(Nat.double(x1), Nat.add(x0, Nat.double(x2))) : Nat}
2119  {==}
2120
2121def Laws.word_or_split(n, a, b, k, q, e, h):
2122  match n:
2123    case 0n:
2124      {==}
2125    case 1n+ +p:
2126      match a b:
2127        case WCon{False{}, +at} WCon{+y, +bt}:
2128          match k:
2129            case 0n:
2130              +hb0 = un.lt1(Word.to_nat(1n+p, WCon{y, bt}), h)
2131              Equal.trans(Nat, Word.to_nat(1n+p, Word.or(1n+p, WCon{False{}, at}, WCon{y, bt})), Nat.add(Word.to_nat(1n+p, WCon{False{}, at}), 0n), Nat.add(Word.to_nat(1n+p, WCon{False{}, at}), Word.to_nat(1n+p, WCon{y, bt})), Equal.trans(Nat, Word.to_nat(1n+p, Word.or(1n+p, WCon{False{}, at}, WCon{y, bt})), Word.to_nat(1n+p, WCon{False{}, at}), Nat.add(Word.to_nat(1n+p, WCon{False{}, at}), 0n), un.or_zero(1n+p, WCon{False{}, at}, WCon{y, bt}, hb0), Equal.sym(Nat, Nat.add(Word.to_nat(1n+p, WCon{False{}, at}), 0n), Word.to_nat(1n+p, WCon{False{}, at}), Laws.nat_add_zero(Word.to_nat(1n+p, WCon{False{}, at})))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(1n+p, WCon{False{}, at}), zz), 0n, Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), 0n, hb0)))
2132            case 1n+ +j:
2133              Equal.trans(Nat, Word.to_nat(1n+p, WCon{y, Word.or(p, at, bt)}), Nat.add(Nat.double(Word.to_nat(p, at)), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Nat.add(Nat.double(Word.to_nat(p, at)), Word.to_nat(1n+p, WCon{y, bt})), Equal.trans(Nat, Word.to_nat(1n+p, WCon{y, Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(y), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), Nat.add(Nat.double(Word.to_nat(p, at)), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt)))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{y, Word.or(p, at, bt)}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, Word.or(p, at, bt)))), Nat.add(U.U32Nat.bit(y), Nat.double(Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)))), un.wc(p, y, Word.or(p, at, bt)), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(y), Nat.double(zz)), Word.to_nat(p, Word.or(p, at, bt)), Nat.add(Word.to_nat(p, at), Word.to_nat(p, bt)), Laws.word_or_split(p, at, bt, j, q, un.double_inj(Word.to_nat(p, at), U.U32Nat.dbl(j, q), e), un.lt_half(y, Word.to_nat(p, bt), U.U32Nat.dbl(j, 1n), Equal.trans(Bool, Nat.is_lt(Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), Nat.double(U.U32Nat.dbl(j, 1n))), Nat.is_lt(Word.to_nat(1n+p, WCon{y, bt}), Nat.double(U.U32Nat.dbl(j, 1n))), True{}, Equal.cong(Nat, Bool, zz => Nat.is_lt(zz, Nat.double(U.U32Nat.dbl(j, 1n))), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), un.wc(p, y, bt))), h))))), ur.r41(U.U32Nat.bit(y), Word.to_nat(p, at), Word.to_nat(p, bt))), Equal.cong(Nat, Nat, zz => Nat.add(Nat.double(Word.to_nat(p, at)), zz), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), Nat.add(U.U32Nat.bit(y), Nat.double(Word.to_nat(p, bt))), un.wc(p, y, bt))))
2134        case WCon{True{}, +at} WCon{+y, +bt}:
2135          match k:
2136            case 0n:
2137              +hb0 = un.lt1(Word.to_nat(1n+p, WCon{y, bt}), h)
2138              Equal.trans(Nat, Word.to_nat(1n+p, Word.or(1n+p, WCon{True{}, at}, WCon{y, bt})), Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), 0n), Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), Word.to_nat(1n+p, WCon{y, bt})), Equal.trans(Nat, Word.to_nat(1n+p, Word.or(1n+p, WCon{True{}, at}, WCon{y, bt})), Word.to_nat(1n+p, WCon{True{}, at}), Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), 0n), un.or_zero(1n+p, WCon{True{}, at}, WCon{y, bt}, hb0), Equal.sym(Nat, Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), 0n), Word.to_nat(1n+p, WCon{True{}, at}), Laws.nat_add_zero(Word.to_nat(1n+p, WCon{True{}, at})))), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), zz), 0n, Word.to_nat(1n+p, WCon{y, bt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{y, bt}), 0n, hb0)))
2139            case 1n+ +j:
2140              Empty.absurd({Word.to_nat(1n+p, Word.or(1n+p, WCon{True{}, at}, WCon{y, bt})) == Nat.add(Word.to_nat(1n+p, WCon{True{}, at}), Word.to_nat(1n+p, WCon{y, bt})) : Nat}, un.odd_even(Word.to_nat(p, at), U.U32Nat.dbl(j, q), e))
2141
2142def Laws.u32_or_split(a, b, k, q, e, h):
2143  match a b:
2144    case U32{+x} U32{+y}:
2145      Laws.word_or_split(32n, x, y, k, q, e, h)
2146
2147def ur.r42(+x0: Nat) -> {2n+Nat.double(x0) == Nat.double(1n+x0) : Nat}:
2148  %Equal.sym(Nat, Nat.double(x0), Nat.add(x0, x0), Laws.nat_double(x0)) : {Nat.add(1n, Nat.add(1n, _)) == Nat.double(1n+x0) : Nat}
2149  %Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, x0))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, x0)), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, x0)), Nat.add(1n, Nat.add(1n, Nat.add(x0, x0))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, x0)))) : {_ == Nat.double(1n+x0) : Nat}
2150  %Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, x0)), Nat.add(1n, Nat.add(1n, Nat.add(x0, x0))), Equal.sym(Nat, Nat.add(1n, Nat.add(1n, Nat.add(x0, x0))), Nat.add(Nat.add(1n, 1n), Nat.add(x0, x0)), Equal.sym(Nat, Nat.add(Nat.add(1n, 1n), Nat.add(x0, x0)), Nat.add(1n, Nat.add(1n, Nat.add(x0, x0))), Laws.nat_add_assoc(1n, 1n, Nat.add(x0, x0))))) : {_ == Nat.double(1n+x0) : Nat}
2151  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, x0)), Nat.add(x0, Nat.add(1n, x0)), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, x0)), Nat.add(1n, Nat.add(x0, x0)), Laws.nat_add_left_comm(x0, 1n, x0))) : {Nat.add(1n, _) == Nat.double(1n+x0) : Nat}
2152  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(1n, x0))), Nat.add(Nat.add(1n, x0), Nat.add(1n, x0)), Equal.sym(Nat, Nat.add(Nat.add(1n, x0), Nat.add(1n, x0)), Nat.add(1n, Nat.add(x0, Nat.add(1n, x0))), Laws.nat_add_assoc(1n, x0, Nat.add(1n, x0)))) : {_ == Nat.double(1n+x0) : Nat}
2153  %Equal.sym(Nat, Nat.add(1n+x0, 1n+x0), Nat.double(1n+x0), Equal.sym(Nat, Nat.double(1n+x0), Nat.add(1n+x0, 1n+x0), Laws.nat_double(1n+x0))) : {_ == Nat.double(1n+x0) : Nat}
2154  {==}
2155
2156def Laws.word_mask_value(n, k, h):
2157  match n:
2158    case 0n:
2159      match k:
2160        case 0n:
2161          {==}
2162        case 1n+ +j:
2163          Empty.absurd({1n+Word.to_nat(0n, U.U32Word.mask(0n, 1n+j)) == U.U32Nat.dbl(1n+j, 1n) : Nat}, un.ft(h))
2164    case 1n+ +p:
2165      match k:
2166        case 0n:
2167          un.succ_cong(Word.to_nat(1n+p, Word.zero(1n+p)), 0n, Laws.word_zero_value(1n+p))
2168        case 1n+ +j:
2169          Equal.trans(Nat, 2n+Nat.double(Word.to_nat(p, U.U32Word.mask(p, j))), Nat.double(1n+Word.to_nat(p, U.U32Word.mask(p, j))), Nat.double(U.U32Nat.dbl(j, 1n)), ur.r42(Word.to_nat(p, U.U32Word.mask(p, j))), Equal.cong(Nat, Nat, zz => Nat.double(zz), 1n+Word.to_nat(p, U.U32Word.mask(p, j)), U.U32Nat.dbl(j, 1n), Laws.word_mask_value(p, j, h)))
2170
2171def un.and_zero(n: Nat, +w: Word(n), +m: Word(n), hm: {Word.to_nat(n, m) == 0n : Nat}) -> {Word.to_nat(n, Word.and(n, w, m)) == 0n : Nat}:
2172  match n:
2173    case 0n:
2174      {==}
2175    case 1n+ +p:
2176      match w m:
2177        case WCon{+x, +wt} WCon{True{}, +mt}:
2178          Empty.absurd({Word.to_nat(1n+p, Word.and(1n+p, WCon{x, wt}, WCon{True{}, mt})) == 0n : Nat}, un.sz(Nat.double(Word.to_nat(p, mt)), hm))
2179        case WCon{+x, +wt} WCon{False{}, +mt}:
2180          Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, False{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(False{}), Nat.double(0n)), 0n, Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, False{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(False{}), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), Nat.add(U.U32Nat.bit(False{}), Nat.double(0n)), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, False{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(Bool.and(x, False{})), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), Nat.add(U.U32Nat.bit(False{}), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), un.wc(p, Bool.and(x, False{}), Word.and(p, wt, mt)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), U.U32Nat.bit(Bool.and(x, False{})), U.U32Nat.bit(False{}), Equal.cong(Bool, Nat, zz => U.U32Nat.bit(zz), Bool.and(x, False{}), False{}, un.band_f(x)))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(False{}), Nat.double(zz)), Word.to_nat(p, Word.and(p, wt, mt)), 0n, un.and_zero(p, wt, mt, un.dz0(Word.to_nat(p, mt), hm)))), {==})
2181
2182def Laws.word_and_mask(n, w, m, k, h):
2183  match n:
2184    case 0n:
2185      Equal.sym(Nat, U.U32Nat.low(k, 0n), 0n, un.low_zero(k))
2186    case 1n+ +p:
2187      match w m:
2188        case WCon{+x, +wt} WCon{False{}, +mt}:
2189          match k:
2190            case 0n:
2191              un.and_zero(1n+p, WCon{x, wt}, WCon{False{}, mt}, un.succ_inj(Word.to_nat(1n+p, WCon{False{}, mt}), 0n, h))
2192            case 1n+ +j:
2193              Empty.absurd({Word.to_nat(1n+p, Word.and(1n+p, WCon{x, wt}, WCon{False{}, mt})) == U.U32Nat.low(1n+j, Word.to_nat(1n+p, WCon{x, wt})) : Nat}, un.odd_even(Word.to_nat(p, mt), U.U32Nat.dbl(j, 1n), h))
2194        case WCon{+x, +wt} WCon{True{}, +mt}:
2195          match k:
2196            case 0n:
2197              un.and_zero(1n+p, WCon{x, wt}, WCon{True{}, mt}, un.succ_inj(Word.to_nat(1n+p, WCon{True{}, mt}), 0n, h))
2198            case 1n+ +j:
2199              Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, True{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Nat.double(U.U32Nat.low(j, U.U32Nat.half(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt))))))), Nat.add(U.U32Nat.odd(Word.to_nat(1n+p, WCon{x, wt})), Nat.double(U.U32Nat.low(j, U.U32Nat.half(Word.to_nat(1n+p, WCon{x, wt}))))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, True{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Nat.double(U.U32Nat.low(j, Word.to_nat(p, wt)))), Nat.add(U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Nat.double(U.U32Nat.low(j, U.U32Nat.half(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt))))))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, True{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(x), Nat.double(U.U32Nat.low(j, Word.to_nat(p, wt)))), Nat.add(U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Nat.double(U.U32Nat.low(j, Word.to_nat(p, wt)))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, True{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), Nat.add(U.U32Nat.bit(x), Nat.double(U.U32Nat.low(j, Word.to_nat(p, wt)))), Equal.trans(Nat, Word.to_nat(1n+p, WCon{Bool.and(x, True{}), Word.and(p, wt, mt)}), Nat.add(U.U32Nat.bit(Bool.and(x, True{})), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), un.wc(p, Bool.and(x, True{}), Word.and(p, wt, mt)), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(Word.to_nat(p, Word.and(p, wt, mt)))), U.U32Nat.bit(Bool.and(x, True{})), U.U32Nat.bit(x), Equal.cong(Bool, Nat, zz => U.U32Nat.bit(zz), Bool.and(x, True{}), x, un.band_t(x)))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.bit(x), Nat.double(zz)), Word.to_nat(p, Word.and(p, wt, mt)), U.U32Nat.low(j, Word.to_nat(p, wt)), Laws.word_and_mask(p, wt, mt, j, un.double_inj(1n+Word.to_nat(p, mt), U.U32Nat.dbl(j, 1n), h)))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(U.U32Nat.low(j, Word.to_nat(p, wt)))), U.U32Nat.bit(x), U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Equal.sym(Nat, U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), U.U32Nat.bit(x), un.odd_bd(x, Word.to_nat(p, wt))))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.odd(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Nat.double(U.U32Nat.low(j, zz))), Word.to_nat(p, wt), U.U32Nat.half(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Equal.sym(Nat, U.U32Nat.half(Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt)))), Word.to_nat(p, wt), un.half_bd(x, Word.to_nat(p, wt))))), Equal.cong(Nat, Nat, zz => Nat.add(U.U32Nat.odd(zz), Nat.double(U.U32Nat.low(j, U.U32Nat.half(zz)))), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt))), Word.to_nat(1n+p, WCon{x, wt}), Equal.sym(Nat, Word.to_nat(1n+p, WCon{x, wt}), Nat.add(U.U32Nat.bit(x), Nat.double(Word.to_nat(p, wt))), un.wc(p, x, wt))))
2200
2201def Laws.u32_and_mask(a, m, k, h):
2202  match a m:
2203    case U32{+x} U32{+y}:
2204      Laws.word_and_mask(32n, x, y, k, h)
2205
2206def Laws.u32_and_65535(a):
2207  match a:
2208    case U32{+x}:
2209      Laws.word_and_mask(32n, x, U.U32Word.mask(32n, 16n), 16n, Laws.word_mask_value(32n, 16n, {==}))
2210
2211def ur.r43(+x0: Nat, +x1: Nat) -> {Nat.add(x0, x1) == Nat.add(x1, x0) : Nat}:
2212  %Equal.sym(Nat, Nat.add(x0, x1), Nat.add(x1, x0), Equal.sym(Nat, Nat.add(x1, x0), Nat.add(x0, x1), Laws.nat_add_comm(x1, x0))) : {_ == Nat.add(x1, x0) : Nat}
2213  {==}
2214
2215def un.lts(x: Nat, y: Nat) -> {Nat.is_lt(x, 1n+y) == Nat.is_le(x, y) : Bool}:
2216  Equal.sym(Bool, Nat.is_le(1n+x, 1n+y), Nat.is_lt(x, 1n+y), un.le_succ(x, 1n+y))
2217
2218def Laws.word_not_sub(n, w):
2219  Laws.word_value_eq(n, Word.not(n, w), Word.sub(n, U.U32Word.mask(n, n), w), Laws.nat_add_cancel(Word.to_nat(n, w), Word.to_nat(n, Word.not(n, w)), Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Equal.trans(Nat, Nat.add(Word.to_nat(n, w), Word.to_nat(n, Word.not(n, w))), Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Nat.add(Word.to_nat(n, w), Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w))), Equal.trans(Nat, Nat.add(Word.to_nat(n, w), Word.to_nat(n, Word.not(n, w))), Word.to_nat(n, U.U32Word.mask(n, n)), Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Equal.trans(Nat, Nat.add(Word.to_nat(n, w), Word.to_nat(n, Word.not(n, w))), Nat.add(Word.to_nat(n, Word.not(n, w)), Word.to_nat(n, w)), Word.to_nat(n, U.U32Word.mask(n, n)), ur.r43(Word.to_nat(n, w), Word.to_nat(n, Word.not(n, w))), un.succ_inj(Nat.add(Word.to_nat(n, Word.not(n, w)), Word.to_nat(n, w)), Word.to_nat(n, U.U32Word.mask(n, n)), Equal.trans(Nat, 1n+Nat.add(Word.to_nat(n, Word.not(n, w)), Word.to_nat(n, w)), U.U32Nat.dbl(n, 1n), 1n+Word.to_nat(n, U.U32Word.mask(n, n)), Laws.word_not_value(n, w), Equal.sym(Nat, 1n+Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, 1n), Laws.word_mask_value(n, n, Laws.nat_le_refl(n)))))), Equal.sym(Nat, Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Word.to_nat(n, U.U32Word.mask(n, n)), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, 0n)), Word.to_nat(n, U.U32Word.mask(n, n)), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, U.U32Nat.bit(False{}))), Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, 0n)), Equal.trans(Nat, Nat.add(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)), Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, U.U32Word.mask(n, n), w))))), Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, U.U32Nat.bit(False{}))), Laws.word_sub_wrap(n, U.U32Word.mask(n, n), w), Equal.cong(Nat, Nat, zz => Nat.add(Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, zz)), U.U32Nat.bit(Cmp.is_lt(Word.cmp(n, U.U32Word.mask(n, n), w))), U.U32Nat.bit(False{}), Equal.cong(Bool, Nat, zz => U.U32Nat.bit(zz), Cmp.is_lt(Word.cmp(n, U.U32Word.mask(n, n), w)), False{}, Equal.trans(Bool, Cmp.is_lt(Word.cmp(n, U.U32Word.mask(n, n), w)), Nat.is_lt(Word.to_nat(n, U.U32Word.mask(n, n)), Word.to_nat(n, w)), False{}, Equal.cong(Cmp, Bool, zz => Cmp.is_lt(zz), Word.cmp(n, U.U32Word.mask(n, n), w), Nat.cmp(Word.to_nat(n, U.U32Word.mask(n, n)), Word.to_nat(n, w)), Laws.word_cmp_value(n, U.U32Word.mask(n, n), w)), un.le_not_lt(Word.to_nat(n, w), Word.to_nat(n, U.U32Word.mask(n, n)), Equal.trans(Bool, Nat.is_le(Word.to_nat(n, w), Word.to_nat(n, U.U32Word.mask(n, n))), Nat.is_lt(Word.to_nat(n, w), 1n+Word.to_nat(n, U.U32Word.mask(n, n))), True{}, Equal.sym(Bool, Nat.is_lt(Word.to_nat(n, w), 1n+Word.to_nat(n, U.U32Word.mask(n, n))), Nat.is_le(Word.to_nat(n, w), Word.to_nat(n, U.U32Word.mask(n, n))), un.lts(Word.to_nat(n, w), Word.to_nat(n, U.U32Word.mask(n, n)))), Equal.trans(Bool, Nat.is_lt(Word.to_nat(n, w), 1n+Word.to_nat(n, U.U32Word.mask(n, n))), Nat.is_lt(Word.to_nat(n, w), U.U32Nat.dbl(n, 1n)), True{}, Equal.cong(Nat, Bool, zz => Nat.is_lt(Word.to_nat(n, w), zz), 1n+Word.to_nat(n, U.U32Word.mask(n, n)), U.U32Nat.dbl(n, 1n), Laws.word_mask_value(n, n, Laws.nat_le_refl(n))), Laws.word_value_lt(n, w)))))))), {==}), ur.r11(Word.to_nat(n, U.U32Word.mask(n, n)), n)))), ur.r43(Word.to_nat(n, Word.sub(n, U.U32Word.mask(n, n), w)), Word.to_nat(n, w)))))
2220
2221def Laws.u32_not_sub(a):
2222  match a:
2223    case U32{+x}:
2224      un.u32_cong(Word.not(32n, x), Word.sub(32n, U.U32Word.mask(32n, 32n), x), Laws.word_not_sub(32n, x))
2225
2226# Shifts by k bits
2227
2228def Laws.u32_shrn_value(a, k):
2229  match k:
2230    case 0n:
2231      {==}
2232    case 1n+ +p:
2233      Equal.trans(Nat, U32.to_nat(U32.shr(U32.shrn(a, p))), U.U32Nat.half(U.U32Nat.high(p, U32.to_nat(a))), U.U32Nat.high(p, U.U32Nat.half(U32.to_nat(a))), Equal.trans(Nat, U32.to_nat(U32.shr(U32.shrn(a, p))), U.U32Nat.half(U32.to_nat(U32.shrn(a, p))), U.U32Nat.half(U.U32Nat.high(p, U32.to_nat(a))), Laws.u32_shr_value(U32.shrn(a, p)), Equal.cong(Nat, Nat, zz => U.U32Nat.half(zz), U32.to_nat(U32.shrn(a, p)), U.U32Nat.high(p, U32.to_nat(a)), Laws.u32_shrn_value(a, p))), Equal.sym(Nat, U.U32Nat.high(p, U.U32Nat.half(U32.to_nat(a))), U.U32Nat.half(U.U32Nat.high(p, U32.to_nat(a))), un.high_half(p, U32.to_nat(a))))
2234
2235def un.u32_shl_low(+x: U32) -> {U32.to_nat(U32.shl(x)) == U.U32Nat.low(32n, Nat.double(U32.to_nat(x))) : Nat}:
2236  match x:
2237    case U32{+v}:
2238      un.shl_low(32n, v)
2239
2240def un.u32_low_self(+a: U32) -> {U32.to_nat(a) == U.U32Nat.low(32n, U32.to_nat(a)) : Nat}:
2241  match a:
2242    case U32{+w}:
2243      Equal.sym(Nat, U.U32Nat.low(32n, Word.to_nat(32n, w)), Word.to_nat(32n, w), Laws.low_small(32n, Word.to_nat(32n, w), Laws.word_value_lt(32n, w)))
2244
2245def Laws.u32_shln_low(a, k):
2246  match k:
2247    case 0n:
2248      un.u32_low_self(a)
2249    case 1n+ +p:
2250      Equal.trans(Nat, U32.to_nat(U32.shl(U32.shln(a, p))), U.U32Nat.low(32n, Nat.double(U.U32Nat.low(32n, U.U32Nat.dbl(p, U32.to_nat(a))))), U.U32Nat.low(32n, Nat.double(U.U32Nat.dbl(p, U32.to_nat(a)))), Equal.trans(Nat, U32.to_nat(U32.shl(U32.shln(a, p))), U.U32Nat.low(32n, Nat.double(U32.to_nat(U32.shln(a, p)))), U.U32Nat.low(32n, Nat.double(U.U32Nat.low(32n, U.U32Nat.dbl(p, U32.to_nat(a))))), un.u32_shl_low(U32.shln(a, p)), Equal.cong(Nat, Nat, zz => U.U32Nat.low(32n, Nat.double(zz)), U32.to_nat(U32.shln(a, p)), U.U32Nat.low(32n, U.U32Nat.dbl(p, U32.to_nat(a))), Laws.u32_shln_low(a, p))), un.low_double_low(32n, U.U32Nat.dbl(p, U32.to_nat(a))))
2251
2252# More of the Nat library
2253
2254def Laws.low_double(k, x):
2255  Equal.trans(Nat, Nat.add(U.U32Nat.odd(Nat.double(x)), Nat.double(U.U32Nat.low(k, U.U32Nat.half(Nat.double(x))))), Nat.add(0n, Nat.double(U.U32Nat.low(k, x))), Nat.double(U.U32Nat.low(k, x)), Equal.trans(Nat, Nat.add(U.U32Nat.odd(Nat.double(x)), Nat.double(U.U32Nat.low(k, U.U32Nat.half(Nat.double(x))))), Nat.add(0n, Nat.double(U.U32Nat.low(k, U.U32Nat.half(Nat.double(x))))), Nat.add(0n, Nat.double(U.U32Nat.low(k, x))), Equal.cong(Nat, Nat, zz => Nat.add(zz, Nat.double(U.U32Nat.low(k, U.U32Nat.half(Nat.double(x))))), U.U32Nat.odd(Nat.double(x)), 0n, un.odd_d(x)), Equal.cong(Nat, Nat, zz => Nat.add(0n, Nat.double(U.U32Nat.low(k, zz))), U.U32Nat.half(Nat.double(x)), x, Laws.half_double(x))), {==})
2256
2257def Laws.high_double(k, x):
2258  Equal.cong(Nat, Nat, zz => U.U32Nat.high(k, zz), U.U32Nat.half(Nat.double(x)), x, Laws.half_double(x))
2259
2260def ur.r44(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(x0, x1), 1n+U.U32Nat.dbl(x2, x3)) == Nat.add(x0, 1n+Nat.add(x1, U.U32Nat.dbl(x2, x3))) : Nat}:
2261  %Equal.sym(Nat, Nat.add(Nat.add(x0, x1), Nat.add(1n, U.U32Nat.dbl(x2, x3))), Nat.add(x0, Nat.add(x1, Nat.add(1n, U.U32Nat.dbl(x2, x3)))), Laws.nat_add_assoc(x0, x1, Nat.add(1n, U.U32Nat.dbl(x2, x3)))) : {_ == Nat.add(x0, 1n+Nat.add(x1, U.U32Nat.dbl(x2, x3))) : Nat}
2262  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, U.U32Nat.dbl(x2, x3))), Nat.add(1n, Nat.add(x1, U.U32Nat.dbl(x2, x3))), Laws.nat_add_left_comm(x1, 1n, U.U32Nat.dbl(x2, x3))) : {Nat.add(x0, _) == Nat.add(x0, 1n+Nat.add(x1, U.U32Nat.dbl(x2, x3))) : Nat}
2263  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Nat.add(1n, Nat.add(x0, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, U.U32Nat.dbl(x2, x3)))) : {_ == Nat.add(x0, 1n+Nat.add(x1, U.U32Nat.dbl(x2, x3))) : Nat}
2264  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Nat.add(x0, Nat.add(1n, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Nat.add(1n, Nat.add(x0, Nat.add(x1, U.U32Nat.dbl(x2, x3)))), Laws.nat_add_left_comm(x0, 1n, Nat.add(x1, U.U32Nat.dbl(x2, x3))))) : {_ == Nat.add(x0, 1n+Nat.add(x1, U.U32Nat.dbl(x2, x3))) : Nat}
2265  {==}
2266
2267def Laws.high_lt(k, j, m, x, e, h):
2268  Equal.trans(Bool, Nat.is_lt(U.U32Nat.high(k, x), U.U32Nat.dbl(j, 1n)), Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n))), True{}, Equal.sym(Bool, Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n))), Nat.is_lt(U.U32Nat.high(k, x), U.U32Nat.dbl(j, 1n)), Laws.dbl_lt(k, U.U32Nat.high(k, x), U.U32Nat.dbl(j, 1n))), Equal.trans(Bool, Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n))), Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x)))), True{}, Equal.sym(Bool, Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x)))), Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n))), Equal.cong(Nat, Bool, zz => Nat.is_lt(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), zz), Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x))), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n)), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x))), U.U32Nat.dbl(Nat.add(k, j), 1n), U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n)), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x))), U.U32Nat.dbl(m, 1n), U.U32Nat.dbl(Nat.add(k, j), 1n), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), 1n+x), U.U32Nat.dbl(m, 1n), Equal.trans(Nat, Nat.add(Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)), 1n+U.U32Nat.dbl(k, U.U32Nat.high(k, x))), Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), 1n+Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x)))), Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), 1n+x), ur.r44(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x), k, U.U32Nat.high(k, x)), Equal.cong(Nat, Nat, zz => Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), 1n+zz), Nat.add(U.U32Nat.low(k, x), U.U32Nat.dbl(k, U.U32Nat.high(k, x))), x, Laws.low_high(k, x))), Laws.nat_lt_witness(x, U.U32Nat.dbl(m, 1n), h)), Equal.cong(Nat, Nat, zz => U.U32Nat.dbl(zz, 1n), m, Nat.add(k, j), Equal.sym(Nat, Nat.add(k, j), m, e))), Equal.sym(Nat, U.U32Nat.dbl(k, U.U32Nat.dbl(j, 1n)), U.U32Nat.dbl(Nat.add(k, j), 1n), Laws.dbl_dbl(k, j, 1n))))), Laws.nat_lt_add(U.U32Nat.dbl(k, U.U32Nat.high(k, x)), Nat.add(Nat.sub(U.U32Nat.dbl(m, 1n), 1n+x), U.U32Nat.low(k, x)))))
2269
2270def ur.r45(+x0: Nat, +x1: Nat, +x2: Nat, +x3: Nat) -> {Nat.add(Nat.add(Nat.mul(x0, Nat.add(x1, 1n+x2)), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}:
2271  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, x2)), Nat.add(1n, Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, 1n, x2)) : {Nat.add(Nat.add(Nat.mul(x0, _), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2272  %Equal.sym(Nat, Nat.mul(x0, Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(x0, 1n), Nat.mul(x0, Nat.add(x1, x2))), Laws.nat_mul_add(x0, 1n, Nat.add(x1, x2))) : {Nat.add(Nat.add(_, Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2273  %Equal.sym(Nat, Nat.mul(x0, Nat.add(x1, x2)), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Laws.nat_mul_add(x0, x1, x2)) : {Nat.add(Nat.add(Nat.add(Nat.mul(x0, 1n), _), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2274  %Equal.sym(Nat, Nat.mul(x0, 1n), Nat.mul(1n, x0), Laws.nat_mul_comm(x0, 1n)) : {Nat.add(Nat.add(Nat.add(_, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2275  %Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0)) : {Nat.add(Nat.add(Nat.add(_, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x3, x1), x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2276  %Equal.sym(Nat, Nat.mul(x3, x1), Nat.mul(x1, x3), Laws.nat_mul_comm(x3, x1)) : {Nat.add(Nat.add(Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(x1, Nat.add(x2, Nat.add(_, x3)))), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2277  %Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x1, x3), x3)), Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)), Laws.nat_add_left_comm(x2, Nat.mul(x1, x3), x3)) : {Nat.add(Nat.add(Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(x1, _)), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2278  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))), Nat.add(x0, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))), Laws.nat_add_assoc(x0, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))) : {Nat.add(_, 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2279  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))), Laws.nat_add_assoc(Nat.mul(x0, x1), Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))) : {Nat.add(Nat.add(x0, _), 1n+Nat.mul(x3, x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2280  %Equal.sym(Nat, Nat.mul(x3, x2), Nat.mul(x2, x3), Laws.nat_mul_comm(x3, x2)) : {Nat.add(Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))))), Nat.add(1n, _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2281  %Equal.sym(Nat, Nat.add(Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))))), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(x0, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))), Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))), Nat.add(1n, Nat.mul(x2, x3)))) : {_ == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2282  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))))), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))), Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))), Nat.add(1n, Nat.mul(x2, x3)))) : {Nat.add(x0, _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2283  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)))), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))), Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))), Nat.add(1n, Nat.mul(x2, x3)))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2284  %Equal.sym(Nat, Nat.add(Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3))), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(x1, Nat.add(Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)), Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)), Nat.add(1n, Nat.mul(x2, x3)))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), _))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2285  %Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x1, x3), Nat.add(x2, x3)), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(Nat.mul(x1, x3), Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(Nat.mul(x1, x3), Nat.add(x2, x3), Nat.add(1n, Nat.mul(x2, x3)))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, _)))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2286  %Equal.sym(Nat, Nat.add(Nat.add(x2, x3), Nat.add(1n, Nat.mul(x2, x3))), Nat.add(x2, Nat.add(x3, Nat.add(1n, Nat.mul(x2, x3)))), Laws.nat_add_assoc(x2, x3, Nat.add(1n, Nat.mul(x2, x3)))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), _))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2287  %Equal.sym(Nat, Nat.add(x3, Nat.add(1n, Nat.mul(x2, x3))), Nat.add(1n, Nat.add(x3, Nat.mul(x2, x3))), Laws.nat_add_left_comm(x3, 1n, Nat.mul(x2, x3))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, _)))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2288  %Equal.sym(Nat, Nat.add(x3, Nat.mul(x2, x3)), Nat.add(Nat.mul(x2, x3), x3), Laws.nat_add_comm(x3, Nat.mul(x2, x3))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(1n, _))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2289  %Equal.sym(Nat, Nat.add(x2, Nat.add(1n, Nat.add(Nat.mul(x2, x3), x3))), Nat.add(1n, Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))), Laws.nat_add_left_comm(x2, 1n, Nat.add(Nat.mul(x2, x3), x3))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), _))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2290  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x3), Nat.add(1n, Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))), Nat.add(1n, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))), Laws.nat_add_left_comm(Nat.mul(x1, x3), 1n, Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, _)))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2291  %Equal.sym(Nat, Nat.add(x1, Nat.add(1n, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))), Nat.add(1n, Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))), Laws.nat_add_left_comm(x1, 1n, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), _))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2292  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x2), Nat.add(1n, Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))), Nat.add(1n, Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))), Laws.nat_add_left_comm(Nat.mul(x0, x2), 1n, Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))) : {Nat.add(x0, Nat.add(Nat.mul(x0, x1), _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2293  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(1n, Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))))), Nat.add(1n, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))))), Laws.nat_add_left_comm(Nat.mul(x0, x1), 1n, Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))))))) : {Nat.add(x0, _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2294  %Equal.sym(Nat, Nat.add(x0, Nat.add(1n, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))))), Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))))), Laws.nat_add_left_comm(x0, 1n, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3)))))))) : {_ == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2295  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))), Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))), Nat.add(Nat.mul(x1, x3), Nat.add(x2, Nat.add(Nat.mul(x2, x3), x3))), Laws.nat_add_left_comm(x2, Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))) : {Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x1, _))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2296  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))), Nat.add(x1, Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))), Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))), Nat.add(Nat.mul(x0, x2), Nat.add(x1, Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))), Laws.nat_add_left_comm(x1, Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))) : {Nat.add(1n, Nat.add(x0, Nat.add(Nat.mul(x0, x1), _))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2297  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x1, Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))), Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))), Equal.sym(Nat, Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))), Nat.add(Nat.mul(x0, x1), Nat.add(x1, Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))), Laws.nat_add_left_comm(x1, Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))))) : {Nat.add(1n, Nat.add(x0, _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2298  %Equal.sym(Nat, Nat.add(x0, Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))))), Nat.add(x1, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))))), Equal.sym(Nat, Nat.add(x1, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))))), Nat.add(x0, Nat.add(x1, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3))))))), Laws.nat_add_left_comm(x1, x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), Nat.add(Nat.mul(x2, x3), x3)))))))) : {Nat.add(1n, _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2299  %Equal.sym(Nat, Nat.add(Nat.mul(x2, x3), x3), Nat.add(x3, Nat.mul(x2, x3)), Equal.sym(Nat, Nat.add(x3, Nat.mul(x2, x3)), Nat.add(Nat.mul(x2, x3), x3), Laws.nat_add_comm(x3, Nat.mul(x2, x3)))) : {Nat.add(1n, Nat.add(x1, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(Nat.mul(x1, x3), _))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2300  %Equal.sym(Nat, Nat.add(Nat.mul(x1, x3), Nat.add(x3, Nat.mul(x2, x3))), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))), Equal.sym(Nat, Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))), Nat.add(Nat.mul(x1, x3), Nat.add(x3, Nat.mul(x2, x3))), Laws.nat_add_left_comm(x3, Nat.mul(x1, x3), Nat.mul(x2, x3)))) : {Nat.add(1n, Nat.add(x1, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x2, _)))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2301  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))), Nat.add(x2, Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))), Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))), Nat.add(Nat.mul(x0, x2), Nat.add(x2, Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))), Laws.nat_add_left_comm(x2, Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))) : {Nat.add(1n, Nat.add(x1, Nat.add(x0, Nat.add(Nat.mul(x0, x1), _)))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2302  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))), Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))), Equal.sym(Nat, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))), Nat.add(Nat.mul(x0, x1), Nat.add(x2, Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))), Laws.nat_add_left_comm(x2, Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))))) : {Nat.add(1n, Nat.add(x1, Nat.add(x0, _))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2303  %Equal.sym(Nat, Nat.add(x0, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))))), Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))))), Equal.sym(Nat, Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))))), Nat.add(x0, Nat.add(x2, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3))))))), Laws.nat_add_left_comm(x2, x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), Nat.mul(x2, x3)))))))) : {Nat.add(1n, Nat.add(x1, _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2304  %Equal.sym(Nat, Nat.mul(x2, x3), Nat.mul(x3, x2), Equal.sym(Nat, Nat.mul(x3, x2), Nat.mul(x2, x3), Laws.nat_mul_comm(x3, x2))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(Nat.mul(x1, x3), _)))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2305  %Equal.sym(Nat, Nat.mul(x1, x3), Nat.mul(x3, x1), Equal.sym(Nat, Nat.mul(x3, x1), Nat.mul(x1, x3), Laws.nat_mul_comm(x3, x1))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(x3, Nat.add(_, Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2306  %Equal.sym(Nat, x3, Nat.mul(1n, x3), Equal.sym(Nat, Nat.mul(1n, x3), x3, Laws.nat_one_mul(x3))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(_, Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2307  %Equal.sym(Nat, Nat.mul(1n, x3), Nat.mul(x3, 1n), Equal.sym(Nat, Nat.mul(x3, 1n), Nat.mul(1n, x3), Laws.nat_mul_comm(x3, 1n))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(x0, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(_, Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2308  %Equal.sym(Nat, x0, Nat.mul(1n, x0), Equal.sym(Nat, Nat.mul(1n, x0), x0, Laws.nat_one_mul(x0))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(_, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2309  %Equal.sym(Nat, Nat.mul(1n, x0), Nat.mul(x0, 1n), Equal.sym(Nat, Nat.mul(x0, 1n), Nat.mul(1n, x0), Laws.nat_mul_comm(x0, 1n))) : {Nat.add(1n, Nat.add(x1, Nat.add(x2, Nat.add(_, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2310  %Equal.sym(Nat, x2, Nat.mul(1n, x2), Equal.sym(Nat, Nat.mul(1n, x2), x2, Laws.nat_one_mul(x2))) : {Nat.add(1n, Nat.add(x1, Nat.add(_, Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2311  %Equal.sym(Nat, x1, Nat.mul(1n, x1), Equal.sym(Nat, Nat.mul(1n, x1), x1, Laws.nat_one_mul(x1))) : {Nat.add(1n, Nat.add(_, Nat.add(Nat.mul(1n, x2), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2312  %Equal.sym(Nat, Nat.add(Nat.mul(1n, x1), Nat.add(Nat.mul(1n, x2), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))))), Nat.add(Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))), Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))), Nat.add(Nat.mul(1n, x1), Nat.add(Nat.mul(1n, x2), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))))), Laws.nat_add_assoc(Nat.mul(1n, x1), Nat.mul(1n, x2), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) : {Nat.add(Nat.mul(1n, 1n), _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2313  %Equal.sym(Nat, Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))))), Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))), Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))), Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))))), Laws.nat_add_assoc(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))))))) : {_ == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2314  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))), Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))), Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))), Nat.add(Nat.mul(x0, x1), Nat.add(Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))), Laws.nat_add_assoc(Nat.mul(x0, x1), Nat.mul(x0, x2), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.mul(x0, 1n), _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2315  %Equal.sym(Nat, Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))), Nat.add(Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))), Equal.sym(Nat, Nat.add(Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))), Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2))))), Laws.nat_add_assoc(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.add(Nat.mul(x3, 1n), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)))))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2316  %Equal.sym(Nat, Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)), Nat.mul(x3, Nat.add(x1, x2)), Equal.sym(Nat, Nat.mul(x3, Nat.add(x1, x2)), Nat.add(Nat.mul(x3, x1), Nat.mul(x3, x2)), Laws.nat_mul_add(x3, x1, x2))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), Nat.add(Nat.mul(x3, 1n), _))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2317  %Equal.sym(Nat, Nat.add(Nat.mul(x3, 1n), Nat.mul(x3, Nat.add(x1, x2))), Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(x3, 1n), Nat.mul(x3, Nat.add(x1, x2))), Laws.nat_mul_add(x3, 1n, Nat.add(x1, x2)))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.add(Nat.mul(x0, 1n), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2))), _)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2318  %Equal.sym(Nat, Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Nat.mul(x0, Nat.add(x1, x2)), Equal.sym(Nat, Nat.mul(x0, Nat.add(x1, x2)), Nat.add(Nat.mul(x0, x1), Nat.mul(x0, x2)), Laws.nat_mul_add(x0, x1, x2))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(Nat.add(Nat.mul(x0, 1n), _), Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2319  %Equal.sym(Nat, Nat.add(Nat.mul(x0, 1n), Nat.mul(x0, Nat.add(x1, x2))), Nat.mul(x0, Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.mul(x0, Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(x0, 1n), Nat.mul(x0, Nat.add(x1, x2))), Laws.nat_mul_add(x0, 1n, Nat.add(x1, x2)))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), Nat.add(_, Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2))))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2320  %Equal.sym(Nat, Nat.add(Nat.mul(x0, Nat.add(1n, Nat.add(x1, x2))), Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2)))), Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(x0, Nat.add(1n, Nat.add(x1, x2))), Nat.mul(x3, Nat.add(1n, Nat.add(x1, x2)))), Laws.nat_add_mul(x0, x3, Nat.add(1n, Nat.add(x1, x2))))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2))), _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2321  %Equal.sym(Nat, Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Nat.mul(1n, Nat.add(x1, x2)), Equal.sym(Nat, Nat.mul(1n, Nat.add(x1, x2)), Nat.add(Nat.mul(1n, x1), Nat.mul(1n, x2)), Laws.nat_mul_add(1n, x1, x2))) : {Nat.add(Nat.add(Nat.mul(1n, 1n), _), Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2)))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2322  %Equal.sym(Nat, Nat.add(Nat.mul(1n, 1n), Nat.mul(1n, Nat.add(x1, x2))), Nat.mul(1n, Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.mul(1n, Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(1n, 1n), Nat.mul(1n, Nat.add(x1, x2))), Laws.nat_mul_add(1n, 1n, Nat.add(x1, x2)))) : {Nat.add(_, Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2)))) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2323  %Equal.sym(Nat, Nat.add(Nat.mul(1n, Nat.add(1n, Nat.add(x1, x2))), Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2)))), Nat.mul(Nat.add(1n, Nat.add(x0, x3)), Nat.add(1n, Nat.add(x1, x2))), Equal.sym(Nat, Nat.mul(Nat.add(1n, Nat.add(x0, x3)), Nat.add(1n, Nat.add(x1, x2))), Nat.add(Nat.mul(1n, Nat.add(1n, Nat.add(x1, x2))), Nat.mul(Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2)))), Laws.nat_add_mul(1n, Nat.add(x0, x3), Nat.add(1n, Nat.add(x1, x2))))) : {_ == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2324  %Equal.sym(Nat, Nat.add(1n, Nat.add(x1, x2)), Nat.add(x1, Nat.add(1n, x2)), Equal.sym(Nat, Nat.add(x1, Nat.add(1n, x2)), Nat.add(1n, Nat.add(x1, x2)), Laws.nat_add_left_comm(x1, 1n, x2))) : {Nat.mul(Nat.add(1n, Nat.add(x0, x3)), _) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2325  %Equal.sym(Nat, Nat.add(1n, Nat.add(x0, x3)), Nat.add(x0, Nat.add(1n, x3)), Equal.sym(Nat, Nat.add(x0, Nat.add(1n, x3)), Nat.add(1n, Nat.add(x0, x3)), Laws.nat_add_left_comm(x0, 1n, x3))) : {Nat.mul(_, Nat.add(x1, 1n+x2)) == Nat.mul(Nat.add(x0, 1n+x3), Nat.add(x1, 1n+x2)) : Nat}
2326  {==}
2327
2328def Laws.nat_mul_lt(a, b, c, d, h1, h2):
2329  Equal.trans(Bool, Nat.is_lt(Nat.mul(a, b), Nat.mul(c, d)), Nat.is_lt(Nat.mul(a, b), Nat.add(Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a)))), 1n+Nat.mul(a, b))), True{}, Equal.sym(Bool, Nat.is_lt(Nat.mul(a, b), Nat.add(Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a)))), 1n+Nat.mul(a, b))), Nat.is_lt(Nat.mul(a, b), Nat.mul(c, d)), Equal.cong(Nat, Bool, zz => Nat.is_lt(Nat.mul(a, b), zz), Nat.add(Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a)))), 1n+Nat.mul(a, b)), Nat.mul(c, d), Equal.trans(Nat, Nat.add(Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a)))), 1n+Nat.mul(a, b)), Nat.mul(c, Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.mul(c, d), Equal.trans(Nat, Nat.add(Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a)))), 1n+Nat.mul(a, b)), Nat.mul(Nat.add(Nat.sub(c, 1n+a), 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.mul(c, Nat.add(Nat.sub(d, 1n+b), 1n+b)), ur.r45(Nat.sub(c, 1n+a), Nat.sub(d, 1n+b), b, a), Equal.cong(Nat, Nat, zz => Nat.mul(zz, Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(c, 1n+a), 1n+a), c, Laws.nat_lt_witness(a, c, h1))), Equal.cong(Nat, Nat, zz => Nat.mul(c, zz), Nat.add(Nat.sub(d, 1n+b), 1n+b), d, Laws.nat_lt_witness(b, d, h2))))), Laws.nat_lt_add(Nat.mul(a, b), Nat.add(Nat.mul(Nat.sub(c, 1n+a), Nat.add(Nat.sub(d, 1n+b), 1n+b)), Nat.add(Nat.sub(d, 1n+b), Nat.add(b, Nat.add(Nat.mul(a, Nat.sub(d, 1n+b)), a))))))
2330
2331def Laws.nat_le_dbl(k, x):
2332  match k:
2333    case 0n:
2334      Laws.nat_le_refl(x)
2335    case 1n+ +j:
2336      un.le_trans(x, U.U32Nat.dbl(j, x), Nat.double(U.U32Nat.dbl(j, x)), Laws.nat_le_dbl(j, x), un.le_double(U.U32Nat.dbl(j, x)))
2337
2338def Laws.dbl_le_exp(j, k, x, h):
2339  Equal.trans(Bool, Nat.is_le(U.U32Nat.dbl(j, x), U.U32Nat.dbl(k, x)), Nat.is_le(U.U32Nat.dbl(j, x), U.U32Nat.dbl(Nat.sub(k, j), U.U32Nat.dbl(j, x))), True{}, Equal.sym(Bool, Nat.is_le(U.U32Nat.dbl(j, x), U.U32Nat.dbl(Nat.sub(k, j), U.U32Nat.dbl(j, x))), Nat.is_le(U.U32Nat.dbl(j, x), U.U32Nat.dbl(k, x)), Equal.cong(Nat, Bool, zz => Nat.is_le(U.U32Nat.dbl(j, x), zz), U.U32Nat.dbl(Nat.sub(k, j), U.U32Nat.dbl(j, x)), U.U32Nat.dbl(k, x), Equal.trans(Nat, U.U32Nat.dbl(Nat.sub(k, j), U.U32Nat.dbl(j, x)), U.U32Nat.dbl(Nat.add(Nat.sub(k, j), j), x), U.U32Nat.dbl(k, x), Laws.dbl_dbl(Nat.sub(k, j), j, x), Equal.cong(Nat, Nat, zz => U.U32Nat.dbl(zz, x), Nat.add(Nat.sub(k, j), j), k, Laws.nat_le_witness(j, k, h))))), Laws.nat_le_dbl(Nat.sub(k, j), U.U32Nat.dbl(j, x)))
2340
2341def Laws.divstep_value(n, s, b, r, a, r1, t, l, g, e, el, eg, er, ha, hr, hb):
2342  ud.p1(Nat.add(r1, Nat.mul(U.U32Nat.bit(g), b)), Nat.add(a, Nat.double(r)), r1, b, ud.k(n, s, b, r, a, r1, t, l, g, e, el, eg, er, ha, hr, hb))
2343
2344def Laws.divstep_lt(n, s, b, r, a, r1, t, l, g, e, el, eg, er, ha, hr, hb):
2345  ud.p2(Nat.add(r1, Nat.mul(U.U32Nat.bit(g), b)), Nat.add(a, Nat.double(r)), r1, b, ud.k(n, s, b, r, a, r1, t, l, g, e, el, eg, er, ha, hr, hb))