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 (* \ / This file is distributed under the terms of the *)
11 (* v GNU Lesser General Public License Version 2.1 *)
13 (**************************************************************************)
17 include "nat/permutation.ma".
18 include "nat/congruence.ma".
20 theorem permut_S_mod: \forall n:nat. permut (S_mod (S n)) n.
21 intro.unfold permut.split.intros.
24 change with ((S i) \mod (S n) < S n).
26 unfold lt.apply le_S_S.apply le_O_n.
29 rewrite < (lt_to_eq_mod i (S n)).
30 rewrite < (lt_to_eq_mod j (S n)).
31 cut (i < n \lor i = n).
32 cut (j < n \lor j = n).
38 apply H2.unfold lt.apply le_S_S.apply le_O_n.
39 rewrite > lt_to_eq_mod.
40 unfold lt.apply le_S_S.assumption.
41 unfold lt.apply le_S_S.assumption.
42 unfold lt.apply le_S_S.apply le_O_n.
43 rewrite > lt_to_eq_mod.
44 unfold lt.apply le_S_S.assumption.
45 unfold lt.apply le_S_S.assumption.
50 apply (not_eq_O_S (i \mod (S n))).
52 rewrite < (mod_n_n (S n)).
53 rewrite < H4 in \vdash (? ? ? (? %?)).
54 rewrite < mod_S.assumption.
55 unfold lt.apply le_S_S.apply le_O_n.
56 rewrite > lt_to_eq_mod.
57 unfold lt.apply le_S_S.assumption.
58 unfold lt.apply le_S_S.assumption.
59 unfold lt.apply le_S_S.apply le_O_n.
63 apply (not_eq_O_S (j \mod (S n))).
64 rewrite < (mod_n_n (S n)).
65 rewrite < H3 in \vdash (? ? (? %?) ?).
66 rewrite < mod_S.assumption.
67 unfold lt.apply le_S_S.apply le_O_n.
68 rewrite > lt_to_eq_mod.
69 unfold lt.apply le_S_S.assumption.
70 unfold lt.apply le_S_S.assumption.
71 unfold lt.apply le_S_S.apply le_O_n.
76 apply le_to_or_lt_eq.assumption.
77 apply le_to_or_lt_eq.assumption.
78 unfold lt.apply le_S_S.assumption.
79 unfold lt.apply le_S_S.assumption.
83 theorem eq_fact_pi: \forall n,m:nat. n < m \to n! = pi n (S_mod m).
86 change with (S n1)*n1!=(S_mod m n1)*(pi n1 (S_mod m)).
87 unfold S_mod in \vdash (? ? ? (? % ?)).
88 rewrite > lt_to_eq_mod.
89 apply eq_f.apply H.apply (trans_lt ? (S n1)).
90 simplify. apply le_n.assumption.assumption.
94 theorem prime_to_not_divides_fact: \forall p:nat. prime p \to \forall n:nat.
95 n \lt p \to \not divides p n!.
96 intros 3.elim n.unfold Not.intros.
97 apply (lt_to_not_le (S O) p).
98 unfold prime in H.elim H.
99 assumption.apply divides_to_le.unfold lt.apply le_n.
101 change with (divides p ((S n1)*n1!) \to False).
103 cut (divides p (S n1) \lor divides p n1!).
104 elim Hcut.apply (lt_to_not_le (S n1) p).
106 apply divides_to_le.unfold lt.apply le_S_S.apply le_O_n.
108 apply (trans_lt ? (S n1)).unfold lt. apply le_n.
109 assumption.assumption.
110 apply divides_times_to_divides.
111 assumption.assumption.
114 theorem permut_mod: \forall p,a:nat. prime p \to
115 \lnot divides p a\to permut (\lambda n.(mod (a*n) p)) (pred p).
116 unfold permut.intros.
117 split.intros.apply le_S_S_to_le.
118 apply (trans_le ? p).
119 change with (mod (a*i) p < p).
121 unfold prime in H.elim H.
122 unfold lt.apply (trans_le ? (S (S O))).
123 apply le_n_Sn.assumption.
124 rewrite < S_pred.apply le_n.
127 apply (trans_lt ? (S O)).unfold lt.apply le_n.assumption.
129 apply (nat_compare_elim i j).
134 rewrite > (S_pred p).
136 apply le_plus_to_minus.
137 apply (trans_le ? (pred p)).assumption.
142 apply (trans_lt ? (S O)).unfold lt.apply le_n.assumption.
143 apply (le_to_not_lt p (j-i)).
144 apply divides_to_le.unfold lt.
145 apply le_SO_minus.assumption.
146 cut (divides p a \lor divides p (j-i)).
147 elim Hcut.apply False_ind.apply H1.assumption.assumption.
148 apply divides_times_to_divides.assumption.
149 rewrite > distr_times_minus.
150 apply eq_mod_to_divides.
153 apply (trans_lt ? (S O)).unfold lt.apply le_n.assumption.
162 rewrite > (S_pred p).
164 apply le_plus_to_minus.
165 apply (trans_le ? (pred p)).assumption.
170 apply (trans_lt ? (S O)).unfold lt.apply le_n.assumption.
171 apply (le_to_not_lt p (i-j)).
172 apply divides_to_le.unfold lt.
173 apply le_SO_minus.assumption.
174 cut (divides p a \lor divides p (i-j)).
175 elim Hcut.apply False_ind.apply H1.assumption.assumption.
176 apply divides_times_to_divides.assumption.
177 rewrite > distr_times_minus.
178 apply eq_mod_to_divides.
181 apply (trans_lt ? (S O)).unfold lt.apply le_n.assumption.
185 theorem congruent_exp_pred_SO: \forall p,a:nat. prime p \to \lnot divides p a \to
186 congruent (exp a (pred p)) (S O) p.
191 [apply divides_to_congruent
193 |change with (O < exp a (pred p)).apply lt_O_exp.assumption
194 |cut (divides p (exp a (pred p)-(S O)) \lor divides p (pred p)!)
198 apply (prime_to_not_divides_fact p H (pred p))
199 [unfold lt.rewrite < (S_pred ? Hcut1).apply le_n.
203 |apply divides_times_to_divides
205 |rewrite > times_minus_l.
206 rewrite > (sym_times (S O)).
207 rewrite < times_n_SO.
208 rewrite > (S_pred (pred p) Hcut2).
209 rewrite > eq_fact_pi.
211 apply congruent_to_divides
213 | apply (transitive_congruent p ?
214 (pi (pred (pred p)) (\lambda m. a*m \mod p) (S O)))
215 [ apply (congruent_pi (\lambda m. a*m)).assumption
216 |cut (pi (pred(pred p)) (\lambda m.m) (S O)
217 = pi (pred(pred p)) (\lambda m.a*m \mod p) (S O))
218 [rewrite > Hcut3.apply congruent_n_n
219 |rewrite < eq_map_iter_i_pi.
220 rewrite < eq_map_iter_i_pi.
221 apply (permut_to_eq_map_iter_i ? ? ? ? ? (λm.m))
224 |rewrite < plus_n_Sm.
226 rewrite < (S_pred ? Hcut2).
227 apply permut_mod[assumption|assumption]
233 |apply sym_eq.apply le_n_O_to_eq.apply le_S_S_to_le.assumption
242 |unfold lt.apply le_S_S_to_le.rewrite < (S_pred ? Hcut1).
243 unfold prime in H.elim H.assumption
245 |unfold prime in H.elim H.
246 apply (trans_lt ? (S O))[unfold lt.apply le_n|assumption]
248 |cut (O < a \lor O = a)
251 |apply False_ind.apply H1.rewrite < H2.apply (witness ? ? O).apply times_n_O
253 |apply le_to_or_lt_eq.apply le_O_n