# HG changeset patch # User hoelzl # Date 1454948293 -3600 # Node ID d2bc8a7e5fec870af53b44039378a2b96eecb508 # Parent 95c6cf433c9188e55f279d71bcb16b3b6f5bf325 move product topology to HOL-Complex_Main diff -r 95c6cf433c91 -r d2bc8a7e5fec src/HOL/Filter.thy --- a/src/HOL/Filter.thy Thu Feb 18 17:53:09 2016 +0100 +++ b/src/HOL/Filter.thy Mon Feb 08 17:18:13 2016 +0100 @@ -479,6 +479,29 @@ eventually P (INF b:B. F b) \ (\b\B. eventually P (F b))" by (subst eventually_Inf_base) auto +lemma eventually_INF_mono: + assumes *: "\\<^sub>F x in \i\I. F i. P x" + assumes T1: "\Q R P. (\x. Q x \ R x \ P x) \ (\x. T Q x \ T R x \ T P x)" + assumes T2: "\P. (\x. P x) \ (\x. T P x)" + assumes **: "\i P. i \ I \ \\<^sub>F x in F i. P x \ \\<^sub>F x in F' i. T P x" + shows "\\<^sub>F x in \i\I. F' i. T P x" +proof - + from * obtain X where "finite X" "X \ I" "\\<^sub>F x in \i\X. F i. P x" + unfolding eventually_INF[of _ I] by auto + moreover then have "eventually (T P) (INFIMUM X F')" + apply (induction X arbitrary: P) + apply (auto simp: eventually_inf T2) + subgoal for x S P Q R + apply (intro exI[of _ "T Q"]) + apply (auto intro!: **) [] + apply (intro exI[of _ "T R"]) + apply (auto intro: T1) [] + done + done + ultimately show "\\<^sub>F x in \i\I. F' i. T P x" + by (subst eventually_INF) auto +qed + subsubsection \Map function for filters\ @@ -530,7 +553,6 @@ by (subst (1 2) eventually_INF) auto qed - subsubsection \Standard filters\ definition principal :: "'a set \ 'a filter" where @@ -768,9 +790,116 @@ by auto qed (auto simp: eventually_principal intro: eventually_True) +lemma eventually_prod1: + assumes "B \ bot" + shows "(\\<^sub>F (x, y) in A \\<^sub>F B. P x) \ (\\<^sub>F x in A. P x)" + unfolding eventually_prod_filter +proof safe + fix R Q assume "\\<^sub>F x in A. R x" "\\<^sub>F x in B. Q x" "\x y. R x \ Q y \ P x" + moreover with \B \ bot\ obtain y where "Q y" by (auto dest: eventually_happens) + ultimately show "eventually P A" + by (force elim: eventually_mono) +next + assume "eventually P A" + then show "\Pf Pg. eventually Pf A \ eventually Pg B \ (\x y. Pf x \ Pg y \ P x)" + by (intro exI[of _ P] exI[of _ "\x. True"]) auto +qed + +lemma eventually_prod2: + assumes "A \ bot" + shows "(\\<^sub>F (x, y) in A \\<^sub>F B. P y) \ (\\<^sub>F y in B. P y)" + unfolding eventually_prod_filter +proof safe + fix R Q assume "\\<^sub>F x in A. R x" "\\<^sub>F x in B. Q x" "\x y. R x \ Q y \ P y" + moreover with \A \ bot\ obtain x where "R x" by (auto dest: eventually_happens) + ultimately show "eventually P B" + by (force elim: eventually_mono) +next + assume "eventually P B" + then show "\Pf Pg. eventually Pf A \ eventually Pg B \ (\x y. Pf x \ Pg y \ P y)" + by (intro exI[of _ P] exI[of _ "\x. True"]) auto +qed + +lemma INF_filter_bot_base: + fixes F :: "'a \ 'b filter" + assumes *: "\i j. i \ I \ j \ I \ \k\I. F k \ F i \ F j" + shows "(INF i:I. F i) = bot \ (\i\I. F i = bot)" +proof cases + assume "\i\I. F i = bot" + moreover then have "(INF i:I. F i) \ bot" + by (auto intro: INF_lower2) + ultimately show ?thesis + by (auto simp: bot_unique) +next + assume **: "\ (\i\I. F i = bot)" + moreover have "(INF i:I. F i) \ bot" + proof cases + assume "I \ {}" + show ?thesis + proof (rule INF_filter_not_bot) + fix J assume "finite J" "J \ I" + then have "\k\I. F k \ (\i\J. F i)" + proof (induction J) + case empty then show ?case + using \I \ {}\ by auto + next + case (insert i J) + moreover then obtain k where "k \ I" "F k \ (\i\J. F i)" by auto + moreover note *[of i k] + ultimately show ?case + by auto + qed + with ** show "(\i\J. F i) \ \" + by (auto simp: bot_unique) + qed + qed (auto simp add: filter_eq_iff) + ultimately show ?thesis + by auto +qed + +lemma Collect_empty_eq_bot: "Collect P = {} \ P = \" + by auto + +lemma prod_filter_eq_bot: "A \\<^sub>F B = bot \ A = bot \ B = bot" + unfolding prod_filter_def +proof (subst INF_filter_bot_base; clarsimp simp: principal_eq_bot_iff Collect_empty_eq_bot bot_fun_def simp del: Collect_empty_eq) + fix A1 A2 B1 B2 assume "\\<^sub>F x in A. A1 x" "\\<^sub>F x in A. A2 x" "\\<^sub>F x in B. B1 x" "\\<^sub>F x in B. B2 x" + then show "\x. eventually x A \ (\y. eventually y B \ Collect x \ Collect y \ Collect A1 \ Collect B1 \ Collect x \ Collect y \ Collect A2 \ Collect B2)" + by (intro exI[of _ "\x. A1 x \ A2 x"] exI[of _ "\x. B1 x \ B2 x"] conjI) + (auto simp: eventually_conj_iff) +next + show "(\x. eventually x A \ (\y. eventually y B \ (x = (\x. False) \ y = (\x. False)))) = (A = \ \ B = \)" + by (auto simp: trivial_limit_def intro: eventually_True) +qed + lemma prod_filter_mono: "F \ F' \ G \ G' \ F \\<^sub>F G \ F' \\<^sub>F G'" by (auto simp: le_filter_def eventually_prod_filter) +lemma prod_filter_mono_iff: + assumes nAB: "A \ bot" "B \ bot" + shows "A \\<^sub>F B \ C \\<^sub>F D \ A \ C \ B \ D" +proof safe + assume *: "A \\<^sub>F B \ C \\<^sub>F D" + moreover with assms have "A \\<^sub>F B \ bot" + by (auto simp: bot_unique prod_filter_eq_bot) + ultimately have "C \\<^sub>F D \ bot" + by (auto simp: bot_unique) + then have nCD: "C \ bot" "D \ bot" + by (auto simp: prod_filter_eq_bot) + + show "A \ C" + proof (rule filter_leI) + fix P assume "eventually P C" with *[THEN filter_leD, of "\(x, y). P x"] show "eventually P A" + using nAB nCD by (simp add: eventually_prod1 eventually_prod2) + qed + + show "B \ D" + proof (rule filter_leI) + fix P assume "eventually P D" with *[THEN filter_leD, of "\(x, y). P y"] show "eventually P B" + using nAB nCD by (simp add: eventually_prod1 eventually_prod2) + qed +qed (intro prod_filter_mono) + lemma eventually_prod_same: "eventually P (F \\<^sub>F F) \ (\Q. eventually Q F \ (\x y. Q x \ Q y \ P (x, y)))" unfolding eventually_prod_filter @@ -791,6 +920,52 @@ apply auto done +lemma prod_filter_INF: + assumes "I \ {}" "J \ {}" + shows "(INF i:I. A i) \\<^sub>F (INF j:J. B j) = (INF i:I. INF j:J. A i \\<^sub>F B j)" +proof (safe intro!: antisym INF_greatest) + from \I \ {}\ obtain i where "i \ I" by auto + from \J \ {}\ obtain j where "j \ J" by auto + + show "(\i\I. \j\J. A i \\<^sub>F B j) \ (\i\I. A i) \\<^sub>F (\j\J. B j)" + unfolding prod_filter_def + proof (safe intro!: INF_greatest) + fix P Q assume P: "\\<^sub>F x in \i\I. A i. P x" and Q: "\\<^sub>F x in \j\J. B j. Q x" + let ?X = "(\i\I. \j\J. \(P, Q)\{(P, Q). (\\<^sub>F x in A i. P x) \ (\\<^sub>F x in B j. Q x)}. principal {(x, y). P x \ Q y})" + have "?X \ principal {x. P (fst x)} \ principal {x. Q (snd x)}" + proof (intro inf_greatest) + have "?X \ (\i\I. \P\{P. eventually P (A i)}. principal {x. P (fst x)})" + by (auto intro!: INF_greatest INF_lower2[of j] INF_lower2 \j\J\ INF_lower2[of "(_, \x. True)"]) + also have "\ \ principal {x. P (fst x)}" + unfolding le_principal + proof (rule eventually_INF_mono[OF P]) + fix i P assume "i \ I" "eventually P (A i)" + then show "\\<^sub>F x in \P\{P. eventually P (A i)}. principal {x. P (fst x)}. x \ {x. P (fst x)}" + unfolding le_principal[symmetric] by (auto intro!: INF_lower) + qed auto + finally show "?X \ principal {x. P (fst x)}" . + + have "?X \ (\i\J. \P\{P. eventually P (B i)}. principal {x. P (snd x)})" + by (auto intro!: INF_greatest INF_lower2[of i] INF_lower2 \i\I\ INF_lower2[of "(\x. True, _)"]) + also have "\ \ principal {x. Q (snd x)}" + unfolding le_principal + proof (rule eventually_INF_mono[OF Q]) + fix j Q assume "j \ J" "eventually Q (B j)" + then show "\\<^sub>F x in \P\{P. eventually P (B j)}. principal {x. P (snd x)}. x \ {x. Q (snd x)}" + unfolding le_principal[symmetric] by (auto intro!: INF_lower) + qed auto + finally show "?X \ principal {x. Q (snd x)}" . + qed + also have "\ = principal {(x, y). P x \ Q y}" + by auto + finally show "?X \ principal {(x, y). P x \ Q y}" . + qed +qed (intro prod_filter_mono INF_lower) + +lemma filtermap_Pair: "filtermap (\x. (f x, g x)) F \ filtermap f F \\<^sub>F filtermap g F" + by (simp add: le_filter_def eventually_filtermap eventually_prod_filter) + (auto elim: eventually_elim2) + subsection \Limits\ definition filterlim :: "('a \ 'b) \ 'b filter \ 'a filter \ bool" where @@ -800,7 +975,7 @@ "_LIM" :: "pttrns \ 'a \ 'b \ 'a \ bool" ("(3LIM (_)/ (_)./ (_) :> (_))" [1000, 10, 0, 10] 10) translations - "LIM x F1. f :> F2" == "CONST filterlim (%x. f) F2 F1" + "LIM x F1. f :> F2" == "CONST filterlim (\x. f) F2 F1" lemma filterlim_iff: "(LIM x F1. f x :> F2) \ (\P. eventually P F2 \ eventually (\x. P (f x)) F1)" @@ -907,6 +1082,11 @@ LIM x F. if P x then f x else g x :> G" unfolding filterlim_iff eventually_inf_principal by (auto simp: eventually_conj_iff) +lemma filterlim_Pair: + "LIM x F. f x :> G \ LIM x F. g x :> H \ LIM x F. (f x, g x) :> G \\<^sub>F H" + unfolding filterlim_def + by (rule order_trans[OF filtermap_Pair prod_filter_mono]) + subsection \Limits to @{const at_top} and @{const at_bot}\ lemma filterlim_at_top: diff -r 95c6cf433c91 -r d2bc8a7e5fec src/HOL/Library/Product_Vector.thy --- a/src/HOL/Library/Product_Vector.thy Thu Feb 18 17:53:09 2016 +0100 +++ b/src/HOL/Library/Product_Vector.thy Mon Feb 08 17:18:13 2016 +0100 @@ -40,239 +40,6 @@ end -subsection \Product is a topological space\ - -instantiation prod :: (topological_space, topological_space) topological_space -begin - -definition open_prod_def[code del]: - "open (S :: ('a \ 'b) set) \ - (\x\S. \A B. open A \ open B \ x \ A \ B \ A \ B \ S)" - -lemma open_prod_elim: - assumes "open S" and "x \ S" - obtains A B where "open A" and "open B" and "x \ A \ B" and "A \ B \ S" -using assms unfolding open_prod_def by fast - -lemma open_prod_intro: - assumes "\x. x \ S \ \A B. open A \ open B \ x \ A \ B \ A \ B \ S" - shows "open S" -using assms unfolding open_prod_def by fast - -instance -proof - show "open (UNIV :: ('a \ 'b) set)" - unfolding open_prod_def by auto -next - fix S T :: "('a \ 'b) set" - assume "open S" "open T" - show "open (S \ T)" - proof (rule open_prod_intro) - fix x assume x: "x \ S \ T" - from x have "x \ S" by simp - obtain Sa Sb where A: "open Sa" "open Sb" "x \ Sa \ Sb" "Sa \ Sb \ S" - using \open S\ and \x \ S\ by (rule open_prod_elim) - from x have "x \ T" by simp - obtain Ta Tb where B: "open Ta" "open Tb" "x \ Ta \ Tb" "Ta \ Tb \ T" - using \open T\ and \x \ T\ by (rule open_prod_elim) - let ?A = "Sa \ Ta" and ?B = "Sb \ Tb" - have "open ?A \ open ?B \ x \ ?A \ ?B \ ?A \ ?B \ S \ T" - using A B by (auto simp add: open_Int) - thus "\A B. open A \ open B \ x \ A \ B \ A \ B \ S \ T" - by fast - qed -next - fix K :: "('a \ 'b) set set" - assume "\S\K. open S" thus "open (\K)" - unfolding open_prod_def by fast -qed - -end - -declare [[code abort: "open::('a::topological_space*'b::topological_space) set \ bool"]] - -lemma open_Times: "open S \ open T \ open (S \ T)" -unfolding open_prod_def by auto - -lemma fst_vimage_eq_Times: "fst -` S = S \ UNIV" -by auto - -lemma snd_vimage_eq_Times: "snd -` S = UNIV \ S" -by auto - -lemma open_vimage_fst: "open S \ open (fst -` S)" -by (simp add: fst_vimage_eq_Times open_Times) - -lemma open_vimage_snd: "open S \ open (snd -` S)" -by (simp add: snd_vimage_eq_Times open_Times) - -lemma closed_vimage_fst: "closed S \ closed (fst -` S)" -unfolding closed_open vimage_Compl [symmetric] -by (rule open_vimage_fst) - -lemma closed_vimage_snd: "closed S \ closed (snd -` S)" -unfolding closed_open vimage_Compl [symmetric] -by (rule open_vimage_snd) - -lemma closed_Times: "closed S \ closed T \ closed (S \ T)" -proof - - have "S \ T = (fst -` S) \ (snd -` T)" by auto - thus "closed S \ closed T \ closed (S \ T)" - by (simp add: closed_vimage_fst closed_vimage_snd closed_Int) -qed - -lemma subset_fst_imageI: "A \ B \ S \ y \ B \ A \ fst ` S" - unfolding image_def subset_eq by force - -lemma subset_snd_imageI: "A \ B \ S \ x \ A \ B \ snd ` S" - unfolding image_def subset_eq by force - -lemma open_image_fst: assumes "open S" shows "open (fst ` S)" -proof (rule openI) - fix x assume "x \ fst ` S" - then obtain y where "(x, y) \ S" by auto - then obtain A B where "open A" "open B" "x \ A" "y \ B" "A \ B \ S" - using \open S\ unfolding open_prod_def by auto - from \A \ B \ S\ \y \ B\ have "A \ fst ` S" by (rule subset_fst_imageI) - with \open A\ \x \ A\ have "open A \ x \ A \ A \ fst ` S" by simp - then show "\T. open T \ x \ T \ T \ fst ` S" by - (rule exI) -qed - -lemma open_image_snd: assumes "open S" shows "open (snd ` S)" -proof (rule openI) - fix y assume "y \ snd ` S" - then obtain x where "(x, y) \ S" by auto - then obtain A B where "open A" "open B" "x \ A" "y \ B" "A \ B \ S" - using \open S\ unfolding open_prod_def by auto - from \A \ B \ S\ \x \ A\ have "B \ snd ` S" by (rule subset_snd_imageI) - with \open B\ \y \ B\ have "open B \ y \ B \ B \ snd ` S" by simp - then show "\T. open T \ y \ T \ T \ snd ` S" by - (rule exI) -qed - -subsubsection \Continuity of operations\ - -lemma tendsto_fst [tendsto_intros]: - assumes "(f \ a) F" - shows "((\x. fst (f x)) \ fst a) F" -proof (rule topological_tendstoI) - fix S assume "open S" and "fst a \ S" - then have "open (fst -` S)" and "a \ fst -` S" - by (simp_all add: open_vimage_fst) - with assms have "eventually (\x. f x \ fst -` S) F" - by (rule topological_tendstoD) - then show "eventually (\x. fst (f x) \ S) F" - by simp -qed - -lemma tendsto_snd [tendsto_intros]: - assumes "(f \ a) F" - shows "((\x. snd (f x)) \ snd a) F" -proof (rule topological_tendstoI) - fix S assume "open S" and "snd a \ S" - then have "open (snd -` S)" and "a \ snd -` S" - by (simp_all add: open_vimage_snd) - with assms have "eventually (\x. f x \ snd -` S) F" - by (rule topological_tendstoD) - then show "eventually (\x. snd (f x) \ S) F" - by simp -qed - -lemma tendsto_Pair [tendsto_intros]: - assumes "(f \ a) F" and "(g \ b) F" - shows "((\x. (f x, g x)) \ (a, b)) F" -proof (rule topological_tendstoI) - fix S assume "open S" and "(a, b) \ S" - then obtain A B where "open A" "open B" "a \ A" "b \ B" "A \ B \ S" - unfolding open_prod_def by fast - have "eventually (\x. f x \ A) F" - using \(f \ a) F\ \open A\ \a \ A\ - by (rule topological_tendstoD) - moreover - have "eventually (\x. g x \ B) F" - using \(g \ b) F\ \open B\ \b \ B\ - by (rule topological_tendstoD) - ultimately - show "eventually (\x. (f x, g x) \ S) F" - by (rule eventually_elim2) - (simp add: subsetD [OF \A \ B \ S\]) -qed - -lemma continuous_fst[continuous_intros]: "continuous F f \ continuous F (\x. fst (f x))" - unfolding continuous_def by (rule tendsto_fst) - -lemma continuous_snd[continuous_intros]: "continuous F f \ continuous F (\x. snd (f x))" - unfolding continuous_def by (rule tendsto_snd) - -lemma continuous_Pair[continuous_intros]: "continuous F f \ continuous F g \ continuous F (\x. (f x, g x))" - unfolding continuous_def by (rule tendsto_Pair) - -lemma continuous_on_fst[continuous_intros]: "continuous_on s f \ continuous_on s (\x. fst (f x))" - unfolding continuous_on_def by (auto intro: tendsto_fst) - -lemma continuous_on_snd[continuous_intros]: "continuous_on s f \ continuous_on s (\x. snd (f x))" - unfolding continuous_on_def by (auto intro: tendsto_snd) - -lemma continuous_on_Pair[continuous_intros]: "continuous_on s f \ continuous_on s g \ continuous_on s (\x. (f x, g x))" - unfolding continuous_on_def by (auto intro: tendsto_Pair) - -lemma continuous_on_swap[continuous_intros]: "continuous_on A prod.swap" - by (simp add: prod.swap_def continuous_on_fst continuous_on_snd continuous_on_Pair continuous_on_id) - -lemma continuous_on_swap_args: - assumes "continuous_on (A\B) (\(x,y). d x y)" - shows "continuous_on (B\A) (\(x,y). d y x)" -proof - - have "(\(x,y). d y x) = (\(x,y). d x y) o prod.swap" - by force - then show ?thesis - apply (rule ssubst) - apply (rule continuous_on_compose) - apply (force intro: continuous_on_subset [OF continuous_on_swap]) - apply (force intro: continuous_on_subset [OF assms]) - done -qed - -lemma isCont_fst [simp]: "isCont f a \ isCont (\x. fst (f x)) a" - by (fact continuous_fst) - -lemma isCont_snd [simp]: "isCont f a \ isCont (\x. snd (f x)) a" - by (fact continuous_snd) - -lemma isCont_Pair [simp]: "\isCont f a; isCont g a\ \ isCont (\x. (f x, g x)) a" - by (fact continuous_Pair) - -subsubsection \Separation axioms\ - -instance prod :: (t0_space, t0_space) t0_space -proof - fix x y :: "'a \ 'b" assume "x \ y" - hence "fst x \ fst y \ snd x \ snd y" - by (simp add: prod_eq_iff) - thus "\U. open U \ (x \ U) \ (y \ U)" - by (fast dest: t0_space elim: open_vimage_fst open_vimage_snd) -qed - -instance prod :: (t1_space, t1_space) t1_space -proof - fix x y :: "'a \ 'b" assume "x \ y" - hence "fst x \ fst y \ snd x \ snd y" - by (simp add: prod_eq_iff) - thus "\U. open U \ x \ U \ y \ U" - by (fast dest: t1_space elim: open_vimage_fst open_vimage_snd) -qed - -instance prod :: (t2_space, t2_space) t2_space -proof - fix x y :: "'a \ 'b" assume "x \ y" - hence "fst x \ fst y \ snd x \ snd y" - by (simp add: prod_eq_iff) - thus "\U V. open U \ open V \ x \ U \ y \ V \ U \ V = {}" - by (fast dest: hausdorff elim: open_vimage_fst open_vimage_snd) -qed - -lemma isCont_swap[continuous_intros]: "isCont prod.swap a" - using continuous_on_eq_continuous_within continuous_on_swap by blast - subsection \Product is a metric space\ (* TODO: Product of uniform spaces and compatibility with metric_spaces! *) diff -r 95c6cf433c91 -r d2bc8a7e5fec src/HOL/Topological_Spaces.thy --- a/src/HOL/Topological_Spaces.thy Thu Feb 18 17:53:09 2016 +0100 +++ b/src/HOL/Topological_Spaces.thy Mon Feb 08 17:18:13 2016 +0100 @@ -2610,4 +2610,254 @@ by (auto simp: filterlim_iff eventually_at_filter eventually_nhds_uniformity continuous_on_def elim: eventually_mono dest!: uniformly_continuous_onD[OF f]) +section \Product Topology\ + + +subsection \Product is a topological space\ + +instantiation prod :: (topological_space, topological_space) topological_space +begin + +definition open_prod_def[code del]: + "open (S :: ('a \ 'b) set) \ + (\x\S. \A B. open A \ open B \ x \ A \ B \ A \ B \ S)" + +lemma open_prod_elim: + assumes "open S" and "x \ S" + obtains A B where "open A" and "open B" and "x \ A \ B" and "A \ B \ S" +using assms unfolding open_prod_def by fast + +lemma open_prod_intro: + assumes "\x. x \ S \ \A B. open A \ open B \ x \ A \ B \ A \ B \ S" + shows "open S" +using assms unfolding open_prod_def by fast + +instance +proof + show "open (UNIV :: ('a \ 'b) set)" + unfolding open_prod_def by auto +next + fix S T :: "('a \ 'b) set" + assume "open S" "open T" + show "open (S \ T)" + proof (rule open_prod_intro) + fix x assume x: "x \ S \ T" + from x have "x \ S" by simp + obtain Sa Sb where A: "open Sa" "open Sb" "x \ Sa \ Sb" "Sa \ Sb \ S" + using \open S\ and \x \ S\ by (rule open_prod_elim) + from x have "x \ T" by simp + obtain Ta Tb where B: "open Ta" "open Tb" "x \ Ta \ Tb" "Ta \ Tb \ T" + using \open T\ and \x \ T\ by (rule open_prod_elim) + let ?A = "Sa \ Ta" and ?B = "Sb \ Tb" + have "open ?A \ open ?B \ x \ ?A \ ?B \ ?A \ ?B \ S \ T" + using A B by (auto simp add: open_Int) + thus "\A B. open A \ open B \ x \ A \ B \ A \ B \ S \ T" + by fast + qed +next + fix K :: "('a \ 'b) set set" + assume "\S\K. open S" thus "open (\K)" + unfolding open_prod_def by fast +qed + end + +declare [[code abort: "open::('a::topological_space*'b::topological_space) set \ bool"]] + +lemma open_Times: "open S \ open T \ open (S \ T)" +unfolding open_prod_def by auto + +lemma fst_vimage_eq_Times: "fst -` S = S \ UNIV" +by auto + +lemma snd_vimage_eq_Times: "snd -` S = UNIV \ S" +by auto + +lemma open_vimage_fst: "open S \ open (fst -` S)" +by (simp add: fst_vimage_eq_Times open_Times) + +lemma open_vimage_snd: "open S \ open (snd -` S)" +by (simp add: snd_vimage_eq_Times open_Times) + +lemma closed_vimage_fst: "closed S \ closed (fst -` S)" +unfolding closed_open vimage_Compl [symmetric] +by (rule open_vimage_fst) + +lemma closed_vimage_snd: "closed S \ closed (snd -` S)" +unfolding closed_open vimage_Compl [symmetric] +by (rule open_vimage_snd) + +lemma closed_Times: "closed S \ closed T \ closed (S \ T)" +proof - + have "S \ T = (fst -` S) \ (snd -` T)" by auto + thus "closed S \ closed T \ closed (S \ T)" + by (simp add: closed_vimage_fst closed_vimage_snd closed_Int) +qed + +lemma subset_fst_imageI: "A \ B \ S \ y \ B \ A \ fst ` S" + unfolding image_def subset_eq by force + +lemma subset_snd_imageI: "A \ B \ S \ x \ A \ B \ snd ` S" + unfolding image_def subset_eq by force + +lemma open_image_fst: assumes "open S" shows "open (fst ` S)" +proof (rule openI) + fix x assume "x \ fst ` S" + then obtain y where "(x, y) \ S" by auto + then obtain A B where "open A" "open B" "x \ A" "y \ B" "A \ B \ S" + using \open S\ unfolding open_prod_def by auto + from \A \ B \ S\ \y \ B\ have "A \ fst ` S" by (rule subset_fst_imageI) + with \open A\ \x \ A\ have "open A \ x \ A \ A \ fst ` S" by simp + then show "\T. open T \ x \ T \ T \ fst ` S" by - (rule exI) +qed + +lemma open_image_snd: assumes "open S" shows "open (snd ` S)" +proof (rule openI) + fix y assume "y \ snd ` S" + then obtain x where "(x, y) \ S" by auto + then obtain A B where "open A" "open B" "x \ A" "y \ B" "A \ B \ S" + using \open S\ unfolding open_prod_def by auto + from \A \ B \ S\ \x \ A\ have "B \ snd ` S" by (rule subset_snd_imageI) + with \open B\ \y \ B\ have "open B \ y \ B \ B \ snd ` S" by simp + then show "\T. open T \ y \ T \ T \ snd ` S" by - (rule exI) +qed + +lemma nhds_prod: "nhds (a, b) = nhds a \\<^sub>F nhds b" + unfolding nhds_def +proof (subst prod_filter_INF, auto intro!: antisym INF_greatest simp: principal_prod_principal) + fix S T assume "open S" "a \ S" "open T" "b \ T" + then show "(INF x : {S. open S \ (a, b) \ S}. principal x) \ principal (S \ T)" + by (intro INF_lower) (auto intro!: open_Times) +next + fix S' assume "open S'" "(a, b) \ S'" + then obtain S T where "open S" "a \ S" "open T" "b \ T" "S \ T \ S'" + by (auto elim: open_prod_elim) + then show "(INF x : {S. open S \ a \ S}. INF y : {S. open S \ b \ S}. principal (x \ y)) \ principal S'" + by (auto intro!: INF_lower2) +qed + +subsubsection \Continuity of operations\ + +lemma tendsto_fst [tendsto_intros]: + assumes "(f \ a) F" + shows "((\x. fst (f x)) \ fst a) F" +proof (rule topological_tendstoI) + fix S assume "open S" and "fst a \ S" + then have "open (fst -` S)" and "a \ fst -` S" + by (simp_all add: open_vimage_fst) + with assms have "eventually (\x. f x \ fst -` S) F" + by (rule topological_tendstoD) + then show "eventually (\x. fst (f x) \ S) F" + by simp +qed + +lemma tendsto_snd [tendsto_intros]: + assumes "(f \ a) F" + shows "((\x. snd (f x)) \ snd a) F" +proof (rule topological_tendstoI) + fix S assume "open S" and "snd a \ S" + then have "open (snd -` S)" and "a \ snd -` S" + by (simp_all add: open_vimage_snd) + with assms have "eventually (\x. f x \ snd -` S) F" + by (rule topological_tendstoD) + then show "eventually (\x. snd (f x) \ S) F" + by simp +qed + +lemma tendsto_Pair [tendsto_intros]: + assumes "(f \ a) F" and "(g \ b) F" + shows "((\x. (f x, g x)) \ (a, b)) F" +proof (rule topological_tendstoI) + fix S assume "open S" and "(a, b) \ S" + then obtain A B where "open A" "open B" "a \ A" "b \ B" "A \ B \ S" + unfolding open_prod_def by fast + have "eventually (\x. f x \ A) F" + using \(f \ a) F\ \open A\ \a \ A\ + by (rule topological_tendstoD) + moreover + have "eventually (\x. g x \ B) F" + using \(g \ b) F\ \open B\ \b \ B\ + by (rule topological_tendstoD) + ultimately + show "eventually (\x. (f x, g x) \ S) F" + by (rule eventually_elim2) + (simp add: subsetD [OF \A \ B \ S\]) +qed + +lemma continuous_fst[continuous_intros]: "continuous F f \ continuous F (\x. fst (f x))" + unfolding continuous_def by (rule tendsto_fst) + +lemma continuous_snd[continuous_intros]: "continuous F f \ continuous F (\x. snd (f x))" + unfolding continuous_def by (rule tendsto_snd) + +lemma continuous_Pair[continuous_intros]: "continuous F f \ continuous F g \ continuous F (\x. (f x, g x))" + unfolding continuous_def by (rule tendsto_Pair) + +lemma continuous_on_fst[continuous_intros]: "continuous_on s f \ continuous_on s (\x. fst (f x))" + unfolding continuous_on_def by (auto intro: tendsto_fst) + +lemma continuous_on_snd[continuous_intros]: "continuous_on s f \ continuous_on s (\x. snd (f x))" + unfolding continuous_on_def by (auto intro: tendsto_snd) + +lemma continuous_on_Pair[continuous_intros]: "continuous_on s f \ continuous_on s g \ continuous_on s (\x. (f x, g x))" + unfolding continuous_on_def by (auto intro: tendsto_Pair) + +lemma continuous_on_swap[continuous_intros]: "continuous_on A prod.swap" + by (simp add: prod.swap_def continuous_on_fst continuous_on_snd continuous_on_Pair continuous_on_id) + +lemma continuous_on_swap_args: + assumes "continuous_on (A\B) (\(x,y). d x y)" + shows "continuous_on (B\A) (\(x,y). d y x)" +proof - + have "(\(x,y). d y x) = (\(x,y). d x y) o prod.swap" + by force + then show ?thesis + apply (rule ssubst) + apply (rule continuous_on_compose) + apply (force intro: continuous_on_subset [OF continuous_on_swap]) + apply (force intro: continuous_on_subset [OF assms]) + done +qed + +lemma isCont_fst [simp]: "isCont f a \ isCont (\x. fst (f x)) a" + by (fact continuous_fst) + +lemma isCont_snd [simp]: "isCont f a \ isCont (\x. snd (f x)) a" + by (fact continuous_snd) + +lemma isCont_Pair [simp]: "\isCont f a; isCont g a\ \ isCont (\x. (f x, g x)) a" + by (fact continuous_Pair) + +subsubsection \Separation axioms\ + +instance prod :: (t0_space, t0_space) t0_space +proof + fix x y :: "'a \ 'b" assume "x \ y" + hence "fst x \ fst y \ snd x \ snd y" + by (simp add: prod_eq_iff) + thus "\U. open U \ (x \ U) \ (y \ U)" + by (fast dest: t0_space elim: open_vimage_fst open_vimage_snd) +qed + +instance prod :: (t1_space, t1_space) t1_space +proof + fix x y :: "'a \ 'b" assume "x \ y" + hence "fst x \ fst y \ snd x \ snd y" + by (simp add: prod_eq_iff) + thus "\U. open U \ x \ U \ y \ U" + by (fast dest: t1_space elim: open_vimage_fst open_vimage_snd) +qed + +instance prod :: (t2_space, t2_space) t2_space +proof + fix x y :: "'a \ 'b" assume "x \ y" + hence "fst x \ fst y \ snd x \ snd y" + by (simp add: prod_eq_iff) + thus "\U V. open U \ open V \ x \ U \ y \ V \ U \ V = {}" + by (fast dest: hausdorff elim: open_vimage_fst open_vimage_snd) +qed + +lemma isCont_swap[continuous_intros]: "isCont prod.swap a" + using continuous_on_eq_continuous_within continuous_on_swap by blast + +end