diff --git a/src/HOL/Analysis/Continuous_Extension.thy b/src/HOL/Analysis/Continuous_Extension.thy --- a/src/HOL/Analysis/Continuous_Extension.thy +++ b/src/HOL/Analysis/Continuous_Extension.thy @@ -1,537 +1,551 @@ (* Title: HOL/Analysis/Continuous_Extension.thy Authors: LC Paulson, based on material from HOL Light *) section \Continuous Extensions of Functions\ theory Continuous_Extension imports Starlike begin subsection\Partitions of unity subordinate to locally finite open coverings\ text\A difference from HOL Light: all summations over infinite sets equal zero, so the "support" must be made explicit in the summation below!\ proposition subordinate_partition_of_unity: fixes S :: "'a::metric_space set" assumes "S \ \\" and opC: "\T. T \ \ \ open T" and fin: "\x. x \ S \ \V. open V \ x \ V \ finite {U \ \. U \ V \ {}}" obtains F :: "['a set, 'a] \ real" where "\U. U \ \ \ continuous_on S (F U) \ (\x \ S. 0 \ F U x)" and "\x U. \U \ \; x \ S; x \ U\ \ F U x = 0" and "\x. x \ S \ supp_sum (\W. F W x) \ = 1" and "\x. x \ S \ \V. open V \ x \ V \ finite {U \ \. \x\V. F U x \ 0}" proof (cases "\W. W \ \ \ S \ W") case True then obtain W where "W \ \" "S \ W" by metis then show ?thesis by (rule_tac F = "\V x. if V = W then 1 else 0" in that) (auto simp: supp_sum_def support_on_def) next case False have nonneg: "0 \ supp_sum (\V. setdist {x} (S - V)) \" for x by (simp add: supp_sum_def sum_nonneg) have sd_pos: "0 < setdist {x} (S - V)" if "V \ \" "x \ S" "x \ V" for V x proof - have "closedin (top_of_set S) (S - V)" by (simp add: Diff_Diff_Int closedin_def opC openin_open_Int \V \ \\) with that False setdist_pos_le [of "{x}" "S - V"] show ?thesis using setdist_gt_0_closedin by fastforce qed have ss_pos: "0 < supp_sum (\V. setdist {x} (S - V)) \" if "x \ S" for x proof - obtain U where "U \ \" "x \ U" using \x \ S\ \S \ \\\ by blast obtain V where "open V" "x \ V" "finite {U \ \. U \ V \ {}}" using \x \ S\ fin by blast then have *: "finite {A \ \. \ S \ A \ x \ closure (S - A)}" using closure_def that by (blast intro: rev_finite_subset) have "x \ closure (S - U)" using \U \ \\ \x \ U\ opC open_Int_closure_eq_empty by fastforce then show ?thesis apply (simp add: setdist_eq_0_sing_1 supp_sum_def support_on_def) apply (rule ordered_comm_monoid_add_class.sum_pos2 [OF *, of U]) using \U \ \\ \x \ U\ False apply (auto simp: sd_pos that) done qed define F where "F \ \W x. if x \ S then setdist {x} (S - W) / supp_sum (\V. setdist {x} (S - V)) \ else 0" show ?thesis proof (rule_tac F = F in that) have "continuous_on S (F U)" if "U \ \" for U proof - have *: "continuous_on S (\x. supp_sum (\V. setdist {x} (S - V)) \)" proof (clarsimp simp add: continuous_on_eq_continuous_within) fix x assume "x \ S" then obtain X where "open X" and x: "x \ S \ X" and finX: "finite {U \ \. U \ X \ {}}" using assms by blast then have OSX: "openin (top_of_set S) (S \ X)" by blast have sumeq: "\x. x \ S \ X \ (\V | V \ \ \ V \ X \ {}. setdist {x} (S - V)) = supp_sum (\V. setdist {x} (S - V)) \" apply (simp add: supp_sum_def) apply (rule sum.mono_neutral_right [OF finX]) apply (auto simp: setdist_eq_0_sing_1 support_on_def subset_iff) apply (meson DiffI closure_subset disjoint_iff_not_equal subsetCE) done show "continuous (at x within S) (\x. supp_sum (\V. setdist {x} (S - V)) \)" apply (rule continuous_transform_within_openin [where f = "\x. (sum (\V. setdist {x} (S - V)) {V \ \. V \ X \ {}})" and S ="S \ X"]) apply (rule continuous_intros continuous_at_setdist continuous_at_imp_continuous_at_within OSX x)+ apply (simp add: sumeq) done qed show ?thesis apply (simp add: F_def) apply (rule continuous_intros *)+ using ss_pos apply force done qed moreover have "\U \ \; x \ S\ \ 0 \ F U x" for U x using nonneg [of x] by (simp add: F_def field_split_simps) ultimately show "\U. U \ \ \ continuous_on S (F U) \ (\x\S. 0 \ F U x)" by metis next show "\x U. \U \ \; x \ S; x \ U\ \ F U x = 0" by (simp add: setdist_eq_0_sing_1 closure_def F_def) next show "supp_sum (\W. F W x) \ = 1" if "x \ S" for x using that ss_pos [OF that] by (simp add: F_def field_split_simps supp_sum_divide_distrib [symmetric]) next show "\V. open V \ x \ V \ finite {U \ \. \x\V. F U x \ 0}" if "x \ S" for x using fin [OF that] that by (fastforce simp: setdist_eq_0_sing_1 closure_def F_def elim!: rev_finite_subset) qed qed subsection\Urysohn's Lemma for Euclidean Spaces\ text \For Euclidean spaces the proof is easy using distances.\ lemma Urysohn_both_ne: assumes US: "closedin (top_of_set U) S" and UT: "closedin (top_of_set U) T" and "S \ T = {}" "S \ {}" "T \ {}" "a \ b" obtains f :: "'a::euclidean_space \ 'b::real_normed_vector" where "continuous_on U f" "\x. x \ U \ f x \ closed_segment a b" "\x. x \ U \ (f x = a \ x \ S)" "\x. x \ U \ (f x = b \ x \ T)" proof - have S0: "\x. x \ U \ setdist {x} S = 0 \ x \ S" using \S \ {}\ US setdist_eq_0_closedin by auto have T0: "\x. x \ U \ setdist {x} T = 0 \ x \ T" using \T \ {}\ UT setdist_eq_0_closedin by auto have sdpos: "0 < setdist {x} S + setdist {x} T" if "x \ U" for x proof - have "\ (setdist {x} S = 0 \ setdist {x} T = 0)" using assms by (metis IntI empty_iff setdist_eq_0_closedin that) then show ?thesis by (metis add.left_neutral add.right_neutral add_pos_pos linorder_neqE_linordered_idom not_le setdist_pos_le) qed define f where "f \ \x. a + (setdist {x} S / (setdist {x} S + setdist {x} T)) *\<^sub>R (b - a)" show ?thesis proof (rule_tac f = f in that) show "continuous_on U f" using sdpos unfolding f_def by (intro continuous_intros | force)+ show "f x \ closed_segment a b" if "x \ U" for x unfolding f_def apply (simp add: closed_segment_def) apply (rule_tac x="(setdist {x} S / (setdist {x} S + setdist {x} T))" in exI) using sdpos that apply (simp add: algebra_simps) done show "\x. x \ U \ (f x = a \ x \ S)" using S0 \a \ b\ f_def sdpos by force show "(f x = b \ x \ T)" if "x \ U" for x proof - have "f x = b \ (setdist {x} S / (setdist {x} S + setdist {x} T)) = 1" unfolding f_def apply (rule iffI) apply (metis \a \ b\ add_diff_cancel_left' eq_iff_diff_eq_0 pth_1 real_vector.scale_right_imp_eq, force) done also have "... \ setdist {x} T = 0 \ setdist {x} S \ 0" using sdpos that by (simp add: field_split_simps) linarith also have "... \ x \ T" using \S \ {}\ \T \ {}\ \S \ T = {}\ that by (force simp: S0 T0) finally show ?thesis . qed qed qed proposition Urysohn_local_strong: assumes US: "closedin (top_of_set U) S" and UT: "closedin (top_of_set U) T" and "S \ T = {}" "a \ b" obtains f :: "'a::euclidean_space \ 'b::euclidean_space" where "continuous_on U f" "\x. x \ U \ f x \ closed_segment a b" "\x. x \ U \ (f x = a \ x \ S)" "\x. x \ U \ (f x = b \ x \ T)" proof (cases "S = {}") case True show ?thesis proof (cases "T = {}") case True show ?thesis proof (rule_tac f = "\x. midpoint a b" in that) show "continuous_on U (\x. midpoint a b)" by (intro continuous_intros) show "midpoint a b \ closed_segment a b" using csegment_midpoint_subset by blast show "(midpoint a b = a) = (x \ S)" for x using \S = {}\ \a \ b\ by simp show "(midpoint a b = b) = (x \ T)" for x using \T = {}\ \a \ b\ by simp qed next case False show ?thesis proof (cases "T = U") case True with \S = {}\ \a \ b\ show ?thesis by (rule_tac f = "\x. b" in that) (auto) next case False with UT closedin_subset obtain c where c: "c \ U" "c \ T" by fastforce obtain f where f: "continuous_on U f" "\x. x \ U \ f x \ closed_segment (midpoint a b) b" "\x. x \ U \ (f x = midpoint a b \ x = c)" "\x. x \ U \ (f x = b \ x \ T)" apply (rule Urysohn_both_ne [of U "{c}" T "midpoint a b" "b"]) using c \T \ {}\ assms apply simp_all done show ?thesis apply (rule_tac f=f in that) using \S = {}\ \T \ {}\ f csegment_midpoint_subset notin_segment_midpoint [OF \a \ b\] apply force+ done qed qed next case False show ?thesis proof (cases "T = {}") case True show ?thesis proof (cases "S = U") case True with \T = {}\ \a \ b\ show ?thesis by (rule_tac f = "\x. a" in that) (auto) next case False with US closedin_subset obtain c where c: "c \ U" "c \ S" by fastforce obtain f where f: "continuous_on U f" "\x. x \ U \ f x \ closed_segment a (midpoint a b)" "\x. x \ U \ (f x = midpoint a b \ x = c)" "\x. x \ U \ (f x = a \ x \ S)" apply (rule Urysohn_both_ne [of U S "{c}" a "midpoint a b"]) using c \S \ {}\ assms apply simp_all apply (metis midpoint_eq_endpoint) done show ?thesis apply (rule_tac f=f in that) using \S \ {}\ \T = {}\ f \a \ b\ apply simp_all apply (metis (no_types) closed_segment_commute csegment_midpoint_subset midpoint_sym subset_iff) apply (metis closed_segment_commute midpoint_sym notin_segment_midpoint) done qed next case False show ?thesis using Urysohn_both_ne [OF US UT \S \ T = {}\ \S \ {}\ \T \ {}\ \a \ b\] that by blast qed qed lemma Urysohn_local: assumes US: "closedin (top_of_set U) S" and UT: "closedin (top_of_set U) T" and "S \ T = {}" obtains f :: "'a::euclidean_space \ 'b::euclidean_space" where "continuous_on U f" "\x. x \ U \ f x \ closed_segment a b" "\x. x \ S \ f x = a" "\x. x \ T \ f x = b" proof (cases "a = b") case True then show ?thesis by (rule_tac f = "\x. b" in that) (auto) next case False then show ?thesis apply (rule Urysohn_local_strong [OF assms]) apply (erule that, assumption) apply (meson US closedin_singleton closedin_trans) apply (meson UT closedin_singleton closedin_trans) done qed lemma Urysohn_strong: assumes US: "closed S" and UT: "closed T" and "S \ T = {}" "a \ b" obtains f :: "'a::euclidean_space \ 'b::euclidean_space" where "continuous_on UNIV f" "\x. f x \ closed_segment a b" "\x. f x = a \ x \ S" "\x. f x = b \ x \ T" using assms by (auto intro: Urysohn_local_strong [of UNIV S T]) proposition Urysohn: assumes US: "closed S" and UT: "closed T" and "S \ T = {}" obtains f :: "'a::euclidean_space \ 'b::euclidean_space" where "continuous_on UNIV f" "\x. f x \ closed_segment a b" "\x. x \ S \ f x = a" "\x. x \ T \ f x = b" using assms by (auto intro: Urysohn_local [of UNIV S T a b]) subsection\Dugundji's Extension Theorem and Tietze Variants\ text \See \cite{dugundji}.\ +lemma convex_supp_sum: + assumes "convex S" and 1: "supp_sum u I = 1" + and "\i. i \ I \ 0 \ u i \ (u i = 0 \ f i \ S)" + shows "supp_sum (\i. u i *\<^sub>R f i) I \ S" +proof - + have fin: "finite {i \ I. u i \ 0}" + using 1 sum.infinite by (force simp: supp_sum_def support_on_def) + then have "supp_sum (\i. u i *\<^sub>R f i) I = sum (\i. u i *\<^sub>R f i) {i \ I. u i \ 0}" + by (force intro: sum.mono_neutral_left simp: supp_sum_def support_on_def) + also have "... \ S" + using 1 assms by (force simp: supp_sum_def support_on_def intro: convex_sum [OF fin \convex S\]) + finally show ?thesis . +qed + theorem Dugundji: fixes f :: "'a::{metric_space,second_countable_topology} \ 'b::real_inner" assumes "convex C" "C \ {}" and cloin: "closedin (top_of_set U) S" and contf: "continuous_on S f" and "f ` S \ C" obtains g where "continuous_on U g" "g ` U \ C" "\x. x \ S \ g x = f x" proof (cases "S = {}") case True then show thesis apply (rule_tac g="\x. SOME y. y \ C" in that) apply (rule continuous_intros) apply (meson all_not_in_conv \C \ {}\ image_subsetI someI_ex, simp) done next case False then have sd_pos: "\x. \x \ U; x \ S\ \ 0 < setdist {x} S" using setdist_eq_0_closedin [OF cloin] le_less setdist_pos_le by fastforce define \ where "\ = {ball x (setdist {x} S / 2) |x. x \ U - S}" have [simp]: "\T. T \ \ \ open T" by (auto simp: \_def) have USS: "U - S \ \\" by (auto simp: sd_pos \_def) obtain \ where USsub: "U - S \ \\" and nbrhd: "\U. U \ \ \ open U \ (\T. T \ \ \ U \ T)" and fin: "\x. x \ U - S \ \V. open V \ x \ V \ finite {U. U \ \ \ U \ V \ {}}" by (rule paracompact [OF USS]) auto have "\v a. v \ U \ v \ S \ a \ S \ T \ ball v (setdist {v} S / 2) \ dist v a \ 2 * setdist {v} S" if "T \ \" for T proof - obtain v where v: "T \ ball v (setdist {v} S / 2)" "v \ U" "v \ S" using \T \ \\ nbrhd by (force simp: \_def) then obtain a where "a \ S" "dist v a < 2 * setdist {v} S" using setdist_ltE [of "{v}" S "2 * setdist {v} S"] using False sd_pos by force with v show ?thesis apply (rule_tac x=v in exI) apply (rule_tac x=a in exI, auto) done qed then obtain \ \ where VA: "\T. T \ \ \ \ T \ U \ \ T \ S \ \ T \ S \ T \ ball (\ T) (setdist {\ T} S / 2) \ dist (\ T) (\ T) \ 2 * setdist {\ T} S" by metis have sdle: "setdist {\ T} S \ 2 * setdist {v} S" if "T \ \" "v \ T" for T v using setdist_Lipschitz [of "\ T" S v] VA [OF \T \ \\] \v \ T\ by auto have d6: "dist a (\ T) \ 6 * dist a v" if "T \ \" "v \ T" "a \ S" for T v a proof - have "dist (\ T) v < setdist {\ T} S / 2" using that VA mem_ball by blast also have "\ \ setdist {v} S" using sdle [OF \T \ \\ \v \ T\] by simp also have vS: "setdist {v} S \ dist a v" by (simp add: setdist_le_dist setdist_sym \a \ S\) finally have VTV: "dist (\ T) v < dist a v" . have VTS: "setdist {\ T} S \ 2 * dist a v" using sdle that vS by force have "dist a (\ T) \ dist a v + dist v (\ T) + dist (\ T) (\ T)" by (metis add.commute add_le_cancel_left dist_commute dist_triangle2 dist_triangle_le) also have "\ \ dist a v + dist a v + dist (\ T) (\ T)" using VTV by (simp add: dist_commute) also have "\ \ 2 * dist a v + 2 * setdist {\ T} S" using VA [OF \T \ \\] by auto finally show ?thesis using VTS by linarith qed obtain H :: "['a set, 'a] \ real" where Hcont: "\Z. Z \ \ \ continuous_on (U-S) (H Z)" and Hge0: "\Z x. \Z \ \; x \ U-S\ \ 0 \ H Z x" and Heq0: "\x Z. \Z \ \; x \ U-S; x \ Z\ \ H Z x = 0" and H1: "\x. x \ U-S \ supp_sum (\W. H W x) \ = 1" and Hfin: "\x. x \ U-S \ \V. open V \ x \ V \ finite {U \ \. \x\V. H U x \ 0}" apply (rule subordinate_partition_of_unity [OF USsub _ fin]) using nbrhd by auto define g where "g \ \x. if x \ S then f x else supp_sum (\T. H T x *\<^sub>R f(\ T)) \" show ?thesis proof (rule that) show "continuous_on U g" proof (clarsimp simp: continuous_on_eq_continuous_within) fix a assume "a \ U" show "continuous (at a within U) g" proof (cases "a \ S") case True show ?thesis proof (clarsimp simp add: continuous_within_topological) fix W assume "open W" "g a \ W" then obtain e where "0 < e" and e: "ball (f a) e \ W" using openE True g_def by auto have "continuous (at a within S) f" using True contf continuous_on_eq_continuous_within by blast then obtain d where "0 < d" and d: "\x. \x \ S; dist x a < d\ \ dist (f x) (f a) < e" using continuous_within_eps_delta \0 < e\ by force have "g y \ ball (f a) e" if "y \ U" and y: "y \ ball a (d / 6)" for y proof (cases "y \ S") case True then have "dist (f a) (f y) < e" by (metis ball_divide_subset_numeral dist_commute in_mono mem_ball y d) then show ?thesis by (simp add: True g_def) next case False have *: "dist (f (\ T)) (f a) < e" if "T \ \" "H T y \ 0" for T proof - have "y \ T" using Heq0 that False \y \ U\ by blast have "dist (\ T) a < d" using d6 [OF \T \ \\ \y \ T\ \a \ S\] y by (simp add: dist_commute mult.commute) then show ?thesis using VA [OF \T \ \\] by (auto simp: d) qed have "supp_sum (\T. H T y *\<^sub>R f (\ T)) \ \ ball (f a) e" apply (rule convex_supp_sum [OF convex_ball]) apply (simp_all add: False H1 Hge0 \y \ U\) by (metis dist_commute *) then show ?thesis by (simp add: False g_def) qed then show "\A. open A \ a \ A \ (\y\U. y \ A \ g y \ W)" apply (rule_tac x = "ball a (d / 6)" in exI) using e \0 < d\ by fastforce qed next case False obtain N where N: "open N" "a \ N" and finN: "finite {U \ \. \a\N. H U a \ 0}" using Hfin False \a \ U\ by auto have oUS: "openin (top_of_set U) (U - S)" using cloin by (simp add: openin_diff) have HcontU: "continuous (at a within U) (H T)" if "T \ \" for T using Hcont [OF \T \ \\] False \a \ U\ \T \ \\ apply (simp add: continuous_on_eq_continuous_within continuous_within) apply (rule Lim_transform_within_set) using oUS apply (force simp: eventually_at openin_contains_ball dist_commute dest!: bspec)+ done show ?thesis proof (rule continuous_transform_within_openin [OF _ oUS]) show "continuous (at a within U) (\x. supp_sum (\T. H T x *\<^sub>R f (\ T)) \)" proof (rule continuous_transform_within_openin) show "continuous (at a within U) (\x. \T\{U \ \. \x\N. H U x \ 0}. H T x *\<^sub>R f (\ T))" by (force intro: continuous_intros HcontU)+ next show "openin (top_of_set U) ((U - S) \ N)" using N oUS openin_trans by blast next show "a \ (U - S) \ N" using False \a \ U\ N by blast next show "\x. x \ (U - S) \ N \ (\T \ {U \ \. \x\N. H U x \ 0}. H T x *\<^sub>R f (\ T)) = supp_sum (\T. H T x *\<^sub>R f (\ T)) \" by (auto simp: supp_sum_def support_on_def intro: sum.mono_neutral_right [OF finN]) qed next show "a \ U - S" using False \a \ U\ by blast next show "\x. x \ U - S \ supp_sum (\T. H T x *\<^sub>R f (\ T)) \ = g x" by (simp add: g_def) qed qed qed show "g ` U \ C" using \f ` S \ C\ VA by (fastforce simp: g_def Hge0 intro!: convex_supp_sum [OF \convex C\] H1) show "\x. x \ S \ g x = f x" by (simp add: g_def) qed qed corollary Tietze: fixes f :: "'a::{metric_space,second_countable_topology} \ 'b::real_inner" assumes "continuous_on S f" and "closedin (top_of_set U) S" and "0 \ B" and "\x. x \ S \ norm(f x) \ B" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" "\x. x \ U \ norm(g x) \ B" using assms by (auto simp: image_subset_iff intro: Dugundji [of "cball 0 B" U S f]) corollary\<^marker>\tag unimportant\ Tietze_closed_interval: fixes f :: "'a::{metric_space,second_countable_topology} \ 'b::euclidean_space" assumes "continuous_on S f" and "closedin (top_of_set U) S" and "cbox a b \ {}" and "\x. x \ S \ f x \ cbox a b" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" "\x. x \ U \ g x \ cbox a b" apply (rule Dugundji [of "cbox a b" U S f]) using assms by auto corollary\<^marker>\tag unimportant\ Tietze_closed_interval_1: fixes f :: "'a::{metric_space,second_countable_topology} \ real" assumes "continuous_on S f" and "closedin (top_of_set U) S" and "a \ b" and "\x. x \ S \ f x \ cbox a b" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" "\x. x \ U \ g x \ cbox a b" apply (rule Dugundji [of "cbox a b" U S f]) using assms by (auto simp: image_subset_iff) corollary\<^marker>\tag unimportant\ Tietze_open_interval: fixes f :: "'a::{metric_space,second_countable_topology} \ 'b::euclidean_space" assumes "continuous_on S f" and "closedin (top_of_set U) S" and "box a b \ {}" and "\x. x \ S \ f x \ box a b" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" "\x. x \ U \ g x \ box a b" apply (rule Dugundji [of "box a b" U S f]) using assms by auto corollary\<^marker>\tag unimportant\ Tietze_open_interval_1: fixes f :: "'a::{metric_space,second_countable_topology} \ real" assumes "continuous_on S f" and "closedin (top_of_set U) S" and "a < b" and no: "\x. x \ S \ f x \ box a b" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" "\x. x \ U \ g x \ box a b" apply (rule Dugundji [of "box a b" U S f]) using assms by (auto simp: image_subset_iff) corollary\<^marker>\tag unimportant\ Tietze_unbounded: fixes f :: "'a::{metric_space,second_countable_topology} \ 'b::real_inner" assumes "continuous_on S f" and "closedin (top_of_set U) S" obtains g where "continuous_on U g" "\x. x \ S \ g x = f x" apply (rule Dugundji [of UNIV U S f]) using assms by auto end diff --git a/src/HOL/Analysis/Line_Segment.thy b/src/HOL/Analysis/Line_Segment.thy --- a/src/HOL/Analysis/Line_Segment.thy +++ b/src/HOL/Analysis/Line_Segment.thy @@ -1,1265 +1,1195 @@ (* Title: HOL/Analysis/Line_Segment.thy Author: L C Paulson, University of Cambridge Author: Robert Himmelmann, TU Muenchen Author: Bogdan Grechuk, University of Edinburgh Author: Armin Heller, TU Muenchen Author: Johannes Hoelzl, TU Muenchen *) section \Line Segment\ theory Line_Segment imports Convex Topology_Euclidean_Space begin subsection\<^marker>\tag unimportant\ \Topological Properties of Convex Sets, Metric Spaces and Functions\ lemma convex_supp_sum: assumes "convex S" and 1: "supp_sum u I = 1" and "\i. i \ I \ 0 \ u i \ (u i = 0 \ f i \ S)" shows "supp_sum (\i. u i *\<^sub>R f i) I \ S" proof - have fin: "finite {i \ I. u i \ 0}" using 1 sum.infinite by (force simp: supp_sum_def support_on_def) then have "supp_sum (\i. u i *\<^sub>R f i) I = sum (\i. u i *\<^sub>R f i) {i \ I. u i \ 0}" by (force intro: sum.mono_neutral_left simp: supp_sum_def support_on_def) also have "... \ S" using 1 assms by (force simp: supp_sum_def support_on_def intro: convex_sum [OF fin \convex S\]) finally show ?thesis . qed -lemma closure_bounded_linear_image_subset: - assumes f: "bounded_linear f" - shows "f ` closure S \ closure (f ` S)" - using linear_continuous_on [OF f] closed_closure closure_subset - by (rule image_closure_subset) - -lemma closure_linear_image_subset: - fixes f :: "'m::euclidean_space \ 'n::real_normed_vector" - assumes "linear f" - shows "f ` (closure S) \ closure (f ` S)" - using assms unfolding linear_conv_bounded_linear - by (rule closure_bounded_linear_image_subset) - -lemma closed_injective_linear_image: - fixes f :: "'a::euclidean_space \ 'b::euclidean_space" - assumes S: "closed S" and f: "linear f" "inj f" - shows "closed (f ` S)" -proof - - obtain g where g: "linear g" "g \ f = id" - using linear_injective_left_inverse [OF f] by blast - then have confg: "continuous_on (range f) g" - using linear_continuous_on linear_conv_bounded_linear by blast - have [simp]: "g ` f ` S = S" - using g by (simp add: image_comp) - have cgf: "closed (g ` f ` S)" - by (simp add: \g \ f = id\ S image_comp) - have [simp]: "(range f \ g -` S) = f ` S" - using g unfolding o_def id_def image_def by auto metis+ - show ?thesis - proof (rule closedin_closed_trans [of "range f"]) - show "closedin (top_of_set (range f)) (f ` S)" - using continuous_closedin_preimage [OF confg cgf] by simp - show "closed (range f)" - apply (rule closed_injective_image_subspace) - using f apply (auto simp: linear_linear linear_injective_0) - done - qed -qed - -lemma closed_injective_linear_image_eq: - fixes f :: "'a::euclidean_space \ 'b::euclidean_space" - assumes f: "linear f" "inj f" - shows "(closed(image f s) \ closed s)" - by (metis closed_injective_linear_image closure_eq closure_linear_image_subset closure_subset_eq f(1) f(2) inj_image_subset_iff) - -lemma closure_injective_linear_image: - fixes f :: "'a::euclidean_space \ 'b::euclidean_space" - shows "\linear f; inj f\ \ f ` (closure S) = closure (f ` S)" - apply (rule subset_antisym) - apply (simp add: closure_linear_image_subset) - by (simp add: closure_minimal closed_injective_linear_image closure_subset image_mono) - -lemma closure_bounded_linear_image: - fixes f :: "'a::euclidean_space \ 'b::euclidean_space" - shows "\linear f; bounded S\ \ f ` (closure S) = closure (f ` S)" - apply (rule subset_antisym, simp add: closure_linear_image_subset) - apply (rule closure_minimal, simp add: closure_subset image_mono) - by (meson bounded_closure closed_closure compact_continuous_image compact_eq_bounded_closed linear_continuous_on linear_conv_bounded_linear) - -lemma closure_scaleR: - fixes S :: "'a::real_normed_vector set" - shows "((*\<^sub>R) c) ` (closure S) = closure (((*\<^sub>R) c) ` S)" -proof - show "((*\<^sub>R) c) ` (closure S) \ closure (((*\<^sub>R) c) ` S)" - using bounded_linear_scaleR_right - by (rule closure_bounded_linear_image_subset) - show "closure (((*\<^sub>R) c) ` S) \ ((*\<^sub>R) c) ` (closure S)" - by (intro closure_minimal image_mono closure_subset closed_scaling closed_closure) -qed - lemma sphere_eq_empty [simp]: fixes a :: "'a::{real_normed_vector, perfect_space}" shows "sphere a r = {} \ r < 0" by (auto simp: sphere_def dist_norm) (metis dist_norm le_less_linear vector_choose_dist) lemma cone_closure: fixes S :: "'a::real_normed_vector set" assumes "cone S" shows "cone (closure S)" proof (cases "S = {}") case True then show ?thesis by auto next case False then have "0 \ S \ (\c. c > 0 \ (*\<^sub>R) c ` S = S)" using cone_iff[of S] assms by auto then have "0 \ closure S \ (\c. c > 0 \ (*\<^sub>R) c ` closure S = closure S)" using closure_subset by (auto simp: closure_scaleR) then show ?thesis using False cone_iff[of "closure S"] by auto qed corollary component_complement_connected: fixes S :: "'a::real_normed_vector set" assumes "connected S" "C \ components (-S)" shows "connected(-C)" using component_diff_connected [of S UNIV] assms by (auto simp: Compl_eq_Diff_UNIV) proposition clopen: fixes S :: "'a :: real_normed_vector set" shows "closed S \ open S \ S = {} \ S = UNIV" by (force intro!: connected_UNIV [unfolded connected_clopen, rule_format]) corollary compact_open: fixes S :: "'a :: euclidean_space set" shows "compact S \ open S \ S = {}" by (auto simp: compact_eq_bounded_closed clopen) corollary finite_imp_not_open: fixes S :: "'a::{real_normed_vector, perfect_space} set" shows "\finite S; open S\ \ S={}" using clopen [of S] finite_imp_closed not_bounded_UNIV by blast corollary empty_interior_finite: fixes S :: "'a::{real_normed_vector, perfect_space} set" shows "finite S \ interior S = {}" by (metis interior_subset finite_subset open_interior [of S] finite_imp_not_open) text \Balls, being convex, are connected.\ lemma convex_local_global_minimum: fixes s :: "'a::real_normed_vector set" assumes "e > 0" and "convex_on s f" and "ball x e \ s" and "\y\ball x e. f x \ f y" shows "\y\s. f x \ f y" proof (rule ccontr) have "x \ s" using assms(1,3) by auto assume "\ ?thesis" then obtain y where "y\s" and y: "f x > f y" by auto then have xy: "0 < dist x y" by auto then obtain u where "0 < u" "u \ 1" and u: "u < e / dist x y" using field_lbound_gt_zero[of 1 "e / dist x y"] xy \e>0\ by auto then have "f ((1-u) *\<^sub>R x + u *\<^sub>R y) \ (1-u) * f x + u * f y" using \x\s\ \y\s\ using assms(2)[unfolded convex_on_def, THEN bspec[where x=x], THEN bspec[where x=y], THEN spec[where x="1-u"]] by auto moreover have *: "x - ((1 - u) *\<^sub>R x + u *\<^sub>R y) = u *\<^sub>R (x - y)" by (simp add: algebra_simps) have "(1 - u) *\<^sub>R x + u *\<^sub>R y \ ball x e" unfolding mem_ball dist_norm unfolding * and norm_scaleR and abs_of_pos[OF \0] unfolding dist_norm[symmetric] using u unfolding pos_less_divide_eq[OF xy] by auto then have "f x \ f ((1 - u) *\<^sub>R x + u *\<^sub>R y)" using assms(4) by auto ultimately show False using mult_strict_left_mono[OF y \u>0\] unfolding left_diff_distrib by auto qed lemma convex_ball [iff]: fixes x :: "'a::real_normed_vector" shows "convex (ball x e)" proof (auto simp: convex_def) fix y z assume yz: "dist x y < e" "dist x z < e" fix u v :: real assume uv: "0 \ u" "0 \ v" "u + v = 1" have "dist x (u *\<^sub>R y + v *\<^sub>R z) \ u * dist x y + v * dist x z" using uv yz using convex_on_dist [of "ball x e" x, unfolded convex_on_def, THEN bspec[where x=y], THEN bspec[where x=z]] by auto then show "dist x (u *\<^sub>R y + v *\<^sub>R z) < e" using convex_bound_lt[OF yz uv] by auto qed lemma convex_cball [iff]: fixes x :: "'a::real_normed_vector" shows "convex (cball x e)" proof - { fix y z assume yz: "dist x y \ e" "dist x z \ e" fix u v :: real assume uv: "0 \ u" "0 \ v" "u + v = 1" have "dist x (u *\<^sub>R y + v *\<^sub>R z) \ u * dist x y + v * dist x z" using uv yz using convex_on_dist [of "cball x e" x, unfolded convex_on_def, THEN bspec[where x=y], THEN bspec[where x=z]] by auto then have "dist x (u *\<^sub>R y + v *\<^sub>R z) \ e" using convex_bound_le[OF yz uv] by auto } then show ?thesis by (auto simp: convex_def Ball_def) qed lemma connected_ball [iff]: fixes x :: "'a::real_normed_vector" shows "connected (ball x e)" using convex_connected convex_ball by auto lemma connected_cball [iff]: fixes x :: "'a::real_normed_vector" shows "connected (cball x e)" using convex_connected convex_cball by auto lemma bounded_convex_hull: fixes s :: "'a::real_normed_vector set" assumes "bounded s" shows "bounded (convex hull s)" proof - from assms obtain B where B: "\x\s. norm x \ B" unfolding bounded_iff by auto show ?thesis by (simp add: bounded_subset[OF bounded_cball, of _ 0 B] B subsetI subset_hull) qed lemma finite_imp_bounded_convex_hull: fixes s :: "'a::real_normed_vector set" shows "finite s \ bounded (convex hull s)" using bounded_convex_hull finite_imp_bounded by auto subsection \Midpoint\ definition\<^marker>\tag important\ midpoint :: "'a::real_vector \ 'a \ 'a" where "midpoint a b = (inverse (2::real)) *\<^sub>R (a + b)" lemma midpoint_idem [simp]: "midpoint x x = x" unfolding midpoint_def by simp lemma midpoint_sym: "midpoint a b = midpoint b a" unfolding midpoint_def by (auto simp add: scaleR_right_distrib) lemma midpoint_eq_iff: "midpoint a b = c \ a + b = c + c" proof - have "midpoint a b = c \ scaleR 2 (midpoint a b) = scaleR 2 c" by simp then show ?thesis unfolding midpoint_def scaleR_2 [symmetric] by simp qed lemma fixes a::real assumes "a \ b" shows ge_midpoint_1: "a \ midpoint a b" and le_midpoint_1: "midpoint a b \ b" by (simp_all add: midpoint_def assms) lemma dist_midpoint: fixes a b :: "'a::real_normed_vector" shows "dist a (midpoint a b) = (dist a b) / 2" (is ?t1) "dist b (midpoint a b) = (dist a b) / 2" (is ?t2) "dist (midpoint a b) a = (dist a b) / 2" (is ?t3) "dist (midpoint a b) b = (dist a b) / 2" (is ?t4) proof - have *: "\x y::'a. 2 *\<^sub>R x = - y \ norm x = (norm y) / 2" unfolding equation_minus_iff by auto have **: "\x y::'a. 2 *\<^sub>R x = y \ norm x = (norm y) / 2" by auto note scaleR_right_distrib [simp] show ?t1 unfolding midpoint_def dist_norm apply (rule **) apply (simp add: scaleR_right_diff_distrib) apply (simp add: scaleR_2) done show ?t2 unfolding midpoint_def dist_norm apply (rule *) apply (simp add: scaleR_right_diff_distrib) apply (simp add: scaleR_2) done show ?t3 unfolding midpoint_def dist_norm apply (rule *) apply (simp add: scaleR_right_diff_distrib) apply (simp add: scaleR_2) done show ?t4 unfolding midpoint_def dist_norm apply (rule **) apply (simp add: scaleR_right_diff_distrib) apply (simp add: scaleR_2) done qed lemma midpoint_eq_endpoint [simp]: "midpoint a b = a \ a = b" "midpoint a b = b \ a = b" unfolding midpoint_eq_iff by auto lemma midpoint_plus_self [simp]: "midpoint a b + midpoint a b = a + b" using midpoint_eq_iff by metis lemma midpoint_linear_image: "linear f \ midpoint(f a)(f b) = f(midpoint a b)" by (simp add: linear_iff midpoint_def) subsection \Open and closed segments\ definition\<^marker>\tag important\ closed_segment :: "'a::real_vector \ 'a \ 'a set" where "closed_segment a b = {(1 - u) *\<^sub>R a + u *\<^sub>R b | u::real. 0 \ u \ u \ 1}" definition\<^marker>\tag important\ open_segment :: "'a::real_vector \ 'a \ 'a set" where "open_segment a b \ closed_segment a b - {a,b}" lemmas segment = open_segment_def closed_segment_def lemma in_segment: "x \ closed_segment a b \ (\u. 0 \ u \ u \ 1 \ x = (1 - u) *\<^sub>R a + u *\<^sub>R b)" "x \ open_segment a b \ a \ b \ (\u. 0 < u \ u < 1 \ x = (1 - u) *\<^sub>R a + u *\<^sub>R b)" using less_eq_real_def by (auto simp: segment algebra_simps) lemma closed_segment_linear_image: "closed_segment (f a) (f b) = f ` (closed_segment a b)" if "linear f" proof - interpret linear f by fact show ?thesis by (force simp add: in_segment add scale) qed lemma open_segment_linear_image: "\linear f; inj f\ \ open_segment (f a) (f b) = f ` (open_segment a b)" by (force simp: open_segment_def closed_segment_linear_image inj_on_def) lemma closed_segment_translation: "closed_segment (c + a) (c + b) = image (\x. c + x) (closed_segment a b)" apply safe apply (rule_tac x="x-c" in image_eqI) apply (auto simp: in_segment algebra_simps) done lemma open_segment_translation: "open_segment (c + a) (c + b) = image (\x. c + x) (open_segment a b)" by (simp add: open_segment_def closed_segment_translation translation_diff) lemma closed_segment_of_real: "closed_segment (of_real x) (of_real y) = of_real ` closed_segment x y" apply (auto simp: image_iff in_segment scaleR_conv_of_real) apply (rule_tac x="(1-u)*x + u*y" in bexI) apply (auto simp: in_segment) done lemma open_segment_of_real: "open_segment (of_real x) (of_real y) = of_real ` open_segment x y" apply (auto simp: image_iff in_segment scaleR_conv_of_real) apply (rule_tac x="(1-u)*x + u*y" in bexI) apply (auto simp: in_segment) done lemma closed_segment_Reals: "\x \ Reals; y \ Reals\ \ closed_segment x y = of_real ` closed_segment (Re x) (Re y)" by (metis closed_segment_of_real of_real_Re) lemma open_segment_Reals: "\x \ Reals; y \ Reals\ \ open_segment x y = of_real ` open_segment (Re x) (Re y)" by (metis open_segment_of_real of_real_Re) lemma open_segment_PairD: "(x, x') \ open_segment (a, a') (b, b') \ (x \ open_segment a b \ a = b) \ (x' \ open_segment a' b' \ a' = b')" by (auto simp: in_segment) lemma closed_segment_PairD: "(x, x') \ closed_segment (a, a') (b, b') \ x \ closed_segment a b \ x' \ closed_segment a' b'" by (auto simp: closed_segment_def) lemma closed_segment_translation_eq [simp]: "d + x \ closed_segment (d + a) (d + b) \ x \ closed_segment a b" proof - have *: "\d x a b. x \ closed_segment a b \ d + x \ closed_segment (d + a) (d + b)" apply (simp add: closed_segment_def) apply (erule ex_forward) apply (simp add: algebra_simps) done show ?thesis using * [where d = "-d"] * by (fastforce simp add:) qed lemma open_segment_translation_eq [simp]: "d + x \ open_segment (d + a) (d + b) \ x \ open_segment a b" by (simp add: open_segment_def) lemma of_real_closed_segment [simp]: "of_real x \ closed_segment (of_real a) (of_real b) \ x \ closed_segment a b" apply (auto simp: in_segment scaleR_conv_of_real elim!: ex_forward) using of_real_eq_iff by fastforce lemma of_real_open_segment [simp]: "of_real x \ open_segment (of_real a) (of_real b) \ x \ open_segment a b" apply (auto simp: in_segment scaleR_conv_of_real elim!: ex_forward del: exE) using of_real_eq_iff by fastforce lemma convex_contains_segment: "convex S \ (\a\S. \b\S. closed_segment a b \ S)" unfolding convex_alt closed_segment_def by auto lemma closed_segment_in_Reals: "\x \ closed_segment a b; a \ Reals; b \ Reals\ \ x \ Reals" by (meson subsetD convex_Reals convex_contains_segment) lemma open_segment_in_Reals: "\x \ open_segment a b; a \ Reals; b \ Reals\ \ x \ Reals" by (metis Diff_iff closed_segment_in_Reals open_segment_def) lemma closed_segment_subset: "\x \ S; y \ S; convex S\ \ closed_segment x y \ S" by (simp add: convex_contains_segment) lemma closed_segment_subset_convex_hull: "\x \ convex hull S; y \ convex hull S\ \ closed_segment x y \ convex hull S" using convex_contains_segment by blast lemma segment_convex_hull: "closed_segment a b = convex hull {a,b}" proof - have *: "\x. {x} \ {}" by auto show ?thesis unfolding segment convex_hull_insert[OF *] convex_hull_singleton by (safe; rule_tac x="1 - u" in exI; force) qed lemma open_closed_segment: "u \ open_segment w z \ u \ closed_segment w z" by (auto simp add: closed_segment_def open_segment_def) lemma segment_open_subset_closed: "open_segment a b \ closed_segment a b" by (auto simp: closed_segment_def open_segment_def) lemma bounded_closed_segment: fixes a :: "'a::real_normed_vector" shows "bounded (closed_segment a b)" by (rule boundedI[where B="max (norm a) (norm b)"]) (auto simp: closed_segment_def max_def convex_bound_le intro!: norm_triangle_le) lemma bounded_open_segment: fixes a :: "'a::real_normed_vector" shows "bounded (open_segment a b)" by (rule bounded_subset [OF bounded_closed_segment segment_open_subset_closed]) lemmas bounded_segment = bounded_closed_segment open_closed_segment lemma ends_in_segment [iff]: "a \ closed_segment a b" "b \ closed_segment a b" unfolding segment_convex_hull by (auto intro!: hull_subset[unfolded subset_eq, rule_format]) lemma eventually_closed_segment: fixes x0::"'a::real_normed_vector" assumes "open X0" "x0 \ X0" shows "\\<^sub>F x in at x0 within U. closed_segment x0 x \ X0" proof - from openE[OF assms] obtain e where e: "0 < e" "ball x0 e \ X0" . then have "\\<^sub>F x in at x0 within U. x \ ball x0 e" by (auto simp: dist_commute eventually_at) then show ?thesis proof eventually_elim case (elim x) have "x0 \ ball x0 e" using \e > 0\ by simp from convex_ball[unfolded convex_contains_segment, rule_format, OF this elim] have "closed_segment x0 x \ ball x0 e" . also note \\ \ X0\ finally show ?case . qed qed lemma closed_segment_commute: "closed_segment a b = closed_segment b a" proof - have "{a, b} = {b, a}" by auto thus ?thesis by (simp add: segment_convex_hull) qed lemma segment_bound1: assumes "x \ closed_segment a b" shows "norm (x - a) \ norm (b - a)" proof - obtain u where "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" "0 \ u" "u \ 1" using assms by (auto simp add: closed_segment_def) then show "norm (x - a) \ norm (b - a)" apply clarify apply (auto simp: algebra_simps) apply (simp add: scaleR_diff_right [symmetric] mult_left_le_one_le) done qed lemma segment_bound: assumes "x \ closed_segment a b" shows "norm (x - a) \ norm (b - a)" "norm (x - b) \ norm (b - a)" by (metis assms closed_segment_commute dist_commute dist_norm segment_bound1)+ lemma open_segment_commute: "open_segment a b = open_segment b a" proof - have "{a, b} = {b, a}" by auto thus ?thesis by (simp add: closed_segment_commute open_segment_def) qed lemma closed_segment_idem [simp]: "closed_segment a a = {a}" unfolding segment by (auto simp add: algebra_simps) lemma open_segment_idem [simp]: "open_segment a a = {}" by (simp add: open_segment_def) lemma closed_segment_eq_open: "closed_segment a b = open_segment a b \ {a,b}" using open_segment_def by auto lemma convex_contains_open_segment: "convex s \ (\a\s. \b\s. open_segment a b \ s)" by (simp add: convex_contains_segment closed_segment_eq_open) lemma closed_segment_eq_real_ivl1: fixes a b::real assumes "a \ b" shows "closed_segment a b = {a .. b}" proof safe fix x assume "x \ closed_segment a b" then obtain u where u: "0 \ u" "u \ 1" and x_def: "x = (1 - u) * a + u * b" by (auto simp: closed_segment_def) have "u * a \ u * b" "(1 - u) * a \ (1 - u) * b" by (auto intro!: mult_left_mono u assms) then show "x \ {a .. b}" unfolding x_def by (auto simp: algebra_simps) next show "\x. x \ {a..b} \ x \ closed_segment a b" by (force simp: closed_segment_def divide_simps algebra_simps intro: exI[where x="(x - a) / (b - a)" for x]) qed lemma closed_segment_eq_real_ivl: fixes a b::real shows "closed_segment a b = (if a \ b then {a .. b} else {b .. a})" using closed_segment_eq_real_ivl1[of a b] closed_segment_eq_real_ivl1[of b a] by (auto simp: closed_segment_commute) lemma open_segment_eq_real_ivl: fixes a b::real shows "open_segment a b = (if a \ b then {a<..x. (v - u) * x + u) ` {0..1}" by (simp add: add.commute [of u] image_affinity_atLeastAtMost [where c=u] closed_segment_eq_real_ivl) lemma closed_segment_same_Re: assumes "Re a = Re b" shows "closed_segment a b = {z. Re z = Re a \ Im z \ closed_segment (Im a) (Im b)}" proof safe fix z assume "z \ closed_segment a b" then obtain u where u: "u \ {0..1}" "z = a + of_real u * (b - a)" by (auto simp: closed_segment_def scaleR_conv_of_real algebra_simps) from assms show "Re z = Re a" by (auto simp: u) from u(1) show "Im z \ closed_segment (Im a) (Im b)" by (force simp: u closed_segment_def algebra_simps) next fix z assume [simp]: "Re z = Re a" and "Im z \ closed_segment (Im a) (Im b)" then obtain u where u: "u \ {0..1}" "Im z = Im a + of_real u * (Im b - Im a)" by (auto simp: closed_segment_def scaleR_conv_of_real algebra_simps) from u(1) show "z \ closed_segment a b" using assms by (force simp: u closed_segment_def algebra_simps scaleR_conv_of_real complex_eq_iff) qed lemma closed_segment_same_Im: assumes "Im a = Im b" shows "closed_segment a b = {z. Im z = Im a \ Re z \ closed_segment (Re a) (Re b)}" proof safe fix z assume "z \ closed_segment a b" then obtain u where u: "u \ {0..1}" "z = a + of_real u * (b - a)" by (auto simp: closed_segment_def scaleR_conv_of_real algebra_simps) from assms show "Im z = Im a" by (auto simp: u) from u(1) show "Re z \ closed_segment (Re a) (Re b)" by (force simp: u closed_segment_def algebra_simps) next fix z assume [simp]: "Im z = Im a" and "Re z \ closed_segment (Re a) (Re b)" then obtain u where u: "u \ {0..1}" "Re z = Re a + of_real u * (Re b - Re a)" by (auto simp: closed_segment_def scaleR_conv_of_real algebra_simps) from u(1) show "z \ closed_segment a b" using assms by (force simp: u closed_segment_def algebra_simps scaleR_conv_of_real complex_eq_iff) qed lemma dist_in_closed_segment: fixes a :: "'a :: euclidean_space" assumes "x \ closed_segment a b" shows "dist x a \ dist a b \ dist x b \ dist a b" proof (intro conjI) obtain u where u: "0 \ u" "u \ 1" and x: "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" using assms by (force simp: in_segment algebra_simps) have "dist x a = u * dist a b" apply (simp add: dist_norm algebra_simps x) by (metis \0 \ u\ abs_of_nonneg norm_minus_commute norm_scaleR real_vector.scale_right_diff_distrib) also have "... \ dist a b" by (simp add: mult_left_le_one_le u) finally show "dist x a \ dist a b" . have "dist x b = norm ((1-u) *\<^sub>R a - (1-u) *\<^sub>R b)" by (simp add: dist_norm algebra_simps x) also have "... = (1-u) * dist a b" proof - have "norm ((1 - 1 * u) *\<^sub>R (a - b)) = (1 - 1 * u) * norm (a - b)" using \u \ 1\ by force then show ?thesis by (simp add: dist_norm real_vector.scale_right_diff_distrib) qed also have "... \ dist a b" by (simp add: mult_left_le_one_le u) finally show "dist x b \ dist a b" . qed lemma dist_in_open_segment: fixes a :: "'a :: euclidean_space" assumes "x \ open_segment a b" shows "dist x a < dist a b \ dist x b < dist a b" proof (intro conjI) obtain u where u: "0 < u" "u < 1" and x: "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" using assms by (force simp: in_segment algebra_simps) have "dist x a = u * dist a b" apply (simp add: dist_norm algebra_simps x) by (metis abs_of_nonneg less_eq_real_def norm_minus_commute norm_scaleR real_vector.scale_right_diff_distrib \0 < u\) also have *: "... < dist a b" by (metis (no_types) assms dist_eq_0_iff dist_not_less_zero in_segment(2) linorder_neqE_linordered_idom mult.left_neutral real_mult_less_iff1 \u < 1\) finally show "dist x a < dist a b" . have ab_ne0: "dist a b \ 0" using * by fastforce have "dist x b = norm ((1-u) *\<^sub>R a - (1-u) *\<^sub>R b)" by (simp add: dist_norm algebra_simps x) also have "... = (1-u) * dist a b" proof - have "norm ((1 - 1 * u) *\<^sub>R (a - b)) = (1 - 1 * u) * norm (a - b)" using \u < 1\ by force then show ?thesis by (simp add: dist_norm real_vector.scale_right_diff_distrib) qed also have "... < dist a b" using ab_ne0 \0 < u\ by simp finally show "dist x b < dist a b" . qed lemma dist_decreases_open_segment_0: fixes x :: "'a :: euclidean_space" assumes "x \ open_segment 0 b" shows "dist c x < dist c 0 \ dist c x < dist c b" proof (rule ccontr, clarsimp simp: not_less) obtain u where u: "0 \ b" "0 < u" "u < 1" and x: "x = u *\<^sub>R b" using assms by (auto simp: in_segment) have xb: "x \ b < b \ b" using u x by auto assume "norm c \ dist c x" then have "c \ c \ (c - x) \ (c - x)" by (simp add: dist_norm norm_le) moreover have "0 < x \ b" using u x by auto ultimately have less: "c \ b < x \ b" by (simp add: x algebra_simps inner_commute u) assume "dist c b \ dist c x" then have "(c - b) \ (c - b) \ (c - x) \ (c - x)" by (simp add: dist_norm norm_le) then have "(b \ b) * (1 - u*u) \ 2 * (b \ c) * (1-u)" by (simp add: x algebra_simps inner_commute) then have "(1+u) * (b \ b) * (1-u) \ 2 * (b \ c) * (1-u)" by (simp add: algebra_simps) then have "(1+u) * (b \ b) \ 2 * (b \ c)" using \u < 1\ by auto with xb have "c \ b \ x \ b" by (auto simp: x algebra_simps inner_commute) with less show False by auto qed proposition dist_decreases_open_segment: fixes a :: "'a :: euclidean_space" assumes "x \ open_segment a b" shows "dist c x < dist c a \ dist c x < dist c b" proof - have *: "x - a \ open_segment 0 (b - a)" using assms by (metis diff_self open_segment_translation_eq uminus_add_conv_diff) show ?thesis using dist_decreases_open_segment_0 [OF *, of "c-a"] assms by (simp add: dist_norm) qed corollary open_segment_furthest_le: fixes a b x y :: "'a::euclidean_space" assumes "x \ open_segment a b" shows "norm (y - x) < norm (y - a) \ norm (y - x) < norm (y - b)" by (metis assms dist_decreases_open_segment dist_norm) corollary dist_decreases_closed_segment: fixes a :: "'a :: euclidean_space" assumes "x \ closed_segment a b" shows "dist c x \ dist c a \ dist c x \ dist c b" apply (cases "x \ open_segment a b") using dist_decreases_open_segment less_eq_real_def apply blast by (metis DiffI assms empty_iff insertE open_segment_def order_refl) corollary segment_furthest_le: fixes a b x y :: "'a::euclidean_space" assumes "x \ closed_segment a b" shows "norm (y - x) \ norm (y - a) \ norm (y - x) \ norm (y - b)" by (metis assms dist_decreases_closed_segment dist_norm) lemma convex_intermediate_ball: fixes a :: "'a :: euclidean_space" shows "\ball a r \ T; T \ cball a r\ \ convex T" apply (simp add: convex_contains_open_segment, clarify) by (metis (no_types, hide_lams) less_le_trans mem_ball mem_cball subsetCE dist_decreases_open_segment) lemma csegment_midpoint_subset: "closed_segment (midpoint a b) b \ closed_segment a b" apply (clarsimp simp: midpoint_def in_segment) apply (rule_tac x="(1 + u) / 2" in exI) apply (auto simp: algebra_simps add_divide_distrib diff_divide_distrib) by (metis field_sum_of_halves scaleR_left.add) lemma notin_segment_midpoint: fixes a :: "'a :: euclidean_space" shows "a \ b \ a \ closed_segment (midpoint a b) b" by (auto simp: dist_midpoint dest!: dist_in_closed_segment) subsubsection\More lemmas, especially for working with the underlying formula\ lemma segment_eq_compose: fixes a :: "'a :: real_vector" shows "(\u. (1 - u) *\<^sub>R a + u *\<^sub>R b) = (\x. a + x) o (\u. u *\<^sub>R (b - a))" by (simp add: o_def algebra_simps) lemma segment_degen_1: fixes a :: "'a :: real_vector" shows "(1 - u) *\<^sub>R a + u *\<^sub>R b = b \ a=b \ u=1" proof - { assume "(1 - u) *\<^sub>R a + u *\<^sub>R b = b" then have "(1 - u) *\<^sub>R a = (1 - u) *\<^sub>R b" by (simp add: algebra_simps) then have "a=b \ u=1" by simp } then show ?thesis by (auto simp: algebra_simps) qed lemma segment_degen_0: fixes a :: "'a :: real_vector" shows "(1 - u) *\<^sub>R a + u *\<^sub>R b = a \ a=b \ u=0" using segment_degen_1 [of "1-u" b a] by (auto simp: algebra_simps) lemma add_scaleR_degen: fixes a b ::"'a::real_vector" assumes "(u *\<^sub>R b + v *\<^sub>R a) = (u *\<^sub>R a + v *\<^sub>R b)" "u \ v" shows "a=b" by (metis (no_types, hide_lams) add.commute add_diff_eq diff_add_cancel real_vector.scale_cancel_left real_vector.scale_left_diff_distrib assms) lemma closed_segment_image_interval: "closed_segment a b = (\u. (1 - u) *\<^sub>R a + u *\<^sub>R b) ` {0..1}" by (auto simp: set_eq_iff image_iff closed_segment_def) lemma open_segment_image_interval: "open_segment a b = (if a=b then {} else (\u. (1 - u) *\<^sub>R a + u *\<^sub>R b) ` {0<..<1})" by (auto simp: open_segment_def closed_segment_def segment_degen_0 segment_degen_1) lemmas segment_image_interval = closed_segment_image_interval open_segment_image_interval lemma closed_segment_neq_empty [simp]: "closed_segment a b \ {}" by auto lemma open_segment_eq_empty [simp]: "open_segment a b = {} \ a = b" proof - { assume a1: "open_segment a b = {}" have "{} \ {0::real<..<1}" by simp then have "a = b" using a1 open_segment_image_interval by fastforce } then show ?thesis by auto qed lemma open_segment_eq_empty' [simp]: "{} = open_segment a b \ a = b" using open_segment_eq_empty by blast lemmas segment_eq_empty = closed_segment_neq_empty open_segment_eq_empty lemma inj_segment: fixes a :: "'a :: real_vector" assumes "a \ b" shows "inj_on (\u. (1 - u) *\<^sub>R a + u *\<^sub>R b) I" proof fix x y assume "(1 - x) *\<^sub>R a + x *\<^sub>R b = (1 - y) *\<^sub>R a + y *\<^sub>R b" then have "x *\<^sub>R (b - a) = y *\<^sub>R (b - a)" by (simp add: algebra_simps) with assms show "x = y" by (simp add: real_vector.scale_right_imp_eq) qed lemma finite_closed_segment [simp]: "finite(closed_segment a b) \ a = b" apply auto apply (rule ccontr) apply (simp add: segment_image_interval) using infinite_Icc [OF zero_less_one] finite_imageD [OF _ inj_segment] apply blast done lemma finite_open_segment [simp]: "finite(open_segment a b) \ a = b" by (auto simp: open_segment_def) lemmas finite_segment = finite_closed_segment finite_open_segment lemma closed_segment_eq_sing: "closed_segment a b = {c} \ a = c \ b = c" by auto lemma open_segment_eq_sing: "open_segment a b \ {c}" by (metis finite_insert finite_open_segment insert_not_empty open_segment_image_interval) lemmas segment_eq_sing = closed_segment_eq_sing open_segment_eq_sing lemma open_segment_bound1: assumes "x \ open_segment a b" shows "norm (x - a) < norm (b - a)" proof - obtain u where "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" "0 < u" "u < 1" "a \ b" using assms by (auto simp add: open_segment_image_interval split: if_split_asm) then show "norm (x - a) < norm (b - a)" apply clarify apply (auto simp: algebra_simps) apply (simp add: scaleR_diff_right [symmetric]) done qed lemma compact_segment [simp]: fixes a :: "'a::real_normed_vector" shows "compact (closed_segment a b)" by (auto simp: segment_image_interval intro!: compact_continuous_image continuous_intros) lemma closed_segment [simp]: fixes a :: "'a::real_normed_vector" shows "closed (closed_segment a b)" by (simp add: compact_imp_closed) lemma closure_closed_segment [simp]: fixes a :: "'a::real_normed_vector" shows "closure(closed_segment a b) = closed_segment a b" by simp lemma open_segment_bound: assumes "x \ open_segment a b" shows "norm (x - a) < norm (b - a)" "norm (x - b) < norm (b - a)" apply (simp add: assms open_segment_bound1) by (metis assms norm_minus_commute open_segment_bound1 open_segment_commute) lemma closure_open_segment [simp]: "closure (open_segment a b) = (if a = b then {} else closed_segment a b)" for a :: "'a::euclidean_space" proof (cases "a = b") case True then show ?thesis by simp next case False have "closure ((\u. u *\<^sub>R (b - a)) ` {0<..<1}) = (\u. u *\<^sub>R (b - a)) ` closure {0<..<1}" apply (rule closure_injective_linear_image [symmetric]) apply (use False in \auto intro!: injI\) done then have "closure ((\u. (1 - u) *\<^sub>R a + u *\<^sub>R b) ` {0<..<1}) = (\x. (1 - x) *\<^sub>R a + x *\<^sub>R b) ` closure {0<..<1}" using closure_translation [of a "((\x. x *\<^sub>R b - x *\<^sub>R a) ` {0<..<1})"] by (simp add: segment_eq_compose field_simps scaleR_diff_left scaleR_diff_right image_image) then show ?thesis by (simp add: segment_image_interval closure_greaterThanLessThan [symmetric] del: closure_greaterThanLessThan) qed lemma closed_open_segment_iff [simp]: fixes a :: "'a::euclidean_space" shows "closed(open_segment a b) \ a = b" by (metis open_segment_def DiffE closure_eq closure_open_segment ends_in_segment(1) insert_iff segment_image_interval(2)) lemma compact_open_segment_iff [simp]: fixes a :: "'a::euclidean_space" shows "compact(open_segment a b) \ a = b" by (simp add: bounded_open_segment compact_eq_bounded_closed) lemma convex_closed_segment [iff]: "convex (closed_segment a b)" unfolding segment_convex_hull by(rule convex_convex_hull) lemma convex_open_segment [iff]: "convex (open_segment a b)" proof - have "convex ((\u. u *\<^sub>R (b - a)) ` {0<..<1})" by (rule convex_linear_image) auto then have "convex ((+) a ` (\u. u *\<^sub>R (b - a)) ` {0<..<1})" by (rule convex_translation) then show ?thesis by (simp add: image_image open_segment_image_interval segment_eq_compose field_simps scaleR_diff_left scaleR_diff_right) qed lemmas convex_segment = convex_closed_segment convex_open_segment lemma subset_closed_segment: "closed_segment a b \ closed_segment c d \ a \ closed_segment c d \ b \ closed_segment c d" by auto (meson contra_subsetD convex_closed_segment convex_contains_segment) lemma subset_co_segment: "closed_segment a b \ open_segment c d \ a \ open_segment c d \ b \ open_segment c d" using closed_segment_subset by blast lemma subset_open_segment: fixes a :: "'a::euclidean_space" shows "open_segment a b \ open_segment c d \ a = b \ a \ closed_segment c d \ b \ closed_segment c d" (is "?lhs = ?rhs") proof (cases "a = b") case True then show ?thesis by simp next case False show ?thesis proof assume rhs: ?rhs with \a \ b\ have "c \ d" using closed_segment_idem singleton_iff by auto have "\uc. (1 - u) *\<^sub>R ((1 - ua) *\<^sub>R c + ua *\<^sub>R d) + u *\<^sub>R ((1 - ub) *\<^sub>R c + ub *\<^sub>R d) = (1 - uc) *\<^sub>R c + uc *\<^sub>R d \ 0 < uc \ uc < 1" if neq: "(1 - ua) *\<^sub>R c + ua *\<^sub>R d \ (1 - ub) *\<^sub>R c + ub *\<^sub>R d" "c \ d" and "a = (1 - ua) *\<^sub>R c + ua *\<^sub>R d" "b = (1 - ub) *\<^sub>R c + ub *\<^sub>R d" and u: "0 < u" "u < 1" and uab: "0 \ ua" "ua \ 1" "0 \ ub" "ub \ 1" for u ua ub proof - have "ua \ ub" using neq by auto moreover have "(u - 1) * ua \ 0" using u uab by (simp add: mult_nonpos_nonneg) ultimately have lt: "(u - 1) * ua < u * ub" using u uab by (metis antisym_conv diff_ge_0_iff_ge le_less_trans mult_eq_0_iff mult_le_0_iff not_less) have "p * ua + q * ub < p+q" if p: "0 < p" and q: "0 < q" for p q proof - have "\ p \ 0" "\ q \ 0" using p q not_less by blast+ then show ?thesis by (metis \ua \ ub\ add_less_cancel_left add_less_cancel_right add_mono_thms_linordered_field(5) less_eq_real_def mult_cancel_left1 mult_less_cancel_left2 uab(2) uab(4)) qed then have "(1 - u) * ua + u * ub < 1" using u \ua \ ub\ by (metis diff_add_cancel diff_gt_0_iff_gt) with lt show ?thesis by (rule_tac x="ua + u*(ub-ua)" in exI) (simp add: algebra_simps) qed with rhs \a \ b\ \c \ d\ show ?lhs unfolding open_segment_image_interval closed_segment_def by (fastforce simp add:) next assume lhs: ?lhs with \a \ b\ have "c \ d" by (meson finite_open_segment rev_finite_subset) have "closure (open_segment a b) \ closure (open_segment c d)" using lhs closure_mono by blast then have "closed_segment a b \ closed_segment c d" by (simp add: \a \ b\ \c \ d\) then show ?rhs by (force simp: \a \ b\) qed qed lemma subset_oc_segment: fixes a :: "'a::euclidean_space" shows "open_segment a b \ closed_segment c d \ a = b \ a \ closed_segment c d \ b \ closed_segment c d" apply (simp add: subset_open_segment [symmetric]) apply (rule iffI) apply (metis closure_closed_segment closure_mono closure_open_segment subset_closed_segment subset_open_segment) apply (meson dual_order.trans segment_open_subset_closed) done lemmas subset_segment = subset_closed_segment subset_co_segment subset_oc_segment subset_open_segment lemma dist_half_times2: fixes a :: "'a :: real_normed_vector" shows "dist ((1 / 2) *\<^sub>R (a + b)) x * 2 = dist (a+b) (2 *\<^sub>R x)" proof - have "norm ((1 / 2) *\<^sub>R (a + b) - x) * 2 = norm (2 *\<^sub>R ((1 / 2) *\<^sub>R (a + b) - x))" by simp also have "... = norm ((a + b) - 2 *\<^sub>R x)" by (simp add: real_vector.scale_right_diff_distrib) finally show ?thesis by (simp only: dist_norm) qed lemma closed_segment_as_ball: "closed_segment a b = affine hull {a,b} \ cball(inverse 2 *\<^sub>R (a + b))(norm(b - a) / 2)" proof (cases "b = a") case True then show ?thesis by (auto simp: hull_inc) next case False then have *: "((\u v. x = u *\<^sub>R a + v *\<^sub>R b \ u + v = 1) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 \ norm (b - a)) = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 \ u \ u \ 1)" for x proof - have "((\u v. x = u *\<^sub>R a + v *\<^sub>R b \ u + v = 1) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 \ norm (b - a)) = ((\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 \ norm (b - a))" unfolding eq_diff_eq [symmetric] by simp also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((a+b) - (2 *\<^sub>R x)) \ norm (b - a))" by (simp add: dist_half_times2) (simp add: dist_norm) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((a+b) - (2 *\<^sub>R ((1 - u) *\<^sub>R a + u *\<^sub>R b))) \ norm (b - a))" by auto also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((1 - u * 2) *\<^sub>R (b - a)) \ norm (b - a))" by (simp add: algebra_simps scaleR_2) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ \1 - u * 2\ * norm (b - a) \ norm (b - a))" by simp also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ \1 - u * 2\ \ 1)" by (simp add: mult_le_cancel_right2 False) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 \ u \ u \ 1)" by auto finally show ?thesis . qed show ?thesis by (simp add: affine_hull_2 Set.set_eq_iff closed_segment_def *) qed lemma open_segment_as_ball: "open_segment a b = affine hull {a,b} \ ball(inverse 2 *\<^sub>R (a + b))(norm(b - a) / 2)" proof (cases "b = a") case True then show ?thesis by (auto simp: hull_inc) next case False then have *: "((\u v. x = u *\<^sub>R a + v *\<^sub>R b \ u + v = 1) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 < norm (b - a)) = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 < u \ u < 1)" for x proof - have "((\u v. x = u *\<^sub>R a + v *\<^sub>R b \ u + v = 1) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 < norm (b - a)) = ((\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b) \ dist ((1 / 2) *\<^sub>R (a + b)) x * 2 < norm (b - a))" unfolding eq_diff_eq [symmetric] by simp also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((a+b) - (2 *\<^sub>R x)) < norm (b - a))" by (simp add: dist_half_times2) (simp add: dist_norm) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((a+b) - (2 *\<^sub>R ((1 - u) *\<^sub>R a + u *\<^sub>R b))) < norm (b - a))" by auto also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ norm ((1 - u * 2) *\<^sub>R (b - a)) < norm (b - a))" by (simp add: algebra_simps scaleR_2) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ \1 - u * 2\ * norm (b - a) < norm (b - a))" by simp also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ \1 - u * 2\ < 1)" by (simp add: mult_le_cancel_right2 False) also have "... = (\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 < u \ u < 1)" by auto finally show ?thesis . qed show ?thesis using False by (force simp: affine_hull_2 Set.set_eq_iff open_segment_image_interval *) qed lemmas segment_as_ball = closed_segment_as_ball open_segment_as_ball lemma connected_segment [iff]: fixes x :: "'a :: real_normed_vector" shows "connected (closed_segment x y)" by (simp add: convex_connected) lemma is_interval_closed_segment_1[intro, simp]: "is_interval (closed_segment a b)" for a b::real unfolding closed_segment_eq_real_ivl by (auto simp: is_interval_def) lemma IVT'_closed_segment_real: fixes f :: "real \ real" assumes "y \ closed_segment (f a) (f b)" assumes "continuous_on (closed_segment a b) f" shows "\x \ closed_segment a b. f x = y" using IVT'[of f a y b] IVT'[of "-f" a "-y" b] IVT'[of f b y a] IVT'[of "-f" b "-y" a] assms by (cases "a \ b"; cases "f b \ f a") (auto simp: closed_segment_eq_real_ivl continuous_on_minus) subsection \Betweenness\ definition\<^marker>\tag important\ "between = (\(a,b) x. x \ closed_segment a b)" lemma betweenI: assumes "0 \ u" "u \ 1" "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" shows "between (a, b) x" using assms unfolding between_def closed_segment_def by auto lemma betweenE: assumes "between (a, b) x" obtains u where "0 \ u" "u \ 1" "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" using assms unfolding between_def closed_segment_def by auto lemma between_implies_scaled_diff: assumes "between (S, T) X" "between (S, T) Y" "S \ Y" obtains c where "(X - Y) = c *\<^sub>R (S - Y)" proof - from \between (S, T) X\ obtain u\<^sub>X where X: "X = u\<^sub>X *\<^sub>R S + (1 - u\<^sub>X) *\<^sub>R T" by (metis add.commute betweenE eq_diff_eq) from \between (S, T) Y\ obtain u\<^sub>Y where Y: "Y = u\<^sub>Y *\<^sub>R S + (1 - u\<^sub>Y) *\<^sub>R T" by (metis add.commute betweenE eq_diff_eq) have "X - Y = (u\<^sub>X - u\<^sub>Y) *\<^sub>R (S - T)" proof - from X Y have "X - Y = u\<^sub>X *\<^sub>R S - u\<^sub>Y *\<^sub>R S + ((1 - u\<^sub>X) *\<^sub>R T - (1 - u\<^sub>Y) *\<^sub>R T)" by simp also have "\ = (u\<^sub>X - u\<^sub>Y) *\<^sub>R S - (u\<^sub>X - u\<^sub>Y) *\<^sub>R T" by (simp add: scaleR_left.diff) finally show ?thesis by (simp add: real_vector.scale_right_diff_distrib) qed moreover from Y have "S - Y = (1 - u\<^sub>Y) *\<^sub>R (S - T)" by (simp add: real_vector.scale_left_diff_distrib real_vector.scale_right_diff_distrib) moreover note \S \ Y\ ultimately have "(X - Y) = ((u\<^sub>X - u\<^sub>Y) / (1 - u\<^sub>Y)) *\<^sub>R (S - Y)" by auto from this that show thesis by blast qed lemma between_mem_segment: "between (a,b) x \ x \ closed_segment a b" unfolding between_def by auto lemma between: "between (a, b) (x::'a::euclidean_space) \ dist a b = (dist a x) + (dist x b)" proof (cases "a = b") case True then show ?thesis by (auto simp add: between_def dist_commute) next case False then have Fal: "norm (a - b) \ 0" and Fal2: "norm (a - b) > 0" by auto have *: "\u. a - ((1 - u) *\<^sub>R a + u *\<^sub>R b) = u *\<^sub>R (a - b)" by (auto simp add: algebra_simps) have "norm (a - x) *\<^sub>R (x - b) = norm (x - b) *\<^sub>R (a - x)" if "x = (1 - u) *\<^sub>R a + u *\<^sub>R b" "0 \ u" "u \ 1" for u proof - have *: "a - x = u *\<^sub>R (a - b)" "x - b = (1 - u) *\<^sub>R (a - b)" unfolding that(1) by (auto simp add:algebra_simps) show "norm (a - x) *\<^sub>R (x - b) = norm (x - b) *\<^sub>R (a - x)" unfolding norm_minus_commute[of x a] * using \0 \ u\ \u \ 1\ by simp qed moreover have "\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 \ u \ u \ 1" if "dist a b = dist a x + dist x b" proof - let ?\ = "norm (a - x) / norm (a - b)" show "\u. x = (1 - u) *\<^sub>R a + u *\<^sub>R b \ 0 \ u \ u \ 1" proof (intro exI conjI) show "?\ \ 1" using Fal2 unfolding that[unfolded dist_norm] norm_ge_zero by auto show "x = (1 - ?\) *\<^sub>R a + (?\) *\<^sub>R b" proof (subst euclidean_eq_iff; intro ballI) fix i :: 'a assume i: "i \ Basis" have "((1 - ?\) *\<^sub>R a + (?\) *\<^sub>R b) \ i = ((norm (a - b) - norm (a - x)) * (a \ i) + norm (a - x) * (b \ i)) / norm (a - b)" using Fal by (auto simp add: field_simps inner_simps) also have "\ = x\i" apply (rule divide_eq_imp[OF Fal]) unfolding that[unfolded dist_norm] using that[unfolded dist_triangle_eq] i apply (subst (asm) euclidean_eq_iff) apply (auto simp add: field_simps inner_simps) done finally show "x \ i = ((1 - ?\) *\<^sub>R a + (?\) *\<^sub>R b) \ i" by auto qed qed (use Fal2 in auto) qed ultimately show ?thesis by (force simp add: between_def closed_segment_def dist_triangle_eq) qed lemma between_midpoint: fixes a :: "'a::euclidean_space" shows "between (a,b) (midpoint a b)" (is ?t1) and "between (b,a) (midpoint a b)" (is ?t2) proof - have *: "\x y z. x = (1/2::real) *\<^sub>R z \ y = (1/2) *\<^sub>R z \ norm z = norm x + norm y" by auto show ?t1 ?t2 unfolding between midpoint_def dist_norm by (auto simp add: field_simps inner_simps euclidean_eq_iff[where 'a='a] intro!: *) qed lemma between_mem_convex_hull: "between (a,b) x \ x \ convex hull {a,b}" unfolding between_mem_segment segment_convex_hull .. lemma between_triv_iff [simp]: "between (a,a) b \ a=b" by (auto simp: between_def) lemma between_triv1 [simp]: "between (a,b) a" by (auto simp: between_def) lemma between_triv2 [simp]: "between (a,b) b" by (auto simp: between_def) lemma between_commute: "between (a,b) = between (b,a)" by (auto simp: between_def closed_segment_commute) lemma between_antisym: fixes a :: "'a :: euclidean_space" shows "\between (b,c) a; between (a,c) b\ \ a = b" by (auto simp: between dist_commute) lemma between_trans: fixes a :: "'a :: euclidean_space" shows "\between (b,c) a; between (a,c) d\ \ between (b,c) d" using dist_triangle2 [of b c d] dist_triangle3 [of b d a] by (auto simp: between dist_commute) lemma between_norm: fixes a :: "'a :: euclidean_space" shows "between (a,b) x \ norm(x - a) *\<^sub>R (b - x) = norm(b - x) *\<^sub>R (x - a)" by (auto simp: between dist_triangle_eq norm_minus_commute algebra_simps) lemma between_swap: fixes A B X Y :: "'a::euclidean_space" assumes "between (A, B) X" assumes "between (A, B) Y" shows "between (X, B) Y \ between (A, Y) X" using assms by (auto simp add: between) lemma between_translation [simp]: "between (a + y,a + z) (a + x) \ between (y,z) x" by (auto simp: between_def) lemma between_trans_2: fixes a :: "'a :: euclidean_space" shows "\between (b,c) a; between (a,b) d\ \ between (c,d) a" by (metis between_commute between_swap between_trans) lemma between_scaleR_lift [simp]: fixes v :: "'a::euclidean_space" shows "between (a *\<^sub>R v, b *\<^sub>R v) (c *\<^sub>R v) \ v = 0 \ between (a, b) c" by (simp add: between dist_norm scaleR_left_diff_distrib [symmetric] distrib_right [symmetric]) lemma between_1: fixes x::real shows "between (a,b) x \ (a \ x \ x \ b) \ (b \ x \ x \ a)" by (auto simp: between_mem_segment closed_segment_eq_real_ivl) end \ No newline at end of file diff --git a/src/HOL/Analysis/Topology_Euclidean_Space.thy b/src/HOL/Analysis/Topology_Euclidean_Space.thy --- a/src/HOL/Analysis/Topology_Euclidean_Space.thy +++ b/src/HOL/Analysis/Topology_Euclidean_Space.thy @@ -1,2508 +1,2579 @@ (* Author: L C Paulson, University of Cambridge Author: Amine Chaieb, University of Cambridge Author: Robert Himmelmann, TU Muenchen Author: Brian Huffman, Portland State University *) chapter \Vector Analysis\ theory Topology_Euclidean_Space imports Elementary_Normed_Spaces Linear_Algebra Norm_Arith begin section \Elementary Topology in Euclidean Space\ lemma euclidean_dist_l2: fixes x y :: "'a :: euclidean_space" shows "dist x y = L2_set (\i. dist (x \ i) (y \ i)) Basis" unfolding dist_norm norm_eq_sqrt_inner L2_set_def by (subst euclidean_inner) (simp add: power2_eq_square inner_diff_left) lemma norm_nth_le: "norm (x \ i) \ norm x" if "i \ Basis" proof - have "(x \ i)\<^sup>2 = (\i\{i}. (x \ i)\<^sup>2)" by simp also have "\ \ (\i\Basis. (x \ i)\<^sup>2)" by (intro sum_mono2) (auto simp: that) finally show ?thesis unfolding norm_conv_dist euclidean_dist_l2[of x] L2_set_def by (auto intro!: real_le_rsqrt) qed subsection\<^marker>\tag unimportant\ \Continuity of the representation WRT an orthogonal basis\ lemma orthogonal_Basis: "pairwise orthogonal Basis" by (simp add: inner_not_same_Basis orthogonal_def pairwise_def) lemma representation_bound: fixes B :: "'N::real_inner set" assumes "finite B" "independent B" "b \ B" and orth: "pairwise orthogonal B" obtains m where "m > 0" "\x. x \ span B \ \representation B x b\ \ m * norm x" proof fix x assume x: "x \ span B" have "b \ 0" using \independent B\ \b \ B\ dependent_zero by blast have [simp]: "b \ b' = (if b' = b then (norm b)\<^sup>2 else 0)" if "b \ B" "b' \ B" for b b' using orth by (simp add: orthogonal_def pairwise_def norm_eq_sqrt_inner that) have "norm x = norm (\b\B. representation B x b *\<^sub>R b)" using real_vector.sum_representation_eq [OF \independent B\ x \finite B\ order_refl] by simp also have "\ = sqrt ((\b\B. representation B x b *\<^sub>R b) \ (\b\B. representation B x b *\<^sub>R b))" by (simp add: norm_eq_sqrt_inner) also have "\ = sqrt (\b\B. (representation B x b *\<^sub>R b) \ (representation B x b *\<^sub>R b))" using \finite B\ by (simp add: inner_sum_left inner_sum_right if_distrib [of "\x. _ * x"] cong: if_cong sum.cong_simp) also have "\ = sqrt (\b\B. (norm (representation B x b *\<^sub>R b))\<^sup>2)" by (simp add: mult.commute mult.left_commute power2_eq_square) also have "\ = sqrt (\b\B. (representation B x b)\<^sup>2 * (norm b)\<^sup>2)" by (simp add: norm_mult power_mult_distrib) finally have "norm x = sqrt (\b\B. (representation B x b)\<^sup>2 * (norm b)\<^sup>2)" . moreover have "sqrt ((representation B x b)\<^sup>2 * (norm b)\<^sup>2) \ sqrt (\b\B. (representation B x b)\<^sup>2 * (norm b)\<^sup>2)" using \b \ B\ \finite B\ by (auto intro: member_le_sum) then have "\representation B x b\ \ (1 / norm b) * sqrt (\b\B. (representation B x b)\<^sup>2 * (norm b)\<^sup>2)" using \b \ 0\ by (simp add: field_split_simps real_sqrt_mult del: real_sqrt_le_iff) ultimately show "\representation B x b\ \ (1 / norm b) * norm x" by simp next show "0 < 1 / norm b" using \independent B\ \b \ B\ dependent_zero by auto qed lemma continuous_on_representation: fixes B :: "'N::euclidean_space set" assumes "finite B" "independent B" "b \ B" "pairwise orthogonal B" shows "continuous_on (span B) (\x. representation B x b)" proof show "\d>0. \x'\span B. dist x' x < d \ dist (representation B x' b) (representation B x b) \ e" if "e > 0" "x \ span B" for x e proof - obtain m where "m > 0" and m: "\x. x \ span B \ \representation B x b\ \ m * norm x" using assms representation_bound by blast show ?thesis unfolding dist_norm proof (intro exI conjI ballI impI) show "e/m > 0" by (simp add: \e > 0\ \m > 0\) show "norm (representation B x' b - representation B x b) \ e" if x': "x' \ span B" and less: "norm (x'-x) < e/m" for x' proof - have "\representation B (x'-x) b\ \ m * norm (x'-x)" using m [of "x'-x"] \x \ span B\ span_diff x' by blast also have "\ < e" by (metis \m > 0\ less mult.commute pos_less_divide_eq) finally have "\representation B (x'-x) b\ \ e" by simp then show ?thesis by (simp add: \x \ span B\ \independent B\ representation_diff x') qed qed qed qed subsection\<^marker>\tag unimportant\\Balls in Euclidean Space\ lemma cball_subset_cball_iff: fixes a :: "'a :: euclidean_space" shows "cball a r \ cball a' r' \ dist a a' + r \ r' \ r < 0" (is "?lhs \ ?rhs") proof assume ?lhs then show ?rhs proof (cases "r < 0") case True then show ?rhs by simp next case False then have [simp]: "r \ 0" by simp have "norm (a - a') + r \ r'" proof (cases "a = a'") case True then show ?thesis using subsetD [where c = "a + r *\<^sub>R (SOME i. i \ Basis)", OF \?lhs\] subsetD [where c = a, OF \?lhs\] by (force simp: SOME_Basis dist_norm) next case False have "norm (a' - (a + (r / norm (a - a')) *\<^sub>R (a - a'))) = norm (a' - a - (r / norm (a - a')) *\<^sub>R (a - a'))" by (simp add: algebra_simps) also have "... = norm ((-1 - (r / norm (a - a'))) *\<^sub>R (a - a'))" by (simp add: algebra_simps) also from \a \ a'\ have "... = \- norm (a - a') - r\" by simp (simp add: field_simps) finally have [simp]: "norm (a' - (a + (r / norm (a - a')) *\<^sub>R (a - a'))) = \norm (a - a') + r\" by linarith from \a \ a'\ show ?thesis using subsetD [where c = "a' + (1 + r / norm(a - a')) *\<^sub>R (a - a')", OF \?lhs\] by (simp add: dist_norm scaleR_add_left) qed then show ?rhs by (simp add: dist_norm) qed qed metric lemma cball_subset_ball_iff: "cball a r \ ball a' r' \ dist a a' + r < r' \ r < 0" (is "?lhs \ ?rhs") for a :: "'a::euclidean_space" proof assume ?lhs then show ?rhs proof (cases "r < 0") case True then show ?rhs by simp next case False then have [simp]: "r \ 0" by simp have "norm (a - a') + r < r'" proof (cases "a = a'") case True then show ?thesis using subsetD [where c = "a + r *\<^sub>R (SOME i. i \ Basis)", OF \?lhs\] subsetD [where c = a, OF \?lhs\] by (force simp: SOME_Basis dist_norm) next case False have False if "norm (a - a') + r \ r'" proof - from that have "\r' - norm (a - a')\ \ r" by (simp split: abs_split) (metis \0 \ r\ \?lhs\ centre_in_cball dist_commute dist_norm less_asym mem_ball subset_eq) then show ?thesis using subsetD [where c = "a + (r' / norm(a - a') - 1) *\<^sub>R (a - a')", OF \?lhs\] \a \ a'\ apply (simp add: dist_norm) apply (simp add: scaleR_left_diff_distrib) apply (simp add: field_simps) done qed then show ?thesis by force qed then show ?rhs by (simp add: dist_norm) qed next assume ?rhs then show ?lhs by metric qed lemma ball_subset_cball_iff: "ball a r \ cball a' r' \ dist a a' + r \ r' \ r \ 0" (is "?lhs = ?rhs") for a :: "'a::euclidean_space" proof (cases "r \ 0") case True then show ?thesis by metric next case False show ?thesis proof assume ?lhs then have "(cball a r \ cball a' r')" by (metis False closed_cball closure_ball closure_closed closure_mono not_less) with False show ?rhs by (fastforce iff: cball_subset_cball_iff) next assume ?rhs with False show ?lhs by metric qed qed lemma ball_subset_ball_iff: fixes a :: "'a :: euclidean_space" shows "ball a r \ ball a' r' \ dist a a' + r \ r' \ r \ 0" (is "?lhs = ?rhs") proof (cases "r \ 0") case True then show ?thesis by metric next case False show ?thesis proof assume ?lhs then have "0 < r'" using False by metric then have "(cball a r \ cball a' r')" by (metis False\?lhs\ closure_ball closure_mono not_less) then show ?rhs using False cball_subset_cball_iff by fastforce qed metric qed lemma ball_eq_ball_iff: fixes x :: "'a :: euclidean_space" shows "ball x d = ball y e \ d \ 0 \ e \ 0 \ x=y \ d=e" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs proof (cases "d \ 0 \ e \ 0") case True with \?lhs\ show ?rhs by safe (simp_all only: ball_eq_empty [of y e, symmetric] ball_eq_empty [of x d, symmetric]) next case False with \?lhs\ show ?rhs apply (auto simp: set_eq_subset ball_subset_ball_iff dist_norm norm_minus_commute algebra_simps) apply (metis add_le_same_cancel1 le_add_same_cancel1 norm_ge_zero norm_pths(2) order_trans) apply (metis add_increasing2 add_le_imp_le_right eq_iff norm_ge_zero) done qed next assume ?rhs then show ?lhs by (auto simp: set_eq_subset ball_subset_ball_iff) qed lemma cball_eq_cball_iff: fixes x :: "'a :: euclidean_space" shows "cball x d = cball y e \ d < 0 \ e < 0 \ x=y \ d=e" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs proof (cases "d < 0 \ e < 0") case True with \?lhs\ show ?rhs by safe (simp_all only: cball_eq_empty [of y e, symmetric] cball_eq_empty [of x d, symmetric]) next case False with \?lhs\ show ?rhs apply (auto simp: set_eq_subset cball_subset_cball_iff dist_norm norm_minus_commute algebra_simps) apply (metis add_le_same_cancel1 le_add_same_cancel1 norm_ge_zero norm_pths(2) order_trans) apply (metis add_increasing2 add_le_imp_le_right eq_iff norm_ge_zero) done qed next assume ?rhs then show ?lhs by (auto simp: set_eq_subset cball_subset_cball_iff) qed lemma ball_eq_cball_iff: fixes x :: "'a :: euclidean_space" shows "ball x d = cball y e \ d \ 0 \ e < 0" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs apply (auto simp: set_eq_subset ball_subset_cball_iff cball_subset_ball_iff algebra_simps) apply (metis add_increasing2 add_le_cancel_right add_less_same_cancel1 dist_not_less_zero less_le_trans zero_le_dist) apply (metis add_less_same_cancel1 dist_not_less_zero less_le_trans not_le) using \?lhs\ ball_eq_empty cball_eq_empty apply blast+ done next assume ?rhs then show ?lhs by auto qed lemma cball_eq_ball_iff: fixes x :: "'a :: euclidean_space" shows "cball x d = ball y e \ d < 0 \ e \ 0" using ball_eq_cball_iff by blast lemma finite_ball_avoid: fixes S :: "'a :: euclidean_space set" assumes "open S" "finite X" "p \ S" shows "\e>0. \w\ball p e. w\S \ (w\p \ w\X)" proof - obtain e1 where "0 < e1" and e1_b:"ball p e1 \ S" using open_contains_ball_eq[OF \open S\] assms by auto obtain e2 where "0 < e2" and "\x\X. x \ p \ e2 \ dist p x" using finite_set_avoid[OF \finite X\,of p] by auto hence "\w\ball p (min e1 e2). w\S \ (w\p \ w\X)" using e1_b by auto thus "\e>0. \w\ball p e. w \ S \ (w \ p \ w \ X)" using \e2>0\ \e1>0\ apply (rule_tac x="min e1 e2" in exI) by auto qed lemma finite_cball_avoid: fixes S :: "'a :: euclidean_space set" assumes "open S" "finite X" "p \ S" shows "\e>0. \w\cball p e. w\S \ (w\p \ w\X)" proof - obtain e1 where "e1>0" and e1: "\w\ball p e1. w\S \ (w\p \ w\X)" using finite_ball_avoid[OF assms] by auto define e2 where "e2 \ e1/2" have "e2>0" and "e2 < e1" unfolding e2_def using \e1>0\ by auto then have "cball p e2 \ ball p e1" by (subst cball_subset_ball_iff,auto) then show "\e>0. \w\cball p e. w \ S \ (w \ p \ w \ X)" using \e2>0\ e1 by auto qed lemma dim_cball: assumes "e > 0" shows "dim (cball (0 :: 'n::euclidean_space) e) = DIM('n)" proof - { fix x :: "'n::euclidean_space" define y where "y = (e / norm x) *\<^sub>R x" then have "y \ cball 0 e" using assms by auto moreover have *: "x = (norm x / e) *\<^sub>R y" using y_def assms by simp moreover from * have "x = (norm x/e) *\<^sub>R y" by auto ultimately have "x \ span (cball 0 e)" using span_scale[of y "cball 0 e" "norm x/e"] span_superset[of "cball 0 e"] by (simp add: span_base) } then have "span (cball 0 e) = (UNIV :: 'n::euclidean_space set)" by auto then show ?thesis using dim_span[of "cball (0 :: 'n::euclidean_space) e"] by (auto) qed subsection \Boxes\ abbreviation\<^marker>\tag important\ One :: "'a::euclidean_space" where "One \ \Basis" lemma One_non_0: assumes "One = (0::'a::euclidean_space)" shows False proof - have "dependent (Basis :: 'a set)" apply (simp add: dependent_finite) apply (rule_tac x="\i. 1" in exI) using SOME_Basis apply (auto simp: assms) done with independent_Basis show False by force qed corollary\<^marker>\tag unimportant\ One_neq_0[iff]: "One \ 0" by (metis One_non_0) corollary\<^marker>\tag unimportant\ Zero_neq_One[iff]: "0 \ One" by (metis One_non_0) definition\<^marker>\tag important\ (in euclidean_space) eucl_less (infix " (\i\Basis. a \ i < b \ i)" definition\<^marker>\tag important\ box_eucl_less: "box a b = {x. a x \tag important\ "cbox a b = {x. \i\Basis. a \ i \ x \ i \ x \ i \ b \ i}" lemma box_def: "box a b = {x. \i\Basis. a \ i < x \ i \ x \ i < b \ i}" and in_box_eucl_less: "x \ box a b \ a x box a b \ (\i\Basis. a \ i < x \ i \ x \ i < b \ i)" "x \ cbox a b \ (\i\Basis. a \ i \ x \ i \ x \ i \ b \ i)" by (auto simp: box_eucl_less eucl_less_def cbox_def) lemma cbox_Pair_eq: "cbox (a, c) (b, d) = cbox a b \ cbox c d" by (force simp: cbox_def Basis_prod_def) lemma cbox_Pair_iff [iff]: "(x, y) \ cbox (a, c) (b, d) \ x \ cbox a b \ y \ cbox c d" by (force simp: cbox_Pair_eq) lemma cbox_Complex_eq: "cbox (Complex a c) (Complex b d) = (\(x,y). Complex x y) ` (cbox a b \ cbox c d)" apply (auto simp: cbox_def Basis_complex_def) apply (rule_tac x = "(Re x, Im x)" in image_eqI) using complex_eq by auto lemma cbox_Pair_eq_0: "cbox (a, c) (b, d) = {} \ cbox a b = {} \ cbox c d = {}" by (force simp: cbox_Pair_eq) lemma swap_cbox_Pair [simp]: "prod.swap ` cbox (c, a) (d, b) = cbox (a,c) (b,d)" by auto lemma mem_box_real[simp]: "(x::real) \ box a b \ a < x \ x < b" "(x::real) \ cbox a b \ a \ x \ x \ b" by (auto simp: mem_box) lemma box_real[simp]: fixes a b:: real shows "box a b = {a <..< b}" "cbox a b = {a .. b}" by auto lemma box_Int_box: fixes a :: "'a::euclidean_space" shows "box a b \ box c d = box (\i\Basis. max (a\i) (c\i) *\<^sub>R i) (\i\Basis. min (b\i) (d\i) *\<^sub>R i)" unfolding set_eq_iff and Int_iff and mem_box by auto lemma rational_boxes: fixes x :: "'a::euclidean_space" assumes "e > 0" shows "\a b. (\i\Basis. a \ i \ \ \ b \ i \ \) \ x \ box a b \ box a b \ ball x e" proof - define e' where "e' = e / (2 * sqrt (real (DIM ('a))))" then have e: "e' > 0" using assms by (auto) have "\i. \y. y \ \ \ y < x \ i \ x \ i - y < e'" (is "\i. ?th i") proof fix i from Rats_dense_in_real[of "x \ i - e'" "x \ i"] e show "?th i" by auto qed from choice[OF this] obtain a where a: "\xa. a xa \ \ \ a xa < x \ xa \ x \ xa - a xa < e'" .. have "\i. \y. y \ \ \ x \ i < y \ y - x \ i < e'" (is "\i. ?th i") proof fix i from Rats_dense_in_real[of "x \ i" "x \ i + e'"] e show "?th i" by auto qed from choice[OF this] obtain b where b: "\xa. b xa \ \ \ x \ xa < b xa \ b xa - x \ xa < e'" .. let ?a = "\i\Basis. a i *\<^sub>R i" and ?b = "\i\Basis. b i *\<^sub>R i" show ?thesis proof (rule exI[of _ ?a], rule exI[of _ ?b], safe) fix y :: 'a assume *: "y \ box ?a ?b" have "dist x y = sqrt (\i\Basis. (dist (x \ i) (y \ i))\<^sup>2)" unfolding L2_set_def[symmetric] by (rule euclidean_dist_l2) also have "\ < sqrt (\(i::'a)\Basis. e^2 / real (DIM('a)))" proof (rule real_sqrt_less_mono, rule sum_strict_mono) fix i :: "'a" assume i: "i \ Basis" have "a i < y\i \ y\i < b i" using * i by (auto simp: box_def) moreover have "a i < x\i" "x\i - a i < e'" using a by auto moreover have "x\i < b i" "b i - x\i < e'" using b by auto ultimately have "\x\i - y\i\ < 2 * e'" by auto then have "dist (x \ i) (y \ i) < e/sqrt (real (DIM('a)))" unfolding e'_def by (auto simp: dist_real_def) then have "(dist (x \ i) (y \ i))\<^sup>2 < (e/sqrt (real (DIM('a))))\<^sup>2" by (rule power_strict_mono) auto then show "(dist (x \ i) (y \ i))\<^sup>2 < e\<^sup>2 / real DIM('a)" by (simp add: power_divide) qed auto also have "\ = e" using \0 < e\ by simp finally show "y \ ball x e" by (auto simp: ball_def) qed (insert a b, auto simp: box_def) qed lemma open_UNION_box: fixes M :: "'a::euclidean_space set" assumes "open M" defines "a' \ \f :: 'a \ real \ real. (\(i::'a)\Basis. fst (f i) *\<^sub>R i)" defines "b' \ \f :: 'a \ real \ real. (\(i::'a)\Basis. snd (f i) *\<^sub>R i)" defines "I \ {f\Basis \\<^sub>E \ \ \. box (a' f) (b' f) \ M}" shows "M = (\f\I. box (a' f) (b' f))" proof - have "x \ (\f\I. box (a' f) (b' f))" if "x \ M" for x proof - obtain e where e: "e > 0" "ball x e \ M" using openE[OF \open M\ \x \ M\] by auto moreover obtain a b where ab: "x \ box a b" "\i \ Basis. a \ i \ \" "\i\Basis. b \ i \ \" "box a b \ ball x e" using rational_boxes[OF e(1)] by metis ultimately show ?thesis by (intro UN_I[of "\i\Basis. (a \ i, b \ i)"]) (auto simp: euclidean_representation I_def a'_def b'_def) qed then show ?thesis by (auto simp: I_def) qed corollary open_countable_Union_open_box: fixes S :: "'a :: euclidean_space set" assumes "open S" obtains \ where "countable \" "\ \ Pow S" "\X. X \ \ \ \a b. X = box a b" "\\ = S" proof - let ?a = "\f. (\(i::'a)\Basis. fst (f i) *\<^sub>R i)" let ?b = "\f. (\(i::'a)\Basis. snd (f i) *\<^sub>R i)" let ?I = "{f\Basis \\<^sub>E \ \ \. box (?a f) (?b f) \ S}" let ?\ = "(\f. box (?a f) (?b f)) ` ?I" show ?thesis proof have "countable ?I" by (simp add: countable_PiE countable_rat) then show "countable ?\" by blast show "\?\ = S" using open_UNION_box [OF assms] by metis qed auto qed lemma rational_cboxes: fixes x :: "'a::euclidean_space" assumes "e > 0" shows "\a b. (\i\Basis. a \ i \ \ \ b \ i \ \) \ x \ cbox a b \ cbox a b \ ball x e" proof - define e' where "e' = e / (2 * sqrt (real (DIM ('a))))" then have e: "e' > 0" using assms by auto have "\i. \y. y \ \ \ y < x \ i \ x \ i - y < e'" (is "\i. ?th i") proof fix i from Rats_dense_in_real[of "x \ i - e'" "x \ i"] e show "?th i" by auto qed from choice[OF this] obtain a where a: "\u. a u \ \ \ a u < x \ u \ x \ u - a u < e'" .. have "\i. \y. y \ \ \ x \ i < y \ y - x \ i < e'" (is "\i. ?th i") proof fix i from Rats_dense_in_real[of "x \ i" "x \ i + e'"] e show "?th i" by auto qed from choice[OF this] obtain b where b: "\u. b u \ \ \ x \ u < b u \ b u - x \ u < e'" .. let ?a = "\i\Basis. a i *\<^sub>R i" and ?b = "\i\Basis. b i *\<^sub>R i" show ?thesis proof (rule exI[of _ ?a], rule exI[of _ ?b], safe) fix y :: 'a assume *: "y \ cbox ?a ?b" have "dist x y = sqrt (\i\Basis. (dist (x \ i) (y \ i))\<^sup>2)" unfolding L2_set_def[symmetric] by (rule euclidean_dist_l2) also have "\ < sqrt (\(i::'a)\Basis. e^2 / real (DIM('a)))" proof (rule real_sqrt_less_mono, rule sum_strict_mono) fix i :: "'a" assume i: "i \ Basis" have "a i \ y\i \ y\i \ b i" using * i by (auto simp: cbox_def) moreover have "a i < x\i" "x\i - a i < e'" using a by auto moreover have "x\i < b i" "b i - x\i < e'" using b by auto ultimately have "\x\i - y\i\ < 2 * e'" by auto then have "dist (x \ i) (y \ i) < e/sqrt (real (DIM('a)))" unfolding e'_def by (auto simp: dist_real_def) then have "(dist (x \ i) (y \ i))\<^sup>2 < (e/sqrt (real (DIM('a))))\<^sup>2" by (rule power_strict_mono) auto then show "(dist (x \ i) (y \ i))\<^sup>2 < e\<^sup>2 / real DIM('a)" by (simp add: power_divide) qed auto also have "\ = e" using \0 < e\ by simp finally show "y \ ball x e" by (auto simp: ball_def) next show "x \ cbox (\i\Basis. a i *\<^sub>R i) (\i\Basis. b i *\<^sub>R i)" using a b less_imp_le by (auto simp: cbox_def) qed (use a b cbox_def in auto) qed lemma open_UNION_cbox: fixes M :: "'a::euclidean_space set" assumes "open M" defines "a' \ \f. (\(i::'a)\Basis. fst (f i) *\<^sub>R i)" defines "b' \ \f. (\(i::'a)\Basis. snd (f i) *\<^sub>R i)" defines "I \ {f\Basis \\<^sub>E \ \ \. cbox (a' f) (b' f) \ M}" shows "M = (\f\I. cbox (a' f) (b' f))" proof - have "x \ (\f\I. cbox (a' f) (b' f))" if "x \ M" for x proof - obtain e where e: "e > 0" "ball x e \ M" using openE[OF \open M\ \x \ M\] by auto moreover obtain a b where ab: "x \ cbox a b" "\i \ Basis. a \ i \ \" "\i \ Basis. b \ i \ \" "cbox a b \ ball x e" using rational_cboxes[OF e(1)] by metis ultimately show ?thesis by (intro UN_I[of "\i\Basis. (a \ i, b \ i)"]) (auto simp: euclidean_representation I_def a'_def b'_def) qed then show ?thesis by (auto simp: I_def) qed corollary open_countable_Union_open_cbox: fixes S :: "'a :: euclidean_space set" assumes "open S" obtains \ where "countable \" "\ \ Pow S" "\X. X \ \ \ \a b. X = cbox a b" "\\ = S" proof - let ?a = "\f. (\(i::'a)\Basis. fst (f i) *\<^sub>R i)" let ?b = "\f. (\(i::'a)\Basis. snd (f i) *\<^sub>R i)" let ?I = "{f\Basis \\<^sub>E \ \ \. cbox (?a f) (?b f) \ S}" let ?\ = "(\f. cbox (?a f) (?b f)) ` ?I" show ?thesis proof have "countable ?I" by (simp add: countable_PiE countable_rat) then show "countable ?\" by blast show "\?\ = S" using open_UNION_cbox [OF assms] by metis qed auto qed lemma box_eq_empty: fixes a :: "'a::euclidean_space" shows "(box a b = {} \ (\i\Basis. b\i \ a\i))" (is ?th1) and "(cbox a b = {} \ (\i\Basis. b\i < a\i))" (is ?th2) proof - { fix i x assume i: "i\Basis" and as:"b\i \ a\i" and x:"x\box a b" then have "a \ i < x \ i \ x \ i < b \ i" unfolding mem_box by (auto simp: box_def) then have "a\i < b\i" by auto then have False using as by auto } moreover { assume as: "\i\Basis. \ (b\i \ a\i)" let ?x = "(1/2) *\<^sub>R (a + b)" { fix i :: 'a assume i: "i \ Basis" have "a\i < b\i" using as[THEN bspec[where x=i]] i by auto then have "a\i < ((1/2) *\<^sub>R (a+b)) \ i" "((1/2) *\<^sub>R (a+b)) \ i < b\i" by (auto simp: inner_add_left) } then have "box a b \ {}" using mem_box(1)[of "?x" a b] by auto } ultimately show ?th1 by blast { fix i x assume i: "i \ Basis" and as:"b\i < a\i" and x:"x\cbox a b" then have "a \ i \ x \ i \ x \ i \ b \ i" unfolding mem_box by auto then have "a\i \ b\i" by auto then have False using as by auto } moreover { assume as:"\i\Basis. \ (b\i < a\i)" let ?x = "(1/2) *\<^sub>R (a + b)" { fix i :: 'a assume i:"i \ Basis" have "a\i \ b\i" using as[THEN bspec[where x=i]] i by auto then have "a\i \ ((1/2) *\<^sub>R (a+b)) \ i" "((1/2) *\<^sub>R (a+b)) \ i \ b\i" by (auto simp: inner_add_left) } then have "cbox a b \ {}" using mem_box(2)[of "?x" a b] by auto } ultimately show ?th2 by blast qed lemma box_ne_empty: fixes a :: "'a::euclidean_space" shows "cbox a b \ {} \ (\i\Basis. a\i \ b\i)" and "box a b \ {} \ (\i\Basis. a\i < b\i)" unfolding box_eq_empty[of a b] by fastforce+ lemma fixes a :: "'a::euclidean_space" shows cbox_sing [simp]: "cbox a a = {a}" and box_sing [simp]: "box a a = {}" unfolding set_eq_iff mem_box eq_iff [symmetric] by (auto intro!: euclidean_eqI[where 'a='a]) (metis all_not_in_conv nonempty_Basis) lemma subset_box_imp: fixes a :: "'a::euclidean_space" shows "(\i\Basis. a\i \ c\i \ d\i \ b\i) \ cbox c d \ cbox a b" and "(\i\Basis. a\i < c\i \ d\i < b\i) \ cbox c d \ box a b" and "(\i\Basis. a\i \ c\i \ d\i \ b\i) \ box c d \ cbox a b" and "(\i\Basis. a\i \ c\i \ d\i \ b\i) \ box c d \ box a b" unfolding subset_eq[unfolded Ball_def] unfolding mem_box by (best intro: order_trans less_le_trans le_less_trans less_imp_le)+ lemma box_subset_cbox: fixes a :: "'a::euclidean_space" shows "box a b \ cbox a b" unfolding subset_eq [unfolded Ball_def] mem_box by (fast intro: less_imp_le) lemma subset_box: fixes a :: "'a::euclidean_space" shows "cbox c d \ cbox a b \ (\i\Basis. c\i \ d\i) \ (\i\Basis. a\i \ c\i \ d\i \ b\i)" (is ?th1) and "cbox c d \ box a b \ (\i\Basis. c\i \ d\i) \ (\i\Basis. a\i < c\i \ d\i < b\i)" (is ?th2) and "box c d \ cbox a b \ (\i\Basis. c\i < d\i) \ (\i\Basis. a\i \ c\i \ d\i \ b\i)" (is ?th3) and "box c d \ box a b \ (\i\Basis. c\i < d\i) \ (\i\Basis. a\i \ c\i \ d\i \ b\i)" (is ?th4) proof - let ?lesscd = "\i\Basis. c\i < d\i" let ?lerhs = "\i\Basis. a\i \ c\i \ d\i \ b\i" show ?th1 ?th2 by (fastforce simp: mem_box)+ have acdb: "a\i \ c\i \ d\i \ b\i" if i: "i \ Basis" and box: "box c d \ cbox a b" and cd: "\i. i \ Basis \ c\i < d\i" for i proof - have "box c d \ {}" using that unfolding box_eq_empty by force { let ?x = "(\j\Basis. (if j=i then ((min (a\j) (d\j))+c\j)/2 else (c\j+d\j)/2) *\<^sub>R j)::'a" assume *: "a\i > c\i" then have "c \ j < ?x \ j \ ?x \ j < d \ j" if "j \ Basis" for j using cd that by (fastforce simp add: i *) then have "?x \ box c d" unfolding mem_box by auto moreover have "?x \ cbox a b" using i cd * by (force simp: mem_box) ultimately have False using box by auto } then have "a\i \ c\i" by force moreover { let ?x = "(\j\Basis. (if j=i then ((max (b\j) (c\j))+d\j)/2 else (c\j+d\j)/2) *\<^sub>R j)::'a" assume *: "b\i < d\i" then have "d \ j > ?x \ j \ ?x \ j > c \ j" if "j \ Basis" for j using cd that by (fastforce simp add: i *) then have "?x \ box c d" unfolding mem_box by auto moreover have "?x \ cbox a b" using i cd * by (force simp: mem_box) ultimately have False using box by auto } then have "b\i \ d\i" by (rule ccontr) auto ultimately show ?thesis by auto qed show ?th3 using acdb by (fastforce simp add: mem_box) have acdb': "a\i \ c\i \ d\i \ b\i" if "i \ Basis" "box c d \ box a b" "\i. i \ Basis \ c\i < d\i" for i using box_subset_cbox[of a b] that acdb by auto show ?th4 using acdb' by (fastforce simp add: mem_box) qed lemma eq_cbox: "cbox a b = cbox c d \ cbox a b = {} \ cbox c d = {} \ a = c \ b = d" (is "?lhs = ?rhs") proof assume ?lhs then have "cbox a b \ cbox c d" "cbox c d \ cbox a b" by auto then show ?rhs by (force simp: subset_box box_eq_empty intro: antisym euclidean_eqI) next assume ?rhs then show ?lhs by force qed lemma eq_cbox_box [simp]: "cbox a b = box c d \ cbox a b = {} \ box c d = {}" (is "?lhs \ ?rhs") proof assume L: ?lhs then have "cbox a b \ box c d" "box c d \ cbox a b" by auto then show ?rhs apply (simp add: subset_box) using L box_ne_empty box_sing apply (fastforce simp add:) done qed force lemma eq_box_cbox [simp]: "box a b = cbox c d \ box a b = {} \ cbox c d = {}" by (metis eq_cbox_box) lemma eq_box: "box a b = box c d \ box a b = {} \ box c d = {} \ a = c \ b = d" (is "?lhs \ ?rhs") proof assume L: ?lhs then have "box a b \ box c d" "box c d \ box a b" by auto then show ?rhs apply (simp add: subset_box) using box_ne_empty(2) L apply auto apply (meson euclidean_eqI less_eq_real_def not_less)+ done qed force lemma subset_box_complex: "cbox a b \ cbox c d \ (Re a \ Re b \ Im a \ Im b) \ Re a \ Re c \ Im a \ Im c \ Re b \ Re d \ Im b \ Im d" "cbox a b \ box c d \ (Re a \ Re b \ Im a \ Im b) \ Re a > Re c \ Im a > Im c \ Re b < Re d \ Im b < Im d" "box a b \ cbox c d \ (Re a < Re b \ Im a < Im b) \ Re a \ Re c \ Im a \ Im c \ Re b \ Re d \ Im b \ Im d" "box a b \ box c d \ (Re a < Re b \ Im a < Im b) \ Re a \ Re c \ Im a \ Im c \ Re b \ Re d \ Im b \ Im d" by (subst subset_box; force simp: Basis_complex_def)+ lemma in_cbox_complex_iff: "x \ cbox a b \ Re x \ {Re a..Re b} \ Im x \ {Im a..Im b}" by (cases x; cases a; cases b) (auto simp: cbox_Complex_eq) lemma box_Complex_eq: "box (Complex a c) (Complex b d) = (\(x,y). Complex x y) ` (box a b \ box c d)" by (auto simp: box_def Basis_complex_def image_iff complex_eq_iff) lemma in_box_complex_iff: "x \ box a b \ Re x \ {Re a<.. Im x \ {Im a<.. cbox c d = cbox (\i\Basis. max (a\i) (c\i) *\<^sub>R i) (\i\Basis. min (b\i) (d\i) *\<^sub>R i)" unfolding set_eq_iff and Int_iff and mem_box by auto lemma disjoint_interval: fixes a::"'a::euclidean_space" shows "cbox a b \ cbox c d = {} \ (\i\Basis. (b\i < a\i \ d\i < c\i \ b\i < c\i \ d\i < a\i))" (is ?th1) and "cbox a b \ box c d = {} \ (\i\Basis. (b\i < a\i \ d\i \ c\i \ b\i \ c\i \ d\i \ a\i))" (is ?th2) and "box a b \ cbox c d = {} \ (\i\Basis. (b\i \ a\i \ d\i < c\i \ b\i \ c\i \ d\i \ a\i))" (is ?th3) and "box a b \ box c d = {} \ (\i\Basis. (b\i \ a\i \ d\i \ c\i \ b\i \ c\i \ d\i \ a\i))" (is ?th4) proof - let ?z = "(\i\Basis. (((max (a\i) (c\i)) + (min (b\i) (d\i))) / 2) *\<^sub>R i)::'a" have **: "\P Q. (\i :: 'a. i \ Basis \ Q ?z i \ P i) \ (\i x :: 'a. i \ Basis \ P i \ Q x i) \ (\x. \i\Basis. Q x i) \ (\i\Basis. P i)" by blast note * = set_eq_iff Int_iff empty_iff mem_box ball_conj_distrib[symmetric] eq_False ball_simps(10) show ?th1 unfolding * by (intro **) auto show ?th2 unfolding * by (intro **) auto show ?th3 unfolding * by (intro **) auto show ?th4 unfolding * by (intro **) auto qed lemma UN_box_eq_UNIV: "(\i::nat. box (- (real i *\<^sub>R One)) (real i *\<^sub>R One)) = UNIV" proof - have "\x \ b\ < real_of_int (\Max ((\b. \x \ b\)`Basis)\ + 1)" if [simp]: "b \ Basis" for x b :: 'a proof - have "\x \ b\ \ real_of_int \\x \ b\\" by (rule le_of_int_ceiling) also have "\ \ real_of_int \Max ((\b. \x \ b\)`Basis)\" by (auto intro!: ceiling_mono) also have "\ < real_of_int (\Max ((\b. \x \ b\)`Basis)\ + 1)" by simp finally show ?thesis . qed then have "\n::nat. \b\Basis. \x \ b\ < real n" for x :: 'a by (metis order.strict_trans reals_Archimedean2) moreover have "\x b::'a. \n::nat. \x \ b\ < real n \ - real n < x \ b \ x \ b < real n" by auto ultimately show ?thesis by (auto simp: box_def inner_sum_left inner_Basis sum.If_cases) qed lemma image_affinity_cbox: fixes m::real fixes a b c :: "'a::euclidean_space" shows "(\x. m *\<^sub>R x + c) ` cbox a b = (if cbox a b = {} then {} else (if 0 \ m then cbox (m *\<^sub>R a + c) (m *\<^sub>R b + c) else cbox (m *\<^sub>R b + c) (m *\<^sub>R a + c)))" proof (cases "m = 0") case True { fix x assume "\i\Basis. x \ i \ c \ i" "\i\Basis. c \ i \ x \ i" then have "x = c" by (simp add: dual_order.antisym euclidean_eqI) } moreover have "c \ cbox (m *\<^sub>R a + c) (m *\<^sub>R b + c)" unfolding True by (auto) ultimately show ?thesis using True by (auto simp: cbox_def) next case False { fix y assume "\i\Basis. a \ i \ y \ i" "\i\Basis. y \ i \ b \ i" "m > 0" then have "\i\Basis. (m *\<^sub>R a + c) \ i \ (m *\<^sub>R y + c) \ i" and "\i\Basis. (m *\<^sub>R y + c) \ i \ (m *\<^sub>R b + c) \ i" by (auto simp: inner_distrib) } moreover { fix y assume "\i\Basis. a \ i \ y \ i" "\i\Basis. y \ i \ b \ i" "m < 0" then have "\i\Basis. (m *\<^sub>R b + c) \ i \ (m *\<^sub>R y + c) \ i" and "\i\Basis. (m *\<^sub>R y + c) \ i \ (m *\<^sub>R a + c) \ i" by (auto simp: mult_left_mono_neg inner_distrib) } moreover { fix y assume "m > 0" and "\i\Basis. (m *\<^sub>R a + c) \ i \ y \ i" and "\i\Basis. y \ i \ (m *\<^sub>R b + c) \ i" then have "y \ (\x. m *\<^sub>R x + c) ` cbox a b" unfolding image_iff Bex_def mem_box apply (intro exI[where x="(1 / m) *\<^sub>R (y - c)"]) apply (auto simp: pos_le_divide_eq pos_divide_le_eq mult.commute inner_distrib inner_diff_left) done } moreover { fix y assume "\i\Basis. (m *\<^sub>R b + c) \ i \ y \ i" "\i\Basis. y \ i \ (m *\<^sub>R a + c) \ i" "m < 0" then have "y \ (\x. m *\<^sub>R x + c) ` cbox a b" unfolding image_iff Bex_def mem_box apply (intro exI[where x="(1 / m) *\<^sub>R (y - c)"]) apply (auto simp: neg_le_divide_eq neg_divide_le_eq mult.commute inner_distrib inner_diff_left) done } ultimately show ?thesis using False by (auto simp: cbox_def) qed lemma image_smult_cbox:"(\x. m *\<^sub>R (x::_::euclidean_space)) ` cbox a b = (if cbox a b = {} then {} else if 0 \ m then cbox (m *\<^sub>R a) (m *\<^sub>R b) else cbox (m *\<^sub>R b) (m *\<^sub>R a))" using image_affinity_cbox[of m 0 a b] by auto lemma swap_continuous: assumes "continuous_on (cbox (a,c) (b,d)) (\(x,y). f x y)" shows "continuous_on (cbox (c,a) (d,b)) (\(x, y). f y x)" proof - have "(\(x, y). f y x) = (\(x, y). f x y) \ prod.swap" by auto then show ?thesis apply (rule ssubst) apply (rule continuous_on_compose) apply (simp add: split_def) apply (rule continuous_intros | simp add: assms)+ done qed subsection \General Intervals\ definition\<^marker>\tag important\ "is_interval (s::('a::euclidean_space) set) \ (\a\s. \b\s. \x. (\i\Basis. ((a\i \ x\i \ x\i \ b\i) \ (b\i \ x\i \ x\i \ a\i))) \ x \ s)" lemma is_interval_1: "is_interval (s::real set) \ (\a\s. \b\s. \ x. a \ x \ x \ b \ x \ s)" unfolding is_interval_def by auto lemma is_interval_Int: "is_interval X \ is_interval Y \ is_interval (X \ Y)" unfolding is_interval_def by blast lemma is_interval_cbox [simp]: "is_interval (cbox a (b::'a::euclidean_space))" (is ?th1) and is_interval_box [simp]: "is_interval (box a b)" (is ?th2) unfolding is_interval_def mem_box Ball_def atLeastAtMost_iff by (meson order_trans le_less_trans less_le_trans less_trans)+ lemma is_interval_empty [iff]: "is_interval {}" unfolding is_interval_def by simp lemma is_interval_univ [iff]: "is_interval UNIV" unfolding is_interval_def by simp lemma mem_is_intervalI: assumes "is_interval s" and "a \ s" "b \ s" and "\i. i \ Basis \ a \ i \ x \ i \ x \ i \ b \ i \ b \ i \ x \ i \ x \ i \ a \ i" shows "x \ s" by (rule assms(1)[simplified is_interval_def, rule_format, OF assms(2,3,4)]) lemma interval_subst: fixes S::"'a::euclidean_space set" assumes "is_interval S" and "x \ S" "y j \ S" and "j \ Basis" shows "(\i\Basis. (if i = j then y i \ i else x \ i) *\<^sub>R i) \ S" by (rule mem_is_intervalI[OF assms(1,2)]) (auto simp: assms) lemma mem_box_componentwiseI: fixes S::"'a::euclidean_space set" assumes "is_interval S" assumes "\i. i \ Basis \ x \ i \ ((\x. x \ i) ` S)" shows "x \ S" proof - from assms have "\i \ Basis. \s \ S. x \ i = s \ i" by auto with finite_Basis obtain s and bs::"'a list" where s: "\i. i \ Basis \ x \ i = s i \ i" "\i. i \ Basis \ s i \ S" and bs: "set bs = Basis" "distinct bs" by (metis finite_distinct_list) from nonempty_Basis s obtain j where j: "j \ Basis" "s j \ S" by blast define y where "y = rec_list (s j) (\j _ Y. (\i\Basis. (if i = j then s i \ i else Y \ i) *\<^sub>R i))" have "x = (\i\Basis. (if i \ set bs then s i \ i else s j \ i) *\<^sub>R i)" using bs by (auto simp: s(1)[symmetric] euclidean_representation) also have [symmetric]: "y bs = \" using bs(2) bs(1)[THEN equalityD1] by (induct bs) (auto simp: y_def euclidean_representation intro!: euclidean_eqI[where 'a='a]) also have "y bs \ S" using bs(1)[THEN equalityD1] apply (induct bs) apply (auto simp: y_def j) apply (rule interval_subst[OF assms(1)]) apply (auto simp: s) done finally show ?thesis . qed lemma cbox01_nonempty [simp]: "cbox 0 One \ {}" by (simp add: box_ne_empty inner_Basis inner_sum_left sum_nonneg) lemma box01_nonempty [simp]: "box 0 One \ {}" by (simp add: box_ne_empty inner_Basis inner_sum_left) lemma empty_as_interval: "{} = cbox One (0::'a::euclidean_space)" using nonempty_Basis box01_nonempty box_eq_empty(1) box_ne_empty(1) by blast lemma interval_subset_is_interval: assumes "is_interval S" shows "cbox a b \ S \ cbox a b = {} \ a \ S \ b \ S" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs using box_ne_empty(1) mem_box(2) by fastforce next assume ?rhs have "cbox a b \ S" if "a \ S" "b \ S" using assms unfolding is_interval_def apply (clarsimp simp add: mem_box) using that by blast with \?rhs\ show ?lhs by blast qed lemma is_real_interval_union: "is_interval (X \ Y)" if X: "is_interval X" and Y: "is_interval Y" and I: "(X \ {} \ Y \ {} \ X \ Y \ {})" for X Y::"real set" proof - consider "X \ {}" "Y \ {}" | "X = {}" | "Y = {}" by blast then show ?thesis proof cases case 1 then obtain r where "r \ X \ X \ Y = {}" "r \ Y \ X \ Y = {}" by blast then show ?thesis using I 1 X Y unfolding is_interval_1 by (metis (full_types) Un_iff le_cases) qed (use that in auto) qed lemma is_interval_translationI: assumes "is_interval X" shows "is_interval ((+) x ` X)" unfolding is_interval_def proof safe fix b d e assume "b \ X" "d \ X" "\i\Basis. (x + b) \ i \ e \ i \ e \ i \ (x + d) \ i \ (x + d) \ i \ e \ i \ e \ i \ (x + b) \ i" hence "e - x \ X" by (intro mem_is_intervalI[OF assms \b \ X\ \d \ X\, of "e - x"]) (auto simp: algebra_simps) thus "e \ (+) x ` X" by force qed lemma is_interval_uminusI: assumes "is_interval X" shows "is_interval (uminus ` X)" unfolding is_interval_def proof safe fix b d e assume "b \ X" "d \ X" "\i\Basis. (- b) \ i \ e \ i \ e \ i \ (- d) \ i \ (- d) \ i \ e \ i \ e \ i \ (- b) \ i" hence "- e \ X" by (intro mem_is_intervalI[OF assms \b \ X\ \d \ X\, of "- e"]) (auto simp: algebra_simps) thus "e \ uminus ` X" by force qed lemma is_interval_uminus[simp]: "is_interval (uminus ` x) = is_interval x" using is_interval_uminusI[of x] is_interval_uminusI[of "uminus ` x"] by (auto simp: image_image) lemma is_interval_neg_translationI: assumes "is_interval X" shows "is_interval ((-) x ` X)" proof - have "(-) x ` X = (+) x ` uminus ` X" by (force simp: algebra_simps) also have "is_interval \" by (metis is_interval_uminusI is_interval_translationI assms) finally show ?thesis . qed lemma is_interval_translation[simp]: "is_interval ((+) x ` X) = is_interval X" using is_interval_neg_translationI[of "(+) x ` X" x] by (auto intro!: is_interval_translationI simp: image_image) lemma is_interval_minus_translation[simp]: shows "is_interval ((-) x ` X) = is_interval X" proof - have "(-) x ` X = (+) x ` uminus ` X" by (force simp: algebra_simps) also have "is_interval \ = is_interval X" by simp finally show ?thesis . qed lemma is_interval_minus_translation'[simp]: shows "is_interval ((\x. x - c) ` X) = is_interval X" using is_interval_translation[of "-c" X] by (metis image_cong uminus_add_conv_diff) lemma is_interval_cball_1[intro, simp]: "is_interval (cball a b)" for a b::real by (simp add: cball_eq_atLeastAtMost is_interval_def) lemma is_interval_ball_real: "is_interval (ball a b)" for a b::real by (simp add: ball_eq_greaterThanLessThan is_interval_def) subsection\<^marker>\tag unimportant\ \Bounded Projections\ lemma bounded_inner_imp_bdd_above: assumes "bounded s" shows "bdd_above ((\x. x \ a) ` s)" by (simp add: assms bounded_imp_bdd_above bounded_linear_image bounded_linear_inner_left) lemma bounded_inner_imp_bdd_below: assumes "bounded s" shows "bdd_below ((\x. x \ a) ` s)" by (simp add: assms bounded_imp_bdd_below bounded_linear_image bounded_linear_inner_left) subsection\<^marker>\tag unimportant\ \Structural rules for pointwise continuity\ lemma continuous_infnorm[continuous_intros]: "continuous F f \ continuous F (\x. infnorm (f x))" unfolding continuous_def by (rule tendsto_infnorm) lemma continuous_inner[continuous_intros]: assumes "continuous F f" and "continuous F g" shows "continuous F (\x. inner (f x) (g x))" using assms unfolding continuous_def by (rule tendsto_inner) subsection\<^marker>\tag unimportant\ \Structural rules for setwise continuity\ lemma continuous_on_infnorm[continuous_intros]: "continuous_on s f \ continuous_on s (\x. infnorm (f x))" unfolding continuous_on by (fast intro: tendsto_infnorm) lemma continuous_on_inner[continuous_intros]: fixes g :: "'a::topological_space \ 'b::real_inner" assumes "continuous_on s f" and "continuous_on s g" shows "continuous_on s (\x. inner (f x) (g x))" using bounded_bilinear_inner assms by (rule bounded_bilinear.continuous_on) subsection\<^marker>\tag unimportant\ \Openness of halfspaces.\ lemma open_halfspace_lt: "open {x. inner a x < b}" by (simp add: open_Collect_less continuous_on_inner) lemma open_halfspace_gt: "open {x. inner a x > b}" by (simp add: open_Collect_less continuous_on_inner) lemma open_halfspace_component_lt: "open {x::'a::euclidean_space. x\i < a}" by (simp add: open_Collect_less continuous_on_inner) lemma open_halfspace_component_gt: "open {x::'a::euclidean_space. x\i > a}" by (simp add: open_Collect_less continuous_on_inner) lemma eucl_less_eq_halfspaces: fixes a :: "'a::euclidean_space" shows "{x. x i\Basis. {x. x \ i < a \ i})" "{x. a i\Basis. {x. a \ i < x \ i})" by (auto simp: eucl_less_def) lemma open_Collect_eucl_less[simp, intro]: fixes a :: "'a::euclidean_space" shows "open {x. x \tag unimportant\ \Closure and Interior of halfspaces and hyperplanes\ lemma continuous_at_inner: "continuous (at x) (inner a)" unfolding continuous_at by (intro tendsto_intros) lemma closed_halfspace_le: "closed {x. inner a x \ b}" by (simp add: closed_Collect_le continuous_on_inner) lemma closed_halfspace_ge: "closed {x. inner a x \ b}" by (simp add: closed_Collect_le continuous_on_inner) lemma closed_hyperplane: "closed {x. inner a x = b}" by (simp add: closed_Collect_eq continuous_on_inner) lemma closed_halfspace_component_le: "closed {x::'a::euclidean_space. x\i \ a}" by (simp add: closed_Collect_le continuous_on_inner) lemma closed_halfspace_component_ge: "closed {x::'a::euclidean_space. x\i \ a}" by (simp add: closed_Collect_le continuous_on_inner) lemma closed_interval_left: fixes b :: "'a::euclidean_space" shows "closed {x::'a. \i\Basis. x\i \ b\i}" by (simp add: Collect_ball_eq closed_INT closed_Collect_le continuous_on_inner) lemma closed_interval_right: fixes a :: "'a::euclidean_space" shows "closed {x::'a. \i\Basis. a\i \ x\i}" by (simp add: Collect_ball_eq closed_INT closed_Collect_le continuous_on_inner) lemma interior_halfspace_le [simp]: assumes "a \ 0" shows "interior {x. a \ x \ b} = {x. a \ x < b}" proof - have *: "a \ x < b" if x: "x \ S" and S: "S \ {x. a \ x \ b}" and "open S" for S x proof - obtain e where "e>0" and e: "cball x e \ S" using \open S\ open_contains_cball x by blast then have "x + (e / norm a) *\<^sub>R a \ cball x e" by (simp add: dist_norm) then have "x + (e / norm a) *\<^sub>R a \ S" using e by blast then have "x + (e / norm a) *\<^sub>R a \ {x. a \ x \ b}" using S by blast moreover have "e * (a \ a) / norm a > 0" by (simp add: \0 < e\ assms) ultimately show ?thesis by (simp add: algebra_simps) qed show ?thesis by (rule interior_unique) (auto simp: open_halfspace_lt *) qed lemma interior_halfspace_ge [simp]: "a \ 0 \ interior {x. a \ x \ b} = {x. a \ x > b}" using interior_halfspace_le [of "-a" "-b"] by simp lemma closure_halfspace_lt [simp]: assumes "a \ 0" shows "closure {x. a \ x < b} = {x. a \ x \ b}" proof - have [simp]: "-{x. a \ x < b} = {x. a \ x \ b}" by (force simp:) then show ?thesis using interior_halfspace_ge [of a b] assms by (force simp: closure_interior) qed lemma closure_halfspace_gt [simp]: "a \ 0 \ closure {x. a \ x > b} = {x. a \ x \ b}" using closure_halfspace_lt [of "-a" "-b"] by simp lemma interior_hyperplane [simp]: assumes "a \ 0" shows "interior {x. a \ x = b} = {}" proof - have [simp]: "{x. a \ x = b} = {x. a \ x \ b} \ {x. a \ x \ b}" by (force simp:) then show ?thesis by (auto simp: assms) qed lemma frontier_halfspace_le: assumes "a \ 0 \ b \ 0" shows "frontier {x. a \ x \ b} = {x. a \ x = b}" proof (cases "a = 0") case True with assms show ?thesis by simp next case False then show ?thesis by (force simp: frontier_def closed_halfspace_le) qed lemma frontier_halfspace_ge: assumes "a \ 0 \ b \ 0" shows "frontier {x. a \ x \ b} = {x. a \ x = b}" proof (cases "a = 0") case True with assms show ?thesis by simp next case False then show ?thesis by (force simp: frontier_def closed_halfspace_ge) qed lemma frontier_halfspace_lt: assumes "a \ 0 \ b \ 0" shows "frontier {x. a \ x < b} = {x. a \ x = b}" proof (cases "a = 0") case True with assms show ?thesis by simp next case False then show ?thesis by (force simp: frontier_def interior_open open_halfspace_lt) qed lemma frontier_halfspace_gt: assumes "a \ 0 \ b \ 0" shows "frontier {x. a \ x > b} = {x. a \ x = b}" proof (cases "a = 0") case True with assms show ?thesis by simp next case False then show ?thesis by (force simp: frontier_def interior_open open_halfspace_gt) qed subsection\<^marker>\tag unimportant\\Some more convenient intermediate-value theorem formulations\ lemma connected_ivt_hyperplane: assumes "connected S" and xy: "x \ S" "y \ S" and b: "inner a x \ b" "b \ inner a y" shows "\z \ S. inner a z = b" proof (rule ccontr) assume as:"\ (\z\S. inner a z = b)" let ?A = "{x. inner a x < b}" let ?B = "{x. inner a x > b}" have "open ?A" "open ?B" using open_halfspace_lt and open_halfspace_gt by auto moreover have "?A \ ?B = {}" by auto moreover have "S \ ?A \ ?B" using as by auto ultimately show False using \connected S\[unfolded connected_def not_ex, THEN spec[where x="?A"], THEN spec[where x="?B"]] using xy b by auto qed lemma connected_ivt_component: fixes x::"'a::euclidean_space" shows "connected S \ x \ S \ y \ S \ x\k \ a \ a \ y\k \ (\z\S. z\k = a)" using connected_ivt_hyperplane[of S x y "k::'a" a] by (auto simp: inner_commute) subsection \Limit Component Bounds\ lemma Lim_component_le: fixes f :: "'a \ 'b::euclidean_space" assumes "(f \ l) net" and "\ (trivial_limit net)" and "eventually (\x. f(x)\i \ b) net" shows "l\i \ b" by (rule tendsto_le[OF assms(2) tendsto_const tendsto_inner[OF assms(1) tendsto_const] assms(3)]) lemma Lim_component_ge: fixes f :: "'a \ 'b::euclidean_space" assumes "(f \ l) net" and "\ (trivial_limit net)" and "eventually (\x. b \ (f x)\i) net" shows "b \ l\i" by (rule tendsto_le[OF assms(2) tendsto_inner[OF assms(1) tendsto_const] tendsto_const assms(3)]) lemma Lim_component_eq: fixes f :: "'a \ 'b::euclidean_space" assumes net: "(f \ l) net" "\ trivial_limit net" and ev:"eventually (\x. f(x)\i = b) net" shows "l\i = b" using ev[unfolded order_eq_iff eventually_conj_iff] using Lim_component_ge[OF net, of b i] using Lim_component_le[OF net, of i b] by auto lemma open_box[intro]: "open (box a b)" proof - have "open (\i\Basis. ((\) i) -` {a \ i <..< b \ i})" by (auto intro!: continuous_open_vimage continuous_inner continuous_ident continuous_const) also have "(\i\Basis. ((\) i) -` {a \ i <..< b \ i}) = box a b" by (auto simp: box_def inner_commute) finally show ?thesis . qed lemma closed_cbox[intro]: fixes a b :: "'a::euclidean_space" shows "closed (cbox a b)" proof - have "closed (\i\Basis. (\x. x\i) -` {a\i .. b\i})" by (intro closed_INT ballI continuous_closed_vimage allI linear_continuous_at closed_real_atLeastAtMost finite_Basis bounded_linear_inner_left) also have "(\i\Basis. (\x. x\i) -` {a\i .. b\i}) = cbox a b" by (auto simp: cbox_def) finally show "closed (cbox a b)" . qed lemma interior_cbox [simp]: fixes a b :: "'a::euclidean_space" shows "interior (cbox a b) = box a b" (is "?L = ?R") proof(rule subset_antisym) show "?R \ ?L" using box_subset_cbox open_box by (rule interior_maximal) { fix x assume "x \ interior (cbox a b)" then obtain s where s: "open s" "x \ s" "s \ cbox a b" .. then obtain e where "e>0" and e:"\x'. dist x' x < e \ x' \ cbox a b" unfolding open_dist and subset_eq by auto { fix i :: 'a assume i: "i \ Basis" have "dist (x - (e / 2) *\<^sub>R i) x < e" and "dist (x + (e / 2) *\<^sub>R i) x < e" unfolding dist_norm apply auto unfolding norm_minus_cancel using norm_Basis[OF i] \e>0\ apply auto done then have "a \ i \ (x - (e / 2) *\<^sub>R i) \ i" and "(x + (e / 2) *\<^sub>R i) \ i \ b \ i" using e[THEN spec[where x="x - (e/2) *\<^sub>R i"]] and e[THEN spec[where x="x + (e/2) *\<^sub>R i"]] unfolding mem_box using i by blast+ then have "a \ i < x \ i" and "x \ i < b \ i" using \e>0\ i by (auto simp: inner_diff_left inner_Basis inner_add_left) } then have "x \ box a b" unfolding mem_box by auto } then show "?L \ ?R" .. qed lemma bounded_cbox [simp]: fixes a :: "'a::euclidean_space" shows "bounded (cbox a b)" proof - let ?b = "\i\Basis. \a\i\ + \b\i\" { fix x :: "'a" assume "\i. i\Basis \ a \ i \ x \ i \ x \ i \ b \ i" then have "(\i\Basis. \x \ i\) \ ?b" by (force simp: intro!: sum_mono) then have "norm x \ ?b" using norm_le_l1[of x] by auto } then show ?thesis unfolding cbox_def bounded_iff by force qed lemma bounded_box [simp]: fixes a :: "'a::euclidean_space" shows "bounded (box a b)" using bounded_cbox[of a b] box_subset_cbox[of a b] bounded_subset[of "cbox a b" "box a b"] by simp lemma not_interval_UNIV [simp]: fixes a :: "'a::euclidean_space" shows "cbox a b \ UNIV" "box a b \ UNIV" using bounded_box[of a b] bounded_cbox[of a b] by force+ lemma not_interval_UNIV2 [simp]: fixes a :: "'a::euclidean_space" shows "UNIV \ cbox a b" "UNIV \ box a b" using bounded_box[of a b] bounded_cbox[of a b] by force+ lemma box_midpoint: fixes a :: "'a::euclidean_space" assumes "box a b \ {}" shows "((1/2) *\<^sub>R (a + b)) \ box a b" proof - have "a \ i < ((1 / 2) *\<^sub>R (a + b)) \ i \ ((1 / 2) *\<^sub>R (a + b)) \ i < b \ i" if "i \ Basis" for i using assms that by (auto simp: inner_add_left box_ne_empty) then show ?thesis unfolding mem_box by auto qed lemma open_cbox_convex: fixes x :: "'a::euclidean_space" assumes x: "x \ box a b" and y: "y \ cbox a b" and e: "0 < e" "e \ 1" shows "(e *\<^sub>R x + (1 - e) *\<^sub>R y) \ box a b" proof - { fix i :: 'a assume i: "i \ Basis" have "a \ i = e * (a \ i) + (1 - e) * (a \ i)" unfolding left_diff_distrib by simp also have "\ < e * (x \ i) + (1 - e) * (y \ i)" proof (rule add_less_le_mono) show "e * (a \ i) < e * (x \ i)" using \0 < e\ i mem_box(1) x by auto show "(1 - e) * (a \ i) \ (1 - e) * (y \ i)" by (meson diff_ge_0_iff_ge \e \ 1\ i mem_box(2) mult_left_mono y) qed finally have "a \ i < (e *\<^sub>R x + (1 - e) *\<^sub>R y) \ i" unfolding inner_simps by auto moreover { have "b \ i = e * (b\i) + (1 - e) * (b\i)" unfolding left_diff_distrib by simp also have "\ > e * (x \ i) + (1 - e) * (y \ i)" proof (rule add_less_le_mono) show "e * (x \ i) < e * (b \ i)" using \0 < e\ i mem_box(1) x by auto show "(1 - e) * (y \ i) \ (1 - e) * (b \ i)" by (meson diff_ge_0_iff_ge \e \ 1\ i mem_box(2) mult_left_mono y) qed finally have "(e *\<^sub>R x + (1 - e) *\<^sub>R y) \ i < b \ i" unfolding inner_simps by auto } ultimately have "a \ i < (e *\<^sub>R x + (1 - e) *\<^sub>R y) \ i \ (e *\<^sub>R x + (1 - e) *\<^sub>R y) \ i < b \ i" by auto } then show ?thesis unfolding mem_box by auto qed lemma closure_cbox [simp]: "closure (cbox a b) = cbox a b" by (simp add: closed_cbox) lemma closure_box [simp]: fixes a :: "'a::euclidean_space" assumes "box a b \ {}" shows "closure (box a b) = cbox a b" proof - have ab: "a cbox a b" define f where [abs_def]: "f n = x + (inverse (real n + 1)) *\<^sub>R (?c - x)" for n { fix n assume fn: "f n a f n = x" and xc: "x \ ?c" have *: "0 < inverse (real n + 1)" "inverse (real n + 1) \ 1" unfolding inverse_le_1_iff by auto have "(inverse (real n + 1)) *\<^sub>R ((1 / 2) *\<^sub>R (a + b)) + (1 - inverse (real n + 1)) *\<^sub>R x = x + (inverse (real n + 1)) *\<^sub>R (((1 / 2) *\<^sub>R (a + b)) - x)" by (auto simp: algebra_simps) then have "f n (f \ x) sequentially" { fix e :: real assume "e > 0" then obtain N :: nat where N: "inverse (real (N + 1)) < e" using reals_Archimedean by auto have "inverse (real n + 1) < e" if "N \ n" for n by (auto intro!: that le_less_trans [OF _ N]) then have "\N::nat. \n\N. inverse (real n + 1) < e" by auto } then have "((\n. inverse (real n + 1)) \ 0) sequentially" unfolding lim_sequentially by(auto simp: dist_norm) then have "(f \ x) sequentially" unfolding f_def using tendsto_add[OF tendsto_const, of "\n::nat. (inverse (real n + 1)) *\<^sub>R ((1 / 2) *\<^sub>R (a + b) - x)" 0 sequentially x] using tendsto_scaleR [OF _ tendsto_const, of "\n::nat. inverse (real n + 1)" 0 sequentially "((1 / 2) *\<^sub>R (a + b) - x)"] by auto } ultimately have "x \ closure (box a b)" using as box_midpoint[OF assms] unfolding closure_def islimpt_sequential by (cases "x=?c") (auto simp: in_box_eucl_less) } then show ?thesis using closure_minimal[OF box_subset_cbox, of a b] by blast qed lemma bounded_subset_box_symmetric: fixes S :: "('a::euclidean_space) set" assumes "bounded S" obtains a where "S \ box (-a) a" proof - obtain b where "b>0" and b: "\x\S. norm x \ b" using assms[unfolded bounded_pos] by auto define a :: 'a where "a = (\i\Basis. (b + 1) *\<^sub>R i)" have "(-a)\i < x\i" and "x\i < a\i" if "x \ S" and i: "i \ Basis" for x i using b Basis_le_norm[OF i, of x] that by (auto simp: a_def) then have "S \ box (-a) a" by (auto simp: simp add: box_def) then show ?thesis .. qed lemma bounded_subset_cbox_symmetric: fixes S :: "('a::euclidean_space) set" assumes "bounded S" obtains a where "S \ cbox (-a) a" proof - obtain a where "S \ box (-a) a" using bounded_subset_box_symmetric[OF assms] by auto then show ?thesis by (meson box_subset_cbox dual_order.trans that) qed lemma frontier_cbox: fixes a b :: "'a::euclidean_space" shows "frontier (cbox a b) = cbox a b - box a b" unfolding frontier_def unfolding interior_cbox and closure_closed[OF closed_cbox] .. lemma frontier_box: fixes a b :: "'a::euclidean_space" shows "frontier (box a b) = (if box a b = {} then {} else cbox a b - box a b)" proof (cases "box a b = {}") case True then show ?thesis using frontier_empty by auto next case False then show ?thesis unfolding frontier_def and closure_box[OF False] and interior_open[OF open_box] by auto qed lemma Int_interval_mixed_eq_empty: fixes a :: "'a::euclidean_space" assumes "box c d \ {}" shows "box a b \ cbox c d = {} \ box a b \ box c d = {}" unfolding closure_box[OF assms, symmetric] unfolding open_Int_closure_eq_empty[OF open_box] .. subsection \Class Instances\ lemma compact_lemma: fixes f :: "nat \ 'a::euclidean_space" assumes "bounded (range f)" shows "\d\Basis. \l::'a. \ r. strict_mono r \ (\e>0. eventually (\n. \i\d. dist (f (r n) \ i) (l \ i) < e) sequentially)" by (rule compact_lemma_general[where unproj="\e. \i\Basis. e i *\<^sub>R i"]) (auto intro!: assms bounded_linear_inner_left bounded_linear_image simp: euclidean_representation) instance\<^marker>\tag important\ euclidean_space \ heine_borel proof fix f :: "nat \ 'a" assume f: "bounded (range f)" then obtain l::'a and r where r: "strict_mono r" and l: "\e>0. eventually (\n. \i\Basis. dist (f (r n) \ i) (l \ i) < e) sequentially" using compact_lemma [OF f] by blast { fix e::real assume "e > 0" hence "e / real_of_nat DIM('a) > 0" by (simp) with l have "eventually (\n. \i\Basis. dist (f (r n) \ i) (l \ i) < e / (real_of_nat DIM('a))) sequentially" by simp moreover { fix n assume n: "\i\Basis. dist (f (r n) \ i) (l \ i) < e / (real_of_nat DIM('a))" have "dist (f (r n)) l \ (\i\Basis. dist (f (r n) \ i) (l \ i))" apply (subst euclidean_dist_l2) using zero_le_dist apply (rule L2_set_le_sum) done also have "\ < (\i\(Basis::'a set). e / (real_of_nat DIM('a)))" apply (rule sum_strict_mono) using n apply auto done finally have "dist (f (r n)) l < e" by auto } ultimately have "eventually (\n. dist (f (r n)) l < e) sequentially" by (rule eventually_mono) } then have *: "((f \ r) \ l) sequentially" unfolding o_def tendsto_iff by simp with r show "\l r. strict_mono r \ ((f \ r) \ l) sequentially" by auto qed instance\<^marker>\tag important\ euclidean_space \ banach .. instance euclidean_space \ second_countable_topology proof define a where "a f = (\i\Basis. fst (f i) *\<^sub>R i)" for f :: "'a \ real \ real" then have a: "\f. (\i\Basis. fst (f i) *\<^sub>R i) = a f" by simp define b where "b f = (\i\Basis. snd (f i) *\<^sub>R i)" for f :: "'a \ real \ real" then have b: "\f. (\i\Basis. snd (f i) *\<^sub>R i) = b f" by simp define B where "B = (\f. box (a f) (b f)) ` (Basis \\<^sub>E (\ \ \))" have "Ball B open" by (simp add: B_def open_box) moreover have "(\A. open A \ (\B'\B. \B' = A))" proof safe fix A::"'a set" assume "open A" show "\B'\B. \B' = A" apply (rule exI[of _ "{b\B. b \ A}"]) apply (subst (3) open_UNION_box[OF \open A\]) apply (auto simp: a b B_def) done qed ultimately have "topological_basis B" unfolding topological_basis_def by blast moreover have "countable B" unfolding B_def by (intro countable_image countable_PiE finite_Basis countable_SIGMA countable_rat) ultimately show "\B::'a set set. countable B \ open = generate_topology B" by (blast intro: topological_basis_imp_subbasis) qed instance euclidean_space \ polish_space .. subsection \Compact Boxes\ lemma compact_cbox [simp]: fixes a :: "'a::euclidean_space" shows "compact (cbox a b)" using bounded_closed_imp_seq_compact[of "cbox a b"] using bounded_cbox[of a b] by (auto simp: compact_eq_seq_compact_metric) proposition is_interval_compact: "is_interval S \ compact S \ (\a b. S = cbox a b)" (is "?lhs = ?rhs") proof (cases "S = {}") case True with empty_as_interval show ?thesis by auto next case False show ?thesis proof assume L: ?lhs then have "is_interval S" "compact S" by auto define a where "a \ \i\Basis. (INF x\S. x \ i) *\<^sub>R i" define b where "b \ \i\Basis. (SUP x\S. x \ i) *\<^sub>R i" have 1: "\x i. \x \ S; i \ Basis\ \ (INF x\S. x \ i) \ x \ i" by (simp add: cInf_lower bounded_inner_imp_bdd_below compact_imp_bounded L) have 2: "\x i. \x \ S; i \ Basis\ \ x \ i \ (SUP x\S. x \ i)" by (simp add: cSup_upper bounded_inner_imp_bdd_above compact_imp_bounded L) have 3: "x \ S" if inf: "\i. i \ Basis \ (INF x\S. x \ i) \ x \ i" and sup: "\i. i \ Basis \ x \ i \ (SUP x\S. x \ i)" for x proof (rule mem_box_componentwiseI [OF \is_interval S\]) fix i::'a assume i: "i \ Basis" have cont: "continuous_on S (\x. x \ i)" by (intro continuous_intros) obtain a where "a \ S" and a: "\y. y\S \ a \ i \ y \ i" using continuous_attains_inf [OF \compact S\ False cont] by blast obtain b where "b \ S" and b: "\y. y\S \ y \ i \ b \ i" using continuous_attains_sup [OF \compact S\ False cont] by blast have "a \ i \ (INF x\S. x \ i)" by (simp add: False a cINF_greatest) also have "\ \ x \ i" by (simp add: i inf) finally have ai: "a \ i \ x \ i" . have "x \ i \ (SUP x\S. x \ i)" by (simp add: i sup) also have "(SUP x\S. x \ i) \ b \ i" by (simp add: False b cSUP_least) finally have bi: "x \ i \ b \ i" . show "x \ i \ (\x. x \ i) ` S" apply (rule_tac x="\j\Basis. (if j = i then x \ i else a \ j) *\<^sub>R j" in image_eqI) apply (simp add: i) apply (rule mem_is_intervalI [OF \is_interval S\ \a \ S\ \b \ S\]) using i ai bi apply force done qed have "S = cbox a b" by (auto simp: a_def b_def mem_box intro: 1 2 3) then show ?rhs by blast next assume R: ?rhs then show ?lhs using compact_cbox is_interval_cbox by blast qed qed subsection\<^marker>\tag unimportant\\Componentwise limits and continuity\ text\But is the premise really necessary? Need to generalise @{thm euclidean_dist_l2}\ lemma Euclidean_dist_upper: "i \ Basis \ dist (x \ i) (y \ i) \ dist x y" by (metis (no_types) member_le_L2_set euclidean_dist_l2 finite_Basis) text\But is the premise \<^term>\i \ Basis\ really necessary?\ lemma open_preimage_inner: assumes "open S" "i \ Basis" shows "open {x. x \ i \ S}" proof (rule openI, simp) fix x assume x: "x \ i \ S" with assms obtain e where "0 < e" and e: "ball (x \ i) e \ S" by (auto simp: open_contains_ball_eq) have "\e>0. ball (y \ i) e \ S" if dxy: "dist x y < e / 2" for y proof (intro exI conjI) have "dist (x \ i) (y \ i) < e / 2" by (meson \i \ Basis\ dual_order.trans Euclidean_dist_upper not_le that) then have "dist (x \ i) z < e" if "dist (y \ i) z < e / 2" for z by (metis dist_commute dist_triangle_half_l that) then have "ball (y \ i) (e / 2) \ ball (x \ i) e" using mem_ball by blast with e show "ball (y \ i) (e / 2) \ S" by (metis order_trans) qed (simp add: \0 < e\) then show "\e>0. ball x e \ {s. s \ i \ S}" by (metis (no_types, lifting) \0 < e\ \open S\ half_gt_zero_iff mem_Collect_eq mem_ball open_contains_ball_eq subsetI) qed proposition tendsto_componentwise_iff: fixes f :: "_ \ 'b::euclidean_space" shows "(f \ l) F \ (\i \ Basis. ((\x. (f x \ i)) \ (l \ i)) F)" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs unfolding tendsto_def apply clarify apply (drule_tac x="{s. s \ i \ S}" in spec) apply (auto simp: open_preimage_inner) done next assume R: ?rhs then have "\e. e > 0 \ \i\Basis. \\<^sub>F x in F. dist (f x \ i) (l \ i) < e" unfolding tendsto_iff by blast then have R': "\e. e > 0 \ \\<^sub>F x in F. \i\Basis. dist (f x \ i) (l \ i) < e" by (simp add: eventually_ball_finite_distrib [symmetric]) show ?lhs unfolding tendsto_iff proof clarify fix e::real assume "0 < e" have *: "L2_set (\i. dist (f x \ i) (l \ i)) Basis < e" if "\i\Basis. dist (f x \ i) (l \ i) < e / real DIM('b)" for x proof - have "L2_set (\i. dist (f x \ i) (l \ i)) Basis \ sum (\i. dist (f x \ i) (l \ i)) Basis" by (simp add: L2_set_le_sum) also have "... < DIM('b) * (e / real DIM('b))" apply (rule sum_bounded_above_strict) using that by auto also have "... = e" by (simp add: field_simps) finally show "L2_set (\i. dist (f x \ i) (l \ i)) Basis < e" . qed have "\\<^sub>F x in F. \i\Basis. dist (f x \ i) (l \ i) < e / DIM('b)" apply (rule R') using \0 < e\ by simp then show "\\<^sub>F x in F. dist (f x) l < e" apply (rule eventually_mono) apply (subst euclidean_dist_l2) using * by blast qed qed corollary continuous_componentwise: "continuous F f \ (\i \ Basis. continuous F (\x. (f x \ i)))" by (simp add: continuous_def tendsto_componentwise_iff [symmetric]) corollary continuous_on_componentwise: fixes S :: "'a :: t2_space set" shows "continuous_on S f \ (\i \ Basis. continuous_on S (\x. (f x \ i)))" apply (simp add: continuous_on_eq_continuous_within) using continuous_componentwise by blast lemma linear_componentwise_iff: "(linear f') \ (\i\Basis. linear (\x. f' x \ i))" apply (auto simp: linear_iff inner_left_distrib) apply (metis inner_left_distrib euclidean_eq_iff) by (metis euclidean_eqI inner_scaleR_left) lemma bounded_linear_componentwise_iff: "(bounded_linear f') \ (\i\Basis. bounded_linear (\x. f' x \ i))" (is "?lhs = ?rhs") proof assume ?lhs then show ?rhs by (simp add: bounded_linear_inner_left_comp) next assume ?rhs then have "(\i\Basis. \K. \x. \f' x \ i\ \ norm x * K)" "linear f'" by (auto simp: bounded_linear_def bounded_linear_axioms_def linear_componentwise_iff [symmetric] ball_conj_distrib) then obtain F where F: "\i x. i \ Basis \ \f' x \ i\ \ norm x * F i" by metis have "norm (f' x) \ norm x * sum F Basis" for x proof - have "norm (f' x) \ (\i\Basis. \f' x \ i\)" by (rule norm_le_l1) also have "... \ (\i\Basis. norm x * F i)" by (metis F sum_mono) also have "... = norm x * sum F Basis" by (simp add: sum_distrib_left) finally show ?thesis . qed then show ?lhs by (force simp: bounded_linear_def bounded_linear_axioms_def \linear f'\) qed subsection\<^marker>\tag unimportant\ \Continuous Extension\ definition clamp :: "'a::euclidean_space \ 'a \ 'a \ 'a" where "clamp a b x = (if (\i\Basis. a \ i \ b \ i) then (\i\Basis. (if x\i < a\i then a\i else if x\i \ b\i then x\i else b\i) *\<^sub>R i) else a)" lemma clamp_in_interval[simp]: assumes "\i. i \ Basis \ a \ i \ b \ i" shows "clamp a b x \ cbox a b" unfolding clamp_def using box_ne_empty(1)[of a b] assms by (auto simp: cbox_def) lemma clamp_cancel_cbox[simp]: fixes x a b :: "'a::euclidean_space" assumes x: "x \ cbox a b" shows "clamp a b x = x" using assms by (auto simp: clamp_def mem_box intro!: euclidean_eqI[where 'a='a]) lemma clamp_empty_interval: assumes "i \ Basis" "a \ i > b \ i" shows "clamp a b = (\_. a)" using assms by (force simp: clamp_def[abs_def] split: if_splits intro!: ext) lemma dist_clamps_le_dist_args: fixes x :: "'a::euclidean_space" shows "dist (clamp a b y) (clamp a b x) \ dist y x" proof cases assume le: "(\i\Basis. a \ i \ b \ i)" then have "(\i\Basis. (dist (clamp a b y \ i) (clamp a b x \ i))\<^sup>2) \ (\i\Basis. (dist (y \ i) (x \ i))\<^sup>2)" by (auto intro!: sum_mono simp: clamp_def dist_real_def abs_le_square_iff[symmetric]) then show ?thesis by (auto intro: real_sqrt_le_mono simp: euclidean_dist_l2[where y=x] euclidean_dist_l2[where y="clamp a b x"] L2_set_def) qed (auto simp: clamp_def) lemma clamp_continuous_at: fixes f :: "'a::euclidean_space \ 'b::metric_space" and x :: 'a assumes f_cont: "continuous_on (cbox a b) f" shows "continuous (at x) (\x. f (clamp a b x))" proof cases assume le: "(\i\Basis. a \ i \ b \ i)" show ?thesis unfolding continuous_at_eps_delta proof safe fix x :: 'a fix e :: real assume "e > 0" moreover have "clamp a b x \ cbox a b" by (simp add: le) moreover note f_cont[simplified continuous_on_iff] ultimately obtain d where d: "0 < d" "\x'. x' \ cbox a b \ dist x' (clamp a b x) < d \ dist (f x') (f (clamp a b x)) < e" by force show "\d>0. \x'. dist x' x < d \ dist (f (clamp a b x')) (f (clamp a b x)) < e" using le by (auto intro!: d clamp_in_interval dist_clamps_le_dist_args[THEN le_less_trans]) qed qed (auto simp: clamp_empty_interval) lemma clamp_continuous_on: fixes f :: "'a::euclidean_space \ 'b::metric_space" assumes f_cont: "continuous_on (cbox a b) f" shows "continuous_on S (\x. f (clamp a b x))" using assms by (auto intro: continuous_at_imp_continuous_on clamp_continuous_at) lemma clamp_bounded: fixes f :: "'a::euclidean_space \ 'b::metric_space" assumes bounded: "bounded (f ` (cbox a b))" shows "bounded (range (\x. f (clamp a b x)))" proof cases assume le: "(\i\Basis. a \ i \ b \ i)" from bounded obtain c where f_bound: "\x\f ` cbox a b. dist undefined x \ c" by (auto simp: bounded_any_center[where a=undefined]) then show ?thesis by (auto intro!: exI[where x=c] clamp_in_interval[OF le[rule_format]] simp: bounded_any_center[where a=undefined]) qed (auto simp: clamp_empty_interval image_def) definition ext_cont :: "('a::euclidean_space \ 'b::metric_space) \ 'a \ 'a \ 'a \ 'b" where "ext_cont f a b = (\x. f (clamp a b x))" lemma ext_cont_cancel_cbox[simp]: fixes x a b :: "'a::euclidean_space" assumes x: "x \ cbox a b" shows "ext_cont f a b x = f x" using assms unfolding ext_cont_def by (auto simp: clamp_def mem_box intro!: euclidean_eqI[where 'a='a] arg_cong[where f=f]) lemma continuous_on_ext_cont[continuous_intros]: "continuous_on (cbox a b) f \ continuous_on S (ext_cont f a b)" by (auto intro!: clamp_continuous_on simp: ext_cont_def) subsection \Separability\ lemma univ_second_countable_sequence: obtains B :: "nat \ 'a::euclidean_space set" where "inj B" "\n. open(B n)" "\S. open S \ \k. S = \{B n |n. n \ k}" proof - obtain \ :: "'a set set" where "countable \" and opn: "\C. C \ \ \ open C" and Un: "\S. open S \ \U. U \ \ \ S = \U" using univ_second_countable by blast have *: "infinite (range (\n. ball (0::'a) (inverse(Suc n))))" apply (rule Infinite_Set.range_inj_infinite) apply (simp add: inj_on_def ball_eq_ball_iff) done have "infinite \" proof assume "finite \" then have "finite (Union ` (Pow \))" by simp then have "finite (range (\n. ball (0::'a) (inverse(Suc n))))" apply (rule rev_finite_subset) by (metis (no_types, lifting) PowI image_eqI image_subset_iff Un [OF open_ball]) with * show False by simp qed obtain f :: "nat \ 'a set" where "\ = range f" "inj f" by (blast intro: countable_as_injective_image [OF \countable \\ \infinite \\]) have *: "\k. S = \{f n |n. n \ k}" if "open S" for S using Un [OF that] apply clarify apply (rule_tac x="f-`U" in exI) using \inj f\ \\ = range f\ apply force done show ?thesis apply (rule that [OF \inj f\ _ *]) apply (auto simp: \\ = range f\ opn) done qed proposition separable: fixes S :: "'a::{metric_space, second_countable_topology} set" obtains T where "countable T" "T \ S" "S \ closure T" proof - obtain \ :: "'a set set" where "countable \" and "{} \ \" and ope: "\C. C \ \ \ openin(top_of_set S) C" and if_ope: "\T. openin(top_of_set S) T \ \\. \ \ \ \ T = \\" by (meson subset_second_countable) then obtain f where f: "\C. C \ \ \ f C \ C" by (metis equals0I) show ?thesis proof show "countable (f ` \)" by (simp add: \countable \\) show "f ` \ \ S" using ope f openin_imp_subset by blast show "S \ closure (f ` \)" proof (clarsimp simp: closure_approachable) fix x and e::real assume "x \ S" "0 < e" have "openin (top_of_set S) (S \ ball x e)" by (simp add: openin_Int_open) with if_ope obtain \ where \: "\ \ \" "S \ ball x e = \\" by meson show "\C \ \. dist (f C) x < e" proof (cases "\ = {}") case True then show ?thesis using \0 < e\ \ \x \ S\ by auto next case False then obtain C where "C \ \" by blast show ?thesis proof show "dist (f C) x < e" by (metis Int_iff Union_iff \ \C \ \\ dist_commute f mem_ball subsetCE) show "C \ \" using \\ \ \\ \C \ \\ by blast qed qed qed qed qed subsection\<^marker>\tag unimportant\ \Diameter\ lemma diameter_cball [simp]: fixes a :: "'a::euclidean_space" shows "diameter(cball a r) = (if r < 0 then 0 else 2*r)" proof - have "diameter(cball a r) = 2*r" if "r \ 0" proof (rule order_antisym) show "diameter (cball a r) \ 2*r" proof (rule diameter_le) fix x y assume "x \ cball a r" "y \ cball a r" then have "norm (x - a) \ r" "norm (a - y) \ r" by (auto simp: dist_norm norm_minus_commute) then have "norm (x - y) \ r+r" using norm_diff_triangle_le by blast then show "norm (x - y) \ 2*r" by simp qed (simp add: that) have "2*r = dist (a + r *\<^sub>R (SOME i. i \ Basis)) (a - r *\<^sub>R (SOME i. i \ Basis))" apply (simp add: dist_norm) by (metis abs_of_nonneg mult.right_neutral norm_numeral norm_scaleR norm_some_Basis real_norm_def scaleR_2 that) also have "... \ diameter (cball a r)" apply (rule diameter_bounded_bound) using that by (auto simp: dist_norm) finally show "2*r \ diameter (cball a r)" . qed then show ?thesis by simp qed lemma diameter_ball [simp]: fixes a :: "'a::euclidean_space" shows "diameter(ball a r) = (if r < 0 then 0 else 2*r)" proof - have "diameter(ball a r) = 2*r" if "r > 0" by (metis bounded_ball diameter_closure closure_ball diameter_cball less_eq_real_def linorder_not_less that) then show ?thesis by (simp add: diameter_def) qed lemma diameter_closed_interval [simp]: "diameter {a..b} = (if b < a then 0 else b-a)" proof - have "{a .. b} = cball ((a+b)/2) ((b-a)/2)" by (auto simp: dist_norm abs_if field_split_simps split: if_split_asm) then show ?thesis by simp qed lemma diameter_open_interval [simp]: "diameter {a<..i \ Basis. a \ i \ b \ i) \ diameter (cbox a b) = dist a b" by (force simp: diameter_def intro!: cSup_eq_maximum L2_set_mono simp: euclidean_dist_l2[where 'a='a] cbox_def dist_norm) subsection\<^marker>\tag unimportant\\Relating linear images to open/closed/interior/closure/connected\ proposition open_surjective_linear_image: fixes f :: "'a::real_normed_vector \ 'b::euclidean_space" assumes "open A" "linear f" "surj f" shows "open(f ` A)" unfolding open_dist proof clarify fix x assume "x \ A" have "bounded (inv f ` Basis)" by (simp add: finite_imp_bounded) with bounded_pos obtain B where "B > 0" and B: "\x. x \ inv f ` Basis \ norm x \ B" by metis obtain e where "e > 0" and e: "\z. dist z x < e \ z \ A" by (metis open_dist \x \ A\ \open A\) define \ where "\ \ e / B / DIM('b)" show "\e>0. \y. dist y (f x) < e \ y \ f ` A" proof (intro exI conjI) show "\ > 0" using \e > 0\ \B > 0\ by (simp add: \_def field_split_simps) have "y \ f ` A" if "dist y (f x) * (B * real DIM('b)) < e" for y proof - define u where "u \ y - f x" show ?thesis proof (rule image_eqI) show "y = f (x + (\i\Basis. (u \ i) *\<^sub>R inv f i))" apply (simp add: linear_add linear_sum linear.scaleR \linear f\ surj_f_inv_f \surj f\) apply (simp add: euclidean_representation u_def) done have "dist (x + (\i\Basis. (u \ i) *\<^sub>R inv f i)) x \ (\i\Basis. norm ((u \ i) *\<^sub>R inv f i))" by (simp add: dist_norm sum_norm_le) also have "... = (\i\Basis. \u \ i\ * norm (inv f i))" by simp also have "... \ (\i\Basis. \u \ i\) * B" by (simp add: B sum_distrib_right sum_mono mult_left_mono) also have "... \ DIM('b) * dist y (f x) * B" apply (rule mult_right_mono [OF sum_bounded_above]) using \0 < B\ by (auto simp: Basis_le_norm dist_norm u_def) also have "... < e" by (metis mult.commute mult.left_commute that) finally show "x + (\i\Basis. (u \ i) *\<^sub>R inv f i) \ A" by (rule e) qed qed then show "\y. dist y (f x) < \ \ y \ f ` A" using \e > 0\ \B > 0\ by (auto simp: \_def field_split_simps) qed qed corollary open_bijective_linear_image_eq: fixes f :: "'a::euclidean_space \ 'b::euclidean_space" assumes "linear f" "bij f" shows "open(f ` A) \ open A" proof assume "open(f ` A)" then have "open(f -` (f ` A))" using assms by (force simp: linear_continuous_at linear_conv_bounded_linear continuous_open_vimage) then show "open A" by (simp add: assms bij_is_inj inj_vimage_image_eq) next assume "open A" then show "open(f ` A)" by (simp add: assms bij_is_surj open_surjective_linear_image) qed corollary interior_bijective_linear_image: fixes f :: "'a::euclidean_space \ 'b::euclidean_space" assumes "linear f" "bij f" shows "interior (f ` S) = f ` interior S" (is "?lhs = ?rhs") proof safe fix x assume x: "x \ ?lhs" then obtain T where "open T" and "x \ T" and "T \ f ` S" by (metis interiorE) then show "x \ ?rhs" by (metis (no_types, hide_lams) assms subsetD interior_maximal open_bijective_linear_image_eq subset_image_iff) next fix x assume x: "x \ interior S" then show "f x \ interior (f ` S)" by (meson assms imageI image_mono interiorI interior_subset open_bijective_linear_image_eq open_interior) qed lemma interior_injective_linear_image: fixes f :: "'a::euclidean_space \ 'a::euclidean_space" assumes "linear f" "inj f" shows "interior(f ` S) = f ` (interior S)" by (simp add: linear_injective_imp_surjective assms bijI interior_bijective_linear_image) lemma interior_surjective_linear_image: fixes f :: "'a::euclidean_space \ 'a::euclidean_space" assumes "linear f" "surj f" shows "interior(f ` S) = f ` (interior S)" by (simp add: assms interior_injective_linear_image linear_surjective_imp_injective) lemma interior_negations: fixes S :: "'a::euclidean_space set" shows "interior(uminus ` S) = image uminus (interior S)" by (simp add: bij_uminus interior_bijective_linear_image linear_uminus) lemma connected_linear_image: fixes f :: "'a::euclidean_space \ 'b::real_normed_vector" assumes "linear f" and "connected s" shows "connected (f ` s)" using connected_continuous_image assms linear_continuous_on linear_conv_bounded_linear by blast subsection\<^marker>\tag unimportant\ \"Isometry" (up to constant bounds) of Injective Linear Map\ proposition injective_imp_isometric: fixes f :: "'a::euclidean_space \ 'b::euclidean_space" assumes s: "closed s" "subspace s" and f: "bounded_linear f" "\x\s. f x = 0 \ x = 0" shows "\e>0. \x\s. norm (f x) \ e * norm x" proof (cases "s \ {0::'a}") case True have "norm x \ norm (f x)" if "x \ s" for x proof - from True that have "x = 0" by auto then show ?thesis by simp qed then show ?thesis by (auto intro!: exI[where x=1]) next case False interpret f: bounded_linear f by fact from False obtain a where a: "a \ 0" "a \ s" by auto from False have "s \ {}" by auto let ?S = "{f x| x. x \ s \ norm x = norm a}" let ?S' = "{x::'a. x\s \ norm x = norm a}" let ?S'' = "{x::'a. norm x = norm a}" have "?S'' = frontier (cball 0 (norm a))" by (simp add: sphere_def dist_norm) then have "compact ?S''" by (metis compact_cball compact_frontier) moreover have "?S' = s \ ?S''" by auto ultimately have "compact ?S'" using closed_Int_compact[of s ?S''] using s(1) by auto moreover have *:"f ` ?S' = ?S" by auto ultimately have "compact ?S" using compact_continuous_image[OF linear_continuous_on[OF f(1)], of ?S'] by auto then have "closed ?S" using compact_imp_closed by auto moreover from a have "?S \ {}" by auto ultimately obtain b' where "b'\?S" "\y\?S. norm b' \ norm y" using distance_attains_inf[of ?S 0] unfolding dist_0_norm by auto then obtain b where "b\s" and ba: "norm b = norm a" and b: "\x\{x \ s. norm x = norm a}. norm (f b) \ norm (f x)" unfolding *[symmetric] unfolding image_iff by auto let ?e = "norm (f b) / norm b" have "norm b > 0" using ba and a and norm_ge_zero by auto moreover have "norm (f b) > 0" using f(2)[THEN bspec[where x=b], OF \b\s\] using \norm b >0\ by simp ultimately have "0 < norm (f b) / norm b" by simp moreover have "norm (f b) / norm b * norm x \ norm (f x)" if "x\s" for x proof (cases "x = 0") case True then show "norm (f b) / norm b * norm x \ norm (f x)" by auto next case False with \a \ 0\ have *: "0 < norm a / norm x" unfolding zero_less_norm_iff[symmetric] by simp have "\x\s. c *\<^sub>R x \ s" for c using s[unfolded subspace_def] by simp with \x \ s\ \x \ 0\ have "(norm a / norm x) *\<^sub>R x \ {x \ s. norm x = norm a}" by simp with \x \ 0\ \a \ 0\ show "norm (f b) / norm b * norm x \ norm (f x)" using b[THEN bspec[where x="(norm a / norm x) *\<^sub>R x"]] unfolding f.scaleR and ba by (auto simp: mult.commute pos_le_divide_eq pos_divide_le_eq) qed ultimately show ?thesis by auto qed proposition closed_injective_image_subspace: fixes f :: "'a::euclidean_space \ 'b::euclidean_space" assumes "subspace s" "bounded_linear f" "\x\s. f x = 0 \ x = 0" "closed s" shows "closed(f ` s)" proof - obtain e where "e > 0" and e: "\x\s. e * norm x \ norm (f x)" using injective_imp_isometric[OF assms(4,1,2,3)] by auto show ?thesis using complete_isometric_image[OF \e>0\ assms(1,2) e] and assms(4) unfolding complete_eq_closed[symmetric] by auto qed + + +lemma closure_bounded_linear_image_subset: + assumes f: "bounded_linear f" + shows "f ` closure S \ closure (f ` S)" + using linear_continuous_on [OF f] closed_closure closure_subset + by (rule image_closure_subset) + +lemma closure_linear_image_subset: + fixes f :: "'m::euclidean_space \ 'n::real_normed_vector" + assumes "linear f" + shows "f ` (closure S) \ closure (f ` S)" + using assms unfolding linear_conv_bounded_linear + by (rule closure_bounded_linear_image_subset) + +lemma closed_injective_linear_image: + fixes f :: "'a::euclidean_space \ 'b::euclidean_space" + assumes S: "closed S" and f: "linear f" "inj f" + shows "closed (f ` S)" +proof - + obtain g where g: "linear g" "g \ f = id" + using linear_injective_left_inverse [OF f] by blast + then have confg: "continuous_on (range f) g" + using linear_continuous_on linear_conv_bounded_linear by blast + have [simp]: "g ` f ` S = S" + using g by (simp add: image_comp) + have cgf: "closed (g ` f ` S)" + by (simp add: \g \ f = id\ S image_comp) + have [simp]: "(range f \ g -` S) = f ` S" + using g unfolding o_def id_def image_def by auto metis+ + show ?thesis + proof (rule closedin_closed_trans [of "range f"]) + show "closedin (top_of_set (range f)) (f ` S)" + using continuous_closedin_preimage [OF confg cgf] by simp + show "closed (range f)" + apply (rule closed_injective_image_subspace) + using f apply (auto simp: linear_linear linear_injective_0) + done + qed +qed + +lemma closed_injective_linear_image_eq: + fixes f :: "'a::euclidean_space \ 'b::euclidean_space" + assumes f: "linear f" "inj f" + shows "(closed(image f s) \ closed s)" + by (metis closed_injective_linear_image closure_eq closure_linear_image_subset closure_subset_eq f(1) f(2) inj_image_subset_iff) + +lemma closure_injective_linear_image: + fixes f :: "'a::euclidean_space \ 'b::euclidean_space" + shows "\linear f; inj f\ \ f ` (closure S) = closure (f ` S)" + apply (rule subset_antisym) + apply (simp add: closure_linear_image_subset) + by (simp add: closure_minimal closed_injective_linear_image closure_subset image_mono) + +lemma closure_bounded_linear_image: + fixes f :: "'a::euclidean_space \ 'b::euclidean_space" + shows "\linear f; bounded S\ \ f ` (closure S) = closure (f ` S)" + apply (rule subset_antisym, simp add: closure_linear_image_subset) + apply (rule closure_minimal, simp add: closure_subset image_mono) + by (meson bounded_closure closed_closure compact_continuous_image compact_eq_bounded_closed linear_continuous_on linear_conv_bounded_linear) + +lemma closure_scaleR: + fixes S :: "'a::real_normed_vector set" + shows "((*\<^sub>R) c) ` (closure S) = closure (((*\<^sub>R) c) ` S)" +proof + show "((*\<^sub>R) c) ` (closure S) \ closure (((*\<^sub>R) c) ` S)" + using bounded_linear_scaleR_right + by (rule closure_bounded_linear_image_subset) + show "closure (((*\<^sub>R) c) ` S) \ ((*\<^sub>R) c) ` (closure S)" + by (intro closure_minimal image_mono closure_subset closed_scaling closed_closure) +qed subsection\<^marker>\tag unimportant\ \Some properties of a canonical subspace\ lemma closed_substandard: "closed {x::'a::euclidean_space. \i\Basis. P i \ x\i = 0}" (is "closed ?A") proof - let ?D = "{i\Basis. P i}" have "closed (\i\?D. {x::'a. x\i = 0})" by (simp add: closed_INT closed_Collect_eq continuous_on_inner) also have "(\i\?D. {x::'a. x\i = 0}) = ?A" by auto finally show "closed ?A" . qed lemma closed_subspace: fixes s :: "'a::euclidean_space set" assumes "subspace s" shows "closed s" proof - have "dim s \ card (Basis :: 'a set)" using dim_subset_UNIV by auto with ex_card[OF this] obtain d :: "'a set" where t: "card d = dim s" and d: "d \ Basis" by auto let ?t = "{x::'a. \i\Basis. i \ d \ x\i = 0}" have "\f. linear f \ f ` {x::'a. \i\Basis. i \ d \ x \ i = 0} = s \ inj_on f {x::'a. \i\Basis. i \ d \ x \ i = 0}" using dim_substandard[of d] t d assms by (intro subspace_isomorphism[OF subspace_substandard[of "\i. i \ d"]]) (auto simp: inner_Basis) then obtain f where f: "linear f" "f ` {x. \i\Basis. i \ d \ x \ i = 0} = s" "inj_on f {x. \i\Basis. i \ d \ x \ i = 0}" by blast interpret f: bounded_linear f using f by (simp add: linear_conv_bounded_linear) have "x \ ?t \ f x = 0 \ x = 0" for x using f.zero d f(3)[THEN inj_onD, of x 0] by auto moreover have "closed ?t" by (rule closed_substandard) moreover have "subspace ?t" by (rule subspace_substandard) ultimately show ?thesis using closed_injective_image_subspace[of ?t f] unfolding f(2) using f(1) unfolding linear_conv_bounded_linear by auto qed lemma complete_subspace: "subspace s \ complete s" for s :: "'a::euclidean_space set" using complete_eq_closed closed_subspace by auto lemma closed_span [iff]: "closed (span s)" for s :: "'a::euclidean_space set" by (simp add: closed_subspace) lemma dim_closure [simp]: "dim (closure s) = dim s" (is "?dc = ?d") for s :: "'a::euclidean_space set" proof - have "?dc \ ?d" using closure_minimal[OF span_superset, of s] using closed_subspace[OF subspace_span, of s] using dim_subset[of "closure s" "span s"] by simp then show ?thesis using dim_subset[OF closure_subset, of s] by simp qed subsection \Set Distance\ lemma setdist_compact_closed: fixes A :: "'a::heine_borel set" assumes A: "compact A" and B: "closed B" and "A \ {}" "B \ {}" shows "\x \ A. \y \ B. dist x y = setdist A B" proof - obtain x where "x \ A" "setdist A B = infdist x B" by (metis A assms(3) setdist_attains_inf setdist_sym) moreover obtain y where"y \ B" "infdist x B = dist x y" using B \B \ {}\ infdist_attains_inf by blast ultimately show ?thesis using \x \ A\ \y \ B\ by auto qed lemma setdist_closed_compact: fixes S :: "'a::heine_borel set" assumes S: "closed S" and T: "compact T" and "S \ {}" "T \ {}" shows "\x \ S. \y \ T. dist x y = setdist S T" using setdist_compact_closed [OF T S \T \ {}\ \S \ {}\] by (metis dist_commute setdist_sym) lemma setdist_eq_0_compact_closed: assumes S: "compact S" and T: "closed T" shows "setdist S T = 0 \ S = {} \ T = {} \ S \ T \ {}" proof (cases "S = {} \ T = {}") case True then show ?thesis by force next case False then show ?thesis by (metis S T disjoint_iff_not_equal in_closed_iff_infdist_zero setdist_attains_inf setdist_eq_0I setdist_sym) qed corollary setdist_gt_0_compact_closed: assumes S: "compact S" and T: "closed T" shows "setdist S T > 0 \ (S \ {} \ T \ {} \ S \ T = {})" using setdist_pos_le [of S T] setdist_eq_0_compact_closed [OF assms] by linarith lemma setdist_eq_0_closed_compact: assumes S: "closed S" and T: "compact T" shows "setdist S T = 0 \ S = {} \ T = {} \ S \ T \ {}" using setdist_eq_0_compact_closed [OF T S] by (metis Int_commute setdist_sym) lemma setdist_eq_0_bounded: fixes S :: "'a::heine_borel set" assumes "bounded S \ bounded T" shows "setdist S T = 0 \ S = {} \ T = {} \ closure S \ closure T \ {}" proof (cases "S = {} \ T = {}") case False then show ?thesis using setdist_eq_0_compact_closed [of "closure S" "closure T"] setdist_eq_0_closed_compact [of "closure S" "closure T"] assms by (force simp: bounded_closure compact_eq_bounded_closed) qed force lemma setdist_eq_0_sing_1: "setdist {x} S = 0 \ S = {} \ x \ closure S" by (metis in_closure_iff_infdist_zero infdist_def infdist_eq_setdist) lemma setdist_eq_0_sing_2: "setdist S {x} = 0 \ S = {} \ x \ closure S" by (metis setdist_eq_0_sing_1 setdist_sym) lemma setdist_neq_0_sing_1: "\setdist {x} S = a; a \ 0\ \ S \ {} \ x \ closure S" by (metis setdist_closure_2 setdist_empty2 setdist_eq_0I singletonI) lemma setdist_neq_0_sing_2: "\setdist S {x} = a; a \ 0\ \ S \ {} \ x \ closure S" by (simp add: setdist_neq_0_sing_1 setdist_sym) lemma setdist_sing_in_set: "x \ S \ setdist {x} S = 0" by (simp add: setdist_eq_0I) lemma setdist_eq_0_closed: "closed S \ (setdist {x} S = 0 \ S = {} \ x \ S)" by (simp add: setdist_eq_0_sing_1) lemma setdist_eq_0_closedin: shows "\closedin (top_of_set U) S; x \ U\ \ (setdist {x} S = 0 \ S = {} \ x \ S)" by (auto simp: closedin_limpt setdist_eq_0_sing_1 closure_def) lemma setdist_gt_0_closedin: shows "\closedin (top_of_set U) S; x \ U; S \ {}; x \ S\ \ setdist {x} S > 0" using less_eq_real_def setdist_eq_0_closedin by fastforce no_notation eucl_less (infix "