src/HOL/Algebra/CRing.thy
changeset 13936 d3671b878828
parent 13889 6676ac2527fa
child 14213 7bf882b0a51e
equal deleted inserted replaced
13935:4822d9597d1e 13936:d3671b878828
     3   Id:        $Id$
     3   Id:        $Id$
     4   Author:    Clemens Ballarin, started 9 December 1996
     4   Author:    Clemens Ballarin, started 9 December 1996
     5   Copyright: Clemens Ballarin
     5   Copyright: Clemens Ballarin
     6 *)
     6 *)
     7 
     7 
     8 theory CRing = Summation
     8 theory CRing = FiniteProduct
     9 files ("ringsimp.ML"):
     9 files ("ringsimp.ML"):
    10 
    10 
    11 section {* The Algebraic Hierarchy of Rings *}
    11 section {* Abelian Groups *}
    12 
    12 
    13 subsection {* Basic Definitions *}
    13 record 'a ring = "'a monoid" +
    14 
       
    15 record 'a ring = "'a group" +
       
    16   zero :: 'a ("\<zero>\<index>")
    14   zero :: 'a ("\<zero>\<index>")
    17   add :: "['a, 'a] => 'a" (infixl "\<oplus>\<index>" 65)
    15   add :: "['a, 'a] => 'a" (infixl "\<oplus>\<index>" 65)
    18   a_inv :: "'a => 'a" ("\<ominus>\<index> _" [81] 80)
    16 
    19 
    17 text {* Derived operations. *}
    20 locale cring = abelian_monoid R +
       
    21   assumes a_abelian_group: "abelian_group (| carrier = carrier R,
       
    22       mult = add R, one = zero R, m_inv = a_inv R |)"
       
    23     and m_inv_def: "[| EX y. y \<in> carrier R & x \<otimes> y = \<one>; x \<in> carrier R |]
       
    24       ==> inv x = (THE y. y \<in> carrier R & x \<otimes> y = \<one>)"
       
    25     and l_distr: "[| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |]
       
    26       ==> (x \<oplus> y) \<otimes> z = x \<otimes> z \<oplus> y \<otimes> z"
       
    27 
       
    28 text {* Derived operation. *}
       
    29 
    18 
    30 constdefs
    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 
    31   minus :: "[('a, 'm) ring_scheme, 'a, 'a] => 'a" (infixl "\<ominus>\<index>" 65)
    23   minus :: "[('a, 'm) ring_scheme, 'a, 'a] => 'a" (infixl "\<ominus>\<index>" 65)
    32   "[| x \<in> carrier R; y \<in> carrier R |] ==> minus R x y == add R x (a_inv R y)"
    24   "[| x \<in> carrier R; y \<in> carrier R |] ==> minus R x y == add R x (a_inv R y)"
    33 
    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 
    34 (*
   190 (*
    35   -- {* Definition of derived operations *}
   191   lemmas (in abelian_monoid) finsum_empty [simp] =
    36 
   192     comm_monoid.finprod_empty [OF a_comm_monoid, simplified]
    37   minus_def:    "a - b = a + (-b)"
   193   is dangeous, because attributes (like simplified) are applied upon opening
    38   inverse_def:  "inverse a = (if a dvd 1 then THE x. a*x = 1 else 0)"
   194   the locale, simplified refers to the simpset at that time!!!
    39   divide_def:   "a / b = a * inverse b"
   195 
    40   power_def:    "a ^ n = nat_rec 1 (%u b. b * a) n"
   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.
    41 *)
   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 
       
   288 section {* The Algebraic Hierarchy of Rings *}
       
   289 
       
   290 subsection {* Basic Definitions *}
       
   291 
       
   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 |]
       
   294       ==> (x \<oplus> y) \<otimes> z = x \<otimes> z \<oplus> y \<otimes> z"
    42 
   295 
    43 locale "domain" = cring +
   296 locale "domain" = cring +
    44   assumes one_not_zero [simp]: "\<one> ~= \<zero>"
   297   assumes one_not_zero [simp]: "\<one> ~= \<zero>"
    45     and integral: "[| a \<otimes> b = \<zero>; a \<in> carrier R; b \<in> carrier R |] ==>
   298     and integral: "[| a \<otimes> b = \<zero>; a \<in> carrier R; b \<in> carrier R |] ==>
    46                   a = \<zero> | b = \<zero>"
   299                   a = \<zero> | b = \<zero>"
    47 
   300 
    48 subsection {* Basic Facts of Rings *}
   301 subsection {* Basic Facts of Rings *}
    49 
   302 
    50 lemma (in cring) a_magma [simp, intro]:
   303 lemma cringI:
    51   "magma (| carrier = carrier R,
   304   assumes abelian_group: "abelian_group R"
    52      mult = add R, one = zero R, m_inv = a_inv R |)"
   305     and comm_monoid: "comm_monoid R"
    53   using a_abelian_group by (simp only: abelian_group_def)
   306     and l_distr: "!!x y z. [| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |]
    54 
   307       ==> mult R (add R x y) z = add R (mult R x z) (mult R y z)"
    55 lemma (in cring) a_l_one [simp, intro]:
   308   shows "cring R"
    56   "l_one (| carrier = carrier R,
   309   by (auto intro: cring.intro
    57      mult = add R, one = zero R, m_inv = a_inv R |)"
   310     abelian_group.axioms comm_monoid.axioms cring_axioms.intro prems)
    58   using a_abelian_group by (simp only: abelian_group_def)
   311 
    59 
   312 lemma (in cring) is_abelian_group:
    60 lemma (in cring) a_abelian_group_parts [simp, intro]:
   313   "abelian_group R"
    61   "semigroup_axioms (| carrier = carrier R,
   314   by (auto intro!: abelian_groupI a_assoc a_comm l_neg)
    62      mult = add R, one = zero R, m_inv = a_inv R |)"
   315 
    63   "group_axioms (| carrier = carrier R,
   316 lemma (in cring) is_comm_monoid:
    64      mult = add R, one = zero R, m_inv = a_inv R |)"
   317   "comm_monoid R"
    65   "abelian_semigroup_axioms (| carrier = carrier R,
   318   by (auto intro!: comm_monoidI m_assoc m_comm)
    66      mult = add R, one = zero R, m_inv = a_inv R |)"
       
    67   using a_abelian_group by (simp_all only: abelian_group_def)
       
    68 
       
    69 lemma (in cring) a_semigroup:
       
    70   "semigroup (| carrier = carrier R,
       
    71      mult = add R, one = zero R, m_inv = a_inv R |)"
       
    72   by (simp add: semigroup_def)
       
    73 
       
    74 lemma (in cring) a_group:
       
    75   "group (| carrier = carrier R,
       
    76      mult = add R, one = zero R, m_inv = a_inv R |)"
       
    77   by (simp add: group_def)
       
    78 
       
    79 lemma (in cring) a_abelian_semigroup:
       
    80   "abelian_semigroup (| carrier = carrier R,
       
    81      mult = add R, one = zero R, m_inv = a_inv R |)"
       
    82   by (simp add: abelian_semigroup_def)
       
    83 
       
    84 lemmas group_record_simps = semigroup.simps monoid.simps group.simps
       
    85 
       
    86 lemmas (in cring) a_closed [intro, simp] =
       
    87   magma.m_closed [OF a_magma, simplified group_record_simps]
       
    88 
       
    89 lemmas (in cring) zero_closed [intro, simp] = 
       
    90   l_one.one_closed [OF a_l_one, simplified group_record_simps]
       
    91 
       
    92 lemmas (in cring) a_inv_closed [intro, simp] =
       
    93   group.inv_closed [OF a_group, simplified group_record_simps]
       
    94 
       
    95 lemma (in cring) minus_closed [intro, simp]:
       
    96   "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<ominus> y \<in> carrier R"
       
    97   by (simp add: minus_def)
       
    98 
       
    99 lemmas (in cring) a_l_cancel [simp] =
       
   100   group.l_cancel [OF a_group, simplified group_record_simps]
       
   101 
       
   102 lemmas (in cring) a_r_cancel [simp] =
       
   103   group.r_cancel [OF a_group, simplified group_record_simps]
       
   104 
       
   105 lemmas (in cring) a_assoc =
       
   106   semigroup.m_assoc [OF a_semigroup, simplified group_record_simps]
       
   107 
       
   108 lemmas (in cring) l_zero [simp] =
       
   109   l_one.l_one [OF a_l_one, simplified group_record_simps]
       
   110 
       
   111 lemmas (in cring) l_neg =
       
   112   group.l_inv [OF a_group, simplified group_record_simps]
       
   113 
       
   114 lemmas (in cring) a_comm =
       
   115   abelian_semigroup.m_comm [OF a_abelian_semigroup,
       
   116   simplified group_record_simps]
       
   117 
       
   118 lemmas (in cring) a_lcomm =
       
   119   abelian_semigroup.m_lcomm [OF a_abelian_semigroup, simplified group_record_simps]
       
   120 
       
   121 lemma (in cring) r_zero [simp]:
       
   122   "x \<in> carrier R ==> x \<oplus> \<zero> = x"
       
   123   using group.r_one [OF a_group]
       
   124   by simp
       
   125 
       
   126 lemma (in cring) r_neg:
       
   127   "x \<in> carrier R ==> x \<oplus> (\<ominus> x) = \<zero>"
       
   128   using group.r_inv [OF a_group]
       
   129   by simp
       
   130 
       
   131 lemmas (in cring) minus_zero [simp] =
       
   132   group.inv_one [OF a_group, simplified group_record_simps]
       
   133 
       
   134 lemma (in cring) minus_minus [simp]:
       
   135   "x \<in> carrier R ==> \<ominus> (\<ominus> x) = x"
       
   136   using group.inv_inv [OF a_group, simplified group_record_simps]
       
   137   by simp
       
   138 
       
   139 lemma (in cring) minus_add:
       
   140   "[| x \<in> carrier R; y \<in> carrier R |] ==> \<ominus> (x \<oplus> y) = \<ominus> x \<oplus> \<ominus> y"
       
   141   using abelian_group.inv_mult [OF a_abelian_group]
       
   142   by simp
       
   143 
       
   144 lemmas (in cring) a_ac = a_assoc a_comm a_lcomm
       
   145 
   319 
   146 subsection {* Normaliser for Commutative Rings *}
   320 subsection {* Normaliser for Commutative Rings *}
   147 
   321 
   148 lemma (in cring) r_neg2:
   322 lemma (in abelian_group) r_neg2:
   149   "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<oplus> (\<ominus> x \<oplus> y) = y"
   323   "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<oplus> (\<ominus> x \<oplus> y) = y"
   150 proof -
   324 proof -
   151   assume G: "x \<in> carrier R" "y \<in> carrier R"
   325   assume G: "x \<in> carrier G" "y \<in> carrier G"
   152   then have "(x \<oplus> \<ominus> x) \<oplus> y = y" by (simp only: r_neg l_zero)
   326   then have "(x \<oplus> \<ominus> x) \<oplus> y = y"
   153   with G show ?thesis by (simp add: a_ac)
   327     by (simp only: r_neg l_zero)
   154 qed
   328   with G show ?thesis 
   155 
   329     by (simp add: a_ac)
   156 lemma (in cring) r_neg1:
   330 qed
   157   "[| x \<in> carrier R; y \<in> carrier R |] ==> \<ominus> x \<oplus> (x \<oplus> y) = y"
   331 
   158 proof -
   332 lemma (in abelian_group) r_neg1:
   159   assume G: "x \<in> carrier R" "y \<in> carrier R"
   333   "[| x \<in> carrier G; y \<in> carrier G |] ==> \<ominus> x \<oplus> (x \<oplus> y) = y"
   160   then have "(\<ominus> x \<oplus> x) \<oplus> y = y" by (simp only: l_neg l_zero)
   334 proof -
       
   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)
   161   with G show ?thesis by (simp add: a_ac)
   338   with G show ?thesis by (simp add: a_ac)
   162 qed
   339 qed
   163 
   340 
   164 lemma (in cring) r_distr:
   341 lemma (in cring) r_distr:
   165   "[| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |]
   342   "[| x \<in> carrier R; y \<in> carrier R; z \<in> carrier R |]
   166   ==> z \<otimes> (x \<oplus> y) = z \<otimes> x \<oplus> z \<otimes> y"
   343   ==> z \<otimes> (x \<oplus> y) = z \<otimes> x \<oplus> z \<otimes> y"
   167 proof -
   344 proof -
   168   assume G: "x \<in> carrier R" "y \<in> carrier R" "z \<in> carrier R"
   345   assume R: "x \<in> carrier R" "y \<in> carrier R" "z \<in> carrier R"
   169   then have "z \<otimes> (x \<oplus> y) = (x \<oplus> y) \<otimes> z" by (simp add: m_comm)
   346   then have "z \<otimes> (x \<oplus> y) = (x \<oplus> y) \<otimes> z" by (simp add: m_comm)
   170   also from G have "... = x \<otimes> z \<oplus> y \<otimes> z" by (simp add: l_distr)
   347   also from R have "... = x \<otimes> z \<oplus> y \<otimes> z" by (simp add: l_distr)
   171   also from G have "... = z \<otimes> x \<oplus> z \<otimes> y" by (simp add: m_comm)
   348   also from R have "... = z \<otimes> x \<oplus> z \<otimes> y" by (simp add: m_comm)
   172   finally show ?thesis .
   349   finally show ?thesis .
   173 qed
   350 qed
   174 
   351 
   175 text {* 
   352 text {* 
   176   The following proofs are from Jacobson, Basic Algebra I, pp.~88--89
   353   The following proofs are from Jacobson, Basic Algebra I, pp.~88--89
   189 
   366 
   190 lemma (in cring) r_null [simp]:
   367 lemma (in cring) r_null [simp]:
   191   "x \<in> carrier R ==> x \<otimes> \<zero> = \<zero>"
   368   "x \<in> carrier R ==> x \<otimes> \<zero> = \<zero>"
   192 proof -
   369 proof -
   193   assume R: "x \<in> carrier R"
   370   assume R: "x \<in> carrier R"
   194   then have "x \<otimes> \<zero> = \<zero> \<otimes> x" by (simp add: ac)
   371   then have "x \<otimes> \<zero> = \<zero> \<otimes> x" by (simp add: m_ac)
   195   also from R have "... = \<zero>" by simp
   372   also from R have "... = \<zero>" by simp
   196   finally show ?thesis .
   373   finally show ?thesis .
   197 qed
   374 qed
   198 
   375 
   199 lemma (in cring) l_minus:
   376 lemma (in cring) l_minus:
   209 
   386 
   210 lemma (in cring) r_minus:
   387 lemma (in cring) r_minus:
   211   "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<otimes> \<ominus> y = \<ominus> (x \<otimes> y)"
   388   "[| x \<in> carrier R; y \<in> carrier R |] ==> x \<otimes> \<ominus> y = \<ominus> (x \<otimes> y)"
   212 proof -
   389 proof -
   213   assume R: "x \<in> carrier R" "y \<in> carrier R"
   390   assume R: "x \<in> carrier R" "y \<in> carrier R"
   214   then have "x \<otimes> \<ominus> y = \<ominus> y \<otimes> x" by (simp add: ac)
   391   then have "x \<otimes> \<ominus> y = \<ominus> y \<otimes> x" by (simp add: m_ac)
   215   also from R have "... = \<ominus> (y \<otimes> x)" by (simp add: l_minus)
   392   also from R have "... = \<ominus> (y \<otimes> x)" by (simp add: l_minus)
   216   also from R have "... = \<ominus> (x \<otimes> y)" by (simp add: ac)
   393   also from R have "... = \<ominus> (x \<otimes> y)" by (simp add: m_ac)
   217   finally show ?thesis .
   394   finally show ?thesis .
   218 qed
   395 qed
       
   396 
       
   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)
   219 
   400 
   220 lemmas (in cring) cring_simprules =
   401 lemmas (in cring) cring_simprules =
   221   a_closed zero_closed a_inv_closed minus_closed m_closed one_closed
   402   a_closed zero_closed a_inv_closed minus_closed m_closed one_closed
   222   a_assoc l_zero l_neg a_comm m_assoc l_one l_distr m_comm minus_def
   403   a_assoc l_zero l_neg a_comm m_assoc l_one l_distr m_comm minus_eq
   223   r_zero r_neg r_neg2 r_neg1 minus_add minus_minus minus_zero
   404   r_zero r_neg r_neg2 r_neg1 minus_add minus_minus minus_zero
   224   a_lcomm m_lcomm r_distr l_null r_null l_minus r_minus
   405   a_lcomm m_lcomm r_distr l_null r_null l_minus r_minus
   225 
   406 
   226 use "ringsimp.ML"
   407 use "ringsimp.ML"
   227 
   408 
   228 method_setup algebra =
   409 method_setup algebra =
   229   {* Method.ctxt_args cring_normalise *}
   410   {* Method.ctxt_args cring_normalise *}
   230   {* computes distributive normal form in commutative rings (locales version) *}
   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
   231 
   416 
   232 text {* Two examples for use of method algebra *}
   417 text {* Two examples for use of method algebra *}
   233 
   418 
   234 lemma
   419 lemma
   235   includes cring R + cring S
   420   includes cring R + cring S
   241   includes cring
   426   includes cring
   242   shows "[| a \<in> carrier R; b \<in> carrier R |] ==> a \<ominus> (a \<ominus> b) = b"
   427   shows "[| a \<in> carrier R; b \<in> carrier R |] ==> a \<ominus> (a \<ominus> b) = b"
   243   by algebra
   428   by algebra
   244 
   429 
   245 subsection {* Sums over Finite Sets *}
   430 subsection {* Sums over Finite Sets *}
   246 
       
   247 text {*
       
   248   This definition makes it easy to lift lemmas from @{term finprod}.
       
   249 *}
       
   250 
       
   251 constdefs
       
   252   finsum :: "[('b, 'm) ring_scheme, 'a => 'b, 'a set] => 'b"
       
   253   "finsum R f A == finprod (| carrier = carrier R,
       
   254      mult = add R, one = zero R, m_inv = a_inv R |) f A"
       
   255 
       
   256 lemma (in cring) a_abelian_monoid:
       
   257   "abelian_monoid (| carrier = carrier R,
       
   258      mult = add R, one = zero R, m_inv = a_inv R |)"
       
   259   by (simp add: abelian_monoid_def)
       
   260 
       
   261 (*
       
   262   lemmas (in cring) finsum_empty [simp] =
       
   263     abelian_monoid.finprod_empty [OF a_abelian_monoid, simplified]
       
   264   is dangeous, because attributes (like simplified) are applied upon opening
       
   265   the locale, simplified refers to the simpset at that time!!!
       
   266 *)
       
   267 
       
   268 lemmas (in cring) finsum_empty [simp] =
       
   269   abelian_monoid.finprod_empty [OF a_abelian_monoid, folded finsum_def,
       
   270     simplified group_record_simps]
       
   271 
       
   272 lemmas (in cring) finsum_insert [simp] =
       
   273   abelian_monoid.finprod_insert [OF a_abelian_monoid, folded finsum_def,
       
   274     simplified group_record_simps]
       
   275 
       
   276 lemmas (in cring) finsum_zero =
       
   277   abelian_monoid.finprod_one [OF a_abelian_monoid, folded finsum_def,
       
   278     simplified group_record_simps]
       
   279 
       
   280 lemmas (in cring) finsum_closed [simp] =
       
   281   abelian_monoid.finprod_closed [OF a_abelian_monoid, folded finsum_def,
       
   282     simplified group_record_simps]
       
   283 
       
   284 lemmas (in cring) finsum_Un_Int =
       
   285   abelian_monoid.finprod_Un_Int [OF a_abelian_monoid, folded finsum_def,
       
   286     simplified group_record_simps]
       
   287 
       
   288 lemmas (in cring) finsum_Un_disjoint =
       
   289   abelian_monoid.finprod_Un_disjoint [OF a_abelian_monoid, folded finsum_def,
       
   290     simplified group_record_simps]
       
   291 
       
   292 lemmas (in cring) finsum_addf =
       
   293   abelian_monoid.finprod_multf [OF a_abelian_monoid, folded finsum_def,
       
   294     simplified group_record_simps]
       
   295 
       
   296 lemmas (in cring) finsum_cong' =
       
   297   abelian_monoid.finprod_cong' [OF a_abelian_monoid, folded finsum_def,
       
   298     simplified group_record_simps]
       
   299 
       
   300 lemmas (in cring) finsum_0 [simp] =
       
   301   abelian_monoid.finprod_0 [OF a_abelian_monoid, folded finsum_def,
       
   302     simplified group_record_simps]
       
   303 
       
   304 lemmas (in cring) finsum_Suc [simp] =
       
   305   abelian_monoid.finprod_Suc [OF a_abelian_monoid, folded finsum_def,
       
   306     simplified group_record_simps]
       
   307 
       
   308 lemmas (in cring) finsum_Suc2 =
       
   309   abelian_monoid.finprod_Suc2 [OF a_abelian_monoid, folded finsum_def,
       
   310     simplified group_record_simps]
       
   311 
       
   312 lemmas (in cring) finsum_add [simp] =
       
   313   abelian_monoid.finprod_mult [OF a_abelian_monoid, folded finsum_def,
       
   314     simplified group_record_simps]
       
   315 
       
   316 lemmas (in cring) finsum_cong =
       
   317   abelian_monoid.finprod_cong [OF a_abelian_monoid, folded finsum_def,
       
   318     simplified group_record_simps]
       
   319 
       
   320 text {*Usually, if this rule causes a failed congruence proof error,
       
   321    the reason is that the premise @{text "g \<in> B -> carrier G"} cannot be shown.
       
   322    Adding @{thm [source] Pi_def} to the simpset is often useful. *}
       
   323 
   431 
   324 lemma (in cring) finsum_ldistr:
   432 lemma (in cring) finsum_ldistr:
   325   "[| finite A; a \<in> carrier R; f \<in> A -> carrier R |] ==>
   433   "[| finite A; a \<in> carrier R; f \<in> A -> carrier R |] ==>
   326    finsum R f A \<otimes> a = finsum R (%i. f i \<otimes> a) A"
   434    finsum R f A \<otimes> a = finsum R (%i. f i \<otimes> a) A"
   327 proof (induct set: Finites)
   435 proof (induct set: Finites)
   378 proof -
   486 proof -
   379   from prem and R have "(a \<otimes> b = a \<otimes> c) = (b = c)" by (rule m_lcancel)
   487   from prem and R have "(a \<otimes> b = a \<otimes> c) = (b = c)" by (rule m_lcancel)
   380   with R show ?thesis by algebra
   488   with R show ?thesis by algebra
   381 qed
   489 qed
   382 
   490 
       
   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 
   383 end
   577 end