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 (**************************************************************************)
15 set "baseuri" "cic:/matita/library_auto/nat/euler_theorem".
17 include "auto/nat/map_iter_p.ma".
18 include "auto/nat/totient.ma".
20 (* a reformulation of totient using card insted of count *)
21 lemma totient_card: \forall n.
22 totient n = card n (\lambda i.eqb (gcd i n) (S O)).
30 apply count_card1;auto
32 | auto.rewrite > gcd_n_n.
39 theorem gcd_pi_p: \forall n,k. O < k \to k \le n \to
40 gcd n (pi_p (\lambda i.eqb (gcd i n) (S O)) k) = (S O).
44 cut (eqb (gcd (S O) n) (S O) = true)
47 (*change with ((gcd n (S O)) = (S O)).
50 (*apply eq_to_eqb_true.auto*)
56 ((gcd n ((S n1)*(pi_p (\lambda i.eqb (gcd i n) (S O)) n1))) = (S O)).
68 (*apply (trans_le ? (S n1))
75 (gcd n (pi_p (\lambda i.eqb (gcd i n) (S O)) n1) = (S O)).
78 (*apply (trans_le ? (S n1))
86 theorem congruent_map_iter_p_times:\forall f:nat \to nat. \forall a,n:nat.
89 (map_iter_p n (\lambda i.eqb (gcd i a) (S O)) (\lambda x.f x) (S O) times)
90 (map_iter_p n (\lambda i.eqb (gcd i a) (S O))
91 (\lambda x.f x \mod a) (S O) times) a.
95 (*rewrite > map_iter_p_O.
96 apply (congruent_n_n ? a)*)
97 | apply (eqb_elim (gcd (S n1) a) (S O))
99 rewrite > map_iter_p_S_true
100 [ rewrite > map_iter_p_S_true
101 [ apply congruent_times
104 (*apply congruent_n_mod_n.
106 | (*NB qui auto non chiude il goal*)
110 (*apply eq_to_eqb_true.
114 (*apply eq_to_eqb_true.
118 rewrite > map_iter_p_S_false
119 [ rewrite > map_iter_p_S_false
120 [ (*BN qui auto non chiude il goal*)
123 (*apply not_eq_to_eqb_false.
127 (*apply not_eq_to_eqb_false.
134 theorem permut_p_mod: \forall a,n. S O < n \to O < a \to gcd a n = (S O) \to
135 permut_p (\lambda x:nat.a*x \mod n) (\lambda i:nat.eqb (gcd i n) (S O)) n.
137 lapply (lt_S_to_lt ? ? H) as H3.
149 [ apply eq_to_eqb_true.
151 apply eq_gcd_times_SO
153 | apply (gcd_SO_to_lt_O i n H).
155 (*apply eqb_true_to_eq.
162 apply eqb_true_to_eq.
169 lapply (gcd_SO_to_lt_n ? ? H H4 (eqb_true_to_eq ? ? H5)) as H9.
170 lapply (gcd_SO_to_lt_n ? ? H H7 (eqb_true_to_eq ? ? H6)) as H10.
171 lapply (gcd_SO_to_lt_O ? ? H (eqb_true_to_eq ? ? H5)) as H11.
172 lapply (gcd_SO_to_lt_O ? ? H (eqb_true_to_eq ? ? H6)) as H12.
176 apply (nat_compare_elim i j)
180 | apply le_to_not_lt.
181 apply (trans_le ? (j -i))
182 [ apply divides_to_le
185 (*apply (lt_plus_to_lt_l i).
187 rewrite < (plus_minus_m_m)
192 | apply (gcd_SO_to_divides_times_to_divides a)
197 | apply mod_O_to_divides
199 | rewrite > distr_times_minus.
213 | apply le_to_not_lt.
214 apply (trans_le ? (i -j))
215 [ apply divides_to_le
218 (*apply (lt_plus_to_lt_l j).
220 rewrite < (plus_minus_m_m)
225 | apply (gcd_SO_to_divides_times_to_divides a)
230 | apply mod_O_to_divides
232 | rewrite > distr_times_minus.
244 theorem congruent_exp_totient_SO: \forall n,a:nat. (S O) < n \to
245 gcd a n = (S O) \to congruent (exp a (totient n)) (S O) n.
248 [ apply divides_to_congruent
250 (*apply (trans_lt ? (S O)).
254 (*change with (O < exp a (totient n)).
257 | apply (gcd_SO_to_divides_times_to_divides (pi_p (\lambda i.eqb (gcd i n) (S O)) n))
259 (*apply (trans_lt ? (S O)).
264 [ apply (trans_lt ? (S O)).
269 | rewrite < sym_times.
270 rewrite > times_minus_l.
271 rewrite > (sym_times (S O)).
272 rewrite < times_n_SO.
273 rewrite > totient_card.
274 rewrite > a_times_pi_p.
275 apply congruent_to_divides
277 (*apply (trans_lt ? (S O)).
280 | apply (transitive_congruent n ?
281 (map_iter_p n (\lambda i.eqb (gcd i n) (S O)) (\lambda x.a*x \mod n) (S O) times))
283 (*apply (congruent_map_iter_p_times ? n n).
284 apply (trans_lt ? (S O))
289 cut ( (map_iter_p n (\lambda i:nat.eqb (gcd i n) (S O)) (\lambda n:nat.n) (S O) times)
290 = (map_iter_p n (\lambda i:nat.eqb (gcd i n) (S O)) (\lambda x:nat.a*x\mod n) (S O) times))
293 | apply (eq_map_iter_p_permut ? ? ? ? ? (λm.m))
296 | apply (permut_p_mod ? ? H Hcut H1)
298 apply not_eq_to_eqb_false.
302 (*apply (lt_to_not_eq (S O) n)
313 | elim (le_to_or_lt_eq O a (le_O_n a));auto
315 | auto.absurd (gcd a n = S O)
320 apply (lt_to_not_eq (S O) n)