2 Title: The algebraic hierarchy of rings as axiomatic classes
4 Author: Clemens Ballarin, started 9 December 1996
5 Copyright: Clemens Ballarin
8 header {* The algebraic hierarchy of rings as axiomatic classes *}
13 section {* Constants *}
15 text {* Most constants are already declared by HOL. *}
18 assoc :: "['a::times, 'a] => bool" (infixl 50)
19 irred :: "'a::{zero, one, times} => bool"
20 prime :: "'a::{zero, one, times} => bool"
24 subsection {* Ring axioms *}
26 axclass ring < zero, one, plus, minus, times, inverse, power
28 a_assoc: "(a + b) + c = a + (b + c)"
31 a_comm: "a + b = b + a"
33 m_assoc: "(a * b) * c = a * (b * c)"
36 l_distr: "(a + b) * c = a * c + b * c"
38 m_comm: "a * b = b * a"
40 -- {* Definition of derived operations *}
42 minus_def: "a - b = a + (-b)"
43 inverse_def: "inverse a = (if a dvd 1 then THE x. a*x = 1 else 0)"
44 divide_def: "a / b = a * inverse b"
45 power_def: "a ^ n = nat_rec 1 (%u b. b * a) n"
48 assoc_def: "a assoc b == a dvd b & b dvd a"
49 irred_def: "irred a == a ~= 0 & ~ a dvd 1
50 & (ALL d. d dvd a --> d dvd 1 | a dvd d)"
51 prime_def: "prime p == p ~= 0 & ~ p dvd 1
52 & (ALL a b. p dvd (a*b) --> p dvd a | p dvd b)"
54 subsection {* Integral domains *}
59 one_not_zero: "1 ~= 0"
60 integral: "a * b = 0 ==> a = 0 | b = 0"
62 subsection {* Factorial domains *}
68 Proper definition using divisor chain condition currently not supported.
69 factorial_divisor: "wf {(a, b). a dvd b & ~ (b dvd a)}"
71 factorial_divisor: "True"
72 factorial_prime: "irred a ==> prime a"
74 subsection {* Euclidean domains *}
80 euclidean_ax: "b ~= 0 ==> Ex (% (q, r, e_size::('a::ringS)=>nat).
81 a = b * q + r & e_size r < e_size b)"
83 Nothing has been proved about Euclidean domains, yet.
85 Fix quo, rem and e_size as constants that are axiomatised with
87 - advantage: more pragmatic and easier to use
88 - disadvantage: for every type, one definition of quo and rem will
89 be fixed, users may want to use differing ones;
90 also, it seems not possible to prove that fields are euclidean
91 domains, because that would require generic (type-independent)
92 definitions of quo and rem.
95 subsection {* Fields *}
100 field_one_not_zero: "1 ~= 0"
101 (* Avoid a common superclass as the first thing we will
102 prove about fields is that they are domains. *)
103 field_ax: "a ~= 0 ==> a dvd 1"
105 section {* Basic facts *}
107 subsection {* Normaliser for rings *}
112 {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *}
113 {* computes distributive normal form in rings *}
116 subsection {* Rings and the summation operator *}
118 (* Basic facts --- move to HOL!!! *)
120 lemma natsum_0 [simp]: "setsum f {..(0::nat)} = (f 0::'a::comm_monoid_add)"
123 lemma natsum_Suc [simp]:
124 "setsum f {..Suc n} = (f (Suc n) + setsum f {..n}::'a::comm_monoid_add)"
125 by (simp add: atMost_Suc)
128 "setsum f {..Suc n} = (setsum (%i. f (Suc i)) {..n} + f 0::'a::comm_monoid_add)"
130 case 0 show ?case by simp
132 case Suc thus ?case by (simp add: semigroup_add.add_assoc)
135 lemma natsum_cong [cong]:
136 "!!k. [| j = k; !!i::nat. i <= k ==> f i = (g i::'a::comm_monoid_add) |] ==>
137 setsum f {..j} = setsum g {..k}"
140 lemma natsum_zero [simp]: "setsum (%i. 0) {..n::nat} = (0::'a::comm_monoid_add)"
141 by (induct n) simp_all
143 lemma natsum_add [simp]:
144 "!!f::nat=>'a::comm_monoid_add.
145 setsum (%i. f i + g i) {..n::nat} = setsum f {..n} + setsum g {..n}"
146 by (induct n) (simp_all add: add_ac)
148 (* Facts specific to rings *)
150 instance ring < comm_monoid_add
153 show "(x::'a::ring) + y = y + x" by (rule a_comm)
154 show "((x::'a::ring) + y) + z = x + (y + z)" by (rule a_assoc)
155 show "0 + (x::'a::ring) = x" by (rule l_zero)
161 [read_cterm (sign_of (the_context ()))
162 ("?t + ?u::'a::ring", TVar (("'z", 0), [])),
163 read_cterm (sign_of (the_context ()))
164 ("?t - ?u::'a::ring", TVar (("'z", 0), [])),
165 read_cterm (sign_of (the_context ()))
166 ("?t * ?u::'a::ring", TVar (("'z", 0), [])),
167 read_cterm (sign_of (the_context ()))
168 ("- ?t::'a::ring", TVar (("'z", 0), []))
171 let val rew = Tactic.prove sg [] []
173 (HOLogic.mk_eq (t, Var (("x", Term.maxidx_of_term t + 1), fastype_of t))))
174 (fn _ => simp_tac ring_ss 1)
176 val (t', u) = Logic.dest_equals (Thm.prop_of rew);
182 val ring_simproc = mk_simproc "ring" lhss proc;
186 ML_setup {* Addsimprocs [ring_simproc] *}
189 "!!a::'a::ring. setsum f {..n::nat} * a = setsum (%i. f i * a) {..n}"
190 by (induct n) simp_all
193 "!!a::'a::ring. a * setsum f {..n::nat} = setsum (%i. a * f i) {..n}"
194 by (induct n) simp_all
196 subsection {* Integral Domains *}
198 declare one_not_zero [simp]
200 lemma zero_not_one [simp]:
201 "0 ~= (1::'a::domain)"
202 by (rule not_sym) simp
204 lemma integral_iff: (* not by default a simp rule! *)
205 "(a * b = (0::'a::domain)) = (a = 0 | b = 0)"
207 assume "a * b = 0" then show "a = 0 | b = 0" by (simp add: integral)
209 assume "a = 0 | b = 0" then show "a * b = 0" by auto
213 lemma "(a::'a::ring) - (a - b) = b" apply simp
214 simproc seems to fail on this example (fixed with new term order)
217 lemma bug: "(b::'a::ring) - (b - a) = a" by simp
218 simproc for rings cannot prove "(a::'a::ring) - (a - b) = b"
221 assumes prem: "(a::'a::domain) ~= 0" shows conc: "(a * b = a * c) = (b = c)"
223 assume eq: "a * b = a * c"
224 then have "a * (b - c) = 0" by simp
225 then have "a = 0 | (b - c) = 0" by (simp only: integral_iff)
226 with prem have "b - c = 0" by auto
227 then have "b = b - (b - c)" by simp
228 also have "b - (b - c) = c" by simp
229 finally show "b = c" .
231 assume "b = c" then show "a * b = a * c" by simp
235 "(a::'a::domain) ~= 0 ==> (b * a = c * a) = (b = c)"
236 by (simp add: m_lcancel)