]> matita.cs.unibo.it Git - helm.git/blob - matitaB/matita/lib/arithmetics/nat.ma
fork for Matita version B
[helm.git] / matitaB / 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 inductive nat : Type[0] ≝
15   | O : nat
16   | S : nat → nat.
17   
18 interpretation "Natural numbers" 'N = nat.
19
20 alias num (instance 0) = "natural number".
21
22 definition pred ≝
23  λn. match n with [ O ⇒ O | S p ⇒ p].
24
25 theorem pred_Sn : ∀n. n = pred (S n).
26 // qed.
27
28 theorem injective_S : injective nat nat S.
29 // qed.
30
31 (*
32 theorem inj_S : \forall n,m:nat.(S n)=(S m) \to n=m.
33 //. qed. *)
34
35 theorem not_eq_S: ∀n,m:nat. n ≠ m → S n ≠ S m.
36 /2/ qed.
37
38 definition not_zero: nat → Prop ≝
39  λn: nat. match n with [ O ⇒ False | (S p) ⇒ True ].
40
41 theorem not_eq_O_S : ∀n:nat. O ≠ S n.
42 #n @nmk #eqOS (change with (not_zero O)) >eqOS // qed.
43
44 theorem not_eq_n_Sn: ∀n:nat. n ≠ S n.
45 #n (elim n) /2/ qed.
46
47 theorem nat_case:
48  ∀n:nat.∀P:nat → Prop. 
49   (n=O → P O) → (∀m:nat. n= S m → P (S m)) → P n.
50 #n #P (elim n) /2/ qed.
51
52 theorem nat_elim2 :
53  ∀R:nat → nat → Prop.
54   (∀n:nat. R O n) 
55   → (∀n:nat. R (S n) O)
56   → (∀n,m:nat. R n m → R (S n) (S m))
57   → ∀n,m:nat. R n m.
58 #R #ROn #RSO #RSS #n (elim n) // #n0 #Rn0m #m (cases m) /2/ qed.
59
60 theorem decidable_eq_nat : ∀n,m:nat.decidable (n=m).
61 @nat_elim2 #n [ (cases n) /2/ | /3/ | #m #Hind (cases Hind) /3/]
62 qed. 
63
64 (*************************** plus ******************************)
65
66 let rec plus n m ≝ 
67  match n with [ O ⇒ m | S p ⇒ S (plus p m) ].
68
69 interpretation "natural plus" 'plus x y = (plus x y).
70
71 theorem plus_O_n: ∀n:nat. n = O+n.
72 // qed.
73
74 (*
75 theorem plus_Sn_m: ∀n,m:nat. S (n + m) = S n + m.
76 // qed.
77 *)
78
79 theorem plus_n_O: ∀n:nat. n = n+O.
80 #n (elim n) normalize // qed.
81
82 theorem plus_n_Sm : ∀n,m:nat. S (n+m) = n + S m.
83 #n (elim n) normalize // qed.
84
85 (*
86 theorem plus_Sn_m1: ∀n,m:nat. S m + n = n + S m.
87 #n (elim n) normalize // qed.
88 *)
89
90 (* deleterio?
91 theorem plus_n_1 : ∀n:nat. S n = n+1.
92 // qed.
93 *)
94
95 theorem commutative_plus: commutative ? plus.
96 #n (elim n) normalize // qed. 
97
98 theorem associative_plus : associative nat plus.
99 #n (elim n) normalize // qed.
100
101 theorem assoc_plus1: ∀a,b,c. c + (b + a) = b + c + a.
102 // qed. 
103
104 theorem injective_plus_r: ∀n:nat.injective nat nat (λm.n+m).
105 #n (elim n) normalize /3/ qed.
106
107 (* theorem inj_plus_r: \forall p,n,m:nat. p+n = p+m \to n=m
108 \def injective_plus_r. 
109
110 theorem injective_plus_l: ∀m:nat.injective nat nat (λn.n+m).
111 /2/ qed. *)
112
113 (* theorem inj_plus_l: \forall p,n,m:nat. n+p = m+p \to n=m
114 \def injective_plus_l. *)
115
116 (*************************** times *****************************)
117
118 let rec times n m ≝ 
119  match n with [ O ⇒ O | S p ⇒ m+(times p m) ].
120
121 interpretation "natural times" 'times x y = (times x y).
122
123 theorem times_Sn_m: ∀n,m:nat. m+n*m = S n*m.
124 // qed.
125
126 theorem times_O_n: ∀n:nat. O = O*n.
127 // qed.
128
129 theorem times_n_O: ∀n:nat. O = n*O.
130 #n (elim n) // qed.
131
132 theorem times_n_Sm : ∀n,m:nat. n+(n*m) = n*(S m).
133 #n (elim n) normalize // qed.
134
135 theorem commutative_times : commutative nat times. 
136 #n (elim n) normalize // qed. 
137
138 (* variant sym_times : \forall n,m:nat. n*m = m*n \def
139 symmetric_times. *)
140
141 theorem distributive_times_plus : distributive nat times plus.
142 #n (elim n) normalize // qed.
143
144 theorem distributive_times_plus_r :
145   ∀a,b,c:nat. (b+c)*a = b*a + c*a.
146 // qed. 
147
148 theorem associative_times: associative nat times.
149 #n (elim n) normalize // qed.
150
151 lemma times_times: ∀x,y,z. x*(y*z) = y*(x*z).
152 // qed. 
153
154 theorem times_n_1 : ∀n:nat. n = n * 1.
155 #n // qed.
156
157 (* ci servono questi risultati? 
158 theorem times_O_to_O: ∀n,m:nat.n*m=O → n=O ∨ m=O.
159 napply nat_elim2 /2/ 
160 #n #m #H normalize #H1 napply False_ind napply not_eq_O_S
161 // qed.
162   
163 theorem times_n_SO : ∀n:nat. n = n * S O.
164 #n // qed.
165
166 theorem times_SSO_n : ∀n:nat. n + n = (S(S O)) * n.
167 normalize // qed.
168
169 nlemma times_SSO: \forall n.(S(S O))*(S n) = S(S((S(S O))*n)).
170 // qed.
171
172 theorem or_eq_eq_S: \forall n.\exists m. 
173 n = (S(S O))*m \lor n = S ((S(S O))*m).
174 #n (elim n)
175   ##[@ /2/
176   ##|#a #H nelim H #b#ornelim or#aeq
177     ##[@ b @ 2 //
178     ##|@ (S b) @ 1 /2/
179     ##]
180 qed.
181 *)
182
183 (******************** ordering relations ************************)
184
185 inductive le (n:nat) : nat → Prop ≝
186   | le_n : le n n
187   | le_S : ∀ m:nat. le n m → le n (S m).
188
189 interpretation "natural 'less or equal to'" 'leq x y = (le x y).
190
191 interpretation "natural 'neither less nor equal to'" 'nleq x y = (Not (le x y)).
192
193 definition lt: nat → nat → Prop ≝ λn,m. S n ≤ m.
194
195 interpretation "natural 'less than'" 'lt x y = (lt x y).
196 interpretation "natural 'not less than'" 'nless x y = (Not (lt x y)).
197
198 (* lemma eq_lt: ∀n,m. (n < m) = (S n ≤ m).
199 // qed. *)
200
201 definition ge: nat → nat → Prop ≝ λn,m.m ≤ n.
202
203 interpretation "natural 'greater or equal to'" 'geq x y = (ge x y).
204
205 definition gt: nat → nat → Prop ≝ λn,m.m<n.
206
207 interpretation "natural 'greater than'" 'gt x y = (gt x y).
208 interpretation "natural 'not greater than'" 'ngtr x y = (Not (gt x y)).
209
210 theorem transitive_le : transitive nat le.
211 #a #b #c #leab #lebc (elim lebc) /2/
212 qed.
213
214 (*
215 theorem trans_le: \forall n,m,p:nat. n \leq m \to m \leq p \to n \leq p
216 \def transitive_le. *)
217
218 theorem transitive_lt: transitive nat lt.
219 #a #b #c #ltab #ltbc (elim ltbc) /2/qed.
220
221 (*
222 theorem trans_lt: \forall n,m,p:nat. lt n m \to lt m p \to lt n p
223 \def transitive_lt. *)
224
225 theorem le_S_S: ∀n,m:nat. n ≤ m → S n ≤ S m.
226 #n #m #lenm (elim lenm) /2/ qed.
227
228 theorem le_O_n : ∀n:nat. O ≤ n.
229 #n (elim n) /2/ qed.
230
231 theorem le_n_Sn : ∀n:nat. n ≤ S n.
232 /2/ qed.
233
234 theorem le_pred_n : ∀n:nat. pred n ≤ n.
235 #n (elim n) // qed.
236
237 theorem monotonic_pred: monotonic ? le pred.
238 #n #m #lenm (elim lenm) /2/ qed.
239
240 theorem le_S_S_to_le: ∀n,m:nat. S n ≤ S m → n ≤ m.
241 (* demo *)
242 /2/ qed.
243
244 (* this are instances of the le versions 
245 theorem lt_S_S_to_lt: ∀n,m. S n < S m → n < m.
246 /2/ qed. 
247
248 theorem lt_to_lt_S_S: ∀n,m. n < m → S n < S m.
249 /2/ qed. *)
250
251 theorem lt_to_not_zero : ∀n,m:nat. n < m → not_zero m.
252 #n #m #Hlt (elim Hlt) // qed.
253
254 (* lt vs. le *)
255 theorem not_le_Sn_O: ∀ n:nat. S n ≰ O.
256 #n @nmk #Hlen0 @(lt_to_not_zero ?? Hlen0) qed.
257
258 theorem not_le_to_not_le_S_S: ∀ n,m:nat. n ≰ m → S n ≰ S m.
259 /3/ qed.
260
261 theorem not_le_S_S_to_not_le: ∀ n,m:nat. S n ≰ S m → n ≰ m.
262 /3/ qed.
263
264 theorem decidable_le: ∀n,m. decidable (n≤m).
265 @nat_elim2 #n /2/ #m * /3/ qed.
266
267 theorem decidable_lt: ∀n,m. decidable (n < m).
268 #n #m @decidable_le  qed.
269
270 theorem not_le_Sn_n: ∀n:nat. S n ≰ n.
271 #n (elim n) /2/ qed.
272
273 (* this is le_S_S_to_le
274 theorem lt_S_to_le: ∀n,m:nat. n < S m → n ≤ m.
275 /2/ qed.
276 *)
277
278 lemma le_gen: ∀P:nat → Prop.∀n.(∀i. i ≤ n → P i) → P n.
279 /2/ qed.
280
281 theorem not_le_to_lt: ∀n,m. n ≰ m → m < n.
282 @nat_elim2 #n
283  [#abs @False_ind /2/
284  |/2/
285  |#m #Hind #HnotleSS @le_S_S /3/
286  ]
287 qed.
288
289 theorem lt_to_not_le: ∀n,m. n < m → m ≰ n.
290 #n #m #Hltnm (elim Hltnm) /3/ qed.
291
292 theorem not_lt_to_le: ∀n,m:nat. n ≮ m → m ≤ n.
293 /4/ qed.
294
295 theorem le_to_not_lt: ∀n,m:nat. n ≤ m → m ≮ n.
296 #n #m #H @lt_to_not_le /2/ (* /3/ *) qed.
297
298 (* lt and le trans *)
299
300 theorem lt_to_le_to_lt: ∀n,m,p:nat. n < m → m ≤ p → n < p.
301 #n #m #p #H #H1 (elim H1) /2/ qed.
302
303 theorem le_to_lt_to_lt: ∀n,m,p:nat. n ≤ m → m < p → n < p.
304 #n #m #p #H (elim H) /3/ qed.
305
306 theorem lt_S_to_lt: ∀n,m. S n < m → n < m.
307 /2/ qed.
308
309 theorem ltn_to_ltO: ∀n,m:nat. n < m → O < m.
310 /2/ qed.
311
312 (*
313 theorem lt_SO_n_to_lt_O_pred_n: \forall n:nat.
314 (S O) \lt n \to O \lt (pred n).
315 intros.
316 apply (ltn_to_ltO (pred (S O)) (pred n) ?).
317  apply (lt_pred (S O) n)
318  [ apply (lt_O_S O) 
319  | assumption
320  ]
321 qed. *)
322
323 theorem lt_O_n_elim: ∀n:nat. O < n → 
324   ∀P:nat → Prop.(∀m:nat.P (S m)) → P n.
325 #n (elim n) // #abs @False_ind /2/
326 qed.
327
328 theorem S_pred: ∀n. 0 < n → S(pred n) = n.
329 #n #posn (cases posn) //
330 qed.
331
332 (*
333 theorem lt_pred: \forall n,m. 
334   O < n \to n < m \to pred n < pred m. 
335 apply nat_elim2
336   [intros.apply False_ind.apply (not_le_Sn_O ? H)
337   |intros.apply False_ind.apply (not_le_Sn_O ? H1)
338   |intros.simplify.unfold.apply le_S_S_to_le.assumption
339   ]
340 qed.
341
342 theorem le_pred_to_le:
343  ∀n,m. O < m → pred n ≤ pred m → n ≤ m.
344 intros 2
345 elim n
346 [ apply le_O_n
347 | simplify in H2
348   rewrite > (S_pred m)
349   [ apply le_S_S
350     assumption
351   | assumption
352   ]
353 ].
354 qed.
355
356 *)
357
358 (* le to lt or eq *)
359 theorem le_to_or_lt_eq: ∀n,m:nat. n ≤ m → n < m ∨ n = m.
360 #n #m #lenm (elim lenm) /3/ qed.
361
362 (* not eq *)
363 theorem lt_to_not_eq : ∀n,m:nat. n < m → n ≠ m.
364 #n #m #H @not_to_not /2/ qed.
365
366 (*not lt 
367 theorem eq_to_not_lt: ∀a,b:nat. a = b → a ≮ b.
368 intros.
369 unfold Not.
370 intros.
371 rewrite > H in H1.
372 apply (lt_to_not_eq b b)
373 [ assumption
374 | reflexivity
375 ]
376 qed. 
377
378 theorem lt_n_m_to_not_lt_m_Sn: ∀n,m. n < m → m ≮ S n.
379 intros
380 unfold Not
381 intro
382 unfold lt in H
383 unfold lt in H1
384 generalize in match (le_S_S ? ? H)
385 intro
386 generalize in match (transitive_le ? ? ? H2 H1)
387 intro
388 apply (not_le_Sn_n ? H3).
389 qed. *)
390
391 theorem not_eq_to_le_to_lt: ∀n,m. n≠m → n≤m → n<m.
392 #n #m #Hneq #Hle cases (le_to_or_lt_eq ?? Hle) //
393 #Heq /3/ qed.
394 (*
395 nelim (Hneq Heq) qed. *)
396
397 (* le elimination *)
398 theorem le_n_O_to_eq : ∀n:nat. n ≤ O → O=n.
399 #n (cases n) // #a  #abs @False_ind /2/ qed.
400
401 theorem le_n_O_elim: ∀n:nat. n ≤ O → ∀P: nat →Prop. P O → P n.
402 #n (cases n) // #a #abs @False_ind /2/ qed. 
403
404 theorem le_n_Sm_elim : ∀n,m:nat.n ≤ S m → 
405 ∀P:Prop. (S n ≤ S m → P) → (n=S m → P) → P.
406 #n #m #Hle #P (elim Hle) /3/ qed.
407
408 (* le and eq *)
409
410 theorem le_to_le_to_eq: ∀n,m. n ≤ m → m ≤ n → n = m.
411 @nat_elim2 /4/
412 qed. 
413
414 theorem lt_O_S : ∀n:nat. O < S n.
415 /2/ qed.
416
417 (*
418 (* other abstract properties *)
419 theorem antisymmetric_le : antisymmetric nat le.
420 unfold antisymmetric.intros 2.
421 apply (nat_elim2 (\lambda n,m.(n \leq m \to m \leq n \to n=m))).
422 intros.apply le_n_O_to_eq.assumption.
423 intros.apply False_ind.apply (not_le_Sn_O ? H).
424 intros.apply eq_f.apply H.
425 apply le_S_S_to_le.assumption.
426 apply le_S_S_to_le.assumption.
427 qed.
428
429 theorem antisym_le: \forall n,m:nat. n \leq m \to m \leq n \to n=m
430 \def antisymmetric_le.
431
432 theorem le_n_m_to_lt_m_Sn_to_eq_n_m: ∀n,m. n ≤ m → m < S n → n=m.
433 intros
434 unfold lt in H1
435 generalize in match (le_S_S_to_le ? ? H1)
436 intro
437 apply antisym_le
438 assumption.
439 qed.
440 *)
441
442 (* well founded induction principles *)
443
444 theorem nat_elim1 : ∀n:nat.∀P:nat → Prop. 
445 (∀m.(∀p. p < m → P p) → P m) → P n.
446 #n #P #H 
447 cut (∀q:nat. q ≤ n → P q) /2/
448 (elim n) 
449  [#q #HleO (* applica male *) 
450     @(le_n_O_elim ? HleO)
451     @H #p #ltpO @False_ind /2/ (* 3 *)
452  |#p #Hind #q #HleS 
453     @H #a #lta @Hind @le_S_S_to_le /2/
454  ]
455 qed.
456
457 (* some properties of functions *)
458
459 definition increasing ≝ λf:nat → nat. ∀n:nat. f n < f (S n).
460
461 theorem increasing_to_monotonic: ∀f:nat → nat.
462   increasing f → monotonic nat lt f.
463 #f #incr #n #m #ltnm (elim ltnm) /2/
464 qed.
465
466 theorem le_n_fn: ∀f:nat → nat. 
467   increasing f → ∀n:nat. n ≤ f n.
468 #f #incr #n (elim n) /2/
469 qed.
470
471 theorem increasing_to_le: ∀f:nat → nat. 
472   increasing f → ∀m:nat.∃i.m ≤ f i.
473 #f #incr #m (elim m) /2/#n * #a #lenfa
474 @(ex_intro ?? (S a)) /2/
475 qed.
476
477 theorem increasing_to_le2: ∀f:nat → nat. increasing f → 
478   ∀m:nat. f 0 ≤ m → ∃i. f i ≤ m ∧ m < f (S i).
479 #f #incr #m #lem (elim lem)
480   [@(ex_intro ? ? O) /2/
481   |#n #len * #a * #len #ltnr (cases(le_to_or_lt_eq … ltnr)) #H
482     [@(ex_intro ? ? a) % /2/ 
483     |@(ex_intro ? ? (S a)) % //
484     ]
485   ]
486 qed.
487
488 theorem increasing_to_injective: ∀f:nat → nat.
489   increasing f → injective nat nat f.
490 #f #incr #n #m cases(decidable_le n m)
491   [#lenm cases(le_to_or_lt_eq … lenm) //
492    #lenm #eqf @False_ind @(absurd … eqf) @lt_to_not_eq 
493    @increasing_to_monotonic //
494   |#nlenm #eqf @False_ind @(absurd … eqf) @sym_not_eq 
495    @lt_to_not_eq @increasing_to_monotonic /2/
496   ]
497 qed.
498
499 (*********************** monotonicity ***************************)
500 theorem monotonic_le_plus_r: 
501 ∀n:nat.monotonic nat le (λm.n + m).
502 #n #a #b (elim n) normalize //
503 #m #H #leab @le_S_S /2/ qed.
504
505 (*
506 theorem le_plus_r: ∀p,n,m:nat. n ≤ m → p + n ≤ p + m
507 ≝ monotonic_le_plus_r. *)
508
509 theorem monotonic_le_plus_l: 
510 ∀m:nat.monotonic nat le (λn.n + m).
511 /2/ qed.
512
513 (*
514 theorem le_plus_l: \forall p,n,m:nat. n \le m \to n + p \le m + p
515 \def monotonic_le_plus_l. *)
516
517 theorem le_plus: ∀n1,n2,m1,m2:nat. n1 ≤ n2  → m1 ≤ m2 
518 → n1 + m1 ≤ n2 + m2.
519 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1+m2))
520 /2/ qed.
521
522 theorem le_plus_n :∀n,m:nat. m ≤ n + m.
523 /2/ qed. 
524
525 lemma le_plus_a: ∀a,n,m. n ≤ m → n ≤ a + m.
526 /2/ qed.
527
528 lemma le_plus_b: ∀b,n,m. n + b ≤ m → n ≤ m.
529 /2/ qed.
530
531 theorem le_plus_n_r :∀n,m:nat. m ≤ m + n.
532 /2/ qed.
533
534 theorem eq_plus_to_le: ∀n,m,p:nat.n=m+p → m ≤ n.
535 // qed.
536
537 theorem le_plus_to_le: ∀a,n,m. a + n ≤ a + m → n ≤ m.
538 #a (elim a) normalize /3/ qed. 
539
540 theorem le_plus_to_le_r: ∀a,n,m. n + a ≤ m +a → n ≤ m.
541 /2/ qed. 
542
543 (* plus & lt *)
544
545 theorem monotonic_lt_plus_r: 
546 ∀n:nat.monotonic nat lt (λm.n+m).
547 /2/ qed.
548
549 (*
550 variant lt_plus_r: \forall n,p,q:nat. p < q \to n + p < n + q \def
551 monotonic_lt_plus_r. *)
552
553 theorem monotonic_lt_plus_l: 
554 ∀n:nat.monotonic nat lt (λm.m+n).
555 /2/ qed.
556
557 (*
558 variant lt_plus_l: \forall n,p,q:nat. p < q \to p + n < q + n \def
559 monotonic_lt_plus_l. *)
560
561 theorem lt_plus: ∀n,m,p,q:nat. n < m → p < q → n + p < m + q.
562 #n #m #p #q #ltnm #ltpq
563 @(transitive_lt ? (n+q))/2/ qed.
564
565 theorem lt_plus_to_lt_l :∀n,p,q:nat. p+n < q+n → p<q.
566 /2/ qed.
567
568 theorem lt_plus_to_lt_r :∀n,p,q:nat. n+p < n+q → p<q.
569 /2/ qed.
570
571 (*
572 theorem le_to_lt_to_lt_plus: ∀a,b,c,d:nat.
573 a ≤ c → b < d → a + b < c+d.
574 (* bello /2/ un po' lento *)
575 #a #b #c #d #leac #lebd 
576 normalize napplyS le_plus // qed.
577 *)
578
579 (* times *)
580 theorem monotonic_le_times_r: 
581 ∀n:nat.monotonic nat le (λm. n * m).
582 #n #x #y #lexy (elim n) normalize//(* lento /2/*)
583 #a #lea @le_plus //
584 qed.
585
586 (*
587 theorem le_times_r: \forall p,n,m:nat. n \le m \to p*n \le p*m
588 \def monotonic_le_times_r. *)
589
590 (*
591 theorem monotonic_le_times_l: 
592 ∀m:nat.monotonic nat le (λn.n*m).
593 /2/ qed.
594 *)
595
596 (*
597 theorem le_times_l: \forall p,n,m:nat. n \le m \to n*p \le m*p
598 \def monotonic_le_times_l. *)
599
600 theorem le_times: ∀n1,n2,m1,m2:nat. 
601 n1 ≤ n2  → m1 ≤ m2 → n1*m1 ≤ n2*m2.
602 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1*m2)) /2/
603 qed.
604
605 (* interessante *)
606 theorem lt_times_n: ∀n,m:nat. O < n → m ≤ n*m.
607 #n #m #H /2/ qed.
608
609 theorem le_times_to_le: 
610 ∀a,n,m. O < a → a * n ≤ a * m → n ≤ m.
611 #a @nat_elim2 normalize
612   [//
613   |#n #H1 #H2 
614      @(transitive_le ? (a*S n)) /2/
615   |#n #m #H #lta #le
616      @le_S_S @H /2/
617   ]
618 qed.
619
620 (*
621 theorem le_S_times_2: ∀n,m.O < m → n ≤ m → S n ≤ 2*m.
622 #n #m #posm #lenm  (* interessante *)
623 applyS (le_plus n m) // qed. *)
624
625 (* times & lt *)
626 (*
627 theorem lt_O_times_S_S: ∀n,m:nat.O < (S n)*(S m).
628 intros.simplify.unfold lt.apply le_S_S.apply le_O_n.
629 qed. *)
630
631 (*
632 theorem lt_times_eq_O: \forall a,b:nat.
633 O < a → a * b = O → b = O.
634 intros.
635 apply (nat_case1 b)
636 [ intros.
637   reflexivity
638 | intros.
639   rewrite > H2 in H1.
640   rewrite > (S_pred a) in H1
641   [ apply False_ind.
642     apply (eq_to_not_lt O ((S (pred a))*(S m)))
643     [ apply sym_eq.
644       assumption
645     | apply lt_O_times_S_S
646     ]
647   | assumption
648   ]
649 ]
650 qed. 
651
652 theorem O_lt_times_to_O_lt: \forall a,c:nat.
653 O \lt (a * c) \to O \lt a.
654 intros.
655 apply (nat_case1 a)
656 [ intros.
657   rewrite > H1 in H.
658   simplify in H.
659   assumption
660 | intros.
661   apply lt_O_S
662 ]
663 qed.
664
665 lemma lt_times_to_lt_O: \forall i,n,m:nat. i < n*m \to O < m.
666 intros.
667 elim (le_to_or_lt_eq O ? (le_O_n m))
668   [assumption
669   |apply False_ind.
670    rewrite < H1 in H.
671    rewrite < times_n_O in H.
672    apply (not_le_Sn_O ? H)
673   ]
674 qed. *)
675
676 (*
677 theorem monotonic_lt_times_r: 
678 ∀n:nat.monotonic nat lt (λm.(S n)*m).
679 /2/ 
680 simplify.
681 intros.elim n.
682 simplify.rewrite < plus_n_O.rewrite < plus_n_O.assumption.
683 apply lt_plus.assumption.assumption.
684 qed. *)
685
686 theorem monotonic_lt_times_r: 
687   ∀c:nat. O < c → monotonic nat lt (λt.(c*t)).
688 #c #posc #n #m #ltnm
689 (elim ltnm) normalize
690   [/2/ 
691   |#a #_ #lt1 @(transitive_le … lt1) //
692   ]
693 qed.
694
695 theorem monotonic_lt_times_l: 
696   ∀c:nat. O < c → monotonic nat lt (λt.(t*c)).
697 /2/
698 qed.
699
700 theorem lt_to_le_to_lt_times: 
701 ∀n,m,p,q:nat. n < m → p ≤ q → O < q → n*p < m*q.
702 #n #m #p #q #ltnm #lepq #posq
703 @(le_to_lt_to_lt ? (n*q))
704   [@monotonic_le_times_r //
705   |@monotonic_lt_times_l //
706   ]
707 qed.
708
709 theorem lt_times:∀n,m,p,q:nat. n<m → p<q → n*p < m*q.
710 #n #m #p #q #ltnm #ltpq @lt_to_le_to_lt_times/2/
711 qed.
712
713 theorem lt_times_n_to_lt_l: 
714 ∀n,p,q:nat. p*n < q*n → p < q.
715 #n #p #q #Hlt (elim (decidable_lt p q)) //
716 #nltpq @False_ind @(absurd ? ? (lt_to_not_le ? ? Hlt))
717 applyS monotonic_le_times_r /2/
718 qed.
719
720 theorem lt_times_n_to_lt_r: 
721 ∀n,p,q:nat. n*p < n*q → p < q.
722 /2/ qed.
723
724 (*
725 theorem nat_compare_times_l : \forall n,p,q:nat. 
726 nat_compare p q = nat_compare ((S n) * p) ((S n) * q).
727 intros.apply nat_compare_elim.intro.
728 apply nat_compare_elim.
729 intro.reflexivity.
730 intro.absurd (p=q).
731 apply (inj_times_r n).assumption.
732 apply lt_to_not_eq. assumption.
733 intro.absurd (q<p).
734 apply (lt_times_to_lt_r n).assumption.
735 apply le_to_not_lt.apply lt_to_le.assumption.
736 intro.rewrite < H.rewrite > nat_compare_n_n.reflexivity.
737 intro.apply nat_compare_elim.intro.
738 absurd (p<q).
739 apply (lt_times_to_lt_r n).assumption.
740 apply le_to_not_lt.apply lt_to_le.assumption.
741 intro.absurd (q=p).
742 symmetry.
743 apply (inj_times_r n).assumption.
744 apply lt_to_not_eq.assumption.
745 intro.reflexivity.
746 qed. *)
747
748 (* times and plus 
749 theorem lt_times_plus_times: \forall a,b,n,m:nat. 
750 a < n \to b < m \to a*m + b < n*m.
751 intros 3.
752 apply (nat_case n)
753   [intros.apply False_ind.apply (not_le_Sn_O ? H)
754   |intros.simplify.
755    rewrite < sym_plus.
756    unfold.
757    change with (S b+a*m1 \leq m1+m*m1).
758    apply le_plus
759     [assumption
760     |apply le_times
761       [apply le_S_S_to_le.assumption
762       |apply le_n
763       ]
764     ]
765   ]
766 qed. *)
767
768 (************************** minus ******************************)
769
770 let rec minus n m ≝ 
771  match n with 
772  [ O ⇒ O
773  | S p ⇒ 
774         match m with
775           [ O ⇒ S p
776     | S q ⇒ minus p q ]].
777         
778 interpretation "natural minus" 'minus x y = (minus x y).
779
780 theorem minus_S_S: ∀n,m:nat.S n - S m = n -m.
781 // qed.
782
783 theorem minus_O_n: ∀n:nat.O=O-n.
784 #n (cases n) // qed.
785
786 theorem minus_n_O: ∀n:nat.n=n-O.
787 #n (cases n) // qed.
788
789 theorem minus_n_n: ∀n:nat.O=n-n.
790 #n (elim n) // qed.
791
792 theorem minus_Sn_n: ∀n:nat. S O = (S n)-n.
793 #n (elim n) normalize // qed.
794
795 theorem minus_Sn_m: ∀m,n:nat. m ≤ n → S n -m = S (n-m).
796 (* qualcosa da capire qui 
797 #n #m #lenm nelim lenm napplyS refl_eq. *)
798 @nat_elim2 
799   [//
800   |#n #abs @False_ind /2/ 
801   |#n #m #Hind #c applyS Hind /2/
802   ]
803 qed.
804
805 (*
806 theorem not_eq_to_le_to_le_minus: 
807   ∀n,m.n ≠ m → n ≤ m → n ≤ m - 1.
808 #n * #m (cases m// #m normalize
809 #H #H1 napply le_S_S_to_le
810 napplyS (not_eq_to_le_to_lt n (S m) H H1)
811 qed. *)
812
813 theorem eq_minus_S_pred: ∀n,m. n - (S m) = pred(n -m).
814 @nat_elim2 normalize // qed.
815
816 theorem plus_minus:
817 ∀m,n,p:nat. m ≤ n → (n-m)+p = (n+p)-m.
818 @nat_elim2 
819   [//
820   |#n #p #abs @False_ind /2/
821   |normalize/3/
822   ]
823 qed.
824
825 theorem minus_plus_m_m: ∀n,m:nat.n = (n+m)-m.
826 /2/ qed.
827
828 theorem plus_minus_m_m: ∀n,m:nat.
829   m ≤ n → n = (n-m)+m.
830 #n #m #lemn @sym_eq /2/ qed.
831
832 theorem le_plus_minus_m_m: ∀n,m:nat. n ≤ (n-m)+m.
833 #n (elim n) // #a #Hind #m (cases m) // normalize #n/2/  
834 qed.
835
836 theorem minus_to_plus :∀n,m,p:nat.
837   m ≤ n → n-m = p → n = m+p.
838 #n #m #p #lemn #eqp (applyS plus_minus_m_m) //
839 qed.
840
841 theorem plus_to_minus :∀n,m,p:nat.n = m+p → n-m = p.
842 #n #m #p #eqp @sym_eq (applyS (minus_plus_m_m p m))
843 qed.
844
845 theorem minus_pred_pred : ∀n,m:nat. O < n → O < m → 
846 pred n - pred m = n - m.
847 #n #m #posn #posm @(lt_O_n_elim n posn) @(lt_O_n_elim m posm) //.
848 qed.
849
850
851 (*
852
853 theorem le_SO_minus: \forall n,m:nat.S n \leq m \to S O \leq m-n.
854 intros.elim H.elim (minus_Sn_n n).apply le_n.
855 rewrite > minus_Sn_m.
856 apply le_S.assumption.
857 apply lt_to_le.assumption.
858 qed.
859
860 theorem minus_le_S_minus_S: \forall n,m:nat. m-n \leq S (m-(S n)).
861 intros.
862 apply (nat_elim2 (\lambda n,m.m-n \leq S (m-(S n)))).
863 intro.elim n1.simplify.apply le_n_Sn.
864 simplify.rewrite < minus_n_O.apply le_n.
865 intros.simplify.apply le_n_Sn.
866 intros.simplify.apply H.
867 qed.
868
869 theorem lt_minus_S_n_to_le_minus_n : \forall n,m,p:nat. m-(S n) < p \to m-n \leq p. 
870 intros 3.intro.
871 (* autobatch *)
872 (* end auto($Revision: 9739 $) proof: TIME=1.33 SIZE=100 DEPTH=100 *)
873 apply (trans_le (m-n) (S (m-(S n))) p).
874 apply minus_le_S_minus_S.
875 assumption.
876 qed.
877
878 theorem le_minus_m: \forall n,m:nat. n-m \leq n.
879 intros.apply (nat_elim2 (\lambda m,n. n-m \leq n)).
880 intros.rewrite < minus_n_O.apply le_n.
881 intros.simplify.apply le_n.
882 intros.simplify.apply le_S.assumption.
883 qed.
884
885 theorem lt_minus_m: \forall n,m:nat. O < n \to O < m \to n-m \lt n.
886 intros.apply (lt_O_n_elim n H).intro.
887 apply (lt_O_n_elim m H1).intro.
888 simplify.unfold lt.apply le_S_S.apply le_minus_m.
889 qed.
890
891 theorem minus_le_O_to_le: \forall n,m:nat. n-m \leq O \to n \leq m.
892 intros 2.
893 apply (nat_elim2 (\lambda n,m:nat.n-m \leq O \to n \leq m)).
894 intros.apply le_O_n.
895 simplify.intros. assumption.
896 simplify.intros.apply le_S_S.apply H.assumption.
897 qed.
898 *)
899
900 (* monotonicity and galois *)
901
902 theorem monotonic_le_minus_l: 
903 ∀p,q,n:nat. q ≤ p → q-n ≤ p-n.
904 @nat_elim2 #p #q
905   [#lePO @(le_n_O_elim ? lePO) //
906   |//
907   |#Hind #n (cases n) // #a #leSS @Hind /2/
908   ]
909 qed.
910
911 theorem le_minus_to_plus: ∀n,m,p. n-m ≤ p → n≤ p+m.
912 #n #m #p #lep @transitive_le
913   [|@le_plus_minus_m_m | @monotonic_le_plus_l // ]
914 qed.
915
916 theorem le_minus_to_plus_r: ∀a,b,c. c ≤ b → a ≤ b - c → a + c ≤ b.
917 #a #b #c #Hlecb #H >(plus_minus_m_m … Hlecb) /2/
918 qed.
919
920 theorem le_plus_to_minus: ∀n,m,p. n ≤ p+m → n-m ≤ p.
921 #n #m #p #lep /2/ qed.
922
923 theorem le_plus_to_minus_r: ∀a,b,c. a + b ≤ c → a ≤ c -b.
924 #a #b #c #H @(le_plus_to_le_r … b) /2/
925 qed.
926
927 theorem lt_minus_to_plus: ∀a,b,c. a - b < c → a < c + b.
928 #a #b #c #H @not_le_to_lt 
929 @(not_to_not … (lt_to_not_le …H)) /2/
930 qed.
931
932 theorem lt_minus_to_plus_r: ∀a,b,c. a < b - c → a + c < b.
933 #a #b #c #H @not_le_to_lt @(not_to_not … (le_plus_to_minus …))
934 @lt_to_not_le //
935 qed.
936
937 theorem lt_plus_to_minus: ∀n,m,p. m ≤ n → n < p+m → n-m < p.
938 #n #m #p #lenm #H normalize <minus_Sn_m // @le_plus_to_minus //
939 qed.
940
941 theorem lt_plus_to_minus_r: ∀a,b,c. a + b < c → a < c - b.
942 #a #b #c #H @le_plus_to_minus_r //
943 qed. 
944
945 theorem monotonic_le_minus_r: 
946 ∀p,q,n:nat. q ≤ p → n-p ≤ n-q.
947 #p #q #n #lepq @le_plus_to_minus
948 @(transitive_le … (le_plus_minus_m_m ? q)) /2/
949 qed.
950
951 theorem eq_minus_O: ∀n,m:nat.
952   n ≤ m → n-m = O.
953 #n #m #lenm @(le_n_O_elim (n-m)) /2/
954 qed.
955
956 theorem distributive_times_minus: distributive ? times minus.
957 #a #b #c
958 (cases (decidable_lt b c)) #Hbc
959  [> eq_minus_O /2/ >eq_minus_O // 
960   @monotonic_le_times_r /2/
961  |@sym_eq (applyS plus_to_minus) <distributive_times_plus 
962   @eq_f (applyS plus_minus_m_m) /2/
963 qed.
964
965 theorem minus_plus: ∀n,m,p. n-m-p = n -(m+p).
966 #n #m #p 
967 cases (decidable_le (m+p) n) #Hlt
968   [@plus_to_minus @plus_to_minus <associative_plus
969    @minus_to_plus //
970   |cut (n ≤ m+p) [@(transitive_le … (le_n_Sn …)) @not_le_to_lt //]
971    #H >eq_minus_O /2/ >eq_minus_O // 
972   ]
973 qed.
974
975 (*
976 theorem plus_minus: ∀n,m,p. p ≤ m → (n+m)-p = n +(m-p).
977 #n #m #p #lepm @plus_to_minus >(commutative_plus p)
978 >associative_plus <plus_minus_m_m //
979 qed.  *)
980
981 theorem minus_minus: ∀n,m,p:nat. p ≤ m → m ≤ n →
982   p+(n-m) = n-(m-p).
983 #n #m #p #lepm #lemn
984 @sym_eq @plus_to_minus <associative_plus <plus_minus_m_m //
985 <commutative_plus <plus_minus_m_m //
986 qed.
987
988 (*********************** boolean arithmetics ********************) 
989 include "basics/bool.ma".
990
991 let rec eqb n m ≝ 
992 match n with 
993   [ O ⇒ match m with [ O ⇒ true | S q ⇒ false] 
994   | S p ⇒ match m with [ O ⇒ false | S q ⇒ eqb p q]
995   ].
996
997 theorem eqb_elim : ∀ n,m:nat.∀ P:bool → Prop.
998 (n=m → (P true)) → (n ≠ m → (P false)) → (P (eqb n m)). 
999 @nat_elim2 
1000   [#n (cases n) normalize /3/ 
1001   |normalize /3/
1002   |normalize /4/ 
1003   ] 
1004 qed.
1005
1006 theorem eqb_n_n: ∀n. eqb n n = true.
1007 #n (elim n) normalize // qed. 
1008
1009 theorem eqb_true_to_eq: ∀n,m:nat. eqb n m = true → n = m.
1010 #n #m @(eqb_elim n m) // #_ #abs @False_ind /2/ qed.
1011
1012 theorem eqb_false_to_not_eq: ∀n,m:nat. eqb n m = false → n ≠ m.
1013 #n #m @(eqb_elim n m) /2/ qed.
1014
1015 theorem eq_to_eqb_true: ∀n,m:nat.n = m → eqb n m = true.
1016 // qed.
1017
1018 theorem not_eq_to_eqb_false: ∀n,m:nat.
1019   n ≠  m → eqb n m = false.
1020 #n #m #noteq @eqb_elim// #Heq @False_ind /2/ qed.
1021
1022 let rec leb n m ≝ 
1023 match n with 
1024     [ O ⇒ true
1025     | (S p) ⇒
1026         match m with 
1027         [ O ⇒ false
1028               | (S q) ⇒ leb p q]].
1029
1030 theorem leb_elim: ∀n,m:nat. ∀P:bool → Prop. 
1031 (n ≤ m → P true) → (n ≰ m → P false) → P (leb n m).
1032 @nat_elim2 normalize
1033   [/2/
1034   |/3/
1035   |#n #m #Hind #P #Pt #Pf @Hind
1036     [#lenm @Pt @le_S_S // |#nlenm @Pf /2/ ]
1037   ]
1038 qed.
1039
1040 theorem leb_true_to_le:∀n,m.leb n m = true → n ≤ m.
1041 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
1042
1043 theorem leb_false_to_not_le:∀n,m.
1044   leb n m = false → n ≰ m.
1045 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
1046
1047 theorem le_to_leb_true: ∀n,m. n ≤ m → leb n m = true.
1048 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
1049
1050 theorem not_le_to_leb_false: ∀n,m. n ≰ m → leb n m = false.
1051 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
1052
1053 theorem lt_to_leb_false: ∀n,m. m < n → leb n m = false.
1054 /3/ qed.
1055
1056 (* serve anche ltb? 
1057 ndefinition ltb ≝λn,m. leb (S n) m.
1058
1059 theorem ltb_elim: ∀n,m:nat. ∀P:bool → Prop. 
1060 (n < m → P true) → (n ≮ m → P false) → P (ltb n m).
1061 #n #m #P #Hlt #Hnlt
1062 napply leb_elim /3/ qed.
1063
1064 theorem ltb_true_to_lt:∀n,m.ltb n m = true → n < m.
1065 #n #m #Hltb napply leb_true_to_le nassumption
1066 qed.
1067
1068 theorem ltb_false_to_not_lt:∀n,m.
1069   ltb n m = false → n ≮ m.
1070 #n #m #Hltb napply leb_false_to_not_le nassumption
1071 qed.
1072
1073 theorem lt_to_ltb_true: ∀n,m. n < m → ltb n m = true.
1074 #n #m #Hltb napply le_to_leb_true nassumption
1075 qed.
1076
1077 theorem le_to_ltb_false: ∀n,m. m \le n → ltb n m = false.
1078 #n #m #Hltb napply lt_to_leb_false /2/
1079 qed. *)
1080
1081 (* min e max *)
1082 definition min: nat →nat →nat ≝
1083 λn.λm. if_then_else ? (leb n m) n m.
1084
1085 definition max: nat →nat →nat ≝
1086 λn.λm. if_then_else ? (leb n m) m n.
1087
1088 lemma commutative_min: commutative ? min.
1089 #n #m normalize @leb_elim 
1090   [@leb_elim normalize /2/
1091   |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
1092   ] qed.
1093
1094 lemma le_minr: ∀i,n,m. i ≤ min n m → i ≤ m.
1095 #i #n #m normalize @leb_elim normalize /2/ qed. 
1096
1097 lemma le_minl: ∀i,n,m. i ≤ min n m → i ≤ n.
1098 /2/ qed.
1099
1100 lemma to_min: ∀i,n,m. i ≤ n → i ≤ m → i ≤ min n m.
1101 #i #n #m #lein #leim normalize (cases (leb n m)) 
1102 normalize // qed.
1103
1104 lemma commutative_max: commutative ? max.
1105 #n #m normalize @leb_elim 
1106   [@leb_elim normalize /2/
1107   |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
1108   ] qed.
1109
1110 lemma le_maxl: ∀i,n,m. max n m ≤ i → n ≤ i.
1111 #i #n #m normalize @leb_elim normalize /2/ qed. 
1112
1113 lemma le_maxr: ∀i,n,m. max n m ≤ i → m ≤ i.
1114 /2/ qed.
1115
1116 lemma to_max: ∀i,n,m. n ≤ i → m ≤ i → max n m ≤ i.
1117 #i #n #m #leni #lemi normalize (cases (leb n m)) 
1118 normalize // qed.
1119