1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| A.Asperti, C.Sacerdoti Coen, *)
8 (* ||A|| E.Tassi, S.Zacchiroli *)
10 (* \ / Matita is distributed under the terms of the *)
11 (* v GNU Lesser General Public License Version 2.1 *)
13 (**************************************************************************)
15 set "baseuri" "cic:/matita/library_auto/nat/primes".
17 include "auto/nat/div_and_mod.ma".
18 include "auto/nat/minimization.ma".
19 include "auto/nat/sigma_and_pi.ma".
20 include "auto/nat/factorial.ma".
22 inductive divides (n,m:nat) : Prop \def
23 witness : \forall p:nat.m = times n p \to divides n m.
25 interpretation "divides" 'divides n m = (cic:/matita/library_auto/nat/primes/divides.ind#xpointer(1/1) n m).
26 interpretation "not divides" 'ndivides n m =
27 (cic:/matita/logic/connectives/Not.con (cic:/matita/library_auto/nat/primes/divides.ind#xpointer(1/1) n m)).
29 theorem reflexive_divides : reflexive nat divides.
32 exact (witness x x (S O) (times_n_SO x)).
35 theorem divides_to_div_mod_spec :
36 \forall n,m. O < n \to n \divides m \to div_mod_spec m n (m / n) O.
42 | apply (lt_O_n_elim n H).
51 theorem div_mod_spec_to_divides :
52 \forall n,m,p. div_mod_spec m n p O \to n \divides m.
56 (*apply (witness n m p).
58 rewrite > (plus_n_O (p*n)).
62 theorem divides_to_mod_O:
63 \forall n,m. O < n \to n \divides m \to (m \mod n) = O.
65 apply (div_mod_spec_to_eq2 m n (m / n) (m \mod n) (m / n) O)
67 (*apply div_mod_spec_div_mod.
70 (*apply divides_to_div_mod_spec;assumption*)
74 theorem mod_O_to_divides:
75 \forall n,m. O< n \to (m \mod n) = O \to n \divides m.
77 apply (witness n m (m / n)).
78 rewrite > (plus_n_O (n * (m / n))).
82 (* Andrea: perche' hint non lo trova ?*)
87 theorem divides_n_O: \forall n:nat. n \divides O.
90 (*apply (witness n O O).
94 theorem divides_n_n: \forall n:nat. n \divides n.
97 apply (witness n n (S O)).
101 theorem divides_SO_n: \forall n:nat. (S O) \divides n.
104 (*apply (witness (S O) n n).
109 theorem divides_plus: \forall n,p,q:nat.
110 n \divides p \to n \divides q \to n \divides p+q.
114 apply (witness n (p+q) (n2+n1)).
119 apply distr_times_plus.*)
122 theorem divides_minus: \forall n,p,q:nat.
123 divides n p \to divides n q \to divides n (p-q).
127 apply (witness n (p-q) (n2-n1)).
132 apply distr_times_minus.*)
135 theorem divides_times: \forall n,m,p,q:nat.
136 n \divides p \to m \divides q \to n*m \divides p*q.
140 apply (witness (n*m) (p*q) (n2*n1)).
143 apply (trans_eq nat ? (n*(m*(n2*n1))))
144 [ apply (trans_eq nat ? (n*(n2*(m*n1))))
147 apply (trans_eq nat ? ((n2*m)*n1))
151 | rewrite > (sym_times n2 m).
161 theorem transitive_divides: transitive ? divides.
166 apply (witness x z (n2*n)).
173 variant trans_divides: \forall n,m,p.
174 n \divides m \to m \divides p \to n \divides p \def transitive_divides.
176 theorem eq_mod_to_divides:\forall n,m,p. O< p \to
177 mod n p = mod m p \to divides p (n-m).
179 cut (n \le m \or \not n \le m)
184 apply (witness p O O).
187 (*apply eq_minus_n_m_O.
190 | apply (witness p (n-m) ((div n p)-(div m p))).
191 rewrite > distr_times_minus.
193 rewrite > (sym_times p).
194 cut ((div n p)*p = n - (mod n p))
196 rewrite > eq_minus_minus_minus_plus.
212 | apply (decidable_le n m)
216 theorem antisymmetric_divides: antisymmetric nat divides.
217 unfold antisymmetric.
235 (*rewrite < times_n_O.
238 apply antisymmetric_le
240 rewrite > times_n_SO in \vdash (? % ?).
247 rewrite > times_n_SO in \vdash (? % ?).
259 theorem divides_to_le : \forall n,m. O < m \to n \divides m \to n \le m.
264 [ apply (lt_O_n_elim n2 Hcut).
267 (*rewrite < sym_times.
271 | elim (le_to_or_lt_eq O n2)
278 apply (not_le_Sn_n O)
285 theorem divides_to_lt_O : \forall n,m. O < m \to n \divides m \to O < n.
288 elim (le_to_or_lt_eq O n (le_O_n n))
297 exact (not_le_Sn_n O)*)
302 (* boolean divides *)
303 definition divides_b : nat \to nat \to bool \def
304 \lambda n,m :nat. (eqb (m \mod n) O).
306 theorem divides_b_to_Prop :
307 \forall n,m:nat. O < n \to
308 match divides_b n m with
309 [ true \Rightarrow n \divides m
310 | false \Rightarrow n \ndivides m].
317 (*apply mod_O_to_divides;assumption*)
324 apply divides_to_mod_O;assumption*)
328 theorem divides_b_true_to_divides :
329 \forall n,m:nat. O < n \to
330 (divides_b n m = true ) \to n \divides m.
334 [ true \Rightarrow n \divides m
335 | false \Rightarrow n \ndivides m].
337 apply divides_b_to_Prop.
341 theorem divides_b_false_to_not_divides :
342 \forall n,m:nat. O < n \to
343 (divides_b n m = false ) \to n \ndivides m.
347 [ true \Rightarrow n \divides m
348 | false \Rightarrow n \ndivides m].
350 apply divides_b_to_Prop.
354 theorem decidable_divides: \forall n,m:nat.O < n \to
355 decidable (n \divides m).
359 (match divides_b n m with
360 [ true \Rightarrow n \divides m
361 | false \Rightarrow n \ndivides m] \to n \divides m \lor n \ndivides m)
363 apply divides_b_to_Prop.
365 | elim (divides_b n m)
367 (*qui auto non chiude il goal, chiuso dalla sola apply H1*)
370 (*qui auto non chiude il goal, chiuso dalla sola apply H1*)
376 theorem divides_to_divides_b_true : \forall n,m:nat. O < n \to
377 n \divides m \to divides_b n m = true.
379 cut (match (divides_b n m) with
380 [ true \Rightarrow n \divides m
381 | false \Rightarrow n \ndivides m] \to ((divides_b n m) = true))
383 apply divides_b_to_Prop.
385 | elim (divides_b n m)
387 | absurd (n \divides m)
389 | (*qui auto non chiude il goal, chiuso dalla sola applicazione di assumption*)
396 theorem not_divides_to_divides_b_false: \forall n,m:nat. O < n \to
397 \lnot(n \divides m) \to (divides_b n m) = false.
399 cut (match (divides_b n m) with
400 [ true \Rightarrow n \divides m
401 | false \Rightarrow n \ndivides m] \to ((divides_b n m) = false))
403 apply divides_b_to_Prop.
405 | elim (divides_b n m)
406 [ absurd (n \divides m)
407 [ (*qui auto non chiude il goal, chiuso dalla sola tattica assumption*)
417 theorem divides_f_pi_f : \forall f:nat \to nat.\forall n,m,i:nat.
418 m \le i \to i \le n+m \to f i \divides pi n f m.
426 | apply antisymmetric_le
432 cut (i < S n1+m \lor i = S n1 + m)
434 [ apply (transitive_divides ? (pi n1 f m))
437 (*apply le_S_S_to_le.
440 (*apply (witness ? ? (f (S n1+m))).
445 apply (witness ? ? (pi n1 f m)).
449 (*apply le_to_or_lt_eq.
456 theorem mod_S_pi: \forall f:nat \to nat.\forall n,i:nat.
457 i < n \to (S O) < (f i) \to (S (pi n f)) \mod (f i) = (S O).
458 intros.cut (pi n f) \mod (f i) = O.
460 apply mod_S.apply trans_lt O (S O).apply le_n (S O).assumption.
461 rewrite > Hcut.assumption.
462 apply divides_to_mod_O.apply trans_lt O (S O).apply le_n (S O).assumption.
463 apply divides_f_pi_f.assumption.
467 (* divides and fact *)
468 theorem divides_fact : \forall n,i:nat.
469 O < i \to i \le n \to i \divides n!.
475 (*apply (le_n_O_elim i H1).
476 apply (not_le_Sn_O O)*)
478 | change with (i \divides (S n1)*n1!).
479 apply (le_n_Sm_elim i n1 H2)
481 apply (transitive_divides ? n1!)
487 (*apply (witness ? ? (S n1)).
493 apply (witness ? ? n1!).
499 theorem mod_S_fact: \forall n,i:nat.
500 (S O) < i \to i \le n \to (S n!) \mod i = (S O).
506 (*apply (trans_lt O (S O))
514 apply divides_to_mod_O
515 [ apply ltn_to_ltO [| apply H]
517 [ apply ltn_to_ltO [| apply H]
524 theorem not_divides_S_fact: \forall n,i:nat.
525 (S O) < i \to i \le n \to i \ndivides S n!.
527 apply divides_b_false_to_not_divides
529 (*apply (trans_lt O (S O))
534 rewrite > mod_S_fact;auto
544 definition prime : nat \to Prop \def
545 \lambda n:nat. (S O) < n \land
546 (\forall m:nat. m \divides n \to (S O) < m \to m = n).
548 theorem not_prime_O: \lnot (prime O).
553 apply (not_le_Sn_O (S O) H1).
556 theorem not_prime_SO: \lnot (prime (S O)).
561 apply (not_le_Sn_n (S O) H1).
564 (* smallest factor *)
565 definition smallest_factor : nat \to nat \def
571 [ O \Rightarrow (S O)
572 | (S q) \Rightarrow min_aux q (S(S q)) (\lambda m.(eqb ((S(S q)) \mod m) O))]].
575 theorem example1 : smallest_prime_factor (S(S(S O))) = (S(S(S O))).
576 normalize.reflexivity.
579 theorem example2: smallest_prime_factor (S(S(S(S O)))) = (S(S O)).
580 normalize.reflexivity.
583 theorem example3 : smallest_prime_factor (S(S(S(S(S(S(S O))))))) = (S(S(S(S(S(S(S O))))))).
584 simplify.reflexivity.
587 theorem lt_SO_smallest_factor:
588 \forall n:nat. (S O) < n \to (S O) < (smallest_factor n).
594 apply (not_le_Sn_O (S O) H)*)
598 (*intro. apply False_ind.
599 apply (not_le_Sn_n (S O) H)*)
602 (S O < min_aux m1 (S(S m1)) (\lambda m.(eqb ((S(S m1)) \mod m) O))).
603 apply (lt_to_le_to_lt ? (S (S O)))
604 [ apply (le_n (S(S O)))
605 | cut ((S(S O)) = (S(S m1)) - m1)
611 (*rewrite < sym_plus.
620 theorem lt_O_smallest_factor: \forall n:nat. O < n \to O < (smallest_factor n).
626 apply (not_le_Sn_n O H)*)
635 apply (trans_lt ? (S O))
639 | apply lt_SO_smallest_factor.
649 theorem divides_smallest_factor_n :
650 \forall n:nat. O < n \to smallest_factor n \divides n.
656 apply (not_le_Sn_O O H)*)
662 apply (witness ? ? (S O)).
666 apply divides_b_true_to_divides
667 [ apply (lt_O_smallest_factor ? H)
669 (eqb ((S(S m1)) \mod (min_aux m1 (S(S m1))
670 (\lambda m.(eqb ((S(S m1)) \mod m) O)))) O = true).
671 apply f_min_aux_true.
672 apply (ex_intro nat ? (S(S m1))).
682 | apply (trans_lt ? (S O))
696 theorem le_smallest_factor_n :
697 \forall n:nat. smallest_factor n \le n.
713 | apply divides_smallest_factor_n.
722 theorem lt_smallest_factor_to_not_divides: \forall n,i:nat.
723 (S O) < n \to (S O) < i \to i < (smallest_factor n) \to i \ndivides n.
728 apply (not_le_Sn_O (S O) H)
733 apply (not_le_Sn_n (S O) H)
735 apply divides_b_false_to_not_divides
737 (*apply (trans_lt O (S O))
742 apply (lt_min_aux_to_false
743 (\lambda i:nat.eqb ((S(S m1)) \mod i) O) (S(S m1)) m1 i)
744 [ cut ((S(S O)) = (S(S m1)-m1))
750 (*rewrite < sym_plus.
761 theorem prime_smallest_factor_n :
762 \forall n:nat. (S O) < n \to prime (smallest_factor n).
764 change with ((S(S O)) \le n \to (S O) < (smallest_factor n) \land
765 (\forall m:nat. m \divides smallest_factor n \to (S O) < m \to m = (smallest_factor n))).
768 [ apply lt_SO_smallest_factor.
771 cut (le m (smallest_factor n))
772 [ elim (le_to_or_lt_eq m (smallest_factor n) Hcut)
773 [ absurd (m \divides n)
774 [ apply (transitive_divides m (smallest_factor n))
776 | apply divides_smallest_factor_n.
778 (*apply (trans_lt ? (S O))
784 | apply lt_smallest_factor_to_not_divides;auto
792 | apply divides_to_le
793 [ apply (trans_lt O (S O))
795 | apply lt_SO_smallest_factor.
804 theorem prime_to_smallest_factor: \forall n. prime n \to
805 smallest_factor n = n.
811 apply (not_prime_O H)*)
817 apply (not_prime_SO H)*)
820 ((S O) < (S(S m1)) \land
821 (\forall m:nat. m \divides S(S m1) \to (S O) < m \to m = (S(S m1))) \to
822 smallest_factor (S(S m1)) = (S(S m1))).
827 [ apply divides_smallest_factor_n.
828 apply (trans_lt ? (S O))
833 | apply lt_SO_smallest_factor.
840 (* a number n > O is prime iff its smallest factor is n *)
841 definition primeb \def \lambda n:nat.
843 [ O \Rightarrow false
846 [ O \Rightarrow false
847 | (S q) \Rightarrow eqb (smallest_factor (S(S q))) (S(S q))]].
850 theorem example4 : primeb (S(S(S O))) = true.
851 normalize.reflexivity.
854 theorem example5 : primeb (S(S(S(S(S(S O)))))) = false.
855 normalize.reflexivity.
858 theorem example6 : primeb (S(S(S(S((S(S(S(S(S(S(S O)))))))))))) = true.
859 normalize.reflexivity.
862 theorem example7 : primeb (S(S(S(S(S(S((S(S(S(S((S(S(S(S(S(S(S O))))))))))))))))))) = true.
863 normalize.reflexivity.
866 theorem primeb_to_Prop: \forall n.
868 [ true \Rightarrow prime n
869 | false \Rightarrow \lnot (prime n)].
878 apply (not_le_Sn_O (S O) H1)*)
887 apply (not_le_Sn_n (S O) H1)*)
890 match eqb (smallest_factor (S(S m1))) (S(S m1)) with
891 [ true \Rightarrow prime (S(S m1))
892 | false \Rightarrow \lnot (prime (S(S m1)))].
893 apply (eqb_elim (smallest_factor (S(S m1))) (S(S m1)))
897 apply prime_smallest_factor_n.
904 change with (prime (S(S m1)) \to False).
908 apply prime_to_smallest_factor.
915 theorem primeb_true_to_prime : \forall n:nat.
916 primeb n = true \to prime n.
920 [ true \Rightarrow prime n
921 | false \Rightarrow \lnot (prime n)].
923 (*qui auto non chiude il goal*)
924 apply primeb_to_Prop.
927 theorem primeb_false_to_not_prime : \forall n:nat.
928 primeb n = false \to \lnot (prime n).
932 [ true \Rightarrow prime n
933 | false \Rightarrow \lnot (prime n)].
935 (*qui auto non chiude il goal*)
936 apply primeb_to_Prop.
939 theorem decidable_prime : \forall n:nat.decidable (prime n).
944 [ true \Rightarrow prime n
945 | false \Rightarrow \lnot (prime n)] \to (prime n) \lor \lnot (prime n))
947 (*qui auto non chiude il goal*)
951 (*qui auto non chiude il goal*)
954 (*qui auto non chiude il goal*)
960 theorem prime_to_primeb_true: \forall n:nat.
961 prime n \to primeb n = true.
963 cut (match (primeb n) with
964 [ true \Rightarrow prime n
965 | false \Rightarrow \lnot (prime n)] \to ((primeb n) = true))
967 (*qui auto non chiude il goal*)
973 | (*qui auto non chiude il goal*)
980 theorem not_prime_to_primeb_false: \forall n:nat.
981 \lnot(prime n) \to primeb n = false.
983 cut (match (primeb n) with
984 [ true \Rightarrow prime n
985 | false \Rightarrow \lnot (prime n)] \to ((primeb n) = false))
987 (*qui auto non chiude il goal*)
991 [ (*qui auto non chiude il goal*)