2 Abstract class ring (commutative, with 1)
4 Author: Clemens Ballarin, started 9 December 1996
8 val a_assoc = thm "semigroup_add.add_assoc";
9 val l_zero = thm "comm_monoid_add.add_0";
10 val a_comm = thm "ab_semigroup_add.add_commute";
14 fun make_left_commute assoc commute s =
15 [rtac (commute RS trans) 1, rtac (assoc RS trans) 1,
16 rtac (commute RS arg_cong) 1];
20 qed_goal "a_lcomm" Ring.thy "!!a::'a::ring. a+(b+c) = b+(a+c)"
21 (make_left_commute a_assoc a_comm);
23 val a_ac = [a_assoc, a_comm, a_lcomm];
25 Goal "!!a::'a::ring. a + 0 = a";
26 by (rtac (a_comm RS trans) 1);
30 Goal "!!a::'a::ring. a + (-a) = 0";
31 by (rtac (a_comm RS trans) 1);
35 Goal "!! a::'a::ring. a + b = a + c ==> b = c";
36 by (rtac box_equals 1);
39 by (res_inst_tac [("a1", "a")] (l_neg RS subst) 1);
40 by (asm_simp_tac (simpset() addsimps [a_assoc]) 1);
43 Goal "!! a::'a::ring. b + a = c + a ==> b = c";
44 by (rtac a_lcancel 1);
45 by (asm_simp_tac (simpset() addsimps a_ac) 1);
48 Goal "!! a::'a::ring. (a + b = a + c) = (b = c)";
49 by (auto_tac (claset() addSDs [a_lcancel], simpset()));
52 Goal "!! a::'a::ring. (b + a = c + a) = (b = c)";
53 by (simp_tac (simpset() addsimps [a_lcancel_eq, a_comm]) 1);
56 Addsimps [a_lcancel_eq, a_rcancel_eq];
58 Goal "!!a::'a::ring. -(-a) = a";
59 by (rtac a_lcancel 1);
60 by (rtac (r_neg RS trans) 1);
61 by (rtac (l_neg RS sym) 1);
64 Goal "- 0 = (0::'a::ring)";
65 by (rtac a_lcancel 1);
66 by (rtac (r_neg RS trans) 1);
67 by (rtac (l_zero RS sym) 1);
70 Goal "!!a::'a::ring. -(a + b) = (-a) + (-b)";
71 by (res_inst_tac [("a", "a+b")] a_lcancel 1);
72 by (simp_tac (simpset() addsimps ([r_neg, l_neg, l_zero]@a_ac)) 1);
77 qed_goal "m_lcomm" Ring.thy "!!a::'a::ring. a*(b*c) = b*(a*c)"
78 (make_left_commute m_assoc m_comm);
80 val m_ac = [m_assoc, m_comm, m_lcomm];
82 Goal "!!a::'a::ring. a * 1 = a";
83 by (rtac (m_comm RS trans) 1);
87 (* distributive and derived *)
89 Goal "!!a::'a::ring. a * (b + c) = a * b + a * c";
90 by (rtac (m_comm RS trans) 1);
91 by (rtac (l_distr RS trans) 1);
92 by (simp_tac (simpset() addsimps [m_comm]) 1);
95 val m_distr = m_ac @ [l_distr, r_distr];
97 (* the following two proofs can be found in
98 Jacobson, Basic Algebra I, pp. 88-89 *)
100 Goal "!!a::'a::ring. 0 * a = 0";
101 by (rtac a_lcancel 1);
102 by (rtac (l_distr RS sym RS trans) 1);
103 by (simp_tac (simpset() addsimps [r_zero]) 1);
106 Goal "!!a::'a::ring. a * 0 = 0";
107 by (rtac (m_comm RS trans) 1);
111 Goal "!!a::'a::ring. (-a) * b = - (a * b)";
112 by (rtac a_lcancel 1);
113 by (rtac (r_neg RS sym RSN (2, trans)) 1);
114 by (rtac (l_distr RS sym RS trans) 1);
115 by (simp_tac (simpset() addsimps [l_null, r_neg]) 1);
118 Goal "!!a::'a::ring. a * (-b) = - (a * b)";
119 by (rtac a_lcancel 1);
120 by (rtac (r_neg RS sym RSN (2, trans)) 1);
121 by (rtac (r_distr RS sym RS trans) 1);
122 by (simp_tac (simpset() addsimps [r_null, r_neg]) 1);
125 val m_minus = [l_minus, r_minus];
127 Addsimps [l_zero, r_zero, l_neg, r_neg, minus_minus, minus0,
128 l_one, r_one, l_null, r_null];
132 Goal "!!a::'a::ring. -a = 0 ==> a = 0";
133 by (res_inst_tac [("t", "a")] (minus_minus RS subst) 1);
137 Goal "!!a::'a::ring. a ~= 0 ==> -a ~= 0";
138 by (blast_tac (claset() addIs [uminus_monom]) 1);
139 qed "uminus_monom_neq";
141 Goal "!!a::'a::ring. a * b ~= 0 ==> a ~= 0";
145 Goal "!!a::'a::ring. a * b ~= 0 ==> b ~= 0";
149 (* reflection between a = b and a -- b = 0 *)
151 Goal "!!a::'a::ring. a = b ==> a + (-b) = 0";
153 qed "eq_imp_diff_zero";
155 Goal "!!a::'a::ring. a + (-b) = 0 ==> a = b";
156 by (res_inst_tac [("a", "-b")] a_rcancel 1);
158 qed "diff_zero_imp_eq";
160 (* this could be a rewrite rule, but won't terminate
161 ==> make it a simproc?
162 Goal "!!a::'a::ring. (a = b) = (a -- b = 0)";
169 Goal "!!a::'a::ring. a ^ 0 = 1";
170 by (simp_tac (simpset() addsimps [power_def]) 1);
173 Goal "!!a::'a::ring. a ^ Suc n = a ^ n * a";
174 by (simp_tac (simpset() addsimps [power_def]) 1);
177 Addsimps [power_0, power_Suc];
179 Goal "1 ^ n = (1::'a::ring)";
180 by (induct_tac "n" 1);
184 Goal "!!n. n ~= 0 ==> 0 ^ n = (0::'a::ring)";
186 by (induct_tac "n" 1);
190 Addsimps [power_zero, power_one];
192 Goal "!! a::'a::ring. a ^ m * a ^ n = a ^ (m + n)";
193 by (induct_tac "m" 1);
199 section "Divisibility";
201 Goalw [dvd_def] "!! a::'a::ring. a dvd 0";
202 by (res_inst_tac [("x", "0")] exI 1);
204 qed "dvd_zero_right";
206 Goalw [dvd_def] "!! a::'a::ring. 0 dvd a ==> a = 0";
210 Goalw [dvd_def] "!! a::'a::ring. a dvd a";
211 by (res_inst_tac [("x", "1")] exI 1);
215 Goalw [dvd_def] "!! a::'a::ring. [| a dvd b; b dvd c |] ==> a dvd c";
217 by (res_inst_tac [("x", "k * ka")] exI 1);
219 qed "dvd_trans_ring";
221 Addsimps [dvd_zero_right, dvd_refl_ring];
224 "!!a::'a::ring. [| a dvd 1; b dvd 1 |] ==> a * b dvd 1";
226 by (res_inst_tac [("x", "k * ka")] exI 1);
227 by (Asm_full_simp_tac 1);
230 Goal "!!a::'a::ring. a dvd 1 ==> a^n dvd 1";
231 by (induct_tac "n" 1);
233 by (asm_simp_tac (simpset() addsimps [unit_mult]) 1);
237 "!! a::'a::ring. [| a dvd b; a dvd c |] ==> a dvd b + c";
239 by (res_inst_tac [("x", "k + ka")] exI 1);
240 by (simp_tac (simpset() addsimps [r_distr]) 1);
244 "!! a::'a::ring. a dvd b ==> a dvd -b";
246 by (res_inst_tac [("x", "-k")] exI 1);
247 by (simp_tac (simpset() addsimps [r_minus]) 1);
248 qed "dvd_uminus_right";
251 "!! a::'a::ring. a dvd b ==> a dvd c*b";
253 by (res_inst_tac [("x", "c * k")] exI 1);
255 qed "dvd_l_mult_right";
258 "!! a::'a::ring. a dvd b ==> a dvd b*c";
260 by (res_inst_tac [("x", "k * c")] exI 1);
262 qed "dvd_r_mult_right";
264 Addsimps [dvd_add_right, dvd_uminus_right, dvd_l_mult_right, dvd_r_mult_right];
266 (* Inverse of multiplication *)
270 Goal "!! a::'a::ring. [| a * x = 1; a * y = 1 |] ==> x = y";
271 by (res_inst_tac [("a", "(a*y)*x"), ("b", "y*(a*x)")] box_equals 1);
274 qed "inverse_unique";
276 Goal "!! a::'a::ring. a dvd 1 ==> a * inverse a = 1";
277 by (asm_full_simp_tac (simpset () addsimps [inverse_def, dvd_def]
278 delsimprocs [ring_simproc]) 1);
282 by (rtac inverse_unique 1);
285 qed "r_inverse_ring";
287 Goal "!! a::'a::ring. a dvd 1 ==> inverse a * a= 1";
288 by (asm_simp_tac (simpset() addsimps [r_inverse_ring]) 1);
289 qed "l_inverse_ring";
291 (* Integral domain *)
294 section "Integral domains";
296 Goal "0 ~= (1::'a::domain)";
298 by (rtac one_not_zero 1);
301 Goal "!! a::'a::domain. a dvd 1 ==> a ~= 0";
302 by (auto_tac (claset() addDs [dvd_zero_left],
303 simpset() addsimps [one_not_zero] ));
304 qed "unit_imp_nonzero";
306 Goal "[| a * b = 0; a ~= 0 |] ==> (b::'a::domain) = 0";
307 by (dtac integral 1);
311 Goal "[| a * b = 0; b ~= 0 |] ==> (a::'a::domain) = 0";
312 by (dtac integral 1);
316 Goal "!! a::'a::domain. [| a ~= 0; b ~= 0 |] ==> a * b ~= 0";
317 by (blast_tac (claset() addIs [l_integral]) 1);
320 Addsimps [not_integral, one_not_zero, zero_not_one];
322 Goal "!! a::'a::domain. [| a * x = x; x ~= 0 |] ==> a = 1";
323 by (res_inst_tac [("a", "- 1")] a_lcancel 1);
325 by (rtac l_integral 1);
327 by (asm_simp_tac (simpset() addsimps [l_distr, l_minus]) 1);
328 qed "l_one_integral";
330 Goal "!! a::'a::domain. [| x * a = x; x ~= 0 |] ==> a = 1";
331 by (res_inst_tac [("a", "- 1")] a_rcancel 1);
333 by (rtac r_integral 1);
335 by (asm_simp_tac (simpset() addsimps [r_distr, r_minus]) 1);
336 qed "r_one_integral";
338 (* cancellation laws for multiplication *)
340 Goal "!! a::'a::domain. [| a ~= 0; a * b = a * c |] ==> b = c";
341 by (rtac diff_zero_imp_eq 1);
342 by (dtac eq_imp_diff_zero 1);
343 by (full_simp_tac (simpset() addsimps [r_minus RS sym, r_distr RS sym]) 1);
344 by (fast_tac (claset() addIs [l_integral]) 1);
347 Goal "!! a::'a::domain. [| a ~= 0; b * a = c * a |] ==> b = c";
348 by (rtac m_lcancel 1);
350 by (Asm_full_simp_tac 1);
353 Goal "!! a::'a::domain. a ~= 0 ==> (a * b = a * c) = (b = c)";
354 by (auto_tac (claset() addDs [m_lcancel], simpset()));
357 Goal "!! a::'a::domain. a ~= 0 ==> (b * a = c * a) = (b = c)";
358 by (asm_simp_tac (simpset() addsimps [m_lcancel_eq, m_comm]) 1);
361 Addsimps [m_lcancel_eq, m_rcancel_eq];
368 Goal "!! a::'a::field. (a dvd 1) = (a ~= 0)";
369 by (auto_tac (claset() addDs [thm "field_ax", dvd_zero_left],
370 simpset() addsimps [thm "field_one_not_zero"]));
373 (* required for instantiation of field < domain in file Field.thy *)
375 Addsimps [field_unit];
377 val field_one_not_zero = thm "field_one_not_zero";
379 Goal "!! a::'a::field. a ~= 0 ==> a * inverse a = 1";
380 by (asm_full_simp_tac (simpset() addsimps [r_inverse_ring]) 1);
383 Goal "!! a::'a::field. a ~= 0 ==> inverse a * a= 1";
384 by (asm_full_simp_tac (simpset() addsimps [l_inverse_ring]) 1);
387 Addsimps [l_inverse, r_inverse];
389 (* fields are integral domains *)
391 Goal "!! a::'a::field. a * b = 0 ==> a = 0 | b = 0";
393 by (res_inst_tac [("a", "(a*b)*inverse b")] box_equals 1);
397 qed "field_integral";
399 (* fields are factorial domains *)
401 Goalw [thm "prime_def", thm "irred_def"]
402 "!! a::'a::field. irred a ==> prime a";
403 by (blast_tac (claset() addIs [thm "field_ax"]) 1);
404 qed "field_fact_prime";