37 |
37 |
38 lemma inv_is_inv_aux: "1 < m ==> Suc (nat (m - 2)) = nat (m - 1)" |
38 lemma inv_is_inv_aux: "1 < m ==> Suc (nat (m - 2)) = nat (m - 1)" |
39 by (subst int_int_eq [symmetric], auto) |
39 by (subst int_int_eq [symmetric], auto) |
40 |
40 |
41 lemma inv_is_inv: |
41 lemma inv_is_inv: |
42 "p \<in> zprime \<Longrightarrow> 0 < a \<Longrightarrow> a < p ==> [a * inv p a = 1] (mod p)" |
42 "zprime p \<Longrightarrow> 0 < a \<Longrightarrow> a < p ==> [a * inv p a = 1] (mod p)" |
43 apply (unfold inv_def) |
43 apply (unfold inv_def) |
44 apply (subst zcong_zmod) |
44 apply (subst zcong_zmod) |
45 apply (subst zmod_zmult1_eq [symmetric]) |
45 apply (subst zmod_zmult1_eq [symmetric]) |
46 apply (subst zcong_zmod [symmetric]) |
46 apply (subst zcong_zmod [symmetric]) |
47 apply (subst power_Suc [symmetric]) |
47 apply (subst power_Suc [symmetric]) |
50 apply (erule_tac [2] zdvd_not_zless) |
50 apply (erule_tac [2] zdvd_not_zless) |
51 apply (unfold zprime_def, auto) |
51 apply (unfold zprime_def, auto) |
52 done |
52 done |
53 |
53 |
54 lemma inv_distinct: |
54 lemma inv_distinct: |
55 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> a \<noteq> inv p a" |
55 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> a \<noteq> inv p a" |
56 apply safe |
56 apply safe |
57 apply (cut_tac a = a and p = p in zcong_square) |
57 apply (cut_tac a = a and p = p in zcong_square) |
58 apply (cut_tac [3] a = a and p = p in inv_is_inv, auto) |
58 apply (cut_tac [3] a = a and p = p in inv_is_inv, auto) |
59 apply (subgoal_tac "a = 1") |
59 apply (subgoal_tac "a = 1") |
60 apply (rule_tac [2] m = p in zcong_zless_imp_eq) |
60 apply (rule_tac [2] m = p in zcong_zless_imp_eq) |
61 apply (subgoal_tac [7] "a = p - 1") |
61 apply (subgoal_tac [7] "a = p - 1") |
62 apply (rule_tac [8] m = p in zcong_zless_imp_eq, auto) |
62 apply (rule_tac [8] m = p in zcong_zless_imp_eq, auto) |
63 done |
63 done |
64 |
64 |
65 lemma inv_not_0: |
65 lemma inv_not_0: |
66 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> 0" |
66 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> 0" |
67 apply safe |
67 apply safe |
68 apply (cut_tac a = a and p = p in inv_is_inv) |
68 apply (cut_tac a = a and p = p in inv_is_inv) |
69 apply (unfold zcong_def, auto) |
69 apply (unfold zcong_def, auto) |
70 apply (subgoal_tac "\<not> p dvd 1") |
70 apply (subgoal_tac "\<not> p dvd 1") |
71 apply (rule_tac [2] zdvd_not_zless) |
71 apply (rule_tac [2] zdvd_not_zless) |
73 prefer 2 |
73 prefer 2 |
74 apply (subst zdvd_zminus_iff [symmetric], auto) |
74 apply (subst zdvd_zminus_iff [symmetric], auto) |
75 done |
75 done |
76 |
76 |
77 lemma inv_not_1: |
77 lemma inv_not_1: |
78 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> 1" |
78 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> 1" |
79 apply safe |
79 apply safe |
80 apply (cut_tac a = a and p = p in inv_is_inv) |
80 apply (cut_tac a = a and p = p in inv_is_inv) |
81 prefer 4 |
81 prefer 4 |
82 apply simp |
82 apply simp |
83 apply (subgoal_tac "a = 1") |
83 apply (subgoal_tac "a = 1") |
94 apply (rule_tac s = "p dvd (a + 1) + (p * -1)" in trans) |
94 apply (rule_tac s = "p dvd (a + 1) + (p * -1)" in trans) |
95 apply (subst zdvd_reduce, auto) |
95 apply (subst zdvd_reduce, auto) |
96 done |
96 done |
97 |
97 |
98 lemma inv_not_p_minus_1: |
98 lemma inv_not_p_minus_1: |
99 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> p - 1" |
99 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a \<noteq> p - 1" |
100 apply safe |
100 apply safe |
101 apply (cut_tac a = a and p = p in inv_is_inv, auto) |
101 apply (cut_tac a = a and p = p in inv_is_inv, auto) |
102 apply (simp add: inv_not_p_minus_1_aux) |
102 apply (simp add: inv_not_p_minus_1_aux) |
103 apply (subgoal_tac "a = p - 1") |
103 apply (subgoal_tac "a = p - 1") |
104 apply (rule_tac [2] zcong_zless_imp_eq, auto) |
104 apply (rule_tac [2] zcong_zless_imp_eq, auto) |
105 done |
105 done |
106 |
106 |
107 lemma inv_g_1: |
107 lemma inv_g_1: |
108 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> 1 < inv p a" |
108 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> 1 < inv p a" |
109 apply (case_tac "0\<le> inv p a") |
109 apply (case_tac "0\<le> inv p a") |
110 apply (subgoal_tac "inv p a \<noteq> 1") |
110 apply (subgoal_tac "inv p a \<noteq> 1") |
111 apply (subgoal_tac "inv p a \<noteq> 0") |
111 apply (subgoal_tac "inv p a \<noteq> 0") |
112 apply (subst order_less_le) |
112 apply (subst order_less_le) |
113 apply (subst zle_add1_eq_le [symmetric]) |
113 apply (subst zle_add1_eq_le [symmetric]) |
116 apply (rule_tac [5] inv_not_1, auto) |
116 apply (rule_tac [5] inv_not_1, auto) |
117 apply (unfold inv_def zprime_def, simp) |
117 apply (unfold inv_def zprime_def, simp) |
118 done |
118 done |
119 |
119 |
120 lemma inv_less_p_minus_1: |
120 lemma inv_less_p_minus_1: |
121 "p \<in> zprime \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a < p - 1" |
121 "zprime p \<Longrightarrow> 1 < a \<Longrightarrow> a < p - 1 ==> inv p a < p - 1" |
122 apply (case_tac "inv p a < p") |
122 apply (case_tac "inv p a < p") |
123 apply (subst order_less_le) |
123 apply (subst order_less_le) |
124 apply (simp add: inv_not_p_minus_1, auto) |
124 apply (simp add: inv_not_p_minus_1, auto) |
125 apply (unfold inv_def zprime_def, simp) |
125 apply (unfold inv_def zprime_def, simp) |
126 done |
126 done |
138 apply (auto simp add: zpower_zadd_distrib) |
138 apply (auto simp add: zpower_zadd_distrib) |
139 apply (subgoal_tac "zcong (x^y * x^(y * z)) (1 * 1) p") |
139 apply (subgoal_tac "zcong (x^y * x^(y * z)) (1 * 1) p") |
140 apply (rule_tac [2] zcong_zmult, simp_all) |
140 apply (rule_tac [2] zcong_zmult, simp_all) |
141 done |
141 done |
142 |
142 |
143 lemma inv_inv: "p \<in> zprime \<Longrightarrow> |
143 lemma inv_inv: "zprime p \<Longrightarrow> |
144 5 \<le> p \<Longrightarrow> 0 < a \<Longrightarrow> a < p ==> inv p (inv p a) = a" |
144 5 \<le> p \<Longrightarrow> 0 < a \<Longrightarrow> a < p ==> inv p (inv p a) = a" |
145 apply (unfold inv_def) |
145 apply (unfold inv_def) |
146 apply (subst zpower_zmod) |
146 apply (subst zpower_zmod) |
147 apply (subst zpower_zpower) |
147 apply (subst zpower_zpower) |
148 apply (rule zcong_zless_imp_eq) |
148 apply (rule zcong_zless_imp_eq) |
195 apply (subst wset.simps) |
195 apply (subst wset.simps) |
196 apply (unfold Let_def, auto) |
196 apply (unfold Let_def, auto) |
197 done |
197 done |
198 |
198 |
199 lemma wset_g_1 [rule_format]: |
199 lemma wset_g_1 [rule_format]: |
200 "p \<in> zprime --> a < p - 1 --> b \<in> wset (a, p) --> 1 < b" |
200 "zprime p --> a < p - 1 --> b \<in> wset (a, p) --> 1 < b" |
201 apply (induct a p rule: wset_induct, auto) |
201 apply (induct a p rule: wset_induct, auto) |
202 apply (case_tac "b = a") |
202 apply (case_tac "b = a") |
203 apply (case_tac [2] "b = inv p a") |
203 apply (case_tac [2] "b = inv p a") |
204 apply (subgoal_tac [3] "b = a \<or> b = inv p a") |
204 apply (subgoal_tac [3] "b = a \<or> b = inv p a") |
205 apply (rule_tac [4] wset_mem_imp_or) |
205 apply (rule_tac [4] wset_mem_imp_or) |
207 apply simp |
207 apply simp |
208 apply (rule inv_g_1, auto) |
208 apply (rule inv_g_1, auto) |
209 done |
209 done |
210 |
210 |
211 lemma wset_less [rule_format]: |
211 lemma wset_less [rule_format]: |
212 "p \<in> zprime --> a < p - 1 --> b \<in> wset (a, p) --> b < p - 1" |
212 "zprime p --> a < p - 1 --> b \<in> wset (a, p) --> b < p - 1" |
213 apply (induct a p rule: wset_induct, auto) |
213 apply (induct a p rule: wset_induct, auto) |
214 apply (case_tac "b = a") |
214 apply (case_tac "b = a") |
215 apply (case_tac [2] "b = inv p a") |
215 apply (case_tac [2] "b = inv p a") |
216 apply (subgoal_tac [3] "b = a \<or> b = inv p a") |
216 apply (subgoal_tac [3] "b = a \<or> b = inv p a") |
217 apply (rule_tac [4] wset_mem_imp_or) |
217 apply (rule_tac [4] wset_mem_imp_or) |
219 apply simp |
219 apply simp |
220 apply (rule inv_less_p_minus_1, auto) |
220 apply (rule inv_less_p_minus_1, auto) |
221 done |
221 done |
222 |
222 |
223 lemma wset_mem [rule_format]: |
223 lemma wset_mem [rule_format]: |
224 "p \<in> zprime --> |
224 "zprime p --> |
225 a < p - 1 --> 1 < b --> b \<le> a --> b \<in> wset (a, p)" |
225 a < p - 1 --> 1 < b --> b \<le> a --> b \<in> wset (a, p)" |
226 apply (induct a p rule: wset.induct, auto) |
226 apply (induct a p rule: wset.induct, auto) |
227 apply (rule_tac wset_subset) |
227 apply (rule_tac wset_subset) |
228 apply (simp (no_asm_simp)) |
228 apply (simp (no_asm_simp)) |
229 apply auto |
229 apply auto |
230 done |
230 done |
231 |
231 |
232 lemma wset_mem_inv_mem [rule_format]: |
232 lemma wset_mem_inv_mem [rule_format]: |
233 "p \<in> zprime --> 5 \<le> p --> a < p - 1 --> b \<in> wset (a, p) |
233 "zprime p --> 5 \<le> p --> a < p - 1 --> b \<in> wset (a, p) |
234 --> inv p b \<in> wset (a, p)" |
234 --> inv p b \<in> wset (a, p)" |
235 apply (induct a p rule: wset_induct, auto) |
235 apply (induct a p rule: wset_induct, auto) |
236 apply (case_tac "b = a") |
236 apply (case_tac "b = a") |
237 apply (subst wset.simps) |
237 apply (subst wset.simps) |
238 apply (unfold Let_def) |
238 apply (unfold Let_def) |
243 apply (subgoal_tac [6] "b = a \<or> b = inv p a") |
243 apply (subgoal_tac [6] "b = a \<or> b = inv p a") |
244 apply (rule_tac [7] wset_mem_imp_or, auto) |
244 apply (rule_tac [7] wset_mem_imp_or, auto) |
245 done |
245 done |
246 |
246 |
247 lemma wset_inv_mem_mem: |
247 lemma wset_inv_mem_mem: |
248 "p \<in> zprime \<Longrightarrow> 5 \<le> p \<Longrightarrow> a < p - 1 \<Longrightarrow> 1 < b \<Longrightarrow> b < p - 1 |
248 "zprime p \<Longrightarrow> 5 \<le> p \<Longrightarrow> a < p - 1 \<Longrightarrow> 1 < b \<Longrightarrow> b < p - 1 |
249 \<Longrightarrow> inv p b \<in> wset (a, p) \<Longrightarrow> b \<in> wset (a, p)" |
249 \<Longrightarrow> inv p b \<in> wset (a, p) \<Longrightarrow> b \<in> wset (a, p)" |
250 apply (rule_tac s = "inv p (inv p b)" and t = b in subst) |
250 apply (rule_tac s = "inv p (inv p b)" and t = b in subst) |
251 apply (rule_tac [2] wset_mem_inv_mem) |
251 apply (rule_tac [2] wset_mem_inv_mem) |
252 apply (rule inv_inv, simp_all) |
252 apply (rule inv_inv, simp_all) |
253 done |
253 done |
258 apply (subst wset.simps) |
258 apply (subst wset.simps) |
259 apply (unfold Let_def, auto) |
259 apply (unfold Let_def, auto) |
260 done |
260 done |
261 |
261 |
262 lemma wset_zcong_prod_1 [rule_format]: |
262 lemma wset_zcong_prod_1 [rule_format]: |
263 "p \<in> zprime --> |
263 "zprime p --> |
264 5 \<le> p --> a < p - 1 --> [(\<Prod>x\<in>wset(a, p). x) = 1] (mod p)" |
264 5 \<le> p --> a < p - 1 --> [(\<Prod>x\<in>wset(a, p). x) = 1] (mod p)" |
265 apply (induct a p rule: wset_induct) |
265 apply (induct a p rule: wset_induct) |
266 prefer 2 |
266 prefer 2 |
267 apply (subst wset.simps) |
267 apply (subst wset.simps) |
268 apply (unfold Let_def, auto) |
268 apply (unfold Let_def, auto) |
279 apply (rule_tac [5] wset_inv_mem_mem) |
279 apply (rule_tac [5] wset_inv_mem_mem) |
280 apply (simp_all add: wset_fin) |
280 apply (simp_all add: wset_fin) |
281 apply (rule inv_distinct, auto) |
281 apply (rule inv_distinct, auto) |
282 done |
282 done |
283 |
283 |
284 lemma d22set_eq_wset: "p \<in> zprime ==> d22set (p - 2) = wset (p - 2, p)" |
284 lemma d22set_eq_wset: "zprime p ==> d22set (p - 2) = wset (p - 2, p)" |
285 apply safe |
285 apply safe |
286 apply (erule wset_mem) |
286 apply (erule wset_mem) |
287 apply (rule_tac [2] d22set_g_1) |
287 apply (rule_tac [2] d22set_g_1) |
288 apply (rule_tac [3] d22set_le) |
288 apply (rule_tac [3] d22set_le) |
289 apply (rule_tac [4] d22set_mem) |
289 apply (rule_tac [4] d22set_mem) |
309 apply (safe, arith) |
309 apply (safe, arith) |
310 apply (rule_tac x = 2 in exI, auto) |
310 apply (rule_tac x = 2 in exI, auto) |
311 done |
311 done |
312 |
312 |
313 theorem Wilson_Russ: |
313 theorem Wilson_Russ: |
314 "p \<in> zprime ==> [zfact (p - 1) = -1] (mod p)" |
314 "zprime p ==> [zfact (p - 1) = -1] (mod p)" |
315 apply (subgoal_tac "[(p - 1) * zfact (p - 2) = -1 * 1] (mod p)") |
315 apply (subgoal_tac "[(p - 1) * zfact (p - 2) = -1 * 1] (mod p)") |
316 apply (rule_tac [2] zcong_zmult) |
316 apply (rule_tac [2] zcong_zmult) |
317 apply (simp only: zprime_def) |
317 apply (simp only: zprime_def) |
318 apply (subst zfact.simps) |
318 apply (subst zfact.simps) |
319 apply (rule_tac t = "p - 1 - 1" and s = "p - 2" in subst, auto) |
319 apply (rule_tac t = "p - 1 - 1" and s = "p - 2" in subst, auto) |