39 |
39 |
40 |
40 |
41 subsection \<open>Basic properties of p\<close> |
41 subsection \<open>Basic properties of p\<close> |
42 |
42 |
43 lemma odd_p: "odd p" |
43 lemma odd_p: "odd p" |
44 by (metis p_prime p_ge_2 prime_odd_nat) |
44 by (metis p_prime p_ge_2 prime_odd_nat) |
45 |
45 |
46 lemma p_minus_one_l: "(int p - 1) div 2 < p" |
46 lemma p_minus_one_l: "(int p - 1) div 2 < p" |
47 proof - |
47 proof - |
48 have "(p - 1) div 2 \<le> (p - 1) div 1" |
48 have "(p - 1) div 2 \<le> (p - 1) div 1" |
49 by (metis div_by_1 div_le_dividend) |
49 by (metis div_by_1 div_le_dividend) |
50 also have "\<dots> = p - 1" by simp |
50 also have "\<dots> = p - 1" by simp |
51 finally show ?thesis using p_ge_2 by arith |
51 finally show ?thesis |
|
52 using p_ge_2 by arith |
52 qed |
53 qed |
53 |
54 |
54 lemma p_eq2: "int p = (2 * ((int p - 1) div 2)) + 1" |
55 lemma p_eq2: "int p = (2 * ((int p - 1) div 2)) + 1" |
55 using odd_p p_ge_2 nonzero_mult_div_cancel_left [of 2 "p - 1"] |
56 using odd_p p_ge_2 nonzero_mult_div_cancel_left [of 2 "p - 1"] by simp |
56 by simp |
57 |
57 |
58 lemma p_odd_int: obtains z :: int where "int p = 2 * z + 1" "0 < z" |
58 lemma p_odd_int: obtains z::int where "int p = 2*z+1" "0<z" |
59 proof |
59 using odd_p p_ge_2 |
60 let ?z = "(int p - 1) div 2" |
60 by (auto simp add: even_iff_mod_2_eq_zero) (metis p_eq2) |
61 show "int p = 2 * ?z + 1" by (rule p_eq2) |
|
62 show "0 < ?z" |
|
63 using p_ge_2 by linarith |
|
64 qed |
61 |
65 |
62 |
66 |
63 subsection \<open>Basic Properties of the Gauss Sets\<close> |
67 subsection \<open>Basic Properties of the Gauss Sets\<close> |
64 |
68 |
65 lemma finite_A: "finite (A)" |
69 lemma finite_A: "finite A" |
66 by (auto simp add: A_def) |
70 by (auto simp add: A_def) |
67 |
71 |
68 lemma finite_B: "finite (B)" |
72 lemma finite_B: "finite B" |
69 by (auto simp add: B_def finite_A) |
73 by (auto simp add: B_def finite_A) |
70 |
74 |
71 lemma finite_C: "finite (C)" |
75 lemma finite_C: "finite C" |
72 by (auto simp add: C_def finite_B) |
76 by (auto simp add: C_def finite_B) |
73 |
77 |
74 lemma finite_D: "finite (D)" |
78 lemma finite_D: "finite D" |
75 by (auto simp add: D_def finite_C) |
79 by (auto simp add: D_def finite_C) |
76 |
80 |
77 lemma finite_E: "finite (E)" |
81 lemma finite_E: "finite E" |
78 by (auto simp add: E_def finite_C) |
82 by (auto simp add: E_def finite_C) |
79 |
83 |
80 lemma finite_F: "finite (F)" |
84 lemma finite_F: "finite F" |
81 by (auto simp add: F_def finite_E) |
85 by (auto simp add: F_def finite_E) |
82 |
86 |
83 lemma C_eq: "C = D \<union> E" |
87 lemma C_eq: "C = D \<union> E" |
84 by (auto simp add: C_def D_def E_def) |
88 by (auto simp add: C_def D_def E_def) |
85 |
89 |
86 lemma A_card_eq: "card A = nat ((int p - 1) div 2)" |
90 lemma A_card_eq: "card A = nat ((int p - 1) div 2)" |
87 by (auto simp add: A_def) |
91 by (auto simp add: A_def) |
88 |
92 |
89 lemma inj_on_xa_A: "inj_on (\<lambda>x. x * a) A" |
93 lemma inj_on_xa_A: "inj_on (\<lambda>x. x * a) A" |
90 using a_nonzero by (simp add: A_def inj_on_def) |
94 using a_nonzero by (simp add: A_def inj_on_def) |
91 |
95 |
92 definition ResSet :: "int => int set => bool" |
96 definition ResSet :: "int \<Rightarrow> int set \<Rightarrow> bool" |
93 where "ResSet m X = (\<forall>y1 y2. (y1 \<in> X & y2 \<in> X & [y1 = y2] (mod m) --> y1 = y2))" |
97 where "ResSet m X \<longleftrightarrow> (\<forall>y1 y2. y1 \<in> X \<and> y2 \<in> X \<and> [y1 = y2] (mod m) \<longrightarrow> y1 = y2)" |
94 |
98 |
95 lemma ResSet_image: |
99 lemma ResSet_image: |
96 "\<lbrakk> 0 < m; ResSet m A; \<forall>x \<in> A. \<forall>y \<in> A. ([f x = f y](mod m) --> x = y) \<rbrakk> \<Longrightarrow> |
100 "0 < m \<Longrightarrow> ResSet m A \<Longrightarrow> \<forall>x \<in> A. \<forall>y \<in> A. ([f x = f y](mod m) \<longrightarrow> x = y) \<Longrightarrow> ResSet m (f ` A)" |
97 ResSet m (f ` A)" |
|
98 by (auto simp add: ResSet_def) |
101 by (auto simp add: ResSet_def) |
99 |
102 |
100 lemma A_res: "ResSet p A" |
103 lemma A_res: "ResSet p A" |
101 using p_ge_2 |
104 using p_ge_2 by (auto simp add: A_def ResSet_def intro!: cong_less_imp_eq_int) |
102 by (auto simp add: A_def ResSet_def intro!: cong_less_imp_eq_int) |
|
103 |
105 |
104 lemma B_res: "ResSet p B" |
106 lemma B_res: "ResSet p B" |
105 proof - |
107 proof - |
106 {fix x fix y |
108 have *: "x = y" |
107 assume a: "[x * a = y * a] (mod p)" |
109 if a: "[x * a = y * a] (mod p)" |
108 assume b: "0 < x" |
110 and b: "0 < x" |
109 assume c: "x \<le> (int p - 1) div 2" |
111 and c: "x \<le> (int p - 1) div 2" |
110 assume d: "0 < y" |
112 and d: "0 < y" |
111 assume e: "y \<le> (int p - 1) div 2" |
113 and e: "y \<le> (int p - 1) div 2" |
112 from p_a_relprime have "\<not>p dvd a" |
114 for x y |
|
115 proof - |
|
116 from p_a_relprime have "\<not> p dvd a" |
113 by (simp add: cong_altdef_int) |
117 by (simp add: cong_altdef_int) |
114 with p_prime have "coprime a (int p)" |
118 with p_prime have "coprime a (int p)" |
115 by (subst gcd.commute, intro prime_imp_coprime) auto |
119 by (subst gcd.commute, intro prime_imp_coprime) auto |
116 with a cong_mult_rcancel_int [of a "int p" x y] |
120 with a cong_mult_rcancel_int [of a "int p" x y] have "[x = y] (mod p)" |
117 have "[x = y] (mod p)" by simp |
121 by simp |
118 with cong_less_imp_eq_int [of x y p] p_minus_one_l |
122 with cong_less_imp_eq_int [of x y p] p_minus_one_l |
119 order_le_less_trans [of x "(int p - 1) div 2" p] |
123 order_le_less_trans [of x "(int p - 1) div 2" p] |
120 order_le_less_trans [of y "(int p - 1) div 2" p] |
124 order_le_less_trans [of y "(int p - 1) div 2" p] |
121 have "x = y" |
125 show ?thesis |
122 by (metis b c cong_less_imp_eq_int d e zero_less_imp_eq_int of_nat_0_le_iff) |
126 by (metis b c cong_less_imp_eq_int d e zero_less_imp_eq_int of_nat_0_le_iff) |
123 } note xy = this |
127 qed |
124 show ?thesis |
128 show ?thesis |
125 apply (insert p_ge_2 p_a_relprime p_minus_one_l) |
129 apply (insert p_ge_2 p_a_relprime p_minus_one_l) |
126 apply (auto simp add: B_def) |
130 apply (auto simp add: B_def) |
127 apply (rule ResSet_image) |
131 apply (rule ResSet_image) |
128 apply (auto simp add: A_res) |
132 apply (auto simp add: A_res) |
129 apply (auto simp add: A_def xy) |
133 apply (auto simp add: A_def *) |
130 done |
134 done |
|
135 qed |
|
136 |
|
137 lemma SR_B_inj: "inj_on (\<lambda>x. x mod p) B" |
|
138 proof - |
|
139 have False |
|
140 if a: "x * a mod p = y * a mod p" |
|
141 and b: "0 < x" |
|
142 and c: "x \<le> (int p - 1) div 2" |
|
143 and d: "0 < y" |
|
144 and e: "y \<le> (int p - 1) div 2" |
|
145 and f: "x \<noteq> y" |
|
146 for x y |
|
147 proof - |
|
148 from a have a': "[x * a = y * a](mod p)" |
|
149 by (metis cong_int_def) |
|
150 from p_a_relprime have "\<not>p dvd a" |
|
151 by (simp add: cong_altdef_int) |
|
152 with p_prime have "coprime a (int p)" |
|
153 by (subst gcd.commute, intro prime_imp_coprime) auto |
|
154 with a' cong_mult_rcancel_int [of a "int p" x y] |
|
155 have "[x = y] (mod p)" by simp |
|
156 with cong_less_imp_eq_int [of x y p] p_minus_one_l |
|
157 order_le_less_trans [of x "(int p - 1) div 2" p] |
|
158 order_le_less_trans [of y "(int p - 1) div 2" p] |
|
159 have "x = y" |
|
160 by (metis b c cong_less_imp_eq_int d e zero_less_imp_eq_int of_nat_0_le_iff) |
|
161 then show ?thesis |
|
162 by (simp add: f) |
131 qed |
163 qed |
132 |
|
133 lemma SR_B_inj: "inj_on (\<lambda>x. x mod p) B" |
|
134 proof - |
|
135 { fix x fix y |
|
136 assume a: "x * a mod p = y * a mod p" |
|
137 assume b: "0 < x" |
|
138 assume c: "x \<le> (int p - 1) div 2" |
|
139 assume d: "0 < y" |
|
140 assume e: "y \<le> (int p - 1) div 2" |
|
141 assume f: "x \<noteq> y" |
|
142 from a have a': "[x * a = y * a](mod p)" |
|
143 by (metis cong_int_def) |
|
144 from p_a_relprime have "\<not>p dvd a" |
|
145 by (simp add: cong_altdef_int) |
|
146 with p_prime have "coprime a (int p)" |
|
147 by (subst gcd.commute, intro prime_imp_coprime) auto |
|
148 with a' cong_mult_rcancel_int [of a "int p" x y] |
|
149 have "[x = y] (mod p)" by simp |
|
150 with cong_less_imp_eq_int [of x y p] p_minus_one_l |
|
151 order_le_less_trans [of x "(int p - 1) div 2" p] |
|
152 order_le_less_trans [of y "(int p - 1) div 2" p] |
|
153 have "x = y" |
|
154 by (metis b c cong_less_imp_eq_int d e zero_less_imp_eq_int of_nat_0_le_iff) |
|
155 then have False |
|
156 by (simp add: f)} |
|
157 then show ?thesis |
164 then show ?thesis |
158 by (auto simp add: B_def inj_on_def A_def) metis |
165 by (auto simp add: B_def inj_on_def A_def) metis |
159 qed |
166 qed |
160 |
167 |
161 lemma inj_on_pminusx_E: "inj_on (\<lambda>x. p - x) E" |
168 lemma inj_on_pminusx_E: "inj_on (\<lambda>x. p - x) E" |
162 apply (auto simp add: E_def C_def B_def A_def) |
169 apply (auto simp add: E_def C_def B_def A_def) |
163 apply (rule_tac g = "(op - (int p))" in inj_on_inverseI) |
170 apply (rule inj_on_inverseI [where g = "op - (int p)"]) |
164 apply auto |
171 apply auto |
165 done |
172 done |
166 |
173 |
167 lemma nonzero_mod_p: |
174 lemma nonzero_mod_p: "0 < x \<Longrightarrow> x < int p \<Longrightarrow> [x \<noteq> 0](mod p)" |
168 fixes x::int shows "\<lbrakk>0 < x; x < int p\<rbrakk> \<Longrightarrow> [x \<noteq> 0](mod p)" |
175 for x :: int |
169 by (simp add: cong_int_def) |
176 by (simp add: cong_int_def) |
170 |
177 |
171 lemma A_ncong_p: "x \<in> A \<Longrightarrow> [x \<noteq> 0](mod p)" |
178 lemma A_ncong_p: "x \<in> A \<Longrightarrow> [x \<noteq> 0](mod p)" |
172 by (rule nonzero_mod_p) (auto simp add: A_def) |
179 by (rule nonzero_mod_p) (auto simp add: A_def) |
173 |
180 |
174 lemma A_greater_zero: "x \<in> A \<Longrightarrow> 0 < x" |
181 lemma A_greater_zero: "x \<in> A \<Longrightarrow> 0 < x" |
175 by (auto simp add: A_def) |
182 by (auto simp add: A_def) |
176 |
183 |
177 lemma B_ncong_p: "x \<in> B \<Longrightarrow> [x \<noteq> 0](mod p)" |
184 lemma B_ncong_p: "x \<in> B \<Longrightarrow> [x \<noteq> 0](mod p)" |
178 by (auto simp: B_def p_prime p_a_relprime A_ncong_p dest: cong_prime_prod_zero_int) |
185 by (auto simp: B_def p_prime p_a_relprime A_ncong_p dest: cong_prime_prod_zero_int) |
179 |
186 |
180 lemma B_greater_zero: "x \<in> B \<Longrightarrow> 0 < x" |
187 lemma B_greater_zero: "x \<in> B \<Longrightarrow> 0 < x" |
181 using a_nonzero by (auto simp add: B_def A_greater_zero) |
188 using a_nonzero by (auto simp add: B_def A_greater_zero) |
182 |
189 |
183 lemma C_greater_zero: "y \<in> C \<Longrightarrow> 0 < y" |
190 lemma C_greater_zero: "y \<in> C \<Longrightarrow> 0 < y" |
184 proof (auto simp add: C_def) |
191 proof (auto simp add: C_def) |
185 fix x :: int |
192 fix x :: int |
186 assume a1: "x \<in> B" |
193 assume x: "x \<in> B" |
187 have f2: "\<And>x\<^sub>1. int x\<^sub>1 = 0 \<or> 0 < int x\<^sub>1" by linarith |
194 moreover from x have "x mod int p \<noteq> 0" |
188 have "x mod int p \<noteq> 0" using a1 B_ncong_p cong_int_def by simp |
195 using B_ncong_p cong_int_def by simp |
189 thus "0 < x mod int p" using a1 f2 |
196 moreover have "int y = 0 \<or> 0 < int y" for y |
|
197 by linarith |
|
198 ultimately show "0 < x mod int p" |
190 by (metis (no_types) B_greater_zero Divides.transfer_int_nat_functions(2) zero_less_imp_eq_int) |
199 by (metis (no_types) B_greater_zero Divides.transfer_int_nat_functions(2) zero_less_imp_eq_int) |
191 qed |
200 qed |
192 |
201 |
193 lemma F_subset: "F \<subseteq> {x. 0 < x & x \<le> ((int p - 1) div 2)}" |
202 lemma F_subset: "F \<subseteq> {x. 0 < x \<and> x \<le> ((int p - 1) div 2)}" |
194 apply (auto simp add: F_def E_def C_def) |
203 apply (auto simp add: F_def E_def C_def) |
195 apply (metis p_ge_2 Divides.pos_mod_bound less_diff_eq nat_int plus_int_code(2) zless_nat_conj) |
204 apply (metis p_ge_2 Divides.pos_mod_bound nat_int zless_nat_conj) |
196 apply (auto intro: p_odd_int) |
205 apply (auto intro: p_odd_int) |
197 done |
206 done |
198 |
207 |
199 lemma D_subset: "D \<subseteq> {x. 0 < x & x \<le> ((p - 1) div 2)}" |
208 lemma D_subset: "D \<subseteq> {x. 0 < x \<and> x \<le> ((p - 1) div 2)}" |
200 by (auto simp add: D_def C_greater_zero) |
209 by (auto simp add: D_def C_greater_zero) |
201 |
210 |
202 lemma F_eq: "F = {x. \<exists>y \<in> A. ( x = p - ((y*a) mod p) & (int p - 1) div 2 < (y*a) mod p)}" |
211 lemma F_eq: "F = {x. \<exists>y \<in> A. (x = p - ((y * a) mod p) \<and> (int p - 1) div 2 < (y * a) mod p)}" |
203 by (auto simp add: F_def E_def D_def C_def B_def A_def) |
212 by (auto simp add: F_def E_def D_def C_def B_def A_def) |
204 |
213 |
205 lemma D_eq: "D = {x. \<exists>y \<in> A. ( x = (y*a) mod p & (y*a) mod p \<le> (int p - 1) div 2)}" |
214 lemma D_eq: "D = {x. \<exists>y \<in> A. (x = (y * a) mod p \<and> (y * a) mod p \<le> (int p - 1) div 2)}" |
206 by (auto simp add: D_def C_def B_def A_def) |
215 by (auto simp add: D_def C_def B_def A_def) |
207 |
216 |
208 lemma all_A_relprime: assumes "x \<in> A" shows "gcd x p = 1" |
217 lemma all_A_relprime: |
|
218 assumes "x \<in> A" |
|
219 shows "gcd x p = 1" |
209 using p_prime A_ncong_p [OF assms] |
220 using p_prime A_ncong_p [OF assms] |
210 by (auto simp: cong_altdef_int gcd.commute[of _ "int p"] intro!: prime_imp_coprime) |
221 by (auto simp: cong_altdef_int gcd.commute[of _ "int p"] intro!: prime_imp_coprime) |
211 |
222 |
212 lemma A_prod_relprime: "gcd (prod id A) p = 1" |
223 lemma A_prod_relprime: "gcd (prod id A) p = 1" |
213 by (metis id_def all_A_relprime prod_coprime) |
224 by (metis id_def all_A_relprime prod_coprime) |
214 |
225 |
215 |
226 |
216 subsection \<open>Relationships Between Gauss Sets\<close> |
227 subsection \<open>Relationships Between Gauss Sets\<close> |
217 |
228 |
218 lemma StandardRes_inj_on_ResSet: "ResSet m X \<Longrightarrow> (inj_on (\<lambda>b. b mod m) X)" |
229 lemma StandardRes_inj_on_ResSet: "ResSet m X \<Longrightarrow> inj_on (\<lambda>b. b mod m) X" |
219 by (auto simp add: ResSet_def inj_on_def cong_int_def) |
230 by (auto simp add: ResSet_def inj_on_def cong_int_def) |
220 |
231 |
221 lemma B_card_eq_A: "card B = card A" |
232 lemma B_card_eq_A: "card B = card A" |
222 using finite_A by (simp add: finite_A B_def inj_on_xa_A card_image) |
233 using finite_A by (simp add: finite_A B_def inj_on_xa_A card_image) |
223 |
234 |
224 lemma B_card_eq: "card B = nat ((int p - 1) div 2)" |
235 lemma B_card_eq: "card B = nat ((int p - 1) div 2)" |
225 by (simp add: B_card_eq_A A_card_eq) |
236 by (simp add: B_card_eq_A A_card_eq) |
226 |
237 |
227 lemma F_card_eq_E: "card F = card E" |
238 lemma F_card_eq_E: "card F = card E" |
228 using finite_E |
239 using finite_E by (simp add: F_def inj_on_pminusx_E card_image) |
229 by (simp add: F_def inj_on_pminusx_E card_image) |
|
230 |
240 |
231 lemma C_card_eq_B: "card C = card B" |
241 lemma C_card_eq_B: "card C = card B" |
232 proof - |
242 proof - |
233 have "inj_on (\<lambda>x. x mod p) B" |
243 have "inj_on (\<lambda>x. x mod p) B" |
234 by (metis SR_B_inj) |
244 by (metis SR_B_inj) |
235 then show ?thesis |
245 then show ?thesis |
236 by (metis C_def card_image) |
246 by (metis C_def card_image) |
237 qed |
247 qed |
238 |
248 |
239 lemma D_E_disj: "D \<inter> E = {}" |
249 lemma D_E_disj: "D \<inter> E = {}" |
290 then show "card (F \<union> D) = nat ((p - 1) div 2)" |
297 then show "card (F \<union> D) = nat ((p - 1) div 2)" |
291 by (simp add: C_card_eq_B B_card_eq) |
298 by (simp add: C_card_eq_B B_card_eq) |
292 qed |
299 qed |
293 |
300 |
294 lemma F_Un_D_eq_A: "F \<union> D = A" |
301 lemma F_Un_D_eq_A: "F \<union> D = A" |
295 using finite_A F_Un_D_subset A_card_eq F_Un_D_card |
302 using finite_A F_Un_D_subset A_card_eq F_Un_D_card by (auto simp add: card_seteq) |
296 by (auto simp add: card_seteq) |
303 |
297 |
304 lemma prod_D_F_eq_prod_A: "prod id D * prod id F = prod id A" |
298 lemma prod_D_F_eq_prod_A: "(prod id D) * (prod id F) = prod id A" |
|
299 by (metis F_D_disj F_Un_D_eq_A Int_commute Un_commute finite_D finite_F prod.union_disjoint) |
305 by (metis F_D_disj F_Un_D_eq_A Int_commute Un_commute finite_D finite_F prod.union_disjoint) |
300 |
306 |
301 lemma prod_F_zcong: "[prod id F = ((-1) ^ (card E)) * (prod id E)] (mod p)" |
307 lemma prod_F_zcong: "[prod id F = ((-1) ^ (card E)) * prod id E] (mod p)" |
302 proof - |
308 proof - |
303 have FE: "prod id F = prod (op - p) E" |
309 have FE: "prod id F = prod (op - p) E" |
304 apply (auto simp add: F_def) |
310 apply (auto simp add: F_def) |
305 apply (insert finite_E inj_on_pminusx_E) |
311 apply (insert finite_E inj_on_pminusx_E) |
306 apply (drule prod.reindex, auto) |
312 apply (drule prod.reindex) |
|
313 apply auto |
307 done |
314 done |
308 then have "\<forall>x \<in> E. [(p-x) mod p = - x](mod p)" |
315 then have "\<forall>x \<in> E. [(p-x) mod p = - x](mod p)" |
309 by (metis cong_int_def minus_mod_self1 mod_mod_trivial) |
316 by (metis cong_int_def minus_mod_self1 mod_mod_trivial) |
310 then have "[prod ((\<lambda>x. x mod p) o (op - p)) E = prod (uminus) E](mod p)" |
317 then have "[prod ((\<lambda>x. x mod p) o (op - p)) E = prod (uminus) E](mod p)" |
311 using finite_E p_ge_2 |
318 using finite_E p_ge_2 cong_prod_int [of E "(\<lambda>x. x mod p) o (op - p)" uminus p] |
312 cong_prod_int [of E "(\<lambda>x. x mod p) o (op - p)" uminus p] |
|
313 by auto |
319 by auto |
314 then have two: "[prod id F = prod (uminus) E](mod p)" |
320 then have two: "[prod id F = prod (uminus) E](mod p)" |
315 by (metis FE cong_cong_mod_int cong_refl_int cong_prod_int minus_mod_self1) |
321 by (metis FE cong_cong_mod_int cong_refl_int cong_prod_int minus_mod_self1) |
316 have "prod uminus E = (-1) ^ (card E) * (prod id E)" |
322 have "prod uminus E = (-1) ^ card E * prod id E" |
317 using finite_E by (induct set: finite) auto |
323 using finite_E by (induct set: finite) auto |
318 with two show ?thesis |
324 with two show ?thesis |
319 by simp |
325 by simp |
320 qed |
326 qed |
321 |
327 |
322 |
328 |
323 subsection \<open>Gauss' Lemma\<close> |
329 subsection \<open>Gauss' Lemma\<close> |
324 |
330 |
325 lemma aux: "prod id A * (- 1) ^ card E * a ^ card A * (- 1) ^ card E = prod id A * a ^ card A" |
331 lemma aux: "prod id A * (- 1) ^ card E * a ^ card A * (- 1) ^ card E = prod id A * a ^ card A" |
326 by (metis (no_types) minus_minus mult.commute mult.left_commute power_minus power_one) |
332 by (metis (no_types) minus_minus mult.commute mult.left_commute power_minus power_one) |
327 |
333 |
328 theorem pre_gauss_lemma: |
334 theorem pre_gauss_lemma: "[a ^ nat((int p - 1) div 2) = (-1) ^ (card E)] (mod p)" |
329 "[a ^ nat((int p - 1) div 2) = (-1) ^ (card E)] (mod p)" |
|
330 proof - |
335 proof - |
331 have "[prod id A = prod id F * prod id D](mod p)" |
336 have "[prod id A = prod id F * prod id D](mod p)" |
332 by (auto simp add: prod_D_F_eq_prod_A mult.commute cong del: prod.strong_cong) |
337 by (auto simp: prod_D_F_eq_prod_A mult.commute cong del: prod.strong_cong) |
333 then have "[prod id A = ((-1)^(card E) * prod id E) * prod id D] (mod p)" |
338 then have "[prod id A = ((-1)^(card E) * prod id E) * prod id D] (mod p)" |
334 apply (rule cong_trans_int) |
339 by (rule cong_trans_int) (metis cong_scalar_int prod_F_zcong) |
335 apply (metis cong_scalar_int prod_F_zcong) |
|
336 done |
|
337 then have "[prod id A = ((-1)^(card E) * prod id C)] (mod p)" |
340 then have "[prod id A = ((-1)^(card E) * prod id C)] (mod p)" |
338 by (metis C_prod_eq_D_times_E mult.commute mult.left_commute) |
341 by (metis C_prod_eq_D_times_E mult.commute mult.left_commute) |
339 then have "[prod id A = ((-1)^(card E) * prod id B)] (mod p)" |
342 then have "[prod id A = ((-1)^(card E) * prod id B)] (mod p)" |
340 by (rule cong_trans_int) (metis C_B_zcong_prod cong_scalar2_int) |
343 by (rule cong_trans_int) (metis C_B_zcong_prod cong_scalar2_int) |
341 then have "[prod id A = ((-1)^(card E) * |
344 then have "[prod id A = ((-1)^(card E) * prod id ((\<lambda>x. x * a) ` A))] (mod p)" |
342 (prod id ((\<lambda>x. x * a) ` A)))] (mod p)" |
|
343 by (simp add: B_def) |
345 by (simp add: B_def) |
344 then have "[prod id A = ((-1)^(card E) * (prod (\<lambda>x. x * a) A))] |
346 then have "[prod id A = ((-1)^(card E) * prod (\<lambda>x. x * a) A)] (mod p)" |
345 (mod p)" |
|
346 by (simp add: inj_on_xa_A prod.reindex) |
347 by (simp add: inj_on_xa_A prod.reindex) |
347 moreover have "prod (\<lambda>x. x * a) A = |
348 moreover have "prod (\<lambda>x. x * a) A = prod (\<lambda>x. a) A * prod id A" |
348 prod (\<lambda>x. a) A * prod id A" |
|
349 using finite_A by (induct set: finite) auto |
349 using finite_A by (induct set: finite) auto |
350 ultimately have "[prod id A = ((-1)^(card E) * (prod (\<lambda>x. a) A * |
350 ultimately have "[prod id A = ((-1)^(card E) * (prod (\<lambda>x. a) A * prod id A))] (mod p)" |
351 prod id A))] (mod p)" |
|
352 by simp |
351 by simp |
353 then have "[prod id A = ((-1)^(card E) * a^(card A) * |
352 then have "[prod id A = ((-1)^(card E) * a^(card A) * prod id A)](mod p)" |
354 prod id A)](mod p)" |
353 by (rule cong_trans_int) |
355 apply (rule cong_trans_int) |
354 (simp add: cong_scalar2_int cong_scalar_int finite_A prod_constant mult.assoc) |
356 apply (simp add: cong_scalar2_int cong_scalar_int finite_A prod_constant mult.assoc) |
|
357 done |
|
358 then have a: "[prod id A * (-1)^(card E) = |
355 then have a: "[prod id A * (-1)^(card E) = |
359 ((-1)^(card E) * a^(card A) * prod id A * (-1)^(card E))](mod p)" |
356 ((-1)^(card E) * a^(card A) * prod id A * (-1)^(card E))](mod p)" |
360 by (rule cong_scalar_int) |
357 by (rule cong_scalar_int) |
361 then have "[prod id A * (-1)^(card E) = prod id A * |
358 then have "[prod id A * (-1)^(card E) = prod id A * |
362 (-1)^(card E) * a^(card A) * (-1)^(card E)](mod p)" |
359 (-1)^(card E) * a^(card A) * (-1)^(card E)](mod p)" |
363 apply (rule cong_trans_int) |
360 by (rule cong_trans_int) (simp add: a mult.commute mult.left_commute) |
364 apply (simp add: a mult.commute mult.left_commute) |
|
365 done |
|
366 then have "[prod id A * (-1)^(card E) = prod id A * a^(card A)](mod p)" |
361 then have "[prod id A * (-1)^(card E) = prod id A * a^(card A)](mod p)" |
367 apply (rule cong_trans_int) |
362 by (rule cong_trans_int) (simp add: aux cong del: prod.strong_cong) |
368 apply (simp add: aux cong del: prod.strong_cong) |
|
369 done |
|
370 with A_prod_relprime have "[(- 1) ^ card E = a ^ card A](mod p)" |
363 with A_prod_relprime have "[(- 1) ^ card E = a ^ card A](mod p)" |
371 by (metis cong_mult_lcancel_int) |
364 by (metis cong_mult_lcancel_int) |
372 then show ?thesis |
365 then show ?thesis |
373 by (simp add: A_card_eq cong_sym_int) |
366 by (simp add: A_card_eq cong_sym_int) |
374 qed |
367 qed |
375 |
368 |
376 theorem gauss_lemma: "(Legendre a p) = (-1) ^ (card E)" |
369 theorem gauss_lemma: "Legendre a p = (-1) ^ (card E)" |
377 proof - |
370 proof - |
378 from euler_criterion p_prime p_ge_2 have |
371 from euler_criterion p_prime p_ge_2 have "[Legendre a p = a^(nat (((p) - 1) div 2))] (mod p)" |
379 "[(Legendre a p) = a^(nat (((p) - 1) div 2))] (mod p)" |
|
380 by auto |
372 by auto |
381 moreover have "int ((p - 1) div 2) =(int p - 1) div 2" using p_eq2 by linarith |
373 moreover have "int ((p - 1) div 2) = (int p - 1) div 2" |
382 hence "[a ^ nat (int ((p - 1) div 2)) = a ^ nat ((int p - 1) div 2)] (mod int p)" by force |
374 using p_eq2 by linarith |
383 moreover note pre_gauss_lemma |
375 then have "[a ^ nat (int ((p - 1) div 2)) = a ^ nat ((int p - 1) div 2)] (mod int p)" |
384 ultimately have "[(Legendre a p) = (-1) ^ (card E)] (mod p)" using cong_trans_int by blast |
376 by force |
385 moreover from p_a_relprime have "(Legendre a p) = 1 | (Legendre a p) = (-1)" |
377 ultimately have "[Legendre a p = (-1) ^ (card E)] (mod p)" |
|
378 using pre_gauss_lemma cong_trans_int by blast |
|
379 moreover from p_a_relprime have "Legendre a p = 1 \<or> Legendre a p = -1" |
386 by (auto simp add: Legendre_def) |
380 by (auto simp add: Legendre_def) |
387 moreover have "(-1::int) ^ (card E) = 1 | (-1::int) ^ (card E) = -1" |
381 moreover have "(-1::int) ^ (card E) = 1 \<or> (-1::int) ^ (card E) = -1" |
388 using neg_one_even_power neg_one_odd_power by blast |
382 using neg_one_even_power neg_one_odd_power by blast |
389 moreover have "[1 \<noteq> - 1] (mod int p)" |
383 moreover have "[1 \<noteq> - 1] (mod int p)" |
390 using cong_altdef_int nonzero_mod_p[of 2] p_odd_int by fastforce |
384 using cong_altdef_int nonzero_mod_p[of 2] p_odd_int by fastforce |
391 ultimately show ?thesis |
385 ultimately show ?thesis |
392 by (auto simp add: cong_sym_int) |
386 by (auto simp add: cong_sym_int) |