Theory Fundamental_Group_Scaffold
theory Fundamental_Group_Scaffold
imports "HOL-Analysis.Homotopy" Carrier_Group_Scaffold
begin
section ‹Fundamental-group quotients›
text ‹
This is the set-based counterpart to the explicit-topology quotient
development. It works directly with subsets of a topological space and the
standard HOL-Analysis path notions, which is exactly the level needed for the
final classical theorem about open sets ‹U› and ‹V›.
›
definition loop_space ::
"'a::topological_space set => 'a => (real => 'a) set"
where
"loop_space S x =
{p. path p ∧ path_image p ⊆ S ∧ pathstart p = x ∧ pathfinish p = x}"
definition loop_class ::
"'a::topological_space set => 'a => (real => 'a) => (real => 'a) set"
where
"loop_class S x p = {q. q ∈ loop_space S x ∧ homotopic_paths S q p}"
definition fundamental_group_space ::
"'a::topological_space set => 'a => ((real => 'a) set) set"
where
"fundamental_group_space S x = loop_class S x ` loop_space S x"
definition some_loop ::
"'a::topological_space set => 'a => (real => 'a) set => (real => 'a)"
where
"some_loop S x Q = (SOME p. p ∈ loop_space S x ∧ Q = loop_class S x p)"
definition fundamental_group_one ::
"'a::topological_space set => 'a => (real => 'a) set"
where
"fundamental_group_one S x = loop_class S x (λ_. x)"
definition fundamental_group_mult ::
"'a::topological_space set => 'a =>
(real => 'a) set => (real => 'a) set => (real => 'a) set"
where
"fundamental_group_mult S x A B =
loop_class S x (some_loop S x A +++ some_loop S x B)"
definition fundamental_group_inv ::
"'a::topological_space set => 'a =>
(real => 'a) set => (real => 'a) set"
where
"fundamental_group_inv S x A = loop_class S x (reversepath (some_loop S x A))"
definition loop_image ::
"('a::topological_space => 'b::topological_space) =>
(real => 'a) => (real => 'b)"
where
"loop_image h p = h ∘ p"
definition fundamental_group_map ::
"'a::topological_space set => 'a =>
'b::topological_space set => 'b =>
('a => 'b) => (real => 'a) set => (real => 'b) set"
where
"fundamental_group_map S x T y h A =
loop_class T y (loop_image h (some_loop S x A))"
lemma loop_spaceI:
assumes "path p"
and "path_image p ⊆ S"
and "pathstart p = x"
and "pathfinish p = x"
shows "p ∈ loop_space S x"
using assms unfolding loop_space_def by blast
lemma constant_loop_in_space:
assumes "x ∈ S"
shows "(λ_. x) ∈ loop_space S x"
proof (rule loop_spaceI)
show "path (λ_. x)"
by (simp add: path_def)
show "path_image (λ_. x) ⊆ S"
using assms by (auto simp: path_image_def)
show "pathstart (λ_. x) = x"
by (simp add: pathstart_def)
show "pathfinish (λ_. x) = x"
by (simp add: pathfinish_def)
qed
lemma loop_class_in_space:
assumes "p ∈ loop_space S x"
shows "loop_class S x p ∈ fundamental_group_space S x"
using assms unfolding fundamental_group_space_def by blast
lemma fundamental_group_spaceE:
assumes "Q ∈ fundamental_group_space S x"
obtains p where "p ∈ loop_space S x" "Q = loop_class S x p"
using assms unfolding fundamental_group_space_def by blast
lemma some_loop_spec:
assumes "Q ∈ fundamental_group_space S x"
shows "some_loop S x Q ∈ loop_space S x"
and "Q = loop_class S x (some_loop S x Q)"
proof -
from assms obtain p where p: "p ∈ loop_space S x" "Q = loop_class S x p"
by (rule fundamental_group_spaceE)
have ex: "∃p. p ∈ loop_space S x ∧ Q = loop_class S x p"
using p by blast
have "some_loop S x Q ∈ loop_space S x ∧ Q = loop_class S x (some_loop S x Q)"
unfolding some_loop_def by (rule someI_ex[OF ex])
then show "some_loop S x Q ∈ loop_space S x"
and "Q = loop_class S x (some_loop S x Q)"
by auto
qed
lemma loop_class_eqI:
assumes p: "p ∈ loop_space S x"
and q: "q ∈ loop_space S x"
and pq: "homotopic_paths S p q"
shows "loop_class S x p = loop_class S x q"
proof (auto simp: loop_class_def)
fix r
assume "homotopic_paths S r p"
then show "homotopic_paths S r q"
using pq by (rule homotopic_paths_trans)
next
fix r
assume "homotopic_paths S r q"
moreover have "homotopic_paths S q p"
using pq by (rule homotopic_paths_sym)
ultimately show "homotopic_paths S r p"
by (rule homotopic_paths_trans)
qed
lemma loop_class_eq_iff:
assumes p: "p ∈ loop_space S x"
and q: "q ∈ loop_space S x"
shows "loop_class S x p = loop_class S x q ⟷ homotopic_paths S p q"
proof
assume h: "loop_class S x p = loop_class S x q"
have "p ∈ loop_class S x p"
proof -
from p have p_props: "path p" "path_image p ⊆ S"
unfolding loop_space_def by auto
have "homotopic_paths S p p"
using p_props by simp
with p show ?thesis
unfolding loop_class_def by auto
qed
with h show "homotopic_paths S p q"
unfolding loop_class_def by blast
next
assume "homotopic_paths S p q"
then show "loop_class S x p = loop_class S x q"
by (rule loop_class_eqI[OF p q])
qed
lemma loop_space_join:
assumes p: "p ∈ loop_space S x"
and q: "q ∈ loop_space S x"
shows "p +++ q ∈ loop_space S x"
proof -
from p have p_props:
"path p" "path_image p ⊆ S" "pathstart p = x" "pathfinish p = x"
unfolding loop_space_def by auto
from q have q_props:
"path q" "path_image q ⊆ S" "pathstart q = x" "pathfinish q = x"
unfolding loop_space_def by auto
show ?thesis
proof (rule loop_spaceI)
show "path (p +++ q)"
using p_props q_props by simp
show "path_image (p +++ q) ⊆ S"
using p_props(2) q_props(2) by (rule subset_path_image_join)
show "pathstart (p +++ q) = x"
using p_props by simp
show "pathfinish (p +++ q) = x"
using q_props by simp
qed
qed
lemma loop_space_reversepath:
assumes "p ∈ loop_space S x"
shows "reversepath p ∈ loop_space S x"
proof -
from assms have p_props:
"path p" "path_image p ⊆ S" "pathstart p = x" "pathfinish p = x"
unfolding loop_space_def by auto
show ?thesis
proof (rule loop_spaceI)
show "path (reversepath p)"
using p_props by simp
show "path_image (reversepath p) ⊆ S"
using p_props by simp
show "pathstart (reversepath p) = x"
using p_props by simp
show "pathfinish (reversepath p) = x"
using p_props by simp
qed
qed
lemma loop_space_continuous_image:
assumes p: "p ∈ loop_space S x"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows "loop_image h p ∈ loop_space T y"
proof -
from p have p_props:
"path p" "path_image p ⊆ S" "pathstart p = x" "pathfinish p = x"
unfolding loop_space_def by auto
show ?thesis
unfolding loop_image_def
proof (rule loop_spaceI)
show "path (h ∘ p)"
using p_props(1) continuous_on_subset[OF cont_h p_props(2)]
by (rule Path_Connected.path_continuous_image)
show "path_image (h ∘ p) ⊆ T"
using p_props(2) map_h
by (auto simp: path_image_def)
show "pathstart (h ∘ p) = y"
using p_props(3) hx by (simp add: pathstart_compose)
show "pathfinish (h ∘ p) = y"
using p_props(4) hx by (simp add: pathfinish_compose)
qed
qed
lemma loop_image_join:
"loop_image h (p +++ q) = loop_image h p +++ loop_image h q"
unfolding loop_image_def
by (rule ext) (simp add: joinpaths_def)
lemma loop_image_reversepath:
"loop_image h (reversepath p) = reversepath (loop_image h p)"
unfolding loop_image_def reversepath_def
by (rule ext) simp
lemma loop_class_join_eqI:
assumes p: "p ∈ loop_space S x"
and p': "p' ∈ loop_space S x"
and q: "q ∈ loop_space S x"
and q': "q' ∈ loop_space S x"
and pp': "homotopic_paths S p p'"
and qq': "homotopic_paths S q q'"
shows "loop_class S x (p +++ q) = loop_class S x (p' +++ q')"
proof (rule loop_class_eqI)
show "p +++ q ∈ loop_space S x"
using p q by (rule loop_space_join)
show "p' +++ q' ∈ loop_space S x"
using p' q' by (rule loop_space_join)
from p have px: "pathfinish p = x"
unfolding loop_space_def by auto
from q have qx: "pathstart q = x"
unfolding loop_space_def by auto
show "homotopic_paths S (p +++ q) (p' +++ q')"
proof (rule homotopic_paths_join)
show "homotopic_paths S p p'"
by (rule pp')
show "homotopic_paths S q q'"
by (rule qq')
show "pathfinish p = pathstart q"
using px qx by simp
qed
qed
lemma loop_class_reverse_eqI:
assumes p: "p ∈ loop_space S x"
and q: "q ∈ loop_space S x"
and pq: "homotopic_paths S p q"
shows "loop_class S x (reversepath p) = loop_class S x (reversepath q)"
proof (rule loop_class_eqI)
show "reversepath p ∈ loop_space S x"
using p by (rule loop_space_reversepath)
show "reversepath q ∈ loop_space S x"
using q by (rule loop_space_reversepath)
from pq show "homotopic_paths S (reversepath p) (reversepath q)"
by (rule homotopic_paths_reversepath_D)
qed
lemma homotopic_paths_rid_const:
assumes "path p"
and "path_image p ⊆ S"
shows "homotopic_paths S (p +++ (λ_. pathfinish p)) p"
proof -
let ?f = "λt::real. if t ≤ 1/2 then 2 *⇩R t else 1"
have contf: "continuous_on {0..1} ?f"
unfolding split_01
by (rule continuous_on_cases continuous_intros | auto)+
have f01: "?f ∈ {0..1} → {0..1}"
by auto
have "homotopic_paths S p (p +++ (λ_. pathfinish p))"
proof (rule homotopic_paths_reparametrize[where f = ?f])
show "path p"
by (rule assms(1))
show "path_image p ⊆ S"
by (rule assms(2))
show "continuous_on {0..1} ?f"
by (rule contf)
show "?f ∈ {0..1} → {0..1}"
by (rule f01)
show "?f 0 = 0" "?f 1 = 1"
by simp_all
show "(p +++ (λ_. pathfinish p)) t = p (?f t)" if "t ∈ {0..1}" for t
using that by (auto simp: joinpaths_def pathfinish_def)
qed
then show ?thesis
by (rule homotopic_paths_sym)
qed
lemma homotopic_paths_lid_const:
assumes "path p"
and "path_image p ⊆ S"
shows "homotopic_paths S ((λ_. pathstart p) +++ p) p"
proof -
let ?f = "λt::real. if t ≤ 1/2 then 0 else 2 *⇩R t - 1"
have contf: "continuous_on {0..1} ?f"
unfolding split_01
by (rule continuous_on_cases continuous_intros | auto)+
have f01: "?f ∈ {0..1} → {0..1}"
by auto
have "homotopic_paths S p ((λ_. pathstart p) +++ p)"
proof (rule homotopic_paths_reparametrize[where f = ?f])
show "path p"
by (rule assms(1))
show "path_image p ⊆ S"
by (rule assms(2))
show "continuous_on {0..1} ?f"
by (rule contf)
show "?f ∈ {0..1} → {0..1}"
by (rule f01)
show "?f 0 = 0" "?f 1 = 1"
by simp_all
show "((λ_. pathstart p) +++ p) t = p (?f t)" if "t ∈ {0..1}" for t
using that by (auto simp: joinpaths_def pathstart_def)
qed
then show ?thesis
by (rule homotopic_paths_sym)
qed
lemma homotopic_paths_rinv_const:
assumes "path p"
and "path_image p ⊆ S"
shows "homotopic_paths S (p +++ reversepath p) (λ_. pathstart p)"
proof -
let ?A = "{0..1} × {0..1}"
let ?h =
"λy. if snd y ≤ 1/2
then p (fst y * (2 * snd y))
else p (fst y * (1 - (2 * snd y - 1)))"
define H where "H = ?h"
have p_cont: "continuous_on {0..1} p"
using assms by (auto simp: path_def)
have h_cont: "continuous_on ?A H"
unfolding H_def
proof (rule continuous_on_cases_le)
show "continuous_on {x ∈ ?A. snd x ≤ 1/2} (λt. p (fst t * (2 * snd t)))"
"continuous_on {x ∈ ?A. 1/2 ≤ snd x} (λt. p (fst t * (1 - (2 * snd t - 1))))"
"continuous_on ?A snd"
by (intro continuous_on_compose2 [OF p_cont] continuous_intros; auto simp: mult_le_one)+
qed (auto simp: algebra_simps)
have h_subset: "H ∈ ?A → S"
proof
fix y :: "real × real"
assume y: "y ∈ ?A"
with assms show "H y ∈ S"
unfolding H_def
by (force simp: path_image_def mult_le_one)
qed
have h0: "∀x∈{0..1}. H (0, x) = (λ_. pathstart p) x"
unfolding H_def by (simp add: pathstart_def)
have h1: "∀x∈{0..1}. H (1, x) = (p +++ reversepath p) x"
unfolding H_def by (auto simp: joinpaths_def reversepath_def)
have hends:
"∀t∈{0..1}. pathstart (H ∘ Pair t) = pathstart (λ_. pathstart p) ∧
pathfinish (H ∘ Pair t) = pathfinish (λ_. pathstart p)"
proof
fix t :: real
assume "t ∈ {0..1}"
show "pathstart (H ∘ Pair t) = pathstart (λ_. pathstart p) ∧
pathfinish (H ∘ Pair t) = pathfinish (λ_. pathstart p)"
proof
show "pathstart (H ∘ Pair t) = pathstart (λ_. pathstart p)"
unfolding H_def by (simp add: pathstart_def)
show "pathfinish (H ∘ Pair t) = pathfinish (λ_. pathstart p)"
unfolding H_def by (simp add: pathstart_def pathfinish_def)
qed
qed
have hom_const:
"homotopic_paths S (λ_. pathstart p) (p +++ reversepath p)"
apply (rule iffD2[OF homotopic_paths])
apply (rule_tac
x = "(λy. if snd y ≤ 1/2
then p (fst y * (2 * snd y))
else p (fst y * (1 - (2 * snd y - 1))))"
in exI)
using h_cont h_subset h0 h1 hends
unfolding H_def
apply blast
done
show ?thesis
using hom_const by (rule homotopic_paths_sym)
qed
lemma homotopic_paths_linv_const:
assumes "path p"
and "path_image p ⊆ S"
shows "homotopic_paths S (reversepath p +++ p) (λ_. pathfinish p)"
using homotopic_paths_rinv_const [of "reversepath p" S] assms
by simp
lemma fundamental_group_one_in_space:
assumes "x ∈ S"
shows "fundamental_group_one S x ∈ fundamental_group_space S x"
unfolding fundamental_group_one_def
using constant_loop_in_space[OF assms] by (rule loop_class_in_space)
lemma fundamental_group_mult_eqI:
assumes A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
and p: "p ∈ loop_space S x"
and q: "q ∈ loop_space S x"
and A: "A = loop_class S x p"
and B: "B = loop_class S x q"
shows "fundamental_group_mult S x A B = loop_class S x (p +++ q)"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have repB: "some_loop S x B ∈ loop_space S x" "B = loop_class S x (some_loop S x B)"
using some_loop_spec[OF B_in] by auto
have homoA': "homotopic_paths S p (some_loop S x A)"
using repA p A by (simp add: loop_class_eq_iff)
have homoA: "homotopic_paths S (some_loop S x A) p"
using homoA' by (rule homotopic_paths_sym)
have homoB': "homotopic_paths S q (some_loop S x B)"
using repB q B by (simp add: loop_class_eq_iff)
have homoB: "homotopic_paths S (some_loop S x B) q"
using homoB' by (rule homotopic_paths_sym)
have "loop_class S x (some_loop S x A +++ some_loop S x B) = loop_class S x (p +++ q)"
by (rule loop_class_join_eqI[OF repA(1) p repB(1) q homoA homoB])
then show ?thesis
unfolding fundamental_group_mult_def .
qed
lemma fundamental_group_mult_in_space:
assumes "A ∈ fundamental_group_space S x"
and "B ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x A B ∈ fundamental_group_space S x"
proof -
have repA: "some_loop S x A ∈ loop_space S x"
using some_loop_spec[OF assms(1)] by auto
have repB: "some_loop S x B ∈ loop_space S x"
using some_loop_spec[OF assms(2)] by auto
show ?thesis
unfolding fundamental_group_mult_def
using loop_space_join[OF repA repB] by (rule loop_class_in_space)
qed
lemma fundamental_group_inv_eqI:
assumes A_in: "A ∈ fundamental_group_space S x"
and p: "p ∈ loop_space S x"
and A: "A = loop_class S x p"
shows "fundamental_group_inv S x A = loop_class S x (reversepath p)"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have homoA': "homotopic_paths S p (some_loop S x A)"
using repA p A by (simp add: loop_class_eq_iff)
have homoA: "homotopic_paths S (some_loop S x A) p"
using homoA' by (rule homotopic_paths_sym)
have "loop_class S x (reversepath (some_loop S x A)) = loop_class S x (reversepath p)"
by (rule loop_class_reverse_eqI[OF repA(1) p homoA])
then show ?thesis
unfolding fundamental_group_inv_def .
qed
lemma fundamental_group_inv_in_space:
assumes "A ∈ fundamental_group_space S x"
shows "fundamental_group_inv S x A ∈ fundamental_group_space S x"
proof -
have repA: "some_loop S x A ∈ loop_space S x"
using some_loop_spec[OF assms] by auto
show ?thesis
unfolding fundamental_group_inv_def
using loop_space_reversepath[OF repA] by (rule loop_class_in_space)
qed
lemma fundamental_group_map_eqI:
assumes A_in: "A ∈ fundamental_group_space S x"
and p: "p ∈ loop_space S x"
and A: "A = loop_class S x p"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows "fundamental_group_map S x T y h A = loop_class T y (loop_image h p)"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have homo':
"homotopic_paths S p (some_loop S x A)"
using repA(1) p repA(2) A
by (simp add: loop_class_eq_iff)
have homo:
"homotopic_paths S (some_loop S x A) p"
using homo' by (rule homotopic_paths_sym)
have map_rep: "loop_image h (some_loop S x A) ∈ loop_space T y"
by (rule loop_space_continuous_image[OF repA(1) cont_h map_h hx])
have map_p: "loop_image h p ∈ loop_space T y"
by (rule loop_space_continuous_image[OF p cont_h map_h hx])
have map_homo:
"homotopic_paths T (loop_image h (some_loop S x A)) (loop_image h p)"
unfolding loop_image_def
by (rule homotopic_paths_continuous_image[OF homo cont_h map_h])
have
"loop_class T y (loop_image h (some_loop S x A)) =
loop_class T y (loop_image h p)"
by (rule loop_class_eqI[OF map_rep map_p map_homo])
then show ?thesis
unfolding fundamental_group_map_def .
qed
lemma fundamental_group_map_in_space:
assumes A_in: "A ∈ fundamental_group_space S x"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows "fundamental_group_map S x T y h A ∈ fundamental_group_space T y"
proof -
have repA: "some_loop S x A ∈ loop_space S x"
using some_loop_spec[OF A_in] by auto
have "loop_image h (some_loop S x A) ∈ loop_space T y"
by (rule loop_space_continuous_image[OF repA cont_h map_h hx])
then show ?thesis
unfolding fundamental_group_map_def by (rule loop_class_in_space)
qed
lemma fundamental_group_map_mult:
assumes A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows
"fundamental_group_map S x T y h (fundamental_group_mult S x A B) =
fundamental_group_mult T y
(fundamental_group_map S x T y h A)
(fundamental_group_map S x T y h B)"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have repB: "some_loop S x B ∈ loop_space S x" "B = loop_class S x (some_loop S x B)"
using some_loop_spec[OF B_in] by auto
have AB_in: "fundamental_group_mult S x A B ∈ fundamental_group_space S x"
by (rule fundamental_group_mult_in_space[OF A_in B_in])
have AB_eq:
"fundamental_group_mult S x A B =
loop_class S x (some_loop S x A +++ some_loop S x B)"
by (rule fundamental_group_mult_eqI[OF A_in B_in repA(1) repB(1) repA(2) repB(2)])
have map_A_in:
"fundamental_group_map S x T y h A ∈ fundamental_group_space T y"
by (rule fundamental_group_map_in_space[OF A_in cont_h map_h hx])
have map_B_in:
"fundamental_group_map S x T y h B ∈ fundamental_group_space T y"
by (rule fundamental_group_map_in_space[OF B_in cont_h map_h hx])
have map_A_eq:
"fundamental_group_map S x T y h A =
loop_class T y (loop_image h (some_loop S x A))"
by (rule fundamental_group_map_eqI[OF A_in repA(1) repA(2) cont_h map_h hx])
have map_B_eq:
"fundamental_group_map S x T y h B =
loop_class T y (loop_image h (some_loop S x B))"
by (rule fundamental_group_map_eqI[OF B_in repB(1) repB(2) cont_h map_h hx])
have left_eq:
"fundamental_group_map S x T y h (fundamental_group_mult S x A B) =
loop_class T y (loop_image h (some_loop S x A +++ some_loop S x B))"
by (rule fundamental_group_map_eqI[OF AB_in loop_space_join[OF repA(1) repB(1)] AB_eq cont_h map_h hx])
have map_loop_A: "loop_image h (some_loop S x A) ∈ loop_space T y"
by (rule loop_space_continuous_image[OF repA(1) cont_h map_h hx])
have map_loop_B: "loop_image h (some_loop S x B) ∈ loop_space T y"
by (rule loop_space_continuous_image[OF repB(1) cont_h map_h hx])
have right_eq:
"fundamental_group_mult T y
(fundamental_group_map S x T y h A)
(fundamental_group_map S x T y h B) =
loop_class T y
(loop_image h (some_loop S x A) +++ loop_image h (some_loop S x B))"
by (rule fundamental_group_mult_eqI[OF map_A_in map_B_in map_loop_A map_loop_B map_A_eq map_B_eq])
have
"loop_class T y (loop_image h (some_loop S x A +++ some_loop S x B)) =
loop_class T y (loop_image h (some_loop S x A) +++ loop_image h (some_loop S x B))"
by (rule arg_cong[where f = "loop_class T y"], simp add: loop_image_join)
then show ?thesis
using left_eq right_eq by simp
qed
lemma fundamental_group_map_id:
assumes A_in: "A ∈ fundamental_group_space S x"
shows "fundamental_group_map S x S x id A = A"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have "fundamental_group_map S x S x id A =
loop_class S x (loop_image id (some_loop S x A))"
by (rule fundamental_group_map_eqI[OF A_in repA(1) repA(2)]) simp_all
then show ?thesis
using repA(2) by (simp add: loop_image_def)
qed
lemma fundamental_group_map_one:
assumes x_in: "x ∈ S"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows
"fundamental_group_map S x T y h (fundamental_group_one S x) =
fundamental_group_one T y"
proof -
have one_in: "fundamental_group_one S x ∈ fundamental_group_space S x"
by (rule fundamental_group_one_in_space[OF x_in])
have const_in: "(λ_. x) ∈ loop_space S x"
by (rule constant_loop_in_space[OF x_in])
have "fundamental_group_map S x T y h (fundamental_group_one S x) =
loop_class T y (loop_image h (λ_. x))"
by (rule fundamental_group_map_eqI[OF one_in const_in]) (simp_all add: fundamental_group_one_def cont_h map_h hx)
then show ?thesis
by (simp add: fundamental_group_one_def loop_image_def hx)
qed
lemma fundamental_group_map_compose:
assumes A_in: "A ∈ fundamental_group_space S x"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
and cont_k: "continuous_on T k"
and map_k: "k ∈ T → U"
and ky: "k y = z"
shows
"fundamental_group_map T y U z k (fundamental_group_map S x T y h A) =
fundamental_group_map S x U z (k ∘ h) A"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have map_A_in:
"fundamental_group_map S x T y h A ∈ fundamental_group_space T y"
by (rule fundamental_group_map_in_space[OF A_in cont_h map_h hx])
have map_A_eq:
"fundamental_group_map S x T y h A =
loop_class T y (loop_image h (some_loop S x A))"
by (rule fundamental_group_map_eqI[OF A_in repA(1) repA(2) cont_h map_h hx])
have left_eq:
"fundamental_group_map T y U z k (fundamental_group_map S x T y h A) =
loop_class U z (loop_image k (loop_image h (some_loop S x A)))"
by (rule fundamental_group_map_eqI[OF map_A_in loop_space_continuous_image[OF repA(1) cont_h map_h hx] map_A_eq cont_k map_k ky])
have comp_cont: "continuous_on S (k ∘ h)"
proof -
have hs: "h ` S ⊆ T"
using map_h by auto
have hk: "continuous_on (h ` S) k"
using cont_k hs by (rule continuous_on_subset)
from cont_h hk show ?thesis
by (rule continuous_on_compose)
qed
have comp_map: "(k ∘ h) ∈ S → U"
using map_h map_k by auto
have right_eq:
"fundamental_group_map S x U z (k ∘ h) A =
loop_class U z (loop_image (k ∘ h) (some_loop S x A))"
by (rule fundamental_group_map_eqI[OF A_in repA(1) repA(2) comp_cont comp_map])
(simp add: hx ky)
have
"loop_class U z (loop_image k (loop_image h (some_loop S x A))) =
loop_class U z (loop_image (k ∘ h) (some_loop S x A))"
by (rule arg_cong[where f = "loop_class U z"]) (simp add: loop_image_def o_assoc)
then show ?thesis
using left_eq right_eq by simp
qed
lemma fundamental_group_mult_one_left:
assumes "x ∈ S"
and "A ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x (fundamental_group_one S x) A = A"
proof -
have const: "(λ_. x) ∈ loop_space S x"
using constant_loop_in_space[OF assms(1)] .
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF assms(2)] by auto
have loopA:
"path (some_loop S x A)"
"path_image (some_loop S x A) ⊆ S"
"pathstart (some_loop S x A) = x"
"pathfinish (some_loop S x A) = x"
using repA(1) unfolding loop_space_def by auto
have mult_eq:
"fundamental_group_mult S x (fundamental_group_one S x) A =
loop_class S x ((λ_. x) +++ some_loop S x A)"
proof (rule fundamental_group_mult_eqI)
show "fundamental_group_one S x ∈ fundamental_group_space S x"
by (rule fundamental_group_one_in_space[OF assms(1)])
show "A ∈ fundamental_group_space S x"
by (rule assms(2))
show "(λ_. x) ∈ loop_space S x"
by (rule const)
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "fundamental_group_one S x = loop_class S x (λ_. x)"
by (simp add: fundamental_group_one_def)
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
qed
have join_loop: "(λ_. x) +++ some_loop S x A ∈ loop_space S x"
using const repA(1) by (rule loop_space_join)
have hom: "homotopic_paths S ((λ_. x) +++ some_loop S x A) (some_loop S x A)"
using homotopic_paths_lid_const[OF loopA(1) loopA(2)] loopA(3) by simp
have class_eq:
"loop_class S x ((λ_. x) +++ some_loop S x A) = loop_class S x (some_loop S x A)"
by (rule loop_class_eqI[OF join_loop repA(1) hom])
show ?thesis
using mult_eq class_eq repA(2) by simp
qed
lemma fundamental_group_mult_one_right:
assumes "x ∈ S"
and "A ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x A (fundamental_group_one S x) = A"
proof -
have const: "(λ_. x) ∈ loop_space S x"
using constant_loop_in_space[OF assms(1)] .
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF assms(2)] by auto
have loopA:
"path (some_loop S x A)"
"path_image (some_loop S x A) ⊆ S"
"pathstart (some_loop S x A) = x"
"pathfinish (some_loop S x A) = x"
using repA(1) unfolding loop_space_def by auto
have mult_eq:
"fundamental_group_mult S x A (fundamental_group_one S x) =
loop_class S x (some_loop S x A +++ (λ_. x))"
proof (rule fundamental_group_mult_eqI)
show "A ∈ fundamental_group_space S x"
by (rule assms(2))
show "fundamental_group_one S x ∈ fundamental_group_space S x"
by (rule fundamental_group_one_in_space[OF assms(1)])
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "(λ_. x) ∈ loop_space S x"
by (rule const)
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
show "fundamental_group_one S x = loop_class S x (λ_. x)"
by (simp add: fundamental_group_one_def)
qed
have join_loop: "some_loop S x A +++ (λ_. x) ∈ loop_space S x"
using repA(1) const by (rule loop_space_join)
have hom: "homotopic_paths S (some_loop S x A +++ (λ_. x)) (some_loop S x A)"
using homotopic_paths_rid_const[OF loopA(1) loopA(2)] loopA(4) by simp
have class_eq:
"loop_class S x (some_loop S x A +++ (λ_. x)) = loop_class S x (some_loop S x A)"
by (rule loop_class_eqI[OF join_loop repA(1) hom])
show ?thesis
using mult_eq class_eq repA(2) by simp
qed
lemma fundamental_group_mult_assoc:
assumes A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
and C_in: "C ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x A (fundamental_group_mult S x B C) =
fundamental_group_mult S x (fundamental_group_mult S x A B) C"
proof -
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF A_in] by auto
have repB: "some_loop S x B ∈ loop_space S x" "B = loop_class S x (some_loop S x B)"
using some_loop_spec[OF B_in] by auto
have repC: "some_loop S x C ∈ loop_space S x" "C = loop_class S x (some_loop S x C)"
using some_loop_spec[OF C_in] by auto
have BC_eq:
"fundamental_group_mult S x B C =
loop_class S x (some_loop S x B +++ some_loop S x C)"
proof (rule fundamental_group_mult_eqI)
show "B ∈ fundamental_group_space S x"
by (rule B_in)
show "C ∈ fundamental_group_space S x"
by (rule C_in)
show "some_loop S x B ∈ loop_space S x"
by (rule repB(1))
show "some_loop S x C ∈ loop_space S x"
by (rule repC(1))
show "B = loop_class S x (some_loop S x B)"
by (rule repB(2))
show "C = loop_class S x (some_loop S x C)"
by (rule repC(2))
qed
have AB_eq:
"fundamental_group_mult S x A B =
loop_class S x (some_loop S x A +++ some_loop S x B)"
proof (rule fundamental_group_mult_eqI)
show "A ∈ fundamental_group_space S x"
by (rule A_in)
show "B ∈ fundamental_group_space S x"
by (rule B_in)
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "some_loop S x B ∈ loop_space S x"
by (rule repB(1))
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
show "B = loop_class S x (some_loop S x B)"
by (rule repB(2))
qed
have join_BC: "some_loop S x B +++ some_loop S x C ∈ loop_space S x"
using repB(1) repC(1) by (rule loop_space_join)
have join_AB: "some_loop S x A +++ some_loop S x B ∈ loop_space S x"
using repA(1) repB(1) by (rule loop_space_join)
have left_eq:
"fundamental_group_mult S x A (fundamental_group_mult S x B C) =
loop_class S x (some_loop S x A +++ (some_loop S x B +++ some_loop S x C))"
proof (rule fundamental_group_mult_eqI)
show "A ∈ fundamental_group_space S x"
by (rule A_in)
show "fundamental_group_mult S x B C ∈ fundamental_group_space S x"
by (rule fundamental_group_mult_in_space[OF B_in C_in])
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "some_loop S x B +++ some_loop S x C ∈ loop_space S x"
by (rule join_BC)
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
show "fundamental_group_mult S x B C =
loop_class S x (some_loop S x B +++ some_loop S x C)"
by (rule BC_eq)
qed
have right_eq:
"fundamental_group_mult S x (fundamental_group_mult S x A B) C =
loop_class S x ((some_loop S x A +++ some_loop S x B) +++ some_loop S x C)"
proof (rule fundamental_group_mult_eqI)
show "fundamental_group_mult S x A B ∈ fundamental_group_space S x"
by (rule fundamental_group_mult_in_space[OF A_in B_in])
show "C ∈ fundamental_group_space S x"
by (rule C_in)
show "some_loop S x A +++ some_loop S x B ∈ loop_space S x"
by (rule join_AB)
show "some_loop S x C ∈ loop_space S x"
by (rule repC(1))
show "fundamental_group_mult S x A B =
loop_class S x (some_loop S x A +++ some_loop S x B)"
by (rule AB_eq)
show "C = loop_class S x (some_loop S x C)"
by (rule repC(2))
qed
have left_loop: "some_loop S x A +++ (some_loop S x B +++ some_loop S x C) ∈ loop_space S x"
using repA(1) join_BC by (rule loop_space_join)
have right_loop: "(some_loop S x A +++ some_loop S x B) +++ some_loop S x C ∈ loop_space S x"
using join_AB repC(1) by (rule loop_space_join)
have hom_assoc:
"homotopic_paths S (some_loop S x A +++ (some_loop S x B +++ some_loop S x C))
((some_loop S x A +++ some_loop S x B) +++ some_loop S x C)"
using repA(1) repB(1) repC(1)
unfolding loop_space_def
by (auto intro: homotopic_paths_assoc)
have class_eq:
"loop_class S x (some_loop S x A +++ (some_loop S x B +++ some_loop S x C)) =
loop_class S x ((some_loop S x A +++ some_loop S x B) +++ some_loop S x C)"
by (rule loop_class_eqI[OF left_loop right_loop hom_assoc])
show ?thesis
using left_eq right_eq class_eq by simp
qed
lemma fundamental_group_mult_inv_right:
assumes "x ∈ S"
and "A ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x A (fundamental_group_inv S x A) = fundamental_group_one S x"
proof -
have const: "(λ_. x) ∈ loop_space S x"
using constant_loop_in_space[OF assms(1)] .
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF assms(2)] by auto
have loopA:
"path (some_loop S x A)"
"path_image (some_loop S x A) ⊆ S"
"pathstart (some_loop S x A) = x"
"pathfinish (some_loop S x A) = x"
using repA(1) unfolding loop_space_def by auto
have inv_eq:
"fundamental_group_inv S x A = loop_class S x (reversepath (some_loop S x A))"
by (rule fundamental_group_inv_eqI[OF assms(2) repA(1) repA(2)])
have mult_eq:
"fundamental_group_mult S x A (fundamental_group_inv S x A) =
loop_class S x (some_loop S x A +++ reversepath (some_loop S x A))"
proof (rule fundamental_group_mult_eqI)
show "A ∈ fundamental_group_space S x"
by (rule assms(2))
show "fundamental_group_inv S x A ∈ fundamental_group_space S x"
by (rule fundamental_group_inv_in_space[OF assms(2)])
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "reversepath (some_loop S x A) ∈ loop_space S x"
by (rule loop_space_reversepath[OF repA(1)])
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
show "fundamental_group_inv S x A = loop_class S x (reversepath (some_loop S x A))"
by (rule inv_eq)
qed
have join_loop: "some_loop S x A +++ reversepath (some_loop S x A) ∈ loop_space S x"
using repA(1) loop_space_reversepath[OF repA(1)] by (rule loop_space_join)
have hom: "homotopic_paths S (some_loop S x A +++ reversepath (some_loop S x A)) (λ_. x)"
using homotopic_paths_rinv_const[OF loopA(1) loopA(2)] loopA(3) by simp
have class_eq:
"loop_class S x (some_loop S x A +++ reversepath (some_loop S x A)) = loop_class S x (λ_. x)"
by (rule loop_class_eqI[OF join_loop const hom])
show ?thesis
using mult_eq class_eq unfolding fundamental_group_one_def by simp
qed
lemma fundamental_group_mult_inv_left:
assumes "x ∈ S"
and "A ∈ fundamental_group_space S x"
shows "fundamental_group_mult S x (fundamental_group_inv S x A) A = fundamental_group_one S x"
proof -
have const: "(λ_. x) ∈ loop_space S x"
using constant_loop_in_space[OF assms(1)] .
have repA: "some_loop S x A ∈ loop_space S x" "A = loop_class S x (some_loop S x A)"
using some_loop_spec[OF assms(2)] by auto
have loopA:
"path (some_loop S x A)"
"path_image (some_loop S x A) ⊆ S"
"pathstart (some_loop S x A) = x"
"pathfinish (some_loop S x A) = x"
using repA(1) unfolding loop_space_def by auto
have inv_eq:
"fundamental_group_inv S x A = loop_class S x (reversepath (some_loop S x A))"
by (rule fundamental_group_inv_eqI[OF assms(2) repA(1) repA(2)])
have mult_eq:
"fundamental_group_mult S x (fundamental_group_inv S x A) A =
loop_class S x (reversepath (some_loop S x A) +++ some_loop S x A)"
proof (rule fundamental_group_mult_eqI)
show "fundamental_group_inv S x A ∈ fundamental_group_space S x"
by (rule fundamental_group_inv_in_space[OF assms(2)])
show "A ∈ fundamental_group_space S x"
by (rule assms(2))
show "reversepath (some_loop S x A) ∈ loop_space S x"
by (rule loop_space_reversepath[OF repA(1)])
show "some_loop S x A ∈ loop_space S x"
by (rule repA(1))
show "fundamental_group_inv S x A = loop_class S x (reversepath (some_loop S x A))"
by (rule inv_eq)
show "A = loop_class S x (some_loop S x A)"
by (rule repA(2))
qed
have join_loop: "reversepath (some_loop S x A) +++ some_loop S x A ∈ loop_space S x"
using loop_space_reversepath[OF repA(1)] repA(1) by (rule loop_space_join)
have hom: "homotopic_paths S (reversepath (some_loop S x A) +++ some_loop S x A) (λ_. x)"
using homotopic_paths_linv_const[OF loopA(1) loopA(2)] loopA(4) by simp
have class_eq:
"loop_class S x (reversepath (some_loop S x A) +++ some_loop S x A) = loop_class S x (λ_. x)"
by (rule loop_class_eqI[OF join_loop const hom])
show ?thesis
using mult_eq class_eq unfolding fundamental_group_one_def by simp
qed
lemma trivial_loop_class_in_space:
assumes "x ∈ S"
shows "loop_class S x (λ_. x) ∈ fundamental_group_space S x"
using constant_loop_in_space[OF assms] by (rule loop_class_in_space)
lemma fundamental_group_carrier_group:
assumes x_in: "x ∈ S"
shows "carrier_group
(fundamental_group_space S x)
(fundamental_group_mult S x)
(fundamental_group_one S x)
(fundamental_group_inv S x)"
proof
show "fundamental_group_one S x ∈ fundamental_group_space S x"
using x_in by (rule fundamental_group_one_in_space)
next
fix A B
assume "A ∈ fundamental_group_space S x" "B ∈ fundamental_group_space S x"
then show "fundamental_group_mult S x A B ∈ fundamental_group_space S x"
by (rule fundamental_group_mult_in_space)
next
fix A
assume "A ∈ fundamental_group_space S x"
then show "fundamental_group_inv S x A ∈ fundamental_group_space S x"
by (rule fundamental_group_inv_in_space)
next
fix A B C
assume A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
and C_in: "C ∈ fundamental_group_space S x"
show
"fundamental_group_mult S x (fundamental_group_mult S x A B) C =
fundamental_group_mult S x A (fundamental_group_mult S x B C)"
by (rule sym, rule fundamental_group_mult_assoc[OF A_in B_in C_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x (fundamental_group_one S x) A = A"
by (rule fundamental_group_mult_one_left[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x A (fundamental_group_one S x) = A"
by (rule fundamental_group_mult_one_right[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x (fundamental_group_inv S x A) A = fundamental_group_one S x"
by (rule fundamental_group_mult_inv_left[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x A (fundamental_group_inv S x A) = fundamental_group_one S x"
by (rule fundamental_group_mult_inv_right[OF x_in A_in])
qed
lemma fundamental_group_map_carrier_group_hom:
assumes x_in: "x ∈ S"
and cont_h: "continuous_on S h"
and map_h: "h ∈ S → T"
and hx: "h x = y"
shows "carrier_group_hom
(fundamental_group_space S x)
(fundamental_group_mult S x)
(fundamental_group_one S x)
(fundamental_group_inv S x)
(fundamental_group_space T y)
(fundamental_group_mult T y)
(fundamental_group_one T y)
(fundamental_group_inv T y)
(fundamental_group_map S x T y h)"
proof -
have y_in: "y ∈ T"
using x_in map_h hx by auto
show ?thesis
proof unfold_locales
show "fundamental_group_one S x ∈ fundamental_group_space S x"
by (rule fundamental_group_one_in_space[OF x_in])
next
fix A B
assume A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
show "fundamental_group_mult S x A B ∈ fundamental_group_space S x"
by (rule fundamental_group_mult_in_space[OF A_in B_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_inv S x A ∈ fundamental_group_space S x"
by (rule fundamental_group_inv_in_space[OF A_in])
next
fix A B C
assume A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
and C_in: "C ∈ fundamental_group_space S x"
show "fundamental_group_mult S x (fundamental_group_mult S x A B) C =
fundamental_group_mult S x A (fundamental_group_mult S x B C)"
by (rule sym, rule fundamental_group_mult_assoc[OF A_in B_in C_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x (fundamental_group_one S x) A = A"
by (rule fundamental_group_mult_one_left[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x A (fundamental_group_one S x) = A"
by (rule fundamental_group_mult_one_right[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x (fundamental_group_inv S x A) A =
fundamental_group_one S x"
by (rule fundamental_group_mult_inv_left[OF x_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_mult S x A (fundamental_group_inv S x A) =
fundamental_group_one S x"
by (rule fundamental_group_mult_inv_right[OF x_in A_in])
next
show "fundamental_group_one T y ∈ fundamental_group_space T y"
by (rule fundamental_group_one_in_space[OF y_in])
next
fix A B
assume A_in: "A ∈ fundamental_group_space T y"
and B_in: "B ∈ fundamental_group_space T y"
show "fundamental_group_mult T y A B ∈ fundamental_group_space T y"
by (rule fundamental_group_mult_in_space[OF A_in B_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space T y"
show "fundamental_group_inv T y A ∈ fundamental_group_space T y"
by (rule fundamental_group_inv_in_space[OF A_in])
next
fix A B C
assume A_in: "A ∈ fundamental_group_space T y"
and B_in: "B ∈ fundamental_group_space T y"
and C_in: "C ∈ fundamental_group_space T y"
show "fundamental_group_mult T y (fundamental_group_mult T y A B) C =
fundamental_group_mult T y A (fundamental_group_mult T y B C)"
by (rule sym, rule fundamental_group_mult_assoc[OF A_in B_in C_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space T y"
show "fundamental_group_mult T y (fundamental_group_one T y) A = A"
by (rule fundamental_group_mult_one_left[OF y_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space T y"
show "fundamental_group_mult T y A (fundamental_group_one T y) = A"
by (rule fundamental_group_mult_one_right[OF y_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space T y"
show "fundamental_group_mult T y (fundamental_group_inv T y A) A =
fundamental_group_one T y"
by (rule fundamental_group_mult_inv_left[OF y_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space T y"
show "fundamental_group_mult T y A (fundamental_group_inv T y A) =
fundamental_group_one T y"
by (rule fundamental_group_mult_inv_right[OF y_in A_in])
next
fix A
assume A_in: "A ∈ fundamental_group_space S x"
show "fundamental_group_map S x T y h A ∈ fundamental_group_space T y"
by (rule fundamental_group_map_in_space[OF A_in cont_h map_h hx])
next
fix A B
assume A_in: "A ∈ fundamental_group_space S x"
and B_in: "B ∈ fundamental_group_space S x"
show "fundamental_group_map S x T y h (fundamental_group_mult S x A B) =
fundamental_group_mult T y
(fundamental_group_map S x T y h A)
(fundamental_group_map S x T y h B)"
by (rule fundamental_group_map_mult[OF A_in B_in cont_h map_h hx])
qed
qed
end