(* Title: HOL/Number_Theory/Residues.thy Author: Jeremy Avigad
An algebraic treatment of residue rings, and resulting proofs of Euler's theorem and Wilson's theorem.
*)
section \<open>Residue rings\<close>
theory Residues imports
Cong "HOL-Algebra.Multiplicative_Group"
Totient begin
lemma (in ring_1) CHAR_dvd_CARD: "CHAR('a) dvd card (UNIV :: 'a set)" proof (cases "card (UNIV :: 'a set) = 0") case False hence [intro]: "CHAR('a) > 0" by (simp add: card_eq_0_iff finite_imp_CHAR_pos)
define G where"G = \ carrier = (UNIV :: 'a set), monoid.mult = (+), one = (0 :: 'a) \"
define H where"H = (of_nat ` {.. interpret group G proof (rule groupI) fix x assume x: "x \ carrier G" show"\y\carrier G. y \\<^bsub>G\<^esub> x = \\<^bsub>G\<^esub>" by (intro bexI[of _ "-x"]) (auto simp: G_def) qed (auto simp: G_def add_ac)
interpret subgroup H G proof show"\\<^bsub>G\<^esub> \ H" using False unfolding G_def H_def by force next fix x y :: 'a assume"x \ H" "y \ H" thenobtain x' y'where [simp]: "x = of_nat x'""y = of_nat y'" by (auto simp: H_def) have"x + y = of_nat ((x' + y') mod CHAR('a))" by (auto simp flip: of_nat_add simp: of_nat_eq_iff_cong_CHAR) moreoverhave"(x' + y') mod CHAR('a) < CHAR('a)" using H_def \<open>y \<in> H\<close> by fastforce ultimatelyshow"x \\<^bsub>G\<^esub> y \ H" by (auto simp: H_def G_def intro!: imageI) next fix x :: 'a assume x: "x \ H" thenobtain x' where [simp]: "x = of_nat x'" and x': "x' < CHAR('a)" by (auto simp: H_def) have"CHAR('a) dvd x' + (CHAR('a) - x') mod CHAR('a)" using mod_eq_0_iff_dvd mod_if x' by fastforce hence"x + of_nat ((CHAR('a) - x') mod CHAR('a)) = 0" by (auto simp flip: of_nat_add simp: of_nat_eq_0_iff_char_dvd) moreoverfrom this have"inv\<^bsub>G\<^esub> x = of_nat ((CHAR('a) - x') mod CHAR('a))" by (intro inv_equality) (auto simp: G_def add_ac) moreoverhave"of_nat ((CHAR('a) - x') mod CHAR('a)) \ H" unfolding H_def using\<open>CHAR('a) > 0\<close> by (intro imageI) auto ultimatelyshow"inv\<^bsub>G\<^esub> x \ H" by force qed (auto simp: G_def H_def)
have"card H dvd card (rcosets\<^bsub>G\<^esub> H) * card H" by simp alsohave"card (rcosets\<^bsub>G\<^esub> H) * card H = Coset.order G" proof (rule lagrange_finite) show"finite (carrier G)" using False card_ge_0_finite by (auto simp: G_def) qed (fact is_subgroup) finallyhave"card H dvd card (UNIV :: 'a set)" by (simp add: Coset.order_def G_def) alsohave"card H = card {.. unfolding H_def by (intro card_image inj_onI) (auto simp: of_nat_eq_iff_cong_CHAR cong_def) finallyshow"CHAR('a) dvd card (UNIV :: 'a set)" by simp qed auto
definition QuadRes :: "int \ int \ bool" where"QuadRes p a = (\y. ([y^2 = a] (mod p)))"
definition Legendre :: "int \ int \ int" where"Legendre a p =
(if ([a = 0] (mod p)) then 0
else if QuadRes p a then 1
else -1)"
subsection \<open>A locale for residue rings\<close>
definition residue_ring :: "int \ int ring" where "residue_ring m = \<lparr>carrier = {0..m - 1},
monoid.mult = \<lambda>x y. (x * y) mod m,
one = 1,
zero = 0,
add = \<lambda>x y. (x + y) mod m\<rparr>"
locale residues = fixes m :: int and R (structure) assumes m_gt_one: "m > 1" defines R_m_def: "R \ residue_ring m" begin
lemma abelian_group: "abelian_group R" proof - have"\y\{0..m - 1}. (x + y) mod m = 0" if "0 \ x" "x < m" for x proof (cases "x = 0") case True with m_gt_one show ?thesis by simp next case False thenhave"(x + (m - x)) mod m = 0" by simp with m_gt_one that show ?thesis by (metis False atLeastAtMost_iff diff_ge_0_iff_ge diff_left_mono int_one_le_iff_zero_less less_le) qed with m_gt_one show ?thesis by (fastforce simp add: R_m_def residue_ring_def mod_add_right_eq ac_simps intro!: abelian_groupI) qed
lemma comm_monoid: "comm_monoid R" proof - have"\x y z. \x \ carrier R; y \ carrier R; z \ carrier R\ \ x \ y \ z = x \ (y \ z)" "\x y. \x \ carrier R; y \ carrier R\ \ x \ y = y \ x" unfolding R_m_def residue_ring_def by (simp_all add: algebra_simps mod_mult_right_eq) thenshow ?thesis unfolding R_m_def residue_ring_def by unfold_locales (use m_gt_one in simp_all) qed
interpretation comm_monoid R using comm_monoid by blast
lemma res_units_eq: "Units R = {x. 0 < x \ x < m \ coprime x m}" (is "_ = ?rhs") proof show"Units R \ ?rhs" using zero_less_mult_iff invertible_coprime by (fastforce simp: Units_def R_m_def residue_ring_def) next show"?rhs \ Units R" unfolding Units_def R_m_def residue_ring_def by (force simp add: cong_def coprime_iff_invertible'_int mult.commute) qed
lemma res_neg_eq: "\ x = (- x) mod m" proof - have"\ x = (THE y. 0 \ y \ y < m \ (x + y) mod m = 0 \ (y + x) mod m = 0)" by (simp add: R_m_def a_inv_def m_inv_def residue_ring_def) alsohave"\ = (- x) mod m" proof - have"\y. 0 \ y \ y < m \ (x + y) mod m = 0 \ (y + x) mod m = 0 \
y = - x mod m" by (metis minus_add_cancel mod_add_eq plus_int_code(1) zmod_trivial_iff) thenshow ?thesis by (intro the_equality) (use m_gt_one in\<open>simp add: add.commute mod_add_right_eq\<close>) qed finallyshow ?thesis . qed
lemma finite [iff]: "finite (carrier R)" by (simp add: res_carrier_eq)
lemma finite_Units [iff]: "finite (Units R)" by (simp add: finite_ring_finite_units)
text\<open>
The function\<open>a \<mapsto> a mod m\<close> maps the integers to the
residue classes. The following lemmasshow that this mapping
respects addition and multiplication on the integers. \<close>
lemma mod_in_carrier [iff]: "a mod m \ carrier R" unfolding res_carrier_eq using insert m_gt_one by auto
lemma add_cong: "(x mod m) \ (y mod m) = (x + y) mod m" by (auto simp: R_m_def residue_ring_def mod_simps)
lemma mult_cong: "(x mod m) \ (y mod m) = (x * y) mod m" by (auto simp: R_m_def residue_ring_def mod_simps)
lemma zero_cong: "\ = 0" by (auto simp: R_m_def residue_ring_def)
lemma one_cong: "\ = 1 mod m" using m_gt_one by (auto simp: R_m_def residue_ring_def)
(* FIXME revise algebra library to use 1? *) lemma pow_cong: "(x mod m) [^] n = x^n mod m" using m_gt_one proof (induct n) case 0 thenshow ?case by (simp add: one_cong) next case (Suc n) thenshow ?case by (simp add: mult_cong power_commutes) qed
lemma neg_cong: "\ (x mod m) = (- x) mod m" by (metis mod_minus_eq res_neg_eq)
lemma (in residues) prod_cong: "finite A \ (\i\A. (f i) mod m) = (\i\A. f i) mod m" by (induct set: finite) (auto simp: one_cong mult_cong)
lemma (in residues) sum_cong: "finite A \ (\i\A. (f i) mod m) = (\i\A. f i) mod m" by (induct set: finite) (auto simp: zero_cong add_cong)
lemma mod_in_res_units [simp]: assumes"1 < m"and"coprime a m" shows"a mod m \ Units R" proof (cases "a mod m = 0") case True with assms show ?thesis by (auto simp add: res_units_eq gcd_red_int [symmetric]) next case False from assms have"0 < m"by simp thenhave"0 \ a mod m" by (rule pos_mod_sign [of m a]) with False have"0 < a mod m"by simp with assms show ?thesis by (auto simp add: res_units_eq gcd_red_int [symmetric] ac_simps) qed
lemma res_eq_to_cong: "(a mod m) = (b mod m) \ [a = b] (mod m)" by (auto simp: cong_def)
text\<open>Simplifying with these will translate a ring equation in R to a congruence.\<close> lemmas res_to_cong_simps =
add_cong mult_cong pow_cong one_cong
prod_cong sum_cong neg_cong res_eq_to_cong
text\<open>Other useful facts about the residue ring.\<close> lemma one_eq_neg_one: "\ = \ \ \ m = 2" using one_cong res_neg_eq res_one_eq zmod_zminus1_eq_if by fastforce
end
subsection \<open>Prime residues\<close>
locale residues_prime = fixes p :: nat and R (structure) assumes p_prime [intro]: "prime p" defines"R \ residue_ring (int p)"
sublocale residues_prime < residues p proof show"1 < int p" using prime_gt_1_nat by auto qed
context residues_prime begin
lemma p_coprime_left: "coprime p a \ \ p dvd a" using p_prime by (auto intro: prime_imp_coprime dest: coprime_common_divisor)
lemma p_coprime_right: "coprime a p \ \ p dvd a" using p_coprime_left [of a] by (simp add: ac_simps)
lemma p_coprime_left_int: "coprime (int p) a \ \ int p dvd a" using p_prime by (auto intro: prime_imp_coprime dest: coprime_common_divisor)
lemma p_coprime_right_int: "coprime a (int p) \ \ int p dvd a" using coprime_commute p_coprime_left_int by blast
lemma is_field: "field R" proof - have"0 < x \ x < int p \ coprime (int p) x" for x by (rule prime_imp_coprime) (auto simp add: zdvd_not_zless) thenshow ?thesis by (intro cring.field_intro2 cring)
(auto simp add: res_carrier_eq res_one_eq res_zero_eq res_units_eq ac_simps) qed
lemma res_prime_units_eq: "Units R = {1..p - 1}" by (auto simp add: res_units_eq p_coprime_right_int zdvd_not_zless)
end
sublocale residues_prime < field by (rule is_field)
section \<open>Test cases: Euler's theorem and Wilson's theorem\<close>
subsection \<open>Euler's theorem\<close>
lemma (in residues) totatives_eq: "totatives (nat m) = nat ` Units R" proof - from m_gt_one have"\m\ > 1" by simp thenhave"totatives (nat \m\) = nat ` abs ` Units R" by (auto simp add: totatives_def res_units_eq image_iff le_less)
(use m_gt_one zless_nat_eq_int_zless in force) moreoverhave"\m\ = m" "abs ` Units R = Units R" using m_gt_one by (auto simp add: res_units_eq image_iff) ultimatelyshow ?thesis by simp qed
lemma (in residues) totient_eq: "totient (nat m) = card (Units R)" proof - have *: "inj_on nat (Units R)" by (rule inj_onI) (auto simp add: res_units_eq) thenshow ?thesis by (simp add: totient_def totatives_eq card_image) qed
lemma (in residues_prime) prime_totient_eq: "totient p = p - 1" using p_prime totient_prime by blast
lemma (in residues) euler_theorem: assumes"coprime a m" shows"[a ^ totient (nat m) = 1] (mod m)" proof - have"a ^ totient (nat m) mod m = 1 mod m" by (metis assms finite_Units m_gt_one mod_in_res_units one_cong totient_eq pow_cong units_power_order_eq_one) thenshow ?thesis using res_eq_to_cong by blast qed
lemma euler_theorem: fixes a m :: nat assumes"coprime a m" shows"[a ^ totient m = 1] (mod m)" proof (cases "m = 0 \ m = 1") case True thenshow ?thesis by auto next case False with assms show ?thesis using residues.euler_theorem [of "int m""int a"] cong_int_iff by (auto simp add: residues_def gcd_int_def) fastforce qed
lemma fermat_theorem: fixes p a :: nat assumes"prime p"and"\ p dvd a" shows"[a ^ (p - 1) = 1] (mod p)" proof - from assms prime_imp_coprime [of p a] have"coprime a p" by (auto simp add: ac_simps) thenhave"[a ^ totient p = 1] (mod p)" by (rule euler_theorem) alsohave"totient p = p - 1" by (rule totient_prime) (rule assms) finallyshow ?thesis . qed
subsection \<open>Wilson's theorem\<close>
lemma (in field) inv_pair_lemma: "x \ Units R \ y \ Units R \
{x, inv x} \<noteq> {y, inv y} \<Longrightarrow> {x, inv x} \<inter> {y, inv y} = {}" by auto
lemma (in residues_prime) wilson_theorem1: assumes a: "p > 2" shows"[fact (p - 1) = (-1::int)] (mod p)" proof - let ?Inverse_Pairs = "{{x, inv x}| x. x \ Units R - {\, \ \}}" have UR: "Units R = {\, \ \} \ \?Inverse_Pairs" by auto have 11: "\ \ \ \" using a one_eq_neg_one by force have"(\i\Units R. i) = (\i\{\, \ \}. i) \ (\i\\?Inverse_Pairs. i)" apply (subst UR) apply (subst finprod_Un_disjoint) using inv_one inv_eq_neg_one_eq apply (auto intro!: funcsetI)+ done alsohave"(\i\{\, \ \}. i) = \ \" by (simp add: 11) alsohave"(\i\(\?Inverse_Pairs). i) = (\A\?Inverse_Pairs. (\y\A. y))" by (rule finprod_Union_disjoint) (auto simp: pairwise_def disjnt_def dest!: inv_eq_imp_eq) alsohave"\ = \" apply (rule finprod_one_eqI) apply clarsimp apply (subst finprod_insert) apply auto apply (metis inv_eq_self) done finallyhave"(\i\Units R. i) = \ \" by simp alsohave"(\i\Units R. i) = (\i\Units R. i mod p)" by (rule finprod_cong') (auto simp: res_units_eq) alsohave"\ = (\i\Units R. i) mod p" by (rule prod_cong) auto alsohave"\ = fact (p - 1) mod p" using assms by (simp add: res_prime_units_eq int_prod zmod_int prod_int_eq fact_prod) finallyhave"fact (p - 1) mod p = \ \" . thenshow ?thesis by (simp add: cong_def res_neg_eq res_one_eq zmod_int) qed
lemma wilson_theorem: assumes"prime p" shows"[fact (p - 1) = - 1] (mod p)" proof (cases "p = 2") case True thenshow ?thesis by (simp add: cong_def fact_prod) next case False thenshow ?thesis using assms prime_ge_2_nat by (metis residues_prime.wilson_theorem1 residues_prime.intro le_eq_less_or_eq) qed
text\<open>
This result can be transferred to the multiplicative group of \<open>\<int>/p\<int>\<close> for \<open>p\<close> prime.\<close>
lemma mod_nat_int_pow_eq: fixes n :: nat and p a :: int shows"a \ 0 \ p \ 0 \ (nat a ^ n) mod (nat p) = nat ((a ^ n) mod p)" by (simp add: nat_mod_as_int)
theorem residue_prime_mult_group_has_gen: fixes p :: nat assumes prime_p : "prime p" shows"\a \ {1 .. p - 1}. {1 .. p - 1} = {a^i mod p|i . i \ UNIV}" proof - have"p \ 2" using prime_gt_1_nat[OF prime_p] by simp interpret R: residues_prime p "residue_ring p" by (simp add: residues_prime_def prime_p) have car: "carrier (residue_ring (int p)) - {\\<^bsub>residue_ring (int p)\<^esub>} = {1 .. int p - 1}" by (auto simp add: R.zero_cong R.res_carrier_eq)
have"x [^]\<^bsub>residue_ring (int p)\<^esub> i = x ^ i mod (int p)" if"x \ {1 .. int p - 1}" for x and i :: nat using that R.pow_cong[of x i] by auto moreover obtain a where a: "a \ {1 .. int p - 1}" and a_gen: "{1 .. int p - 1} = {a[^]\<^bsub>residue_ring (int p)\<^esub>i|i::nat . i \ UNIV}" using field.finite_field_mult_group_has_gen[OF R.is_field] by (auto simp add: car[symmetric] carrier_mult_of) moreover have"nat ` {1 .. int p - 1} = {1 .. p - 1}" (is"?L = ?R") proof have"n \ ?R" if "n \ ?L" for n using that \<open>p\<ge>2\<close> by force thenshow"?L \ ?R" by blast have"n \ ?L" if "n \ ?R" for n using that \<open>p\<ge>2\<close> by (auto intro: rev_image_eqI [of "int n"]) thenshow"?R \ ?L" by blast qed moreover have"nat ` {a^i mod (int p) | i::nat. i \ UNIV} = {nat a^i mod p | i . i \ UNIV}" (is "?L = ?R") proof have"x \ ?R" if "x \ ?L" for x proof - from that obtain i where i: "x = nat (a^i mod (int p))" by blast thenhave"x = nat a ^ i mod p" using mod_nat_int_pow_eq[of a "int p" i] a \<open>p\<ge>2\<close> by auto with i show ?thesis by blast qed thenshow"?L \ ?R" by blast have"x \ ?L" if "x \ ?R" for x proof - from that obtain i where i: "x = nat a^i mod p" by blast with mod_nat_int_pow_eq[of a "int p" i] a \<open>p\<ge>2\<close> show ?thesis by auto qed thenshow"?R \ ?L" by blast qed ultimatelyhave"{1 .. p - 1} = {nat a^i mod p | i. i \ UNIV}" by presburger moreoverfrom a have"nat a \ {1 .. p - 1}" by force ultimatelyshow ?thesis .. qed
subsection \<open>Upper bound for the number of $n$-th roots\<close>
lemma roots_mod_prime_bound: fixes n c p :: nat assumes"prime p""n > 0" defines"A \ {x\{..
shows"card A \ n" proof -
define R where"R = residue_ring (int p)" from assms(1) interpret residues_prime p R by unfold_locales (simp_all add: R_def) interpret R: UP_domain R "UP R"by (unfold_locales)
let ?f = "UnivPoly.monom (UP R) \\<^bsub>R\<^esub> n \\<^bsub>(UP R)\<^esub> UnivPoly.monom (UP R) (int (c mod p)) 0" have in_carrier: "int (c mod p) \ carrier R" using prime_gt_1_nat[OF assms(1)] by (simp add: R_def residue_ring_def)
have"deg R ?f = n" using assms in_carrier by (simp add: R.deg_minus_eq) hence f_not_zero: "?f \ \\<^bsub>UP R\<^esub>" using assms by (auto simp add : R.deg_nzero_nzero) have roots_bound: "finite {a \ carrier R. UnivPoly.eval R R id a ?f = \\<^bsub>R\<^esub>} \
card {a \<in> carrier R. UnivPoly.eval R R id a ?f = \<zero>\<^bsub>R\<^esub>} \<le> deg R ?f" using finite in_carrier by (intro R.roots_bound[OF _ f_not_zero]) simp have subs: "{x \ carrier R. x [^]\<^bsub>R\<^esub> n = int (c mod p)} \
{a \<in> carrier R. UnivPoly.eval R R id a ?f = \<zero>\<^bsub>R\<^esub>}" using in_carrier by (auto simp: R.evalRR_simps) thenhave"card {x \ carrier R. x [^]\<^bsub>R\<^esub> n = int (c mod p)} \
card {a \<in> carrier R. UnivPoly.eval R R id a ?f = \<zero>\<^bsub>R\<^esub>}" using finite by (intro card_mono) auto alsohave"\ \ n" using\<open>deg R ?f = n\<close> roots_bound by linarith also { fix x assume"x \ carrier R" hence"x [^]\<^bsub>R\<^esub> n = (x ^ n) mod (int p)" by (subst pow_cong [symmetric]) (auto simp: R_def residue_ring_def)
} hence"{x \ carrier R. x [^]\<^bsub>R\<^esub> n = int (c mod p)} = {x \ carrier R. [x ^ n = int c] (mod p)}" by (fastforce simp: cong_def zmod_int) alsohave"bij_betw int A {x \ carrier R. [x ^ n = int c] (mod p)}" by (rule bij_betwI[of int _ _ nat])
(use cong_int_iff in\<open>force simp: R_def residue_ring_def A_def\<close>)+ from bij_betw_same_card[OF this] have"card {x \ carrier R. [x ^ n = int c] (mod p)} = card A" .. finallyshow ?thesis . qed
end
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.