Theory FreeGroups
section ‹The Free Group›
theory "FreeGroups"
imports
"HOL-Algebra.Group"
Cancelation
Generators
begin
text ‹
Based on the work in @{theory "Free-Groups.Cancelation"}, the free group is now easily defined
over the set of fully canceled words with the corresponding operations.
›
subsection ‹Inversion›
text ‹
To define the inverse of a word, we first create a helper function that inverts
a single generator, and show that it is self-inverse.
›
definition inv1 :: "'a g_i ⇒ 'a g_i"
where "inv1 = apfst Not"
lemma inv1_inv1: "inv1 ∘ inv1 = id"
by (simp add: fun_eq_iff comp_def inv1_def)
lemmas inv1_inv1_simp [simp] = inv1_inv1[unfolded id_def]
lemma snd_inv1: "snd ∘ inv1 = snd"
by(simp add: fun_eq_iff comp_def inv1_def)
text ‹
The inverse of a word is obtained by reversing the order of the generators and
inverting each generator using @{term inv1}. Some properties of @{term inv_fg}
are noted.
›
definition inv_fg :: "'a word_g_i ⇒ 'a word_g_i"
where "inv_fg l = rev (map inv1 l)"
lemma cancelling_inf[simp]: "canceling (inv1 a) (inv1 b) = canceling a b"
by(simp add: canceling_def inv1_def)
lemma inv_idemp: "inv_fg (inv_fg l) = l"
by (auto simp add:inv_fg_def rev_map)
lemma inv_fg_cancel: "normalize (l @ inv_fg l) = []"
proof(induct l rule:rev_induct)
case Nil thus ?case
by (auto simp add: inv_fg_def)
next
case (snoc x xs)
have "canceling x (inv1 x)" by (simp add:inv1_def canceling_def)
moreover
let ?i = "length xs"
have "Suc ?i < length xs + 1 + 1 + length xs"
by auto
moreover
have "inv_fg (xs @ [x]) = [inv1 x] @ inv_fg xs"
by (auto simp add:inv_fg_def)
ultimately
have "cancels_to_1_at ?i (xs @ [x] @ (inv_fg (xs @ [x]))) (xs @ inv_fg xs)"
by (auto simp add:cancels_to_1_at_def cancel_at_def nth_append)
hence "cancels_to_1 (xs @ [x] @ (inv_fg (xs @ [x]))) (xs @ inv_fg xs)"
by (auto simp add: cancels_to_1_def)
hence "cancels_to (xs @ [x] @ (inv_fg (xs @ [x]))) (xs @ inv_fg xs)"
by (auto simp add:cancels_to_def)
with ‹normalize (xs @ (inv_fg xs)) = []›
show "normalize ((xs @ [x]) @ (inv_fg (xs @ [x]))) = []"
by auto
qed
lemma inv_fg_cancel2: "normalize (inv_fg l @ l) = []"
proof-
have "normalize (inv_fg l @ inv_fg (inv_fg l)) = []" by (rule inv_fg_cancel)
thus "normalize (inv_fg l @ l) = []" by (simp add: inv_idemp)
qed
lemma canceled_rev:
assumes "canceled l"
shows "canceled (rev l)"
proof(rule ccontr)
assume "¬canceled (rev l)"
hence "Domainp cancels_to_1 (rev l)" by (simp add: canceled_def)
then obtain l' where "cancels_to_1 (rev l) l'" by auto
then obtain i where "cancels_to_1_at i (rev l) l'" by (auto simp add:cancels_to_1_def)
hence "Suc i < length (rev l)"
and "canceling (rev l ! i) (rev l ! Suc i)"
by (auto simp add:cancels_to_1_at_def)
let ?x = "length l - i - 2"
from ‹Suc i < length (rev l)›
have "Suc ?x < length l" by auto
moreover
from ‹Suc i < length (rev l)›
have "i < length l" and "length l - Suc i = Suc(length l - Suc (Suc i))" by auto
hence "rev l ! i = l ! Suc ?x" and "rev l ! Suc i = l ! ?x"
by (auto simp add: rev_nth map_nth)
with ‹canceling (rev l ! i) (rev l ! Suc i)›
have "canceling (l ! Suc ?x) (l ! ?x)" by auto
hence "canceling (l ! ?x) (l ! Suc ?x)" by (rule cancel_sym)
hence "canceling (l ! ?x) (l ! Suc ?x)" by simp
ultimately
have "cancels_to_1_at ?x l (cancel_at ?x l)"
by (auto simp add:cancels_to_1_at_def)
hence "cancels_to_1 l (cancel_at ?x l)"
by (auto simp add:cancels_to_1_def)
hence "¬canceled l"
by (auto simp add:canceled_def)
with ‹canceled l› show False by contradiction
qed
lemma inv_fg_closure1:
assumes "canceled l"
shows "canceled (inv_fg l)"
unfolding inv_fg_def and inv1_def and apfst_def
proof-
have "inj Not" by (auto intro:injI)
moreover
have "inj_on id (snd ` set l)" by auto
ultimately
have "canceled (map (map_prod Not id) l)"
using ‹canceled l›
by -(rule rename_gens_canceled)
thus "canceled (rev (map (map_prod Not id) l))" by (rule canceled_rev)
qed
lemma inv_fg_closure2:
"l ∈ lists (UNIV × gens) ⟹ inv_fg l ∈ lists (UNIV × gens)"
by (auto iff:lists_eq_set simp add:inv1_def inv_fg_def)
subsection ‹The definition›
text ‹
Finally, we can define the Free Group over a set of generators, and show that it
is indeed a group.
›
definition free_group :: "'a set => ((bool * 'a) list) monoid" (‹ℱı›)
where
"ℱ⇘gens⇙ ≡ ⦇
carrier = {l∈lists (UNIV × gens). canceled l },
mult = λ x y. normalize (x @ y),
one = []
⦈"
lemma occuring_gens_in_element:
"x ∈ carrier ℱ⇘gens⇙ ⟹ x ∈ lists (UNIV × gens)"
by(auto simp add:free_group_def)
theorem free_group_is_group: "group ℱ⇘gens⇙"
proof
fix x y
assume "x ∈ carrier ℱ⇘gens⇙" hence x: "x ∈ lists (UNIV × gens)" by
(rule occuring_gens_in_element)
assume "y ∈ carrier ℱ⇘gens⇙" hence y: "y ∈ lists (UNIV × gens)" by
(rule occuring_gens_in_element)
from x and y
have "x ⊗⇘ℱ⇘gens⇙⇙ y ∈ lists (UNIV × gens)"
by (auto intro!: normalize_preserves_generators simp add:free_group_def append_in_lists_conv)
thus "x ⊗⇘ℱ⇘gens⇙⇙ y ∈ carrier ℱ⇘gens⇙"
by (auto simp add:free_group_def)
next
fix x y z
have "cancels_to (x @ y) (normalize (x @ (y::'a word_g_i)))"
and "cancels_to z (z::'a word_g_i)"
by auto
hence "normalize (normalize (x @ y) @ z) = normalize ((x @ y) @ z)"
by (rule normalize_append_cancel_to[THEN sym])
also
have "… = normalize (x @ (y @ z))" by auto
also
have "cancels_to (y @ z) (normalize (y @ (z::'a word_g_i)))"
and "cancels_to x (x::'a word_g_i)"
by auto
hence "normalize (x @ (y @ z)) = normalize (x @ normalize (y @ z))"
by -(rule normalize_append_cancel_to)
finally
show "x ⊗⇘ℱ⇘gens⇙⇙ y ⊗⇘ℱ⇘gens⇙⇙ z =
x ⊗⇘ℱ⇘gens⇙⇙ (y ⊗⇘ℱ⇘gens⇙⇙ z)"
by (auto simp add:free_group_def)
next
show "𝟭⇘ℱ⇘gens⇙⇙ ∈ carrier ℱ⇘gens⇙"
by (auto simp add:free_group_def)
next
fix x
assume "x ∈ carrier ℱ⇘gens⇙"
thus "𝟭⇘ℱ⇘gens⇙⇙ ⊗⇘ℱ⇘gens⇙⇙ x = x"
by (auto simp add:free_group_def)
next
fix x
assume "x ∈ carrier ℱ⇘gens⇙"
thus "x ⊗⇘ℱ⇘gens⇙⇙ 𝟭⇘ℱ⇘gens⇙⇙ = x"
by (auto simp add:free_group_def)
next
show "carrier ℱ⇘gens⇙ ⊆ Units ℱ⇘gens⇙"
proof (simp add:free_group_def Units_def, rule subsetI)
fix x :: "'a word_g_i"
let ?x' = "inv_fg x"
assume "x ∈ {y∈lists(UNIV×gens). canceled y}"
hence "?x' ∈ lists(UNIV×gens) ∧ canceled ?x'"
by (auto elim:inv_fg_closure1 simp add:inv_fg_closure2)
moreover
have "normalize (?x' @ x) = []"
and "normalize (x @ ?x') = []"
by (auto simp add:inv_fg_cancel inv_fg_cancel2)
ultimately
have "∃y. y ∈ lists (UNIV × gens) ∧
canceled y ∧
normalize (y @ x) = [] ∧ normalize (x @ y) = []"
by auto
with ‹x ∈ {y∈lists(UNIV×gens). canceled y}›
show "x ∈ {y ∈ lists (UNIV × gens). canceled y ∧
(∃x. x ∈ lists (UNIV × gens) ∧
canceled x ∧
normalize (x @ y) = [] ∧ normalize (y @ x) = [])}"
by auto
qed
qed
lemma inv_is_inv_fg[simp]:
"x ∈ carrier ℱ⇘gens⇙ ⟹ inv⇘ℱ⇘gens⇙⇙ x = inv_fg x"
by (rule group.inv_equality,auto simp add:free_group_is_group,auto simp add: free_group_def inv_fg_cancel inv_fg_cancel2 inv_fg_closure1 inv_fg_closure2)
subsection ‹The universal property›
text ‹Free Groups are important due to their universal property: Every map of
the set of generators to another group can be extended uniquely to an
homomorphism from the Free Group.›
definition insert (‹ι›)
where "ι g = [(False, g)]"
lemma insert_closed:
"g ∈ gens ⟹ ι g ∈ carrier ℱ⇘gens⇙"
by (auto simp add:insert_def free_group_def)
definition (in group) lift_gi
where "lift_gi f gi = (if fst gi then inv (f (snd gi)) else f (snd gi))"
lemma (in group) lift_gi_closed:
assumes cl: "f ∈ gens → carrier G"
and "snd gi ∈ gens"
shows "lift_gi f gi ∈ carrier G"
using assms by (auto simp add:lift_gi_def)
definition (in group) lift
where "lift f w = m_concat (map (lift_gi f) w)"
lemma (in group) lift_nil[simp]: "lift f [] = 𝟭"
by (auto simp add:lift_def)
lemma (in group) lift_closed[simp]:
assumes cl: "f ∈ gens → carrier G"
and "x ∈ lists (UNIV × gens)"
shows "lift f x ∈ carrier G"
proof-
have "set (map (lift_gi f) x) ⊆ carrier G"
using ‹x ∈ lists (UNIV × gens)›
by (auto simp add:lift_gi_closed[OF cl])
thus "lift f x ∈ carrier G"
by (auto simp add:lift_def)
qed
lemma (in group) lift_append[simp]:
assumes cl: "f ∈ gens → carrier G"
and "x ∈ lists (UNIV × gens)"
and "y ∈ lists (UNIV × gens)"
shows "lift f (x @ y) = lift f x ⊗ lift f y"
proof-
from ‹x ∈ lists (UNIV × gens)›
have "set (map snd x) ⊆ gens" by auto
hence "set (map (lift_gi f) x) ⊆ carrier G"
by (induct x)(auto simp add:lift_gi_closed[OF cl])
moreover
from ‹y ∈ lists (UNIV × gens)›
have "set (map snd y) ⊆ gens" by auto
hence "set (map (lift_gi f) y) ⊆ carrier G"
by (induct y)(auto simp add:lift_gi_closed[OF cl])
ultimately
show "lift f (x @ y) = lift f x ⊗ lift f y"
by (auto simp add:lift_def m_assoc simp del:set_map foldr_append)
qed
lemma (in group) lift_cancels_to:
assumes "cancels_to x y"
and "x ∈ lists (UNIV × gens)"
and cl: "f ∈ gens → carrier G"
shows "lift f x = lift f y"
using assms
unfolding cancels_to_def
proof(induct rule:rtranclp_induct)
case (step y z)
from ‹cancels_to_1⇧*⇧* x y›
and ‹x ∈ lists (UNIV × gens)›
have "y ∈ lists (UNIV × gens)"
by -(rule cancels_to_preserves_generators, simp add:cancels_to_def)
hence "lift f x = lift f y"
using step by auto
also
from ‹cancels_to_1 y z›
obtain ys1 y1 y2 ys2
where y: "y = ys1 @ y1 # y2 # ys2"
and "z = ys1 @ ys2"
and "canceling y1 y2"
by (rule cancels_to_1_unfold)
have "lift f y = lift f (ys1 @ [y1] @ [y2] @ ys2)"
using y by simp
also
from y and cl and ‹y ∈ lists (UNIV × gens)›
have "lift f (ys1 @ [y1] @ [y2] @ ys2)
= lift f ys1 ⊗ (lift f [y1] ⊗ lift f [y2]) ⊗ lift f ys2"
by (auto intro:lift_append[OF cl] simp del: append_Cons simp add:m_assoc iff:lists_eq_set)
also
from cl[THEN funcset_image]
and y and ‹y ∈ lists (UNIV × gens)›
and ‹canceling y1 y2›
have "(lift f [y1] ⊗ lift f [y2]) = 𝟭"
by (auto simp add:lift_def lift_gi_def canceling_def iff:lists_eq_set)
hence "lift f ys1 ⊗ (lift f [y1] ⊗ lift f [y2]) ⊗ lift f ys2
= lift f ys1 ⊗ 𝟭 ⊗ lift f ys2"
by simp
also
from y and ‹y ∈ lists (UNIV × gens)›
and cl
have "lift f ys1 ⊗ 𝟭 ⊗ lift f ys2 = lift f (ys1 @ ys2)"
by (auto intro:lift_append iff:lists_eq_set)
also
from ‹z = ys1 @ ys2›
have "lift f (ys1 @ ys2) = lift f z" by simp
finally show "lift f x = lift f z" .
qed auto
lemma (in group) lift_is_hom:
assumes cl: "f ∈ gens → carrier G"
shows "lift f ∈ hom ℱ⇘gens⇙ G"
proof-
{
fix x
assume "x ∈ carrier ℱ⇘gens⇙"
hence "x ∈ lists (UNIV × gens)"
unfolding free_group_def by simp
hence "lift f x ∈ carrier G"
by (induct x, auto simp add:lift_def lift_gi_closed[OF cl])
}
moreover
{ fix x
assume "x ∈ carrier ℱ⇘gens⇙"
fix y
assume "y ∈ carrier ℱ⇘gens⇙"
from ‹x ∈ carrier ℱ⇘gens⇙› and ‹y ∈ carrier ℱ⇘gens⇙›
have "x ∈ lists (UNIV × gens)" and "y ∈ lists (UNIV × gens)"
by (auto simp add:free_group_def)
have "cancels_to (x @ y) (normalize (x @ y))" by simp
from ‹x ∈ lists (UNIV × gens)› and ‹y ∈ lists (UNIV × gens)›
and lift_cancels_to[THEN sym, OF ‹cancels_to (x @ y) (normalize (x @ y))›] and cl
have "lift f (x ⊗⇘ℱ⇘gens⇙⇙ y) = lift f (x @ y)"
by (auto simp add:free_group_def iff:lists_eq_set)
also
from ‹x ∈ lists (UNIV × gens)› and ‹y ∈ lists (UNIV × gens)› and cl
have "lift f (x @ y) = lift f x ⊗ lift f y"
by simp
finally
have "lift f (x ⊗⇘ℱ⇘gens⇙⇙ y) = lift f x ⊗ lift f y" .
}
ultimately
show "lift f ∈ hom ℱ⇘gens⇙ G"
by auto
qed
lemma gens_span_free_group:
shows "⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙ = carrier ℱ⇘gens⇙"
proof
interpret group "ℱ⇘gens⇙" by (rule free_group_is_group)
show "⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙ ⊆ carrier ℱ⇘gens⇙"
by(rule gen_span_closed, auto simp add:insert_def free_group_def)
show "carrier ℱ⇘gens⇙ ⊆ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
proof
fix x
show "x ∈ carrier ℱ⇘gens⇙ ⟹ x ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
proof(induct x)
case Nil
have "one ℱ⇘gens⇙ ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by simp
thus "[] ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by (simp add:free_group_def)
next
case (Cons a x)
from ‹a # x ∈ carrier ℱ⇘gens⇙›
have "x ∈ carrier ℱ⇘gens⇙"
by (auto intro:cons_canceled simp add:free_group_def)
hence "x ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
using Cons by simp
moreover
from ‹a # x ∈ carrier ℱ⇘gens⇙›
have "snd a ∈ gens"
by (auto simp add:free_group_def)
hence isa: "ι (snd a) ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by (auto simp add:insert_def intro:gen_gens)
have "[a] ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
proof(cases "fst a")
case False
hence "[a] = ι (snd a)" by (cases a, auto simp add:insert_def)
with isa show "[a] ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙" by simp
next
case True
from ‹snd a ∈ gens›
have "ι (snd a) ∈ carrier ℱ⇘gens⇙"
by (auto simp add:free_group_def insert_def)
with True
have "[a] = inv⇘ℱ⇘gens⇙⇙ (ι (snd a))"
by (cases a, auto simp add:insert_def inv_fg_def inv1_def)
moreover
from isa
have "inv⇘ℱ⇘gens⇙⇙ (ι (snd a)) ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by (auto intro:gen_inv)
ultimately
show "[a] ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by simp
qed
ultimately
have "mult ℱ⇘gens⇙ [a] x ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙"
by (auto intro:gen_mult)
with
‹a # x ∈ carrier ℱ⇘gens⇙›
show "a # x ∈ ⟨ι ` gens⟩⇘ℱ⇘gens⇙⇙" by (simp add:free_group_def)
qed
qed
qed
lemma (in group) lift_is_unique:
assumes "group G"
and cl: "f ∈ gens → carrier G"
and "h ∈ hom ℱ⇘gens⇙ G"
and "∀ g ∈ gens. h (ι g) = f g"
shows "∀x ∈ carrier ℱ⇘gens⇙. h x = lift f x"
unfolding gens_span_free_group[THEN sym]
proof(rule hom_unique_on_span[of "ℱ⇘gens⇙" G])
show "group ℱ⇘gens⇙" by (rule free_group_is_group)
next
show "group G" by fact
next
show "ι ` gens ⊆ carrier ℱ⇘gens⇙"
by(auto intro:insert_closed)
next
show "h ∈ hom ℱ⇘gens⇙ G" by fact
next
show "lift f ∈ hom ℱ⇘gens⇙ G" by (rule lift_is_hom[OF cl])
next
from ‹∀g∈ gens. h (ι g) = f g› and cl[THEN funcset_image]
show "∀g∈ ι ` gens. h g = lift f g"
by(auto simp add:insert_def lift_def lift_gi_def)
qed
end