]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/lib/arithmetics/nat.ma
81d6c9310247dc42c5f2d0d76e66a986ae1d45fc
[helm.git] / matita / matita / lib / arithmetics / nat.ma
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department of the University of Bologna, Italy.                     
5     ||I||                                                                 
6     ||T||  
7     ||A||  This file is distributed under the terms of the 
8     \   /  GNU General Public License Version 2        
9      \ /      
10       V_______________________________________________________________ *)
11
12 include "basics/relations.ma".
13
14 (* Definitions **************************************************************)
15
16 (* natural numbers *)
17
18 inductive nat : Type[0] ≝
19   | O : nat
20   | S : nat → nat.
21   
22 interpretation "Natural numbers" 'N = nat.
23
24 alias num (instance 0) = "natural number".
25
26 definition pred ≝
27  λn. match n with [ O ⇒ O | S p ⇒ p].
28
29 definition not_zero: nat → Prop ≝
30  λn: nat. match n with [ O ⇒ False | (S p) ⇒ True ].
31
32 (* order relations *)
33
34 inductive le (n:nat) : nat → Prop ≝
35   | le_n : le n n
36   | le_S : ∀ m:nat. le n m → le n (S m).
37
38 interpretation "natural 'less or equal to'" 'leq x y = (le x y).
39
40 interpretation "natural 'neither less nor equal to'" 'nleq x y = (Not (le x y)).
41
42 definition lt: nat → nat → Prop ≝ λn,m. S n ≤ m.
43
44 interpretation "natural 'less than'" 'lt x y = (lt x y).
45
46 interpretation "natural 'not less than'" 'nless x y = (Not (lt x y)).
47
48 definition ge: nat → nat → Prop ≝ λn,m.m ≤ n.
49
50 interpretation "natural 'greater or equal to'" 'geq x y = (ge x y).
51
52 definition gt: nat → nat → Prop ≝ λn,m.m<n.
53
54 interpretation "natural 'greater than'" 'gt x y = (gt x y).
55
56 interpretation "natural 'not greater than'" 'ngtr x y = (Not (gt x y)).
57
58 (* abstract properties *)
59
60 definition increasing ≝ λf:nat → nat. ∀n:nat. f n < f (S n).
61
62 (* arithmetic operations *)
63
64 let rec plus n m ≝ 
65  match n with [ O ⇒ m | S p ⇒ S (plus p m) ].
66
67 interpretation "natural plus" 'plus x y = (plus x y).
68
69 let rec times n m ≝ 
70  match n with [ O ⇒ 0 | S p ⇒ m + (times p m) ].
71
72 interpretation "natural times" 'times x y = (times x y).
73
74 let rec minus n m ≝ 
75  match n with 
76  [ O ⇒ O
77  | S p ⇒ 
78         match m with
79           [ O ⇒ S p
80     | S q ⇒ minus p q ]].
81         
82 interpretation "natural minus" 'minus x y = (minus x y).
83
84 (* Generic conclusion ******************************************************)
85
86 theorem nat_case:
87  ∀n:nat.∀P:nat → Prop. 
88   (n=O → P O) → (∀m:nat. n= S m → P (S m)) → P n.
89 #n #P (elim n) /2/ qed.
90
91 theorem nat_elim2 :
92  ∀R:nat → nat → Prop.
93   (∀n:nat. R O n) 
94   → (∀n:nat. R (S n) O)
95   → (∀n,m:nat. R n m → R (S n) (S m))
96   → ∀n,m:nat. R n m.
97 #R #ROn #RSO #RSS #n (elim n) // #n0 #Rn0m #m (cases m) /2/ qed.
98
99 lemma le_gen: ∀P:nat → Prop.∀n.(∀i. i ≤ n → P i) → P n.
100 /2/ qed.
101
102 (* Equalities ***************************************************************)
103
104 theorem pred_Sn : ∀n. n = pred (S n).
105 // qed.
106
107 theorem injective_S : injective nat nat S.
108 // qed.
109
110 theorem S_pred: ∀n. 0 < n → S(pred n) = n.
111 #n #posn (cases posn) //
112 qed.
113
114 theorem plus_O_n: ∀n:nat. n = 0 + n.
115 // qed.
116
117 theorem plus_n_O: ∀n:nat. n = n + 0.
118 #n (elim n) normalize // qed.
119
120 theorem plus_n_Sm : ∀n,m:nat. S (n+m) = n + S m.
121 #n (elim n) normalize // qed.
122
123 theorem commutative_plus: commutative ? plus.
124 #n (elim n) normalize // qed. 
125
126 theorem associative_plus : associative nat plus.
127 #n (elim n) normalize // qed.
128
129 theorem assoc_plus1: ∀a,b,c. c + (b + a) = b + c + a.
130 // qed. 
131
132 theorem injective_plus_r: ∀n:nat.injective nat nat (λm.n+m).
133 #n (elim n) normalize /3/ qed.
134
135 theorem injective_plus_l: ∀n:nat.injective nat nat (λm.m+n). 
136 /2/ qed.
137
138 theorem not_eq_S: ∀n,m:nat. n ≠ m → S n ≠ S m.
139 /2/ qed.
140
141 theorem times_Sn_m: ∀n,m:nat. m+n*m = S n*m.
142 // qed.
143
144 theorem times_O_n: ∀n:nat. 0 = 0 * n.
145 // qed.
146
147 theorem times_n_O: ∀n:nat. 0 = n * 0.
148 #n (elim n) // qed.
149
150 theorem times_n_Sm : ∀n,m:nat. n+(n*m) = n*(S m).
151 #n (elim n) normalize // qed.
152
153 theorem commutative_times : commutative nat times. 
154 #n (elim n) normalize // qed. 
155
156 theorem distributive_times_plus : distributive nat times plus.
157 #n (elim n) normalize // qed.
158
159 theorem distributive_times_plus_r :
160   ∀a,b,c:nat. (b+c)*a = b*a + c*a.
161 // qed. 
162
163 theorem associative_times: associative nat times.
164 #n (elim n) normalize // qed.
165
166 lemma times_times: ∀x,y,z. x*(y*z) = y*(x*z).
167 // qed. 
168
169 theorem times_n_1 : ∀n:nat. n = n * 1.
170 #n // qed.
171
172 theorem minus_S_S: ∀n,m:nat.S n - S m = n -m.
173 // qed.
174
175 theorem minus_O_n: ∀n:nat.0=0-n.
176 #n (cases n) // qed.
177
178 theorem minus_n_O: ∀n:nat.n=n-0.
179 #n (cases n) // qed.
180
181 theorem minus_n_n: ∀n:nat.0=n-n.
182 #n (elim n) // qed.
183
184 theorem minus_Sn_n: ∀n:nat. S 0 = (S n)-n.
185 #n (elim n) normalize // qed.
186
187 theorem eq_minus_S_pred: ∀n,m. n - (S m) = pred(n -m).
188 @nat_elim2 normalize // qed.
189
190 lemma plus_plus_comm_23: ∀x,y,z. x + y + z = x + z + y.
191 // qed.
192
193 (* Negated equalities *******************************************************)
194
195 theorem not_eq_O_S : ∀n:nat. 0 ≠ S n.
196 #n @nmk #eqOS (change with (not_zero O)) >eqOS // qed.
197
198 theorem not_eq_n_Sn: ∀n:nat. n ≠ S n.
199 #n (elim n) /2/ qed.
200
201 (* Atomic conclusion *******************************************************)
202
203 (* not_zero *)
204
205 theorem lt_to_not_zero : ∀n,m:nat. n < m → not_zero m.
206 #n #m #Hlt (elim Hlt) // qed.
207
208 (* le *)
209
210 theorem le_S_S: ∀n,m:nat. n ≤ m → S n ≤ S m.
211 #n #m #lenm (elim lenm) /2/ qed.
212
213 theorem le_O_n : ∀n:nat. 0 ≤ n.
214 #n (elim n) /2/ qed.
215
216 theorem le_n_Sn : ∀n:nat. n ≤ S n.
217 /2/ qed.
218
219 theorem transitive_le : transitive nat le.
220 #a #b #c #leab #lebc (elim lebc) /2/
221 qed.
222
223 theorem le_pred_n : ∀n:nat. pred n ≤ n.
224 #n (elim n) // qed.
225
226 theorem monotonic_pred: monotonic ? le pred.
227 #n #m #lenm (elim lenm) /2/ qed.
228
229 theorem le_S_S_to_le: ∀n,m:nat. S n ≤ S m → n ≤ m.
230 (* demo *)
231 /2/ qed-.
232
233 theorem monotonic_le_plus_r: 
234 ∀n:nat.monotonic nat le (λm.n + m).
235 #n #a #b (elim n) normalize //
236 #m #H #leab @le_S_S /2/ qed.
237
238 theorem monotonic_le_plus_l: 
239 ∀m:nat.monotonic nat le (λn.n + m).
240 /2/ qed.
241
242 theorem le_plus: ∀n1,n2,m1,m2:nat. n1 ≤ n2  → m1 ≤ m2 
243 → n1 + m1 ≤ n2 + m2.
244 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1+m2))
245 /2/ qed-.
246
247 theorem le_plus_n :∀n,m:nat. m ≤ n + m.
248 /2/ qed. 
249
250 lemma le_plus_a: ∀a,n,m. n ≤ m → n ≤ a + m.
251 /2/ qed.
252
253 lemma le_plus_b: ∀b,n,m. n + b ≤ m → n ≤ m.
254 /2/ qed.
255
256 theorem le_plus_n_r :∀n,m:nat. m ≤ m + n.
257 /2/ qed.
258
259 theorem eq_plus_to_le: ∀n,m,p:nat.n=m+p → m ≤ n.
260 // qed-.
261
262 theorem le_plus_to_le: ∀a,n,m. a + n ≤ a + m → n ≤ m.
263 #a (elim a) normalize /3/ qed. 
264
265 theorem le_plus_to_le_r: ∀a,n,m. n + a ≤ m +a → n ≤ m.
266 /2/ qed-. 
267
268 theorem monotonic_le_times_r: 
269 ∀n:nat.monotonic nat le (λm. n * m).
270 #n #x #y #lexy (elim n) normalize//(* lento /2/*)
271 #a #lea @le_plus //
272 qed.
273
274 theorem le_times: ∀n1,n2,m1,m2:nat. 
275 n1 ≤ n2  → m1 ≤ m2 → n1*m1 ≤ n2*m2.
276 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1*m2)) /2/
277 qed.
278
279 (* interessante *)
280 theorem lt_times_n: ∀n,m:nat. O < n → m ≤ n*m.
281 #n #m #H /2/ qed.
282
283 theorem le_times_to_le: 
284 ∀a,n,m. O < a → a * n ≤ a * m → n ≤ m.
285 #a @nat_elim2 normalize
286   [//
287   |#n #H1 #H2 
288      @(transitive_le ? (a*S n)) /2/
289   |#n #m #H #lta #le
290      @le_S_S @H /2/
291   ]
292 qed-.
293
294 theorem le_plus_minus_m_m: ∀n,m:nat. n ≤ (n-m)+m.
295 #n (elim n) // #a #Hind #m (cases m) // normalize #n/2/  
296 qed.
297
298 theorem le_plus_to_minus_r: ∀a,b,c. a + b ≤ c → a ≤ c -b.
299 #a #b #c #H @(le_plus_to_le_r … b) /2/
300 qed.
301
302 (* lt *)
303
304 theorem transitive_lt: transitive nat lt.
305 #a #b #c #ltab #ltbc (elim ltbc) /2/
306 qed.
307
308 theorem lt_to_le_to_lt: ∀n,m,p:nat. n < m → m ≤ p → n < p.
309 #n #m #p #H #H1 (elim H1) /2/ qed.
310
311 theorem le_to_lt_to_lt: ∀n,m,p:nat. n ≤ m → m < p → n < p.
312 #n #m #p #H (elim H) /3/ qed.
313
314 theorem lt_S_to_lt: ∀n,m. S n < m → n < m.
315 /2/ qed.
316
317 theorem ltn_to_ltO: ∀n,m:nat. n < m → 0 < m.
318 /2/ qed.
319
320 theorem lt_O_S : ∀n:nat. O < S n.
321 /2/ qed.
322
323 theorem monotonic_lt_plus_r: 
324 ∀n:nat.monotonic nat lt (λm.n+m).
325 /2/ qed.
326
327 theorem monotonic_lt_plus_l: 
328 ∀n:nat.monotonic nat lt (λm.m+n).
329 /2/ qed.
330
331 theorem lt_plus: ∀n,m,p,q:nat. n < m → p < q → n + p < m + q.
332 #n #m #p #q #ltnm #ltpq
333 @(transitive_lt ? (n+q))/2/ qed.
334
335 theorem lt_plus_to_lt_l :∀n,p,q:nat. p+n < q+n → p<q.
336 /2/ qed.
337
338 theorem lt_plus_to_lt_r :∀n,p,q:nat. n+p < n+q → p<q.
339 /2/ qed-.
340
341 theorem increasing_to_monotonic: ∀f:nat → nat.
342   increasing f → monotonic nat lt f.
343 #f #incr #n #m #ltnm (elim ltnm) /2/
344 qed.
345
346 theorem monotonic_lt_times_r: 
347   ∀c:nat. O < c → monotonic nat lt (λt.(c*t)).
348 #c #posc #n #m #ltnm
349 (elim ltnm) normalize
350   [/2/ 
351   |#a #_ #lt1 @(transitive_le … lt1) //
352   ]
353 qed.
354
355 theorem monotonic_lt_times_l: 
356   ∀c:nat. 0 < c → monotonic nat lt (λt.(t*c)).
357 /2/
358 qed.
359
360 theorem lt_to_le_to_lt_times: 
361 ∀n,m,p,q:nat. n < m → p ≤ q → O < q → n*p < m*q.
362 #n #m #p #q #ltnm #lepq #posq
363 @(le_to_lt_to_lt ? (n*q))
364   [@monotonic_le_times_r //
365   |@monotonic_lt_times_l //
366   ]
367 qed.
368
369 theorem lt_times:∀n,m,p,q:nat. n<m → p<q → n*p < m*q.
370 #n #m #p #q #ltnm #ltpq @lt_to_le_to_lt_times/2/
371 qed.
372
373 theorem lt_plus_to_minus_r: ∀a,b,c. a + b < c → a < c - b.
374 #a #b #c #H @le_plus_to_minus_r //
375 qed.
376
377 lemma lt_plus_Sn_r: ∀a,x,n. a < a + x + (S n).
378 /2 width=1/ qed.
379
380 theorem lt_S_S_to_lt: ∀n,m:nat. S n < S m → n < m.
381 (* demo *)
382 /2/ qed-.
383
384 (* not le, lt *)
385
386 theorem not_le_Sn_O: ∀ n:nat. S n ≰ 0.
387 #n @nmk #Hlen0 @(lt_to_not_zero ?? Hlen0) qed.
388
389 theorem not_le_to_not_le_S_S: ∀ n,m:nat. n ≰ m → S n ≰ S m.
390 /3/ qed.
391
392 theorem not_le_S_S_to_not_le: ∀ n,m:nat. S n ≰ S m → n ≰ m.
393 /3/ qed.
394
395 theorem not_le_Sn_n: ∀n:nat. S n ≰ n.
396 #n (elim n) /2/ qed.
397
398 theorem lt_to_not_le: ∀n,m. n < m → m ≰ n.
399 #n #m #Hltnm (elim Hltnm) /3/ qed.
400
401 theorem not_le_to_lt: ∀n,m. n ≰ m → m < n.
402 @nat_elim2 #n
403  [#abs @False_ind /2/
404  |/2/
405  |#m #Hind #HnotleSS @le_S_S /3/
406  ]
407 qed.
408
409 (* not lt, le *)
410
411 theorem not_lt_to_le: ∀n,m:nat. n ≮ m → m ≤ n.
412 /4/ qed.
413
414 theorem le_to_not_lt: ∀n,m:nat. n ≤ m → m ≮ n.
415 #n #m #H @lt_to_not_le /2/ (* /3/ *) qed.
416
417 (* Compound conclusion ******************************************************)
418
419 theorem decidable_eq_nat : ∀n,m:nat.decidable (n=m).
420 @nat_elim2 #n [ (cases n) /2/ | /3/ | #m #Hind (cases Hind) /3/]
421 qed. 
422
423 theorem decidable_le: ∀n,m. decidable (n≤m).
424 @nat_elim2 #n /2/ #m * /3/ qed.
425
426 theorem decidable_lt: ∀n,m. decidable (n < m).
427 #n #m @decidable_le  qed.
428
429 theorem le_to_or_lt_eq: ∀n,m:nat. n ≤ m → n < m ∨ n = m.
430 #n #m #lenm (elim lenm) /3/ qed.
431
432 theorem increasing_to_le2: ∀f:nat → nat. increasing f → 
433   ∀m:nat. f 0 ≤ m → ∃i. f i ≤ m ∧ m < f (S i).
434 #f #incr #m #lem (elim lem)
435   [@(ex_intro ? ? O) /2/
436   |#n #len * #a * #len #ltnr (cases(le_to_or_lt_eq … ltnr)) #H
437     [@(ex_intro ? ? a) % /2/ 
438     |@(ex_intro ? ? (S a)) % //
439     ]
440   ]
441 qed.
442
443 lemma le_inv_plus_l: ∀x,y,z. x + y ≤ z → x ≤ z - y ∧ y ≤ z.
444 /3 width=2/ qed-.
445
446 lemma lt_inv_plus_l: ∀x,y,z. x + y < z → x < z ∧ y < z - x.
447 /3 width=2/ qed-.
448
449 lemma lt_or_ge: ∀m,n. m < n ∨ n ≤ m.
450 #m #n elim (decidable_lt m n) /2 width=1/ /3 width=1/
451 qed-.
452
453 lemma le_or_ge: ∀m,n. m ≤ n ∨ n ≤ m.
454 #m #n elim (decidable_le m n) /2 width=1/ /4 width=2/
455 qed-.
456
457 (* More general conclusion **************************************************)
458
459 theorem nat_ind_plus: ∀R:predicate nat.
460                       R 0 → (∀n. R n → R (n + 1)) → ∀n. R n.
461 /3 width=1 by nat_ind/ qed-.
462
463 theorem lt_O_n_elim: ∀n:nat. 0 < n → 
464   ∀P:nat → Prop.(∀m:nat.P (S m)) → P n.
465 #n (elim n) // #abs @False_ind /2/ @absurd
466 qed.
467
468 theorem le_n_O_elim: ∀n:nat. n ≤ O → ∀P: nat →Prop. P O → P n.
469 #n (cases n) // #a #abs @False_ind /2/ qed. 
470
471 theorem le_n_Sm_elim : ∀n,m:nat.n ≤ S m → 
472 ∀P:Prop. (S n ≤ S m → P) → (n=S m → P) → P.
473 #n #m #Hle #P (elim Hle) /3/ qed.
474
475 theorem nat_elim1 : ∀n:nat.∀P:nat → Prop. 
476 (∀m.(∀p. p < m → P p) → P m) → P n.
477 #n #P #H 
478 cut (∀q:nat. q ≤ n → P q) /2/
479 (elim n) 
480  [#q #HleO (* applica male *) 
481     @(le_n_O_elim ? HleO)
482     @H #p #ltpO @False_ind /2/ (* 3 *)
483  |#p #Hind #q #HleS 
484     @H #a #lta @Hind @le_S_S_to_le /2/
485  ]
486 qed.
487
488 (* More negated equalities **************************************************)
489
490 theorem lt_to_not_eq : ∀n,m:nat. n < m → n ≠ m.
491 #n #m #H @not_to_not /2/ qed.
492
493 (* More equalities **********************************************************)
494
495 theorem le_n_O_to_eq : ∀n:nat. n ≤ 0 → 0=n.
496 #n (cases n) // #a  #abs @False_ind /2/ qed.
497
498 theorem le_to_le_to_eq: ∀n,m. n ≤ m → m ≤ n → n = m.
499 @nat_elim2 /4/
500 qed. 
501
502 theorem increasing_to_injective: ∀f:nat → nat.
503   increasing f → injective nat nat f.
504 #f #incr #n #m cases(decidable_le n m)
505   [#lenm cases(le_to_or_lt_eq … lenm) //
506    #lenm #eqf @False_ind @(absurd … eqf) @lt_to_not_eq 
507    @increasing_to_monotonic //
508   |#nlenm #eqf @False_ind @(absurd … eqf) @sym_not_eq 
509    @lt_to_not_eq @increasing_to_monotonic /2/
510   ]
511 qed.
512
513 theorem minus_Sn_m: ∀m,n:nat. m ≤ n → S n -m = S (n-m).
514 (* qualcosa da capire qui 
515 #n #m #lenm nelim lenm napplyS refl_eq. *)
516 @nat_elim2 
517   [//
518   |#n #abs @False_ind /2/ 
519   |#n #m #Hind #c applyS Hind /2/
520   ]
521 qed.
522
523 theorem plus_minus:
524 ∀m,n,p:nat. m ≤ n → (n-m)+p = (n+p)-m.
525 @nat_elim2 
526   [//
527   |#n #p #abs @False_ind /2/
528   |normalize/3/
529   ]
530 qed.
531
532 theorem minus_plus_m_m: ∀n,m:nat.n = (n+m)-m.
533 /2/ qed.
534
535 theorem plus_minus_m_m: ∀n,m:nat.
536   m ≤ n → n = (n-m)+m.
537 #n #m #lemn @sym_eq /2/ qed.
538
539 theorem minus_to_plus :∀n,m,p:nat.
540   m ≤ n → n-m = p → n = m+p.
541 #n #m #p #lemn #eqp (applyS plus_minus_m_m) //
542 qed.
543
544 theorem plus_to_minus :∀n,m,p:nat.n = m+p → n-m = p.
545 #n #m #p #eqp @sym_eq (applyS (minus_plus_m_m p m))
546 qed.
547
548 theorem minus_pred_pred : ∀n,m:nat. O < n → O < m → 
549 pred n - pred m = n - m.
550 #n #m #posn #posm @(lt_O_n_elim n posn) @(lt_O_n_elim m posm) //.
551 qed.
552
553 theorem plus_minus_commutative: ∀x,y,z. z ≤ y → x + (y - z) = x + y - z.
554 /2 by plus_minus/ qed.
555
556 (* More atomic conclusion ***************************************************)
557
558 (* le *)
559
560 theorem le_n_fn: ∀f:nat → nat. 
561   increasing f → ∀n:nat. n ≤ f n.
562 #f #incr #n (elim n) /2/
563 qed-.
564
565 theorem monotonic_le_minus_l: 
566 ∀p,q,n:nat. q ≤ p → q-n ≤ p-n.
567 @nat_elim2 #p #q
568   [#lePO @(le_n_O_elim ? lePO) //
569   |//
570   |#Hind #n (cases n) // #a #leSS @Hind /2/
571   ]
572 qed.
573
574 theorem le_minus_to_plus: ∀n,m,p. n-m ≤ p → n≤ p+m.
575 #n #m #p #lep @transitive_le
576   [|@le_plus_minus_m_m | @monotonic_le_plus_l // ]
577 qed.
578
579 theorem le_minus_to_plus_r: ∀a,b,c. c ≤ b → a ≤ b - c → a + c ≤ b.
580 #a #b #c #Hlecb #H >(plus_minus_m_m … Hlecb) /2/
581 qed.
582
583 theorem le_plus_to_minus: ∀n,m,p. n ≤ p+m → n-m ≤ p.
584 #n #m #p #lep /2/ qed.
585
586 theorem monotonic_le_minus_r: 
587 ∀p,q,n:nat. q ≤ p → n-p ≤ n-q.
588 #p #q #n #lepq @le_plus_to_minus
589 @(transitive_le … (le_plus_minus_m_m ? q)) /2/
590 qed.
591
592 theorem increasing_to_le: ∀f:nat → nat. 
593   increasing f → ∀m:nat.∃i.m ≤ f i.
594 #f #incr #m (elim m) /2/#n * #a #lenfa
595 @(ex_intro ?? (S a)) /2/
596 qed.
597
598 lemma le_plus_compatible: ∀x1,x2,y1,y2. x1 ≤ y1 → x2 ≤ y2 → x1 + x2 ≤ y1 + y2.
599 /3 by le_minus_to_plus, monotonic_le_plus_r, transitive_le/ qed.
600
601 (* lt *)
602
603 theorem not_eq_to_le_to_lt: ∀n,m. n≠m → n≤m → n<m.
604 #n #m #Hneq #Hle cases (le_to_or_lt_eq ?? Hle) //
605 #Heq /3/ qed-.
606
607 theorem lt_times_n_to_lt_l: 
608 ∀n,p,q:nat. p*n < q*n → p < q.
609 #n #p #q #Hlt (elim (decidable_lt p q)) //
610 #nltpq @False_ind @(absurd ? ? (lt_to_not_le ? ? Hlt))
611 applyS monotonic_le_times_r /2/
612 qed.
613
614 theorem lt_times_n_to_lt_r: 
615 ∀n,p,q:nat. n*p < n*q → p < q.
616 /2/ qed-.
617
618 theorem lt_minus_to_plus: ∀a,b,c. a - b < c → a < c + b.
619 #a #b #c #H @not_le_to_lt 
620 @(not_to_not … (lt_to_not_le …H)) /2/
621 qed.
622
623 theorem lt_minus_to_plus_r: ∀a,b,c. a < b - c → a + c < b.
624 #a #b #c #H @not_le_to_lt @(not_to_not … (le_plus_to_minus …))
625 @lt_to_not_le //
626 qed.
627
628 theorem lt_plus_to_minus: ∀n,m,p. m ≤ n → n < p+m → n-m < p.
629 #n #m #p #lenm #H normalize <minus_Sn_m // @le_plus_to_minus //
630 qed.
631
632 theorem monotonic_lt_minus_l: ∀p,q,n. n ≤ q → q < p → q - n < p - n.
633 #p #q #n #H1 #H2
634 @lt_plus_to_minus_r <plus_minus_m_m //
635 qed.
636
637 (* Still more equalities ****************************************************)
638
639 theorem eq_minus_O: ∀n,m:nat.
640   n ≤ m → n-m = O.
641 #n #m #lenm @(le_n_O_elim (n-m)) /2/
642 qed.
643
644 theorem distributive_times_minus: distributive ? times minus.
645 #a #b #c
646 (cases (decidable_lt b c)) #Hbc
647  [> eq_minus_O /2/ >eq_minus_O // 
648   @monotonic_le_times_r /2/
649  |@sym_eq (applyS plus_to_minus) <distributive_times_plus 
650   @eq_f (applyS plus_minus_m_m) /2/
651 qed.
652
653 theorem minus_plus: ∀n,m,p. n-m-p = n -(m+p).
654 #n #m #p 
655 cases (decidable_le (m+p) n) #Hlt
656   [@plus_to_minus @plus_to_minus <associative_plus
657    @minus_to_plus //
658   |cut (n ≤ m+p) [@(transitive_le … (le_n_Sn …)) @not_le_to_lt //]
659    #H >eq_minus_O /2/ (* >eq_minus_O // *) 
660   ]
661 qed.
662
663 theorem minus_minus: ∀n,m,p:nat. p ≤ m → m ≤ n →
664   p+(n-m) = n-(m-p).
665 #n #m #p #lepm #lemn
666 @sym_eq @plus_to_minus <associative_plus <plus_minus_m_m //
667 <commutative_plus <plus_minus_m_m //
668 qed.
669
670 lemma minus_minus_comm: ∀a,b,c. a - b - c = a - c - b.
671 /3 by monotonic_le_minus_l, le_to_le_to_eq/ qed.
672
673 lemma minus_le_minus_minus_comm: ∀b,c,a. c ≤ b → a - (b - c) = a + c - b.
674 #b #c #a #H >(plus_minus_m_m b c) in ⊢ (? ? ?%); //
675 qed.
676
677 lemma minus_minus_m_m: ∀m,n. n ≤ m → m - (m - n) = n.
678 /2 width=1/ qed.
679
680 (* Stilll more atomic conclusion ********************************************)
681
682 (* le *)
683
684 lemma le_fwd_plus_plus_ge: ∀m1,m2. m2 ≤ m1 → ∀n1,n2. m1 + n1 ≤ m2 + n2 → n1 ≤ n2.
685 #m1 #m2 #H #n1 #n2 >commutative_plus
686 #H elim (le_inv_plus_l … H) -H >commutative_plus <minus_le_minus_minus_comm //
687 #H #_ @(transitive_le … H) /2 width=1/
688 qed-. 
689
690 (*********************** boolean arithmetics ********************) 
691
692 include "basics/bool.ma".
693
694 let rec eqb n m ≝ 
695 match n with 
696   [ O ⇒ match m with [ O ⇒ true | S q ⇒ false] 
697   | S p ⇒ match m with [ O ⇒ false | S q ⇒ eqb p q]
698   ].
699
700 theorem eqb_elim : ∀ n,m:nat.∀ P:bool → Prop.
701 (n=m → (P true)) → (n ≠ m → (P false)) → (P (eqb n m)). 
702 @nat_elim2 
703   [#n (cases n) normalize /3/ 
704   |normalize /3/
705   |normalize /4/ 
706   ] 
707 qed.
708
709 theorem eqb_n_n: ∀n. eqb n n = true.
710 #n (elim n) normalize // qed. 
711
712 theorem eqb_true_to_eq: ∀n,m:nat. eqb n m = true → n = m.
713 #n #m @(eqb_elim n m) // #_ #abs @False_ind /2/ qed.
714
715 theorem eqb_false_to_not_eq: ∀n,m:nat. eqb n m = false → n ≠ m.
716 #n #m @(eqb_elim n m) /2/ qed.
717
718 theorem eq_to_eqb_true: ∀n,m:nat.n = m → eqb n m = true.
719 // qed.
720
721 theorem not_eq_to_eqb_false: ∀n,m:nat.
722   n ≠  m → eqb n m = false.
723 #n #m #noteq @eqb_elim// #Heq @False_ind /2/ qed.
724
725 let rec leb n m ≝ 
726 match n with 
727     [ O ⇒ true
728     | (S p) ⇒
729         match m with 
730         [ O ⇒ false
731               | (S q) ⇒ leb p q]].
732
733 theorem leb_elim: ∀n,m:nat. ∀P:bool → Prop. 
734 (n ≤ m → P true) → (n ≰ m → P false) → P (leb n m).
735 @nat_elim2 normalize
736   [/2/
737   |/3/
738   |#n #m #Hind #P #Pt #Pf @Hind
739     [#lenm @Pt @le_S_S // |#nlenm @Pf /2/ ]
740   ]
741 qed.
742
743 theorem leb_true_to_le:∀n,m.leb n m = true → n ≤ m.
744 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
745
746 theorem leb_false_to_not_le:∀n,m.
747   leb n m = false → n ≰ m.
748 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
749
750 theorem le_to_leb_true: ∀n,m. n ≤ m → leb n m = true.
751 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
752
753 theorem not_le_to_leb_false: ∀n,m. n ≰ m → leb n m = false.
754 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
755
756 theorem lt_to_leb_false: ∀n,m. m < n → leb n m = false.
757 /3/ qed.
758
759 (* min e max *)
760 definition min: nat →nat →nat ≝
761 λn.λm. if leb n m then n else m.
762
763 definition max: nat →nat →nat ≝
764 λn.λm. if leb n m then m else n.
765
766 lemma commutative_min: commutative ? min.
767 #n #m normalize @leb_elim 
768   [@leb_elim normalize /2/
769   |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
770   ] qed.
771
772 lemma le_minr: ∀i,n,m. i ≤ min n m → i ≤ m.
773 #i #n #m normalize @leb_elim normalize /2/ qed. 
774
775 lemma le_minl: ∀i,n,m. i ≤ min n m → i ≤ n.
776 /2/ qed-.
777
778 lemma to_min: ∀i,n,m. i ≤ n → i ≤ m → i ≤ min n m.
779 #i #n #m #lein #leim normalize (cases (leb n m)) 
780 normalize // qed.
781
782 lemma commutative_max: commutative ? max.
783 #n #m normalize @leb_elim 
784   [@leb_elim normalize /2/
785   |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
786   ] qed.
787
788 lemma le_maxl: ∀i,n,m. max n m ≤ i → n ≤ i.
789 #i #n #m normalize @leb_elim normalize /2/ qed. 
790
791 lemma le_maxr: ∀i,n,m. max n m ≤ i → m ≤ i.
792 /2/ qed-.
793
794 lemma to_max: ∀i,n,m. n ≤ i → m ≤ i → max n m ≤ i.
795 #i #n #m #leni #lemi normalize (cases (leb n m)) 
796 normalize // qed.