27 RRset2norRR :: "int set => int => int => int" |
27 RRset2norRR :: "int set => int => int => int" |
28 |
28 |
29 inductive "RsetR m" |
29 inductive "RsetR m" |
30 intros |
30 intros |
31 empty [simp]: "{} \<in> RsetR m" |
31 empty [simp]: "{} \<in> RsetR m" |
32 insert: "A \<in> RsetR m ==> zgcd (a, m) = #1 ==> |
32 insert: "A \<in> RsetR m ==> zgcd (a, m) = Numeral1 ==> |
33 \<forall>a'. a' \<in> A --> \<not> zcong a a' m ==> insert a A \<in> RsetR m" |
33 \<forall>a'. a' \<in> A --> \<not> zcong a a' m ==> insert a A \<in> RsetR m" |
34 |
34 |
35 recdef BnorRset |
35 recdef BnorRset |
36 "measure ((\<lambda>(a, m). nat a) :: int * int => nat)" |
36 "measure ((\<lambda>(a, m). nat a) :: int * int => nat)" |
37 "BnorRset (a, m) = |
37 "BnorRset (a, m) = |
38 (if #0 < a then |
38 (if Numeral0 < a then |
39 let na = BnorRset (a - #1, m) |
39 let na = BnorRset (a - Numeral1, m) |
40 in (if zgcd (a, m) = #1 then insert a na else na) |
40 in (if zgcd (a, m) = Numeral1 then insert a na else na) |
41 else {})" |
41 else {})" |
42 |
42 |
43 defs |
43 defs |
44 norRRset_def: "norRRset m == BnorRset (m - #1, m)" |
44 norRRset_def: "norRRset m == BnorRset (m - Numeral1, m)" |
45 noXRRset_def: "noXRRset m x == (\<lambda>a. a * x) ` norRRset m" |
45 noXRRset_def: "noXRRset m x == (\<lambda>a. a * x) ` norRRset m" |
46 phi_def: "phi m == card (norRRset m)" |
46 phi_def: "phi m == card (norRRset m)" |
47 is_RRset_def: "is_RRset A m == A \<in> RsetR m \<and> card A = phi m" |
47 is_RRset_def: "is_RRset A m == A \<in> RsetR m \<and> card A = phi m" |
48 RRset2norRR_def: |
48 RRset2norRR_def: |
49 "RRset2norRR A m a == |
49 "RRset2norRR A m a == |
50 (if #1 < m \<and> is_RRset A m \<and> a \<in> A then |
50 (if Numeral1 < m \<and> is_RRset A m \<and> a \<in> A then |
51 SOME b. zcong a b m \<and> b \<in> norRRset m |
51 SOME b. zcong a b m \<and> b \<in> norRRset m |
52 else #0)" |
52 else Numeral0)" |
53 |
53 |
54 constdefs |
54 constdefs |
55 zcongm :: "int => int => int => bool" |
55 zcongm :: "int => int => int => bool" |
56 "zcongm m == \<lambda>a b. zcong a b m" |
56 "zcongm m == \<lambda>a b. zcong a b m" |
57 |
57 |
58 lemma abs_eq_1_iff [iff]: "(abs z = (#1::int)) = (z = #1 \<or> z = #-1)" |
58 lemma abs_eq_1_iff [iff]: "(abs z = (Numeral1::int)) = (z = Numeral1 \<or> z = # -1)" |
59 -- {* LCP: not sure why this lemma is needed now *} |
59 -- {* LCP: not sure why this lemma is needed now *} |
60 apply (auto simp add: zabs_def) |
60 apply (auto simp add: zabs_def) |
61 done |
61 done |
62 |
62 |
63 |
63 |
65 |
65 |
66 declare BnorRset.simps [simp del] |
66 declare BnorRset.simps [simp del] |
67 |
67 |
68 lemma BnorRset_induct: |
68 lemma BnorRset_induct: |
69 "(!!a m. P {} a m) ==> |
69 "(!!a m. P {} a m) ==> |
70 (!!a m. #0 < (a::int) ==> P (BnorRset (a - #1, m::int)) (a - #1) m |
70 (!!a m. Numeral0 < (a::int) ==> P (BnorRset (a - Numeral1, m::int)) (a - Numeral1) m |
71 ==> P (BnorRset(a,m)) a m) |
71 ==> P (BnorRset(a,m)) a m) |
72 ==> P (BnorRset(u,v)) u v" |
72 ==> P (BnorRset(u,v)) u v" |
73 proof - |
73 proof - |
74 case rule_context |
74 case rule_context |
75 show ?thesis |
75 show ?thesis |
76 apply (rule BnorRset.induct) |
76 apply (rule BnorRset.induct) |
77 apply safe |
77 apply safe |
78 apply (case_tac [2] "#0 < a") |
78 apply (case_tac [2] "Numeral0 < a") |
79 apply (rule_tac [2] rule_context) |
79 apply (rule_tac [2] rule_context) |
80 apply simp_all |
80 apply simp_all |
81 apply (simp_all add: BnorRset.simps rule_context) |
81 apply (simp_all add: BnorRset.simps rule_context) |
82 done |
82 done |
83 qed |
83 qed |
92 |
92 |
93 lemma Bnor_mem_zle_swap: "a < b ==> b \<notin> BnorRset (a, m)" |
93 lemma Bnor_mem_zle_swap: "a < b ==> b \<notin> BnorRset (a, m)" |
94 apply (auto dest: Bnor_mem_zle) |
94 apply (auto dest: Bnor_mem_zle) |
95 done |
95 done |
96 |
96 |
97 lemma Bnor_mem_zg [rule_format]: "b \<in> BnorRset (a, m) --> #0 < b" |
97 lemma Bnor_mem_zg [rule_format]: "b \<in> BnorRset (a, m) --> Numeral0 < b" |
98 apply (induct a m rule: BnorRset_induct) |
98 apply (induct a m rule: BnorRset_induct) |
99 prefer 2 |
99 prefer 2 |
100 apply (subst BnorRset.simps) |
100 apply (subst BnorRset.simps) |
101 apply (unfold Let_def) |
101 apply (unfold Let_def) |
102 apply auto |
102 apply auto |
103 done |
103 done |
104 |
104 |
105 lemma Bnor_mem_if [rule_format]: |
105 lemma Bnor_mem_if [rule_format]: |
106 "zgcd (b, m) = #1 --> #0 < b --> b \<le> a --> b \<in> BnorRset (a, m)" |
106 "zgcd (b, m) = Numeral1 --> Numeral0 < b --> b \<le> a --> b \<in> BnorRset (a, m)" |
107 apply (induct a m rule: BnorRset.induct) |
107 apply (induct a m rule: BnorRset.induct) |
108 apply auto |
108 apply auto |
109 apply (case_tac "a = b") |
109 apply (case_tac "a = b") |
110 prefer 2 |
110 prefer 2 |
111 apply (simp add: order_less_le) |
111 apply (simp add: order_less_le) |
140 apply (subst BnorRset.simps) |
140 apply (subst BnorRset.simps) |
141 apply (unfold Let_def) |
141 apply (unfold Let_def) |
142 apply auto |
142 apply auto |
143 done |
143 done |
144 |
144 |
145 lemma aux: "a \<le> b - #1 ==> a < (b::int)" |
145 lemma aux: "a \<le> b - Numeral1 ==> a < (b::int)" |
146 apply auto |
146 apply auto |
147 done |
147 done |
148 |
148 |
149 lemma norR_mem_unique: |
149 lemma norR_mem_unique: |
150 "#1 < m ==> |
150 "Numeral1 < m ==> |
151 zgcd (a, m) = #1 ==> \<exists>!b. [a = b] (mod m) \<and> b \<in> norRRset m" |
151 zgcd (a, m) = Numeral1 ==> \<exists>!b. [a = b] (mod m) \<and> b \<in> norRRset m" |
152 apply (unfold norRRset_def) |
152 apply (unfold norRRset_def) |
153 apply (cut_tac a = a and m = m in zcong_zless_unique) |
153 apply (cut_tac a = a and m = m in zcong_zless_unique) |
154 apply auto |
154 apply auto |
155 apply (rule_tac [2] m = m in zcong_zless_imp_eq) |
155 apply (rule_tac [2] m = m in zcong_zless_imp_eq) |
156 apply (auto intro: Bnor_mem_zle Bnor_mem_zg zcong_trans |
156 apply (auto intro: Bnor_mem_zle Bnor_mem_zg zcong_trans |
157 order_less_imp_le aux simp add: zcong_sym) |
157 order_less_imp_le aux simp add: zcong_sym) |
158 apply (rule_tac "x" = "b" in exI) |
158 apply (rule_tac "x" = "b" in exI) |
159 apply safe |
159 apply safe |
160 apply (rule Bnor_mem_if) |
160 apply (rule Bnor_mem_if) |
161 apply (case_tac [2] "b = #0") |
161 apply (case_tac [2] "b = Numeral0") |
162 apply (auto intro: order_less_le [THEN iffD2]) |
162 apply (auto intro: order_less_le [THEN iffD2]) |
163 prefer 2 |
163 prefer 2 |
164 apply (simp only: zcong_def) |
164 apply (simp only: zcong_def) |
165 apply (subgoal_tac "zgcd (a, m) = m") |
165 apply (subgoal_tac "zgcd (a, m) = m") |
166 prefer 2 |
166 prefer 2 |
171 |
171 |
172 |
172 |
173 text {* \medskip @{term noXRRset} *} |
173 text {* \medskip @{term noXRRset} *} |
174 |
174 |
175 lemma RRset_gcd [rule_format]: |
175 lemma RRset_gcd [rule_format]: |
176 "is_RRset A m ==> a \<in> A --> zgcd (a, m) = #1" |
176 "is_RRset A m ==> a \<in> A --> zgcd (a, m) = Numeral1" |
177 apply (unfold is_RRset_def) |
177 apply (unfold is_RRset_def) |
178 apply (rule RsetR.induct) |
178 apply (rule RsetR.induct) |
179 apply auto |
179 apply auto |
180 done |
180 done |
181 |
181 |
182 lemma RsetR_zmult_mono: |
182 lemma RsetR_zmult_mono: |
183 "A \<in> RsetR m ==> |
183 "A \<in> RsetR m ==> |
184 #0 < m ==> zgcd (x, m) = #1 ==> (\<lambda>a. a * x) ` A \<in> RsetR m" |
184 Numeral0 < m ==> zgcd (x, m) = Numeral1 ==> (\<lambda>a. a * x) ` A \<in> RsetR m" |
185 apply (erule RsetR.induct) |
185 apply (erule RsetR.induct) |
186 apply simp_all |
186 apply simp_all |
187 apply (rule RsetR.insert) |
187 apply (rule RsetR.insert) |
188 apply auto |
188 apply auto |
189 apply (blast intro: zgcd_zgcd_zmult) |
189 apply (blast intro: zgcd_zgcd_zmult) |
190 apply (simp add: zcong_cancel) |
190 apply (simp add: zcong_cancel) |
191 done |
191 done |
192 |
192 |
193 lemma card_nor_eq_noX: |
193 lemma card_nor_eq_noX: |
194 "#0 < m ==> |
194 "Numeral0 < m ==> |
195 zgcd (x, m) = #1 ==> card (noXRRset m x) = card (norRRset m)" |
195 zgcd (x, m) = Numeral1 ==> card (noXRRset m x) = card (norRRset m)" |
196 apply (unfold norRRset_def noXRRset_def) |
196 apply (unfold norRRset_def noXRRset_def) |
197 apply (rule card_image) |
197 apply (rule card_image) |
198 apply (auto simp add: inj_on_def Bnor_fin) |
198 apply (auto simp add: inj_on_def Bnor_fin) |
199 apply (simp add: BnorRset.simps) |
199 apply (simp add: BnorRset.simps) |
200 done |
200 done |
201 |
201 |
202 lemma noX_is_RRset: |
202 lemma noX_is_RRset: |
203 "#0 < m ==> zgcd (x, m) = #1 ==> is_RRset (noXRRset m x) m" |
203 "Numeral0 < m ==> zgcd (x, m) = Numeral1 ==> is_RRset (noXRRset m x) m" |
204 apply (unfold is_RRset_def phi_def) |
204 apply (unfold is_RRset_def phi_def) |
205 apply (auto simp add: card_nor_eq_noX) |
205 apply (auto simp add: card_nor_eq_noX) |
206 apply (unfold noXRRset_def norRRset_def) |
206 apply (unfold noXRRset_def norRRset_def) |
207 apply (rule RsetR_zmult_mono) |
207 apply (rule RsetR_zmult_mono) |
208 apply (rule Bnor_in_RsetR) |
208 apply (rule Bnor_in_RsetR) |
209 apply simp_all |
209 apply simp_all |
210 done |
210 done |
211 |
211 |
212 lemma aux_some: |
212 lemma aux_some: |
213 "#1 < m ==> is_RRset A m ==> a \<in> A |
213 "Numeral1 < m ==> is_RRset A m ==> a \<in> A |
214 ==> zcong a (SOME b. [a = b] (mod m) \<and> b \<in> norRRset m) m \<and> |
214 ==> zcong a (SOME b. [a = b] (mod m) \<and> b \<in> norRRset m) m \<and> |
215 (SOME b. [a = b] (mod m) \<and> b \<in> norRRset m) \<in> norRRset m" |
215 (SOME b. [a = b] (mod m) \<and> b \<in> norRRset m) \<in> norRRset m" |
216 apply (rule norR_mem_unique [THEN ex1_implies_ex, THEN someI_ex]) |
216 apply (rule norR_mem_unique [THEN ex1_implies_ex, THEN someI_ex]) |
217 apply (rule_tac [2] RRset_gcd) |
217 apply (rule_tac [2] RRset_gcd) |
218 apply simp_all |
218 apply simp_all |
219 done |
219 done |
220 |
220 |
221 lemma RRset2norRR_correct: |
221 lemma RRset2norRR_correct: |
222 "#1 < m ==> is_RRset A m ==> a \<in> A ==> |
222 "Numeral1 < m ==> is_RRset A m ==> a \<in> A ==> |
223 [a = RRset2norRR A m a] (mod m) \<and> RRset2norRR A m a \<in> norRRset m" |
223 [a = RRset2norRR A m a] (mod m) \<and> RRset2norRR A m a \<in> norRRset m" |
224 apply (unfold RRset2norRR_def) |
224 apply (unfold RRset2norRR_def) |
225 apply simp |
225 apply simp |
226 apply (rule aux_some) |
226 apply (rule aux_some) |
227 apply simp_all |
227 apply simp_all |
250 (SOME a. P a) = (SOME a. Q a) ==> \<exists>a. P a \<and> Q a" |
250 (SOME a. P a) = (SOME a. Q a) ==> \<exists>a. P a \<and> Q a" |
251 apply auto |
251 apply auto |
252 done |
252 done |
253 |
253 |
254 lemma RRset2norRR_inj: |
254 lemma RRset2norRR_inj: |
255 "#1 < m ==> is_RRset A m ==> inj_on (RRset2norRR A m) A" |
255 "Numeral1 < m ==> is_RRset A m ==> inj_on (RRset2norRR A m) A" |
256 apply (unfold RRset2norRR_def inj_on_def) |
256 apply (unfold RRset2norRR_def inj_on_def) |
257 apply auto |
257 apply auto |
258 apply (subgoal_tac "\<exists>b. ([x = b] (mod m) \<and> b \<in> norRRset m) \<and> |
258 apply (subgoal_tac "\<exists>b. ([x = b] (mod m) \<and> b \<in> norRRset m) \<and> |
259 ([y = b] (mod m) \<and> b \<in> norRRset m)") |
259 ([y = b] (mod m) \<and> b \<in> norRRset m)") |
260 apply (rule_tac [2] aux) |
260 apply (rule_tac [2] aux) |
284 apply (unfold inj_on_def) |
284 apply (unfold inj_on_def) |
285 apply auto |
285 apply auto |
286 done |
286 done |
287 |
287 |
288 lemma Bnor_prod_power [rule_format]: |
288 lemma Bnor_prod_power [rule_format]: |
289 "x \<noteq> #0 ==> a < m --> setprod ((\<lambda>a. a * x) ` BnorRset (a, m)) = |
289 "x \<noteq> Numeral0 ==> a < m --> setprod ((\<lambda>a. a * x) ` BnorRset (a, m)) = |
290 setprod (BnorRset(a, m)) * x^card (BnorRset (a, m))" |
290 setprod (BnorRset(a, m)) * x^card (BnorRset (a, m))" |
291 apply (induct a m rule: BnorRset_induct) |
291 apply (induct a m rule: BnorRset_induct) |
292 prefer 2 |
292 prefer 2 |
293 apply (subst BnorRset.simps) |
293 apply (subst BnorRset.simps) |
294 apply (unfold Let_def) |
294 apply (unfold Let_def) |
311 apply (subgoal_tac [2] "a \<notin> A \<and> b \<notin> B \<and> finite A \<and> finite B") |
311 apply (subgoal_tac [2] "a \<notin> A \<and> b \<notin> B \<and> finite A \<and> finite B") |
312 apply (auto intro: fin_bijRl fin_bijRr zcong_zmult) |
312 apply (auto intro: fin_bijRl fin_bijRr zcong_zmult) |
313 done |
313 done |
314 |
314 |
315 lemma Bnor_prod_zgcd [rule_format]: |
315 lemma Bnor_prod_zgcd [rule_format]: |
316 "a < m --> zgcd (setprod (BnorRset (a, m)), m) = #1" |
316 "a < m --> zgcd (setprod (BnorRset (a, m)), m) = Numeral1" |
317 apply (induct a m rule: BnorRset_induct) |
317 apply (induct a m rule: BnorRset_induct) |
318 prefer 2 |
318 prefer 2 |
319 apply (subst BnorRset.simps) |
319 apply (subst BnorRset.simps) |
320 apply (unfold Let_def) |
320 apply (unfold Let_def) |
321 apply auto |
321 apply auto |
322 apply (simp add: Bnor_fin Bnor_mem_zle_swap) |
322 apply (simp add: Bnor_fin Bnor_mem_zle_swap) |
323 apply (blast intro: zgcd_zgcd_zmult) |
323 apply (blast intro: zgcd_zgcd_zmult) |
324 done |
324 done |
325 |
325 |
326 theorem Euler_Fermat: |
326 theorem Euler_Fermat: |
327 "#0 < m ==> zgcd (x, m) = #1 ==> [x^(phi m) = #1] (mod m)" |
327 "Numeral0 < m ==> zgcd (x, m) = Numeral1 ==> [x^(phi m) = Numeral1] (mod m)" |
328 apply (unfold norRRset_def phi_def) |
328 apply (unfold norRRset_def phi_def) |
329 apply (case_tac "x = #0") |
329 apply (case_tac "x = Numeral0") |
330 apply (case_tac [2] "m = #1") |
330 apply (case_tac [2] "m = Numeral1") |
331 apply (rule_tac [3] iffD1) |
331 apply (rule_tac [3] iffD1) |
332 apply (rule_tac [3] k = "setprod (BnorRset (m - #1, m))" |
332 apply (rule_tac [3] k = "setprod (BnorRset (m - Numeral1, m))" |
333 in zcong_cancel2) |
333 in zcong_cancel2) |
334 prefer 5 |
334 prefer 5 |
335 apply (subst Bnor_prod_power [symmetric]) |
335 apply (subst Bnor_prod_power [symmetric]) |
336 apply (rule_tac [7] Bnor_prod_zgcd) |
336 apply (rule_tac [7] Bnor_prod_zgcd) |
337 apply simp_all |
337 apply simp_all |
350 apply (rule Bnor_fin) |
350 apply (rule Bnor_fin) |
351 done |
351 done |
352 |
352 |
353 lemma Bnor_prime [rule_format (no_asm)]: |
353 lemma Bnor_prime [rule_format (no_asm)]: |
354 "p \<in> zprime ==> |
354 "p \<in> zprime ==> |
355 a < p --> (\<forall>b. #0 < b \<and> b \<le> a --> zgcd (b, p) = #1) |
355 a < p --> (\<forall>b. Numeral0 < b \<and> b \<le> a --> zgcd (b, p) = Numeral1) |
356 --> card (BnorRset (a, p)) = nat a" |
356 --> card (BnorRset (a, p)) = nat a" |
357 apply (unfold zprime_def) |
357 apply (unfold zprime_def) |
358 apply (induct a p rule: BnorRset.induct) |
358 apply (induct a p rule: BnorRset.induct) |
359 apply (subst BnorRset.simps) |
359 apply (subst BnorRset.simps) |
360 apply (unfold Let_def) |
360 apply (unfold Let_def) |
361 apply auto |
361 apply auto |
362 done |
362 done |
363 |
363 |
364 lemma phi_prime: "p \<in> zprime ==> phi p = nat (p - #1)" |
364 lemma phi_prime: "p \<in> zprime ==> phi p = nat (p - Numeral1)" |
365 apply (unfold phi_def norRRset_def) |
365 apply (unfold phi_def norRRset_def) |
366 apply (rule Bnor_prime) |
366 apply (rule Bnor_prime) |
367 apply auto |
367 apply auto |
368 apply (erule zless_zprime_imp_zrelprime) |
368 apply (erule zless_zprime_imp_zrelprime) |
369 apply simp_all |
369 apply simp_all |
370 done |
370 done |
371 |
371 |
372 theorem Little_Fermat: |
372 theorem Little_Fermat: |
373 "p \<in> zprime ==> \<not> p dvd x ==> [x^(nat (p - #1)) = #1] (mod p)" |
373 "p \<in> zprime ==> \<not> p dvd x ==> [x^(nat (p - Numeral1)) = Numeral1] (mod p)" |
374 apply (subst phi_prime [symmetric]) |
374 apply (subst phi_prime [symmetric]) |
375 apply (rule_tac [2] Euler_Fermat) |
375 apply (rule_tac [2] Euler_Fermat) |
376 apply (erule_tac [3] zprime_imp_zrelprime) |
376 apply (erule_tac [3] zprime_imp_zrelprime) |
377 apply (unfold zprime_def) |
377 apply (unfold zprime_def) |
378 apply auto |
378 apply auto |