Theory Topological_Seifert_Van_Kampen
theory Topological_Seifert_Van_Kampen
imports
Carrier_Amalgamated_Free_Product_Eval
Explicit_Fundamental_Group_Scaffold
Topological_Pushout_Scaffold
Seifert_Van_Kampen_Scaffold
begin
section ‹Concrete decode data for topological pushouts›
text ‹
Once the pushout topology and the carrier-side amalgamation evaluator are
available, the remaining task is to package a concrete decoding map back into
the fundamental group of the pushout. This theory shows how such decode data
yields the abstract carrier-level Seifert--van Kampen bijection in the
topological pushout setting.
›
lemma loopin_image_compose [simp]:
"loopin_image g (loopin_image f p) = loopin_image (g ∘ f) p"
unfolding loopin_image_def by (rule ext) simp
lemma fundamental_groupin_map_eq:
assumes A_in: "A ∈ fundamental_groupin_space X x"
and f_cont: "continuous_map X Y f"
and g_cont: "continuous_map X Y g"
and fx: "f x = y"
and gx: "g x = y"
and fg: "⋀u. f u = g u"
shows "fundamental_groupin_map X x Y y f A = fundamental_groupin_map X x Y y g A"
proof -
have repA: "some_loopin X x A ∈ loopin_space X x" "A = loopin_class X x (some_loopin X x A)"
using some_loopin_spec[OF A_in] by auto
have left_eq:
"fundamental_groupin_map X x Y y f A =
loopin_class Y y (loopin_image f (some_loopin X x A))"
by (rule fundamental_groupin_map_rep[OF A_in repA(1) repA(2) f_cont fx])
have right_eq:
"fundamental_groupin_map X x Y y g A =
loopin_class Y y (loopin_image g (some_loopin X x A))"
by (rule fundamental_groupin_map_rep[OF A_in repA(1) repA(2) g_cont gx])
have "loopin_image f (some_loopin X x A) = loopin_image g (some_loopin X x A)"
using fg by (simp add: loopin_image_def fun_eq_iff)
then show ?thesis
using left_eq right_eq by simp
qed
lemma fundamental_groupin_map_compose:
assumes A_in: "A ∈ fundamental_groupin_space X x"
and f_cont: "continuous_map X Y f"
and g_cont: "continuous_map Y Z g"
and fx: "f x = y"
and gy: "g y = z"
shows "fundamental_groupin_map Y y Z z g (fundamental_groupin_map X x Y y f A) =
fundamental_groupin_map X x Z z (g ∘ f) A"
proof -
have repA: "some_loopin X x A ∈ loopin_space X x" "A = loopin_class X x (some_loopin X x A)"
using some_loopin_spec[OF A_in] by auto
have mapA_in: "fundamental_groupin_map X x Y y f A ∈ fundamental_groupin_space Y y"
by (rule fundamental_groupin_map_in_space[OF A_in f_cont fx])
have mapA_eq:
"fundamental_groupin_map X x Y y f A =
loopin_class Y y (loopin_image f (some_loopin X x A))"
by (rule fundamental_groupin_map_rep[OF A_in repA(1) repA(2) f_cont fx])
have map_loop_in: "loopin_image f (some_loopin X x A) ∈ loopin_space Y y"
by (rule loopin_image_in_space[OF repA(1) f_cont fx])
have left_eq:
"fundamental_groupin_map Y y Z z g (fundamental_groupin_map X x Y y f A) =
loopin_class Z z (loopin_image g (loopin_image f (some_loopin X x A)))"
by (rule fundamental_groupin_map_rep[OF mapA_in map_loop_in mapA_eq g_cont gy])
have comp_cont: "continuous_map X Z (g ∘ f)"
using f_cont g_cont by (rule continuous_map_compose)
have right_eq:
"fundamental_groupin_map X x Z z (g ∘ f) A =
loopin_class Z z (loopin_image (g ∘ f) (some_loopin X x A))"
by (rule fundamental_groupin_map_rep[OF A_in repA(1) repA(2) comp_cont]) (simp add: fx gy)
show ?thesis
using left_eq right_eq by simp
qed
locale topological_svk_setup =
fixes X :: "'a topology"
and Y :: "'b topology"
and Z :: "'c topology"
and f :: "'c ⇒ 'a"
and g :: "'c ⇒ 'b"
and z0 :: "'c"
assumes z0_in: "z0 ∈ topspace Z"
and f_cont: "continuous_map Z X f"
and g_cont: "continuous_map Z Y g"
begin
abbreviation x0 where "x0 ≡ f z0"
abbreviation y0 where "y0 ≡ g z0"
abbreviation P where "P ≡ pushout_topology X Y f g"
abbreviation p0 where "p0 ≡ pushout_inl f g x0"
abbreviation G1 where "G1 ≡ fundamental_groupin_space X x0"
abbreviation G2 where "G2 ≡ fundamental_groupin_space Y y0"
abbreviation H where "H ≡ fundamental_groupin_space Z z0"
abbreviation mult1 where "mult1 ≡ fundamental_groupin_mult X x0"
abbreviation one1 where "one1 ≡ fundamental_groupin_one X x0"
abbreviation mult2 where "mult2 ≡ fundamental_groupin_mult Y y0"
abbreviation one2 where "one2 ≡ fundamental_groupin_one Y y0"
abbreviation multP where "multP ≡ fundamental_groupin_mult P p0"
abbreviation oneP where "oneP ≡ fundamental_groupin_one P p0"
abbreviation i1 where "i1 ≡ fundamental_groupin_map Z z0 X x0 f"
abbreviation i2 where "i2 ≡ fundamental_groupin_map Z z0 Y y0 g"
abbreviation j1 where "j1 ≡ fundamental_groupin_map X x0 P p0 (pushout_inl f g)"
abbreviation j2 where "j2 ≡ fundamental_groupin_map Y y0 P p0 (pushout_inr f g)"
lemma x0_in [simp]: "x0 ∈ topspace X"
using z0_in f_cont unfolding continuous_map_def by blast
lemma y0_in [simp]: "y0 ∈ topspace Y"
using z0_in g_cont unfolding continuous_map_def by blast
lemma pushout_basepoint_eq [simp]:
"pushout_inr f g y0 = p0"
by (simp add: pushout_glue)
lemma pushout_basepoint_in [simp]:
"p0 ∈ topspace P"
by (simp add: pushout_inl_in_topspace[OF x0_in])
lemma pushout_fundamental_group_maps_agree:
assumes h_in: "h ∈ H"
shows "j1 (i1 h) = j2 (i2 h)"
proof -
have left_comp:
"j1 (i1 h) = fundamental_groupin_map Z z0 P p0 ((pushout_inl f g) ∘ f) h"
by (simp add: fundamental_groupin_map_compose[OF h_in f_cont continuous_map_pushout_inl])
have right_comp:
"j2 (i2 h) = fundamental_groupin_map Z z0 P p0 ((pushout_inr f g) ∘ g) h"
by (simp add: fundamental_groupin_map_compose[OF h_in g_cont continuous_map_pushout_inr])
have left_cont: "continuous_map Z P ((pushout_inl f g) ∘ f)"
by (rule continuous_map_compose[OF f_cont continuous_map_pushout_inl])
have right_cont: "continuous_map Z P ((pushout_inr f g) ∘ g)"
by (rule continuous_map_compose[OF g_cont continuous_map_pushout_inr])
have left_z0: "((pushout_inl f g) ∘ f) z0 = p0"
by simp
have right_z0: "((pushout_inr f g) ∘ g) z0 = p0"
by simp
have comp_fun_eq: "((pushout_inl f g) ∘ f) u = ((pushout_inr f g) ∘ g) u" for u
by (simp add: pushout_glue)
have comp_eq:
"fundamental_groupin_map Z z0 P p0 ((pushout_inl f g) ∘ f) h =
fundamental_groupin_map Z z0 P p0 ((pushout_inr f g) ∘ g) h"
by (rule fundamental_groupin_map_eq[OF h_in left_cont right_cont left_z0 right_z0 comp_fun_eq])
show ?thesis
using left_comp right_comp comp_eq by simp
qed
lemma i1_in_G1:
assumes "h ∈ H"
shows "i1 h ∈ G1"
by (rule fundamental_groupin_map_in_space[OF assms f_cont]) simp
lemma i2_in_G2:
assumes "h ∈ H"
shows "i2 h ∈ G2"
by (rule fundamental_groupin_map_in_space[OF assms g_cont]) simp
lemma decode_locale:
"carrier_full_amalg_word_eval
G1 mult1 one1 (fundamental_groupin_inv X x0)
G2 mult2 one2 (fundamental_groupin_inv Y y0)
H i1 i2
(fundamental_groupin_space P p0) multP oneP (fundamental_groupin_inv P p0)
j1 j2"
proof (rule carrier_full_amalg_word_eval.intro)
show "carrier_group
(fundamental_groupin_space X x0)
(fundamental_groupin_mult X x0)
(fundamental_groupin_one X x0)
(fundamental_groupin_inv X x0)"
by (rule fundamental_groupin_carrier_group[OF x0_in])
show "carrier_group
(fundamental_groupin_space Y y0)
(fundamental_groupin_mult Y y0)
(fundamental_groupin_one Y y0)
(fundamental_groupin_inv Y y0)"
by (rule fundamental_groupin_carrier_group[OF y0_in])
show "carrier_group
(fundamental_groupin_space P p0) multP oneP (fundamental_groupin_inv P p0)"
by (rule fundamental_groupin_carrier_group[OF pushout_basepoint_in])
show "carrier_group_hom
(fundamental_groupin_space X x0)
(fundamental_groupin_mult X x0)
(fundamental_groupin_one X x0)
(fundamental_groupin_inv X x0)
(fundamental_groupin_space P p0) multP oneP (fundamental_groupin_inv P p0)
(fundamental_groupin_map X x0 P p0 (pushout_inl f g))"
by (rule fundamental_groupin_map_carrier_group_hom[OF x0_in continuous_map_pushout_inl]) simp
show "carrier_group_hom
(fundamental_groupin_space Y y0)
(fundamental_groupin_mult Y y0)
(fundamental_groupin_one Y y0)
(fundamental_groupin_inv Y y0)
(fundamental_groupin_space P p0) multP oneP (fundamental_groupin_inv P p0)
(fundamental_groupin_map Y y0 P p0 (pushout_inr f g))"
by (rule fundamental_groupin_map_carrier_group_hom[OF y0_in continuous_map_pushout_inr]) simp
show "carrier_full_amalg_word_eval_axioms G1 G2 H i1 i2 j1 j2"
proof (rule carrier_full_amalg_word_eval_axioms.intro)
show "h ∈ H ⟹ i1 h ∈ G1" for h
by (rule i1_in_G1)
show "h ∈ H ⟹ i2 h ∈ G2" for h
by (rule i2_in_G2)
show "h ∈ H ⟹ j1 (i1 h) = j2 (i2 h)" for h
by (rule pushout_fundamental_group_maps_agree)
qed
qed
interpretation decode:
carrier_full_amalg_word_eval
G1 mult1 one1 "fundamental_groupin_inv X x0"
G2 mult2 one2 "fundamental_groupin_inv Y y0"
H i1 i2
"fundamental_groupin_space P p0" multP oneP "fundamental_groupin_inv P p0"
j1 j2
by (rule decode_locale)
abbreviation svk_word_eval where "svk_word_eval ≡ decode.carrier_full_amalg_eval"
abbreviation svk_decode where "svk_decode ≡ decode.carrier_full_amalg_decode"
lemma svk_decode_in_space:
"svk_decode w ∈ fundamental_groupin_space P p0"
by (rule decode.carrier_full_amalg_decode_in_carrier)
lemma svk_decode_respects:
assumes "carrier_full_amalg_equiv G1 G2 H i1 i2 mult1 one1 mult2 one2 u v"
shows "svk_decode u = svk_decode v"
using assms by (rule decode.carrier_full_amalg_decode_respects)
lemma svk_decode_eq_eval:
assumes "fpw_in_space G1 G2 w"
shows "svk_decode w = svk_word_eval w"
using assms by (rule decode.carrier_full_amalg_decode_eq_eval)
end
locale topological_svk_open_cover =
topological_svk_setup X Y Z f g z0
for X :: "'a topology"
and Y :: "'b topology"
and Z :: "'c topology"
and f :: "'c ⇒ 'a"
and g :: "'c ⇒ 'b"
and z0 :: "'c" +
assumes left_open: "openin P (pushout_inl f g ` topspace X)"
and right_open: "openin P (pushout_inr f g ` topspace Y)"
begin
lemma loopin_subdivision_by_summands:
assumes p_loop: "p ∈ loopin_space P p0"
shows "∃n::nat. 0 < n ∧
(∀i<n.
subpathin (real i / real n) (real (Suc i) / real n) p ` {0..1}
⊆ pushout_inl f g ` topspace X ∨
subpathin (real i / real n) (real (Suc i) / real n) p ` {0..1}
⊆ pushout_inr f g ` topspace Y)"
proof -
let ?L = "pushout_inl f g ` topspace X"
let ?R = "pushout_inr f g ` topspace Y"
from p_loop obtain p_path where p_path: "pathin P p"
by (rule loopin_spaceE)
have p_img: "p ` {0..1} ⊆ topspace P"
by (rule pathin_image_subset_topspace[OF p_path])
have cover: "p ` {0..1} ⊆ ?L ∪ ?R"
using p_img by (auto simp: pushout_topspace_alt)
have cover': "p ` {0..1} ⊆ ⋃{?L, ?R}"
using cover by auto
have open_cover: "openin P U" if "U ∈ {?L, ?R}" for U
using that left_open right_open by auto
have subdiv:
"∃n::nat. 0 < n ∧
(∀i<n. ∃U∈{?L, ?R}.
subpathin (real i / real n) (real (Suc i) / real n) p ` {0..1} ⊆ U)"
by (rule pathin_subdivision_open_cover[OF p_path cover' open_cover])
then obtain n :: nat where n_pos: "0 < n"
and n_cover:
"∀i<n. ∃U∈{?L, ?R}.
subpathin (real i / real n) (real (Suc i) / real n) p ` {0..1} ⊆ U"
by blast
show ?thesis
using n_pos n_cover by auto
qed
end
locale topological_svk =
topological_svk_setup X Y Z f g z0
for X :: "'a topology"
and Y :: "'b topology"
and Z :: "'c topology"
and f :: "'c ⇒ 'a"
and g :: "'c ⇒ 'b"
and z0 :: "'c" +
fixes encode
assumes encode_in_space: "fpw_in_space G1 G2 (encode A)"
and decode_encode: "svk_decode (encode A) = A"
and encode_decode:
"carrier_full_amalg_equiv G1 G2 H i1 i2 mult1 one1 mult2 one2 (encode (svk_decode w)) w"
begin
lemma svk_locale:
"carrier_svk_encode_decode_interface
G1 G2 H i1 i2 mult1 one1 mult2 one2 encode svk_decode"
proof (rule carrier_svk_encode_decode_interface.intro)
show "fpw_in_space G1 G2 (encode x)" for x
by (fact encode_in_space)
show "carrier_full_amalg_equiv G1 G2 H i1 i2 mult1 one1 mult2 one2 u v ⟹ svk_decode u = svk_decode v" for u v
by (rule svk_decode_respects)
show "svk_decode (encode x) = x" for x
by (fact decode_encode)
show "carrier_full_amalg_equiv G1 G2 H i1 i2 mult1 one1 mult2 one2 (encode (svk_decode w)) w" for w
by (fact encode_decode)
qed
interpretation svk: carrier_svk_encode_decode_interface
G1 G2 H i1 i2 mult1 one1 mult2 one2 encode svk_decode
by (rule svk_locale)
text ‹
The theorem below isolates the topological conclusion once an encoding map has
been supplied and the usual round-trip laws have been verified. The classical
open-union theorem later instantiates this interface by constructing that
encoding from loop partitions subordinate to ‹U› and ‹V›.
›
theorem topological_seifert_van_kampen_bij_betw:
"bij_betw svk.carrier_svk_quotient_map UNIV
(carrier_full_amalgamated_free_product_space G1 G2 H i1 i2 mult1 one1 mult2 one2)"
by (rule svk.carrier_seifert_van_kampen_bij_betw)
end
end