100 field_one_not_zero: "1 ~= 0" |
100 field_one_not_zero: "1 ~= 0" |
101 (* Avoid a common superclass as the first thing we will |
101 (* Avoid a common superclass as the first thing we will |
102 prove about fields is that they are domains. *) |
102 prove about fields is that they are domains. *) |
103 field_ax: "a ~= 0 ==> a dvd 1" |
103 field_ax: "a ~= 0 ==> a dvd 1" |
104 |
104 |
|
105 |
105 section {* Basic facts *} |
106 section {* Basic facts *} |
106 |
107 |
107 subsection {* Normaliser for rings *} |
108 subsection {* Normaliser for rings *} |
108 |
109 |
109 use "order.ML" |
110 (* derived rewrite rules *) |
|
111 |
|
112 lemma a_lcomm: "(a::'a::ring)+(b+c) = b+(a+c)" |
|
113 apply (rule a_comm [THEN trans]) |
|
114 apply (rule a_assoc [THEN trans]) |
|
115 apply (rule a_comm [THEN arg_cong]) |
|
116 done |
|
117 |
|
118 lemma r_zero: "(a::'a::ring) + 0 = a" |
|
119 apply (rule a_comm [THEN trans]) |
|
120 apply (rule l_zero) |
|
121 done |
|
122 |
|
123 lemma r_neg: "(a::'a::ring) + (-a) = 0" |
|
124 apply (rule a_comm [THEN trans]) |
|
125 apply (rule l_neg) |
|
126 done |
|
127 |
|
128 lemma r_neg2: "(a::'a::ring) + (-a + b) = b" |
|
129 apply (rule a_assoc [symmetric, THEN trans]) |
|
130 apply (simp add: r_neg l_zero) |
|
131 done |
|
132 |
|
133 lemma r_neg1: "-(a::'a::ring) + (a + b) = b" |
|
134 apply (rule a_assoc [symmetric, THEN trans]) |
|
135 apply (simp add: l_neg l_zero) |
|
136 done |
|
137 |
|
138 |
|
139 (* auxiliary *) |
|
140 |
|
141 lemma a_lcancel: "!! a::'a::ring. a + b = a + c ==> b = c" |
|
142 apply (rule box_equals) |
|
143 prefer 2 |
|
144 apply (rule l_zero) |
|
145 prefer 2 |
|
146 apply (rule l_zero) |
|
147 apply (rule_tac a1 = a in l_neg [THEN subst]) |
|
148 apply (simp add: a_assoc) |
|
149 done |
|
150 |
|
151 lemma minus_add: "-((a::'a::ring) + b) = (-a) + (-b)" |
|
152 apply (rule_tac a = "a + b" in a_lcancel) |
|
153 apply (simp add: r_neg l_neg l_zero a_assoc a_comm a_lcomm) |
|
154 done |
|
155 |
|
156 lemma minus_minus: "-(-(a::'a::ring)) = a" |
|
157 apply (rule a_lcancel) |
|
158 apply (rule r_neg [THEN trans]) |
|
159 apply (rule l_neg [symmetric]) |
|
160 done |
|
161 |
|
162 lemma minus0: "- 0 = (0::'a::ring)" |
|
163 apply (rule a_lcancel) |
|
164 apply (rule r_neg [THEN trans]) |
|
165 apply (rule l_zero [symmetric]) |
|
166 done |
|
167 |
|
168 |
|
169 (* derived rules for multiplication *) |
|
170 |
|
171 lemma m_lcomm: "(a::'a::ring)*(b*c) = b*(a*c)" |
|
172 apply (rule m_comm [THEN trans]) |
|
173 apply (rule m_assoc [THEN trans]) |
|
174 apply (rule m_comm [THEN arg_cong]) |
|
175 done |
|
176 |
|
177 lemma r_one: "(a::'a::ring) * 1 = a" |
|
178 apply (rule m_comm [THEN trans]) |
|
179 apply (rule l_one) |
|
180 done |
|
181 |
|
182 lemma r_distr: "(a::'a::ring) * (b + c) = a * b + a * c" |
|
183 apply (rule m_comm [THEN trans]) |
|
184 apply (rule l_distr [THEN trans]) |
|
185 apply (simp add: m_comm) |
|
186 done |
|
187 |
|
188 |
|
189 (* the following proof is from Jacobson, Basic Algebra I, pp. 88-89 *) |
|
190 lemma l_null: "0 * (a::'a::ring) = 0" |
|
191 apply (rule a_lcancel) |
|
192 apply (rule l_distr [symmetric, THEN trans]) |
|
193 apply (simp add: r_zero) |
|
194 done |
|
195 |
|
196 lemma r_null: "(a::'a::ring) * 0 = 0" |
|
197 apply (rule m_comm [THEN trans]) |
|
198 apply (rule l_null) |
|
199 done |
|
200 |
|
201 lemma l_minus: "(-(a::'a::ring)) * b = - (a * b)" |
|
202 apply (rule a_lcancel) |
|
203 apply (rule r_neg [symmetric, THEN [2] trans]) |
|
204 apply (rule l_distr [symmetric, THEN trans]) |
|
205 apply (simp add: l_null r_neg) |
|
206 done |
|
207 |
|
208 lemma r_minus: "(a::'a::ring) * (-b) = - (a * b)" |
|
209 apply (rule a_lcancel) |
|
210 apply (rule r_neg [symmetric, THEN [2] trans]) |
|
211 apply (rule r_distr [symmetric, THEN trans]) |
|
212 apply (simp add: r_null r_neg) |
|
213 done |
|
214 |
|
215 (*** Term order for commutative rings ***) |
|
216 |
|
217 ML {* |
|
218 fun ring_ord (Const (a, _)) = |
|
219 find_index (fn a' => a = a') |
|
220 ["HOL.zero", "HOL.plus", "HOL.uminus", "HOL.minus", "HOL.one", "HOL.times"] |
|
221 | ring_ord _ = ~1; |
|
222 |
|
223 fun termless_ring (a, b) = (Term.term_lpo ring_ord (a, b) = LESS); |
|
224 |
|
225 val ring_ss = HOL_basic_ss settermless termless_ring addsimps |
|
226 [thm "a_assoc", thm "l_zero", thm "l_neg", thm "a_comm", thm "m_assoc", |
|
227 thm "l_one", thm "l_distr", thm "m_comm", thm "minus_def", |
|
228 thm "r_zero", thm "r_neg", thm "r_neg2", thm "r_neg1", thm "minus_add", |
|
229 thm "minus_minus", thm "minus0", thm "a_lcomm", thm "m_lcomm", (*thm "r_one",*) |
|
230 thm "r_distr", thm "l_null", thm "r_null", thm "l_minus", thm "r_minus"]; |
|
231 *} (* Note: r_one is not necessary in ring_ss *) |
110 |
232 |
111 method_setup ring = |
233 method_setup ring = |
112 {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *} |
234 {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *} |
113 {* computes distributive normal form in rings *} |
235 {* computes distributive normal form in rings *} |
|
236 |
|
237 lemmas ring_simps = |
|
238 l_zero r_zero l_neg r_neg minus_minus minus0 |
|
239 l_one r_one l_null r_null l_minus r_minus |
114 |
240 |
115 |
241 |
116 subsection {* Rings and the summation operator *} |
242 subsection {* Rings and the summation operator *} |
117 |
243 |
118 (* Basic facts --- move to HOL!!! *) |
244 (* Basic facts --- move to HOL!!! *) |
276 ultimately have "c = a * (l * j)" by simp |
402 ultimately have "c = a * (l * j)" by simp |
277 then have "\<exists>k. c = a * k" .. |
403 then have "\<exists>k. c = a * k" .. |
278 then show ?thesis using dvd_def by blast |
404 then show ?thesis using dvd_def by blast |
279 qed |
405 qed |
280 |
406 |
281 lemma dvd_def': |
407 |
282 "m dvd n \<equiv> \<exists>k. n = m * k" unfolding dvd_def by simp |
408 lemma unit_mult: |
|
409 "!!a::'a::ring. [| a dvd 1; b dvd 1 |] ==> a * b dvd 1" |
|
410 apply (unfold dvd_def) |
|
411 apply clarify |
|
412 apply (rule_tac x = "k * ka" in exI) |
|
413 apply simp |
|
414 done |
|
415 |
|
416 lemma unit_power: "!!a::'a::ring. a dvd 1 ==> a^n dvd 1" |
|
417 apply (induct_tac n) |
|
418 apply simp |
|
419 apply (simp add: unit_mult) |
|
420 done |
|
421 |
|
422 lemma dvd_add_right [simp]: |
|
423 "!! a::'a::ring. [| a dvd b; a dvd c |] ==> a dvd b + c" |
|
424 apply (unfold dvd_def) |
|
425 apply clarify |
|
426 apply (rule_tac x = "k + ka" in exI) |
|
427 apply (simp add: r_distr) |
|
428 done |
|
429 |
|
430 lemma dvd_uminus_right [simp]: |
|
431 "!! a::'a::ring. a dvd b ==> a dvd -b" |
|
432 apply (unfold dvd_def) |
|
433 apply clarify |
|
434 apply (rule_tac x = "-k" in exI) |
|
435 apply (simp add: r_minus) |
|
436 done |
|
437 |
|
438 lemma dvd_l_mult_right [simp]: |
|
439 "!! a::'a::ring. a dvd b ==> a dvd c*b" |
|
440 apply (unfold dvd_def) |
|
441 apply clarify |
|
442 apply (rule_tac x = "c * k" in exI) |
|
443 apply simp |
|
444 done |
|
445 |
|
446 lemma dvd_r_mult_right [simp]: |
|
447 "!! a::'a::ring. a dvd b ==> a dvd b*c" |
|
448 apply (unfold dvd_def) |
|
449 apply clarify |
|
450 apply (rule_tac x = "k * c" in exI) |
|
451 apply simp |
|
452 done |
|
453 |
|
454 |
|
455 (* Inverse of multiplication *) |
|
456 |
|
457 section "inverse" |
|
458 |
|
459 lemma inverse_unique: "!! a::'a::ring. [| a * x = 1; a * y = 1 |] ==> x = y" |
|
460 apply (rule_tac a = "(a*y) * x" and b = "y * (a*x)" in box_equals) |
|
461 apply (simp (no_asm)) |
|
462 apply auto |
|
463 done |
|
464 |
|
465 lemma r_inverse_ring: "!! a::'a::ring. a dvd 1 ==> a * inverse a = 1" |
|
466 apply (unfold inverse_def dvd_def) |
|
467 apply (tactic {* asm_full_simp_tac (simpset () delsimprocs [ring_simproc]) 1 *}) |
|
468 apply clarify |
|
469 apply (rule theI) |
|
470 apply assumption |
|
471 apply (rule inverse_unique) |
|
472 apply assumption |
|
473 apply assumption |
|
474 done |
|
475 |
|
476 lemma l_inverse_ring: "!! a::'a::ring. a dvd 1 ==> inverse a * a = 1" |
|
477 by (simp add: r_inverse_ring) |
|
478 |
|
479 |
|
480 (* Fields *) |
|
481 |
|
482 section "Fields" |
|
483 |
|
484 lemma field_unit [simp]: "!! a::'a::field. (a dvd 1) = (a ~= 0)" |
|
485 by (auto dest: field_ax dvd_zero_left simp add: field_one_not_zero) |
|
486 |
|
487 lemma r_inverse [simp]: "!! a::'a::field. a ~= 0 ==> a * inverse a = 1" |
|
488 by (simp add: r_inverse_ring) |
|
489 |
|
490 lemma l_inverse [simp]: "!! a::'a::field. a ~= 0 ==> inverse a * a= 1" |
|
491 by (simp add: l_inverse_ring) |
|
492 |
|
493 |
|
494 (* fields are integral domains *) |
|
495 |
|
496 lemma field_integral: "!! a::'a::field. a * b = 0 ==> a = 0 | b = 0" |
|
497 apply (tactic "Step_tac 1") |
|
498 apply (rule_tac a = " (a*b) * inverse b" in box_equals) |
|
499 apply (rule_tac [3] refl) |
|
500 prefer 2 |
|
501 apply (simp (no_asm)) |
|
502 apply auto |
|
503 done |
|
504 |
|
505 |
|
506 (* fields are factorial domains *) |
|
507 |
|
508 lemma field_fact_prime: "!! a::'a::field. irred a ==> prime a" |
|
509 unfolding prime_def irred_def by (blast intro: field_ax) |
283 |
510 |
284 end |
511 end |