main.bend
bend-ml-nat-lemmas@0.1.2.0 · 288 lines · 19 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import Base
16
17
18
19def product(xs: List<&2, Nat>) -> Nat:
20 match xs:
21 case Nil{}:
22 1n
23 case Con{h, t}:
24 Nat.mul(h, product(t))
25
26
27law add_zero:
28 for a: Nat
29 {Nat.add(a, 0n) == a : Nat}
30
31
32
33def add_zero(a):
34 match a:
35 case 0n:
36 {==}
37 case 1n+p:
38 %add_zero(p) : {1n+Nat.add(p, 0n) == 1n+_ : Nat}
39 {==}
40
41law add_succ:
42 for a: Nat
43 for -b: Nat
44 {1n+Nat.add(a, b) == Nat.add(a, 1n+b) : Nat}
45
46
47def add_succ(a, b):
48 match a:
49 case 0n:
50 {==}
51 case 1n+p:
52 %add_succ(p, b) : {2n+Nat.add(p, b) == 1n+_ : Nat}
53 {==}
54
55law add_comm:
56 for a: Nat
57 for +b: Nat
58 {Nat.add(a, b) == Nat.add(b, a) : Nat}
59
60
61def add_comm(a, b):
62 match a:
63 case 0n:
64 %add_zero(b) : {_ == Nat.add(b, 0n) : Nat}
65 {==}
66 case 1n+p:
67 %add_succ(b, p) : {1n+Nat.add(p, b) == _ : Nat}
68 %add_comm(p, b) : {1n+Nat.add(p, b) == 1n+_ : Nat}
69 {==}
70
71law add_assoc:
72 for a: Nat
73 for -b: Nat
74 for -c: Nat
75 {Nat.add(a, Nat.add(b, c)) == Nat.add(Nat.add(a, b), c) : Nat}
76
77
78def add_assoc(a, b, c):
79 match a:
80 case 0n:
81 {==}
82 case 1n+p:
83 %add_assoc(p, b, c) : {1n+Nat.add(p, Nat.add(b, c)) == 1n+_ : Nat}
84 {==}
85
86law mul_zero:
87 for a: Nat
88 {Nat.mul(a, 0n) == 0n : Nat}
89
90
91def mul_zero(a):
92 match a:
93 case 0n:
94 {==}
95 case 1n+p:
96 mul_zero(p)
97
98
99
100def add_swap(x: Nat, +y: Nat, +z: Nat) -> {Nat.add(x, Nat.add(y, z)) == Nat.add(y, Nat.add(x, z)) : Nat}:
101 match x:
102 case 0n:
103 {==}
104 case 1n+q:
105 %add_succ(y, Nat.add(q, z)) : {1n+Nat.add(q, Nat.add(y, z)) == _ : Nat}
106 %add_swap(q, y, z) : {1n+Nat.add(q, Nat.add(y, z)) == 1n+_ : Nat}
107 {==}
108
109law mul_succ:
110 for +a: Nat
111 for +b: Nat
112 {Nat.mul(a, 1n+b) == Nat.add(a, Nat.mul(a, b)) : Nat}
113
114
115def mul_succ(a, b):
116 match a:
117 case 0n:
118 {==}
119 case 1n++p:
120 %Equal.sym(Nat, Nat.mul(p, 1n+b), Nat.add(p, Nat.mul(p, b)), mul_succ(p, b)) : {1n+Nat.add(b, _) == 1n+Nat.add(p, Nat.add(b, Nat.mul(p, b))) : Nat}
121 %add_swap(b, p, Nat.mul(p, b)) : {1n+Nat.add(b, Nat.add(p, Nat.mul(p, b))) == 1n+_ : Nat}
122 {==}
123
124law mul_comm:
125 for +a: Nat
126 for +b: Nat
127 {Nat.mul(a, b) == Nat.mul(b, a) : Nat}
128
129
130def mul_comm(a, b):
131 match a:
132 case 0n:
133 %mul_zero(b) : {_ == Nat.mul(b, 0n) : Nat}
134 {==}
135 case 1n++p:
136 %Equal.sym(Nat, Nat.mul(b, 1n+p), Nat.add(b, Nat.mul(b, p)), mul_succ(b, p)) : {Nat.add(b, Nat.mul(p, b)) == _ : Nat}
137 %mul_comm(p, b) : {Nat.add(b, Nat.mul(p, b)) == Nat.add(b, _) : Nat}
138 {==}
139
140law mul_dist:
141 for a: Nat
142 for -b: Nat
143 for +c: Nat
144 {Nat.add(Nat.mul(a, c), Nat.mul(b, c)) == Nat.mul(Nat.add(a, b), c) : Nat}
145
146
147def mul_dist(a, b, c):
148 match a:
149 case 0n:
150 {==}
151 case 1n+p:
152 %mul_dist(p, b, c) : {Nat.add(Nat.add(c, Nat.mul(p, c)), Nat.mul(b, c)) == Nat.add(c, _) : Nat}
153 %add_assoc(c, Nat.mul(p, c), Nat.mul(b, c)) : {_ == Nat.add(c, Nat.add(Nat.mul(p, c), Nat.mul(b, c))) : Nat}
154 {==}
155
156law mul_assoc:
157 for +a: Nat
158 for +b: Nat
159 for +c: Nat
160 {Nat.mul(a, Nat.mul(b, c)) == Nat.mul(Nat.mul(a, b), c) : Nat}
161
162
163
164
165def mul_assoc(a, b, c):
166 match a:
167 case 0n:
168 {==}
169 case 1n++p:
170 %Equal.sym(Nat, Nat.mul(p, Nat.mul(b, c)), Nat.mul(Nat.mul(p, b), c), mul_assoc(p, b, c)) : {Nat.add(Nat.mul(b, c), _) == Nat.mul(Nat.add(b, Nat.mul(p, b)), c) : Nat}
171 mul_dist(b, Nat.mul(p, b), c)
172
173law add4:
174 for +a: Nat
175 for +b: Nat
176 for +c: Nat
177 for +d: Nat
178 {Nat.add(Nat.add(a, b), Nat.add(c, d)) == Nat.add(Nat.add(a, c), Nat.add(b, d)) : Nat}
179
180
181
182def add4(a, b, c, d):
183 Equal.trans(Nat, Nat.add(Nat.add(a, b), Nat.add(c, d)), Nat.add(a, Nat.add(b, Nat.add(c, d))), Nat.add(Nat.add(a, c), Nat.add(b, d)),
184 Equal.sym(Nat, Nat.add(a, Nat.add(b, Nat.add(c, d))), Nat.add(Nat.add(a, b), Nat.add(c, d)), add_assoc(a, b, Nat.add(c, d))),
185 Equal.trans(Nat, Nat.add(a, Nat.add(b, Nat.add(c, d))), Nat.add(a, Nat.add(c, Nat.add(b, d))), Nat.add(Nat.add(a, c), Nat.add(b, d)),
186 Equal.cong(Nat, Nat, s => Nat.add(a, s), Nat.add(b, Nat.add(c, d)), Nat.add(c, Nat.add(b, d)), add_swap(b, c, d)),
187 add_assoc(a, c, Nat.add(b, d))))
188
189law mul_dist_l:
190 for +k: Nat
191 for +a: Nat
192 for +b: Nat
193 {Nat.mul(k, Nat.add(a, b)) == Nat.add(Nat.mul(k, a), Nat.mul(k, b)) : Nat}
194
195
196
197def mul_dist_l(k, a, b):
198 Equal.trans(Nat, Nat.mul(k, Nat.add(a, b)), Nat.mul(Nat.add(a, b), k), Nat.add(Nat.mul(k, a), Nat.mul(k, b)),
199 mul_comm(k, Nat.add(a, b)),
200 Equal.trans(Nat, Nat.mul(Nat.add(a, b), k), Nat.add(Nat.mul(a, k), Nat.mul(b, k)), Nat.add(Nat.mul(k, a), Nat.mul(k, b)),
201 Equal.sym(Nat, Nat.add(Nat.mul(a, k), Nat.mul(b, k)), Nat.mul(Nat.add(a, b), k), mul_dist(a, b, k)),
202 Equal.trans(Nat, Nat.add(Nat.mul(a, k), Nat.mul(b, k)), Nat.add(Nat.mul(k, a), Nat.mul(b, k)), Nat.add(Nat.mul(k, a), Nat.mul(k, b)),
203 Equal.cong(Nat, Nat, s => Nat.add(s, Nat.mul(b, k)), Nat.mul(a, k), Nat.mul(k, a), mul_comm(a, k)),
204 Equal.cong(Nat, Nat, s => Nat.add(Nat.mul(k, a), s), Nat.mul(b, k), Nat.mul(k, b), mul_comm(b, k)))))
205
206law mul_one_l:
207 for +a: Nat
208 {Nat.mul(1n, a) == a : Nat}
209
210
211
212def mul_one_l(a):
213 add_zero(a)
214
215law mul_one_r:
216 for +a: Nat
217 {Nat.mul(a, 1n) == a : Nat}
218
219
220def mul_one_r(a):
221 match a:
222 case 0n:
223 {==}
224 case 1n++p:
225 %mul_one_r(p) : {1n+Nat.mul(p, 1n) == 1n+_ : Nat}
226 {==}
227
228law append_nil:
229 for -A: Data
230 for xs: List<&2, A>
231 {List.append(&2, A, xs, Nil{}) == xs : List<&2, A>}
232
233
234def append_nil(A, xs):
235 match xs:
236 case Nil{}:
237 {==}
238 case Con{h, t}:
239 %append_nil(A, t) : {Con{h, List.append(&2, A, t, Nil{})} == Con{h, _} : List<&2, A>}
240 {==}
241
242law append_assoc:
243 for -A: Data
244 for xs: List<&2, A>
245 for ys: List<&2, A>
246 for zs: List<&2, A>
247 {List.append(&2, A, List.append(&2, A, xs, ys), zs) == List.append(&2, A, xs, List.append(&2, A, ys, zs)) : List<&2, A>}
248
249
250def append_assoc(A, xs, ys, zs):
251 match xs:
252 case Nil{}:
253 {==}
254 case Con{h, t}:
255 %append_assoc(A, t, ys, zs) : {Con{h, List.append(&2, A, List.append(&2, A, t, ys), zs)} == Con{h, _} : List<&2, A>}
256 {==}
257
258law length_append:
259 for -A: Data
260 for xs: List<&2, A>
261 for ys: List<&2, A>
262 {List.length(&2, A, List.append(&2, A, xs, ys)) == Nat.add(List.length(&2, A, xs), List.length(&2, A, ys)) : Nat}
263
264
265def length_append(A, xs, ys):
266 match xs:
267 case Nil{}:
268 {==}
269 case Con{h, t}:
270 %length_append(A, t, ys) : {1n+List.length(&2, A, List.append(&2, A, t, ys)) == 1n+_ : Nat}
271 {==}
272
273law product_append:
274 for +xs: List<&2, Nat>
275 for +ys: List<&2, Nat>
276 {product(List.append(&2, Nat, xs, ys)) == Nat.mul(product(xs), product(ys)) : Nat}
277
278
279
280
281
282def product_append(xs, ys):
283 match xs:
284 case Nil{}:
285 Equal.sym(Nat, Nat.mul(1n, product(ys)), product(ys), mul_one_l(product(ys)))
286 case Con{+h, +t}:
287 %Equal.sym(Nat, product(List.append(&2, Nat, t, ys)), Nat.mul(product(t), product(ys)), product_append(t, ys)) : {Nat.mul(h, _) == Nat.mul(Nat.mul(h, product(t)), product(ys)) : Nat}
288 mul_assoc(h, product(t), product(ys))