+++ /dev/null
-(**************************************************************************)
-(* __ *)
-(* ||M|| *)
-(* ||A|| A project by Andrea Asperti *)
-(* ||T|| *)
-(* ||I|| Developers: *)
-(* ||T|| A.Asperti, C.Sacerdoti Coen, *)
-(* ||A|| E.Tassi, S.Zacchiroli *)
-(* \ / *)
-(* \ / This file is distributed under the terms of the *)
-(* v GNU Lesser General Public License Version 2.1 *)
-(* *)
-(**************************************************************************)
-
-set "baseuri" "cic:/matita/library_autobatch/nat/euler_theorem".
-
-include "auto/nat/map_iter_p.ma".
-include "auto/nat/totient.ma".
-
-(* a reformulation of totient using card insted of count *)
-lemma totient_card: \forall n.
-totient n = card n (\lambda i.eqb (gcd i n) (S O)).
-intro.
-apply (nat_case n)
-[ reflexivity
-| intro.
- apply (nat_case m)
- [ reflexivity
- | intro.
- apply count_card1;autobatch
- (*[ reflexivity
- | autobatch.rewrite > gcd_n_n.
- reflexivity
- ]*)
- ]
-]
-qed.
-
-theorem gcd_pi_p: \forall n,k. O < k \to k \le n \to
-gcd n (pi_p (\lambda i.eqb (gcd i n) (S O)) k) = (S O).
-intros 3.
-elim H
-[ rewrite > pi_p_S.
- cut (eqb (gcd (S O) n) (S O) = true)
- [ rewrite > Hcut.
- autobatch
- (*change with ((gcd n (S O)) = (S O)).
- autobatch*)
- | autobatch
- (*apply eq_to_eqb_true.autobatch*)
- ]
-| rewrite > pi_p_S.
- apply eqb_elim
- [ intro.
- change with
- ((gcd n ((S n1)*(pi_p (\lambda i.eqb (gcd i n) (S O)) n1))) = (S O)).
- apply eq_gcd_times_SO
- [ autobatch
- (*unfold.
- apply le_S.
- assumption*)
- | apply lt_O_pi_p.
- | autobatch
- (*rewrite > sym_gcd.
- assumption.*)
- | apply H2.
- autobatch
- (*apply (trans_le ? (S n1))
- [ apply le_n_Sn
- | assumption
- ]*)
- ]
- | intro.
- change with
- (gcd n (pi_p (\lambda i.eqb (gcd i n) (S O)) n1) = (S O)).
- apply H2.
- autobatch
- (*apply (trans_le ? (S n1))
- [ apply le_n_Sn
- | assumption
- ]*)
- ]
-]
-qed.
-
-theorem congruent_map_iter_p_times:\forall f:nat \to nat. \forall a,n:nat.
-O < a \to
-congruent
-(map_iter_p n (\lambda i.eqb (gcd i a) (S O)) (\lambda x.f x) (S O) times)
-(map_iter_p n (\lambda i.eqb (gcd i a) (S O))
- (\lambda x.f x \mod a) (S O) times) a.
-intros.
-elim n
-[ autobatch
- (*rewrite > map_iter_p_O.
- apply (congruent_n_n ? a)*)
-| apply (eqb_elim (gcd (S n1) a) (S O))
- [ intro.
- rewrite > map_iter_p_S_true
- [ rewrite > map_iter_p_S_true
- [ apply congruent_times
- [ assumption
- | autobatch
- (*apply congruent_n_mod_n.
- assumption*)
- | (*NB qui autobatch non chiude il goal*)
- assumption
- ]
- | autobatch
- (*apply eq_to_eqb_true.
- assumption*)
- ]
- | autobatch
- (*apply eq_to_eqb_true.
- assumption*)
- ]
- | intro.
- rewrite > map_iter_p_S_false
- [ rewrite > map_iter_p_S_false
- [ (*BN qui autobatch non chiude il goal*)
- assumption
- | autobatch
- (*apply not_eq_to_eqb_false.
- assumption*)
- ]
- | autobatch
- (*apply not_eq_to_eqb_false.
- assumption*)
- ]
- ]
-]
-qed.
-
-theorem permut_p_mod: \forall a,n. S O < n \to O < a \to gcd a n = (S O) \to
-permut_p (\lambda x:nat.a*x \mod n) (\lambda i:nat.eqb (gcd i n) (S O)) n.
-intros.
-lapply (lt_S_to_lt ? ? H) as H3.
-unfold permut_p.
-simplify.
-intros.
-split
-[ split
- [ autobatch
- (*apply lt_to_le.
- apply lt_mod_m_m.
- assumption*)
- | rewrite > sym_gcd.
- rewrite > gcd_mod
- [ apply eq_to_eqb_true.
- rewrite > sym_gcd.
- apply eq_gcd_times_SO
- [ assumption
- | apply (gcd_SO_to_lt_O i n H).
- autobatch
- (*apply eqb_true_to_eq.
- assumption*)
- | autobatch
- (*rewrite > sym_gcd.
- assumption*)
- | autobatch
- (*rewrite > sym_gcd.
- apply eqb_true_to_eq.
- assumption*)
- ]
- | assumption
- ]
- ]
-| intros.
- lapply (gcd_SO_to_lt_n ? ? H H4 (eqb_true_to_eq ? ? H5)) as H9.
- lapply (gcd_SO_to_lt_n ? ? H H7 (eqb_true_to_eq ? ? H6)) as H10.
- lapply (gcd_SO_to_lt_O ? ? H (eqb_true_to_eq ? ? H5)) as H11.
- lapply (gcd_SO_to_lt_O ? ? H (eqb_true_to_eq ? ? H6)) as H12.
- unfold Not.
- intro.
- apply H8.
- apply (nat_compare_elim i j)
- [ intro.
- absurd (j < n)
- [ assumption
- | apply le_to_not_lt.
- apply (trans_le ? (j -i))
- [ apply divides_to_le
- [(*fattorizzare*)
- unfold lt.autobatch.
- (*apply (lt_plus_to_lt_l i).
- simplify.
- rewrite < (plus_minus_m_m)
- [ assumption
- | apply lt_to_le.
- assumption
- ]*)
- | apply (gcd_SO_to_divides_times_to_divides a)
- [ assumption
- | autobatch
- (*rewrite > sym_gcd.
- assumption*)
- | apply mod_O_to_divides
- [ assumption
- | rewrite > distr_times_minus.
- autobatch
- ]
- ]
- ]
- | autobatch
- ]
- ]
- | autobatch
- (*intro.
- assumption*)
- | intro.
- absurd (i < n)
- [ assumption
- | apply le_to_not_lt.
- apply (trans_le ? (i -j))
- [ apply divides_to_le
- [(*fattorizzare*)
- unfold lt.autobatch.
- (*apply (lt_plus_to_lt_l j).
- simplify.
- rewrite < (plus_minus_m_m)
- [ assumption
- | apply lt_to_le.
- assumption
- ]*)
- | apply (gcd_SO_to_divides_times_to_divides a)
- [ assumption
- | autobatch
- (*rewrite > sym_gcd.
- assumption*)
- | apply mod_O_to_divides
- [ assumption
- | rewrite > distr_times_minus.
- autobatch
- ]
- ]
- ]
- | autobatch
- ]
- ]
- ]
-]
-qed.
-
-theorem congruent_exp_totient_SO: \forall n,a:nat. (S O) < n \to
-gcd a n = (S O) \to congruent (exp a (totient n)) (S O) n.
-intros.
-cut (O < a)
-[ apply divides_to_congruent
- [ autobatch
- (*apply (trans_lt ? (S O)).
- apply lt_O_S.
- assumption*)
- | autobatch
- (*change with (O < exp a (totient n)).
- apply lt_O_exp.
- assumption*)
- | apply (gcd_SO_to_divides_times_to_divides (pi_p (\lambda i.eqb (gcd i n) (S O)) n))
- [ autobatch
- (*apply (trans_lt ? (S O)).
- apply lt_O_S.
- assumption*)
- | autobatch
- (*apply gcd_pi_p
- [ apply (trans_lt ? (S O)).
- apply lt_O_S.
- assumption
- | apply le_n
- ]*)
- | rewrite < sym_times.
- rewrite > times_minus_l.
- rewrite > (sym_times (S O)).
- rewrite < times_n_SO.
- rewrite > totient_card.
- rewrite > a_times_pi_p.
- apply congruent_to_divides
- [ autobatch
- (*apply (trans_lt ? (S O)).
- apply lt_O_S.
- assumption*)
- | apply (transitive_congruent n ?
- (map_iter_p n (\lambda i.eqb (gcd i n) (S O)) (\lambda x.a*x \mod n) (S O) times))
- [ autobatch
- (*apply (congruent_map_iter_p_times ? n n).
- apply (trans_lt ? (S O))
- [ apply lt_O_S
- | assumption
- ]*)
- | unfold pi_p.
- cut ( (map_iter_p n (\lambda i:nat.eqb (gcd i n) (S O)) (\lambda n:nat.n) (S O) times)
- = (map_iter_p n (\lambda i:nat.eqb (gcd i n) (S O)) (\lambda x:nat.a*x\mod n) (S O) times))
- [ rewrite < Hcut1.
- apply congruent_n_n
- | apply (eq_map_iter_p_permut ? ? ? ? ? (λm.m))
- [ apply assoc_times
- | apply sym_times
- | apply (permut_p_mod ? ? H Hcut H1)
- | simplify.
- apply not_eq_to_eqb_false.
- unfold.
- intro.
- autobatch
- (*apply (lt_to_not_eq (S O) n)
- [ assumption
- | apply sym_eq.
- assumption
- ]*)
- ]
- ]
- ]
- ]
- ]
- ]
-| elim (le_to_or_lt_eq O a (le_O_n a));autobatch
- (*[ assumption
- | autobatch.absurd (gcd a n = S O)
- [ assumption
- | rewrite < H2.
- simplify.
- unfold.intro.
- apply (lt_to_not_eq (S O) n)
- [ assumption
- | apply sym_eq.
- assumption
- ]
- ]
- ]*)
-]
-qed.
-
\ No newline at end of file