Theory Group_ZF

(* 
This file is a part of IsarMathLib - 
a library of formalized mathematics for Isabelle/Isar.

Copyright (C) 2005 - 2008  Slawomir Kolodynski

This program is free software; Redistribution and use in source and binary forms, 
with or without modification, are permitted provided that the 
following conditions are met:

1. Redistributions of source code must retain the above copyright notice, 
   this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright notice, 
   this list of conditions and the following disclaimer in the documentation and/or 
   other materials provided with the distribution.
   3. The name of the author may not be used to endorse or promote products 
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*)

section Groups - introduction

theory Group_ZF imports Monoid_ZF

begin

textThis theory file covers basics of group theory.

subsectionDefinition and basic properties of groups

textIn this section we define the notion of a group and set up the 
   notation for discussing groups. We prove some basic theorems about
   groups.

textTo define a group we take a monoid and add a requirement 
  that the right inverse needs to exist for every element of the group.
  
definition
  "IsAgroup(G,f)  
  (IsAmonoid(G,f)  (gG. bG. f`g,b = TheNeutralElement(G,f)))"

textWe define the group inverse as the set
  $\{\langle x,y \rangle \in G\times G: x\cdot y = e \}$, where $e$ is the
  neutral element of the group. This set (which can be written as 
  $(\cdot)^{-1}\{ e\}$) is a certain relation on the group (carrier). 
  Since, as we show later, for every $x\in G$ there is exactly one $y\in G$
  such that $x \cdot y = e$  this relation is in fact a function from $G$ to $G$.

definition
  "GroupInv(G,f)  {x,y  G×G. f`x,y = TheNeutralElement(G,f)}"

textWe will use the miltiplicative notation for groups. The neutral
  element is denoted $1$.

locale group0 =
  fixes G 
  fixes P
  assumes groupAssum: "IsAgroup(G,P)"

  fixes neut ("𝟭")
  defines neut_def[simp]: "𝟭  TheNeutralElement(G,P)"
  
  fixes groper (infixl "" 70)
  defines groper_def[simp]: "a  b  P`a,b"
  
  fixes inv ("_¯ " [90] 91)
  defines inv_def[simp]: "x¯  GroupInv(G,P)`(x)"

textFirst we show a lemma that says that we can use theorems proven in
  the monoid0› context (locale).

lemma (in group0) group0_2_L1: shows "monoid0(G,P)"
  using groupAssum IsAgroup_def monoid0_def by simp

textThe theorems proven in the monoid› context are valid in the group0› context.

sublocale group0 < monoid: monoid0 G P groper
  unfolding groper_def using group0_2_L1 by auto

textIn some strange cases Isabelle has difficulties with applying
  the definition of a group. The next lemma defines a rule to be applied
  in such cases.

lemma definition_of_group: assumes "IsAmonoid(G,f)" 
  and "gG. bG. f`g,b = TheNeutralElement(G,f)"
  shows "IsAgroup(G,f)" 
  using assms IsAgroup_def by simp

textA technical lemma that allows to use $1$ as the neutral element of 
  the group without referencing a list of lemmas and definitions.

lemma (in group0) group0_2_L2: 
  shows "𝟭G  (gG.(𝟭g = g  g𝟭 = g))"
  using group0_2_L1 monoid.unit_is_neutral by simp

textThe group is closed under the group operation. Used all the time,
  useful to have handy.

lemma (in group0) group_op_closed: assumes "aG"  "bG"
  shows "ab  G" using assms monoid.group0_1_L1 
  by simp

textThe group operation is associative. This is another technical lemma 
  that allows to shorten the list of referenced lemmas in some proofs.

lemma (in group0) group_oper_assoc: 
  assumes "aG"  "bG"  "cG" shows "a(bc) = abc"
  using groupAssum assms IsAgroup_def IsAmonoid_def 
    IsAssociative_def group_op_closed by simp

textThe group operation maps $G\times G$ into $G$. It is conveniet to have
  this fact easily accessible in the group0› context.

lemma (in group0) group_oper_fun: shows "P : G×GG"
  using groupAssum IsAgroup_def IsAmonoid_def IsAssociative_def
  by simp
  
textThe definition of a group requires the existence of the right inverse.
  We show that this is also the left inverse.

theorem (in group0) group0_2_T1: 
  assumes A1: "gG" and A2: "bG" and A3: "gb = 𝟭"
  shows "bg = 𝟭"
proof -
  from A2 groupAssum obtain c where I: "c  G  bc = 𝟭" 
    using IsAgroup_def by auto
  then have "cG" by simp
  have "𝟭G" using group0_2_L2 by simp
  with A1 A2 I have "bg =  b(g(bc))"
    using group_op_closed group0_2_L2 group_oper_assoc 
    by simp
  also from  A1 A2 cG have "b(g(bc)) = b(gbc)"
    using group_oper_assoc by simp
  also from A3 A2 I have "b(gbc)= 𝟭" using group0_2_L2 by simp
  finally show "bg = 𝟭" by simp
qed

textFor every element of a group there is only one inverse.

lemma (in group0) group0_2_L4: 
  assumes A1: "xG" shows "∃!y. yG  xy = 𝟭"
proof
  from A1 groupAssum show "y. yG   xy = 𝟭" 
    using IsAgroup_def by auto
  fix y n
  assume A2: "yG   xy = 𝟭" and A3:"nG  xn = 𝟭" show "y=n"
  proof -
    from A1 A2 have T1: "yx = 𝟭"
      using group0_2_T1 by simp
    from A2 A3 have "y = y(xn)" 
      using group0_2_L2 by simp
    also from A1 A2 A3 have " = (yx)n" 
      using group_oper_assoc by blast
    also from T1 A3 have " = n" 
      using group0_2_L2 by simp
    finally show "y=n" by simp
  qed
qed

textThe group inverse is a function that maps G into G.

theorem group0_2_T2: 
  assumes A1: "IsAgroup(G,f)" shows "GroupInv(G,f) : GG"
proof -
  have "GroupInv(G,f)  G×G" using GroupInv_def by auto
  moreover from A1 have
    "xG. ∃!y. yG  x,y  GroupInv(G,f)"
    using group0_def group0.group0_2_L4 GroupInv_def by simp
  ultimately show ?thesis using func1_1_L11 by simp
qed

textWe can think about the group inverse (the function) 
  as the inverse image of the neutral element. Recall that
  in Isabelle f-``(A)› denotes the inverse image of
  the set $A$.

theorem (in group0) group0_2_T3: shows "P-``{𝟭} = GroupInv(G,P)"
proof -
  from groupAssum have "P : G×G  G" 
    using IsAgroup_def IsAmonoid_def IsAssociative_def 
    by simp
  then show "P-``{𝟭} = GroupInv(G,P)"
    using func1_1_L14 GroupInv_def by auto
qed

textThe inverse is in the group.

lemma (in group0) inverse_in_group: assumes A1: "xG" shows "x¯G"
proof -
  from groupAssum have "GroupInv(G,P) : GG" using group0_2_T2 by simp
  with A1 show ?thesis using apply_type by simp
qed

textThe notation for the inverse means what it is supposed to mean.

lemma (in group0) group0_2_L6: 
  assumes A1: "xG" shows "xx¯ = 𝟭  x¯x = 𝟭"
proof
  from groupAssum have "GroupInv(G,P) : GG" 
    using group0_2_T2 by simp 
  with A1 have "x,x¯   GroupInv(G,P)" 
    using apply_Pair by simp
  then show "xx¯ = 𝟭" using GroupInv_def by simp
  with A1 show "x¯x = 𝟭" using inverse_in_group group0_2_T1 
    by blast 
qed

textThe next two lemmas state that unless we multiply by 
  the neutral element, the result is always 
  different than any of the operands.

lemma (in group0) group0_2_L7: 
  assumes A1: "aG" and A2: "bG" and A3: "ab = a"
  shows "b=𝟭"
proof -
  from A3 have "a¯  (ab) = a¯a" by simp
  with A1 A2 show ?thesis using
    inverse_in_group group_oper_assoc group0_2_L6 group0_2_L2
    by simp
qed

textSee the comment to group0_2_L7›.

lemma (in group0) group0_2_L8: 
  assumes A1: "aG" and A2: "bG" and A3: "ab = b"
  shows "a=𝟭"
proof -
  from A3 have "(ab)b¯  = bb¯" by simp
  with A1 A2 have "a(bb¯)  = bb¯" using
    inverse_in_group group_oper_assoc by simp
  with A1 A2 show ?thesis 
    using group0_2_L6 group0_2_L2 by simp
qed

textThe inverse of the neutral element is the neutral element.

lemma (in group0) group_inv_of_one: shows "𝟭¯ = 𝟭"
  using group0_2_L2 inverse_in_group group0_2_L6 group0_2_L7 by blast

textif $a^{-1} = 1$, then $a=1$.

lemma (in group0) group0_2_L8A:  
  assumes A1: "aG" and A2: "a¯ = 𝟭"
  shows "a = 𝟭"
proof -
  from A1 have "aa¯ = 𝟭" using group0_2_L6 by simp
  with A1 A2 show "a = 𝟭" using group0_2_L2 by simp
qed

textIf $a$ is not a unit, then its inverse is not a unit either.

lemma (in group0) group0_2_L8B:
  assumes "aG" and "a  𝟭"
  shows "a¯  𝟭" using assms group0_2_L8A by auto

textIf $a^{-1}$ is not a unit, then a is not a unit either.

lemma (in group0) group0_2_L8C:
  assumes "aG" and "a¯  𝟭"
  shows "a𝟭"
  using assms group0_2_L8A group_inv_of_one by auto

textIf a product of two elements of a group is equal to the neutral
element then they are inverses of each other.

lemma (in group0) group0_2_L9: 
  assumes A1: "aG" and A2: "bG" and A3: "ab = 𝟭" 
  shows "a = b¯" and "b = a¯"
proof -
  from A3 have "abb¯ = 𝟭b¯" by simp 
  with A1 A2 have "a(bb¯) = 𝟭b¯" using
    inverse_in_group group_oper_assoc by simp
  with A1 A2 show "a = b¯" using
    group0_2_L6 inverse_in_group group0_2_L2 by simp
  from A3 have "a¯(ab) = a¯𝟭" by simp
  with A1 A2 show "b = a¯" using 
    inverse_in_group group_oper_assoc group0_2_L6 group0_2_L2
    by simp
qed

textIt happens quite often that we know what is (have a meta-function for) 
  the right inverse in a group. The next lemma shows that the value 
  of the group inverse (function) is equal to the right inverse 
  (meta-function).

lemma (in group0) group0_2_L9A: 
  assumes A1: "gG. b(g)  G  gb(g) = 𝟭"
  shows "gG. b(g) = g¯"
proof
  fix g assume "gG"
  moreover from A1 gG have "b(g)  G" by simp
  moreover from A1 gG have "gb(g) = 𝟭" by simp
  ultimately show "b(g) = g¯" by (rule group0_2_L9)
qed
 
textWhat is the inverse of a product?

lemma (in group0) group_inv_of_two:
  assumes A1: "aG" and A2: "bG" 
  shows " b¯a¯ = (ab)¯"
proof -
  from A1 A2 have 
    "b¯G"  "a¯G"  "abG"  "b¯a¯  G"
    using inverse_in_group group_op_closed 
    by auto
  from A1 A2 b¯a¯  G  have "ab(b¯a¯) = a(b(b¯a¯))"
    using group_oper_assoc by simp
  moreover from A2 b¯G a¯G have "b(b¯a¯) = bb¯a¯"
    using group_oper_assoc by simp
  moreover from A2 a¯G have "bb¯a¯ = a¯"
     using group0_2_L6 group0_2_L2 by simp
  ultimately have "ab(b¯a¯) = aa¯"
    by simp
  with A1 have "ab(b¯a¯) = 𝟭"
    using group0_2_L6 by simp
  with ab  G  b¯a¯  G show "b¯a¯ = (ab)¯"
    using group0_2_L9 by simp
qed

textWhat is the inverse of a product of three elements?

lemma (in group0) group_inv_of_three:
  assumes A1: "aG"  "bG"  "cG"
  shows
  "(abc)¯ = c¯(ab)¯"
  "(abc)¯ = c¯(b¯a¯)"
  "(abc)¯ = c¯b¯a¯"
proof -
  from A1 have T: 
    "ab  G"  "a¯  G"  "b¯  G"   "c¯  G"  
    using group_op_closed inverse_in_group by auto
  with A1 show 
    "(abc)¯ = c¯(ab)¯" and "(abc)¯ = c¯(b¯a¯)"
     using group_inv_of_two by auto
   with T show "(abc)¯ = c¯b¯a¯" using group_oper_assoc
     by simp
qed

textThe inverse of the inverse is the element.

lemma (in group0) group_inv_of_inv:
  assumes "aG" shows "a = (a¯)¯"
  using assms inverse_in_group group0_2_L6 group0_2_L9 
  by simp

textGroup inverse is nilpotent, therefore a bijection and involution.

lemma (in group0) group_inv_bij: 
  shows "GroupInv(G,P) O GroupInv(G,P) = id(G)" and "GroupInv(G,P)  bij(G,G)" and
  "GroupInv(G,P) = converse(GroupInv(G,P))"
proof -
  have I: "GroupInv(G,P): GG" using groupAssum group0_2_T2 by simp
  then have "GroupInv(G,P) O GroupInv(G,P): GG" and "id(G):GG"
    using comp_fun id_type by auto
  moreover 
  { fix g assume "gG"
    with I have "(GroupInv(G,P) O GroupInv(G,P))`(g) = id(G)`(g)"
      using comp_fun_apply group_inv_of_inv id_conv by simp
  } hence "gG. (GroupInv(G,P) O GroupInv(G,P))`(g) = id(G)`(g)" by simp
  ultimately show "GroupInv(G,P) O GroupInv(G,P) = id(G)"
    by (rule func_eq)
  with I show "GroupInv(G,P)  bij(G,G)" using nilpotent_imp_bijective
    by simp
  with GroupInv(G,P) O GroupInv(G,P) = id(G) show
    "GroupInv(G,P) = converse(GroupInv(G,P))" using comp_id_conv by simp
qed

textA set comprehension form of the image of a set under the group inverse. 

lemma (in group0) ginv_image: assumes "VG" 
  shows "GroupInv(G,P)``(V)  G" and "GroupInv(G,P)``(V) = {g¯. g  V}"  
proof -
  from assms have I: "GroupInv(G,P)``(V) = {GroupInv(G,P)`(g). gV}" 
    using groupAssum group0_2_T2 func_imagedef by blast 
  thus "GroupInv(G,P)``(V) = {g¯. g  V}"  by simp
  show "GroupInv(G,P)``(V)  G" using groupAssum group0_2_T2 func1_1_L6(2) by blast
qed

textInverse of an element that belongs to the inverse of the set belongs to the set. 

lemma (in group0) ginv_image_el: assumes "VG" "g  GroupInv(G,P)``(V)"
  shows "g¯  V"
  using assms ginv_image group_inv_of_inv by auto 

textFor the group inverse the image is the same as inverse image.

lemma (in group0) inv_image_vimage: shows "GroupInv(G,P)``(V) = GroupInv(G,P)-``(V)"
  using group_inv_bij vimage_converse by simp

textIf the unit is in a set then it is in the inverse of that set.

lemma (in group0) neut_inv_neut: assumes "AG" and "𝟭A"
  shows "𝟭  GroupInv(G,P)``(A)"
proof -
  have "GroupInv(G,P):GG" using groupAssum group0_2_T2 by simp
  with assms have "𝟭¯  GroupInv(G,P)``(A)" using func_imagedef by auto
  then show ?thesis using group_inv_of_one by simp
qed

textThe group inverse is onto.

lemma (in group0) group_inv_surj: shows "GroupInv(G,P)``(G) = G"
  using group_inv_bij bij_def surj_range_image_domain by auto

textIf $a^{-1}\cdot b=1$, then $a=b$.

lemma (in group0) group0_2_L11:
  assumes A1: "aG"  "bG" and A2: "a¯b = 𝟭"
  shows "a=b"
proof -
  from A1 A2 have "a¯  G"  "bG"  "a¯b = 𝟭" 
    using inverse_in_group by auto
  then have "b = (a¯)¯" by (rule group0_2_L9)
  with A1 show "a=b" using group_inv_of_inv by simp
qed

textIf $a\cdot b^{-1}=1$, then $a=b$.

lemma (in group0) group0_2_L11A: 
  assumes A1: "aG"  "bG" and A2: "ab¯ = 𝟭"
  shows "a=b"
proof -
  from A1 A2 have "a  G"  "b¯G"  "ab¯ = 𝟭"
    using inverse_in_group by auto
  then have "a = (b¯)¯" by (rule group0_2_L9)
  with A1 show "a=b" using group_inv_of_inv by simp
qed

textIf if the inverse of $b$ is different than $a$, then the
  inverse of $a$ is different than $b$.

lemma (in group0) group0_2_L11B:
  assumes A1: "aG" and A2: "b¯  a"
  shows "a¯  b"
proof -
  { assume "a¯ = b"
    then have "(a¯)¯ = b¯" by simp
    with A1 A2 have False using group_inv_of_inv
      by simp
  } then show "a¯  b" by auto
qed

textWhat is the inverse of $ab^{-1}$ ?

lemma (in group0) group0_2_L12:
  assumes A1: "aG"  "bG" 
  shows 
  "(ab¯)¯ = ba¯"
  "(a¯b)¯ = b¯a"
proof -
  from A1 have 
    "(ab¯)¯ = (b¯)¯ a¯" and "(a¯b)¯ = b¯(a¯)¯"
    using inverse_in_group group_inv_of_two by auto
  with A1 show  "(ab¯)¯ = ba¯"  "(a¯b)¯ = b¯a"
    using group_inv_of_inv by auto
qed

textA couple useful rearrangements with three elements: 
  we can insert a $b\cdot b^{-1}$ 
  between two group elements (another version) and one about a product of 
  an element and inverse of a product, and two others.

lemma (in group0) group0_2_L14A:
  assumes A1: "aG"  "bG"  "cG"
  shows 
  "ac¯= (ab¯)(bc¯)"
  "a¯c = (a¯b)(b¯c)"
  "a(bc)¯ = ac¯b¯"
  "a(bc¯) = abc¯"
  "(ab¯c¯)¯ = cba¯"
  "abc¯(cb¯) = a"
  "a(bc)c¯ = ab"
proof -
  from A1 have T: 
    "a¯  G"  "b¯G"  "c¯G"  
    "a¯b  G"  "ab¯  G"  "ab  G"  
    "cb¯  G"  "bc  G"
    using inverse_in_group group_op_closed
    by auto
   from A1 T have 
     "ac¯ =  a(b¯b)c¯"
     "a¯c =  a¯(bb¯)c"
    using group0_2_L2 group0_2_L6 by auto
   with A1 T show 
     "ac¯= (ab¯)(bc¯)"
     "a¯c = (a¯b)(b¯c)"
     using group_oper_assoc by auto
  from A1 have "a(bc)¯ = a(c¯b¯)"
    using group_inv_of_two by simp
  with A1 T show "a(bc)¯ =ac¯b¯" 
    using group_oper_assoc by simp
  from A1 T show "a(bc¯) = abc¯"
    using group_oper_assoc by simp
  from A1 T show  "(ab¯c¯)¯ = cba¯"
    using group_inv_of_three  group_inv_of_inv
    by simp
  from T have "abc¯(cb¯) = ab(c¯(cb¯))"
    using group_oper_assoc by simp
  also from A1 T have " =  abb¯"
    using group_oper_assoc group0_2_L6 group0_2_L2
    by simp
  also from A1 T have " = a(bb¯)"
    using group_oper_assoc by simp
  also from A1 have " = a"
    using group0_2_L6 group0_2_L2 by simp
  finally show "abc¯(cb¯) = a" by simp
  from A1 T have "a(bc)c¯ =  a(b(cc¯))"
    using group_oper_assoc by simp
  also from A1 T have " = ab"
    using  group0_2_L6 group0_2_L2 by simp
  finally show "a(bc)c¯ = ab"
    by simp
qed

text A simple equation to solve 

lemma (in group0) simple_equation0: 
  assumes "aG"  "bG" "cG" "ab¯ = c¯"
  shows "c = ba¯" 
proof - 
  from assms(4) have "(ab¯)¯ = (c¯)¯" by simp
  with assms(1,2,3) show "c = ba¯" using group0_2_L12(1) group_inv_of_inv by simp
qed

text Another simple equation 

lemma (in group0) simple_equation1: 
  assumes "aG"  "bG" "cG" "a¯b = c¯"
  shows "c = b¯a" 
proof - 
  from assms(4) have "(a¯b)¯ = (c¯)¯" by simp
  with assms(1,2,3) show "c = b¯a" using group0_2_L12(2) group_inv_of_inv by simp
qed
     
textAnother lemma about rearranging a product of four group
  elements.

lemma (in group0) group0_2_L15:
  assumes A1: "aG"  "bG"  "cG"  "dG"
  shows "(ab)(cd)¯ = a(bd¯)a¯(ac¯)"
proof -
  from A1 have T1:
    "d¯G"  "c¯G" "abG" "a(bd¯)G"
    using inverse_in_group group_op_closed
    by auto
  with A1 have "(ab)(cd)¯ = (ab)(d¯c¯)"
    using group_inv_of_two by simp
  also from A1 T1 have " = a(bd¯)c¯"
    using group_oper_assoc by simp
  also from A1 T1 have " = a(bd¯)a¯(ac¯)"
    using group0_2_L14A by blast
  finally show ?thesis by simp
qed

textWe can cancel an element with its inverse that is written next to it.

lemma (in group0) inv_cancel_two:
  assumes A1: "aG"  "bG"
  shows 
  "ab¯b = a"  
  "abb¯ = a"
  "a¯(ab) = b"
  "a(a¯b) = b"
proof -
  from A1 have 
    "ab¯b = a(b¯b)"   "abb¯ = a(bb¯)"
    "a¯(ab) = a¯ab"   "a(a¯b) = aa¯b"
    using inverse_in_group group_oper_assoc by auto
  with A1 show
    "ab¯b = a"
    "abb¯ = a"
    "a¯(ab) = b"
    "a(a¯b) = b"
    using group0_2_L6 group0_2_L2 by auto
qed

textAnother lemma about cancelling with two group elements.

lemma (in group0) group0_2_L16A:
  assumes A1: "aG"  "bG"
  shows "a(ba)¯ = b¯"
proof -
  from A1 have "(ba)¯ = a¯b¯"  "b¯  G"
    using group_inv_of_two inverse_in_group by auto
  with A1 show "a(ba)¯ = b¯" using inv_cancel_two
    by simp
qed

text Some other identities with three element and cancelling. 

lemma (in group0) cancel_middle:
  assumes "aG"  "bG" "cG"
  shows 
    "(ab)¯(ac) = b¯c"
    "(ab)(cb)¯ = ac¯"
    "a¯(abc)c¯ = b"
    "a(bc¯)c = ab"
    "ab¯(bc¯) = ac¯"
proof -
  from assms have "(ab)¯(ac) = b¯(a¯(ac))"
    using group_inv_of_two inverse_in_group group_oper_assoc group_op_closed by auto
  with assms(1,3) show "(ab)¯(ac) = b¯c" using inv_cancel_two(3) by simp
  from assms have "(ab)(cb)¯ = a(b(b¯c¯))"
    using group_inv_of_two inverse_in_group group_oper_assoc group_op_closed by auto
  with assms show "(ab)(cb)¯ =ac¯" using inverse_in_group inv_cancel_two(4) by simp
  from assms have "a¯(abc)c¯ = (a¯a)b(cc¯)" 
    using inverse_in_group group_oper_assoc group_op_closed by auto
  with assms show "a¯(abc)c¯ = b" using group0_2_L6 group0_2_L2 by simp
  from assms have "a(bc¯)c = ab(c¯c)" using inverse_in_group group_oper_assoc group_op_closed
    by simp
  with assms show "a(bc¯)c = ab" using group_op_closed group0_2_L6 group0_2_L2 by simp
  from assms have "ab¯(bc¯) = a(b¯b)c¯" using inverse_in_group group_oper_assoc group_op_closed
    by simp
  with assms  show "ab¯(bc¯) = ac¯" using group0_2_L6 group0_2_L2 by simp
qed

textAdding a neutral element to a set that is 
  closed under the group operation results in a set that is closed under the 
  group operation.

lemma (in group0) group0_2_L17: 
  assumes "HG"
  and "H {is closed under} P"
  shows "(H  {𝟭}) {is closed under} P"
  using assms IsOpClosed_def group0_2_L2 by auto

textWe can put an element on the other side of an equation.

lemma (in group0) group0_2_L18:
  assumes A1: "aG"  "bG"
  and A2: "c = ab"
  shows "cb¯ = a"  "a¯c = b" 
proof-
  from A2 A1 have "cb¯ =  a(bb¯)"  "a¯c = (a¯a)b"
    using inverse_in_group group_oper_assoc by auto
  moreover from A1 have "a(bb¯) = a"  "(a¯a)b = b"
    using group0_2_L6 group0_2_L2 by auto
  ultimately show "cb¯ = a"  "a¯c = b" 
    by auto
qed

text We can cancel an element on the right from both sides of an equation. 

lemma (in group0) cancel_right: assumes "aG"  "bG"  "cG" "ab = cb"
  shows "a = c" 
proof -
  from assms(4) have "abb¯ = cbb¯" by simp
  with assms(1,2,3) show ?thesis using inv_cancel_two(2) by simp
qed

text We can cancel an element on the left from both sides of an equation. 

lemma (in group0) cancel_left: assumes "aG"  "bG"  "cG" "ab = ac"
  shows "b=c"
proof -
  from assms(4) have "a¯(ab) = a¯(ac)" by simp
  with assms(1,2,3) show ?thesis using inv_cancel_two(3) by simp
qed

textMultiplying different group elements by the same factor results
  in different group elements.

lemma (in group0) group0_2_L19: 
  assumes A1: "aG"  "bG"  "cG" and A2: "ab"
  shows "ac  bc" and "ca  cb"
proof -
  { assume "ac = bc  ca =cb"
    then have "acc¯ = bcc¯  c¯(ca) = c¯(cb)"
      by auto
    with A1 A2 have False using inv_cancel_two by simp
  } then show "ac  bc" and "ca  cb" by auto
qed

subsectionSubgroups

textThere are two common ways to define subgroups. One requires that the
  group operation is closed in the subgroup. The second one defines subgroup 
  as a subset of a group which is itself a group under the group operations.
  We use the second approach because it results in shorter definition. 
  
  The rest of this section is devoted to proving the equivalence of these two
  definitions of the notion of a subgroup. 


textA pair $(H,P)$ is a subgroup if $H$ forms a group with the 
  operation $P$ restricted to $H\times H$. It may be surprising that 
  we don't require $H$ to be a subset of $G$. This however can be inferred
  from the definition if the pair $(G,P)$ is a group, 
  see lemma group0_3_L2›.

definition
  "IsAsubgroup(H,P)  IsAgroup(H, restrict(P,H×H))"

textThe group is its own subgroup.

lemma (in group0) group_self_subgroup: shows "IsAsubgroup(G,P)"
  using groupAssum group_oper_fun restrict_domain
  unfolding IsAsubgroup_def by simp
 
textFormally the group operation in a subgroup is different than in the
  group as they have different domains. Of course we want to use the original 
  operation with the associated notation in the subgroup. The next couple of 
  lemmas will allow for that. 

  The next lemma states that the neutral element of 
  a subgroup is in the subgroup and it is 
  both right and left neutral there. The notation is very ugly because
  we don't want to introduce a separate notation for the subgroup operation.


lemma group0_3_L1: 
  assumes A1: "IsAsubgroup(H,f)"
  and A2: "n = TheNeutralElement(H,restrict(f,H×H))"
  shows "n  H"
  "hH. restrict(f,H×H)`n,h  = h"
  "hH. restrict(f,H×H)`h,n = h"
proof -
  let ?b = "restrict(f,H×H)"
  let ?e = "TheNeutralElement(H,restrict(f,H×H))"
  from A1 have "group0(H,?b)"
    using IsAsubgroup_def group0_def by simp
  then have I:
    "?e  H  (hH. (?b`?e,h  = h  ?b`h,?e = h))"
    by (rule group0.group0_2_L2)
  with A2 show "n  H" by simp
  from A2 I show "hH. ?b`n,h = h" and "hH. ?b`h,n = h"
    by auto
qed

textA subgroup is contained in the group.

lemma (in group0) group0_3_L2: 
  assumes A1: "IsAsubgroup(H,P)"
  shows "H  G"
proof
  fix h assume "hH"
  let ?b = "restrict(P,H×H)"
  let ?n = "TheNeutralElement(H,restrict(P,H×H))"
   from A1 have "?b  H×HH" 
    using IsAsubgroup_def IsAgroup_def 
      IsAmonoid_def IsAssociative_def by simp
  moreover from A1 hH have " ?n,h  H×H" 
    using group0_3_L1 by simp
  moreover from A1 hH have "h = ?b`?n,h " 
    using group0_3_L1 by simp
  ultimately have "?n,h,h  ?b" 
    using func1_1_L5A by blast
  then have "?n,h,h  P" using restrict_subset by auto
  moreover from groupAssum have "P:G×GG"
    using IsAgroup_def IsAmonoid_def IsAssociative_def 
    by simp
  ultimately show "hG" using func1_1_L5 
    by blast
qed

textThe group's neutral element (denoted $1$ in the group0 context)
  is a neutral element for the subgroup with respect to the group action.

lemma (in group0) group0_3_L3:
  assumes "IsAsubgroup(H,P)"
  shows "hH. 𝟭h = h  h𝟭 = h"
  using assms groupAssum group0_3_L2 group0_2_L2
  by auto

textThe neutral element of a subgroup is the same as that of the group.

lemma (in group0) group0_3_L4: assumes A1: "IsAsubgroup(H,P)"
  shows "TheNeutralElement(H,restrict(P,H×H)) = 𝟭"
proof -
  let ?n = "TheNeutralElement(H,restrict(P,H×H))"
  from A1 have "?n  H" using group0_3_L1 by simp
  with groupAssum A1 have "?nG" using  group0_3_L2 by auto
  with A1 ?n  H show ?thesis using 
     group0_3_L1 restrict_if group0_2_L7 by simp
qed

textThe neutral element of the group (denoted $1$ in the group0 context)
  belongs to every subgroup.

lemma (in group0) group0_3_L5: assumes A1: "IsAsubgroup(H,P)"
  shows "𝟭  H"
proof -
  from A1 show "𝟭H" using group0_3_L1 group0_3_L4 
    by fast
qed

textSubgroups are closed with respect to the group operation.

lemma (in group0) group0_3_L6: assumes A1: "IsAsubgroup(H,P)"
  and A2: "aH" "bH"
  shows "ab  H"
proof - 
  let ?f = "restrict(P,H×H)"
  from A1 have "monoid0(H,?f)" using
    IsAsubgroup_def IsAgroup_def monoid0_def by simp
  with A2 have "?f` (a,b)  H" using monoid0.group0_1_L1
    by blast
 with A2 show "ab  H" using restrict_if by simp
qed

textA preliminary lemma that we need to show that taking the inverse 
  in the subgroup is the same as taking the inverse
  in the group.

lemma group0_3_L7A: 
  assumes A1: "IsAgroup(G,f)" 
  and A2: "IsAsubgroup(H,f)" and A3: "g = restrict(f,H×H)"
  shows "GroupInv(G,f)  H×H = GroupInv(H,g)"
proof -
  let ?e = "TheNeutralElement(G,f)"
  let ?e1 = "TheNeutralElement(H,g)"
  from A1 have "group0(G,f)" using group0_def by simp
  from A2 A3 have "group0(H,g)" 
    using IsAsubgroup_def group0_def by simp
  from group0(G,f) A2 A3  have "GroupInv(G,f) = f-``{?e1}" 
    using group0.group0_3_L4 group0.group0_2_T3
    by simp
  moreover have "g-``{?e1} = f-``{?e1}  H×H"
  proof -
    from A1 have "f  G×GG" 
      using IsAgroup_def IsAmonoid_def IsAssociative_def 
      by simp
    moreover from A2 group0(G,f) have "H×H  G×G" 
      using group0.group0_3_L2 by auto
    ultimately show "g-``{?e1} = f-``{?e1}  H×H"
      using A3 func1_2_L1 by simp
  qed
  moreover from A3 group0(H,g) have "GroupInv(H,g) = g-``{?e1}" 
    using group0.group0_2_T3 by simp
  ultimately show ?thesis by simp
qed

textUsing the lemma above we can show the actual statement: 
  taking the inverse in the subgroup is the same as taking the inverse
  in the group.

theorem (in group0) group0_3_T1:
  assumes A1: "IsAsubgroup(H,P)" 
  and A2: "g = restrict(P,H×H)"
  shows "GroupInv(H,g) = restrict(GroupInv(G,P),H)"
proof -
  from groupAssum have "GroupInv(G,P) : GG" 
    using group0_2_T2 by simp
  moreover from A1 A2 have "GroupInv(H,g) : HH"
    using IsAsubgroup_def group0_2_T2 by simp
  moreover from A1 have "H  G" 
    using group0_3_L2 by simp
  moreover from groupAssum A1 A2 have 
    "GroupInv(G,P)  H×H = GroupInv(H,g)"
    using group0_3_L7A by simp
  ultimately show ?thesis
    using func1_2_L3 by simp
qed

textA sligtly weaker, but more convenient in applications,
  reformulation of the above theorem.

theorem (in group0) group0_3_T2: 
  assumes "IsAsubgroup(H,P)" 
  and "g = restrict(P,H×H)"
  shows "hH. GroupInv(H,g)`(h) = h¯"
  using assms group0_3_T1 restrict_if by simp

textSubgroups are closed with respect to taking the group inverse.

theorem (in group0) group0_3_T3A: 
  assumes A1: "IsAsubgroup(H,P)" and A2: "hH"
  shows "h¯ H"
proof -
  let ?g = "restrict(P,H×H)"
  from A1 have  "GroupInv(H,?g)  HH"
    using IsAsubgroup_def group0_2_T2 by simp
  with A2 have "GroupInv(H,?g)`(h)  H"
    using apply_type by simp
  with A1 A2 show "h¯ H" using group0_3_T2 by simp
qed

textThe next theorem states that a nonempty subset of 
  a group $G$ that is closed under the group operation and 
  taking the inverse is a subgroup of the group.

theorem (in group0) group0_3_T3:
  assumes A1: "H0"
  and A2: "HG"
  and A3: "H {is closed under} P"
  and A4: "xH. x¯  H"
  shows "IsAsubgroup(H,P)"
proof -
  let ?g = "restrict(P,H×H)"
  let ?n = "TheNeutralElement(H,?g)"
  from A3 have I: "xH.yH. xy  H"
    using IsOpClosed_def by simp
  from A1 obtain x where "xH" by auto
  with A4 I A2 have "𝟭H"
    using group0_2_L6 by blast
  with A3 A2 have T2: "IsAmonoid(H,?g)"
    using monoid.group0_1_T1
    by simp
  moreover have "hH.bH. ?g`h,b = ?n"
  proof
    fix h assume "hH"
    with A4 A2 have "hh¯ = 𝟭"
      using group0_2_L6 by auto
    moreover from groupAssum A2 A3 𝟭H have "𝟭 = ?n"
      using IsAgroup_def group0_1_L6 by auto
    moreover from A4 hH have "?g`h,h¯ = hh¯"
      using restrict_if by simp
    ultimately have "?g`h,h¯ = ?n" by simp
    with A4 hH show "bH. ?g`h,b = ?n" by auto
  qed
  ultimately show "IsAsubgroup(H,P)" using 
    IsAsubgroup_def IsAgroup_def by simp
qed

textThe singleton with the neutral element is a subgroup.

corollary (in group0) unit_singl_subgr:
  shows "IsAsubgroup({𝟭},P)"
  using group0_2_L2 group_inv_of_one group0_3_T3
  unfolding IsOpClosed_def 
  by auto

textIntersection of subgroups is a subgroup. This lemma is obsolete and should be replaced by 
  subgroup_inter›. 

lemma group0_3_L7:
  assumes A1: "IsAgroup(G,f)"
  and A2: "IsAsubgroup(H1,f)"
  and A3: "IsAsubgroup(H2,f)"
  shows "IsAsubgroup(H1H2,restrict(f,H1×H1))"
proof -
  let ?e = "TheNeutralElement(G,f)"
  let ?g = "restrict(f,H1×H1)"
  from A1 have I: "group0(G,f)"
    using group0_def by simp
  from A2 have "group0(H1,?g)"
    using IsAsubgroup_def group0_def by simp
  moreover have "H1H2  0"
  proof -
    from A1 A2 A3 have "?e  H1H2"
      using group0_def group0.group0_3_L5 by simp
    thus ?thesis by auto
  qed
  moreover have "H1H2  H1" by auto
  moreover from A2 A3 I H1H2  H1 have 
    "H1H2 {is closed under} ?g"
    using group0.group0_3_L6 IsOpClosed_def 
      func_ZF_4_L7 func_ZF_4_L5 by simp
  moreover from A2 A3 I have 
    "x  H1H2. GroupInv(H1,?g)`(x)  H1H2"
    using group0.group0_3_T2 group0.group0_3_T3A
    by simp
  ultimately show ?thesis
    using group0.group0_3_T3 by simp
qed

textIntersection of subgroups is a subgroup.

lemma (in group0) subgroup_inter: assumes "0"
  and "H. IsAsubgroup(H,P)"
  shows "IsAsubgroup(,P)"
proof -
  {
    fix H assume "H:"
    with assms(2) have "𝟭:H" using group0_3_L5 by auto
  }
  then have "  0" using assms(1) by auto moreover
  {
    fix t assume "t:"
    then have "H. t:H" by auto
    with assms have "t:G" using group0_3_L2 by blast
  }
  then have "  G" by auto moreover
  {
    fix x y assume xy:"x:" "y:"
    {
      fix J assume J:"J:"
      with xy have "x:J" "y:J" by auto
      with J have "P`x,y:J" using assms(2) group0_3_L6 by auto
    }
    then have "P`x,y:" using assms(1) by auto
  }
  then have " {is closed under} P" unfolding IsOpClosed_def by simp
  moreover
  {
    fix x assume x:"x:"
    {
      fix J assume J:"J:"
      with x have "x:J" by auto
      with J assms(2) have "x¯  J" using group0_3_T3A by auto
    }
    then have "x¯  " using assms(1) by auto
  }
  then have "x  . x¯  " by simp
  ultimately show ?thesis using group0_3_T3 by auto
qed

textThe range of the subgroup operation is the whole subgroup.

lemma image_subgr_op: assumes A1: "IsAsubgroup(H,P)"
  shows "restrict(P,H×H)``(H×H) = H"
proof -
  from A1 have "monoid0(H,restrict(P,H×H))"
    using IsAsubgroup_def IsAgroup_def monoid0_def 
    by simp
  then show ?thesis by (rule monoid0.range_carr)
qed

textIf we restrict the inverse to a subgroup, then the restricted 
  inverse is onto the subgroup.

lemma (in group0) restr_inv_onto: assumes A1: "IsAsubgroup(H,P)"
  shows "restrict(GroupInv(G,P),H)``(H) = H"
proof -
  from A1 have "GroupInv(H,restrict(P,H×H))``(H) = H"
    using IsAsubgroup_def group0_def group0.group_inv_surj
    by simp
  with A1 show ?thesis using group0_3_T1 by simp
qed

textA union of two subgroups is a subgroup iff 
  one of the subgroups is a subset of the other subgroup.

lemma (in group0) union_subgroups: 
  assumes "IsAsubgroup(H1,P)" and "IsAsubgroup(H2,P)"
  shows "IsAsubgroup(H1H2,P)  (H1H2  H2H1)"
proof 
  assume "H1H2  H2H1" show "IsAsubgroup(H1H2,P)"
  proof -
    from H1H2  H2H1 have "H2 = H1H2  H1 = H1H2" by auto
    with assms show "IsAsubgroup(H1H2,P)" by auto
  qed
next
  assume "IsAsubgroup(H1H2, P)" show "H1H2  H2H1"
  proof -
    { assume "¬ H1H2"
      then obtain x where "xH1" and "xH2" by auto
      with assms(1) have "x¯  H1" using group0_3_T3A by simp
      { fix y assume "yH2"
        let ?z = "xy"
        from xH1 yH2 have "x  H1H2" and "y  H1H2" by auto
        with IsAsubgroup(H1H2,P) have "?z  H1H2" using group0_3_L6 by blast
        from assms x  H1H2  yH2 have "xG" "yG" and "y¯H2"
          using group0_3_T3A group0_3_L2 by auto
        then have "?zy¯ = x" and "x¯?z = y" using inv_cancel_two(2,3) by auto
        { assume "?z  H2"
          with IsAsubgroup(H2,P) y¯H2 have "?zy¯  H2" using group0_3_L6 by simp
          with ?zy¯ = x xH2 have False by auto
        } hence "?z  H2" by auto
        with assms(1) x¯  H1 ?z  H1H2 have "x¯?z  H1" using group0_3_L6 by simp
        with x¯?z = y have "yH1" by simp
      } hence "H2H1" by blast
    } thus ?thesis by blast
  qed
qed

textTransitivity for "is a subgroup of" relation. The proof (probably) uses the lemma 
  restrict_restrict› from standard Isabelle/ZF library which states that 
  restrict(restrict(f,A),B) = restrict(f,A∩B)›. That lemma is added to the simplifier, so it does
  not have to be referenced explicitly in the proof below. 

lemma subgroup_transitive: 
  assumes "IsAgroup(G3,P)" "IsAsubgroup(G2,P)" "IsAsubgroup(G1,restrict(P,G2×G2))"
  shows "IsAsubgroup(G1,P)"
proof -
  from assms(2) have "group0(G2,restrict(P,G2×G2))" unfolding IsAsubgroup_def group0_def by simp
  with assms(3) have "G1G2" using group0.group0_3_L2 by simp
  hence "G2×G2  G1×G1 = G1×G1" by auto
  with assms(3) show "IsAsubgroup(G1,P)" unfolding IsAsubgroup_def by simp
qed

subsectionGroups vs. loops

textWe defined groups as monoids with the inverse operation. An alternative way of defining a group
  is as a loop whose operation is associative. 

text Groups have left and right division. 

lemma (in group0) gr_has_lr_div: shows "HasLeftDiv(G,P)" and "HasRightDiv(G,P)"
proof -
  { fix x y assume "xG" "yG" 
    then have "x¯y  G  x(x¯y) = y" using group_op_closed inverse_in_group inv_cancel_two(4)
      by simp
    hence "z. zG  xz =y" by auto
    moreover 
    { fix z1 z2 assume "z1G  xz1 =y" and "z2G  xz2 =y"
      with xG have "z1 = z2" using cancel_left by blast
    }
    ultimately have "∃!z. zG  xz =y" by auto
  } then show "HasLeftDiv(G,P)" unfolding HasLeftDiv_def by simp
  { fix x y assume "xG" "yG" 
    then have "yx¯  G  (yx¯)x = y" using group_op_closed inverse_in_group inv_cancel_two(1)
      by simp
    hence "z. zG  zx =y" by auto
    moreover 
    { fix z1 z2 assume "z1G  z1x =y" and "z2G  z2x =y"
      with xG have "z1 = z2" using cancel_right by blast
    }
    ultimately have "∃!z. zG  zx =y" by auto
  } then show "HasRightDiv(G,P)" unfolding HasRightDiv_def by simp
qed

textA group is a quasigroup and a loop.

lemma (in group0) group_is_loop: shows "IsAquasigroup(G,P)" and "IsAloop(G,P)"
proof -
  show "IsAquasigroup(G,P)" unfolding IsAquasigroup_def HasLatinSquareProp_def
    using gr_has_lr_div group_oper_fun by simp
  then show "IsAloop(G,P)" unfolding IsAloop_def using group0_2_L2 by auto
qed

text An associative loop is a group.

theorem assoc_loop_is_gr: assumes "IsAloop(G,P)" and "P {is associative on} G"
  shows "IsAgroup(G,P)" 
proof -
  from assms(1) have "eG. xG. P`e,x = x  P`x,e = x"
    unfolding IsAloop_def by simp
  with assms(2) have "IsAmonoid(G,P)" unfolding IsAmonoid_def by simp
  { fix x assume "xG" 
    let ?y = "RightInv(G,P)`(x)"
    from assms(1) xG have "?y  G" and "P`x,?y = TheNeutralElement(G,P)"
      using loop_loop0_valid loop0.lr_inv_props(3,4) by auto
    hence "yG. P`x,y = TheNeutralElement(G,P)" by auto
  }
  with IsAmonoid(G,P) show "IsAgroup(G,P)" unfolding IsAgroup_def by simp
qed

textFor groups the left and right inverse are the same as the group inverse. 

lemma (in group0) lr_inv_gr_inv: 
  shows "LeftInv(G,P) = GroupInv(G,P)" and "RightInv(G,P) = GroupInv(G,P)"
proof -
  have "LeftInv(G,P):GG" using group_is_loop loop_loop0_valid loop0.lr_inv_fun(1)
    by simp
  moreover from groupAssum have "GroupInv(G,P):GG" using group0_2_T2 by simp
  moreover
  { fix x assume "xG"
    let ?y = "LeftInv(G,P)`(x)"
    from xG have "?y  G" and "?yx = 𝟭"
      using group_is_loop(2) loop_loop0_valid loop0.lr_inv_props(1,2) by auto
    with xG have "LeftInv(G,P)`(x) = GroupInv(G,P)`(x)" using group0_2_L9(1) by simp
  }
  ultimately show "LeftInv(G,P) = GroupInv(G,P)" using func_eq by blast
  have "RightInv(G,P):GG" using group_is_loop loop_loop0_valid loop0.lr_inv_fun(2)
    by simp
  moreover from groupAssum have "GroupInv(G,P):GG" using group0_2_T2 by simp
  moreover
  { fix x assume "xG"
    let ?y = "RightInv(G,P)`(x)"
    from xG have "?y  G" and "x?y = 𝟭"
      using group_is_loop(2) loop_loop0_valid loop0.lr_inv_props(3,4) by auto
    with xG have "RightInv(G,P)`(x) = GroupInv(G,P)`(x)" using group0_2_L9(2) by simp
  }
  ultimately show "RightInv(G,P) = GroupInv(G,P)" using func_eq by blast  
qed


end