| author | paulson | 
| Thu, 04 Sep 2003 11:15:53 +0200 | |
| changeset 14182 | 5f49f00fe084 | 
| parent 13936 | d3671b878828 | 
| child 14213 | 7bf882b0a51e | 
| permissions | -rw-r--r-- | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 1 | (* | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 2 | Title: The algebraic hierarchy of rings | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 3 | Id: $Id$ | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 4 | Author: Clemens Ballarin, started 9 December 1996 | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 5 | Copyright: Clemens Ballarin | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 6 | *) | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 7 | |
| 13936 | 8 | theory CRing = FiniteProduct | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 9 | files ("ringsimp.ML"):
 | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 10 | |
| 13936 | 11 | section {* Abelian Groups *}
 | 
| 12 | ||
| 13 | record 'a ring = "'a monoid" + | |
| 14 |   zero :: 'a ("\<zero>\<index>")
 | |
| 15 | add :: "['a, 'a] => 'a" (infixl "\<oplus>\<index>" 65) | |
| 16 | ||
| 17 | text {* Derived operations. *}
 | |
| 18 | ||
| 19 | constdefs | |
| 20 |   a_inv :: "[('a, 'm) ring_scheme, 'a ] => 'a" ("\<ominus>\<index> _" [81] 80)
 | |
| 21 | "a_inv R == m_inv (| carrier = carrier R, mult = add R, one = zero R |)" | |
| 22 | ||
| 23 |   minus :: "[('a, 'm) ring_scheme, 'a, 'a] => 'a" (infixl "\<ominus>\<index>" 65)
 | |
| 24 | "[| x \<in> carrier R; y \<in> carrier R |] ==> minus R x y == add R x (a_inv R y)" | |
| 25 | ||
| 26 | locale abelian_monoid = struct G + | |
| 27 | assumes a_comm_monoid: "comm_monoid (| carrier = carrier G, | |
| 28 | mult = add G, one = zero G |)" | |
| 29 | ||
| 30 | text {*
 | |
| 31 | The following definition is redundant but simple to use. | |
| 32 | *} | |
| 33 | ||
| 34 | locale abelian_group = abelian_monoid + | |
| 35 | assumes a_comm_group: "comm_group (| carrier = carrier G, | |
| 36 | mult = add G, one = zero G |)" | |
| 37 | ||
| 38 | subsection {* Basic Properties *}
 | |
| 39 | ||
| 40 | lemma abelian_monoidI: | |
| 41 | assumes a_closed: | |
| 42 | "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> add R x y \<in> carrier R" | |
| 43 | and zero_closed: "zero R \<in> carrier R" | |
| 44 | and a_assoc: | |
| 45 | "!!x y z. [| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |] ==> | |
| 46 | add R (add R x y) z = add R x (add R y z)" | |
| 47 | and l_zero: "!!x. x \<in> carrier R ==> add R (zero R) x = x" | |
| 48 | and a_comm: | |
| 49 | "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> add R x y = add R y x" | |
| 50 | shows "abelian_monoid R" | |
| 51 | by (auto intro!: abelian_monoid.intro comm_monoidI intro: prems) | |
| 52 | ||
| 53 | lemma abelian_groupI: | |
| 54 | assumes a_closed: | |
| 55 | "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> add R x y \<in> carrier R" | |
| 56 | and zero_closed: "zero R \<in> carrier R" | |
| 57 | and a_assoc: | |
| 58 | "!!x y z. [| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |] ==> | |
| 59 | add R (add R x y) z = add R x (add R y z)" | |
| 60 | and a_comm: | |
| 61 | "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> add R x y = add R y x" | |
| 62 | and l_zero: "!!x. x \<in> carrier R ==> add R (zero R) x = x" | |
| 63 | and l_inv_ex: "!!x. x \<in> carrier R ==> EX y : carrier R. add R y x = zero R" | |
| 64 | shows "abelian_group R" | |
| 65 | by (auto intro!: abelian_group.intro abelian_monoidI | |
| 66 | abelian_group_axioms.intro comm_monoidI comm_groupI | |
| 67 | intro: prems) | |
| 68 | ||
| 69 | (* TODO: The following thms are probably unnecessary. *) | |
| 70 | ||
| 71 | lemma (in abelian_monoid) a_magma: | |
| 72 | "magma (| carrier = carrier G, mult = add G, one = zero G |)" | |
| 73 | by (rule comm_monoid.axioms) (rule a_comm_monoid) | |
| 74 | ||
| 75 | lemma (in abelian_monoid) a_semigroup: | |
| 76 | "semigroup (| carrier = carrier G, mult = add G, one = zero G |)" | |
| 77 | by (unfold semigroup_def) (fast intro: comm_monoid.axioms a_comm_monoid) | |
| 78 | ||
| 79 | lemma (in abelian_monoid) a_monoid: | |
| 80 | "monoid (| carrier = carrier G, mult = add G, one = zero G |)" | |
| 81 | by (unfold monoid_def) (fast intro: a_comm_monoid comm_monoid.axioms) | |
| 82 | ||
| 83 | lemma (in abelian_group) a_group: | |
| 84 | "group (| carrier = carrier G, mult = add G, one = zero G |)" | |
| 85 | by (unfold group_def semigroup_def) | |
| 86 | (fast intro: comm_group.axioms a_comm_group) | |
| 87 | ||
| 88 | lemma (in abelian_monoid) a_comm_semigroup: | |
| 89 | "comm_semigroup (| carrier = carrier G, mult = add G, one = zero G |)" | |
| 90 | by (unfold comm_semigroup_def semigroup_def) | |
| 91 | (fast intro: comm_monoid.axioms a_comm_monoid) | |
| 92 | ||
| 93 | lemmas monoid_record_simps = semigroup.simps monoid.simps | |
| 94 | ||
| 95 | lemma (in abelian_monoid) a_closed [intro, simp]: | |
| 96 | "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<oplus> y \<in> carrier G" | |
| 97 | by (rule magma.m_closed [OF a_magma, simplified monoid_record_simps]) | |
| 98 | ||
| 99 | lemma (in abelian_monoid) zero_closed [intro, simp]: | |
| 100 | "\<zero> \<in> carrier G" | |
| 101 | by (rule monoid.one_closed [OF a_monoid, simplified monoid_record_simps]) | |
| 102 | ||
| 103 | lemma (in abelian_group) a_inv_closed [intro, simp]: | |
| 104 | "x \<in> carrier G ==> \<ominus> x \<in> carrier G" | |
| 105 | by (simp add: a_inv_def | |
| 106 | group.inv_closed [OF a_group, simplified monoid_record_simps]) | |
| 107 | ||
| 108 | lemma (in abelian_group) minus_closed [intro, simp]: | |
| 109 | "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<ominus> y \<in> carrier G" | |
| 110 | by (simp add: minus_def) | |
| 111 | ||
| 112 | lemma (in abelian_group) a_l_cancel [simp]: | |
| 113 | "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==> | |
| 114 | (x \<oplus> y = x \<oplus> z) = (y = z)" | |
| 115 | by (rule group.l_cancel [OF a_group, simplified monoid_record_simps]) | |
| 116 | ||
| 117 | lemma (in abelian_group) a_r_cancel [simp]: | |
| 118 | "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==> | |
| 119 | (y \<oplus> x = z \<oplus> x) = (y = z)" | |
| 120 | by (rule group.r_cancel [OF a_group, simplified monoid_record_simps]) | |
| 121 | ||
| 122 | lemma (in abelian_monoid) a_assoc: | |
| 123 | "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==> | |
| 124 | (x \<oplus> y) \<oplus> z = x \<oplus> (y \<oplus> z)" | |
| 125 | by (rule semigroup.m_assoc [OF a_semigroup, simplified monoid_record_simps]) | |
| 126 | ||
| 127 | lemma (in abelian_monoid) l_zero [simp]: | |
| 128 | "x \<in> carrier G ==> \<zero> \<oplus> x = x" | |
| 129 | by (rule monoid.l_one [OF a_monoid, simplified monoid_record_simps]) | |
| 130 | ||
| 131 | lemma (in abelian_group) l_neg: | |
| 132 | "x \<in> carrier G ==> \<ominus> x \<oplus> x = \<zero>" | |
| 133 | by (simp add: a_inv_def | |
| 134 | group.l_inv [OF a_group, simplified monoid_record_simps]) | |
| 135 | ||
| 136 | lemma (in abelian_monoid) a_comm: | |
| 137 | "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<oplus> y = y \<oplus> x" | |
| 138 | by (rule comm_semigroup.m_comm [OF a_comm_semigroup, | |
| 139 | simplified monoid_record_simps]) | |
| 140 | ||
| 141 | lemma (in abelian_monoid) a_lcomm: | |
| 142 | "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==> | |
| 143 | x \<oplus> (y \<oplus> z) = y \<oplus> (x \<oplus> z)" | |
| 144 | by (rule comm_semigroup.m_lcomm [OF a_comm_semigroup, | |
| 145 | simplified monoid_record_simps]) | |
| 146 | ||
| 147 | lemma (in abelian_monoid) r_zero [simp]: | |
| 148 | "x \<in> carrier G ==> x \<oplus> \<zero> = x" | |
| 149 | using monoid.r_one [OF a_monoid] | |
| 150 | by simp | |
| 151 | ||
| 152 | lemma (in abelian_group) r_neg: | |
| 153 | "x \<in> carrier G ==> x \<oplus> (\<ominus> x) = \<zero>" | |
| 154 | using group.r_inv [OF a_group] | |
| 155 | by (simp add: a_inv_def) | |
| 156 | ||
| 157 | lemma (in abelian_group) minus_zero [simp]: | |
| 158 | "\<ominus> \<zero> = \<zero>" | |
| 159 | by (simp add: a_inv_def | |
| 160 | group.inv_one [OF a_group, simplified monoid_record_simps]) | |
| 161 | ||
| 162 | lemma (in abelian_group) minus_minus [simp]: | |
| 163 | "x \<in> carrier G ==> \<ominus> (\<ominus> x) = x" | |
| 164 | using group.inv_inv [OF a_group, simplified monoid_record_simps] | |
| 165 | by (simp add: a_inv_def) | |
| 166 | ||
| 167 | lemma (in abelian_group) a_inv_inj: | |
| 168 | "inj_on (a_inv G) (carrier G)" | |
| 169 | using group.inv_inj [OF a_group, simplified monoid_record_simps] | |
| 170 | by (simp add: a_inv_def) | |
| 171 | ||
| 172 | lemma (in abelian_group) minus_add: | |
| 173 | "[| x \<in> carrier G; y \<in> carrier G |] ==> \<ominus> (x \<oplus> y) = \<ominus> x \<oplus> \<ominus> y" | |
| 174 | using comm_group.inv_mult [OF a_comm_group] | |
| 175 | by (simp add: a_inv_def) | |
| 176 | ||
| 177 | lemmas (in abelian_monoid) a_ac = a_assoc a_comm a_lcomm | |
| 178 | ||
| 179 | subsection {* Sums over Finite Sets *}
 | |
| 180 | ||
| 181 | text {*
 | |
| 182 |   This definition makes it easy to lift lemmas from @{term finprod}.
 | |
| 183 | *} | |
| 184 | ||
| 185 | constdefs | |
| 186 |   finsum :: "[('b, 'm) ring_scheme, 'a => 'b, 'a set] => 'b"
 | |
| 187 | "finsum G f A == finprod (| carrier = carrier G, | |
| 188 | mult = add G, one = zero G |) f A" | |
| 189 | ||
| 190 | (* | |
| 191 | lemmas (in abelian_monoid) finsum_empty [simp] = | |
| 192 | comm_monoid.finprod_empty [OF a_comm_monoid, simplified] | |
| 193 | is dangeous, because attributes (like simplified) are applied upon opening | |
| 194 | the locale, simplified refers to the simpset at that time!!! | |
| 195 | ||
| 196 | lemmas (in abelian_monoid) finsum_empty [simp] = | |
| 197 | abelian_monoid.finprod_empty [OF a_abelian_monoid, folded finsum_def, | |
| 198 | simplified monoid_record_simps] | |
| 199 | makes the locale slow, because proofs are repeated for every | |
| 200 | "lemma (in abelian_monoid)" command. | |
| 201 | When lemma is used time in UnivPoly.thy from beginning to UP_cring goes down | |
| 202 | from 110 secs to 60 secs. | |
| 203 | *) | |
| 204 | ||
| 205 | lemma (in abelian_monoid) finsum_empty [simp]: | |
| 206 |   "finsum G f {} = \<zero>"
 | |
| 207 | by (rule comm_monoid.finprod_empty [OF a_comm_monoid, | |
| 208 | folded finsum_def, simplified monoid_record_simps]) | |
| 209 | ||
| 210 | lemma (in abelian_monoid) finsum_insert [simp]: | |
| 211 | "[| finite F; a \<notin> F; f \<in> F -> carrier G; f a \<in> carrier G |] | |
| 212 | ==> finsum G f (insert a F) = f a \<oplus> finsum G f F" | |
| 213 | by (rule comm_monoid.finprod_insert [OF a_comm_monoid, | |
| 214 | folded finsum_def, simplified monoid_record_simps]) | |
| 215 | ||
| 216 | lemma (in abelian_monoid) finsum_zero [simp]: | |
| 217 | "finite A ==> finsum G (%i. \<zero>) A = \<zero>" | |
| 218 | by (rule comm_monoid.finprod_one [OF a_comm_monoid, folded finsum_def, | |
| 219 | simplified monoid_record_simps]) | |
| 220 | ||
| 221 | lemma (in abelian_monoid) finsum_closed [simp]: | |
| 222 | fixes A | |
| 223 | assumes fin: "finite A" and f: "f \<in> A -> carrier G" | |
| 224 | shows "finsum G f A \<in> carrier G" | |
| 225 | by (rule comm_monoid.finprod_closed [OF a_comm_monoid, | |
| 226 | folded finsum_def, simplified monoid_record_simps]) | |
| 227 | ||
| 228 | lemma (in abelian_monoid) finsum_Un_Int: | |
| 229 | "[| finite A; finite B; g \<in> A -> carrier G; g \<in> B -> carrier G |] ==> | |
| 230 | finsum G g (A Un B) \<oplus> finsum G g (A Int B) = | |
| 231 | finsum G g A \<oplus> finsum G g B" | |
| 232 | by (rule comm_monoid.finprod_Un_Int [OF a_comm_monoid, | |
| 233 | folded finsum_def, simplified monoid_record_simps]) | |
| 234 | ||
| 235 | lemma (in abelian_monoid) finsum_Un_disjoint: | |
| 236 |   "[| finite A; finite B; A Int B = {};
 | |
| 237 | g \<in> A -> carrier G; g \<in> B -> carrier G |] | |
| 238 | ==> finsum G g (A Un B) = finsum G g A \<oplus> finsum G g B" | |
| 239 | by (rule comm_monoid.finprod_Un_disjoint [OF a_comm_monoid, | |
| 240 | folded finsum_def, simplified monoid_record_simps]) | |
| 241 | ||
| 242 | lemma (in abelian_monoid) finsum_addf: | |
| 243 | "[| finite A; f \<in> A -> carrier G; g \<in> A -> carrier G |] ==> | |
| 244 | finsum G (%x. f x \<oplus> g x) A = (finsum G f A \<oplus> finsum G g A)" | |
| 245 | by (rule comm_monoid.finprod_multf [OF a_comm_monoid, | |
| 246 | folded finsum_def, simplified monoid_record_simps]) | |
| 247 | ||
| 248 | lemma (in abelian_monoid) finsum_cong': | |
| 249 | "[| A = B; g : B -> carrier G; | |
| 250 | !!i. i : B ==> f i = g i |] ==> finsum G f A = finsum G g B" | |
| 251 | by (rule comm_monoid.finprod_cong' [OF a_comm_monoid, | |
| 252 | folded finsum_def, simplified monoid_record_simps]) auto | |
| 253 | ||
| 254 | lemma (in abelian_monoid) finsum_0 [simp]: | |
| 255 |   "f : {0::nat} -> carrier G ==> finsum G f {..0} = f 0"
 | |
| 256 | by (rule comm_monoid.finprod_0 [OF a_comm_monoid, folded finsum_def, | |
| 257 | simplified monoid_record_simps]) | |
| 258 | ||
| 259 | lemma (in abelian_monoid) finsum_Suc [simp]: | |
| 260 |   "f : {..Suc n} -> carrier G ==>
 | |
| 261 |    finsum G f {..Suc n} = (f (Suc n) \<oplus> finsum G f {..n})"
 | |
| 262 | by (rule comm_monoid.finprod_Suc [OF a_comm_monoid, folded finsum_def, | |
| 263 | simplified monoid_record_simps]) | |
| 264 | ||
| 265 | lemma (in abelian_monoid) finsum_Suc2: | |
| 266 |   "f : {..Suc n} -> carrier G ==>
 | |
| 267 |    finsum G f {..Suc n} = (finsum G (%i. f (Suc i)) {..n} \<oplus> f 0)"
 | |
| 268 | by (rule comm_monoid.finprod_Suc2 [OF a_comm_monoid, folded finsum_def, | |
| 269 | simplified monoid_record_simps]) | |
| 270 | ||
| 271 | lemma (in abelian_monoid) finsum_add [simp]: | |
| 272 |   "[| f : {..n} -> carrier G; g : {..n} -> carrier G |] ==>
 | |
| 273 |      finsum G (%i. f i \<oplus> g i) {..n::nat} =
 | |
| 274 |      finsum G f {..n} \<oplus> finsum G g {..n}"
 | |
| 275 | by (rule comm_monoid.finprod_mult [OF a_comm_monoid, folded finsum_def, | |
| 276 | simplified monoid_record_simps]) | |
| 277 | ||
| 278 | lemma (in abelian_monoid) finsum_cong: | |
| 279 | "[| A = B; !!i. i : B ==> f i = g i; | |
| 280 | g : B -> carrier G = True |] ==> finsum G f A = finsum G g B" | |
| 281 | by (rule comm_monoid.finprod_cong [OF a_comm_monoid, folded finsum_def, | |
| 282 | simplified monoid_record_simps]) auto | |
| 283 | ||
| 284 | text {*Usually, if this rule causes a failed congruence proof error,
 | |
| 285 |    the reason is that the premise @{text "g \<in> B -> carrier G"} cannot be shown.
 | |
| 286 |    Adding @{thm [source] Pi_def} to the simpset is often useful. *}
 | |
| 287 | ||
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 288 | section {* The Algebraic Hierarchy of Rings *}
 | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 289 | |
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 290 | subsection {* Basic Definitions *}
 | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 291 | |
| 13936 | 292 | locale cring = abelian_group R + comm_monoid R + | 
| 293 | assumes l_distr: "[| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |] | |
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 294 | ==> (x \<oplus> y) \<otimes> z = x \<otimes> z \<oplus> y \<otimes> z" | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 295 | |
| 13864 | 296 | locale "domain" = cring + | 
| 297 | assumes one_not_zero [simp]: "\<one> ~= \<zero>" | |
| 298 | and integral: "[| a \<otimes> b = \<zero>; a \<in> carrier R; b \<in> carrier R |] ==> | |
| 299 | a = \<zero> | b = \<zero>" | |
| 300 | ||
| 301 | subsection {* Basic Facts of Rings *}
 | |
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 302 | |
| 13936 | 303 | lemma cringI: | 
| 304 | assumes abelian_group: "abelian_group R" | |
| 305 | and comm_monoid: "comm_monoid R" | |
| 306 | and l_distr: "!!x y z. [| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |] | |
| 307 | ==> mult R (add R x y) z = add R (mult R x z) (mult R y z)" | |
| 308 | shows "cring R" | |
| 309 | by (auto intro: cring.intro | |
| 310 | abelian_group.axioms comm_monoid.axioms cring_axioms.intro prems) | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 311 | |
| 13936 | 312 | lemma (in cring) is_abelian_group: | 
| 313 | "abelian_group R" | |
| 314 | by (auto intro!: abelian_groupI a_assoc a_comm l_neg) | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 315 | |
| 13936 | 316 | lemma (in cring) is_comm_monoid: | 
| 317 | "comm_monoid R" | |
| 318 | by (auto intro!: comm_monoidI m_assoc m_comm) | |
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 319 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 320 | subsection {* Normaliser for Commutative Rings *}
 | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 321 | |
| 13936 | 322 | lemma (in abelian_group) r_neg2: | 
| 323 | "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<oplus> (\<ominus> x \<oplus> y) = y" | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 324 | proof - | 
| 13936 | 325 | assume G: "x \<in> carrier G" "y \<in> carrier G" | 
| 326 | then have "(x \<oplus> \<ominus> x) \<oplus> y = y" | |
| 327 | by (simp only: r_neg l_zero) | |
| 328 | with G show ?thesis | |
| 329 | by (simp add: a_ac) | |
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 330 | qed | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 331 | |
| 13936 | 332 | lemma (in abelian_group) r_neg1: | 
| 333 | "[| x \<in> carrier G; y \<in> carrier G |] ==> \<ominus> x \<oplus> (x \<oplus> y) = y" | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 334 | proof - | 
| 13936 | 335 | assume G: "x \<in> carrier G" "y \<in> carrier G" | 
| 336 | then have "(\<ominus> x \<oplus> x) \<oplus> y = y" | |
| 337 | by (simp only: l_neg l_zero) | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 338 | with G show ?thesis by (simp add: a_ac) | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 339 | qed | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 340 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 341 | lemma (in cring) r_distr: | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 342 | "[| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |] | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 343 | ==> z \<otimes> (x \<oplus> y) = z \<otimes> x \<oplus> z \<otimes> y" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 344 | proof - | 
| 13936 | 345 | assume R: "x \<in> carrier R" "y \<in> carrier R" "z \<in> carrier R" | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 346 | then have "z \<otimes> (x \<oplus> y) = (x \<oplus> y) \<otimes> z" by (simp add: m_comm) | 
| 13936 | 347 | also from R have "... = x \<otimes> z \<oplus> y \<otimes> z" by (simp add: l_distr) | 
| 348 | also from R have "... = z \<otimes> x \<oplus> z \<otimes> y" by (simp add: m_comm) | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 349 | finally show ?thesis . | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 350 | qed | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 351 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 352 | text {* 
 | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 353 | The following proofs are from Jacobson, Basic Algebra I, pp.~88--89 | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 354 | *} | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 355 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 356 | lemma (in cring) l_null [simp]: | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 357 | "x \<in> carrier R ==> \<zero> \<otimes> x = \<zero>" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 358 | proof - | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 359 | assume R: "x \<in> carrier R" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 360 | then have "\<zero> \<otimes> x \<oplus> \<zero> \<otimes> x = (\<zero> \<oplus> \<zero>) \<otimes> x" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 361 | by (simp add: l_distr del: l_zero r_zero) | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 362 | also from R have "... = \<zero> \<otimes> x \<oplus> \<zero>" by simp | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 363 | finally have "\<zero> \<otimes> x \<oplus> \<zero> \<otimes> x = \<zero> \<otimes> x \<oplus> \<zero>" . | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 364 | with R show ?thesis by (simp del: r_zero) | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 365 | qed | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 366 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 367 | lemma (in cring) r_null [simp]: | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 368 | "x \<in> carrier R ==> x \<otimes> \<zero> = \<zero>" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 369 | proof - | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 370 | assume R: "x \<in> carrier R" | 
| 13936 | 371 | then have "x \<otimes> \<zero> = \<zero> \<otimes> x" by (simp add: m_ac) | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 372 | also from R have "... = \<zero>" by simp | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 373 | finally show ?thesis . | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 374 | qed | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 375 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 376 | lemma (in cring) l_minus: | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 377 | "[| x \<in> carrier R; y \<in> carrier R |] ==> \<ominus> x \<otimes> y = \<ominus> (x \<otimes> y)" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 378 | proof - | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 379 | assume R: "x \<in> carrier R" "y \<in> carrier R" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 380 | then have "(\<ominus> x) \<otimes> y \<oplus> x \<otimes> y = (\<ominus> x \<oplus> x) \<otimes> y" by (simp add: l_distr) | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 381 | also from R have "... = \<zero>" by (simp add: l_neg l_null) | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 382 | finally have "(\<ominus> x) \<otimes> y \<oplus> x \<otimes> y = \<zero>" . | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 383 | with R have "(\<ominus> x) \<otimes> y \<oplus> x \<otimes> y \<oplus> \<ominus> (x \<otimes> y) = \<zero> \<oplus> \<ominus> (x \<otimes> y)" by simp | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 384 | with R show ?thesis by (simp add: a_assoc r_neg ) | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 385 | qed | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 386 | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 387 | lemma (in cring) r_minus: | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 388 | "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<otimes> \<ominus> y = \<ominus> (x \<otimes> y)" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 389 | proof - | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 390 | assume R: "x \<in> carrier R" "y \<in> carrier R" | 
| 13936 | 391 | then have "x \<otimes> \<ominus> y = \<ominus> y \<otimes> x" by (simp add: m_ac) | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 392 | also from R have "... = \<ominus> (y \<otimes> x)" by (simp add: l_minus) | 
| 13936 | 393 | also from R have "... = \<ominus> (x \<otimes> y)" by (simp add: m_ac) | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 394 | finally show ?thesis . | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 395 | qed | 
| 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 396 | |
| 13936 | 397 | lemma (in cring) minus_eq: | 
| 398 | "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<ominus> y = x \<oplus> \<ominus> y" | |
| 399 | by (simp only: minus_def) | |
| 400 | ||
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 401 | lemmas (in cring) cring_simprules = | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 402 | a_closed zero_closed a_inv_closed minus_closed m_closed one_closed | 
| 13936 | 403 | a_assoc l_zero l_neg a_comm m_assoc l_one l_distr m_comm minus_eq | 
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 404 | r_zero r_neg r_neg2 r_neg1 minus_add minus_minus minus_zero | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 405 | a_lcomm m_lcomm r_distr l_null r_null l_minus r_minus | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 406 | |
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 407 | use "ringsimp.ML" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 408 | |
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 409 | method_setup algebra = | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 410 |   {* Method.ctxt_args cring_normalise *}
 | 
| 13936 | 411 |   {* computes distributive normal form in locale context cring *}
 | 
| 412 | ||
| 413 | lemma (in cring) nat_pow_zero: | |
| 414 | "(n::nat) ~= 0 ==> \<zero> (^) n = \<zero>" | |
| 415 | by (induct n) simp_all | |
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 416 | |
| 13864 | 417 | text {* Two examples for use of method algebra *}
 | 
| 418 | ||
| 13854 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 419 | lemma | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 420 | includes cring R + cring S | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 421 | shows "[| a \<in> carrier R; b \<in> carrier R; c \<in> carrier S; d \<in> carrier S |] ==> | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 422 | a \<oplus> \<ominus> (a \<oplus> \<ominus> b) = b & c \<otimes>\<^sub>2 d = d \<otimes>\<^sub>2 c" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 423 | by algebra | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 424 | |
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 425 | lemma | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 426 | includes cring | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 427 | shows "[| a \<in> carrier R; b \<in> carrier R |] ==> a \<ominus> (a \<ominus> b) = b" | 
| 
91c9ab25fece
First distributed version of Group and Ring theory.
 ballarin parents: 
13835diff
changeset | 428 | by algebra | 
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 429 | |
| 13864 | 430 | subsection {* Sums over Finite Sets *}
 | 
| 431 | ||
| 432 | lemma (in cring) finsum_ldistr: | |
| 433 | "[| finite A; a \<in> carrier R; f \<in> A -> carrier R |] ==> | |
| 434 | finsum R f A \<otimes> a = finsum R (%i. f i \<otimes> a) A" | |
| 435 | proof (induct set: Finites) | |
| 436 | case empty then show ?case by simp | |
| 437 | next | |
| 438 | case (insert F x) then show ?case by (simp add: Pi_def l_distr) | |
| 439 | qed | |
| 440 | ||
| 441 | lemma (in cring) finsum_rdistr: | |
| 442 | "[| finite A; a \<in> carrier R; f \<in> A -> carrier R |] ==> | |
| 443 | a \<otimes> finsum R f A = finsum R (%i. a \<otimes> f i) A" | |
| 444 | proof (induct set: Finites) | |
| 445 | case empty then show ?case by simp | |
| 446 | next | |
| 447 | case (insert F x) then show ?case by (simp add: Pi_def r_distr) | |
| 448 | qed | |
| 449 | ||
| 450 | subsection {* Facts of Integral Domains *}
 | |
| 451 | ||
| 452 | lemma (in "domain") zero_not_one [simp]: | |
| 453 | "\<zero> ~= \<one>" | |
| 454 | by (rule not_sym) simp | |
| 455 | ||
| 456 | lemma (in "domain") integral_iff: (* not by default a simp rule! *) | |
| 457 | "[| a \<in> carrier R; b \<in> carrier R |] ==> (a \<otimes> b = \<zero>) = (a = \<zero> | b = \<zero>)" | |
| 458 | proof | |
| 459 | assume "a \<in> carrier R" "b \<in> carrier R" "a \<otimes> b = \<zero>" | |
| 460 | then show "a = \<zero> | b = \<zero>" by (simp add: integral) | |
| 461 | next | |
| 462 | assume "a \<in> carrier R" "b \<in> carrier R" "a = \<zero> | b = \<zero>" | |
| 463 | then show "a \<otimes> b = \<zero>" by auto | |
| 464 | qed | |
| 465 | ||
| 466 | lemma (in "domain") m_lcancel: | |
| 467 | assumes prem: "a ~= \<zero>" | |
| 468 | and R: "a \<in> carrier R" "b \<in> carrier R" "c \<in> carrier R" | |
| 469 | shows "(a \<otimes> b = a \<otimes> c) = (b = c)" | |
| 470 | proof | |
| 471 | assume eq: "a \<otimes> b = a \<otimes> c" | |
| 472 | with R have "a \<otimes> (b \<ominus> c) = \<zero>" by algebra | |
| 473 | with R have "a = \<zero> | (b \<ominus> c) = \<zero>" by (simp add: integral_iff) | |
| 474 | with prem and R have "b \<ominus> c = \<zero>" by auto | |
| 475 | with R have "b = b \<ominus> (b \<ominus> c)" by algebra | |
| 476 | also from R have "b \<ominus> (b \<ominus> c) = c" by algebra | |
| 477 | finally show "b = c" . | |
| 478 | next | |
| 479 | assume "b = c" then show "a \<otimes> b = a \<otimes> c" by simp | |
| 480 | qed | |
| 481 | ||
| 482 | lemma (in "domain") m_rcancel: | |
| 483 | assumes prem: "a ~= \<zero>" | |
| 484 | and R: "a \<in> carrier R" "b \<in> carrier R" "c \<in> carrier R" | |
| 485 | shows conc: "(b \<otimes> a = c \<otimes> a) = (b = c)" | |
| 486 | proof - | |
| 487 | from prem and R have "(a \<otimes> b = a \<otimes> c) = (b = c)" by (rule m_lcancel) | |
| 488 | with R show ?thesis by algebra | |
| 489 | qed | |
| 490 | ||
| 13936 | 491 | subsection {* Morphisms *}
 | 
| 492 | ||
| 493 | constdefs | |
| 494 |   ring_hom :: "[('a, 'm) ring_scheme, ('b, 'n) ring_scheme] => ('a => 'b) set"
 | |
| 495 |   "ring_hom R S == {h. h \<in> carrier R -> carrier S &
 | |
| 496 | (ALL x y. x \<in> carrier R & y \<in> carrier R --> | |
| 497 | h (mult R x y) = mult S (h x) (h y) & | |
| 498 | h (add R x y) = add S (h x) (h y)) & | |
| 499 | h (one R) = one S}" | |
| 500 | ||
| 501 | lemma ring_hom_memI: | |
| 502 | assumes hom_closed: "!!x. x \<in> carrier R ==> h x \<in> carrier S" | |
| 503 | and hom_mult: "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> | |
| 504 | h (mult R x y) = mult S (h x) (h y)" | |
| 505 | and hom_add: "!!x y. [| x \<in> carrier R; y \<in> carrier R |] ==> | |
| 506 | h (add R x y) = add S (h x) (h y)" | |
| 507 | and hom_one: "h (one R) = one S" | |
| 508 | shows "h \<in> ring_hom R S" | |
| 509 | by (auto simp add: ring_hom_def prems Pi_def) | |
| 510 | ||
| 511 | lemma ring_hom_closed: | |
| 512 | "[| h \<in> ring_hom R S; x \<in> carrier R |] ==> h x \<in> carrier S" | |
| 513 | by (auto simp add: ring_hom_def funcset_mem) | |
| 514 | ||
| 515 | lemma ring_hom_mult: | |
| 516 | "[| h \<in> ring_hom R S; x \<in> carrier R; y \<in> carrier R |] ==> | |
| 517 | h (mult R x y) = mult S (h x) (h y)" | |
| 518 | by (simp add: ring_hom_def) | |
| 519 | ||
| 520 | lemma ring_hom_add: | |
| 521 | "[| h \<in> ring_hom R S; x \<in> carrier R; y \<in> carrier R |] ==> | |
| 522 | h (add R x y) = add S (h x) (h y)" | |
| 523 | by (simp add: ring_hom_def) | |
| 524 | ||
| 525 | lemma ring_hom_one: | |
| 526 | "h \<in> ring_hom R S ==> h (one R) = one S" | |
| 527 | by (simp add: ring_hom_def) | |
| 528 | ||
| 529 | locale ring_hom_cring = cring R + cring S + var h + | |
| 530 | assumes homh [simp, intro]: "h \<in> ring_hom R S" | |
| 531 | notes hom_closed [simp, intro] = ring_hom_closed [OF homh] | |
| 532 | and hom_mult [simp] = ring_hom_mult [OF homh] | |
| 533 | and hom_add [simp] = ring_hom_add [OF homh] | |
| 534 | and hom_one [simp] = ring_hom_one [OF homh] | |
| 535 | ||
| 536 | lemma (in ring_hom_cring) hom_zero [simp]: | |
| 537 | "h \<zero> = \<zero>\<^sub>2" | |
| 538 | proof - | |
| 539 | have "h \<zero> \<oplus>\<^sub>2 h \<zero> = h \<zero> \<oplus>\<^sub>2 \<zero>\<^sub>2" | |
| 540 | by (simp add: hom_add [symmetric] del: hom_add) | |
| 541 | then show ?thesis by (simp del: S.r_zero) | |
| 542 | qed | |
| 543 | ||
| 544 | lemma (in ring_hom_cring) hom_a_inv [simp]: | |
| 545 | "x \<in> carrier R ==> h (\<ominus> x) = \<ominus>\<^sub>2 h x" | |
| 546 | proof - | |
| 547 | assume R: "x \<in> carrier R" | |
| 548 | then have "h x \<oplus>\<^sub>2 h (\<ominus> x) = h x \<oplus>\<^sub>2 (\<ominus>\<^sub>2 h x)" | |
| 549 | by (simp add: hom_add [symmetric] R.r_neg S.r_neg del: hom_add) | |
| 550 | with R show ?thesis by simp | |
| 551 | qed | |
| 552 | ||
| 553 | lemma (in ring_hom_cring) hom_finsum [simp]: | |
| 554 | "[| finite A; f \<in> A -> carrier R |] ==> | |
| 555 | h (finsum R f A) = finsum S (h o f) A" | |
| 556 | proof (induct set: Finites) | |
| 557 | case empty then show ?case by simp | |
| 558 | next | |
| 559 | case insert then show ?case by (simp add: Pi_def) | |
| 560 | qed | |
| 561 | ||
| 562 | lemma (in ring_hom_cring) hom_finprod: | |
| 563 | "[| finite A; f \<in> A -> carrier R |] ==> | |
| 564 | h (finprod R f A) = finprod S (h o f) A" | |
| 565 | proof (induct set: Finites) | |
| 566 | case empty then show ?case by simp | |
| 567 | next | |
| 568 | case insert then show ?case by (simp add: Pi_def) | |
| 569 | qed | |
| 570 | ||
| 571 | declare ring_hom_cring.hom_finprod [simp] | |
| 572 | ||
| 573 | lemma id_ring_hom [simp]: | |
| 574 | "id \<in> ring_hom R R" | |
| 575 | by (auto intro!: ring_hom_memI) | |
| 576 | ||
| 13835 
12b2ffbe543a
Change to meta simplifier: congruence rules may now have frees as head of term.
 ballarin parents: diff
changeset | 577 | end |