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.
7 ||A|| This file is distributed under the terms of the
8 \ / GNU General Public License Version 2
10 V_______________________________________________________________ *)
12 include "basics/relations.ma".
14 inductive nat : Type[0] ≝
18 interpretation "Natural numbers" 'N = nat.
20 alias num (instance 0) = "natural number".
23 λn. match n with [ O ⇒ O | S p ⇒ p].
25 theorem pred_Sn : ∀n. n = pred (S n).
28 theorem injective_S : injective nat nat S.
32 theorem inj_S : \forall n,m:nat.(S n)=(S m) \to n=m.
35 theorem not_eq_S: ∀n,m:nat. n ≠ m → S n ≠ S m.
38 definition not_zero: nat → Prop ≝
39 λn: nat. match n with [ O ⇒ False | (S p) ⇒ True ].
41 theorem not_eq_O_S : ∀n:nat. O ≠ S n.
42 #n @nmk #eqOS (change with (not_zero O)) >eqOS // qed.
44 theorem not_eq_n_Sn: ∀n:nat. n ≠ S n.
49 (n=O → P O) → (∀m:nat. n= S m → P (S m)) → P n.
50 #n #P (elim n) /2/ qed.
56 → (∀n,m:nat. R n m → R (S n) (S m))
58 #R #ROn #RSO #RSS #n (elim n) // #n0 #Rn0m #m (cases m) /2/ qed.
60 theorem decidable_eq_nat : ∀n,m:nat.decidable (n=m).
61 @nat_elim2 #n [ (cases n) /2/ | /3/ | #m #Hind (cases Hind) /3/]
64 (*************************** plus ******************************)
67 match n with [ O ⇒ m | S p ⇒ S (plus p m) ].
69 interpretation "natural plus" 'plus x y = (plus x y).
71 theorem plus_O_n: ∀n:nat. n = O+n.
75 theorem plus_Sn_m: ∀n,m:nat. S (n + m) = S n + m.
79 theorem plus_n_O: ∀n:nat. n = n+O.
80 #n (elim n) normalize // qed.
82 theorem plus_n_Sm : ∀n,m:nat. S (n+m) = n + S m.
83 #n (elim n) normalize // qed.
86 theorem plus_Sn_m1: ∀n,m:nat. S m + n = n + S m.
87 #n (elim n) normalize // qed.
91 theorem plus_n_1 : ∀n:nat. S n = n+1.
95 theorem commutative_plus: commutative ? plus.
96 #n (elim n) normalize // qed.
98 theorem associative_plus : associative nat plus.
99 #n (elim n) normalize // qed.
101 theorem assoc_plus1: ∀a,b,c. c + (b + a) = b + c + a.
104 theorem injective_plus_r: ∀n:nat.injective nat nat (λm.n+m).
105 #n (elim n) normalize /3/ qed.
107 (* theorem inj_plus_r: \forall p,n,m:nat. p+n = p+m \to n=m
108 \def injective_plus_r.
110 theorem injective_plus_l: ∀m:nat.injective nat nat (λn.n+m).
113 (* theorem inj_plus_l: \forall p,n,m:nat. n+p = m+p \to n=m
114 \def injective_plus_l. *)
116 (*************************** times *****************************)
119 match n with [ O ⇒ O | S p ⇒ m+(times p m) ].
121 interpretation "natural times" 'times x y = (times x y).
123 theorem times_Sn_m: ∀n,m:nat. m+n*m = S n*m.
126 theorem times_O_n: ∀n:nat. O = O*n.
129 theorem times_n_O: ∀n:nat. O = n*O.
132 theorem times_n_Sm : ∀n,m:nat. n+(n*m) = n*(S m).
133 #n (elim n) normalize // qed.
135 theorem commutative_times : commutative nat times.
136 #n (elim n) normalize // qed.
138 (* variant sym_times : \forall n,m:nat. n*m = m*n \def
141 theorem distributive_times_plus : distributive nat times plus.
142 #n (elim n) normalize // qed.
144 theorem distributive_times_plus_r :
145 ∀a,b,c:nat. (b+c)*a = b*a + c*a.
148 theorem associative_times: associative nat times.
149 #n (elim n) normalize // qed.
151 lemma times_times: ∀x,y,z. x*(y*z) = y*(x*z).
154 (* ci servono questi risultati?
155 theorem times_O_to_O: ∀n,m:nat.n*m=O → n=O ∨ m=O.
157 #n #m #H normalize #H1 napply False_ind napply not_eq_O_S
160 theorem times_n_SO : ∀n:nat. n = n * S O.
163 theorem times_SSO_n : ∀n:nat. n + n = (S(S O)) * n.
166 nlemma times_SSO: \forall n.(S(S O))*(S n) = S(S((S(S O))*n)).
169 theorem or_eq_eq_S: \forall n.\exists m.
170 n = (S(S O))*m \lor n = S ((S(S O))*m).
173 ##|#a #H nelim H #b#ornelim or#aeq
180 (******************** ordering relations ************************)
182 inductive le (n:nat) : nat → Prop ≝
184 | le_S : ∀ m:nat. le n m → le n (S m).
186 interpretation "natural 'less or equal to'" 'leq x y = (le x y).
188 interpretation "natural 'neither less nor equal to'" 'nleq x y = (Not (le x y)).
190 definition lt: nat → nat → Prop ≝ λn,m. S n ≤ m.
192 interpretation "natural 'less than'" 'lt x y = (lt x y).
193 interpretation "natural 'not less than'" 'nless x y = (Not (lt x y)).
195 (* lemma eq_lt: ∀n,m. (n < m) = (S n ≤ m).
198 definition ge: nat → nat → Prop ≝ λn,m.m ≤ n.
200 interpretation "natural 'greater or equal to'" 'geq x y = (ge x y).
202 definition gt: nat → nat → Prop ≝ λn,m.m<n.
204 interpretation "natural 'greater than'" 'gt x y = (gt x y).
205 interpretation "natural 'not greater than'" 'ngtr x y = (Not (gt x y)).
207 theorem transitive_le : transitive nat le.
208 #a #b #c #leab #lebc (elim lebc) /2/
212 theorem trans_le: \forall n,m,p:nat. n \leq m \to m \leq p \to n \leq p
213 \def transitive_le. *)
215 theorem transitive_lt: transitive nat lt.
216 #a #b #c #ltab #ltbc (elim ltbc) /2/qed.
219 theorem trans_lt: \forall n,m,p:nat. lt n m \to lt m p \to lt n p
220 \def transitive_lt. *)
222 theorem le_S_S: ∀n,m:nat. n ≤ m → S n ≤ S m.
223 #n #m #lenm (elim lenm) /2/ qed.
225 theorem le_O_n : ∀n:nat. O ≤ n.
228 theorem le_n_Sn : ∀n:nat. n ≤ S n.
231 theorem le_pred_n : ∀n:nat. pred n ≤ n.
234 theorem monotonic_pred: monotonic ? le pred.
235 #n #m #lenm (elim lenm) /2/ qed.
237 theorem le_S_S_to_le: ∀n,m:nat. S n ≤ S m → n ≤ m.
241 (* this are instances of the le versions
242 theorem lt_S_S_to_lt: ∀n,m. S n < S m → n < m.
245 theorem lt_to_lt_S_S: ∀n,m. n < m → S n < S m.
248 theorem lt_to_not_zero : ∀n,m:nat. n < m → not_zero m.
249 #n #m #Hlt (elim Hlt) // qed.
252 theorem not_le_Sn_O: ∀ n:nat. S n ≰ O.
253 #n @nmk #Hlen0 @(lt_to_not_zero ?? Hlen0) qed.
255 theorem not_le_to_not_le_S_S: ∀ n,m:nat. n ≰ m → S n ≰ S m.
258 theorem not_le_S_S_to_not_le: ∀ n,m:nat. S n ≰ S m → n ≰ m.
261 theorem decidable_le: ∀n,m. decidable (n≤m).
262 @nat_elim2 #n /2/ #m * /3/ qed.
264 theorem decidable_lt: ∀n,m. decidable (n < m).
265 #n #m @decidable_le qed.
267 theorem not_le_Sn_n: ∀n:nat. S n ≰ n.
270 (* this is le_S_S_to_le
271 theorem lt_S_to_le: ∀n,m:nat. n < S m → n ≤ m.
275 lemma le_gen: ∀P:nat → Prop.∀n.(∀i. i ≤ n → P i) → P n.
278 theorem not_le_to_lt: ∀n,m. n ≰ m → m < n.
282 |#m #Hind #HnotleSS @le_S_S /3/
286 theorem lt_to_not_le: ∀n,m. n < m → m ≰ n.
287 #n #m #Hltnm (elim Hltnm) /3/ qed.
289 theorem not_lt_to_le: ∀n,m:nat. n ≮ m → m ≤ n.
292 theorem le_to_not_lt: ∀n,m:nat. n ≤ m → m ≮ n.
293 #n #m #H @lt_to_not_le /2/ (* /3/ *) qed.
295 (* lt and le trans *)
297 theorem lt_to_le_to_lt: ∀n,m,p:nat. n < m → m ≤ p → n < p.
298 #n #m #p #H #H1 (elim H1) /2/ qed.
300 theorem le_to_lt_to_lt: ∀n,m,p:nat. n ≤ m → m < p → n < p.
301 #n #m #p #H (elim H) /3/ qed.
303 theorem lt_S_to_lt: ∀n,m. S n < m → n < m.
306 theorem ltn_to_ltO: ∀n,m:nat. n < m → O < m.
310 theorem lt_SO_n_to_lt_O_pred_n: \forall n:nat.
311 (S O) \lt n \to O \lt (pred n).
313 apply (ltn_to_ltO (pred (S O)) (pred n) ?).
314 apply (lt_pred (S O) n)
320 theorem lt_O_n_elim: ∀n:nat. O < n →
321 ∀P:nat → Prop.(∀m:nat.P (S m)) → P n.
322 #n (elim n) // #abs @False_ind /2/
325 theorem S_pred: ∀n. 0 < n → S(pred n) = n.
326 #n #posn (cases posn) //
330 theorem lt_pred: \forall n,m.
331 O < n \to n < m \to pred n < pred m.
333 [intros.apply False_ind.apply (not_le_Sn_O ? H)
334 |intros.apply False_ind.apply (not_le_Sn_O ? H1)
335 |intros.simplify.unfold.apply le_S_S_to_le.assumption
339 theorem le_pred_to_le:
340 ∀n,m. O < m → pred n ≤ pred m → n ≤ m.
356 theorem le_to_or_lt_eq: ∀n,m:nat. n ≤ m → n < m ∨ n = m.
357 #n #m #lenm (elim lenm) /3/ qed.
360 theorem lt_to_not_eq : ∀n,m:nat. n < m → n ≠ m.
361 #n #m #H @not_to_not /2/ qed.
364 theorem eq_to_not_lt: ∀a,b:nat. a = b → a ≮ b.
369 apply (lt_to_not_eq b b)
375 theorem lt_n_m_to_not_lt_m_Sn: ∀n,m. n < m → m ≮ S n.
381 generalize in match (le_S_S ? ? H)
383 generalize in match (transitive_le ? ? ? H2 H1)
385 apply (not_le_Sn_n ? H3).
388 theorem not_eq_to_le_to_lt: ∀n,m. n≠m → n≤m → n<m.
389 #n #m #Hneq #Hle cases (le_to_or_lt_eq ?? Hle) //
392 nelim (Hneq Heq) qed. *)
395 theorem le_n_O_to_eq : ∀n:nat. n ≤ O → O=n.
396 #n (cases n) // #a #abs @False_ind /2/ qed.
398 theorem le_n_O_elim: ∀n:nat. n ≤ O → ∀P: nat →Prop. P O → P n.
399 #n (cases n) // #a #abs @False_ind /2/ qed.
401 theorem le_n_Sm_elim : ∀n,m:nat.n ≤ S m →
402 ∀P:Prop. (S n ≤ S m → P) → (n=S m → P) → P.
403 #n #m #Hle #P (elim Hle) /3/ qed.
407 theorem le_to_le_to_eq: ∀n,m. n ≤ m → m ≤ n → n = m.
411 theorem lt_O_S : ∀n:nat. O < S n.
415 (* other abstract properties *)
416 theorem antisymmetric_le : antisymmetric nat le.
417 unfold antisymmetric.intros 2.
418 apply (nat_elim2 (\lambda n,m.(n \leq m \to m \leq n \to n=m))).
419 intros.apply le_n_O_to_eq.assumption.
420 intros.apply False_ind.apply (not_le_Sn_O ? H).
421 intros.apply eq_f.apply H.
422 apply le_S_S_to_le.assumption.
423 apply le_S_S_to_le.assumption.
426 theorem antisym_le: \forall n,m:nat. n \leq m \to m \leq n \to n=m
427 \def antisymmetric_le.
429 theorem le_n_m_to_lt_m_Sn_to_eq_n_m: ∀n,m. n ≤ m → m < S n → n=m.
432 generalize in match (le_S_S_to_le ? ? H1)
439 (* well founded induction principles *)
441 theorem nat_elim1 : ∀n:nat.∀P:nat → Prop.
442 (∀m.(∀p. p < m → P p) → P m) → P n.
444 cut (∀q:nat. q ≤ n → P q) /2/
446 [#q #HleO (* applica male *)
447 @(le_n_O_elim ? HleO)
448 @H #p #ltpO @False_ind /2/ (* 3 *)
450 @H #a #lta @Hind @le_S_S_to_le /2/
454 (* some properties of functions *)
456 definition increasing \def \lambda f:nat \to nat.
457 \forall n:nat. f n < f (S n).
459 theorem increasing_to_monotonic: \forall f:nat \to nat.
460 increasing f \to monotonic nat lt f.
461 unfold monotonic.unfold lt.unfold increasing.unfold lt.intros.elim H1.apply H.
462 apply (trans_le ? (f n1)).
463 assumption.apply (trans_le ? (S (f n1))).
468 theorem le_n_fn: \forall f:nat \to nat. (increasing f)
469 \to \forall n:nat. n \le (f n).
472 apply (trans_le ? (S (f n1))).
473 apply le_S_S.apply H1.
474 simplify in H. unfold increasing in H.unfold lt in H.apply H.
477 theorem increasing_to_le: \forall f:nat \to nat. (increasing f)
478 \to \forall m:nat. \exists i. m \le (f i).
480 apply (ex_intro ? ? O).apply le_O_n.
482 apply (ex_intro ? ? (S a)).
483 apply (trans_le ? (S (f a))).
484 apply le_S_S.assumption.
485 simplify in H.unfold increasing in H.unfold lt in H.
489 theorem increasing_to_le2: \forall f:nat \to nat. (increasing f)
490 \to \forall m:nat. (f O) \le m \to
491 \exists i. (f i) \le m \land m <(f (S i)).
493 apply (ex_intro ? ? O).
494 split.apply le_n.apply H.
496 cut ((S n1) < (f (S a)) \lor (S n1) = (f (S a))).
498 apply (ex_intro ? ? a).
499 split.apply le_S. assumption.assumption.
500 apply (ex_intro ? ? (S a)).
501 split.rewrite < H7.apply le_n.
504 apply le_to_or_lt_eq.apply H6.
508 (*********************** monotonicity ***************************)
509 theorem monotonic_le_plus_r:
510 ∀n:nat.monotonic nat le (λm.n + m).
511 #n #a #b (elim n) normalize //
512 #m #H #leab @le_S_S /2/ qed.
515 theorem le_plus_r: ∀p,n,m:nat. n ≤ m → p + n ≤ p + m
516 ≝ monotonic_le_plus_r. *)
518 theorem monotonic_le_plus_l:
519 ∀m:nat.monotonic nat le (λn.n + m).
523 theorem le_plus_l: \forall p,n,m:nat. n \le m \to n + p \le m + p
524 \def monotonic_le_plus_l. *)
526 theorem le_plus: ∀n1,n2,m1,m2:nat. n1 ≤ n2 → m1 ≤ m2
528 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1+m2))
531 theorem le_plus_n :∀n,m:nat. m ≤ n + m.
534 lemma le_plus_a: ∀a,n,m. n ≤ m → n ≤ a + m.
537 lemma le_plus_b: ∀b,n,m. n + b ≤ m → n ≤ m.
540 theorem le_plus_n_r :∀n,m:nat. m ≤ m + n.
543 theorem eq_plus_to_le: ∀n,m,p:nat.n=m+p → m ≤ n.
546 theorem le_plus_to_le: ∀a,n,m. a + n ≤ a + m → n ≤ m.
547 #a (elim a) normalize /3/ qed.
549 theorem le_plus_to_le_r: ∀a,n,m. n + a ≤ m +a → n ≤ m.
554 theorem monotonic_lt_plus_r:
555 ∀n:nat.monotonic nat lt (λm.n+m).
559 variant lt_plus_r: \forall n,p,q:nat. p < q \to n + p < n + q \def
560 monotonic_lt_plus_r. *)
562 theorem monotonic_lt_plus_l:
563 ∀n:nat.monotonic nat lt (λm.m+n).
567 variant lt_plus_l: \forall n,p,q:nat. p < q \to p + n < q + n \def
568 monotonic_lt_plus_l. *)
570 theorem lt_plus: ∀n,m,p,q:nat. n < m → p < q → n + p < m + q.
571 #n #m #p #q #ltnm #ltpq
572 @(transitive_lt ? (n+q))/2/ qed.
574 theorem lt_plus_to_lt_l :∀n,p,q:nat. p+n < q+n → p<q.
577 theorem lt_plus_to_lt_r :∀n,p,q:nat. n+p < n+q → p<q.
581 theorem le_to_lt_to_lt_plus: ∀a,b,c,d:nat.
582 a ≤ c → b < d → a + b < c+d.
583 (* bello /2/ un po' lento *)
584 #a #b #c #d #leac #lebd
585 normalize napplyS le_plus // qed.
589 theorem monotonic_le_times_r:
590 ∀n:nat.monotonic nat le (λm. n * m).
591 #n #x #y #lexy (elim n) normalize//(* lento /2/*)
596 theorem le_times_r: \forall p,n,m:nat. n \le m \to p*n \le p*m
597 \def monotonic_le_times_r. *)
600 theorem monotonic_le_times_l:
601 ∀m:nat.monotonic nat le (λn.n*m).
606 theorem le_times_l: \forall p,n,m:nat. n \le m \to n*p \le m*p
607 \def monotonic_le_times_l. *)
609 theorem le_times: ∀n1,n2,m1,m2:nat.
610 n1 ≤ n2 → m1 ≤ m2 → n1*m1 ≤ n2*m2.
611 #n1 #n2 #m1 #m2 #len #lem @(transitive_le ? (n1*m2)) /2/
615 theorem lt_times_n: ∀n,m:nat. O < n → m ≤ n*m.
618 theorem le_times_to_le:
619 ∀a,n,m. O < a → a * n ≤ a * m → n ≤ m.
620 #a @nat_elim2 normalize
623 @(transitive_le ? (a*S n)) /2/
630 theorem le_S_times_2: ∀n,m.O < m → n ≤ m → S n ≤ 2*m.
631 #n #m #posm #lenm (* interessante *)
632 applyS (le_plus n m) // qed. *)
636 theorem lt_O_times_S_S: ∀n,m:nat.O < (S n)*(S m).
637 intros.simplify.unfold lt.apply le_S_S.apply le_O_n.
641 theorem lt_times_eq_O: \forall a,b:nat.
642 O < a → a * b = O → b = O.
649 rewrite > (S_pred a) in H1
651 apply (eq_to_not_lt O ((S (pred a))*(S m)))
654 | apply lt_O_times_S_S
661 theorem O_lt_times_to_O_lt: \forall a,c:nat.
662 O \lt (a * c) \to O \lt a.
674 lemma lt_times_to_lt_O: \forall i,n,m:nat. i < n*m \to O < m.
676 elim (le_to_or_lt_eq O ? (le_O_n m))
680 rewrite < times_n_O in H.
681 apply (not_le_Sn_O ? H)
686 theorem monotonic_lt_times_r:
687 ∀n:nat.monotonic nat lt (λm.(S n)*m).
691 simplify.rewrite < plus_n_O.rewrite < plus_n_O.assumption.
692 apply lt_plus.assumption.assumption.
695 theorem monotonic_lt_times_l:
696 ∀c:nat. O < c → monotonic nat lt (λt.(t*c)).
698 (elim ltnm) normalize
700 |#a #_ #lt1 @(transitive_le … lt1) //
704 theorem monotonic_lt_times_r:
705 ∀c:nat. O < c → monotonic nat lt (λt.(c*t)).
708 theorem lt_to_le_to_lt_times:
709 ∀n,m,p,q:nat. n < m → p ≤ q → O < q → n*p < m*q.
710 #n #m #p #q #ltnm #lepq #posq
711 @(le_to_lt_to_lt ? (n*q))
712 [@monotonic_le_times_r //
713 |@monotonic_lt_times_l //
717 theorem lt_times:∀n,m,p,q:nat. n<m → p<q → n*p < m*q.
718 #n #m #p #q #ltnm #ltpq @lt_to_le_to_lt_times/2/
721 theorem lt_times_n_to_lt_l:
722 ∀n,p,q:nat. p*n < q*n → p < q.
723 #n #p #q #Hlt (elim (decidable_lt p q)) //
724 #nltpq @False_ind @(absurd ? ? (lt_to_not_le ? ? Hlt))
725 applyS monotonic_le_times_r /2/
728 theorem lt_times_n_to_lt_r:
729 ∀n,p,q:nat. n*p < n*q → p < q.
733 theorem nat_compare_times_l : \forall n,p,q:nat.
734 nat_compare p q = nat_compare ((S n) * p) ((S n) * q).
735 intros.apply nat_compare_elim.intro.
736 apply nat_compare_elim.
739 apply (inj_times_r n).assumption.
740 apply lt_to_not_eq. assumption.
742 apply (lt_times_to_lt_r n).assumption.
743 apply le_to_not_lt.apply lt_to_le.assumption.
744 intro.rewrite < H.rewrite > nat_compare_n_n.reflexivity.
745 intro.apply nat_compare_elim.intro.
747 apply (lt_times_to_lt_r n).assumption.
748 apply le_to_not_lt.apply lt_to_le.assumption.
751 apply (inj_times_r n).assumption.
752 apply lt_to_not_eq.assumption.
757 theorem lt_times_plus_times: \forall a,b,n,m:nat.
758 a < n \to b < m \to a*m + b < n*m.
761 [intros.apply False_ind.apply (not_le_Sn_O ? H)
765 change with (S b+a*m1 \leq m1+m*m1).
769 [apply le_S_S_to_le.assumption
776 (************************** minus ******************************)
784 | S q ⇒ minus p q ]].
786 interpretation "natural minus" 'minus x y = (minus x y).
788 theorem minus_S_S: ∀n,m:nat.S n - S m = n -m.
791 theorem minus_O_n: ∀n:nat.O=O-n.
794 theorem minus_n_O: ∀n:nat.n=n-O.
797 theorem minus_n_n: ∀n:nat.O=n-n.
800 theorem minus_Sn_n: ∀n:nat. S O = (S n)-n.
801 #n (elim n) normalize // qed.
803 theorem minus_Sn_m: ∀m,n:nat. m ≤ n → S n -m = S (n-m).
804 (* qualcosa da capire qui
805 #n #m #lenm nelim lenm napplyS refl_eq. *)
808 |#n #abs @False_ind /2/
809 |#n #m #Hind #c applyS Hind /2/
814 theorem not_eq_to_le_to_le_minus:
815 ∀n,m.n ≠ m → n ≤ m → n ≤ m - 1.
816 #n * #m (cases m// #m normalize
817 #H #H1 napply le_S_S_to_le
818 napplyS (not_eq_to_le_to_lt n (S m) H H1)
821 theorem eq_minus_S_pred: ∀n,m. n - (S m) = pred(n -m).
822 @nat_elim2 normalize // qed.
825 ∀m,n,p:nat. m ≤ n → (n-m)+p = (n+p)-m.
828 |#n #p #abs @False_ind /2/
833 theorem minus_plus_m_m: ∀n,m:nat.n = (n+m)-m.
836 theorem plus_minus_m_m: ∀n,m:nat.
838 #n #m #lemn @sym_eq /2/ qed.
840 theorem le_plus_minus_m_m: ∀n,m:nat. n ≤ (n-m)+m.
841 #n (elim n) // #a #Hind #m (cases m) // normalize #n/2/
844 theorem minus_to_plus :∀n,m,p:nat.
845 m ≤ n → n-m = p → n = m+p.
846 #n #m #p #lemn #eqp (applyS plus_minus_m_m) //
849 theorem plus_to_minus :∀n,m,p:nat.n = m+p → n-m = p.
850 #n #m #p #eqp @sym_eq (applyS (minus_plus_m_m p m))
853 theorem minus_pred_pred : ∀n,m:nat. O < n → O < m →
854 pred n - pred m = n - m.
855 #n #m #posn #posm @(lt_O_n_elim n posn) @(lt_O_n_elim m posm) //.
861 theorem le_SO_minus: \forall n,m:nat.S n \leq m \to S O \leq m-n.
862 intros.elim H.elim (minus_Sn_n n).apply le_n.
863 rewrite > minus_Sn_m.
864 apply le_S.assumption.
865 apply lt_to_le.assumption.
868 theorem minus_le_S_minus_S: \forall n,m:nat. m-n \leq S (m-(S n)).
870 apply (nat_elim2 (\lambda n,m.m-n \leq S (m-(S n)))).
871 intro.elim n1.simplify.apply le_n_Sn.
872 simplify.rewrite < minus_n_O.apply le_n.
873 intros.simplify.apply le_n_Sn.
874 intros.simplify.apply H.
877 theorem lt_minus_S_n_to_le_minus_n : \forall n,m,p:nat. m-(S n) < p \to m-n \leq p.
880 (* end auto($Revision: 9739 $) proof: TIME=1.33 SIZE=100 DEPTH=100 *)
881 apply (trans_le (m-n) (S (m-(S n))) p).
882 apply minus_le_S_minus_S.
886 theorem le_minus_m: \forall n,m:nat. n-m \leq n.
887 intros.apply (nat_elim2 (\lambda m,n. n-m \leq n)).
888 intros.rewrite < minus_n_O.apply le_n.
889 intros.simplify.apply le_n.
890 intros.simplify.apply le_S.assumption.
893 theorem lt_minus_m: \forall n,m:nat. O < n \to O < m \to n-m \lt n.
894 intros.apply (lt_O_n_elim n H).intro.
895 apply (lt_O_n_elim m H1).intro.
896 simplify.unfold lt.apply le_S_S.apply le_minus_m.
899 theorem minus_le_O_to_le: \forall n,m:nat. n-m \leq O \to n \leq m.
901 apply (nat_elim2 (\lambda n,m:nat.n-m \leq O \to n \leq m)).
903 simplify.intros. assumption.
904 simplify.intros.apply le_S_S.apply H.assumption.
908 (* monotonicity and galois *)
910 theorem monotonic_le_minus_l:
911 ∀p,q,n:nat. q ≤ p → q-n ≤ p-n.
913 [#lePO @(le_n_O_elim ? lePO) //
915 |#Hind #n (cases n) // #a #leSS @Hind /2/
919 theorem le_minus_to_plus: ∀n,m,p. n-m ≤ p → n≤ p+m.
920 #n #m #p #lep @transitive_le
921 [|@le_plus_minus_m_m | @monotonic_le_plus_l // ]
924 theorem le_plus_to_minus: ∀n,m,p. n ≤ p+m → n-m ≤ p.
925 #n #m #p #lep /2/ qed.
927 theorem monotonic_le_minus_r:
928 ∀p,q,n:nat. q ≤ p → n-p ≤ n-q.
929 #p #q #n #lepq @le_plus_to_minus
930 @(transitive_le … (le_plus_minus_m_m ? q)) /2/
933 theorem eq_minus_O: ∀n,m:nat.
935 #n #m #lenm @(le_n_O_elim (n-m)) /2/
938 theorem distributive_times_minus: distributive ? times minus.
940 (cases (decidable_lt b c)) #Hbc
941 [> eq_minus_O /2/ >eq_minus_O //
942 @monotonic_le_times_r /2/
943 |@sym_eq (applyS plus_to_minus) <distributive_times_plus
944 @eq_f (applyS plus_minus_m_m) /2/
947 theorem minus_minus: ∀n,m,p. n-m-p = n -(m+p).
949 cases (decidable_le (m+p) n) #Hlt
950 [@plus_to_minus @plus_to_minus <associative_plus
952 |cut (n ≤ m+p) [@(transitive_le … (le_n_Sn …)) @not_le_to_lt //]
953 #H >eq_minus_O /2/ >eq_minus_O //
957 (*********************** boolean arithmetics ********************)
958 include "basics/bool.ma".
962 [ O ⇒ match m with [ O ⇒ true | S q ⇒ false]
963 | S p ⇒ match m with [ O ⇒ false | S q ⇒ eqb p q]
966 theorem eqb_elim : ∀ n,m:nat.∀ P:bool → Prop.
967 (n=m → (P true)) → (n ≠ m → (P false)) → (P (eqb n m)).
969 [#n (cases n) normalize /3/
975 theorem eqb_n_n: ∀n. eqb n n = true.
976 #n (elim n) normalize // qed.
978 theorem eqb_true_to_eq: ∀n,m:nat. eqb n m = true → n = m.
979 #n #m @(eqb_elim n m) // #_ #abs @False_ind /2/ qed.
981 theorem eqb_false_to_not_eq: ∀n,m:nat. eqb n m = false → n ≠ m.
982 #n #m @(eqb_elim n m) /2/ qed.
984 theorem eq_to_eqb_true: ∀n,m:nat.n = m → eqb n m = true.
987 theorem not_eq_to_eqb_false: ∀n,m:nat.
988 n ≠ m → eqb n m = false.
989 #n #m #noteq @eqb_elim// #Heq @False_ind /2/ qed.
999 theorem leb_elim: ∀n,m:nat. ∀P:bool → Prop.
1000 (n ≤ m → P true) → (n ≰ m → P false) → P (leb n m).
1001 @nat_elim2 normalize
1004 |#n #m #Hind #P #Pt #Pf @Hind
1005 [#lenm @Pt @le_S_S // |#nlenm @Pf /2/ ]
1009 theorem leb_true_to_le:∀n,m.leb n m = true → n ≤ m.
1010 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
1012 theorem leb_false_to_not_le:∀n,m.
1013 leb n m = false → n ≰ m.
1014 #n #m @leb_elim // #_ #abs @False_ind /2/ qed.
1016 theorem le_to_leb_true: ∀n,m. n ≤ m → leb n m = true.
1017 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
1019 theorem not_le_to_leb_false: ∀n,m. n ≰ m → leb n m = false.
1020 #n #m @leb_elim // #H #H1 @False_ind /2/ qed.
1022 theorem lt_to_leb_false: ∀n,m. m < n → leb n m = false.
1026 ndefinition ltb ≝λn,m. leb (S n) m.
1028 theorem ltb_elim: ∀n,m:nat. ∀P:bool → Prop.
1029 (n < m → P true) → (n ≮ m → P false) → P (ltb n m).
1031 napply leb_elim /3/ qed.
1033 theorem ltb_true_to_lt:∀n,m.ltb n m = true → n < m.
1034 #n #m #Hltb napply leb_true_to_le nassumption
1037 theorem ltb_false_to_not_lt:∀n,m.
1038 ltb n m = false → n ≮ m.
1039 #n #m #Hltb napply leb_false_to_not_le nassumption
1042 theorem lt_to_ltb_true: ∀n,m. n < m → ltb n m = true.
1043 #n #m #Hltb napply le_to_leb_true nassumption
1046 theorem le_to_ltb_false: ∀n,m. m \le n → ltb n m = false.
1047 #n #m #Hltb napply lt_to_leb_false /2/
1051 definition min: nat →nat →nat ≝
1052 λn.λm. if_then_else ? (leb n m) n m.
1054 definition max: nat →nat →nat ≝
1055 λn.λm. if_then_else ? (leb n m) m n.
1057 lemma commutative_min: commutative ? min.
1058 #n #m normalize @leb_elim
1059 [@leb_elim normalize /2/
1060 |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
1063 lemma le_minr: ∀i,n,m. i ≤ min n m → i ≤ m.
1064 #i #n #m normalize @leb_elim normalize /2/ qed.
1066 lemma le_minl: ∀i,n,m. i ≤ min n m → i ≤ n.
1069 lemma to_min: ∀i,n,m. i ≤ n → i ≤ m → i ≤ min n m.
1070 #i #n #m #lein #leim normalize (cases (leb n m))
1073 lemma commutative_max: commutative ? max.
1074 #n #m normalize @leb_elim
1075 [@leb_elim normalize /2/
1076 |#notle >(le_to_leb_true …) // @(transitive_le ? (S m)) /2/
1079 lemma le_maxl: ∀i,n,m. max n m ≤ i → n ≤ i.
1080 #i #n #m normalize @leb_elim normalize /2/ qed.
1082 lemma le_maxr: ∀i,n,m. max n m ≤ i → m ≤ i.
1085 lemma to_max: ∀i,n,m. n ≤ i → m ≤ i → max n m ≤ i.
1086 #i #n #m #leni #lemi normalize (cases (leb n m))