src/HOL/Algebra/Group.thy
changeset 13936 d3671b878828
parent 13854 91c9ab25fece
child 13940 c67798653056
equal deleted inserted replaced
13935:4822d9597d1e 13936:d3671b878828
     4   Author: Clemens Ballarin, started 4 February 2003
     4   Author: Clemens Ballarin, started 4 February 2003
     5 
     5 
     6 Based on work by Florian Kammueller, L C Paulson and Markus Wenzel.
     6 Based on work by Florian Kammueller, L C Paulson and Markus Wenzel.
     7 *)
     7 *)
     8 
     8 
     9 header {* Algebraic Structures up to Abelian Groups *}
     9 header {* Algebraic Structures up to Commutative Groups *}
    10 
    10 
    11 theory Group = FuncSet:
    11 theory Group = FuncSet:
       
    12 
       
    13 axclass number < type
       
    14 
       
    15 instance nat :: number ..
       
    16 instance int :: number ..
       
    17 
       
    18 section {* From Magmas to Groups *}
    12 
    19 
    13 text {*
    20 text {*
    14   Definitions follow Jacobson, Basic Algebra I, Freeman, 1985; with
    21   Definitions follow Jacobson, Basic Algebra I, Freeman, 1985; with
    15   the exception of \emph{magma} which, following Bourbaki, is a set
    22   the exception of \emph{magma} which, following Bourbaki, is a set
    16   together with a binary, closed operation.
    23   together with a binary, closed operation.
    17 *}
    24 *}
    18 
    25 
    19 section {* From Magmas to Groups *}
       
    20 
       
    21 subsection {* Definitions *}
    26 subsection {* Definitions *}
    22 
    27 
    23 record 'a semigroup =
    28 record 'a semigroup =
    24   carrier :: "'a set"
    29   carrier :: "'a set"
    25   mult :: "['a, 'a] => 'a" (infixl "\<otimes>\<index>" 70)
    30   mult :: "['a, 'a] => 'a" (infixl "\<otimes>\<index>" 70)
    26 
    31 
    27 record 'a monoid = "'a semigroup" +
    32 record 'a monoid = "'a semigroup" +
    28   one :: 'a ("\<one>\<index>")
    33   one :: 'a ("\<one>\<index>")
    29 
    34 
    30 record 'a group = "'a monoid" +
    35 constdefs
    31   m_inv :: "'a => 'a" ("inv\<index> _" [81] 80)
    36   m_inv :: "[('a, 'm) monoid_scheme, 'a] => 'a" ("inv\<index> _" [81] 80)
       
    37   "m_inv G x == (THE y. y \<in> carrier G &
       
    38                   mult G x y = one G & mult G y x = one G)"
       
    39 
       
    40   Units :: "('a, 'm) monoid_scheme => 'a set"
       
    41   "Units G == {y. y \<in> carrier G &
       
    42                   (EX x : carrier G. mult G x y = one G & mult G y x = one G)}"
       
    43 
       
    44 consts
       
    45   pow :: "[('a, 'm) monoid_scheme, 'a, 'b::number] => 'a" (infixr "'(^')\<index>" 75)
       
    46 
       
    47 defs (overloaded)
       
    48   nat_pow_def: "pow G a n == nat_rec (one G) (%u b. mult G b a) n"
       
    49   int_pow_def: "pow G a z ==
       
    50     let p = nat_rec (one G) (%u b. mult G b a)
       
    51     in if neg z then m_inv G (p (nat (-z))) else p (nat z)"
    32 
    52 
    33 locale magma = struct G +
    53 locale magma = struct G +
    34   assumes m_closed [intro, simp]:
    54   assumes m_closed [intro, simp]:
    35     "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<otimes> y \<in> carrier G"
    55     "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<otimes> y \<in> carrier G"
    36 
    56 
    37 locale semigroup = magma +
    57 locale semigroup = magma +
    38   assumes m_assoc:
    58   assumes m_assoc:
    39     "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
    59     "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
    40      (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
    60     (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
    41 
    61 
    42 locale l_one = struct G +
    62 locale monoid = semigroup +
    43   assumes one_closed [intro, simp]: "\<one> \<in> carrier G"
    63   assumes one_closed [intro, simp]: "\<one> \<in> carrier G"
    44     and l_one [simp]: "x \<in> carrier G ==> \<one> \<otimes> x = x"
    64     and l_one [simp]: "x \<in> carrier G ==> \<one> \<otimes> x = x"
    45 
    65     and r_one [simp]: "x \<in> carrier G ==> x \<otimes> \<one> = x"
    46 locale group = semigroup + l_one +
    66 
    47   assumes inv_closed [intro, simp]: "x \<in> carrier G ==> inv x \<in> carrier G"
    67 lemma monoidI:
    48     and l_inv: "x \<in> carrier G ==> inv x \<otimes> x = \<one>"
    68   assumes m_closed:
       
    69       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y \<in> carrier G"
       
    70     and one_closed: "one G \<in> carrier G"
       
    71     and m_assoc:
       
    72       "!!x y z. [| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
       
    73       mult G (mult G x y) z = mult G x (mult G y z)"
       
    74     and l_one: "!!x. x \<in> carrier G ==> mult G (one G) x = x"
       
    75     and r_one: "!!x. x \<in> carrier G ==> mult G x (one G) = x"
       
    76   shows "monoid G"
       
    77   by (fast intro!: monoid.intro magma.intro semigroup_axioms.intro
       
    78     semigroup.intro monoid_axioms.intro
       
    79     intro: prems)
       
    80 
       
    81 lemma (in monoid) Units_closed [dest]:
       
    82   "x \<in> Units G ==> x \<in> carrier G"
       
    83   by (unfold Units_def) fast
       
    84 
       
    85 lemma (in monoid) inv_unique:
       
    86   assumes eq: "y \<otimes> x = \<one>" "x \<otimes> y' = \<one>"
       
    87     and G: "x \<in> carrier G" "y \<in> carrier G" "y' \<in> carrier G"
       
    88   shows "y = y'"
       
    89 proof -
       
    90   from G eq have "y = y \<otimes> (x \<otimes> y')" by simp
       
    91   also from G have "... = (y \<otimes> x) \<otimes> y'" by (simp add: m_assoc)
       
    92   also from G eq have "... = y'" by simp
       
    93   finally show ?thesis .
       
    94 qed
       
    95 
       
    96 lemma (in monoid) Units_inv_closed [intro, simp]:
       
    97   "x \<in> Units G ==> inv x \<in> carrier G"
       
    98   apply (unfold Units_def m_inv_def)
       
    99   apply auto
       
   100   apply (rule theI2, fast)
       
   101    apply (fast intro: inv_unique)
       
   102   apply fast
       
   103   done
       
   104 
       
   105 lemma (in monoid) Units_l_inv:
       
   106   "x \<in> Units G ==> inv x \<otimes> x = \<one>"
       
   107   apply (unfold Units_def m_inv_def)
       
   108   apply auto
       
   109   apply (rule theI2, fast)
       
   110    apply (fast intro: inv_unique)
       
   111   apply fast
       
   112   done
       
   113 
       
   114 lemma (in monoid) Units_r_inv:
       
   115   "x \<in> Units G ==> x \<otimes> inv x = \<one>"
       
   116   apply (unfold Units_def m_inv_def)
       
   117   apply auto
       
   118   apply (rule theI2, fast)
       
   119    apply (fast intro: inv_unique)
       
   120   apply fast
       
   121   done
       
   122 
       
   123 lemma (in monoid) Units_inv_Units [intro, simp]:
       
   124   "x \<in> Units G ==> inv x \<in> Units G"
       
   125 proof -
       
   126   assume x: "x \<in> Units G"
       
   127   show "inv x \<in> Units G"
       
   128     by (auto simp add: Units_def
       
   129       intro: Units_l_inv Units_r_inv x Units_closed [OF x])
       
   130 qed
       
   131 
       
   132 lemma (in monoid) Units_l_cancel [simp]:
       
   133   "[| x \<in> Units G; y \<in> carrier G; z \<in> carrier G |] ==>
       
   134    (x \<otimes> y = x \<otimes> z) = (y = z)"
       
   135 proof
       
   136   assume eq: "x \<otimes> y = x \<otimes> z"
       
   137     and G: "x \<in> Units G" "y \<in> carrier G" "z \<in> carrier G"
       
   138   then have "(inv x \<otimes> x) \<otimes> y = (inv x \<otimes> x) \<otimes> z"
       
   139     by (simp add: m_assoc Units_closed)
       
   140   with G show "y = z" by (simp add: Units_l_inv)
       
   141 next
       
   142   assume eq: "y = z"
       
   143     and G: "x \<in> Units G" "y \<in> carrier G" "z \<in> carrier G"
       
   144   then show "x \<otimes> y = x \<otimes> z" by simp
       
   145 qed
       
   146 
       
   147 lemma (in monoid) Units_inv_inv [simp]:
       
   148   "x \<in> Units G ==> inv (inv x) = x"
       
   149 proof -
       
   150   assume x: "x \<in> Units G"
       
   151   then have "inv x \<otimes> inv (inv x) = inv x \<otimes> x"
       
   152     by (simp add: Units_l_inv Units_r_inv)
       
   153   with x show ?thesis by (simp add: Units_closed)
       
   154 qed
       
   155 
       
   156 lemma (in monoid) inv_inj_on_Units:
       
   157   "inj_on (m_inv G) (Units G)"
       
   158 proof (rule inj_onI)
       
   159   fix x y
       
   160   assume G: "x \<in> Units G" "y \<in> Units G" and eq: "inv x = inv y"
       
   161   then have "inv (inv x) = inv (inv y)" by simp
       
   162   with G show "x = y" by simp
       
   163 qed
       
   164 
       
   165 text {* Power *}
       
   166 
       
   167 lemma (in monoid) nat_pow_closed [intro, simp]:
       
   168   "x \<in> carrier G ==> x (^) (n::nat) \<in> carrier G"
       
   169   by (induct n) (simp_all add: nat_pow_def)
       
   170 
       
   171 lemma (in monoid) nat_pow_0 [simp]:
       
   172   "x (^) (0::nat) = \<one>"
       
   173   by (simp add: nat_pow_def)
       
   174 
       
   175 lemma (in monoid) nat_pow_Suc [simp]:
       
   176   "x (^) (Suc n) = x (^) n \<otimes> x"
       
   177   by (simp add: nat_pow_def)
       
   178 
       
   179 lemma (in monoid) nat_pow_one [simp]:
       
   180   "\<one> (^) (n::nat) = \<one>"
       
   181   by (induct n) simp_all
       
   182 
       
   183 lemma (in monoid) nat_pow_mult:
       
   184   "x \<in> carrier G ==> x (^) (n::nat) \<otimes> x (^) m = x (^) (n + m)"
       
   185   by (induct m) (simp_all add: m_assoc [THEN sym])
       
   186 
       
   187 lemma (in monoid) nat_pow_pow:
       
   188   "x \<in> carrier G ==> (x (^) n) (^) m = x (^) (n * m::nat)"
       
   189   by (induct m) (simp, simp add: nat_pow_mult add_commute)
       
   190 
       
   191 text {*
       
   192   A group is a monoid all of whose elements are invertible.
       
   193 *}
       
   194 
       
   195 locale group = monoid +
       
   196   assumes Units: "carrier G <= Units G"
       
   197 
       
   198 theorem groupI:
       
   199   assumes m_closed [simp]:
       
   200       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y \<in> carrier G"
       
   201     and one_closed [simp]: "one G \<in> carrier G"
       
   202     and m_assoc:
       
   203       "!!x y z. [| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
       
   204       mult G (mult G x y) z = mult G x (mult G y z)"
       
   205     and l_one [simp]: "!!x. x \<in> carrier G ==> mult G (one G) x = x"
       
   206     and l_inv_ex: "!!x. x \<in> carrier G ==> EX y : carrier G. mult G y x = one G"
       
   207   shows "group G"
       
   208 proof -
       
   209   have l_cancel [simp]:
       
   210     "!!x y z. [| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
       
   211     (mult G x y = mult G x z) = (y = z)"
       
   212   proof
       
   213     fix x y z
       
   214     assume eq: "mult G x y = mult G x z"
       
   215       and G: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
       
   216     with l_inv_ex obtain x_inv where xG: "x_inv \<in> carrier G"
       
   217       and l_inv: "mult G x_inv x = one G" by fast
       
   218     from G eq xG have "mult G (mult G x_inv x) y = mult G (mult G x_inv x) z"
       
   219       by (simp add: m_assoc)
       
   220     with G show "y = z" by (simp add: l_inv)
       
   221   next
       
   222     fix x y z
       
   223     assume eq: "y = z"
       
   224       and G: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
       
   225     then show "mult G x y = mult G x z" by simp
       
   226   qed
       
   227   have r_one:
       
   228     "!!x. x \<in> carrier G ==> mult G x (one G) = x"
       
   229   proof -
       
   230     fix x
       
   231     assume x: "x \<in> carrier G"
       
   232     with l_inv_ex obtain x_inv where xG: "x_inv \<in> carrier G"
       
   233       and l_inv: "mult G x_inv x = one G" by fast
       
   234     from x xG have "mult G x_inv (mult G x (one G)) = mult G x_inv x"
       
   235       by (simp add: m_assoc [symmetric] l_inv)
       
   236     with x xG show "mult G x (one G) = x" by simp 
       
   237   qed
       
   238   have inv_ex:
       
   239     "!!x. x \<in> carrier G ==> EX y : carrier G. mult G y x = one G &
       
   240       mult G x y = one G"
       
   241   proof -
       
   242     fix x
       
   243     assume x: "x \<in> carrier G"
       
   244     with l_inv_ex obtain y where y: "y \<in> carrier G"
       
   245       and l_inv: "mult G y x = one G" by fast
       
   246     from x y have "mult G y (mult G x y) = mult G y (one G)"
       
   247       by (simp add: m_assoc [symmetric] l_inv r_one)
       
   248     with x y have r_inv: "mult G x y = one G"
       
   249       by simp
       
   250     from x y show "EX y : carrier G. mult G y x = one G &
       
   251       mult G x y = one G"
       
   252       by (fast intro: l_inv r_inv)
       
   253   qed
       
   254   then have carrier_subset_Units: "carrier G <= Units G"
       
   255     by (unfold Units_def) fast
       
   256   show ?thesis
       
   257     by (fast intro!: group.intro magma.intro semigroup_axioms.intro
       
   258       semigroup.intro monoid_axioms.intro group_axioms.intro
       
   259       carrier_subset_Units intro: prems r_one)
       
   260 qed
       
   261 
       
   262 lemma (in monoid) monoid_groupI:
       
   263   assumes l_inv_ex:
       
   264     "!!x. x \<in> carrier G ==> EX y : carrier G. mult G y x = one G"
       
   265   shows "group G"
       
   266   by (rule groupI) (auto intro: m_assoc l_inv_ex)
       
   267 
       
   268 lemma (in group) Units_eq [simp]:
       
   269   "Units G = carrier G"
       
   270 proof
       
   271   show "Units G <= carrier G" by fast
       
   272 next
       
   273   show "carrier G <= Units G" by (rule Units)
       
   274 qed
       
   275 
       
   276 lemma (in group) inv_closed [intro, simp]:
       
   277   "x \<in> carrier G ==> inv x \<in> carrier G"
       
   278   using Units_inv_closed by simp
       
   279 
       
   280 lemma (in group) l_inv:
       
   281   "x \<in> carrier G ==> inv x \<otimes> x = \<one>"
       
   282   using Units_l_inv by simp
    49 
   283 
    50 subsection {* Cancellation Laws and Basic Properties *}
   284 subsection {* Cancellation Laws and Basic Properties *}
    51 
   285 
    52 lemma (in group) l_cancel [simp]:
   286 lemma (in group) l_cancel [simp]:
    53   "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
   287   "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
    54    (x \<otimes> y = x \<otimes> z) = (y = z)"
   288    (x \<otimes> y = x \<otimes> z) = (y = z)"
    55 proof
   289   using Units_l_inv by simp
    56   assume eq: "x \<otimes> y = x \<otimes> z"
   290 (*
    57     and G: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
       
    58   then have "(inv x \<otimes> x) \<otimes> y = (inv x \<otimes> x) \<otimes> z" by (simp add: m_assoc)
       
    59   with G show "y = z" by (simp add: l_inv)
       
    60 next
       
    61   assume eq: "y = z"
       
    62     and G: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
       
    63   then show "x \<otimes> y = x \<otimes> z" by simp
       
    64 qed
       
    65 
       
    66 lemma (in group) r_one [simp]:  
   291 lemma (in group) r_one [simp]:  
    67   "x \<in> carrier G ==> x \<otimes> \<one> = x"
   292   "x \<in> carrier G ==> x \<otimes> \<one> = x"
    68 proof -
   293 proof -
    69   assume x: "x \<in> carrier G"
   294   assume x: "x \<in> carrier G"
    70   then have "inv x \<otimes> (x \<otimes> \<one>) = inv x \<otimes> x"
   295   then have "inv x \<otimes> (x \<otimes> \<one>) = inv x \<otimes> x"
    71     by (simp add: m_assoc [symmetric] l_inv)
   296     by (simp add: m_assoc [symmetric] l_inv)
    72   with x show ?thesis by simp 
   297   with x show ?thesis by simp 
    73 qed
   298 qed
    74 
   299 *)
    75 lemma (in group) r_inv:
   300 lemma (in group) r_inv:
    76   "x \<in> carrier G ==> x \<otimes> inv x = \<one>"
   301   "x \<in> carrier G ==> x \<otimes> inv x = \<one>"
    77 proof -
   302 proof -
    78   assume x: "x \<in> carrier G"
   303   assume x: "x \<in> carrier G"
    79   then have "inv x \<otimes> (x \<otimes> inv x) = inv x \<otimes> \<one>"
   304   then have "inv x \<otimes> (x \<otimes> inv x) = inv x \<otimes> \<one>"
   104   finally show ?thesis .
   329   finally show ?thesis .
   105 qed
   330 qed
   106 
   331 
   107 lemma (in group) inv_inv [simp]:
   332 lemma (in group) inv_inv [simp]:
   108   "x \<in> carrier G ==> inv (inv x) = x"
   333   "x \<in> carrier G ==> inv (inv x) = x"
   109 proof -
   334   using Units_inv_inv by simp
   110   assume x: "x \<in> carrier G"
   335 
   111   then have "inv x \<otimes> inv (inv x) = inv x \<otimes> x" by (simp add: l_inv r_inv)
   336 lemma (in group) inv_inj:
   112   with x show ?thesis by simp
   337   "inj_on (m_inv G) (carrier G)"
   113 qed
   338   using inv_inj_on_Units by simp
   114 
   339 
   115 lemma (in group) inv_mult_group:
   340 lemma (in group) inv_mult_group:
   116   "[| x \<in> carrier G; y \<in> carrier G |] ==> inv (x \<otimes> y) = inv y \<otimes> inv x"
   341   "[| x \<in> carrier G; y \<in> carrier G |] ==> inv (x \<otimes> y) = inv y \<otimes> inv x"
   117 proof -
   342 proof -
   118   assume G: "x \<in> carrier G" "y \<in> carrier G"
   343   assume G: "x \<in> carrier G" "y \<in> carrier G"
   119   then have "inv (x \<otimes> y) \<otimes> (x \<otimes> y) = (inv y \<otimes> inv x) \<otimes> (x \<otimes> y)"
   344   then have "inv (x \<otimes> y) \<otimes> (x \<otimes> y) = (inv y \<otimes> inv x) \<otimes> (x \<otimes> y)"
   120     by (simp add: m_assoc l_inv) (simp add: m_assoc [symmetric] l_inv)
   345     by (simp add: m_assoc l_inv) (simp add: m_assoc [symmetric] l_inv)
   121   with G show ?thesis by simp
   346   with G show ?thesis by simp
   122 qed
   347 qed
   123 
   348 
       
   349 text {* Power *}
       
   350 
       
   351 lemma (in group) int_pow_def2:
       
   352   "a (^) (z::int) = (if neg z then inv (a (^) (nat (-z))) else a (^) (nat z))"
       
   353   by (simp add: int_pow_def nat_pow_def Let_def)
       
   354 
       
   355 lemma (in group) int_pow_0 [simp]:
       
   356   "x (^) (0::int) = \<one>"
       
   357   by (simp add: int_pow_def2)
       
   358 
       
   359 lemma (in group) int_pow_one [simp]:
       
   360   "\<one> (^) (z::int) = \<one>"
       
   361   by (simp add: int_pow_def2)
       
   362 
   124 subsection {* Substructures *}
   363 subsection {* Substructures *}
   125 
   364 
   126 locale submagma = var H + struct G +
   365 locale submagma = var H + struct G +
   127   assumes subset [intro, simp]: "H \<subseteq> carrier G"
   366   assumes subset [intro, simp]: "H \<subseteq> carrier G"
   128     and m_closed [intro, simp]: "[| x \<in> H; y \<in> H |] ==> x \<otimes> y \<in> H"
   367     and m_closed [intro, simp]: "[| x \<in> H; y \<in> H |] ==> x \<otimes> y \<in> H"
   129 
   368 
   130 declare (in submagma) magma.intro [intro] semigroup.intro [intro]
   369 declare (in submagma) magma.intro [intro] semigroup.intro [intro]
   131 
   370   semigroup_axioms.intro [intro]
   132 (*
   371 (*
   133 alternative definition of submagma
   372 alternative definition of submagma
   134 
   373 
   135 locale submagma = var H + struct G +
   374 locale submagma = var H + struct G +
   136   assumes subset [intro, simp]: "carrier H \<subseteq> carrier G"
   375   assumes subset [intro, simp]: "carrier H \<subseteq> carrier G"
   165 locale subgroup = submagma H G +
   404 locale subgroup = submagma H G +
   166   assumes one_closed [intro, simp]: "\<one> \<in> H"
   405   assumes one_closed [intro, simp]: "\<one> \<in> H"
   167     and m_inv_closed [intro, simp]: "x \<in> H ==> inv x \<in> H"
   406     and m_inv_closed [intro, simp]: "x \<in> H ==> inv x \<in> H"
   168 
   407 
   169 declare (in subgroup) group.intro [intro]
   408 declare (in subgroup) group.intro [intro]
   170 
   409 (*
   171 lemma (in subgroup) l_oneI [intro]:
   410 lemma (in subgroup) l_oneI [intro]:
   172   includes l_one G
   411   includes l_one G
   173   shows "l_one (G(| carrier := H |))"
   412   shows "l_one (G(| carrier := H |))"
   174   by rule simp_all
   413   by rule simp_all
   175 
   414 *)
   176 lemma (in subgroup) group_axiomsI [intro]:
   415 lemma (in subgroup) group_axiomsI [intro]:
   177   includes group G
   416   includes group G
   178   shows "group_axioms (G(| carrier := H |))"
   417   shows "group_axioms (G(| carrier := H |))"
   179   by rule (simp_all add: l_inv)
   418   by rule (auto intro: l_inv r_inv simp add: Units_def)
   180 
   419 
   181 lemma (in subgroup) groupI [intro]:
   420 lemma (in subgroup) groupI [intro]:
   182   includes group G
   421   includes group G
   183   shows "group (G(| carrier := H |))"
   422   shows "group (G(| carrier := H |))"
   184   using prems by fast
   423   by (rule groupI) (auto intro: m_assoc l_inv)
   185 
   424 
   186 text {*
   425 text {*
   187   Since @{term H} is nonempty, it contains some element @{term x}.  Since
   426   Since @{term H} is nonempty, it contains some element @{term x}.  Since
   188   it is closed under inverse, it contains @{text "inv x"}.  Since
   427   it is closed under inverse, it contains @{text "inv x"}.  Since
   189   it is closed under product, it contains @{text "x \<otimes> inv x = \<one>"}.
   428   it is closed under product, it contains @{text "x \<otimes> inv x = \<one>"}.
   221   "[| x \<in> H; y \<in> H |] ==> x \<otimes> y \<in> H"
   460   "[| x \<in> H; y \<in> H |] ==> x \<otimes> y \<in> H"
   222   ..
   461   ..
   223 
   462 
   224 declare magma.m_closed [simp]
   463 declare magma.m_closed [simp]
   225 
   464 
   226 declare l_one.one_closed [iff] group.inv_closed [simp]
   465 declare monoid.one_closed [iff] group.inv_closed [simp]
   227   l_one.l_one [simp] group.r_one [simp] group.inv_inv [simp]
   466   monoid.l_one [simp] monoid.r_one [simp] group.inv_inv [simp]
   228 
   467 
   229 lemma subgroup_nonempty:
   468 lemma subgroup_nonempty:
   230   "~ subgroup {} G"
   469   "~ subgroup {} G"
   231   by (blast dest: subgroup.one_closed)
   470   by (blast dest: subgroup.one_closed)
   232 
   471 
   239   then have "finite H" by (blast intro: finite_subset dest: subset)
   478   then have "finite H" by (blast intro: finite_subset dest: subset)
   240   with zero sub have "subgroup {} G" by simp
   479   with zero sub have "subgroup {} G" by simp
   241   with subgroup_nonempty show ?thesis by contradiction
   480   with subgroup_nonempty show ?thesis by contradiction
   242 qed
   481 qed
   243 
   482 
       
   483 (*
       
   484 lemma (in monoid) Units_subgroup:
       
   485   "subgroup (Units G) G"
       
   486 *)
       
   487 
   244 subsection {* Direct Products *}
   488 subsection {* Direct Products *}
   245 
   489 
   246 constdefs
   490 constdefs
   247   DirProdSemigroup ::
   491   DirProdSemigroup ::
   248     "[('a, 'm) semigroup_scheme, ('b, 'n) semigroup_scheme]
   492     "[('a, 'm) semigroup_scheme, ('b, 'n) semigroup_scheme]
   249     => ('a \<times> 'b) semigroup"
   493     => ('a \<times> 'b) semigroup"
   250     (infixr "\<times>\<^sub>s" 80)
   494     (infixr "\<times>\<^sub>s" 80)
   251   "G \<times>\<^sub>s H == (| carrier = carrier G \<times> carrier H,
   495   "G \<times>\<^sub>s H == (| carrier = carrier G \<times> carrier H,
   252     mult = (%(xg, xh) (yg, yh). (mult G xg yg, mult H xh yh)) |)"
   496     mult = (%(xg, xh) (yg, yh). (mult G xg yg, mult H xh yh)) |)"
   253 
   497 
   254   DirProdMonoid ::
   498   DirProdGroup ::
   255     "[('a, 'm) monoid_scheme, ('b, 'n) monoid_scheme] => ('a \<times> 'b) monoid"
   499     "[('a, 'm) monoid_scheme, ('b, 'n) monoid_scheme] => ('a \<times> 'b) monoid"
   256     (infixr "\<times>\<^sub>m" 80)
   500     (infixr "\<times>\<^sub>g" 80)
   257   "G \<times>\<^sub>m H == (| carrier = carrier (G \<times>\<^sub>s H),
   501   "G \<times>\<^sub>g H == (| carrier = carrier (G \<times>\<^sub>s H),
   258     mult = mult (G \<times>\<^sub>s H),
   502     mult = mult (G \<times>\<^sub>s H),
   259     one = (one G, one H) |)"
   503     one = (one G, one H) |)"
   260 
   504 (*
   261   DirProdGroup ::
   505   DirProdGroup ::
   262     "[('a, 'm) group_scheme, ('b, 'n) group_scheme] => ('a \<times> 'b) group"
   506     "[('a, 'm) group_scheme, ('b, 'n) group_scheme] => ('a \<times> 'b) group"
   263     (infixr "\<times>\<^sub>g" 80)
   507     (infixr "\<times>\<^sub>g" 80)
   264   "G \<times>\<^sub>g H == (| carrier = carrier (G \<times>\<^sub>m H),
   508   "G \<times>\<^sub>g H == (| carrier = carrier (G \<times>\<^sub>m H),
   265     mult = mult (G \<times>\<^sub>m H),
   509     mult = mult (G \<times>\<^sub>m H),
   266     one = one (G \<times>\<^sub>m H),
   510     one = one (G \<times>\<^sub>m H),
   267     m_inv = (%(g, h). (m_inv G g, m_inv H h)) |)"
   511     m_inv = (%(g, h). (m_inv G g, m_inv H h)) |)"
       
   512 *)
   268 
   513 
   269 lemma DirProdSemigroup_magma:
   514 lemma DirProdSemigroup_magma:
   270   includes magma G + magma H
   515   includes magma G + magma H
   271   shows "magma (G \<times>\<^sub>s H)"
   516   shows "magma (G \<times>\<^sub>s H)"
   272   by rule (auto simp add: DirProdSemigroup_def)
   517   by rule (auto simp add: DirProdSemigroup_def)
   285 
   530 
   286 lemma DirProdGroup_magma:
   531 lemma DirProdGroup_magma:
   287   includes magma G + magma H
   532   includes magma G + magma H
   288   shows "magma (G \<times>\<^sub>g H)"
   533   shows "magma (G \<times>\<^sub>g H)"
   289   by rule
   534   by rule
   290     (auto simp add: DirProdGroup_def DirProdMonoid_def DirProdSemigroup_def)
   535     (auto simp add: DirProdGroup_def DirProdSemigroup_def)
   291 
   536 
   292 lemma DirProdGroup_semigroup_axioms:
   537 lemma DirProdGroup_semigroup_axioms:
   293   includes semigroup G + semigroup H
   538   includes semigroup G + semigroup H
   294   shows "semigroup_axioms (G \<times>\<^sub>g H)"
   539   shows "semigroup_axioms (G \<times>\<^sub>g H)"
   295   by rule
   540   by rule
   296     (auto simp add: DirProdGroup_def DirProdMonoid_def DirProdSemigroup_def
   541     (auto simp add: DirProdGroup_def DirProdSemigroup_def
   297       G.m_assoc H.m_assoc)
   542       G.m_assoc H.m_assoc)
   298 
   543 
   299 lemma DirProdGroup_semigroup:
   544 lemma DirProdGroup_semigroup:
   300   includes semigroup G + semigroup H
   545   includes semigroup G + semigroup H
   301   shows "semigroup (G \<times>\<^sub>g H)"
   546   shows "semigroup (G \<times>\<^sub>g H)"
   306 (* ... and further lemmas for group ... *)
   551 (* ... and further lemmas for group ... *)
   307 
   552 
   308 lemma DirProdGroup_group:
   553 lemma DirProdGroup_group:
   309   includes group G + group H
   554   includes group G + group H
   310   shows "group (G \<times>\<^sub>g H)"
   555   shows "group (G \<times>\<^sub>g H)"
   311 by rule
   556   by (rule groupI)
   312   (auto intro: magma.intro l_one.intro
   557     (auto intro: G.m_assoc H.m_assoc G.l_inv H.l_inv
   313       semigroup_axioms.intro group_axioms.intro
   558       simp add: DirProdGroup_def DirProdSemigroup_def)
   314     simp add: DirProdGroup_def DirProdMonoid_def DirProdSemigroup_def
       
   315       G.m_assoc H.m_assoc G.l_inv H.l_inv)
       
   316 
   559 
   317 subsection {* Homomorphisms *}
   560 subsection {* Homomorphisms *}
   318 
   561 
   319 constdefs
   562 constdefs
   320   hom :: "[('a, 'c) semigroup_scheme, ('b, 'd) semigroup_scheme]
   563   hom :: "[('a, 'c) semigroup_scheme, ('b, 'd) semigroup_scheme]
   374     by (simp add: hom_mult [symmetric] H.r_inv del: hom_mult)
   617     by (simp add: hom_mult [symmetric] H.r_inv del: hom_mult)
   375   finally have "h x \<otimes>\<^sub>2 h (inv x) = h x \<otimes>\<^sub>2 inv\<^sub>2 (h x)" .
   618   finally have "h x \<otimes>\<^sub>2 h (inv x) = h x \<otimes>\<^sub>2 inv\<^sub>2 (h x)" .
   376   with x show ?thesis by simp
   619   with x show ?thesis by simp
   377 qed
   620 qed
   378 
   621 
   379 section {* Abelian Structures *}
   622 section {* Commutative Structures *}
       
   623 
       
   624 text {*
       
   625   Naming convention: multiplicative structures that are commutative
       
   626   are called \emph{commutative}, additive structures are called
       
   627   \emph{Abelian}.
       
   628 *}
   380 
   629 
   381 subsection {* Definition *}
   630 subsection {* Definition *}
   382 
   631 
   383 locale abelian_semigroup = semigroup +
   632 locale comm_semigroup = semigroup +
   384   assumes m_comm: "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<otimes> y = y \<otimes> x"
   633   assumes m_comm: "[| x \<in> carrier G; y \<in> carrier G |] ==> x \<otimes> y = y \<otimes> x"
   385 
   634 
   386 lemma (in abelian_semigroup) m_lcomm:
   635 lemma (in comm_semigroup) m_lcomm:
   387   "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
   636   "[| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
   388    x \<otimes> (y \<otimes> z) = y \<otimes> (x \<otimes> z)"
   637    x \<otimes> (y \<otimes> z) = y \<otimes> (x \<otimes> z)"
   389 proof -
   638 proof -
   390   assume xyz: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
   639   assume xyz: "x \<in> carrier G" "y \<in> carrier G" "z \<in> carrier G"
   391   from xyz have "x \<otimes> (y \<otimes> z) = (x \<otimes> y) \<otimes> z" by (simp add: m_assoc)
   640   from xyz have "x \<otimes> (y \<otimes> z) = (x \<otimes> y) \<otimes> z" by (simp add: m_assoc)
   392   also from xyz have "... = (y \<otimes> x) \<otimes> z" by (simp add: m_comm)
   641   also from xyz have "... = (y \<otimes> x) \<otimes> z" by (simp add: m_comm)
   393   also from xyz have "... = y \<otimes> (x \<otimes> z)" by (simp add: m_assoc)
   642   also from xyz have "... = y \<otimes> (x \<otimes> z)" by (simp add: m_assoc)
   394   finally show ?thesis .
   643   finally show ?thesis .
   395 qed
   644 qed
   396 
   645 
   397 lemmas (in abelian_semigroup) ac = m_assoc m_comm m_lcomm
   646 lemmas (in comm_semigroup) m_ac = m_assoc m_comm m_lcomm
   398 
   647 
   399 locale abelian_monoid = abelian_semigroup + l_one
   648 locale comm_monoid = comm_semigroup + monoid
   400 
   649 
   401 lemma (in abelian_monoid) l_one [simp]:
   650 lemma comm_monoidI:
       
   651   assumes m_closed:
       
   652       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y \<in> carrier G"
       
   653     and one_closed: "one G \<in> carrier G"
       
   654     and m_assoc:
       
   655       "!!x y z. [| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
       
   656       mult G (mult G x y) z = mult G x (mult G y z)"
       
   657     and l_one: "!!x. x \<in> carrier G ==> mult G (one G) x = x"
       
   658     and m_comm:
       
   659       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y = mult G y x"
       
   660   shows "comm_monoid G"
       
   661   using l_one
       
   662   by (auto intro!: comm_monoid.intro magma.intro semigroup_axioms.intro
       
   663     comm_semigroup_axioms.intro monoid_axioms.intro
       
   664     intro: prems simp: m_closed one_closed m_comm)
       
   665 
       
   666 lemma (in monoid) monoid_comm_monoidI:
       
   667   assumes m_comm:
       
   668       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y = mult G y x"
       
   669   shows "comm_monoid G"
       
   670   by (rule comm_monoidI) (auto intro: m_assoc m_comm)
       
   671 (*
       
   672 lemma (in comm_monoid) r_one [simp]:
   402   "x \<in> carrier G ==> x \<otimes> \<one> = x"
   673   "x \<in> carrier G ==> x \<otimes> \<one> = x"
   403 proof -
   674 proof -
   404   assume G: "x \<in> carrier G"
   675   assume G: "x \<in> carrier G"
   405   then have "x \<otimes> \<one> = \<one> \<otimes> x" by (simp add: m_comm)
   676   then have "x \<otimes> \<one> = \<one> \<otimes> x" by (simp add: m_comm)
   406   also from G have "... = x" by simp
   677   also from G have "... = x" by simp
   407   finally show ?thesis .
   678   finally show ?thesis .
   408 qed
   679 qed
   409 
   680 *)
   410 locale abelian_group = abelian_monoid + group
   681 
   411 
   682 lemma (in comm_monoid) nat_pow_distr:
   412 lemma (in abelian_group) inv_mult:
   683   "[| x \<in> carrier G; y \<in> carrier G |] ==>
       
   684   (x \<otimes> y) (^) (n::nat) = x (^) n \<otimes> y (^) n"
       
   685   by (induct n) (simp, simp add: m_ac)
       
   686 
       
   687 locale comm_group = comm_monoid + group
       
   688 
       
   689 lemma (in group) group_comm_groupI:
       
   690   assumes m_comm: "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==>
       
   691       mult G x y = mult G y x"
       
   692   shows "comm_group G"
       
   693   by (fast intro: comm_group.intro comm_semigroup_axioms.intro
       
   694     group.axioms prems)
       
   695 
       
   696 lemma comm_groupI:
       
   697   assumes m_closed:
       
   698       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y \<in> carrier G"
       
   699     and one_closed: "one G \<in> carrier G"
       
   700     and m_assoc:
       
   701       "!!x y z. [| x \<in> carrier G; y \<in> carrier G; z \<in> carrier G |] ==>
       
   702       mult G (mult G x y) z = mult G x (mult G y z)"
       
   703     and m_comm:
       
   704       "!!x y. [| x \<in> carrier G; y \<in> carrier G |] ==> mult G x y = mult G y x"
       
   705     and l_one: "!!x. x \<in> carrier G ==> mult G (one G) x = x"
       
   706     and l_inv_ex: "!!x. x \<in> carrier G ==> EX y : carrier G. mult G y x = one G"
       
   707   shows "comm_group G"
       
   708   by (fast intro: group.group_comm_groupI groupI prems)
       
   709 
       
   710 lemma (in comm_group) inv_mult:
   413   "[| x \<in> carrier G; y \<in> carrier G |] ==> inv (x \<otimes> y) = inv x \<otimes> inv y"
   711   "[| x \<in> carrier G; y \<in> carrier G |] ==> inv (x \<otimes> y) = inv x \<otimes> inv y"
   414   by (simp add: ac inv_mult_group)
   712   by (simp add: m_ac inv_mult_group)
   415 
   713 
   416 end
   714 end