(* 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‹Residue rings›
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 ⊗🪙G🪙 x = 1🪙G🪙" by (intro bexI[of _ "-x"]) (auto simp: G_def) qed (auto simp: G_def add_ac)
interpret subgroup H G proof show"1🪙G🪙∈ 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 ‹y ∈ H›by fastforce ultimatelyshow"x ⊗🪙G🪙 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🪙G🪙 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‹CHAR('a) > 0›by (intro imageI) auto ultimatelyshow"inv🪙G🪙 x ∈ H"by force qed (auto simp: G_def H_def)
have"card H dvd card (rcosets🪙G🪙 H) * card H" by simp alsohave"card (rcosets🪙G🪙 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‹A locale for residue rings›
definition residue_ring :: "int ==> int ring" where "residue_ring m = (carrier = {0..m - 1}, monoid.mult = λx y. (x * y) mod m, one = 1, zero = 0, add = λx y. (x + y) mod m)"
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‹simp add: add.commute mod_add_right_eq›) 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‹ The function ‹a ↦ a mod m›maps the integers to the residue classes. The following lemmas show that this mapping respects addition and multiplication on the integers. ›
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 = 0" by (auto simp: R_m_def residue_ring_def)
lemma one_cong: "1 = 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‹Simplifying with these will translate a ring equation in R to a congruence.› lemmas res_to_cong_simps =
add_cong mult_cong pow_cong one_cong
prod_cong sum_cong neg_cong res_eq_to_cong
text‹Other useful facts about the residue ring.› lemma one_eq_neg_one: "1 = ⊖1==> m = 2" using one_cong res_neg_eq res_one_eq zmod_zminus1_eq_if by fastforce
end
subsection‹Prime residues›
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‹Test cases: Euler's theorem and Wilson's theorem›
subsection‹Euler's theorem›
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‹Wilson's theorem›
lemma (in field) inv_pair_lemma: "x ∈ Units R ==> y ∈ Units R ==> {x, inv x} ≠ {y, inv y} ==> {x, inv x} ∩ {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 - {1, ⊖1}}" have UR: "Units R = {1, ⊖1} ∪∪?Inverse_Pairs" by auto have 11: "1≠⊖1" using a one_eq_neg_one by force have"(⨂i∈Units R. i) = (⨂i∈{1, ⊖1}. 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∈{1, ⊖1}. i) = ⊖1" 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"… = 1" apply (rule finprod_one_eqI) apply clarsimp apply (subst finprod_insert) apply auto apply (metis inv_eq_self) done finallyhave"(⨂i∈Units R. i) = ⊖1" 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 = ⊖1" . 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‹ This result can be transferred to the multiplicative group of ‹ℤ/pℤ› f
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)) - {0🪙residue_ring (int p)🪙} = {1 .. int p - 1}" by (auto simp add: R.zero_cong R.res_carrier_eq)
have"x [^]🪙residue_ring (int p)🪙 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[^]🪙residue_ring (int p)🪙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 ‹p≥2›by force thenshow"?L ⊆ ?R"by blast have"n ∈ ?L"if"n ∈ ?R"for n using that ‹p≥2›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 ‹p≥2›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 ‹p≥2›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‹Upper bound for the number of $n$-th roots›
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) 1🪙R🪙 n ⊖🪙(UP R)🪙 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 ≠0🪙UP R🪙"using assms by (auto simp add : R.deg_nzero_nzero) have roots_bound: "finite {a ∈ carrier R. UnivPoly.eval R R id a ?f = 0🪙R🪙} ∧
card {a ∈ carrier R. UnivPoly.eval R R id a ?f = 0🪙R🪙} ≤ deg R ?f" using finite in_carrier by (intro R.roots_bound[OF _ f_not_zero]) simp have subs: "{x ∈ carrier R. x [^]🪙R🪙 n = int (c mod p)} ⊆ {a ∈ carrier R. UnivPoly.eval R R id a ?f = 0🪙R🪙}" using in_carrier by (auto simp: R.evalRR_simps) thenhave"card {x ∈ carrier R. x [^]🪙R🪙 n = int (c mod p)} ≤ card {a ∈ carrier R. UnivPoly.eval R R id a ?f = 0🪙R🪙}" using finite by (intro card_mono) auto alsohave"…≤ n" using‹deg R ?f = n› roots_bound by linarith also { fix x assume"x ∈ carrier R" hence"x [^]🪙R🪙 n = (x ^ n) mod (int p)" by (subst pow_cong [symmetric]) (auto simp: R_def residue_ring_def)
} hence"{x ∈ carrier R. x [^]🪙R🪙 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‹force simp: R_def residue_ring_def A_def›)+ from bij_betw_same_card[OF this] have"card {x ∈ carrier R. [x ^ n = int c] (mod p)} = card A" .. finallyshow ?thesis . qed
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-04-26)
¤
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 und die Messung sind noch experimentell.