| author | wenzelm | 
| Mon, 14 Nov 2011 17:48:26 +0100 | |
| changeset 45490 | 20c8c0cca555 | 
| parent 44872 | a98ef45122f3 | 
| child 47163 | 248376f8881d | 
| permissions | -rw-r--r-- | 
| 41959 | 1 | (* Title: HOL/Number_Theory/Residues.thy | 
| 31719 | 2 | Author: Jeremy Avigad | 
| 3 | ||
| 41541 | 4 | An algebraic treatment of residue rings, and resulting proofs of | 
| 41959 | 5 | Euler's theorem and Wilson's theorem. | 
| 31719 | 6 | *) | 
| 7 | ||
| 8 | header {* Residue rings *}
 | |
| 9 | ||
| 10 | theory Residues | |
| 11 | imports | |
| 41541 | 12 | UniqueFactorization | 
| 13 | Binomial | |
| 14 | MiscAlgebra | |
| 31719 | 15 | begin | 
| 16 | ||
| 17 | ||
| 18 | (* | |
| 44872 | 19 | |
| 31719 | 20 | A locale for residue rings | 
| 21 | ||
| 22 | *) | |
| 23 | ||
| 35416 
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
 haftmann parents: 
32479diff
changeset | 24 | definition residue_ring :: "int => int ring" where | 
| 44872 | 25 | "residue_ring m == (| | 
| 26 |     carrier =       {0..m - 1},
 | |
| 31719 | 27 | mult = (%x y. (x * y) mod m), | 
| 28 | one = 1, | |
| 29 | zero = 0, | |
| 30 | add = (%x y. (x + y) mod m) |)" | |
| 31 | ||
| 32 | locale residues = | |
| 33 | fixes m :: int and R (structure) | |
| 34 | assumes m_gt_one: "m > 1" | |
| 35 | defines "R == residue_ring m" | |
| 36 | ||
| 44872 | 37 | context residues | 
| 38 | begin | |
| 31719 | 39 | |
| 40 | lemma abelian_group: "abelian_group R" | |
| 41 | apply (insert m_gt_one) | |
| 42 | apply (rule abelian_groupI) | |
| 43 | apply (unfold R_def residue_ring_def) | |
| 41541 | 44 | apply (auto simp add: mod_add_right_eq [symmetric] add_ac) | 
| 31719 | 45 | apply (case_tac "x = 0") | 
| 46 | apply force | |
| 47 | apply (subgoal_tac "(x + (m - x)) mod m = 0") | |
| 48 | apply (erule bexI) | |
| 49 | apply auto | |
| 41541 | 50 | done | 
| 31719 | 51 | |
| 52 | lemma comm_monoid: "comm_monoid R" | |
| 53 | apply (insert m_gt_one) | |
| 54 | apply (unfold R_def residue_ring_def) | |
| 55 | apply (rule comm_monoidI) | |
| 56 | apply auto | |
| 57 | apply (subgoal_tac "x * y mod m * z mod m = z * (x * y mod m) mod m") | |
| 58 | apply (erule ssubst) | |
| 59 | apply (subst zmod_zmult1_eq [symmetric])+ | |
| 60 | apply (simp_all only: mult_ac) | |
| 41541 | 61 | done | 
| 31719 | 62 | |
| 63 | lemma cring: "cring R" | |
| 64 | apply (rule cringI) | |
| 65 | apply (rule abelian_group) | |
| 66 | apply (rule comm_monoid) | |
| 67 | apply (unfold R_def residue_ring_def, auto) | |
| 68 | apply (subst mod_add_eq [symmetric]) | |
| 69 | apply (subst mult_commute) | |
| 70 | apply (subst zmod_zmult1_eq [symmetric]) | |
| 36350 | 71 | apply (simp add: field_simps) | 
| 41541 | 72 | done | 
| 31719 | 73 | |
| 74 | end | |
| 75 | ||
| 76 | sublocale residues < cring | |
| 77 | by (rule cring) | |
| 78 | ||
| 79 | ||
| 41541 | 80 | context residues | 
| 81 | begin | |
| 31719 | 82 | |
| 44872 | 83 | (* These lemmas translate back and forth between internal and | 
| 31719 | 84 | external concepts *) | 
| 85 | ||
| 86 | lemma res_carrier_eq: "carrier R = {0..m - 1}"
 | |
| 44872 | 87 | unfolding R_def residue_ring_def by auto | 
| 31719 | 88 | |
| 89 | lemma res_add_eq: "x \<oplus> y = (x + y) mod m" | |
| 44872 | 90 | unfolding R_def residue_ring_def by auto | 
| 31719 | 91 | |
| 92 | lemma res_mult_eq: "x \<otimes> y = (x * y) mod m" | |
| 44872 | 93 | unfolding R_def residue_ring_def by auto | 
| 31719 | 94 | |
| 95 | lemma res_zero_eq: "\<zero> = 0" | |
| 44872 | 96 | unfolding R_def residue_ring_def by auto | 
| 31719 | 97 | |
| 98 | lemma res_one_eq: "\<one> = 1" | |
| 44872 | 99 | unfolding R_def residue_ring_def units_of_def by auto | 
| 31719 | 100 | |
| 101 | lemma res_units_eq: "Units R = { x. 0 < x & x < m & coprime x m}"
 | |
| 102 | apply (insert m_gt_one) | |
| 103 | apply (unfold Units_def R_def residue_ring_def) | |
| 104 | apply auto | |
| 105 | apply (subgoal_tac "x ~= 0") | |
| 106 | apply auto | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 107 | apply (rule invertible_coprime_int) | 
| 31719 | 108 | apply (subgoal_tac "x ~= 0") | 
| 109 | apply auto | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 110 | apply (subst (asm) coprime_iff_invertible'_int) | 
| 31719 | 111 | apply (rule m_gt_one) | 
| 112 | apply (auto simp add: cong_int_def mult_commute) | |
| 41541 | 113 | done | 
| 31719 | 114 | |
| 115 | lemma res_neg_eq: "\<ominus> x = (- x) mod m" | |
| 116 | apply (insert m_gt_one) | |
| 117 | apply (unfold R_def a_inv_def m_inv_def residue_ring_def) | |
| 118 | apply auto | |
| 119 | apply (rule the_equality) | |
| 120 | apply auto | |
| 121 | apply (subst mod_add_right_eq [symmetric]) | |
| 122 | apply auto | |
| 123 | apply (subst mod_add_left_eq [symmetric]) | |
| 124 | apply auto | |
| 125 | apply (subgoal_tac "y mod m = - x mod m") | |
| 126 | apply simp | |
| 127 | apply (subst zmod_eq_dvd_iff) | |
| 128 | apply auto | |
| 41541 | 129 | done | 
| 31719 | 130 | |
| 44872 | 131 | lemma finite [iff]: "finite (carrier R)" | 
| 31719 | 132 | by (subst res_carrier_eq, auto) | 
| 133 | ||
| 44872 | 134 | lemma finite_Units [iff]: "finite (Units R)" | 
| 31719 | 135 | by (subst res_units_eq, auto) | 
| 136 | ||
| 44872 | 137 | (* The function a -> a mod m maps the integers to the | 
| 138 | residue classes. The following lemmas show that this mapping | |
| 31719 | 139 | respects addition and multiplication on the integers. *) | 
| 140 | ||
| 141 | lemma mod_in_carrier [iff]: "a mod m : carrier R" | |
| 142 | apply (unfold res_carrier_eq) | |
| 143 | apply (insert m_gt_one, auto) | |
| 41541 | 144 | done | 
| 31719 | 145 | |
| 146 | lemma add_cong: "(x mod m) \<oplus> (y mod m) = (x + y) mod m" | |
| 44872 | 147 | unfolding R_def residue_ring_def | 
| 148 | apply auto | |
| 149 | apply presburger | |
| 150 | done | |
| 31719 | 151 | |
| 152 | lemma mult_cong: "(x mod m) \<otimes> (y mod m) = (x * y) mod m" | |
| 153 | apply (unfold R_def residue_ring_def, auto) | |
| 154 | apply (subst zmod_zmult1_eq [symmetric]) | |
| 155 | apply (subst mult_commute) | |
| 156 | apply (subst zmod_zmult1_eq [symmetric]) | |
| 157 | apply (subst mult_commute) | |
| 158 | apply auto | |
| 41541 | 159 | done | 
| 31719 | 160 | |
| 161 | lemma zero_cong: "\<zero> = 0" | |
| 44872 | 162 | unfolding R_def residue_ring_def by auto | 
| 31719 | 163 | |
| 164 | lemma one_cong: "\<one> = 1 mod m" | |
| 44872 | 165 | using m_gt_one unfolding R_def residue_ring_def by auto | 
| 31719 | 166 | |
| 167 | (* revise algebra library to use 1? *) | |
| 168 | lemma pow_cong: "(x mod m) (^) n = x^n mod m" | |
| 169 | apply (insert m_gt_one) | |
| 170 | apply (induct n) | |
| 41541 | 171 | apply (auto simp add: nat_pow_def one_cong) | 
| 31719 | 172 | apply (subst mult_commute) | 
| 173 | apply (rule mult_cong) | |
| 41541 | 174 | done | 
| 31719 | 175 | |
| 176 | lemma neg_cong: "\<ominus> (x mod m) = (- x) mod m" | |
| 177 | apply (rule sym) | |
| 178 | apply (rule sum_zero_eq_neg) | |
| 179 | apply auto | |
| 180 | apply (subst add_cong) | |
| 181 | apply (subst zero_cong) | |
| 182 | apply auto | |
| 41541 | 183 | done | 
| 31719 | 184 | |
| 44872 | 185 | lemma (in residues) prod_cong: | 
| 186 | "finite A \<Longrightarrow> (\<Otimes> i:A. (f i) mod m) = (PROD i:A. f i) mod m" | |
| 31719 | 187 | apply (induct set: finite) | 
| 31727 | 188 | apply (auto simp: one_cong mult_cong) | 
| 41541 | 189 | done | 
| 31719 | 190 | |
| 191 | lemma (in residues) sum_cong: | |
| 44872 | 192 | "finite A \<Longrightarrow> (\<Oplus> i:A. (f i) mod m) = (SUM i: A. f i) mod m" | 
| 31719 | 193 | apply (induct set: finite) | 
| 31727 | 194 | apply (auto simp: zero_cong add_cong) | 
| 41541 | 195 | done | 
| 31719 | 196 | |
| 44872 | 197 | lemma mod_in_res_units [simp]: "1 < m \<Longrightarrow> coprime a m \<Longrightarrow> | 
| 31719 | 198 | a mod m : Units R" | 
| 199 | apply (subst res_units_eq, auto) | |
| 200 | apply (insert pos_mod_sign [of m a]) | |
| 201 | apply (subgoal_tac "a mod m ~= 0") | |
| 202 | apply arith | |
| 203 | apply auto | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 204 | apply (subst (asm) gcd_red_int) | 
| 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 205 | apply (subst gcd_commute_int, assumption) | 
| 41541 | 206 | done | 
| 31719 | 207 | |
| 44872 | 208 | lemma res_eq_to_cong: "((a mod m) = (b mod m)) = [a = b] (mod (m::int))" | 
| 31719 | 209 | unfolding cong_int_def by auto | 
| 210 | ||
| 44872 | 211 | (* Simplifying with these will translate a ring equation in R to a | 
| 31719 | 212 | congruence. *) | 
| 213 | ||
| 214 | lemmas res_to_cong_simps = add_cong mult_cong pow_cong one_cong | |
| 215 | prod_cong sum_cong neg_cong res_eq_to_cong | |
| 216 | ||
| 217 | (* Other useful facts about the residue ring *) | |
| 218 | ||
| 219 | lemma one_eq_neg_one: "\<one> = \<ominus> \<one> \<Longrightarrow> m = 2" | |
| 220 | apply (simp add: res_one_eq res_neg_eq) | |
| 221 | apply (insert m_gt_one) | |
| 222 | apply (subgoal_tac "~(m > 2)") | |
| 223 | apply arith | |
| 224 | apply (rule notI) | |
| 225 | apply (subgoal_tac "-1 mod m = m - 1") | |
| 226 | apply force | |
| 227 | apply (subst mod_add_self2 [symmetric]) | |
| 228 | apply (subst mod_pos_pos_trivial) | |
| 229 | apply auto | |
| 41541 | 230 | done | 
| 31719 | 231 | |
| 232 | end | |
| 233 | ||
| 234 | ||
| 235 | (* prime residues *) | |
| 236 | ||
| 237 | locale residues_prime = | |
| 238 | fixes p :: int and R (structure) | |
| 239 | assumes p_prime [intro]: "prime p" | |
| 240 | defines "R == residue_ring p" | |
| 241 | ||
| 242 | sublocale residues_prime < residues p | |
| 243 | apply (unfold R_def residues_def) | |
| 244 | using p_prime apply auto | |
| 41541 | 245 | done | 
| 31719 | 246 | |
| 44872 | 247 | context residues_prime | 
| 248 | begin | |
| 31719 | 249 | |
| 250 | lemma is_field: "field R" | |
| 251 | apply (rule cring.field_intro2) | |
| 252 | apply (rule cring) | |
| 44872 | 253 | apply (auto simp add: res_carrier_eq res_one_eq res_zero_eq res_units_eq) | 
| 31719 | 254 | apply (rule classical) | 
| 255 | apply (erule notE) | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 256 | apply (subst gcd_commute_int) | 
| 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 257 | apply (rule prime_imp_coprime_int) | 
| 31719 | 258 | apply (rule p_prime) | 
| 259 | apply (rule notI) | |
| 260 | apply (frule zdvd_imp_le) | |
| 261 | apply auto | |
| 41541 | 262 | done | 
| 31719 | 263 | |
| 264 | lemma res_prime_units_eq: "Units R = {1..p - 1}"
 | |
| 265 | apply (subst res_units_eq) | |
| 266 | apply auto | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 267 | apply (subst gcd_commute_int) | 
| 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 268 | apply (rule prime_imp_coprime_int) | 
| 31719 | 269 | apply (rule p_prime) | 
| 270 | apply (rule zdvd_not_zless) | |
| 271 | apply auto | |
| 41541 | 272 | done | 
| 31719 | 273 | |
| 274 | end | |
| 275 | ||
| 276 | sublocale residues_prime < field | |
| 277 | by (rule is_field) | |
| 278 | ||
| 279 | ||
| 280 | (* | |
| 281 | Test cases: Euler's theorem and Wilson's theorem. | |
| 282 | *) | |
| 283 | ||
| 284 | ||
| 285 | subsection{* Euler's theorem *}
 | |
| 286 | ||
| 287 | (* the definition of the phi function *) | |
| 288 | ||
| 44872 | 289 | definition phi :: "int => nat" | 
| 290 |   where "phi m = card({ x. 0 < x & x < m & gcd x m = 1})"
 | |
| 31719 | 291 | |
| 292 | lemma phi_zero [simp]: "phi 0 = 0" | |
| 293 | apply (subst phi_def) | |
| 44872 | 294 | (* Auto hangs here. Once again, where is the simplification rule | 
| 31719 | 295 | 1 == Suc 0 coming from? *) | 
| 296 | apply (auto simp add: card_eq_0_iff) | |
| 297 | (* Add card_eq_0_iff as a simp rule? delete card_empty_imp? *) | |
| 41541 | 298 | done | 
| 31719 | 299 | |
| 300 | lemma phi_one [simp]: "phi 1 = 0" | |
| 44872 | 301 | by (auto simp add: phi_def card_eq_0_iff) | 
| 31719 | 302 | |
| 303 | lemma (in residues) phi_eq: "phi m = card(Units R)" | |
| 304 | by (simp add: phi_def res_units_eq) | |
| 305 | ||
| 44872 | 306 | lemma (in residues) euler_theorem1: | 
| 31719 | 307 | assumes a: "gcd a m = 1" | 
| 308 | shows "[a^phi m = 1] (mod m)" | |
| 309 | proof - | |
| 310 | from a m_gt_one have [simp]: "a mod m : Units R" | |
| 311 | by (intro mod_in_res_units) | |
| 312 | from phi_eq have "(a mod m) (^) (phi m) = (a mod m) (^) (card (Units R))" | |
| 313 | by simp | |
| 44872 | 314 | also have "\<dots> = \<one>" | 
| 31719 | 315 | by (intro units_power_order_eq_one, auto) | 
| 316 | finally show ?thesis | |
| 317 | by (simp add: res_to_cong_simps) | |
| 318 | qed | |
| 319 | ||
| 320 | (* In fact, there is a two line proof! | |
| 321 | ||
| 44872 | 322 | lemma (in residues) euler_theorem1: | 
| 31719 | 323 | assumes a: "gcd a m = 1" | 
| 324 | shows "[a^phi m = 1] (mod m)" | |
| 325 | proof - | |
| 326 | have "(a mod m) (^) (phi m) = \<one>" | |
| 327 | by (simp add: phi_eq units_power_order_eq_one a m_gt_one) | |
| 44872 | 328 | then show ?thesis | 
| 31719 | 329 | by (simp add: res_to_cong_simps) | 
| 330 | qed | |
| 331 | ||
| 332 | *) | |
| 333 | ||
| 334 | (* outside the locale, we can relax the restriction m > 1 *) | |
| 335 | ||
| 336 | lemma euler_theorem: | |
| 337 | assumes "m >= 0" and "gcd a m = 1" | |
| 338 | shows "[a^phi m = 1] (mod m)" | |
| 339 | proof (cases) | |
| 340 | assume "m = 0 | m = 1" | |
| 44872 | 341 | then show ?thesis by auto | 
| 31719 | 342 | next | 
| 343 | assume "~(m = 0 | m = 1)" | |
| 41541 | 344 | with assms show ?thesis | 
| 31719 | 345 | by (intro residues.euler_theorem1, unfold residues_def, auto) | 
| 346 | qed | |
| 347 | ||
| 348 | lemma (in residues_prime) phi_prime: "phi p = (nat p - 1)" | |
| 349 | apply (subst phi_eq) | |
| 350 | apply (subst res_prime_units_eq) | |
| 351 | apply auto | |
| 41541 | 352 | done | 
| 31719 | 353 | |
| 354 | lemma phi_prime: "prime p \<Longrightarrow> phi p = (nat p - 1)" | |
| 355 | apply (rule residues_prime.phi_prime) | |
| 356 | apply (erule residues_prime.intro) | |
| 41541 | 357 | done | 
| 31719 | 358 | |
| 359 | lemma fermat_theorem: | |
| 360 | assumes "prime p" and "~ (p dvd a)" | |
| 361 | shows "[a^(nat p - 1) = 1] (mod p)" | |
| 362 | proof - | |
| 41541 | 363 | from assms have "[a^phi p = 1] (mod p)" | 
| 31719 | 364 | apply (intro euler_theorem) | 
| 365 | (* auto should get this next part. matching across | |
| 366 | substitutions is needed. *) | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 367 | apply (frule prime_gt_1_int, arith) | 
| 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 368 | apply (subst gcd_commute_int, erule prime_imp_coprime_int, assumption) | 
| 31719 | 369 | done | 
| 370 | also have "phi p = nat p - 1" | |
| 41541 | 371 | by (rule phi_prime, rule assms) | 
| 31719 | 372 | finally show ?thesis . | 
| 373 | qed | |
| 374 | ||
| 375 | ||
| 376 | subsection {* Wilson's theorem *}
 | |
| 377 | ||
| 44872 | 378 | lemma (in field) inv_pair_lemma: "x : Units R \<Longrightarrow> y : Units R \<Longrightarrow> | 
| 379 |     {x, inv x} ~= {y, inv y} \<Longrightarrow> {x, inv x} Int {y, inv y} = {}"
 | |
| 31719 | 380 | apply auto | 
| 381 | apply (erule notE) | |
| 382 | apply (erule inv_eq_imp_eq) | |
| 383 | apply auto | |
| 384 | apply (erule notE) | |
| 385 | apply (erule inv_eq_imp_eq) | |
| 386 | apply auto | |
| 41541 | 387 | done | 
| 31719 | 388 | |
| 389 | lemma (in residues_prime) wilson_theorem1: | |
| 390 | assumes a: "p > 2" | |
| 391 | shows "[fact (p - 1) = - 1] (mod p)" | |
| 392 | proof - | |
| 44872 | 393 |   let ?InversePairs = "{ {x, inv x} | x. x : Units R - {\<one>, \<ominus> \<one>}}"
 | 
| 31732 | 394 |   have UR: "Units R = {\<one>, \<ominus> \<one>} Un (Union ?InversePairs)"
 | 
| 31719 | 395 | by auto | 
| 44872 | 396 | have "(\<Otimes>i: Units R. i) = | 
| 31719 | 397 |     (\<Otimes>i: {\<one>, \<ominus> \<one>}. i) \<otimes> (\<Otimes>i: Union ?InversePairs. i)"
 | 
| 31732 | 398 | apply (subst UR) | 
| 31719 | 399 | apply (subst finprod_Un_disjoint) | 
| 31732 | 400 | apply (auto intro:funcsetI) | 
| 31719 | 401 | apply (drule sym, subst (asm) inv_eq_one_eq) | 
| 402 | apply auto | |
| 403 | apply (drule sym, subst (asm) inv_eq_neg_one_eq) | |
| 404 | apply auto | |
| 405 | done | |
| 406 |   also have "(\<Otimes>i: {\<one>, \<ominus> \<one>}. i) = \<ominus> \<one>"
 | |
| 407 | apply (subst finprod_insert) | |
| 408 | apply auto | |
| 409 | apply (frule one_eq_neg_one) | |
| 410 | apply (insert a, force) | |
| 411 | done | |
| 44872 | 412 | also have "(\<Otimes>i:(Union ?InversePairs). i) = | 
| 41541 | 413 | (\<Otimes>A: ?InversePairs. (\<Otimes>y:A. y))" | 
| 31719 | 414 | apply (subst finprod_Union_disjoint) | 
| 415 | apply force | |
| 416 | apply force | |
| 417 | apply clarify | |
| 418 | apply (rule inv_pair_lemma) | |
| 419 | apply auto | |
| 420 | done | |
| 421 | also have "\<dots> = \<one>" | |
| 422 | apply (rule finprod_one) | |
| 423 | apply auto | |
| 424 | apply (subst finprod_insert) | |
| 425 | apply auto | |
| 426 | apply (frule inv_eq_self) | |
| 31732 | 427 | apply (auto) | 
| 31719 | 428 | done | 
| 429 | finally have "(\<Otimes>i: Units R. i) = \<ominus> \<one>" | |
| 430 | by simp | |
| 431 | also have "(\<Otimes>i: Units R. i) = (\<Otimes>i: Units R. i mod p)" | |
| 432 | apply (rule finprod_cong') | |
| 31732 | 433 | apply (auto) | 
| 31719 | 434 | apply (subst (asm) res_prime_units_eq) | 
| 435 | apply auto | |
| 436 | done | |
| 437 | also have "\<dots> = (PROD i: Units R. i) mod p" | |
| 438 | apply (rule prod_cong) | |
| 439 | apply auto | |
| 440 | done | |
| 441 | also have "\<dots> = fact (p - 1) mod p" | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 442 | apply (subst fact_altdef_int) | 
| 41541 | 443 | apply (insert assms, force) | 
| 31719 | 444 | apply (subst res_prime_units_eq, rule refl) | 
| 445 | done | |
| 446 | finally have "fact (p - 1) mod p = \<ominus> \<one>". | |
| 44872 | 447 | then show ?thesis by (simp add: res_to_cong_simps) | 
| 31719 | 448 | qed | 
| 449 | ||
| 450 | lemma wilson_theorem: "prime (p::int) \<Longrightarrow> [fact (p - 1) = - 1] (mod p)" | |
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 451 | apply (frule prime_gt_1_int) | 
| 31719 | 452 | apply (case_tac "p = 2") | 
| 31952 
40501bb2d57c
renamed lemmas: nat_xyz/int_xyz -> xyz_nat/xyz_int
 nipkow parents: 
31798diff
changeset | 453 | apply (subst fact_altdef_int, simp) | 
| 31719 | 454 | apply (subst cong_int_def) | 
| 455 | apply simp | |
| 456 | apply (rule residues_prime.wilson_theorem1) | |
| 457 | apply (rule residues_prime.intro) | |
| 458 | apply auto | |
| 44872 | 459 | done | 
| 31719 | 460 | |
| 461 | end |