Divided Topology_Euclidean_Space in two, creating new theory Connected. Also deleted some duplicate / variant theorems
authorpaulson <lp15@cam.ac.uk>
Tue Oct 10 17:15:37 2017 +0100 (19 months ago)
changeset 66827c94531b5007d
parent 66826 0d60d2118544
child 66833 091012ac3dc2
Divided Topology_Euclidean_Space in two, creating new theory Connected. Also deleted some duplicate / variant theorems
src/HOL/Analysis/Bounded_Linear_Function.thy
src/HOL/Analysis/Cauchy_Integral_Theorem.thy
src/HOL/Analysis/Complex_Analysis_Basics.thy
src/HOL/Analysis/Complex_Transcendental.thy
src/HOL/Analysis/Conformal_Mappings.thy
src/HOL/Analysis/Connected.thy
src/HOL/Analysis/Convex_Euclidean_Space.thy
src/HOL/Analysis/Function_Topology.thy
src/HOL/Analysis/Further_Topology.thy
src/HOL/Analysis/Great_Picard.thy
src/HOL/Analysis/Homeomorphism.thy
src/HOL/Analysis/Ordered_Euclidean_Space.thy
src/HOL/Analysis/Path_Connected.thy
src/HOL/Analysis/Riemann_Mapping.thy
src/HOL/Analysis/Tagged_Division.thy
src/HOL/Analysis/Topology_Euclidean_Space.thy
src/HOL/Analysis/Uniform_Limit.thy
src/HOL/Analysis/Winding_Numbers.thy
src/HOL/Limits.thy
src/HOL/Nonstandard_Analysis/HLim.thy
src/HOL/Topological_Spaces.thy
src/HOL/Transcendental.thy
     1.1 --- a/src/HOL/Analysis/Bounded_Linear_Function.thy	Tue Oct 10 14:03:51 2017 +0100
     1.2 +++ b/src/HOL/Analysis/Bounded_Linear_Function.thy	Tue Oct 10 17:15:37 2017 +0100
     1.3 @@ -496,7 +496,7 @@
     1.4        cond_application_beta sum.delta' euclidean_representation
     1.5        cong: if_cong)
     1.6  
     1.7 -text \<open>TODO: generalize (via @{thm compact_cball})?\<close>
     1.8 +text \<open>TODO: generalize (via @{text compact_cball})?\<close>
     1.9  instance blinfun :: (euclidean_space, euclidean_space) heine_borel
    1.10  proof
    1.11    fix f :: "nat \<Rightarrow> 'a \<Rightarrow>\<^sub>L 'b"
     2.1 --- a/src/HOL/Analysis/Cauchy_Integral_Theorem.thy	Tue Oct 10 14:03:51 2017 +0100
     2.2 +++ b/src/HOL/Analysis/Cauchy_Integral_Theorem.thy	Tue Oct 10 17:15:37 2017 +0100
     2.3 @@ -2955,7 +2955,7 @@
     2.4        using holomorphic_convex_primitive [OF convex_ball k contfb fcd] d
     2.5              interior_subset by force
     2.6      then have "\<forall>y\<in>ball z d. (h has_field_derivative f y) (at y within s)"
     2.7 -      by (metis Topology_Euclidean_Space.open_ball at_within_open d(2) os subsetCE)
     2.8 +      by (metis open_ball at_within_open d(2) os subsetCE)
     2.9      then have "\<exists>h. (\<forall>y. cmod (y - z) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
    2.10        by (force simp: dist_norm norm_minus_commute)
    2.11      then have "\<exists>d h. 0 < d \<and> (\<forall>y. cmod (y - z) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
     3.1 --- a/src/HOL/Analysis/Complex_Analysis_Basics.thy	Tue Oct 10 14:03:51 2017 +0100
     3.2 +++ b/src/HOL/Analysis/Complex_Analysis_Basics.thy	Tue Oct 10 17:15:37 2017 +0100
     3.3 @@ -497,7 +497,7 @@
     3.4  lemma analytic_on_imp_differentiable_at:
     3.5    "f analytic_on s \<Longrightarrow> x \<in> s \<Longrightarrow> f field_differentiable (at x)"
     3.6   apply (auto simp: analytic_on_def holomorphic_on_def)
     3.7 -by (metis Topology_Euclidean_Space.open_ball centre_in_ball field_differentiable_within_open)
     3.8 +by (metis open_ball centre_in_ball field_differentiable_within_open)
     3.9  
    3.10  lemma analytic_on_subset: "f analytic_on s \<Longrightarrow> t \<subseteq> s \<Longrightarrow> f analytic_on t"
    3.11    by (auto simp: analytic_on_def)
    3.12 @@ -521,7 +521,7 @@
    3.13      then show "\<exists>t. open t \<and> s \<subseteq> t \<and> f analytic_on t"
    3.14        apply (simp add: analytic_on_def)
    3.15        apply (rule exI [where x="\<Union>{u. open u \<and> f analytic_on u}"], auto)
    3.16 -      apply (metis Topology_Euclidean_Space.open_ball analytic_on_open centre_in_ball)
    3.17 +      apply (metis open_ball analytic_on_open centre_in_ball)
    3.18        by (metis analytic_on_def)
    3.19    next
    3.20      fix t
    3.21 @@ -652,7 +652,7 @@
    3.22    have "continuous_on (ball z e) f"
    3.23      by (metis fh holomorphic_on_imp_continuous_on)
    3.24    then obtain e' where e': "0 < e'" and nz': "\<And>y. dist z y < e' \<Longrightarrow> f y \<noteq> 0"
    3.25 -    by (metis Topology_Euclidean_Space.open_ball centre_in_ball continuous_on_open_avoid e z nz)
    3.26 +    by (metis open_ball centre_in_ball continuous_on_open_avoid e z nz)
    3.27    have "(\<lambda>z. inverse (f z)) holomorphic_on ball z (min e e')"
    3.28      apply (rule holomorphic_on_inverse)
    3.29      apply (metis fh holomorphic_on_subset min.cobounded2 min.commute subset_ball)
     4.1 --- a/src/HOL/Analysis/Complex_Transcendental.thy	Tue Oct 10 14:03:51 2017 +0100
     4.2 +++ b/src/HOL/Analysis/Complex_Transcendental.thy	Tue Oct 10 17:15:37 2017 +0100
     4.3 @@ -2102,7 +2102,7 @@
     4.4    have "(\<lambda>n. ln(1 + 1/n) / ln n) \<longlonglongrightarrow> 0"
     4.5    proof (rule Lim_transform_bound)
     4.6      show "(inverse o real) \<longlonglongrightarrow> 0"
     4.7 -      by (metis comp_def seq_harmonic tendsto_explicit)
     4.8 +      by (metis comp_def lim_inverse_n tendsto_explicit)
     4.9      show "\<forall>\<^sub>F n in sequentially. norm (ln (1 + 1 / n) / ln n) \<le> norm ((inverse \<circ> real) n)"
    4.10      proof
    4.11        fix n::nat
     5.1 --- a/src/HOL/Analysis/Conformal_Mappings.thy	Tue Oct 10 14:03:51 2017 +0100
     5.2 +++ b/src/HOL/Analysis/Conformal_Mappings.thy	Tue Oct 10 17:15:37 2017 +0100
     5.3 @@ -693,7 +693,7 @@
     5.4    have cd: "\<And>x. dist \<xi> x < r \<Longrightarrow> (\<lambda>z. deriv g z / g z) field_differentiable at x"
     5.5      apply (rule derivative_intros)+
     5.6      using holg mem_ball apply (blast intro: holomorphic_deriv holomorphic_on_imp_differentiable_at)
     5.7 -    apply (metis Topology_Euclidean_Space.open_ball at_within_open holg holomorphic_on_def mem_ball)
     5.8 +    apply (metis open_ball at_within_open holg holomorphic_on_def mem_ball)
     5.9      using gne mem_ball by blast
    5.10    obtain h where h: "\<And>x. x \<in> ball \<xi> r \<Longrightarrow> (h has_field_derivative deriv g x / g x) (at x)"
    5.11      apply (rule exE [OF holomorphic_convex_primitive [of "ball \<xi> r" "{}" "\<lambda>z. deriv g z / g z"]])
    5.12 @@ -1234,7 +1234,7 @@
    5.13          apply (rule has_complex_derivative_locally_invertible [OF holgw, of \<xi>])
    5.14          using \<open>0 < r\<close> \<open>0 < \<delta>\<close>
    5.15          apply (simp_all add:)
    5.16 -        by (meson Topology_Euclidean_Space.open_ball centre_in_ball)
    5.17 +        by (meson open_ball centre_in_ball)
    5.18        define U where "U = (\<lambda>w. (w - \<xi>) * g w) ` T"
    5.19        have "open U" by (metis oimT U_def)
    5.20        have "0 \<in> U"
    5.21 @@ -1931,7 +1931,7 @@
    5.22    have hol0: "(\<lambda>z. f (a + z)) holomorphic_on cball 0 r"
    5.23      unfolding fz by (intro holomorphic_intros holf holomorphic_on_compose | simp)+
    5.24    then have [simp]: "\<And>x. norm x < r \<Longrightarrow> (\<lambda>z. f (a + z)) field_differentiable at x"
    5.25 -    by (metis Topology_Euclidean_Space.open_ball at_within_open ball_subset_cball diff_0 dist_norm holomorphic_on_def holomorphic_on_subset mem_ball norm_minus_cancel)
    5.26 +    by (metis open_ball at_within_open ball_subset_cball diff_0 dist_norm holomorphic_on_def holomorphic_on_subset mem_ball norm_minus_cancel)
    5.27    have [simp]: "\<And>z. norm z < r \<Longrightarrow> f field_differentiable at (a + z)"
    5.28      by (metis holf open_ball add_diff_cancel_left' dist_complex_def holomorphic_on_imp_differentiable_at holomorphic_on_subset interior_cball interior_subset mem_ball norm_minus_commute)
    5.29    then have [simp]: "f field_differentiable at a"
    5.30 @@ -2131,13 +2131,13 @@
    5.31    then show ?thesis
    5.32    proof cases
    5.33      case 1 then show ?thesis
    5.34 -      by (simp add: Topology_Euclidean_Space.ball_empty that)
    5.35 +      by (simp add: ball_empty that)
    5.36    next
    5.37      case 2
    5.38      show ?thesis
    5.39      proof (cases "deriv f a = 0")
    5.40        case True then show ?thesis
    5.41 -        using rle by (simp add: Topology_Euclidean_Space.ball_empty that)
    5.42 +        using rle by (simp add: ball_empty that)
    5.43      next
    5.44        case False
    5.45        then have "t > 0"
    5.46 @@ -3620,7 +3620,7 @@
    5.47                    have po:"zo = Suc (zo - Suc 0) " using \<open>zo>0\<close> by auto
    5.48                    have "(zp has_field_derivative (deriv zp w)) (at w)"
    5.49                      using DERIV_deriv_iff_has_field_derivative pp_holo
    5.50 -                    by (meson Topology_Euclidean_Space.open_ball \<open>w \<in> ball p r\<close> ball_subset_cball holomorphic_derivI holomorphic_on_subset)
    5.51 +                    by (meson open_ball \<open>w \<in> ball p r\<close> ball_subset_cball holomorphic_derivI holomorphic_on_subset)
    5.52                    then show "(f' has_field_derivative  der) (at w)"
    5.53                      using \<open>w\<noteq>p\<close> \<open>zo>0\<close> unfolding der_def f'_def
    5.54                      by (auto intro!: derivative_eq_intros simp add:field_simps)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/HOL/Analysis/Connected.thy	Tue Oct 10 17:15:37 2017 +0100
     6.3 @@ -0,0 +1,5388 @@
     6.4 +(*  Author:     L C Paulson, University of Cambridge*)
     6.5 +
     6.6 +section \<open>Connected Components, Homeomorphisms, Baire property, etc.\<close>
     6.7 +
     6.8 +text\<open>Material split off from Topology_Euclidean_Space\<close>
     6.9 +
    6.10 +theory Connected
    6.11 +imports Topology_Euclidean_Space
    6.12 +begin
    6.13 +
    6.14 +subsection \<open>More properties of closed balls, spheres, etc.\<close>
    6.15 +
    6.16 +lemma mem_interior_cball: "x \<in> interior S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S)"
    6.17 +  apply (simp add: interior_def, safe)
    6.18 +  apply (force simp: open_contains_cball)
    6.19 +  apply (rule_tac x="ball x e" in exI)
    6.20 +  apply (simp add: subset_trans [OF ball_subset_cball])
    6.21 +  done
    6.22 +
    6.23 +lemma islimpt_ball:
    6.24 +  fixes x y :: "'a::{real_normed_vector,perfect_space}"
    6.25 +  shows "y islimpt ball x e \<longleftrightarrow> 0 < e \<and> y \<in> cball x e"
    6.26 +  (is "?lhs \<longleftrightarrow> ?rhs")
    6.27 +proof
    6.28 +  show ?rhs if ?lhs
    6.29 +  proof
    6.30 +    {
    6.31 +      assume "e \<le> 0"
    6.32 +      then have *: "ball x e = {}"
    6.33 +        using ball_eq_empty[of x e] by auto
    6.34 +      have False using \<open>?lhs\<close>
    6.35 +        unfolding * using islimpt_EMPTY[of y] by auto
    6.36 +    }
    6.37 +    then show "e > 0" by (metis not_less)
    6.38 +    show "y \<in> cball x e"
    6.39 +      using closed_cball[of x e] islimpt_subset[of y "ball x e" "cball x e"]
    6.40 +        ball_subset_cball[of x e] \<open>?lhs\<close>
    6.41 +      unfolding closed_limpt by auto
    6.42 +  qed
    6.43 +  show ?lhs if ?rhs
    6.44 +  proof -
    6.45 +    from that have "e > 0" by auto
    6.46 +    {
    6.47 +      fix d :: real
    6.48 +      assume "d > 0"
    6.49 +      have "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
    6.50 +      proof (cases "d \<le> dist x y")
    6.51 +        case True
    6.52 +        then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
    6.53 +        proof (cases "x = y")
    6.54 +          case True
    6.55 +          then have False
    6.56 +            using \<open>d \<le> dist x y\<close> \<open>d>0\<close> by auto
    6.57 +          then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
    6.58 +            by auto
    6.59 +        next
    6.60 +          case False
    6.61 +          have "dist x (y - (d / (2 * dist y x)) *\<^sub>R (y - x)) =
    6.62 +            norm (x - y + (d / (2 * norm (y - x))) *\<^sub>R (y - x))"
    6.63 +            unfolding mem_cball mem_ball dist_norm diff_diff_eq2 diff_add_eq[symmetric]
    6.64 +            by auto
    6.65 +          also have "\<dots> = \<bar>- 1 + d / (2 * norm (x - y))\<bar> * norm (x - y)"
    6.66 +            using scaleR_left_distrib[of "- 1" "d / (2 * norm (y - x))", symmetric, of "y - x"]
    6.67 +            unfolding scaleR_minus_left scaleR_one
    6.68 +            by (auto simp: norm_minus_commute)
    6.69 +          also have "\<dots> = \<bar>- norm (x - y) + d / 2\<bar>"
    6.70 +            unfolding abs_mult_pos[of "norm (x - y)", OF norm_ge_zero[of "x - y"]]
    6.71 +            unfolding distrib_right using \<open>x\<noteq>y\<close>  by auto
    6.72 +          also have "\<dots> \<le> e - d/2" using \<open>d \<le> dist x y\<close> and \<open>d>0\<close> and \<open>?rhs\<close>
    6.73 +            by (auto simp: dist_norm)
    6.74 +          finally have "y - (d / (2 * dist y x)) *\<^sub>R (y - x) \<in> ball x e" using \<open>d>0\<close>
    6.75 +            by auto
    6.76 +          moreover
    6.77 +          have "(d / (2*dist y x)) *\<^sub>R (y - x) \<noteq> 0"
    6.78 +            using \<open>x\<noteq>y\<close>[unfolded dist_nz] \<open>d>0\<close> unfolding scaleR_eq_0_iff
    6.79 +            by (auto simp: dist_commute)
    6.80 +          moreover
    6.81 +          have "dist (y - (d / (2 * dist y x)) *\<^sub>R (y - x)) y < d"
    6.82 +            unfolding dist_norm
    6.83 +            apply simp
    6.84 +            unfolding norm_minus_cancel
    6.85 +            using \<open>d > 0\<close> \<open>x\<noteq>y\<close>[unfolded dist_nz] dist_commute[of x y]
    6.86 +            unfolding dist_norm
    6.87 +            apply auto
    6.88 +            done
    6.89 +          ultimately show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
    6.90 +            apply (rule_tac x = "y - (d / (2*dist y x)) *\<^sub>R (y - x)" in bexI)
    6.91 +            apply auto
    6.92 +            done
    6.93 +        qed
    6.94 +      next
    6.95 +        case False
    6.96 +        then have "d > dist x y" by auto
    6.97 +        show "\<exists>x' \<in> ball x e. x' \<noteq> y \<and> dist x' y < d"
    6.98 +        proof (cases "x = y")
    6.99 +          case True
   6.100 +          obtain z where **: "z \<noteq> y" "dist z y < min e d"
   6.101 +            using perfect_choose_dist[of "min e d" y]
   6.102 +            using \<open>d > 0\<close> \<open>e>0\<close> by auto
   6.103 +          show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
   6.104 +            unfolding \<open>x = y\<close>
   6.105 +            using \<open>z \<noteq> y\<close> **
   6.106 +            apply (rule_tac x=z in bexI)
   6.107 +            apply (auto simp: dist_commute)
   6.108 +            done
   6.109 +        next
   6.110 +          case False
   6.111 +          then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
   6.112 +            using \<open>d>0\<close> \<open>d > dist x y\<close> \<open>?rhs\<close>
   6.113 +            apply (rule_tac x=x in bexI, auto)
   6.114 +            done
   6.115 +        qed
   6.116 +      qed
   6.117 +    }
   6.118 +    then show ?thesis
   6.119 +      unfolding mem_cball islimpt_approachable mem_ball by auto
   6.120 +  qed
   6.121 +qed
   6.122 +
   6.123 +lemma closure_ball_lemma:
   6.124 +  fixes x y :: "'a::real_normed_vector"
   6.125 +  assumes "x \<noteq> y"
   6.126 +  shows "y islimpt ball x (dist x y)"
   6.127 +proof (rule islimptI)
   6.128 +  fix T
   6.129 +  assume "y \<in> T" "open T"
   6.130 +  then obtain r where "0 < r" "\<forall>z. dist z y < r \<longrightarrow> z \<in> T"
   6.131 +    unfolding open_dist by fast
   6.132 +  (* choose point between x and y, within distance r of y. *)
   6.133 +  define k where "k = min 1 (r / (2 * dist x y))"
   6.134 +  define z where "z = y + scaleR k (x - y)"
   6.135 +  have z_def2: "z = x + scaleR (1 - k) (y - x)"
   6.136 +    unfolding z_def by (simp add: algebra_simps)
   6.137 +  have "dist z y < r"
   6.138 +    unfolding z_def k_def using \<open>0 < r\<close>
   6.139 +    by (simp add: dist_norm min_def)
   6.140 +  then have "z \<in> T"
   6.141 +    using \<open>\<forall>z. dist z y < r \<longrightarrow> z \<in> T\<close> by simp
   6.142 +  have "dist x z < dist x y"
   6.143 +    unfolding z_def2 dist_norm
   6.144 +    apply (simp add: norm_minus_commute)
   6.145 +    apply (simp only: dist_norm [symmetric])
   6.146 +    apply (subgoal_tac "\<bar>1 - k\<bar> * dist x y < 1 * dist x y", simp)
   6.147 +    apply (rule mult_strict_right_mono)
   6.148 +    apply (simp add: k_def \<open>0 < r\<close> \<open>x \<noteq> y\<close>)
   6.149 +    apply (simp add: \<open>x \<noteq> y\<close>)
   6.150 +    done
   6.151 +  then have "z \<in> ball x (dist x y)"
   6.152 +    by simp
   6.153 +  have "z \<noteq> y"
   6.154 +    unfolding z_def k_def using \<open>x \<noteq> y\<close> \<open>0 < r\<close>
   6.155 +    by (simp add: min_def)
   6.156 +  show "\<exists>z\<in>ball x (dist x y). z \<in> T \<and> z \<noteq> y"
   6.157 +    using \<open>z \<in> ball x (dist x y)\<close> \<open>z \<in> T\<close> \<open>z \<noteq> y\<close>
   6.158 +    by fast
   6.159 +qed
   6.160 +
   6.161 +lemma closure_ball [simp]:
   6.162 +  fixes x :: "'a::real_normed_vector"
   6.163 +  shows "0 < e \<Longrightarrow> closure (ball x e) = cball x e"
   6.164 +  apply (rule equalityI)
   6.165 +  apply (rule closure_minimal)
   6.166 +  apply (rule ball_subset_cball)
   6.167 +  apply (rule closed_cball)
   6.168 +  apply (rule subsetI, rename_tac y)
   6.169 +  apply (simp add: le_less [where 'a=real])
   6.170 +  apply (erule disjE)
   6.171 +  apply (rule subsetD [OF closure_subset], simp)
   6.172 +  apply (simp add: closure_def, clarify)
   6.173 +  apply (rule closure_ball_lemma)
   6.174 +  apply (simp add: zero_less_dist_iff)
   6.175 +  done
   6.176 +
   6.177 +(* In a trivial vector space, this fails for e = 0. *)
   6.178 +lemma interior_cball [simp]:
   6.179 +  fixes x :: "'a::{real_normed_vector, perfect_space}"
   6.180 +  shows "interior (cball x e) = ball x e"
   6.181 +proof (cases "e \<ge> 0")
   6.182 +  case False note cs = this
   6.183 +  from cs have null: "ball x e = {}"
   6.184 +    using ball_empty[of e x] by auto
   6.185 +  moreover
   6.186 +  {
   6.187 +    fix y
   6.188 +    assume "y \<in> cball x e"
   6.189 +    then have False
   6.190 +      by (metis ball_eq_empty null cs dist_eq_0_iff dist_le_zero_iff empty_subsetI mem_cball subset_antisym subset_ball)
   6.191 +  }
   6.192 +  then have "cball x e = {}" by auto
   6.193 +  then have "interior (cball x e) = {}"
   6.194 +    using interior_empty by auto
   6.195 +  ultimately show ?thesis by blast
   6.196 +next
   6.197 +  case True note cs = this
   6.198 +  have "ball x e \<subseteq> cball x e"
   6.199 +    using ball_subset_cball by auto
   6.200 +  moreover
   6.201 +  {
   6.202 +    fix S y
   6.203 +    assume as: "S \<subseteq> cball x e" "open S" "y\<in>S"
   6.204 +    then obtain d where "d>0" and d: "\<forall>x'. dist x' y < d \<longrightarrow> x' \<in> S"
   6.205 +      unfolding open_dist by blast
   6.206 +    then obtain xa where xa_y: "xa \<noteq> y" and xa: "dist xa y < d"
   6.207 +      using perfect_choose_dist [of d] by auto
   6.208 +    have "xa \<in> S"
   6.209 +      using d[THEN spec[where x = xa]]
   6.210 +      using xa by (auto simp: dist_commute)
   6.211 +    then have xa_cball: "xa \<in> cball x e"
   6.212 +      using as(1) by auto
   6.213 +    then have "y \<in> ball x e"
   6.214 +    proof (cases "x = y")
   6.215 +      case True
   6.216 +      then have "e > 0" using cs order.order_iff_strict xa_cball xa_y by fastforce
   6.217 +      then show "y \<in> ball x e"
   6.218 +        using \<open>x = y \<close> by simp
   6.219 +    next
   6.220 +      case False
   6.221 +      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) y < d"
   6.222 +        unfolding dist_norm
   6.223 +        using \<open>d>0\<close> norm_ge_zero[of "y - x"] \<open>x \<noteq> y\<close> by auto
   6.224 +      then have *: "y + (d / 2 / dist y x) *\<^sub>R (y - x) \<in> cball x e"
   6.225 +        using d as(1)[unfolded subset_eq] by blast
   6.226 +      have "y - x \<noteq> 0" using \<open>x \<noteq> y\<close> by auto
   6.227 +      hence **:"d / (2 * norm (y - x)) > 0"
   6.228 +        unfolding zero_less_norm_iff[symmetric] using \<open>d>0\<close> by auto
   6.229 +      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) x =
   6.230 +        norm (y + (d / (2 * norm (y - x))) *\<^sub>R y - (d / (2 * norm (y - x))) *\<^sub>R x - x)"
   6.231 +        by (auto simp: dist_norm algebra_simps)
   6.232 +      also have "\<dots> = norm ((1 + d / (2 * norm (y - x))) *\<^sub>R (y - x))"
   6.233 +        by (auto simp: algebra_simps)
   6.234 +      also have "\<dots> = \<bar>1 + d / (2 * norm (y - x))\<bar> * norm (y - x)"
   6.235 +        using ** by auto
   6.236 +      also have "\<dots> = (dist y x) + d/2"
   6.237 +        using ** by (auto simp: distrib_right dist_norm)
   6.238 +      finally have "e \<ge> dist x y +d/2"
   6.239 +        using *[unfolded mem_cball] by (auto simp: dist_commute)
   6.240 +      then show "y \<in> ball x e"
   6.241 +        unfolding mem_ball using \<open>d>0\<close> by auto
   6.242 +    qed
   6.243 +  }
   6.244 +  then have "\<forall>S \<subseteq> cball x e. open S \<longrightarrow> S \<subseteq> ball x e"
   6.245 +    by auto
   6.246 +  ultimately show ?thesis
   6.247 +    using interior_unique[of "ball x e" "cball x e"]
   6.248 +    using open_ball[of x e]
   6.249 +    by auto
   6.250 +qed
   6.251 +
   6.252 +lemma interior_ball [simp]: "interior (ball x e) = ball x e"
   6.253 +  by (simp add: interior_open)
   6.254 +
   6.255 +lemma frontier_ball [simp]:
   6.256 +  fixes a :: "'a::real_normed_vector"
   6.257 +  shows "0 < e \<Longrightarrow> frontier (ball a e) = sphere a e"
   6.258 +  by (force simp: frontier_def)
   6.259 +
   6.260 +lemma frontier_cball [simp]:
   6.261 +  fixes a :: "'a::{real_normed_vector, perfect_space}"
   6.262 +  shows "frontier (cball a e) = sphere a e"
   6.263 +  by (force simp: frontier_def)
   6.264 +
   6.265 +lemma cball_eq_empty [simp]: "cball x e = {} \<longleftrightarrow> e < 0"
   6.266 +  apply (simp add: set_eq_iff not_le)
   6.267 +  apply (metis zero_le_dist dist_self order_less_le_trans)
   6.268 +  done
   6.269 +
   6.270 +lemma cball_empty [simp]: "e < 0 \<Longrightarrow> cball x e = {}"
   6.271 +  by simp
   6.272 +
   6.273 +lemma cball_eq_sing:
   6.274 +  fixes x :: "'a::{metric_space,perfect_space}"
   6.275 +  shows "cball x e = {x} \<longleftrightarrow> e = 0"
   6.276 +proof (rule linorder_cases)
   6.277 +  assume e: "0 < e"
   6.278 +  obtain a where "a \<noteq> x" "dist a x < e"
   6.279 +    using perfect_choose_dist [OF e] by auto
   6.280 +  then have "a \<noteq> x" "dist x a \<le> e"
   6.281 +    by (auto simp: dist_commute)
   6.282 +  with e show ?thesis by (auto simp: set_eq_iff)
   6.283 +qed auto
   6.284 +
   6.285 +lemma cball_sing:
   6.286 +  fixes x :: "'a::metric_space"
   6.287 +  shows "e = 0 \<Longrightarrow> cball x e = {x}"
   6.288 +  by (auto simp: set_eq_iff)
   6.289 +
   6.290 +lemma ball_divide_subset: "d \<ge> 1 \<Longrightarrow> ball x (e/d) \<subseteq> ball x e"
   6.291 +  apply (cases "e \<le> 0")
   6.292 +  apply (simp add: ball_empty divide_simps)
   6.293 +  apply (rule subset_ball)
   6.294 +  apply (simp add: divide_simps)
   6.295 +  done
   6.296 +
   6.297 +lemma ball_divide_subset_numeral: "ball x (e / numeral w) \<subseteq> ball x e"
   6.298 +  using ball_divide_subset one_le_numeral by blast
   6.299 +
   6.300 +lemma cball_divide_subset: "d \<ge> 1 \<Longrightarrow> cball x (e/d) \<subseteq> cball x e"
   6.301 +  apply (cases "e < 0")
   6.302 +  apply (simp add: divide_simps)
   6.303 +  apply (rule subset_cball)
   6.304 +  apply (metis div_by_1 frac_le not_le order_refl zero_less_one)
   6.305 +  done
   6.306 +
   6.307 +lemma cball_divide_subset_numeral: "cball x (e / numeral w) \<subseteq> cball x e"
   6.308 +  using cball_divide_subset one_le_numeral by blast
   6.309 +
   6.310 +lemma compact_cball[simp]:
   6.311 +  fixes x :: "'a::heine_borel"
   6.312 +  shows "compact (cball x e)"
   6.313 +  using compact_eq_bounded_closed bounded_cball closed_cball
   6.314 +  by blast
   6.315 +
   6.316 +lemma compact_frontier_bounded[intro]:
   6.317 +  fixes S :: "'a::heine_borel set"
   6.318 +  shows "bounded S \<Longrightarrow> compact (frontier S)"
   6.319 +  unfolding frontier_def
   6.320 +  using compact_eq_bounded_closed
   6.321 +  by blast
   6.322 +
   6.323 +lemma compact_frontier[intro]:
   6.324 +  fixes S :: "'a::heine_borel set"
   6.325 +  shows "compact S \<Longrightarrow> compact (frontier S)"
   6.326 +  using compact_eq_bounded_closed compact_frontier_bounded
   6.327 +  by blast
   6.328 +
   6.329 +corollary compact_sphere [simp]:
   6.330 +  fixes a :: "'a::{real_normed_vector,perfect_space,heine_borel}"
   6.331 +  shows "compact (sphere a r)"
   6.332 +using compact_frontier [of "cball a r"] by simp
   6.333 +
   6.334 +corollary bounded_sphere [simp]:
   6.335 +  fixes a :: "'a::{real_normed_vector,perfect_space,heine_borel}"
   6.336 +  shows "bounded (sphere a r)"
   6.337 +by (simp add: compact_imp_bounded)
   6.338 +
   6.339 +corollary closed_sphere  [simp]:
   6.340 +  fixes a :: "'a::{real_normed_vector,perfect_space,heine_borel}"
   6.341 +  shows "closed (sphere a r)"
   6.342 +by (simp add: compact_imp_closed)
   6.343 +
   6.344 +subsection \<open>Connectedness\<close>
   6.345 +
   6.346 +lemma connected_local:
   6.347 + "connected S \<longleftrightarrow>
   6.348 +  \<not> (\<exists>e1 e2.
   6.349 +      openin (subtopology euclidean S) e1 \<and>
   6.350 +      openin (subtopology euclidean S) e2 \<and>
   6.351 +      S \<subseteq> e1 \<union> e2 \<and>
   6.352 +      e1 \<inter> e2 = {} \<and>
   6.353 +      e1 \<noteq> {} \<and>
   6.354 +      e2 \<noteq> {})"
   6.355 +  unfolding connected_def openin_open
   6.356 +  by safe blast+
   6.357 +
   6.358 +lemma exists_diff:
   6.359 +  fixes P :: "'a set \<Rightarrow> bool"
   6.360 +  shows "(\<exists>S. P (- S)) \<longleftrightarrow> (\<exists>S. P S)"
   6.361 +    (is "?lhs \<longleftrightarrow> ?rhs")
   6.362 +proof -
   6.363 +  have ?rhs if ?lhs
   6.364 +    using that by blast
   6.365 +  moreover have "P (- (- S))" if "P S" for S
   6.366 +  proof -
   6.367 +    have "S = - (- S)" by simp
   6.368 +    with that show ?thesis by metis
   6.369 +  qed
   6.370 +  ultimately show ?thesis by metis
   6.371 +qed
   6.372 +
   6.373 +lemma connected_clopen: "connected S \<longleftrightarrow>
   6.374 +  (\<forall>T. openin (subtopology euclidean S) T \<and>
   6.375 +     closedin (subtopology euclidean S) T \<longrightarrow> T = {} \<or> T = S)" (is "?lhs \<longleftrightarrow> ?rhs")
   6.376 +proof -
   6.377 +  have "\<not> connected S \<longleftrightarrow>
   6.378 +    (\<exists>e1 e2. open e1 \<and> open (- e2) \<and> S \<subseteq> e1 \<union> (- e2) \<and> e1 \<inter> (- e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (- e2) \<inter> S \<noteq> {})"
   6.379 +    unfolding connected_def openin_open closedin_closed
   6.380 +    by (metis double_complement)
   6.381 +  then have th0: "connected S \<longleftrightarrow>
   6.382 +    \<not> (\<exists>e2 e1. closed e2 \<and> open e1 \<and> S \<subseteq> e1 \<union> (- e2) \<and> e1 \<inter> (- e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (- e2) \<inter> S \<noteq> {})"
   6.383 +    (is " _ \<longleftrightarrow> \<not> (\<exists>e2 e1. ?P e2 e1)")
   6.384 +    by (simp add: closed_def) metis
   6.385 +  have th1: "?rhs \<longleftrightarrow> \<not> (\<exists>t' t. closed t'\<and>t = S\<inter>t' \<and> t\<noteq>{} \<and> t\<noteq>S \<and> (\<exists>t'. open t' \<and> t = S \<inter> t'))"
   6.386 +    (is "_ \<longleftrightarrow> \<not> (\<exists>t' t. ?Q t' t)")
   6.387 +    unfolding connected_def openin_open closedin_closed by auto
   6.388 +  have "(\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)" for e2
   6.389 +  proof -
   6.390 +    have "?P e2 e1 \<longleftrightarrow> (\<exists>t. closed e2 \<and> t = S\<inter>e2 \<and> open e1 \<and> t = S\<inter>e1 \<and> t\<noteq>{} \<and> t \<noteq> S)" for e1
   6.391 +      by auto
   6.392 +    then show ?thesis
   6.393 +      by metis
   6.394 +  qed
   6.395 +  then have "\<forall>e2. (\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)"
   6.396 +    by blast
   6.397 +  then show ?thesis
   6.398 +    by (simp add: th0 th1)
   6.399 +qed
   6.400 +
   6.401 +lemma connected_continuous_image:
   6.402 +  assumes "continuous_on s f"
   6.403 +    and "connected s"
   6.404 +  shows "connected(f ` s)"
   6.405 +proof -
   6.406 +  {
   6.407 +    fix T
   6.408 +    assume as:
   6.409 +      "T \<noteq> {}"
   6.410 +      "T \<noteq> f ` s"
   6.411 +      "openin (subtopology euclidean (f ` s)) T"
   6.412 +      "closedin (subtopology euclidean (f ` s)) T"
   6.413 +    have "{x \<in> s. f x \<in> T} = {} \<or> {x \<in> s. f x \<in> T} = s"
   6.414 +      using assms(1)[unfolded continuous_on_open, THEN spec[where x=T]]
   6.415 +      using assms(1)[unfolded continuous_on_closed, THEN spec[where x=T]]
   6.416 +      using assms(2)[unfolded connected_clopen, THEN spec[where x="{x \<in> s. f x \<in> T}"]] as(3,4) by auto
   6.417 +    then have False using as(1,2)
   6.418 +      using as(4)[unfolded closedin_def topspace_euclidean_subtopology] by auto
   6.419 +  }
   6.420 +  then show ?thesis
   6.421 +    unfolding connected_clopen by auto
   6.422 +qed
   6.423 +
   6.424 +lemma connected_linear_image:
   6.425 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::real_normed_vector"
   6.426 +  assumes "linear f" and "connected s"
   6.427 +  shows "connected (f ` s)"
   6.428 +using connected_continuous_image assms linear_continuous_on linear_conv_bounded_linear by blast
   6.429 +
   6.430 +subsection \<open>Connected components, considered as a connectedness relation or a set\<close>
   6.431 +
   6.432 +definition "connected_component s x y \<equiv> \<exists>t. connected t \<and> t \<subseteq> s \<and> x \<in> t \<and> y \<in> t"
   6.433 +
   6.434 +abbreviation "connected_component_set s x \<equiv> Collect (connected_component s x)"
   6.435 +
   6.436 +lemma connected_componentI:
   6.437 +  "connected t \<Longrightarrow> t \<subseteq> s \<Longrightarrow> x \<in> t \<Longrightarrow> y \<in> t \<Longrightarrow> connected_component s x y"
   6.438 +  by (auto simp: connected_component_def)
   6.439 +
   6.440 +lemma connected_component_in: "connected_component s x y \<Longrightarrow> x \<in> s \<and> y \<in> s"
   6.441 +  by (auto simp: connected_component_def)
   6.442 +
   6.443 +lemma connected_component_refl: "x \<in> s \<Longrightarrow> connected_component s x x"
   6.444 +  by (auto simp: connected_component_def) (use connected_sing in blast)
   6.445 +
   6.446 +lemma connected_component_refl_eq [simp]: "connected_component s x x \<longleftrightarrow> x \<in> s"
   6.447 +  by (auto simp: connected_component_refl) (auto simp: connected_component_def)
   6.448 +
   6.449 +lemma connected_component_sym: "connected_component s x y \<Longrightarrow> connected_component s y x"
   6.450 +  by (auto simp: connected_component_def)
   6.451 +
   6.452 +lemma connected_component_trans:
   6.453 +  "connected_component s x y \<Longrightarrow> connected_component s y z \<Longrightarrow> connected_component s x z"
   6.454 +  unfolding connected_component_def
   6.455 +  by (metis Int_iff Un_iff Un_subset_iff equals0D connected_Un)
   6.456 +
   6.457 +lemma connected_component_of_subset:
   6.458 +  "connected_component s x y \<Longrightarrow> s \<subseteq> t \<Longrightarrow> connected_component t x y"
   6.459 +  by (auto simp: connected_component_def)
   6.460 +
   6.461 +lemma connected_component_Union: "connected_component_set s x = \<Union>{t. connected t \<and> x \<in> t \<and> t \<subseteq> s}"
   6.462 +  by (auto simp: connected_component_def)
   6.463 +
   6.464 +lemma connected_connected_component [iff]: "connected (connected_component_set s x)"
   6.465 +  by (auto simp: connected_component_Union intro: connected_Union)
   6.466 +
   6.467 +lemma connected_iff_eq_connected_component_set:
   6.468 +  "connected s \<longleftrightarrow> (\<forall>x \<in> s. connected_component_set s x = s)"
   6.469 +proof (cases "s = {}")
   6.470 +  case True
   6.471 +  then show ?thesis by simp
   6.472 +next
   6.473 +  case False
   6.474 +  then obtain x where "x \<in> s" by auto
   6.475 +  show ?thesis
   6.476 +  proof
   6.477 +    assume "connected s"
   6.478 +    then show "\<forall>x \<in> s. connected_component_set s x = s"
   6.479 +      by (force simp: connected_component_def)
   6.480 +  next
   6.481 +    assume "\<forall>x \<in> s. connected_component_set s x = s"
   6.482 +    then show "connected s"
   6.483 +      by (metis \<open>x \<in> s\<close> connected_connected_component)
   6.484 +  qed
   6.485 +qed
   6.486 +
   6.487 +lemma connected_component_subset: "connected_component_set s x \<subseteq> s"
   6.488 +  using connected_component_in by blast
   6.489 +
   6.490 +lemma connected_component_eq_self: "connected s \<Longrightarrow> x \<in> s \<Longrightarrow> connected_component_set s x = s"
   6.491 +  by (simp add: connected_iff_eq_connected_component_set)
   6.492 +
   6.493 +lemma connected_iff_connected_component:
   6.494 +  "connected s \<longleftrightarrow> (\<forall>x \<in> s. \<forall>y \<in> s. connected_component s x y)"
   6.495 +  using connected_component_in by (auto simp: connected_iff_eq_connected_component_set)
   6.496 +
   6.497 +lemma connected_component_maximal:
   6.498 +  "x \<in> t \<Longrightarrow> connected t \<Longrightarrow> t \<subseteq> s \<Longrightarrow> t \<subseteq> (connected_component_set s x)"
   6.499 +  using connected_component_eq_self connected_component_of_subset by blast
   6.500 +
   6.501 +lemma connected_component_mono:
   6.502 +  "s \<subseteq> t \<Longrightarrow> connected_component_set s x \<subseteq> connected_component_set t x"
   6.503 +  by (simp add: Collect_mono connected_component_of_subset)
   6.504 +
   6.505 +lemma connected_component_eq_empty [simp]: "connected_component_set s x = {} \<longleftrightarrow> x \<notin> s"
   6.506 +  using connected_component_refl by (fastforce simp: connected_component_in)
   6.507 +
   6.508 +lemma connected_component_set_empty [simp]: "connected_component_set {} x = {}"
   6.509 +  using connected_component_eq_empty by blast
   6.510 +
   6.511 +lemma connected_component_eq:
   6.512 +  "y \<in> connected_component_set s x \<Longrightarrow> (connected_component_set s y = connected_component_set s x)"
   6.513 +  by (metis (no_types, lifting)
   6.514 +      Collect_cong connected_component_sym connected_component_trans mem_Collect_eq)
   6.515 +
   6.516 +lemma closed_connected_component:
   6.517 +  assumes s: "closed s"
   6.518 +  shows "closed (connected_component_set s x)"
   6.519 +proof (cases "x \<in> s")
   6.520 +  case False
   6.521 +  then show ?thesis
   6.522 +    by (metis connected_component_eq_empty closed_empty)
   6.523 +next
   6.524 +  case True
   6.525 +  show ?thesis
   6.526 +    unfolding closure_eq [symmetric]
   6.527 +  proof
   6.528 +    show "closure (connected_component_set s x) \<subseteq> connected_component_set s x"
   6.529 +      apply (rule connected_component_maximal)
   6.530 +        apply (simp add: closure_def True)
   6.531 +       apply (simp add: connected_imp_connected_closure)
   6.532 +      apply (simp add: s closure_minimal connected_component_subset)
   6.533 +      done
   6.534 +  next
   6.535 +    show "connected_component_set s x \<subseteq> closure (connected_component_set s x)"
   6.536 +      by (simp add: closure_subset)
   6.537 +  qed
   6.538 +qed
   6.539 +
   6.540 +lemma connected_component_disjoint:
   6.541 +  "connected_component_set s a \<inter> connected_component_set s b = {} \<longleftrightarrow>
   6.542 +    a \<notin> connected_component_set s b"
   6.543 +  apply (auto simp: connected_component_eq)
   6.544 +  using connected_component_eq connected_component_sym
   6.545 +  apply blast
   6.546 +  done
   6.547 +
   6.548 +lemma connected_component_nonoverlap:
   6.549 +  "connected_component_set s a \<inter> connected_component_set s b = {} \<longleftrightarrow>
   6.550 +    a \<notin> s \<or> b \<notin> s \<or> connected_component_set s a \<noteq> connected_component_set s b"
   6.551 +  apply (auto simp: connected_component_in)
   6.552 +  using connected_component_refl_eq
   6.553 +    apply blast
   6.554 +   apply (metis connected_component_eq mem_Collect_eq)
   6.555 +  apply (metis connected_component_eq mem_Collect_eq)
   6.556 +  done
   6.557 +
   6.558 +lemma connected_component_overlap:
   6.559 +  "connected_component_set s a \<inter> connected_component_set s b \<noteq> {} \<longleftrightarrow>
   6.560 +    a \<in> s \<and> b \<in> s \<and> connected_component_set s a = connected_component_set s b"
   6.561 +  by (auto simp: connected_component_nonoverlap)
   6.562 +
   6.563 +lemma connected_component_sym_eq: "connected_component s x y \<longleftrightarrow> connected_component s y x"
   6.564 +  using connected_component_sym by blast
   6.565 +
   6.566 +lemma connected_component_eq_eq:
   6.567 +  "connected_component_set s x = connected_component_set s y \<longleftrightarrow>
   6.568 +    x \<notin> s \<and> y \<notin> s \<or> x \<in> s \<and> y \<in> s \<and> connected_component s x y"
   6.569 +  apply (cases "y \<in> s", simp)
   6.570 +   apply (metis connected_component_eq connected_component_eq_empty connected_component_refl_eq mem_Collect_eq)
   6.571 +  apply (cases "x \<in> s", simp)
   6.572 +   apply (metis connected_component_eq_empty)
   6.573 +  using connected_component_eq_empty
   6.574 +  apply blast
   6.575 +  done
   6.576 +
   6.577 +lemma connected_iff_connected_component_eq:
   6.578 +  "connected s \<longleftrightarrow> (\<forall>x \<in> s. \<forall>y \<in> s. connected_component_set s x = connected_component_set s y)"
   6.579 +  by (simp add: connected_component_eq_eq connected_iff_connected_component)
   6.580 +
   6.581 +lemma connected_component_idemp:
   6.582 +  "connected_component_set (connected_component_set s x) x = connected_component_set s x"
   6.583 +  apply (rule subset_antisym)
   6.584 +   apply (simp add: connected_component_subset)
   6.585 +  apply (metis connected_component_eq_empty connected_component_maximal
   6.586 +      connected_component_refl_eq connected_connected_component mem_Collect_eq set_eq_subset)
   6.587 +  done
   6.588 +
   6.589 +lemma connected_component_unique:
   6.590 +  "\<lbrakk>x \<in> c; c \<subseteq> s; connected c;
   6.591 +    \<And>c'. x \<in> c' \<and> c' \<subseteq> s \<and> connected c'
   6.592 +              \<Longrightarrow> c' \<subseteq> c\<rbrakk>
   6.593 +        \<Longrightarrow> connected_component_set s x = c"
   6.594 +apply (rule subset_antisym)
   6.595 +apply (meson connected_component_maximal connected_component_subset connected_connected_component contra_subsetD)
   6.596 +by (simp add: connected_component_maximal)
   6.597 +
   6.598 +lemma joinable_connected_component_eq:
   6.599 +  "\<lbrakk>connected t; t \<subseteq> s;
   6.600 +    connected_component_set s x \<inter> t \<noteq> {};
   6.601 +    connected_component_set s y \<inter> t \<noteq> {}\<rbrakk>
   6.602 +    \<Longrightarrow> connected_component_set s x = connected_component_set s y"
   6.603 +apply (simp add: ex_in_conv [symmetric])
   6.604 +apply (rule connected_component_eq)
   6.605 +by (metis (no_types, hide_lams) connected_component_eq_eq connected_component_in connected_component_maximal subsetD mem_Collect_eq)
   6.606 +
   6.607 +
   6.608 +lemma Union_connected_component: "\<Union>(connected_component_set s ` s) = s"
   6.609 +  apply (rule subset_antisym)
   6.610 +  apply (simp add: SUP_least connected_component_subset)
   6.611 +  using connected_component_refl_eq
   6.612 +  by force
   6.613 +
   6.614 +
   6.615 +lemma complement_connected_component_unions:
   6.616 +    "s - connected_component_set s x =
   6.617 +     \<Union>(connected_component_set s ` s - {connected_component_set s x})"
   6.618 +  apply (subst Union_connected_component [symmetric], auto)
   6.619 +  apply (metis connected_component_eq_eq connected_component_in)
   6.620 +  by (metis connected_component_eq mem_Collect_eq)
   6.621 +
   6.622 +lemma connected_component_intermediate_subset:
   6.623 +        "\<lbrakk>connected_component_set u a \<subseteq> t; t \<subseteq> u\<rbrakk>
   6.624 +        \<Longrightarrow> connected_component_set t a = connected_component_set u a"
   6.625 +  apply (case_tac "a \<in> u")
   6.626 +  apply (simp add: connected_component_maximal connected_component_mono subset_antisym)
   6.627 +  using connected_component_eq_empty by blast
   6.628 +
   6.629 +proposition connected_Times:
   6.630 +  assumes S: "connected S" and T: "connected T"
   6.631 +  shows "connected (S \<times> T)"
   6.632 +proof (clarsimp simp add: connected_iff_connected_component)
   6.633 +  fix x y x' y'
   6.634 +  assume xy: "x \<in> S" "y \<in> T" "x' \<in> S" "y' \<in> T"
   6.635 +  with xy obtain U V where U: "connected U" "U \<subseteq> S" "x \<in> U" "x' \<in> U"
   6.636 +                       and V: "connected V" "V \<subseteq> T" "y \<in> V" "y' \<in> V"
   6.637 +    using S T \<open>x \<in> S\<close> \<open>x' \<in> S\<close> by blast+
   6.638 +  show "connected_component (S \<times> T) (x, y) (x', y')"
   6.639 +    unfolding connected_component_def
   6.640 +  proof (intro exI conjI)
   6.641 +    show "connected ((\<lambda>x. (x, y)) ` U \<union> Pair x' ` V)"
   6.642 +    proof (rule connected_Un)
   6.643 +      have "continuous_on U (\<lambda>x. (x, y))"
   6.644 +        by (intro continuous_intros)
   6.645 +      then show "connected ((\<lambda>x. (x, y)) ` U)"
   6.646 +        by (rule connected_continuous_image) (rule \<open>connected U\<close>)
   6.647 +      have "continuous_on V (Pair x')"
   6.648 +        by (intro continuous_intros)
   6.649 +      then show "connected (Pair x' ` V)"
   6.650 +        by (rule connected_continuous_image) (rule \<open>connected V\<close>)
   6.651 +    qed (use U V in auto)
   6.652 +  qed (use U V in auto)
   6.653 +qed
   6.654 +
   6.655 +corollary connected_Times_eq [simp]:
   6.656 +   "connected (S \<times> T) \<longleftrightarrow> S = {} \<or> T = {} \<or> connected S \<and> connected T"  (is "?lhs = ?rhs")
   6.657 +proof
   6.658 +  assume L: ?lhs
   6.659 +  show ?rhs
   6.660 +  proof (cases "S = {} \<or> T = {}")
   6.661 +    case True
   6.662 +    then show ?thesis by auto
   6.663 +  next
   6.664 +    case False
   6.665 +    have "connected (fst ` (S \<times> T))" "connected (snd ` (S \<times> T))"
   6.666 +      using continuous_on_fst continuous_on_snd continuous_on_id
   6.667 +      by (blast intro: connected_continuous_image [OF _ L])+
   6.668 +    with False show ?thesis
   6.669 +      by auto
   6.670 +  qed
   6.671 +next
   6.672 +  assume ?rhs
   6.673 +  then show ?lhs
   6.674 +    by (auto simp: connected_Times)
   6.675 +qed
   6.676 +
   6.677 +
   6.678 +subsection \<open>The set of connected components of a set\<close>
   6.679 +
   6.680 +definition components:: "'a::topological_space set \<Rightarrow> 'a set set"
   6.681 +  where "components s \<equiv> connected_component_set s ` s"
   6.682 +
   6.683 +lemma components_iff: "s \<in> components u \<longleftrightarrow> (\<exists>x. x \<in> u \<and> s = connected_component_set u x)"
   6.684 +  by (auto simp: components_def)
   6.685 +
   6.686 +lemma componentsI: "x \<in> u \<Longrightarrow> connected_component_set u x \<in> components u"
   6.687 +  by (auto simp: components_def)
   6.688 +
   6.689 +lemma componentsE:
   6.690 +  assumes "s \<in> components u"
   6.691 +  obtains x where "x \<in> u" "s = connected_component_set u x"
   6.692 +  using assms by (auto simp: components_def)
   6.693 +
   6.694 +lemma Union_components [simp]: "\<Union>(components u) = u"
   6.695 +  apply (rule subset_antisym)
   6.696 +  using Union_connected_component components_def apply fastforce
   6.697 +  apply (metis Union_connected_component components_def set_eq_subset)
   6.698 +  done
   6.699 +
   6.700 +lemma pairwise_disjoint_components: "pairwise (\<lambda>X Y. X \<inter> Y = {}) (components u)"
   6.701 +  apply (simp add: pairwise_def)
   6.702 +  apply (auto simp: components_iff)
   6.703 +  apply (metis connected_component_eq_eq connected_component_in)+
   6.704 +  done
   6.705 +
   6.706 +lemma in_components_nonempty: "c \<in> components s \<Longrightarrow> c \<noteq> {}"
   6.707 +    by (metis components_iff connected_component_eq_empty)
   6.708 +
   6.709 +lemma in_components_subset: "c \<in> components s \<Longrightarrow> c \<subseteq> s"
   6.710 +  using Union_components by blast
   6.711 +
   6.712 +lemma in_components_connected: "c \<in> components s \<Longrightarrow> connected c"
   6.713 +  by (metis components_iff connected_connected_component)
   6.714 +
   6.715 +lemma in_components_maximal:
   6.716 +  "c \<in> components s \<longleftrightarrow>
   6.717 +    c \<noteq> {} \<and> c \<subseteq> s \<and> connected c \<and> (\<forall>d. d \<noteq> {} \<and> c \<subseteq> d \<and> d \<subseteq> s \<and> connected d \<longrightarrow> d = c)"
   6.718 +  apply (rule iffI)
   6.719 +   apply (simp add: in_components_nonempty in_components_connected)
   6.720 +   apply (metis (full_types) components_iff connected_component_eq_self connected_component_intermediate_subset connected_component_refl in_components_subset mem_Collect_eq rev_subsetD)
   6.721 +  apply (metis bot.extremum_uniqueI components_iff connected_component_eq_empty connected_component_maximal connected_component_subset connected_connected_component subset_emptyI)
   6.722 +  done
   6.723 +
   6.724 +lemma joinable_components_eq:
   6.725 +  "connected t \<and> t \<subseteq> s \<and> c1 \<in> components s \<and> c2 \<in> components s \<and> c1 \<inter> t \<noteq> {} \<and> c2 \<inter> t \<noteq> {} \<Longrightarrow> c1 = c2"
   6.726 +  by (metis (full_types) components_iff joinable_connected_component_eq)
   6.727 +
   6.728 +lemma closed_components: "\<lbrakk>closed s; c \<in> components s\<rbrakk> \<Longrightarrow> closed c"
   6.729 +  by (metis closed_connected_component components_iff)
   6.730 +
   6.731 +lemma compact_components:
   6.732 +  fixes s :: "'a::heine_borel set"
   6.733 +  shows "\<lbrakk>compact s; c \<in> components s\<rbrakk> \<Longrightarrow> compact c"
   6.734 +by (meson bounded_subset closed_components in_components_subset compact_eq_bounded_closed)
   6.735 +
   6.736 +lemma components_nonoverlap:
   6.737 +    "\<lbrakk>c \<in> components s; c' \<in> components s\<rbrakk> \<Longrightarrow> (c \<inter> c' = {}) \<longleftrightarrow> (c \<noteq> c')"
   6.738 +  apply (auto simp: in_components_nonempty components_iff)
   6.739 +    using connected_component_refl apply blast
   6.740 +   apply (metis connected_component_eq_eq connected_component_in)
   6.741 +  by (metis connected_component_eq mem_Collect_eq)
   6.742 +
   6.743 +lemma components_eq: "\<lbrakk>c \<in> components s; c' \<in> components s\<rbrakk> \<Longrightarrow> (c = c' \<longleftrightarrow> c \<inter> c' \<noteq> {})"
   6.744 +  by (metis components_nonoverlap)
   6.745 +
   6.746 +lemma components_eq_empty [simp]: "components s = {} \<longleftrightarrow> s = {}"
   6.747 +  by (simp add: components_def)
   6.748 +
   6.749 +lemma components_empty [simp]: "components {} = {}"
   6.750 +  by simp
   6.751 +
   6.752 +lemma connected_eq_connected_components_eq: "connected s \<longleftrightarrow> (\<forall>c \<in> components s. \<forall>c' \<in> components s. c = c')"
   6.753 +  by (metis (no_types, hide_lams) components_iff connected_component_eq_eq connected_iff_connected_component)
   6.754 +
   6.755 +lemma components_eq_sing_iff: "components s = {s} \<longleftrightarrow> connected s \<and> s \<noteq> {}"
   6.756 +  apply (rule iffI)
   6.757 +  using in_components_connected apply fastforce
   6.758 +  apply safe
   6.759 +  using Union_components apply fastforce
   6.760 +   apply (metis components_iff connected_component_eq_self)
   6.761 +  using in_components_maximal
   6.762 +  apply auto
   6.763 +  done
   6.764 +
   6.765 +lemma components_eq_sing_exists: "(\<exists>a. components s = {a}) \<longleftrightarrow> connected s \<and> s \<noteq> {}"
   6.766 +  apply (rule iffI)
   6.767 +  using connected_eq_connected_components_eq apply fastforce
   6.768 +  apply (metis components_eq_sing_iff)
   6.769 +  done
   6.770 +
   6.771 +lemma connected_eq_components_subset_sing: "connected s \<longleftrightarrow> components s \<subseteq> {s}"
   6.772 +  by (metis Union_components components_empty components_eq_sing_iff connected_empty insert_subset order_refl subset_singletonD)
   6.773 +
   6.774 +lemma connected_eq_components_subset_sing_exists: "connected s \<longleftrightarrow> (\<exists>a. components s \<subseteq> {a})"
   6.775 +  by (metis components_eq_sing_exists connected_eq_components_subset_sing empty_iff subset_iff subset_singletonD)
   6.776 +
   6.777 +lemma in_components_self: "s \<in> components s \<longleftrightarrow> connected s \<and> s \<noteq> {}"
   6.778 +  by (metis components_empty components_eq_sing_iff empty_iff in_components_connected insertI1)
   6.779 +
   6.780 +lemma components_maximal: "\<lbrakk>c \<in> components s; connected t; t \<subseteq> s; c \<inter> t \<noteq> {}\<rbrakk> \<Longrightarrow> t \<subseteq> c"
   6.781 +  apply (simp add: components_def ex_in_conv [symmetric], clarify)
   6.782 +  by (meson connected_component_def connected_component_trans)
   6.783 +
   6.784 +lemma exists_component_superset: "\<lbrakk>t \<subseteq> s; s \<noteq> {}; connected t\<rbrakk> \<Longrightarrow> \<exists>c. c \<in> components s \<and> t \<subseteq> c"
   6.785 +  apply (cases "t = {}", force)
   6.786 +  apply (metis components_def ex_in_conv connected_component_maximal contra_subsetD image_eqI)
   6.787 +  done
   6.788 +
   6.789 +lemma components_intermediate_subset: "\<lbrakk>s \<in> components u; s \<subseteq> t; t \<subseteq> u\<rbrakk> \<Longrightarrow> s \<in> components t"
   6.790 +  apply (auto simp: components_iff)
   6.791 +  apply (metis connected_component_eq_empty connected_component_intermediate_subset)
   6.792 +  done
   6.793 +
   6.794 +lemma in_components_unions_complement: "c \<in> components s \<Longrightarrow> s - c = \<Union>(components s - {c})"
   6.795 +  by (metis complement_connected_component_unions components_def components_iff)
   6.796 +
   6.797 +lemma connected_intermediate_closure:
   6.798 +  assumes cs: "connected s" and st: "s \<subseteq> t" and ts: "t \<subseteq> closure s"
   6.799 +  shows "connected t"
   6.800 +proof (rule connectedI)
   6.801 +  fix A B
   6.802 +  assume A: "open A" and B: "open B" and Alap: "A \<inter> t \<noteq> {}" and Blap: "B \<inter> t \<noteq> {}"
   6.803 +    and disj: "A \<inter> B \<inter> t = {}" and cover: "t \<subseteq> A \<union> B"
   6.804 +  have disjs: "A \<inter> B \<inter> s = {}"
   6.805 +    using disj st by auto
   6.806 +  have "A \<inter> closure s \<noteq> {}"
   6.807 +    using Alap Int_absorb1 ts by blast
   6.808 +  then have Alaps: "A \<inter> s \<noteq> {}"
   6.809 +    by (simp add: A open_Int_closure_eq_empty)
   6.810 +  have "B \<inter> closure s \<noteq> {}"
   6.811 +    using Blap Int_absorb1 ts by blast
   6.812 +  then have Blaps: "B \<inter> s \<noteq> {}"
   6.813 +    by (simp add: B open_Int_closure_eq_empty)
   6.814 +  then show False
   6.815 +    using cs [unfolded connected_def] A B disjs Alaps Blaps cover st
   6.816 +    by blast
   6.817 +qed
   6.818 +
   6.819 +lemma closedin_connected_component: "closedin (subtopology euclidean s) (connected_component_set s x)"
   6.820 +proof (cases "connected_component_set s x = {}")
   6.821 +  case True
   6.822 +  then show ?thesis
   6.823 +    by (metis closedin_empty)
   6.824 +next
   6.825 +  case False
   6.826 +  then obtain y where y: "connected_component s x y"
   6.827 +    by blast
   6.828 +  have *: "connected_component_set s x \<subseteq> s \<inter> closure (connected_component_set s x)"
   6.829 +    by (auto simp: closure_def connected_component_in)
   6.830 +  have "connected_component s x y \<Longrightarrow> s \<inter> closure (connected_component_set s x) \<subseteq> connected_component_set s x"
   6.831 +    apply (rule connected_component_maximal, simp)
   6.832 +    using closure_subset connected_component_in apply fastforce
   6.833 +    using * connected_intermediate_closure apply blast+
   6.834 +    done
   6.835 +  with y * show ?thesis
   6.836 +    by (auto simp: closedin_closed)
   6.837 +qed
   6.838 +
   6.839 +
   6.840 +subsection \<open>Intersecting chains of compact sets and the Baire property\<close>
   6.841 +
   6.842 +proposition bounded_closed_chain:
   6.843 +  fixes \<F> :: "'a::heine_borel set set"
   6.844 +  assumes "B \<in> \<F>" "bounded B" and \<F>: "\<And>S. S \<in> \<F> \<Longrightarrow> closed S" and "{} \<notin> \<F>"
   6.845 +      and chain: "\<And>S T. S \<in> \<F> \<and> T \<in> \<F> \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
   6.846 +    shows "\<Inter>\<F> \<noteq> {}"
   6.847 +proof -
   6.848 +  have "B \<inter> \<Inter>\<F> \<noteq> {}"
   6.849 +  proof (rule compact_imp_fip)
   6.850 +    show "compact B" "\<And>T. T \<in> \<F> \<Longrightarrow> closed T"
   6.851 +      by (simp_all add: assms compact_eq_bounded_closed)
   6.852 +    show "\<lbrakk>finite \<G>; \<G> \<subseteq> \<F>\<rbrakk> \<Longrightarrow> B \<inter> \<Inter>\<G> \<noteq> {}" for \<G>
   6.853 +    proof (induction \<G> rule: finite_induct)
   6.854 +      case empty
   6.855 +      with assms show ?case by force
   6.856 +    next
   6.857 +      case (insert U \<G>)
   6.858 +      then have "U \<in> \<F>" and ne: "B \<inter> \<Inter>\<G> \<noteq> {}" by auto
   6.859 +      then consider "B \<subseteq> U" | "U \<subseteq> B"
   6.860 +          using \<open>B \<in> \<F>\<close> chain by blast
   6.861 +        then show ?case
   6.862 +        proof cases
   6.863 +          case 1
   6.864 +          then show ?thesis
   6.865 +            using Int_left_commute ne by auto
   6.866 +        next
   6.867 +          case 2
   6.868 +          have "U \<noteq> {}"
   6.869 +            using \<open>U \<in> \<F>\<close> \<open>{} \<notin> \<F>\<close> by blast
   6.870 +          moreover
   6.871 +          have False if "\<And>x. x \<in> U \<Longrightarrow> \<exists>Y\<in>\<G>. x \<notin> Y"
   6.872 +          proof -
   6.873 +            have "\<And>x. x \<in> U \<Longrightarrow> \<exists>Y\<in>\<G>. Y \<subseteq> U"
   6.874 +              by (metis chain contra_subsetD insert.prems insert_subset that)
   6.875 +            then obtain Y where "Y \<in> \<G>" "Y \<subseteq> U"
   6.876 +              by (metis all_not_in_conv \<open>U \<noteq> {}\<close>)
   6.877 +            moreover obtain x where "x \<in> \<Inter>\<G>"
   6.878 +              by (metis Int_emptyI ne)
   6.879 +            ultimately show ?thesis
   6.880 +              by (metis Inf_lower subset_eq that)
   6.881 +          qed
   6.882 +          with 2 show ?thesis
   6.883 +            by blast
   6.884 +        qed
   6.885 +      qed
   6.886 +  qed
   6.887 +  then show ?thesis by blast
   6.888 +qed
   6.889 +
   6.890 +corollary compact_chain:
   6.891 +  fixes \<F> :: "'a::heine_borel set set"
   6.892 +  assumes "\<And>S. S \<in> \<F> \<Longrightarrow> compact S" "{} \<notin> \<F>"
   6.893 +          "\<And>S T. S \<in> \<F> \<and> T \<in> \<F> \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
   6.894 +    shows "\<Inter> \<F> \<noteq> {}"
   6.895 +proof (cases "\<F> = {}")
   6.896 +  case True
   6.897 +  then show ?thesis by auto
   6.898 +next
   6.899 +  case False
   6.900 +  show ?thesis
   6.901 +    by (metis False all_not_in_conv assms compact_imp_bounded compact_imp_closed bounded_closed_chain)
   6.902 +qed
   6.903 +
   6.904 +lemma compact_nest:
   6.905 +  fixes F :: "'a::linorder \<Rightarrow> 'b::heine_borel set"
   6.906 +  assumes F: "\<And>n. compact(F n)" "\<And>n. F n \<noteq> {}" and mono: "\<And>m n. m \<le> n \<Longrightarrow> F n \<subseteq> F m"
   6.907 +  shows "\<Inter>range F \<noteq> {}"
   6.908 +proof -
   6.909 +  have *: "\<And>S T. S \<in> range F \<and> T \<in> range F \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
   6.910 +    by (metis mono image_iff le_cases)
   6.911 +  show ?thesis
   6.912 +    apply (rule compact_chain [OF _ _ *])
   6.913 +    using F apply (blast intro: dest: *)+
   6.914 +    done
   6.915 +qed
   6.916 +
   6.917 +text\<open>The Baire property of dense sets\<close>
   6.918 +theorem Baire:
   6.919 +  fixes S::"'a::{real_normed_vector,heine_borel} set"
   6.920 +  assumes "closed S" "countable \<G>"
   6.921 +      and ope: "\<And>T. T \<in> \<G> \<Longrightarrow> openin (subtopology euclidean S) T \<and> S \<subseteq> closure T"
   6.922 + shows "S \<subseteq> closure(\<Inter>\<G>)"
   6.923 +proof (cases "\<G> = {}")
   6.924 +  case True
   6.925 +  then show ?thesis
   6.926 +    using closure_subset by auto
   6.927 +next
   6.928 +  let ?g = "from_nat_into \<G>"
   6.929 +  case False
   6.930 +  then have gin: "?g n \<in> \<G>" for n
   6.931 +    by (simp add: from_nat_into)
   6.932 +  show ?thesis
   6.933 +  proof (clarsimp simp: closure_approachable)
   6.934 +    fix x and e::real
   6.935 +    assume "x \<in> S" "0 < e"
   6.936 +    obtain TF where opeF: "\<And>n. openin (subtopology euclidean S) (TF n)"
   6.937 +               and ne: "\<And>n. TF n \<noteq> {}"
   6.938 +               and subg: "\<And>n. S \<inter> closure(TF n) \<subseteq> ?g n"
   6.939 +               and subball: "\<And>n. closure(TF n) \<subseteq> ball x e"
   6.940 +               and decr: "\<And>n. TF(Suc n) \<subseteq> TF n"
   6.941 +    proof -
   6.942 +      have *: "\<exists>Y. (openin (subtopology euclidean S) Y \<and> Y \<noteq> {} \<and>
   6.943 +                   S \<inter> closure Y \<subseteq> ?g n \<and> closure Y \<subseteq> ball x e) \<and> Y \<subseteq> U"
   6.944 +        if opeU: "openin (subtopology euclidean S) U" and "U \<noteq> {}" and cloU: "closure U \<subseteq> ball x e" for U n
   6.945 +      proof -
   6.946 +        obtain T where T: "open T" "U = T \<inter> S"
   6.947 +          using \<open>openin (subtopology euclidean S) U\<close> by (auto simp: openin_subtopology)
   6.948 +        with \<open>U \<noteq> {}\<close> have "T \<inter> closure (?g n) \<noteq> {}"
   6.949 +          using gin ope by fastforce
   6.950 +        then have "T \<inter> ?g n \<noteq> {}"
   6.951 +          using \<open>open T\<close> open_Int_closure_eq_empty by blast
   6.952 +        then obtain y where "y \<in> U" "y \<in> ?g n"
   6.953 +          using T ope [of "?g n", OF gin] by (blast dest:  openin_imp_subset)
   6.954 +        moreover have "openin (subtopology euclidean S) (U \<inter> ?g n)"
   6.955 +          using gin ope opeU by blast
   6.956 +        ultimately obtain d where U: "U \<inter> ?g n \<subseteq> S" and "d > 0" and d: "ball y d \<inter> S \<subseteq> U \<inter> ?g n"
   6.957 +          by (force simp: openin_contains_ball)
   6.958 +        show ?thesis
   6.959 +        proof (intro exI conjI)
   6.960 +          show "openin (subtopology euclidean S) (S \<inter> ball y (d/2))"
   6.961 +            by (simp add: openin_open_Int)
   6.962 +          show "S \<inter> ball y (d/2) \<noteq> {}"
   6.963 +            using \<open>0 < d\<close> \<open>y \<in> U\<close> opeU openin_imp_subset by fastforce
   6.964 +          have "S \<inter> closure (S \<inter> ball y (d/2)) \<subseteq> S \<inter> closure (ball y (d/2))"
   6.965 +            using closure_mono by blast
   6.966 +          also have "... \<subseteq> ?g n"
   6.967 +            using \<open>d > 0\<close> d by force
   6.968 +          finally show "S \<inter> closure (S \<inter> ball y (d/2)) \<subseteq> ?g n" .
   6.969 +          have "closure (S \<inter> ball y (d/2)) \<subseteq> S \<inter> ball y d"
   6.970 +          proof -
   6.971 +            have "closure (ball y (d/2)) \<subseteq> ball y d"
   6.972 +              using \<open>d > 0\<close> by auto
   6.973 +            then have "closure (S \<inter> ball y (d/2)) \<subseteq> ball y d"
   6.974 +              by (meson closure_mono inf.cobounded2 subset_trans)
   6.975 +            then show ?thesis
   6.976 +              by (simp add: \<open>closed S\<close> closure_minimal)
   6.977 +          qed
   6.978 +          also have "...  \<subseteq> ball x e"
   6.979 +            using cloU closure_subset d by blast
   6.980 +          finally show "closure (S \<inter> ball y (d/2)) \<subseteq> ball x e" .
   6.981 +          show "S \<inter> ball y (d/2) \<subseteq> U"
   6.982 +            using ball_divide_subset_numeral d by blast
   6.983 +        qed
   6.984 +      qed
   6.985 +      let ?\<Phi> = "\<lambda>n X. openin (subtopology euclidean S) X \<and> X \<noteq> {} \<and>
   6.986 +                      S \<inter> closure X \<subseteq> ?g n \<and> closure X \<subseteq> ball x e"
   6.987 +      have "closure (S \<inter> ball x (e / 2)) \<subseteq> closure(ball x (e/2))"
   6.988 +        by (simp add: closure_mono)
   6.989 +      also have "...  \<subseteq> ball x e"
   6.990 +        using \<open>e > 0\<close> by auto
   6.991 +      finally have "closure (S \<inter> ball x (e / 2)) \<subseteq> ball x e" .
   6.992 +      moreover have"openin (subtopology euclidean S) (S \<inter> ball x (e / 2))" "S \<inter> ball x (e / 2) \<noteq> {}"
   6.993 +        using \<open>0 < e\<close> \<open>x \<in> S\<close> by auto
   6.994 +      ultimately obtain Y where Y: "?\<Phi> 0 Y \<and> Y \<subseteq> S \<inter> ball x (e / 2)"
   6.995 +            using * [of "S \<inter> ball x (e/2)" 0] by metis
   6.996 +      show thesis
   6.997 +      proof (rule exE [OF dependent_nat_choice [of ?\<Phi> "\<lambda>n X Y. Y \<subseteq> X"]])
   6.998 +        show "\<exists>x. ?\<Phi> 0 x"
   6.999 +          using Y by auto
  6.1000 +        show "\<exists>Y. ?\<Phi> (Suc n) Y \<and> Y \<subseteq> X" if "?\<Phi> n X" for X n
  6.1001 +          using that by (blast intro: *)
  6.1002 +      qed (use that in metis)
  6.1003 +    qed
  6.1004 +    have "(\<Inter>n. S \<inter> closure (TF n)) \<noteq> {}"
  6.1005 +    proof (rule compact_nest)
  6.1006 +      show "\<And>n. compact (S \<inter> closure (TF n))"
  6.1007 +        by (metis closed_closure subball bounded_subset_ballI compact_eq_bounded_closed closed_Int_compact [OF \<open>closed S\<close>])
  6.1008 +      show "\<And>n. S \<inter> closure (TF n) \<noteq> {}"
  6.1009 +        by (metis Int_absorb1 opeF \<open>closed S\<close> closure_eq_empty closure_minimal ne openin_imp_subset)
  6.1010 +      show "\<And>m n. m \<le> n \<Longrightarrow> S \<inter> closure (TF n) \<subseteq> S \<inter> closure (TF m)"
  6.1011 +        by (meson closure_mono decr dual_order.refl inf_mono lift_Suc_antimono_le)
  6.1012 +    qed
  6.1013 +    moreover have "(\<Inter>n. S \<inter> closure (TF n)) \<subseteq> {y \<in> \<Inter>\<G>. dist y x < e}"
  6.1014 +    proof (clarsimp, intro conjI)
  6.1015 +      fix y
  6.1016 +      assume "y \<in> S" and y: "\<forall>n. y \<in> closure (TF n)"
  6.1017 +      then show "\<forall>T\<in>\<G>. y \<in> T"
  6.1018 +        by (metis Int_iff from_nat_into_surj [OF \<open>countable \<G>\<close>] set_mp subg)
  6.1019 +      show "dist y x < e"
  6.1020 +        by (metis y dist_commute mem_ball subball subsetCE)
  6.1021 +    qed
  6.1022 +    ultimately show "\<exists>y \<in> \<Inter>\<G>. dist y x < e"
  6.1023 +      by auto
  6.1024 +  qed
  6.1025 +qed
  6.1026 +
  6.1027 +subsection\<open>Some theorems on sups and infs using the notion "bounded".\<close>
  6.1028 +
  6.1029 +lemma bounded_real: "bounded (S::real set) \<longleftrightarrow> (\<exists>a. \<forall>x\<in>S. \<bar>x\<bar> \<le> a)"
  6.1030 +  by (simp add: bounded_iff)
  6.1031 +
  6.1032 +lemma bounded_imp_bdd_above: "bounded S \<Longrightarrow> bdd_above (S :: real set)"
  6.1033 +  by (auto simp: bounded_def bdd_above_def dist_real_def)
  6.1034 +     (metis abs_le_D1 abs_minus_commute diff_le_eq)
  6.1035 +
  6.1036 +lemma bounded_imp_bdd_below: "bounded S \<Longrightarrow> bdd_below (S :: real set)"
  6.1037 +  by (auto simp: bounded_def bdd_below_def dist_real_def)
  6.1038 +     (metis abs_le_D1 add.commute diff_le_eq)
  6.1039 +
  6.1040 +lemma bounded_inner_imp_bdd_above:
  6.1041 +  assumes "bounded s"
  6.1042 +    shows "bdd_above ((\<lambda>x. x \<bullet> a) ` s)"
  6.1043 +by (simp add: assms bounded_imp_bdd_above bounded_linear_image bounded_linear_inner_left)
  6.1044 +
  6.1045 +lemma bounded_inner_imp_bdd_below:
  6.1046 +  assumes "bounded s"
  6.1047 +    shows "bdd_below ((\<lambda>x. x \<bullet> a) ` s)"
  6.1048 +by (simp add: assms bounded_imp_bdd_below bounded_linear_image bounded_linear_inner_left)
  6.1049 +
  6.1050 +lemma bounded_has_Sup:
  6.1051 +  fixes S :: "real set"
  6.1052 +  assumes "bounded S"
  6.1053 +    and "S \<noteq> {}"
  6.1054 +  shows "\<forall>x\<in>S. x \<le> Sup S"
  6.1055 +    and "\<forall>b. (\<forall>x\<in>S. x \<le> b) \<longrightarrow> Sup S \<le> b"
  6.1056 +proof
  6.1057 +  show "\<forall>b. (\<forall>x\<in>S. x \<le> b) \<longrightarrow> Sup S \<le> b"
  6.1058 +    using assms by (metis cSup_least)
  6.1059 +qed (metis cSup_upper assms(1) bounded_imp_bdd_above)
  6.1060 +
  6.1061 +lemma Sup_insert:
  6.1062 +  fixes S :: "real set"
  6.1063 +  shows "bounded S \<Longrightarrow> Sup (insert x S) = (if S = {} then x else max x (Sup S))"
  6.1064 +  by (auto simp: bounded_imp_bdd_above sup_max cSup_insert_If)
  6.1065 +
  6.1066 +lemma Sup_insert_finite:
  6.1067 +  fixes S :: "'a::conditionally_complete_linorder set"
  6.1068 +  shows "finite S \<Longrightarrow> Sup (insert x S) = (if S = {} then x else max x (Sup S))"
  6.1069 +by (simp add: cSup_insert sup_max)
  6.1070 +
  6.1071 +lemma bounded_has_Inf:
  6.1072 +  fixes S :: "real set"
  6.1073 +  assumes "bounded S"
  6.1074 +    and "S \<noteq> {}"
  6.1075 +  shows "\<forall>x\<in>S. x \<ge> Inf S"
  6.1076 +    and "\<forall>b. (\<forall>x\<in>S. x \<ge> b) \<longrightarrow> Inf S \<ge> b"
  6.1077 +proof
  6.1078 +  show "\<forall>b. (\<forall>x\<in>S. x \<ge> b) \<longrightarrow> Inf S \<ge> b"
  6.1079 +    using assms by (metis cInf_greatest)
  6.1080 +qed (metis cInf_lower assms(1) bounded_imp_bdd_below)
  6.1081 +
  6.1082 +lemma Inf_insert:
  6.1083 +  fixes S :: "real set"
  6.1084 +  shows "bounded S \<Longrightarrow> Inf (insert x S) = (if S = {} then x else min x (Inf S))"
  6.1085 +  by (auto simp: bounded_imp_bdd_below inf_min cInf_insert_If)
  6.1086 +
  6.1087 +lemma Inf_insert_finite:
  6.1088 +  fixes S :: "'a::conditionally_complete_linorder set"
  6.1089 +  shows "finite S \<Longrightarrow> Inf (insert x S) = (if S = {} then x else min x (Inf S))"
  6.1090 +by (simp add: cInf_eq_Min)
  6.1091 +
  6.1092 +lemma finite_imp_less_Inf:
  6.1093 +  fixes a :: "'a::conditionally_complete_linorder"
  6.1094 +  shows "\<lbrakk>finite X; x \<in> X; \<And>x. x\<in>X \<Longrightarrow> a < x\<rbrakk> \<Longrightarrow> a < Inf X"
  6.1095 +  by (induction X rule: finite_induct) (simp_all add: cInf_eq_Min Inf_insert_finite)
  6.1096 +
  6.1097 +lemma finite_less_Inf_iff:
  6.1098 +  fixes a :: "'a :: conditionally_complete_linorder"
  6.1099 +  shows "\<lbrakk>finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> a < Inf X \<longleftrightarrow> (\<forall>x \<in> X. a < x)"
  6.1100 +  by (auto simp: cInf_eq_Min)
  6.1101 +
  6.1102 +lemma finite_imp_Sup_less:
  6.1103 +  fixes a :: "'a::conditionally_complete_linorder"
  6.1104 +  shows "\<lbrakk>finite X; x \<in> X; \<And>x. x\<in>X \<Longrightarrow> a > x\<rbrakk> \<Longrightarrow> a > Sup X"
  6.1105 +  by (induction X rule: finite_induct) (simp_all add: cSup_eq_Max Sup_insert_finite)
  6.1106 +
  6.1107 +lemma finite_Sup_less_iff:
  6.1108 +  fixes a :: "'a :: conditionally_complete_linorder"
  6.1109 +  shows "\<lbrakk>finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> a > Sup X \<longleftrightarrow> (\<forall>x \<in> X. a > x)"
  6.1110 +  by (auto simp: cSup_eq_Max)
  6.1111 +
  6.1112 +proposition is_interval_compact:
  6.1113 +   "is_interval S \<and> compact S \<longleftrightarrow> (\<exists>a b. S = cbox a b)"   (is "?lhs = ?rhs")
  6.1114 +proof (cases "S = {}")
  6.1115 +  case True
  6.1116 +  with empty_as_interval show ?thesis by auto
  6.1117 +next
  6.1118 +  case False
  6.1119 +  show ?thesis
  6.1120 +  proof
  6.1121 +    assume L: ?lhs
  6.1122 +    then have "is_interval S" "compact S" by auto
  6.1123 +    define a where "a \<equiv> \<Sum>i\<in>Basis. (INF x:S. x \<bullet> i) *\<^sub>R i"
  6.1124 +    define b where "b \<equiv> \<Sum>i\<in>Basis. (SUP x:S. x \<bullet> i) *\<^sub>R i"
  6.1125 +    have 1: "\<And>x i. \<lbrakk>x \<in> S; i \<in> Basis\<rbrakk> \<Longrightarrow> (INF x:S. x \<bullet> i) \<le> x \<bullet> i"
  6.1126 +      by (simp add: cInf_lower bounded_inner_imp_bdd_below compact_imp_bounded L)
  6.1127 +    have 2: "\<And>x i. \<lbrakk>x \<in> S; i \<in> Basis\<rbrakk> \<Longrightarrow> x \<bullet> i \<le> (SUP x:S. x \<bullet> i)"
  6.1128 +      by (simp add: cSup_upper bounded_inner_imp_bdd_above compact_imp_bounded L)
  6.1129 +    have 3: "x \<in> S" if inf: "\<And>i. i \<in> Basis \<Longrightarrow> (INF x:S. x \<bullet> i) \<le> x \<bullet> i"
  6.1130 +                   and sup: "\<And>i. i \<in> Basis \<Longrightarrow> x \<bullet> i \<le> (SUP x:S. x \<bullet> i)" for x
  6.1131 +    proof (rule mem_box_componentwiseI [OF \<open>is_interval S\<close>])
  6.1132 +      fix i::'a
  6.1133 +      assume i: "i \<in> Basis"
  6.1134 +      have cont: "continuous_on S (\<lambda>x. x \<bullet> i)"
  6.1135 +        by (intro continuous_intros)
  6.1136 +      obtain a where "a \<in> S" and a: "\<And>y. y\<in>S \<Longrightarrow> a \<bullet> i \<le> y \<bullet> i"
  6.1137 +        using continuous_attains_inf [OF \<open>compact S\<close> False cont] by blast
  6.1138 +      obtain b where "b \<in> S" and b: "\<And>y. y\<in>S \<Longrightarrow> y \<bullet> i \<le> b \<bullet> i"
  6.1139 +        using continuous_attains_sup [OF \<open>compact S\<close> False cont] by blast
  6.1140 +      have "a \<bullet> i \<le> (INF x:S. x \<bullet> i)"
  6.1141 +        by (simp add: False a cINF_greatest)
  6.1142 +      also have "\<dots> \<le> x \<bullet> i"
  6.1143 +        by (simp add: i inf)
  6.1144 +      finally have ai: "a \<bullet> i \<le> x \<bullet> i" .
  6.1145 +      have "x \<bullet> i \<le> (SUP x:S. x \<bullet> i)"
  6.1146 +        by (simp add: i sup)
  6.1147 +      also have "(SUP x:S. x \<bullet> i) \<le> b \<bullet> i"
  6.1148 +        by (simp add: False b cSUP_least)
  6.1149 +      finally have bi: "x \<bullet> i \<le> b \<bullet> i" .
  6.1150 +      show "x \<bullet> i \<in> (\<lambda>x. x \<bullet> i) ` S"
  6.1151 +        apply (rule_tac x="\<Sum>j\<in>Basis. (if j = i then x \<bullet> i else a \<bullet> j) *\<^sub>R j" in image_eqI)
  6.1152 +        apply (simp add: i)
  6.1153 +        apply (rule mem_is_intervalI [OF \<open>is_interval S\<close> \<open>a \<in> S\<close> \<open>b \<in> S\<close>])
  6.1154 +        using i ai bi apply force
  6.1155 +        done
  6.1156 +    qed
  6.1157 +    have "S = cbox a b"
  6.1158 +      by (auto simp: a_def b_def mem_box intro: 1 2 3)
  6.1159 +    then show ?rhs
  6.1160 +      by blast
  6.1161 +  next
  6.1162 +    assume R: ?rhs
  6.1163 +    then show ?lhs
  6.1164 +      using compact_cbox is_interval_cbox by blast
  6.1165 +  qed
  6.1166 +qed
  6.1167 +
  6.1168 +subsection\<open>Relations among convergence and absolute convergence for power series.\<close>
  6.1169 +
  6.1170 +lemma summable_imp_bounded:
  6.1171 +  fixes f :: "nat \<Rightarrow> 'a::real_normed_vector"
  6.1172 +  shows "summable f \<Longrightarrow> bounded (range f)"
  6.1173 +by (frule summable_LIMSEQ_zero) (simp add: convergent_imp_bounded)
  6.1174 +
  6.1175 +lemma summable_imp_sums_bounded:
  6.1176 +   "summable f \<Longrightarrow> bounded (range (\<lambda>n. sum f {..<n}))"
  6.1177 +by (auto simp: summable_def sums_def dest: convergent_imp_bounded)
  6.1178 +
  6.1179 +lemma power_series_conv_imp_absconv_weak:
  6.1180 +  fixes a:: "nat \<Rightarrow> 'a::{real_normed_div_algebra,banach}" and w :: 'a
  6.1181 +  assumes sum: "summable (\<lambda>n. a n * z ^ n)" and no: "norm w < norm z"
  6.1182 +    shows "summable (\<lambda>n. of_real(norm(a n)) * w ^ n)"
  6.1183 +proof -
  6.1184 +  obtain M where M: "\<And>x. norm (a x * z ^ x) \<le> M"
  6.1185 +    using summable_imp_bounded [OF sum] by (force simp: bounded_iff)
  6.1186 +  then have *: "summable (\<lambda>n. norm (a n) * norm w ^ n)"
  6.1187 +    by (rule_tac M=M in Abel_lemma) (auto simp: norm_mult norm_power intro: no)
  6.1188 +  show ?thesis
  6.1189 +    apply (rule series_comparison_complex [of "(\<lambda>n. of_real(norm(a n) * norm w ^ n))"])
  6.1190 +    apply (simp only: summable_complex_of_real *)
  6.1191 +    apply (auto simp: norm_mult norm_power)
  6.1192 +    done
  6.1193 +qed
  6.1194 +
  6.1195 +subsection \<open>Bounded closed nest property (proof does not use Heine-Borel)\<close>
  6.1196 +
  6.1197 +lemma bounded_closed_nest:
  6.1198 +  fixes s :: "nat \<Rightarrow> ('a::heine_borel) set"
  6.1199 +  assumes "\<forall>n. closed (s n)"
  6.1200 +    and "\<forall>n. s n \<noteq> {}"
  6.1201 +    and "\<forall>m n. m \<le> n \<longrightarrow> s n \<subseteq> s m"
  6.1202 +    and "bounded (s 0)"
  6.1203 +  shows "\<exists>a. \<forall>n. a \<in> s n"
  6.1204 +proof -
  6.1205 +  from assms(2) obtain x where x: "\<forall>n. x n \<in> s n"
  6.1206 +    using choice[of "\<lambda>n x. x \<in> s n"] by auto
  6.1207 +  from assms(4,1) have "seq_compact (s 0)"
  6.1208 +    by (simp add: bounded_closed_imp_seq_compact)
  6.1209 +  then obtain l r where lr: "l \<in> s 0" "strict_mono r" "(x \<circ> r) \<longlonglongrightarrow> l"
  6.1210 +    using x and assms(3) unfolding seq_compact_def by blast
  6.1211 +  have "\<forall>n. l \<in> s n"
  6.1212 +  proof
  6.1213 +    fix n :: nat
  6.1214 +    have "closed (s n)"
  6.1215 +      using assms(1) by simp
  6.1216 +    moreover have "\<forall>i. (x \<circ> r) i \<in> s i"
  6.1217 +      using x and assms(3) and lr(2) [THEN seq_suble] by auto
  6.1218 +    then have "\<forall>i. (x \<circ> r) (i + n) \<in> s n"
  6.1219 +      using assms(3) by (fast intro!: le_add2)
  6.1220 +    moreover have "(\<lambda>i. (x \<circ> r) (i + n)) \<longlonglongrightarrow> l"
  6.1221 +      using lr(3) by (rule LIMSEQ_ignore_initial_segment)
  6.1222 +    ultimately show "l \<in> s n"
  6.1223 +      by (rule closed_sequentially)
  6.1224 +  qed
  6.1225 +  then show ?thesis ..
  6.1226 +qed
  6.1227 +
  6.1228 +text \<open>Decreasing case does not even need compactness, just completeness.\<close>
  6.1229 +
  6.1230 +lemma decreasing_closed_nest:
  6.1231 +  fixes s :: "nat \<Rightarrow> ('a::complete_space) set"
  6.1232 +  assumes
  6.1233 +    "\<forall>n. closed (s n)"
  6.1234 +    "\<forall>n. s n \<noteq> {}"
  6.1235 +    "\<forall>m n. m \<le> n \<longrightarrow> s n \<subseteq> s m"
  6.1236 +    "\<forall>e>0. \<exists>n. \<forall>x\<in>s n. \<forall>y\<in>s n. dist x y < e"
  6.1237 +  shows "\<exists>a. \<forall>n. a \<in> s n"
  6.1238 +proof -
  6.1239 +  have "\<forall>n. \<exists>x. x \<in> s n"
  6.1240 +    using assms(2) by auto
  6.1241 +  then have "\<exists>t. \<forall>n. t n \<in> s n"
  6.1242 +    using choice[of "\<lambda>n x. x \<in> s n"] by auto
  6.1243 +  then obtain t where t: "\<forall>n. t n \<in> s n" by auto
  6.1244 +  {
  6.1245 +    fix e :: real
  6.1246 +    assume "e > 0"
  6.1247 +    then obtain N where N:"\<forall>x\<in>s N. \<forall>y\<in>s N. dist x y < e"
  6.1248 +      using assms(4) by auto
  6.1249 +    {
  6.1250 +      fix m n :: nat
  6.1251 +      assume "N \<le> m \<and> N \<le> n"
  6.1252 +      then have "t m \<in> s N" "t n \<in> s N"
  6.1253 +        using assms(3) t unfolding  subset_eq t by blast+
  6.1254 +      then have "dist (t m) (t n) < e"
  6.1255 +        using N by auto
  6.1256 +    }
  6.1257 +    then have "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (t m) (t n) < e"
  6.1258 +      by auto
  6.1259 +  }
  6.1260 +  then have "Cauchy t"
  6.1261 +    unfolding cauchy_def by auto
  6.1262 +  then obtain l where l:"(t \<longlongrightarrow> l) sequentially"
  6.1263 +    using complete_UNIV unfolding complete_def by auto
  6.1264 +  {
  6.1265 +    fix n :: nat
  6.1266 +    {
  6.1267 +      fix e :: real
  6.1268 +      assume "e > 0"
  6.1269 +      then obtain N :: nat where N: "\<forall>n\<ge>N. dist (t n) l < e"
  6.1270 +        using l[unfolded lim_sequentially] by auto
  6.1271 +      have "t (max n N) \<in> s n"
  6.1272 +        using assms(3)
  6.1273 +        unfolding subset_eq
  6.1274 +        apply (erule_tac x=n in allE)
  6.1275 +        apply (erule_tac x="max n N" in allE)
  6.1276 +        using t
  6.1277 +        apply auto
  6.1278 +        done
  6.1279 +      then have "\<exists>y\<in>s n. dist y l < e"
  6.1280 +        apply (rule_tac x="t (max n N)" in bexI)
  6.1281 +        using N
  6.1282 +        apply auto
  6.1283 +        done
  6.1284 +    }
  6.1285 +    then have "l \<in> s n"
  6.1286 +      using closed_approachable[of "s n" l] assms(1) by auto
  6.1287 +  }
  6.1288 +  then show ?thesis by auto
  6.1289 +qed
  6.1290 +
  6.1291 +text \<open>Strengthen it to the intersection actually being a singleton.\<close>
  6.1292 +
  6.1293 +lemma decreasing_closed_nest_sing:
  6.1294 +  fixes s :: "nat \<Rightarrow> 'a::complete_space set"
  6.1295 +  assumes
  6.1296 +    "\<forall>n. closed(s n)"
  6.1297 +    "\<forall>n. s n \<noteq> {}"
  6.1298 +    "\<forall>m n. m \<le> n \<longrightarrow> s n \<subseteq> s m"
  6.1299 +    "\<forall>e>0. \<exists>n. \<forall>x \<in> (s n). \<forall> y\<in>(s n). dist x y < e"
  6.1300 +  shows "\<exists>a. \<Inter>(range s) = {a}"
  6.1301 +proof -
  6.1302 +  obtain a where a: "\<forall>n. a \<in> s n"
  6.1303 +    using decreasing_closed_nest[of s] using assms by auto
  6.1304 +  {
  6.1305 +    fix b
  6.1306 +    assume b: "b \<in> \<Inter>(range s)"
  6.1307 +    {
  6.1308 +      fix e :: real
  6.1309 +      assume "e > 0"
  6.1310 +      then have "dist a b < e"
  6.1311 +        using assms(4) and b and a by blast
  6.1312 +    }
  6.1313 +    then have "dist a b = 0"
  6.1314 +      by (metis dist_eq_0_iff dist_nz less_le)
  6.1315 +  }
  6.1316 +  with a have "\<Inter>(range s) = {a}"
  6.1317 +    unfolding image_def by auto
  6.1318 +  then show ?thesis ..
  6.1319 +qed
  6.1320 +
  6.1321 +
  6.1322 +subsection \<open>Infimum Distance\<close>
  6.1323 +
  6.1324 +definition "infdist x A = (if A = {} then 0 else INF a:A. dist x a)"
  6.1325 +
  6.1326 +lemma bdd_below_infdist[intro, simp]: "bdd_below (dist x`A)"
  6.1327 +  by (auto intro!: zero_le_dist)
  6.1328 +
  6.1329 +lemma infdist_notempty: "A \<noteq> {} \<Longrightarrow> infdist x A = (INF a:A. dist x a)"
  6.1330 +  by (simp add: infdist_def)
  6.1331 +
  6.1332 +lemma infdist_nonneg: "0 \<le> infdist x A"
  6.1333 +  by (auto simp: infdist_def intro: cINF_greatest)
  6.1334 +
  6.1335 +lemma infdist_le: "a \<in> A \<Longrightarrow> infdist x A \<le> dist x a"
  6.1336 +  by (auto intro: cINF_lower simp add: infdist_def)
  6.1337 +
  6.1338 +lemma infdist_le2: "a \<in> A \<Longrightarrow> dist x a \<le> d \<Longrightarrow> infdist x A \<le> d"
  6.1339 +  by (auto intro!: cINF_lower2 simp add: infdist_def)
  6.1340 +
  6.1341 +lemma infdist_zero[simp]: "a \<in> A \<Longrightarrow> infdist a A = 0"
  6.1342 +  by (auto intro!: antisym infdist_nonneg infdist_le2)
  6.1343 +
  6.1344 +lemma infdist_triangle: "infdist x A \<le> infdist y A + dist x y"
  6.1345 +proof (cases "A = {}")
  6.1346 +  case True
  6.1347 +  then show ?thesis by (simp add: infdist_def)
  6.1348 +next
  6.1349 +  case False
  6.1350 +  then obtain a where "a \<in> A" by auto
  6.1351 +  have "infdist x A \<le> Inf {dist x y + dist y a |a. a \<in> A}"
  6.1352 +  proof (rule cInf_greatest)
  6.1353 +    from \<open>A \<noteq> {}\<close> show "{dist x y + dist y a |a. a \<in> A} \<noteq> {}"
  6.1354 +      by simp
  6.1355 +    fix d
  6.1356 +    assume "d \<in> {dist x y + dist y a |a. a \<in> A}"
  6.1357 +    then obtain a where d: "d = dist x y + dist y a" "a \<in> A"
  6.1358 +      by auto
  6.1359 +    show "infdist x A \<le> d"
  6.1360 +      unfolding infdist_notempty[OF \<open>A \<noteq> {}\<close>]
  6.1361 +    proof (rule cINF_lower2)
  6.1362 +      show "a \<in> A" by fact
  6.1363 +      show "dist x a \<le> d"
  6.1364 +        unfolding d by (rule dist_triangle)
  6.1365 +    qed simp
  6.1366 +  qed
  6.1367 +  also have "\<dots> = dist x y + infdist y A"
  6.1368 +  proof (rule cInf_eq, safe)
  6.1369 +    fix a
  6.1370 +    assume "a \<in> A"
  6.1371 +    then show "dist x y + infdist y A \<le> dist x y + dist y a"
  6.1372 +      by (auto intro: infdist_le)
  6.1373 +  next
  6.1374 +    fix i
  6.1375 +    assume inf: "\<And>d. d \<in> {dist x y + dist y a |a. a \<in> A} \<Longrightarrow> i \<le> d"
  6.1376 +    then have "i - dist x y \<le> infdist y A"
  6.1377 +      unfolding infdist_notempty[OF \<open>A \<noteq> {}\<close>] using \<open>a \<in> A\<close>
  6.1378 +      by (intro cINF_greatest) (auto simp: field_simps)
  6.1379 +    then show "i \<le> dist x y + infdist y A"
  6.1380 +      by simp
  6.1381 +  qed
  6.1382 +  finally show ?thesis by simp
  6.1383 +qed
  6.1384 +
  6.1385 +lemma in_closure_iff_infdist_zero:
  6.1386 +  assumes "A \<noteq> {}"
  6.1387 +  shows "x \<in> closure A \<longleftrightarrow> infdist x A = 0"
  6.1388 +proof
  6.1389 +  assume "x \<in> closure A"
  6.1390 +  show "infdist x A = 0"
  6.1391 +  proof (rule ccontr)
  6.1392 +    assume "infdist x A \<noteq> 0"
  6.1393 +    with infdist_nonneg[of x A] have "infdist x A > 0"
  6.1394 +      by auto
  6.1395 +    then have "ball x (infdist x A) \<inter> closure A = {}"
  6.1396 +      apply auto
  6.1397 +      apply (metis \<open>x \<in> closure A\<close> closure_approachable dist_commute infdist_le not_less)
  6.1398 +      done
  6.1399 +    then have "x \<notin> closure A"
  6.1400 +      by (metis \<open>0 < infdist x A\<close> centre_in_ball disjoint_iff_not_equal)
  6.1401 +    then show False using \<open>x \<in> closure A\<close> by simp
  6.1402 +  qed
  6.1403 +next
  6.1404 +  assume x: "infdist x A = 0"
  6.1405 +  then obtain a where "a \<in> A"
  6.1406 +    by atomize_elim (metis all_not_in_conv assms)
  6.1407 +  show "x \<in> closure A"
  6.1408 +    unfolding closure_approachable
  6.1409 +    apply safe
  6.1410 +  proof (rule ccontr)
  6.1411 +    fix e :: real
  6.1412 +    assume "e > 0"
  6.1413 +    assume "\<not> (\<exists>y\<in>A. dist y x < e)"
  6.1414 +    then have "infdist x A \<ge> e" using \<open>a \<in> A\<close>
  6.1415 +      unfolding infdist_def
  6.1416 +      by (force simp: dist_commute intro: cINF_greatest)
  6.1417 +    with x \<open>e > 0\<close> show False by auto
  6.1418 +  qed
  6.1419 +qed
  6.1420 +
  6.1421 +lemma in_closed_iff_infdist_zero:
  6.1422 +  assumes "closed A" "A \<noteq> {}"
  6.1423 +  shows "x \<in> A \<longleftrightarrow> infdist x A = 0"
  6.1424 +proof -
  6.1425 +  have "x \<in> closure A \<longleftrightarrow> infdist x A = 0"
  6.1426 +    by (rule in_closure_iff_infdist_zero) fact
  6.1427 +  with assms show ?thesis by simp
  6.1428 +qed
  6.1429 +
  6.1430 +lemma tendsto_infdist [tendsto_intros]:
  6.1431 +  assumes f: "(f \<longlongrightarrow> l) F"
  6.1432 +  shows "((\<lambda>x. infdist (f x) A) \<longlongrightarrow> infdist l A) F"
  6.1433 +proof (rule tendstoI)
  6.1434 +  fix e ::real
  6.1435 +  assume "e > 0"
  6.1436 +  from tendstoD[OF f this]
  6.1437 +  show "eventually (\<lambda>x. dist (infdist (f x) A) (infdist l A) < e) F"
  6.1438 +  proof (eventually_elim)
  6.1439 +    fix x
  6.1440 +    from infdist_triangle[of l A "f x"] infdist_triangle[of "f x" A l]
  6.1441 +    have "dist (infdist (f x) A) (infdist l A) \<le> dist (f x) l"
  6.1442 +      by (simp add: dist_commute dist_real_def)
  6.1443 +    also assume "dist (f x) l < e"
  6.1444 +    finally show "dist (infdist (f x) A) (infdist l A) < e" .
  6.1445 +  qed
  6.1446 +qed
  6.1447 +
  6.1448 +lemma continuous_infdist[continuous_intros]:
  6.1449 +  assumes "continuous F f"
  6.1450 +  shows "continuous F (\<lambda>x. infdist (f x) A)"
  6.1451 +  using assms unfolding continuous_def by (rule tendsto_infdist)
  6.1452 +
  6.1453 +subsection \<open>Equality of continuous functions on closure and related results.\<close>
  6.1454 +
  6.1455 +lemma continuous_closedin_preimage_constant:
  6.1456 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.1457 +  shows "continuous_on s f \<Longrightarrow> closedin (subtopology euclidean s) {x \<in> s. f x = a}"
  6.1458 +  using continuous_closedin_preimage[of s f "{a}"] by auto
  6.1459 +
  6.1460 +lemma continuous_closed_preimage_constant:
  6.1461 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.1462 +  shows "continuous_on s f \<Longrightarrow> closed s \<Longrightarrow> closed {x \<in> s. f x = a}"
  6.1463 +  using continuous_closed_preimage[of s f "{a}"] by auto
  6.1464 +
  6.1465 +lemma continuous_constant_on_closure:
  6.1466 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.1467 +  assumes "continuous_on (closure S) f"
  6.1468 +      and "\<And>x. x \<in> S \<Longrightarrow> f x = a"
  6.1469 +      and "x \<in> closure S"
  6.1470 +  shows "f x = a"
  6.1471 +    using continuous_closed_preimage_constant[of "closure S" f a]
  6.1472 +      assms closure_minimal[of S "{x \<in> closure S. f x = a}"] closure_subset
  6.1473 +    unfolding subset_eq
  6.1474 +    by auto
  6.1475 +
  6.1476 +lemma image_closure_subset:
  6.1477 +  assumes "continuous_on (closure s) f"
  6.1478 +    and "closed t"
  6.1479 +    and "(f ` s) \<subseteq> t"
  6.1480 +  shows "f ` (closure s) \<subseteq> t"
  6.1481 +proof -
  6.1482 +  have "s \<subseteq> {x \<in> closure s. f x \<in> t}"
  6.1483 +    using assms(3) closure_subset by auto
  6.1484 +  moreover have "closed {x \<in> closure s. f x \<in> t}"
  6.1485 +    using continuous_closed_preimage[OF assms(1)] and assms(2) by auto
  6.1486 +  ultimately have "closure s = {x \<in> closure s . f x \<in> t}"
  6.1487 +    using closure_minimal[of s "{x \<in> closure s. f x \<in> t}"] by auto
  6.1488 +  then show ?thesis by auto
  6.1489 +qed
  6.1490 +
  6.1491 +lemma continuous_on_closure_norm_le:
  6.1492 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  6.1493 +  assumes "continuous_on (closure s) f"
  6.1494 +    and "\<forall>y \<in> s. norm(f y) \<le> b"
  6.1495 +    and "x \<in> (closure s)"
  6.1496 +  shows "norm (f x) \<le> b"
  6.1497 +proof -
  6.1498 +  have *: "f ` s \<subseteq> cball 0 b"
  6.1499 +    using assms(2)[unfolded mem_cball_0[symmetric]] by auto
  6.1500 +  show ?thesis
  6.1501 +    using image_closure_subset[OF assms(1) closed_cball[of 0 b] *] assms(3)
  6.1502 +    unfolding subset_eq
  6.1503 +    apply (erule_tac x="f x" in ballE)
  6.1504 +    apply (auto simp: dist_norm)
  6.1505 +    done
  6.1506 +qed
  6.1507 +
  6.1508 +lemma isCont_indicator:
  6.1509 +  fixes x :: "'a::t2_space"
  6.1510 +  shows "isCont (indicator A :: 'a \<Rightarrow> real) x = (x \<notin> frontier A)"
  6.1511 +proof auto
  6.1512 +  fix x
  6.1513 +  assume cts_at: "isCont (indicator A :: 'a \<Rightarrow> real) x" and fr: "x \<in> frontier A"
  6.1514 +  with continuous_at_open have 1: "\<forall>V::real set. open V \<and> indicator A x \<in> V \<longrightarrow>
  6.1515 +    (\<exists>U::'a set. open U \<and> x \<in> U \<and> (\<forall>y\<in>U. indicator A y \<in> V))" by auto
  6.1516 +  show False
  6.1517 +  proof (cases "x \<in> A")
  6.1518 +    assume x: "x \<in> A"
  6.1519 +    hence "indicator A x \<in> ({0<..<2} :: real set)" by simp
  6.1520 +    hence "\<exists>U. open U \<and> x \<in> U \<and> (\<forall>y\<in>U. indicator A y \<in> ({0<..<2} :: real set))"
  6.1521 +      using 1 open_greaterThanLessThan by blast
  6.1522 +    then guess U .. note U = this
  6.1523 +    hence "\<forall>y\<in>U. indicator A y > (0::real)"
  6.1524 +      unfolding greaterThanLessThan_def by auto
  6.1525 +    hence "U \<subseteq> A" using indicator_eq_0_iff by force
  6.1526 +    hence "x \<in> interior A" using U interiorI by auto
  6.1527 +    thus ?thesis using fr unfolding frontier_def by simp
  6.1528 +  next
  6.1529 +    assume x: "x \<notin> A"
  6.1530 +    hence "indicator A x \<in> ({-1<..<1} :: real set)" by simp
  6.1531 +    hence "\<exists>U. open U \<and> x \<in> U \<and> (\<forall>y\<in>U. indicator A y \<in> ({-1<..<1} :: real set))"
  6.1532 +      using 1 open_greaterThanLessThan by blast
  6.1533 +    then guess U .. note U = this
  6.1534 +    hence "\<forall>y\<in>U. indicator A y < (1::real)"
  6.1535 +      unfolding greaterThanLessThan_def by auto
  6.1536 +    hence "U \<subseteq> -A" by auto
  6.1537 +    hence "x \<in> interior (-A)" using U interiorI by auto
  6.1538 +    thus ?thesis using fr interior_complement unfolding frontier_def by auto
  6.1539 +  qed
  6.1540 +next
  6.1541 +  assume nfr: "x \<notin> frontier A"
  6.1542 +  hence "x \<in> interior A \<or> x \<in> interior (-A)"
  6.1543 +    by (auto simp: frontier_def closure_interior)
  6.1544 +  thus "isCont ((indicator A)::'a \<Rightarrow> real) x"
  6.1545 +  proof
  6.1546 +    assume int: "x \<in> interior A"
  6.1547 +    then obtain U where U: "open U" "x \<in> U" "U \<subseteq> A" unfolding interior_def by auto
  6.1548 +    hence "\<forall>y\<in>U. indicator A y = (1::real)" unfolding indicator_def by auto
  6.1549 +    hence "continuous_on U (indicator A)" by (simp add: continuous_on_const indicator_eq_1_iff)
  6.1550 +    thus ?thesis using U continuous_on_eq_continuous_at by auto
  6.1551 +  next
  6.1552 +    assume ext: "x \<in> interior (-A)"
  6.1553 +    then obtain U where U: "open U" "x \<in> U" "U \<subseteq> -A" unfolding interior_def by auto
  6.1554 +    then have "continuous_on U (indicator A)"
  6.1555 +      using continuous_on_topological by (auto simp: subset_iff)
  6.1556 +    thus ?thesis using U continuous_on_eq_continuous_at by auto
  6.1557 +  qed
  6.1558 +qed
  6.1559 +
  6.1560 +subsection \<open>A function constant on a set\<close>
  6.1561 +
  6.1562 +definition constant_on  (infixl "(constant'_on)" 50)
  6.1563 +  where "f constant_on A \<equiv> \<exists>y. \<forall>x\<in>A. f x = y"
  6.1564 +
  6.1565 +lemma constant_on_subset: "\<lbrakk>f constant_on A; B \<subseteq> A\<rbrakk> \<Longrightarrow> f constant_on B"
  6.1566 +  unfolding constant_on_def by blast
  6.1567 +
  6.1568 +lemma injective_not_constant:
  6.1569 +  fixes S :: "'a::{perfect_space} set"
  6.1570 +  shows "\<lbrakk>open S; inj_on f S; f constant_on S\<rbrakk> \<Longrightarrow> S = {}"
  6.1571 +unfolding constant_on_def
  6.1572 +by (metis equals0I inj_on_contraD islimpt_UNIV islimpt_def)
  6.1573 +
  6.1574 +lemma constant_on_closureI:
  6.1575 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.1576 +  assumes cof: "f constant_on S" and contf: "continuous_on (closure S) f"
  6.1577 +    shows "f constant_on (closure S)"
  6.1578 +using continuous_constant_on_closure [OF contf] cof unfolding constant_on_def
  6.1579 +by metis
  6.1580 +
  6.1581 +subsection\<open>Relating linear images to open/closed/interior/closure\<close>
  6.1582 +
  6.1583 +proposition open_surjective_linear_image:
  6.1584 +  fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::euclidean_space"
  6.1585 +  assumes "open A" "linear f" "surj f"
  6.1586 +    shows "open(f ` A)"
  6.1587 +unfolding open_dist
  6.1588 +proof clarify
  6.1589 +  fix x
  6.1590 +  assume "x \<in> A"
  6.1591 +  have "bounded (inv f ` Basis)"
  6.1592 +    by (simp add: finite_imp_bounded)
  6.1593 +  with bounded_pos obtain B where "B > 0" and B: "\<And>x. x \<in> inv f ` Basis \<Longrightarrow> norm x \<le> B"
  6.1594 +    by metis
  6.1595 +  obtain e where "e > 0" and e: "\<And>z. dist z x < e \<Longrightarrow> z \<in> A"
  6.1596 +    by (metis open_dist \<open>x \<in> A\<close> \<open>open A\<close>)
  6.1597 +  define \<delta> where "\<delta> \<equiv> e / B / DIM('b)"
  6.1598 +  show "\<exists>e>0. \<forall>y. dist y (f x) < e \<longrightarrow> y \<in> f ` A"
  6.1599 +  proof (intro exI conjI)
  6.1600 +    show "\<delta> > 0"
  6.1601 +      using \<open>e > 0\<close> \<open>B > 0\<close>  by (simp add: \<delta>_def divide_simps)
  6.1602 +    have "y \<in> f ` A" if "dist y (f x) * (B * real DIM('b)) < e" for y
  6.1603 +    proof -
  6.1604 +      define u where "u \<equiv> y - f x"
  6.1605 +      show ?thesis
  6.1606 +      proof (rule image_eqI)
  6.1607 +        show "y = f (x + (\<Sum>i\<in>Basis. (u \<bullet> i) *\<^sub>R inv f i))"
  6.1608 +          apply (simp add: linear_add linear_sum linear.scaleR \<open>linear f\<close> surj_f_inv_f \<open>surj f\<close>)
  6.1609 +          apply (simp add: euclidean_representation u_def)
  6.1610 +          done
  6.1611 +        have "dist (x + (\<Sum>i\<in>Basis. (u \<bullet> i) *\<^sub>R inv f i)) x \<le> (\<Sum>i\<in>Basis. norm ((u \<bullet> i) *\<^sub>R inv f i))"
  6.1612 +          by (simp add: dist_norm sum_norm_le)
  6.1613 +        also have "... = (\<Sum>i\<in>Basis. \<bar>u \<bullet> i\<bar> * norm (inv f i))"
  6.1614 +          by simp
  6.1615 +        also have "... \<le> (\<Sum>i\<in>Basis. \<bar>u \<bullet> i\<bar>) * B"
  6.1616 +          by (simp add: B sum_distrib_right sum_mono mult_left_mono)
  6.1617 +        also have "... \<le> DIM('b) * dist y (f x) * B"
  6.1618 +          apply (rule mult_right_mono [OF sum_bounded_above])
  6.1619 +          using \<open>0 < B\<close> by (auto simp: Basis_le_norm dist_norm u_def)
  6.1620 +        also have "... < e"
  6.1621 +          by (metis mult.commute mult.left_commute that)
  6.1622 +        finally show "x + (\<Sum>i\<in>Basis. (u \<bullet> i) *\<^sub>R inv f i) \<in> A"
  6.1623 +          by (rule e)
  6.1624 +      qed
  6.1625 +    qed
  6.1626 +    then show "\<forall>y. dist y (f x) < \<delta> \<longrightarrow> y \<in> f ` A"
  6.1627 +      using \<open>e > 0\<close> \<open>B > 0\<close>
  6.1628 +      by (auto simp: \<delta>_def divide_simps mult_less_0_iff)
  6.1629 +  qed
  6.1630 +qed
  6.1631 +
  6.1632 +corollary open_bijective_linear_image_eq:
  6.1633 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  6.1634 +  assumes "linear f" "bij f"
  6.1635 +    shows "open(f ` A) \<longleftrightarrow> open A"
  6.1636 +proof
  6.1637 +  assume "open(f ` A)"
  6.1638 +  then have "open(f -` (f ` A))"
  6.1639 +    using assms by (force simp: linear_continuous_at linear_conv_bounded_linear continuous_open_vimage)
  6.1640 +  then show "open A"
  6.1641 +    by (simp add: assms bij_is_inj inj_vimage_image_eq)
  6.1642 +next
  6.1643 +  assume "open A"
  6.1644 +  then show "open(f ` A)"
  6.1645 +    by (simp add: assms bij_is_surj open_surjective_linear_image)
  6.1646 +qed
  6.1647 +
  6.1648 +corollary interior_bijective_linear_image:
  6.1649 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  6.1650 +  assumes "linear f" "bij f"
  6.1651 +  shows "interior (f ` S) = f ` interior S"  (is "?lhs = ?rhs")
  6.1652 +proof safe
  6.1653 +  fix x
  6.1654 +  assume x: "x \<in> ?lhs"
  6.1655 +  then obtain T where "open T" and "x \<in> T" and "T \<subseteq> f ` S"
  6.1656 +    by (metis interiorE)
  6.1657 +  then show "x \<in> ?rhs"
  6.1658 +    by (metis (no_types, hide_lams) assms subsetD interior_maximal open_bijective_linear_image_eq subset_image_iff)
  6.1659 +next
  6.1660 +  fix x
  6.1661 +  assume x: "x \<in> interior S"
  6.1662 +  then show "f x \<in> interior (f ` S)"
  6.1663 +    by (meson assms imageI image_mono interiorI interior_subset open_bijective_linear_image_eq open_interior)
  6.1664 +qed
  6.1665 +
  6.1666 +lemma interior_injective_linear_image:
  6.1667 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'a::euclidean_space"
  6.1668 +  assumes "linear f" "inj f"
  6.1669 +   shows "interior(f ` S) = f ` (interior S)"
  6.1670 +  by (simp add: linear_injective_imp_surjective assms bijI interior_bijective_linear_image)
  6.1671 +
  6.1672 +lemma interior_surjective_linear_image:
  6.1673 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'a::euclidean_space"
  6.1674 +  assumes "linear f" "surj f"
  6.1675 +   shows "interior(f ` S) = f ` (interior S)"
  6.1676 +  by (simp add: assms interior_injective_linear_image linear_surjective_imp_injective)
  6.1677 +
  6.1678 +lemma interior_negations:
  6.1679 +  fixes S :: "'a::euclidean_space set"
  6.1680 +  shows "interior(uminus ` S) = image uminus (interior S)"
  6.1681 +  by (simp add: bij_uminus interior_bijective_linear_image linear_uminus)
  6.1682 +
  6.1683 +text \<open>Preservation of compactness and connectedness under continuous function.\<close>
  6.1684 +
  6.1685 +lemma compact_eq_openin_cover:
  6.1686 +  "compact S \<longleftrightarrow>
  6.1687 +    (\<forall>C. (\<forall>c\<in>C. openin (subtopology euclidean S) c) \<and> S \<subseteq> \<Union>C \<longrightarrow>
  6.1688 +      (\<exists>D\<subseteq>C. finite D \<and> S \<subseteq> \<Union>D))"
  6.1689 +proof safe
  6.1690 +  fix C
  6.1691 +  assume "compact S" and "\<forall>c\<in>C. openin (subtopology euclidean S) c" and "S \<subseteq> \<Union>C"
  6.1692 +  then have "\<forall>c\<in>{T. open T \<and> S \<inter> T \<in> C}. open c" and "S \<subseteq> \<Union>{T. open T \<and> S \<inter> T \<in> C}"
  6.1693 +    unfolding openin_open by force+
  6.1694 +  with \<open>compact S\<close> obtain D where "D \<subseteq> {T. open T \<and> S \<inter> T \<in> C}" and "finite D" and "S \<subseteq> \<Union>D"
  6.1695 +    by (meson compactE)
  6.1696 +  then have "image (\<lambda>T. S \<inter> T) D \<subseteq> C \<and> finite (image (\<lambda>T. S \<inter> T) D) \<and> S \<subseteq> \<Union>(image (\<lambda>T. S \<inter> T) D)"
  6.1697 +    by auto
  6.1698 +  then show "\<exists>D\<subseteq>C. finite D \<and> S \<subseteq> \<Union>D" ..
  6.1699 +next
  6.1700 +  assume 1: "\<forall>C. (\<forall>c\<in>C. openin (subtopology euclidean S) c) \<and> S \<subseteq> \<Union>C \<longrightarrow>
  6.1701 +        (\<exists>D\<subseteq>C. finite D \<and> S \<subseteq> \<Union>D)"
  6.1702 +  show "compact S"
  6.1703 +  proof (rule compactI)
  6.1704 +    fix C
  6.1705 +    let ?C = "image (\<lambda>T. S \<inter> T) C"
  6.1706 +    assume "\<forall>t\<in>C. open t" and "S \<subseteq> \<Union>C"
  6.1707 +    then have "(\<forall>c\<in>?C. openin (subtopology euclidean S) c) \<and> S \<subseteq> \<Union>?C"
  6.1708 +      unfolding openin_open by auto
  6.1709 +    with 1 obtain D where "D \<subseteq> ?C" and "finite D" and "S \<subseteq> \<Union>D"
  6.1710 +      by metis
  6.1711 +    let ?D = "inv_into C (\<lambda>T. S \<inter> T) ` D"
  6.1712 +    have "?D \<subseteq> C \<and> finite ?D \<and> S \<subseteq> \<Union>?D"
  6.1713 +    proof (intro conjI)
  6.1714 +      from \<open>D \<subseteq> ?C\<close> show "?D \<subseteq> C"
  6.1715 +        by (fast intro: inv_into_into)
  6.1716 +      from \<open>finite D\<close> show "finite ?D"
  6.1717 +        by (rule finite_imageI)
  6.1718 +      from \<open>S \<subseteq> \<Union>D\<close> show "S \<subseteq> \<Union>?D"
  6.1719 +        apply (rule subset_trans, clarsimp)
  6.1720 +        apply (frule subsetD [OF \<open>D \<subseteq> ?C\<close>, THEN f_inv_into_f])
  6.1721 +        apply (erule rev_bexI, fast)
  6.1722 +        done
  6.1723 +    qed
  6.1724 +    then show "\<exists>D\<subseteq>C. finite D \<and> S \<subseteq> \<Union>D" ..
  6.1725 +  qed
  6.1726 +qed
  6.1727 +
  6.1728 +subsection\<open> Theorems relating continuity and uniform continuity to closures\<close>
  6.1729 +
  6.1730 +lemma continuous_on_closure:
  6.1731 +   "continuous_on (closure S) f \<longleftrightarrow>
  6.1732 +    (\<forall>x e. x \<in> closure S \<and> 0 < e
  6.1733 +           \<longrightarrow> (\<exists>d. 0 < d \<and> (\<forall>y. y \<in> S \<and> dist y x < d \<longrightarrow> dist (f y) (f x) < e)))"
  6.1734 +   (is "?lhs = ?rhs")
  6.1735 +proof
  6.1736 +  assume ?lhs then show ?rhs
  6.1737 +    unfolding continuous_on_iff  by (metis Un_iff closure_def)
  6.1738 +next
  6.1739 +  assume R [rule_format]: ?rhs
  6.1740 +  show ?lhs
  6.1741 +  proof
  6.1742 +    fix x and e::real
  6.1743 +    assume "0 < e" and x: "x \<in> closure S"
  6.1744 +    obtain \<delta>::real where "\<delta> > 0"
  6.1745 +                   and \<delta>: "\<And>y. \<lbrakk>y \<in> S; dist y x < \<delta>\<rbrakk> \<Longrightarrow> dist (f y) (f x) < e/2"
  6.1746 +      using R [of x "e/2"] \<open>0 < e\<close> x by auto
  6.1747 +    have "dist (f y) (f x) \<le> e" if y: "y \<in> closure S" and dyx: "dist y x < \<delta>/2" for y
  6.1748 +    proof -
  6.1749 +      obtain \<delta>'::real where "\<delta>' > 0"
  6.1750 +                      and \<delta>': "\<And>z. \<lbrakk>z \<in> S; dist z y < \<delta>'\<rbrakk> \<Longrightarrow> dist (f z) (f y) < e/2"
  6.1751 +        using R [of y "e/2"] \<open>0 < e\<close> y by auto
  6.1752 +      obtain z where "z \<in> S" and z: "dist z y < min \<delta>' \<delta> / 2"
  6.1753 +        using closure_approachable y
  6.1754 +        by (metis \<open>0 < \<delta>'\<close> \<open>0 < \<delta>\<close> divide_pos_pos min_less_iff_conj zero_less_numeral)
  6.1755 +      have "dist (f z) (f y) < e/2"
  6.1756 +        apply (rule \<delta>' [OF \<open>z \<in> S\<close>])
  6.1757 +        using z \<open>0 < \<delta>'\<close> by linarith
  6.1758 +      moreover have "dist (f z) (f x) < e/2"
  6.1759 +        apply (rule \<delta> [OF \<open>z \<in> S\<close>])
  6.1760 +        using z \<open>0 < \<delta>\<close>  dist_commute[of y z] dist_triangle_half_r [of y] dyx by auto
  6.1761 +      ultimately show ?thesis
  6.1762 +        by (metis dist_commute dist_triangle_half_l less_imp_le)
  6.1763 +    qed
  6.1764 +    then show "\<exists>d>0. \<forall>x'\<in>closure S. dist x' x < d \<longrightarrow> dist (f x') (f x) \<le> e"
  6.1765 +      by (rule_tac x="\<delta>/2" in exI) (simp add: \<open>\<delta> > 0\<close>)
  6.1766 +  qed
  6.1767 +qed
  6.1768 +
  6.1769 +lemma continuous_on_closure_sequentially:
  6.1770 +  fixes f :: "'a::metric_space \<Rightarrow> 'b :: metric_space"
  6.1771 +  shows
  6.1772 +   "continuous_on (closure S) f \<longleftrightarrow>
  6.1773 +    (\<forall>x a. a \<in> closure S \<and> (\<forall>n. x n \<in> S) \<and> x \<longlonglongrightarrow> a \<longrightarrow> (f \<circ> x) \<longlonglongrightarrow> f a)"
  6.1774 +   (is "?lhs = ?rhs")
  6.1775 +proof -
  6.1776 +  have "continuous_on (closure S) f \<longleftrightarrow>
  6.1777 +           (\<forall>x \<in> closure S. continuous (at x within S) f)"
  6.1778 +    by (force simp: continuous_on_closure continuous_within_eps_delta)
  6.1779 +  also have "... = ?rhs"
  6.1780 +    by (force simp: continuous_within_sequentially)
  6.1781 +  finally show ?thesis .
  6.1782 +qed
  6.1783 +
  6.1784 +lemma uniformly_continuous_on_closure:
  6.1785 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  6.1786 +  assumes ucont: "uniformly_continuous_on S f"
  6.1787 +      and cont: "continuous_on (closure S) f"
  6.1788 +    shows "uniformly_continuous_on (closure S) f"
  6.1789 +unfolding uniformly_continuous_on_def
  6.1790 +proof (intro allI impI)
  6.1791 +  fix e::real
  6.1792 +  assume "0 < e"
  6.1793 +  then obtain d::real
  6.1794 +    where "d>0"
  6.1795 +      and d: "\<And>x x'. \<lbrakk>x\<in>S; x'\<in>S; dist x' x < d\<rbrakk> \<Longrightarrow> dist (f x') (f x) < e/3"
  6.1796 +    using ucont [unfolded uniformly_continuous_on_def, rule_format, of "e/3"] by auto
  6.1797 +  show "\<exists>d>0. \<forall>x\<in>closure S. \<forall>x'\<in>closure S. dist x' x < d \<longrightarrow> dist (f x') (f x) < e"
  6.1798 +  proof (rule exI [where x="d/3"], clarsimp simp: \<open>d > 0\<close>)
  6.1799 +    fix x y
  6.1800 +    assume x: "x \<in> closure S" and y: "y \<in> closure S" and dyx: "dist y x * 3 < d"
  6.1801 +    obtain d1::real where "d1 > 0"
  6.1802 +           and d1: "\<And>w. \<lbrakk>w \<in> closure S; dist w x < d1\<rbrakk> \<Longrightarrow> dist (f w) (f x) < e/3"
  6.1803 +      using cont [unfolded continuous_on_iff, rule_format, of "x" "e/3"] \<open>0 < e\<close> x by auto
  6.1804 +     obtain x' where "x' \<in> S" and x': "dist x' x < min d1 (d / 3)"
  6.1805 +        using closure_approachable [of x S]
  6.1806 +        by (metis \<open>0 < d1\<close> \<open>0 < d\<close> divide_pos_pos min_less_iff_conj x zero_less_numeral)
  6.1807 +    obtain d2::real where "d2 > 0"
  6.1808 +           and d2: "\<forall>w \<in> closure S. dist w y < d2 \<longrightarrow> dist (f w) (f y) < e/3"
  6.1809 +      using cont [unfolded continuous_on_iff, rule_format, of "y" "e/3"] \<open>0 < e\<close> y by auto
  6.1810 +     obtain y' where "y' \<in> S" and y': "dist y' y < min d2 (d / 3)"
  6.1811 +        using closure_approachable [of y S]
  6.1812 +        by (metis \<open>0 < d2\<close> \<open>0 < d\<close> divide_pos_pos min_less_iff_conj y zero_less_numeral)
  6.1813 +     have "dist x' x < d/3" using x' by auto
  6.1814 +     moreover have "dist x y < d/3"
  6.1815 +       by (metis dist_commute dyx less_divide_eq_numeral1(1))
  6.1816 +     moreover have "dist y y' < d/3"
  6.1817 +       by (metis (no_types) dist_commute min_less_iff_conj y')
  6.1818 +     ultimately have "dist x' y' < d/3 + d/3 + d/3"
  6.1819 +       by (meson dist_commute_lessI dist_triangle_lt add_strict_mono)
  6.1820 +     then have "dist x' y' < d" by simp
  6.1821 +     then have "dist (f x') (f y') < e/3"
  6.1822 +       by (rule d [OF \<open>y' \<in> S\<close> \<open>x' \<in> S\<close>])
  6.1823 +     moreover have "dist (f x') (f x) < e/3" using \<open>x' \<in> S\<close> closure_subset x' d1
  6.1824 +       by (simp add: closure_def)
  6.1825 +     moreover have "dist (f y') (f y) < e/3" using \<open>y' \<in> S\<close> closure_subset y' d2
  6.1826 +       by (simp add: closure_def)
  6.1827 +     ultimately have "dist (f y) (f x) < e/3 + e/3 + e/3"
  6.1828 +       by (meson dist_commute_lessI dist_triangle_lt add_strict_mono)
  6.1829 +    then show "dist (f y) (f x) < e" by simp
  6.1830 +  qed
  6.1831 +qed
  6.1832 +
  6.1833 +lemma uniformly_continuous_on_extension_at_closure:
  6.1834 +  fixes f::"'a::metric_space \<Rightarrow> 'b::complete_space"
  6.1835 +  assumes uc: "uniformly_continuous_on X f"
  6.1836 +  assumes "x \<in> closure X"
  6.1837 +  obtains l where "(f \<longlongrightarrow> l) (at x within X)"
  6.1838 +proof -
  6.1839 +  from assms obtain xs where xs: "xs \<longlonglongrightarrow> x" "\<And>n. xs n \<in> X"
  6.1840 +    by (auto simp: closure_sequential)
  6.1841 +
  6.1842 +  from uniformly_continuous_on_Cauchy[OF uc LIMSEQ_imp_Cauchy, OF xs]
  6.1843 +  obtain l where l: "(\<lambda>n. f (xs n)) \<longlonglongrightarrow> l"
  6.1844 +    by atomize_elim (simp only: convergent_eq_Cauchy)
  6.1845 +
  6.1846 +  have "(f \<longlongrightarrow> l) (at x within X)"
  6.1847 +  proof (safe intro!: Lim_within_LIMSEQ)
  6.1848 +    fix xs'
  6.1849 +    assume "\<forall>n. xs' n \<noteq> x \<and> xs' n \<in> X"
  6.1850 +      and xs': "xs' \<longlonglongrightarrow> x"
  6.1851 +    then have "xs' n \<noteq> x" "xs' n \<in> X" for n by auto
  6.1852 +
  6.1853 +    from uniformly_continuous_on_Cauchy[OF uc LIMSEQ_imp_Cauchy, OF \<open>xs' \<longlonglongrightarrow> x\<close> \<open>xs' _ \<in> X\<close>]
  6.1854 +    obtain l' where l': "(\<lambda>n. f (xs' n)) \<longlonglongrightarrow> l'"
  6.1855 +      by atomize_elim (simp only: convergent_eq_Cauchy)
  6.1856 +
  6.1857 +    show "(\<lambda>n. f (xs' n)) \<longlonglongrightarrow> l"
  6.1858 +    proof (rule tendstoI)
  6.1859 +      fix e::real assume "e > 0"
  6.1860 +      define e' where "e' \<equiv> e / 2"
  6.1861 +      have "e' > 0" using \<open>e > 0\<close> by (simp add: e'_def)
  6.1862 +
  6.1863 +      have "\<forall>\<^sub>F n in sequentially. dist (f (xs n)) l < e'"
  6.1864 +        by (simp add: \<open>0 < e'\<close> l tendstoD)
  6.1865 +      moreover
  6.1866 +      from uc[unfolded uniformly_continuous_on_def, rule_format, OF \<open>e' > 0\<close>]
  6.1867 +      obtain d where d: "d > 0" "\<And>x x'. x \<in> X \<Longrightarrow> x' \<in> X \<Longrightarrow> dist x x' < d \<Longrightarrow> dist (f x) (f x') < e'"
  6.1868 +        by auto
  6.1869 +      have "\<forall>\<^sub>F n in sequentially. dist (xs n) (xs' n) < d"
  6.1870 +        by (auto intro!: \<open>0 < d\<close> order_tendstoD tendsto_eq_intros xs xs')
  6.1871 +      ultimately
  6.1872 +      show "\<forall>\<^sub>F n in sequentially. dist (f (xs' n)) l < e"
  6.1873 +      proof eventually_elim
  6.1874 +        case (elim n)
  6.1875 +        have "dist (f (xs' n)) l \<le> dist (f (xs n)) (f (xs' n)) + dist (f (xs n)) l"
  6.1876 +          by (metis dist_triangle dist_commute)
  6.1877 +        also have "dist (f (xs n)) (f (xs' n)) < e'"
  6.1878 +          by (auto intro!: d xs \<open>xs' _ \<in> _\<close> elim)
  6.1879 +        also note \<open>dist (f (xs n)) l < e'\<close>
  6.1880 +        also have "e' + e' = e" by (simp add: e'_def)
  6.1881 +        finally show ?case by simp
  6.1882 +      qed
  6.1883 +    qed
  6.1884 +  qed
  6.1885 +  thus ?thesis ..
  6.1886 +qed
  6.1887 +
  6.1888 +lemma uniformly_continuous_on_extension_on_closure:
  6.1889 +  fixes f::"'a::metric_space \<Rightarrow> 'b::complete_space"
  6.1890 +  assumes uc: "uniformly_continuous_on X f"
  6.1891 +  obtains g where "uniformly_continuous_on (closure X) g" "\<And>x. x \<in> X \<Longrightarrow> f x = g x"
  6.1892 +    "\<And>Y h x. X \<subseteq> Y \<Longrightarrow> Y \<subseteq> closure X \<Longrightarrow> continuous_on Y h \<Longrightarrow> (\<And>x. x \<in> X \<Longrightarrow> f x = h x) \<Longrightarrow> x \<in> Y \<Longrightarrow> h x = g x"
  6.1893 +proof -
  6.1894 +  from uc have cont_f: "continuous_on X f"
  6.1895 +    by (simp add: uniformly_continuous_imp_continuous)
  6.1896 +  obtain y where y: "(f \<longlongrightarrow> y x) (at x within X)" if "x \<in> closure X" for x
  6.1897 +    apply atomize_elim
  6.1898 +    apply (rule choice)
  6.1899 +    using uniformly_continuous_on_extension_at_closure[OF assms]
  6.1900 +    by metis
  6.1901 +  let ?g = "\<lambda>x. if x \<in> X then f x else y x"
  6.1902 +
  6.1903 +  have "uniformly_continuous_on (closure X) ?g"
  6.1904 +    unfolding uniformly_continuous_on_def
  6.1905 +  proof safe
  6.1906 +    fix e::real assume "e > 0"
  6.1907 +    define e' where "e' \<equiv> e / 3"
  6.1908 +    have "e' > 0" using \<open>e > 0\<close> by (simp add: e'_def)
  6.1909 +    from uc[unfolded uniformly_continuous_on_def, rule_format, OF \<open>0 < e'\<close>]
  6.1910 +    obtain d where "d > 0" and d: "\<And>x x'. x \<in> X \<Longrightarrow> x' \<in> X \<Longrightarrow> dist x' x < d \<Longrightarrow> dist (f x') (f x) < e'"
  6.1911 +      by auto
  6.1912 +    define d' where "d' = d / 3"
  6.1913 +    have "d' > 0" using \<open>d > 0\<close> by (simp add: d'_def)
  6.1914 +    show "\<exists>d>0. \<forall>x\<in>closure X. \<forall>x'\<in>closure X. dist x' x < d \<longrightarrow> dist (?g x') (?g x) < e"
  6.1915 +    proof (safe intro!: exI[where x=d'] \<open>d' > 0\<close>)
  6.1916 +      fix x x' assume x: "x \<in> closure X" and x': "x' \<in> closure X" and dist: "dist x' x < d'"
  6.1917 +      then obtain xs xs' where xs: "xs \<longlonglongrightarrow> x" "\<And>n. xs n \<in> X"
  6.1918 +        and xs': "xs' \<longlonglongrightarrow> x'" "\<And>n. xs' n \<in> X"
  6.1919 +        by (auto simp: closure_sequential)
  6.1920 +      have "\<forall>\<^sub>F n in sequentially. dist (xs' n) x' < d'"
  6.1921 +        and "\<forall>\<^sub>F n in sequentially. dist (xs n) x < d'"
  6.1922 +        by (auto intro!: \<open>0 < d'\<close> order_tendstoD tendsto_eq_intros xs xs')
  6.1923 +      moreover
  6.1924 +      have "(\<lambda>x. f (xs x)) \<longlonglongrightarrow> y x" if "x \<in> closure X" "x \<notin> X" "xs \<longlonglongrightarrow> x" "\<And>n. xs n \<in> X" for xs x
  6.1925 +        using that not_eventuallyD
  6.1926 +        by (force intro!: filterlim_compose[OF y[OF \<open>x \<in> closure X\<close>]] simp: filterlim_at)
  6.1927 +      then have "(\<lambda>x. f (xs' x)) \<longlonglongrightarrow> ?g x'" "(\<lambda>x. f (xs x)) \<longlonglongrightarrow> ?g x"
  6.1928 +        using x x'
  6.1929 +        by (auto intro!: continuous_on_tendsto_compose[OF cont_f] simp: xs' xs)
  6.1930 +      then have "\<forall>\<^sub>F n in sequentially. dist (f (xs' n)) (?g x') < e'"
  6.1931 +        "\<forall>\<^sub>F n in sequentially. dist (f (xs n)) (?g x) < e'"
  6.1932 +        by (auto intro!: \<open>0 < e'\<close> order_tendstoD tendsto_eq_intros)
  6.1933 +      ultimately
  6.1934 +      have "\<forall>\<^sub>F n in sequentially. dist (?g x') (?g x) < e"
  6.1935 +      proof eventually_elim
  6.1936 +        case (elim n)
  6.1937 +        have "dist (?g x') (?g x) \<le>
  6.1938 +          dist (f (xs' n)) (?g x') + dist (f (xs' n)) (f (xs n)) + dist (f (xs n)) (?g x)"
  6.1939 +          by (metis add.commute add_le_cancel_left dist_commute dist_triangle dist_triangle_le)
  6.1940 +        also
  6.1941 +        {
  6.1942 +          have "dist (xs' n) (xs n) \<le> dist (xs' n) x' + dist x' x + dist (xs n) x"
  6.1943 +            by (metis add.commute add_le_cancel_left  dist_triangle dist_triangle_le)
  6.1944 +          also note \<open>dist (xs' n) x' < d'\<close>
  6.1945 +          also note \<open>dist x' x < d'\<close>
  6.1946 +          also note \<open>dist (xs n) x < d'\<close>
  6.1947 +          finally have "dist (xs' n) (xs n) < d" by (simp add: d'_def)
  6.1948 +        }
  6.1949 +        with \<open>xs _ \<in> X\<close> \<open>xs' _ \<in> X\<close> have "dist (f (xs' n)) (f (xs n)) < e'"
  6.1950 +          by (rule d)
  6.1951 +        also note \<open>dist (f (xs' n)) (?g x') < e'\<close>
  6.1952 +        also note \<open>dist (f (xs n)) (?g x) < e'\<close>
  6.1953 +        finally show ?case by (simp add: e'_def)
  6.1954 +      qed
  6.1955 +      then show "dist (?g x') (?g x) < e" by simp
  6.1956 +    qed
  6.1957 +  qed
  6.1958 +  moreover have "f x = ?g x" if "x \<in> X" for x using that by simp
  6.1959 +  moreover
  6.1960 +  {
  6.1961 +    fix Y h x
  6.1962 +    assume Y: "x \<in> Y" "X \<subseteq> Y" "Y \<subseteq> closure X" and cont_h: "continuous_on Y h"
  6.1963 +      and extension: "(\<And>x. x \<in> X \<Longrightarrow> f x = h x)"
  6.1964 +    {
  6.1965 +      assume "x \<notin> X"
  6.1966 +      have "x \<in> closure X" using Y by auto
  6.1967 +      then obtain xs where xs: "xs \<longlonglongrightarrow> x" "\<And>n. xs n \<in> X"
  6.1968 +        by (auto simp: closure_sequential)
  6.1969 +      from continuous_on_tendsto_compose[OF cont_h xs(1)] xs(2) Y
  6.1970 +      have hx: "(\<lambda>x. f (xs x)) \<longlonglongrightarrow> h x"
  6.1971 +        by (auto simp: set_mp extension)
  6.1972 +      then have "(\<lambda>x. f (xs x)) \<longlonglongrightarrow> y x"
  6.1973 +        using \<open>x \<notin> X\<close> not_eventuallyD xs(2)
  6.1974 +        by (force intro!: filterlim_compose[OF y[OF \<open>x \<in> closure X\<close>]] simp: filterlim_at xs)
  6.1975 +      with hx have "h x = y x" by (rule LIMSEQ_unique)
  6.1976 +    } then
  6.1977 +    have "h x = ?g x"
  6.1978 +      using extension by auto
  6.1979 +  }
  6.1980 +  ultimately show ?thesis ..
  6.1981 +qed
  6.1982 +
  6.1983 +lemma bounded_uniformly_continuous_image:
  6.1984 +  fixes f :: "'a :: heine_borel \<Rightarrow> 'b :: heine_borel"
  6.1985 +  assumes "uniformly_continuous_on S f" "bounded S"
  6.1986 +  shows "bounded(image f S)"
  6.1987 +  by (metis (no_types, lifting) assms bounded_closure_image compact_closure compact_continuous_image compact_eq_bounded_closed image_cong uniformly_continuous_imp_continuous uniformly_continuous_on_extension_on_closure)
  6.1988 +
  6.1989 +subsection \<open>Making a continuous function avoid some value in a neighbourhood.\<close>
  6.1990 +
  6.1991 +lemma continuous_within_avoid:
  6.1992 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::t1_space"
  6.1993 +  assumes "continuous (at x within s) f"
  6.1994 +    and "f x \<noteq> a"
  6.1995 +  shows "\<exists>e>0. \<forall>y \<in> s. dist x y < e --> f y \<noteq> a"
  6.1996 +proof -
  6.1997 +  obtain U where "open U" and "f x \<in> U" and "a \<notin> U"
  6.1998 +    using t1_space [OF \<open>f x \<noteq> a\<close>] by fast
  6.1999 +  have "(f \<longlongrightarrow> f x) (at x within s)"
  6.2000 +    using assms(1) by (simp add: continuous_within)
  6.2001 +  then have "eventually (\<lambda>y. f y \<in> U) (at x within s)"
  6.2002 +    using \<open>open U\<close> and \<open>f x \<in> U\<close>
  6.2003 +    unfolding tendsto_def by fast
  6.2004 +  then have "eventually (\<lambda>y. f y \<noteq> a) (at x within s)"
  6.2005 +    using \<open>a \<notin> U\<close> by (fast elim: eventually_mono)
  6.2006 +  then show ?thesis
  6.2007 +    using \<open>f x \<noteq> a\<close> by (auto simp: dist_commute zero_less_dist_iff eventually_at)
  6.2008 +qed
  6.2009 +
  6.2010 +lemma continuous_at_avoid:
  6.2011 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::t1_space"
  6.2012 +  assumes "continuous (at x) f"
  6.2013 +    and "f x \<noteq> a"
  6.2014 +  shows "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> f y \<noteq> a"
  6.2015 +  using assms continuous_within_avoid[of x UNIV f a] by simp
  6.2016 +
  6.2017 +lemma continuous_on_avoid:
  6.2018 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::t1_space"
  6.2019 +  assumes "continuous_on s f"
  6.2020 +    and "x \<in> s"
  6.2021 +    and "f x \<noteq> a"
  6.2022 +  shows "\<exists>e>0. \<forall>y \<in> s. dist x y < e \<longrightarrow> f y \<noteq> a"
  6.2023 +  using assms(1)[unfolded continuous_on_eq_continuous_within, THEN bspec[where x=x],
  6.2024 +    OF assms(2)] continuous_within_avoid[of x s f a]
  6.2025 +  using assms(3)
  6.2026 +  by auto
  6.2027 +
  6.2028 +lemma continuous_on_open_avoid:
  6.2029 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::t1_space"
  6.2030 +  assumes "continuous_on s f"
  6.2031 +    and "open s"
  6.2032 +    and "x \<in> s"
  6.2033 +    and "f x \<noteq> a"
  6.2034 +  shows "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> f y \<noteq> a"
  6.2035 +  using assms(1)[unfolded continuous_on_eq_continuous_at[OF assms(2)], THEN bspec[where x=x], OF assms(3)]
  6.2036 +  using continuous_at_avoid[of x f a] assms(4)
  6.2037 +  by auto
  6.2038 +
  6.2039 +subsection\<open>Quotient maps\<close>
  6.2040 +
  6.2041 +lemma quotient_map_imp_continuous_open:
  6.2042 +  assumes t: "f ` s \<subseteq> t"
  6.2043 +      and ope: "\<And>u. u \<subseteq> t
  6.2044 +              \<Longrightarrow> (openin (subtopology euclidean s) {x. x \<in> s \<and> f x \<in> u} \<longleftrightarrow>
  6.2045 +                   openin (subtopology euclidean t) u)"
  6.2046 +    shows "continuous_on s f"
  6.2047 +proof -
  6.2048 +  have [simp]: "{x \<in> s. f x \<in> f ` s} = s" by auto
  6.2049 +  show ?thesis
  6.2050 +    using ope [OF t]
  6.2051 +    apply (simp add: continuous_on_open)
  6.2052 +    by (metis (no_types, lifting) "ope"  openin_imp_subset openin_trans)
  6.2053 +qed
  6.2054 +
  6.2055 +lemma quotient_map_imp_continuous_closed:
  6.2056 +  assumes t: "f ` s \<subseteq> t"
  6.2057 +      and ope: "\<And>u. u \<subseteq> t
  6.2058 +                  \<Longrightarrow> (closedin (subtopology euclidean s) {x. x \<in> s \<and> f x \<in> u} \<longleftrightarrow>
  6.2059 +                       closedin (subtopology euclidean t) u)"
  6.2060 +    shows "continuous_on s f"
  6.2061 +proof -
  6.2062 +  have [simp]: "{x \<in> s. f x \<in> f ` s} = s" by auto
  6.2063 +  show ?thesis
  6.2064 +    using ope [OF t]
  6.2065 +    apply (simp add: continuous_on_closed)
  6.2066 +    by (metis (no_types, lifting) "ope" closedin_imp_subset closedin_subtopology_refl closedin_trans openin_subtopology_refl openin_subtopology_self)
  6.2067 +qed
  6.2068 +
  6.2069 +lemma open_map_imp_quotient_map:
  6.2070 +  assumes contf: "continuous_on s f"
  6.2071 +      and t: "t \<subseteq> f ` s"
  6.2072 +      and ope: "\<And>t. openin (subtopology euclidean s) t
  6.2073 +                   \<Longrightarrow> openin (subtopology euclidean (f ` s)) (f ` t)"
  6.2074 +    shows "openin (subtopology euclidean s) {x \<in> s. f x \<in> t} =
  6.2075 +           openin (subtopology euclidean (f ` s)) t"
  6.2076 +proof -
  6.2077 +  have "t = image f {x. x \<in> s \<and> f x \<in> t}"
  6.2078 +    using t by blast
  6.2079 +  then show ?thesis
  6.2080 +    using "ope" contf continuous_on_open by fastforce
  6.2081 +qed
  6.2082 +
  6.2083 +lemma closed_map_imp_quotient_map:
  6.2084 +  assumes contf: "continuous_on s f"
  6.2085 +      and t: "t \<subseteq> f ` s"
  6.2086 +      and ope: "\<And>t. closedin (subtopology euclidean s) t
  6.2087 +              \<Longrightarrow> closedin (subtopology euclidean (f ` s)) (f ` t)"
  6.2088 +    shows "openin (subtopology euclidean s) {x \<in> s. f x \<in> t} \<longleftrightarrow>
  6.2089 +           openin (subtopology euclidean (f ` s)) t"
  6.2090 +          (is "?lhs = ?rhs")
  6.2091 +proof
  6.2092 +  assume ?lhs
  6.2093 +  then have *: "closedin (subtopology euclidean s) (s - {x \<in> s. f x \<in> t})"
  6.2094 +    using closedin_diff by fastforce
  6.2095 +  have [simp]: "(f ` s - f ` (s - {x \<in> s. f x \<in> t})) = t"
  6.2096 +    using t by blast
  6.2097 +  show ?rhs
  6.2098 +    using ope [OF *, unfolded closedin_def] by auto
  6.2099 +next
  6.2100 +  assume ?rhs
  6.2101 +  with contf show ?lhs
  6.2102 +    by (auto simp: continuous_on_open)
  6.2103 +qed
  6.2104 +
  6.2105 +lemma continuous_right_inverse_imp_quotient_map:
  6.2106 +  assumes contf: "continuous_on s f" and imf: "f ` s \<subseteq> t"
  6.2107 +      and contg: "continuous_on t g" and img: "g ` t \<subseteq> s"
  6.2108 +      and fg [simp]: "\<And>y. y \<in> t \<Longrightarrow> f(g y) = y"
  6.2109 +      and u: "u \<subseteq> t"
  6.2110 +    shows "openin (subtopology euclidean s) {x. x \<in> s \<and> f x \<in> u} \<longleftrightarrow>
  6.2111 +           openin (subtopology euclidean t) u"
  6.2112 +          (is "?lhs = ?rhs")
  6.2113 +proof -
  6.2114 +  have f: "\<And>z. openin (subtopology euclidean (f ` s)) z \<Longrightarrow>
  6.2115 +                openin (subtopology euclidean s) {x \<in> s. f x \<in> z}"
  6.2116 +  and  g: "\<And>z. openin (subtopology euclidean (g ` t)) z \<Longrightarrow>
  6.2117 +                openin (subtopology euclidean t) {x \<in> t. g x \<in> z}"
  6.2118 +    using contf contg by (auto simp: continuous_on_open)
  6.2119 +  show ?thesis
  6.2120 +  proof
  6.2121 +    have "{x \<in> t. g x \<in> g ` t \<and> g x \<in> s \<and> f (g x) \<in> u} = {x \<in> t. f (g x) \<in> u}"
  6.2122 +      using imf img by blast
  6.2123 +    also have "... = u"
  6.2124 +      using u by auto
  6.2125 +    finally have [simp]: "{x \<in> t. g x \<in> g ` t \<and> g x \<in> s \<and> f (g x) \<in> u} = u" .
  6.2126 +    assume ?lhs
  6.2127 +    then have *: "openin (subtopology euclidean (g ` t)) (g ` t \<inter> {x \<in> s. f x \<in> u})"
  6.2128 +      by (meson img openin_Int openin_subtopology_Int_subset openin_subtopology_self)
  6.2129 +    show ?rhs
  6.2130 +      using g [OF *] by simp
  6.2131 +  next
  6.2132 +    assume rhs: ?rhs
  6.2133 +    show ?lhs
  6.2134 +      apply (rule f)
  6.2135 +      by (metis fg image_eqI image_subset_iff imf img openin_subopen openin_subtopology_self openin_trans rhs)
  6.2136 +  qed
  6.2137 +qed
  6.2138 +
  6.2139 +lemma continuous_left_inverse_imp_quotient_map:
  6.2140 +  assumes "continuous_on s f"
  6.2141 +      and "continuous_on (f ` s) g"
  6.2142 +      and  "\<And>x. x \<in> s \<Longrightarrow> g(f x) = x"
  6.2143 +      and "u \<subseteq> f ` s"
  6.2144 +    shows "openin (subtopology euclidean s) {x. x \<in> s \<and> f x \<in> u} \<longleftrightarrow>
  6.2145 +           openin (subtopology euclidean (f ` s)) u"
  6.2146 +apply (rule continuous_right_inverse_imp_quotient_map)
  6.2147 +using assms
  6.2148 +apply force+
  6.2149 +done
  6.2150 +
  6.2151 +text \<open>Proving a function is constant by proving that a level set is open\<close>
  6.2152 +
  6.2153 +lemma continuous_levelset_openin_cases:
  6.2154 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.2155 +  shows "connected s \<Longrightarrow> continuous_on s f \<Longrightarrow>
  6.2156 +        openin (subtopology euclidean s) {x \<in> s. f x = a}
  6.2157 +        \<Longrightarrow> (\<forall>x \<in> s. f x \<noteq> a) \<or> (\<forall>x \<in> s. f x = a)"
  6.2158 +  unfolding connected_clopen
  6.2159 +  using continuous_closedin_preimage_constant by auto
  6.2160 +
  6.2161 +lemma continuous_levelset_openin:
  6.2162 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.2163 +  shows "connected s \<Longrightarrow> continuous_on s f \<Longrightarrow>
  6.2164 +        openin (subtopology euclidean s) {x \<in> s. f x = a} \<Longrightarrow>
  6.2165 +        (\<exists>x \<in> s. f x = a)  \<Longrightarrow> (\<forall>x \<in> s. f x = a)"
  6.2166 +  using continuous_levelset_openin_cases[of s f ]
  6.2167 +  by meson
  6.2168 +
  6.2169 +lemma continuous_levelset_open:
  6.2170 +  fixes f :: "_ \<Rightarrow> 'b::t1_space"
  6.2171 +  assumes "connected s"
  6.2172 +    and "continuous_on s f"
  6.2173 +    and "open {x \<in> s. f x = a}"
  6.2174 +    and "\<exists>x \<in> s.  f x = a"
  6.2175 +  shows "\<forall>x \<in> s. f x = a"
  6.2176 +  using continuous_levelset_openin[OF assms(1,2), of a, unfolded openin_open]
  6.2177 +  using assms (3,4)
  6.2178 +  by fast
  6.2179 +
  6.2180 +text \<open>Some arithmetical combinations (more to prove).\<close>
  6.2181 +
  6.2182 +lemma open_scaling[intro]:
  6.2183 +  fixes s :: "'a::real_normed_vector set"
  6.2184 +  assumes "c \<noteq> 0"
  6.2185 +    and "open s"
  6.2186 +  shows "open((\<lambda>x. c *\<^sub>R x) ` s)"
  6.2187 +proof -
  6.2188 +  {
  6.2189 +    fix x
  6.2190 +    assume "x \<in> s"
  6.2191 +    then obtain e where "e>0"
  6.2192 +      and e:"\<forall>x'. dist x' x < e \<longrightarrow> x' \<in> s" using assms(2)[unfolded open_dist, THEN bspec[where x=x]]
  6.2193 +      by auto
  6.2194 +    have "e * \<bar>c\<bar> > 0"
  6.2195 +      using assms(1)[unfolded zero_less_abs_iff[symmetric]] \<open>e>0\<close> by auto
  6.2196 +    moreover
  6.2197 +    {
  6.2198 +      fix y
  6.2199 +      assume "dist y (c *\<^sub>R x) < e * \<bar>c\<bar>"
  6.2200 +      then have "norm ((1 / c) *\<^sub>R y - x) < e"
  6.2201 +        unfolding dist_norm
  6.2202 +        using norm_scaleR[of c "(1 / c) *\<^sub>R y - x", unfolded scaleR_right_diff_distrib, unfolded scaleR_scaleR] assms(1)
  6.2203 +          assms(1)[unfolded zero_less_abs_iff[symmetric]] by (simp del:zero_less_abs_iff)
  6.2204 +      then have "y \<in> op *\<^sub>R c ` s"
  6.2205 +        using rev_image_eqI[of "(1 / c) *\<^sub>R y" s y "op *\<^sub>R c"]
  6.2206 +        using e[THEN spec[where x="(1 / c) *\<^sub>R y"]]
  6.2207 +        using assms(1)
  6.2208 +        unfolding dist_norm scaleR_scaleR
  6.2209 +        by auto
  6.2210 +    }
  6.2211 +    ultimately have "\<exists>e>0. \<forall>x'. dist x' (c *\<^sub>R x) < e \<longrightarrow> x' \<in> op *\<^sub>R c ` s"
  6.2212 +      apply (rule_tac x="e * \<bar>c\<bar>" in exI, auto)
  6.2213 +      done
  6.2214 +  }
  6.2215 +  then show ?thesis unfolding open_dist by auto
  6.2216 +qed
  6.2217 +
  6.2218 +lemma minus_image_eq_vimage:
  6.2219 +  fixes A :: "'a::ab_group_add set"
  6.2220 +  shows "(\<lambda>x. - x) ` A = (\<lambda>x. - x) -` A"
  6.2221 +  by (auto intro!: image_eqI [where f="\<lambda>x. - x"])
  6.2222 +
  6.2223 +lemma open_negations:
  6.2224 +  fixes S :: "'a::real_normed_vector set"
  6.2225 +  shows "open S \<Longrightarrow> open ((\<lambda>x. - x) ` S)"
  6.2226 +  using open_scaling [of "- 1" S] by simp
  6.2227 +
  6.2228 +lemma open_translation:
  6.2229 +  fixes S :: "'a::real_normed_vector set"
  6.2230 +  assumes "open S"
  6.2231 +  shows "open((\<lambda>x. a + x) ` S)"
  6.2232 +proof -
  6.2233 +  {
  6.2234 +    fix x
  6.2235 +    have "continuous (at x) (\<lambda>x. x - a)"
  6.2236 +      by (intro continuous_diff continuous_ident continuous_const)
  6.2237 +  }
  6.2238 +  moreover have "{x. x - a \<in> S} = op + a ` S"
  6.2239 +    by force
  6.2240 +  ultimately show ?thesis
  6.2241 +    by (metis assms continuous_open_vimage vimage_def)
  6.2242 +qed
  6.2243 +
  6.2244 +lemma open_affinity:
  6.2245 +  fixes S :: "'a::real_normed_vector set"
  6.2246 +  assumes "open S"  "c \<noteq> 0"
  6.2247 +  shows "open ((\<lambda>x. a + c *\<^sub>R x) ` S)"
  6.2248 +proof -
  6.2249 +  have *: "(\<lambda>x. a + c *\<^sub>R x) = (\<lambda>x. a + x) \<circ> (\<lambda>x. c *\<^sub>R x)"
  6.2250 +    unfolding o_def ..
  6.2251 +  have "op + a ` op *\<^sub>R c ` S = (op + a \<circ> op *\<^sub>R c) ` S"
  6.2252 +    by auto
  6.2253 +  then show ?thesis
  6.2254 +    using assms open_translation[of "op *\<^sub>R c ` S" a]
  6.2255 +    unfolding *
  6.2256 +    by auto
  6.2257 +qed
  6.2258 +
  6.2259 +lemma interior_translation:
  6.2260 +  fixes S :: "'a::real_normed_vector set"
  6.2261 +  shows "interior ((\<lambda>x. a + x) ` S) = (\<lambda>x. a + x) ` (interior S)"
  6.2262 +proof (rule set_eqI, rule)
  6.2263 +  fix x
  6.2264 +  assume "x \<in> interior (op + a ` S)"
  6.2265 +  then obtain e where "e > 0" and e: "ball x e \<subseteq> op + a ` S"
  6.2266 +    unfolding mem_interior by auto
  6.2267 +  then have "ball (x - a) e \<subseteq> S"
  6.2268 +    unfolding subset_eq Ball_def mem_ball dist_norm
  6.2269 +    by (auto simp: diff_diff_eq)
  6.2270 +  then show "x \<in> op + a ` interior S"
  6.2271 +    unfolding image_iff
  6.2272 +    apply (rule_tac x="x - a" in bexI)
  6.2273 +    unfolding mem_interior
  6.2274 +    using \<open>e > 0\<close>
  6.2275 +    apply auto
  6.2276 +    done
  6.2277 +next
  6.2278 +  fix x
  6.2279 +  assume "x \<in> op + a ` interior S"
  6.2280 +  then obtain y e where "e > 0" and e: "ball y e \<subseteq> S" and y: "x = a + y"
  6.2281 +    unfolding image_iff Bex_def mem_interior by auto
  6.2282 +  {
  6.2283 +    fix z
  6.2284 +    have *: "a + y - z = y + a - z" by auto
  6.2285 +    assume "z \<in> ball x e"
  6.2286 +    then have "z - a \<in> S"
  6.2287 +      using e[unfolded subset_eq, THEN bspec[where x="z - a"]]
  6.2288 +      unfolding mem_ball dist_norm y group_add_class.diff_diff_eq2 *
  6.2289 +      by auto
  6.2290 +    then have "z \<in> op + a ` S"
  6.2291 +      unfolding image_iff by (auto intro!: bexI[where x="z - a"])
  6.2292 +  }
  6.2293 +  then have "ball x e \<subseteq> op + a ` S"
  6.2294 +    unfolding subset_eq by auto
  6.2295 +  then show "x \<in> interior (op + a ` S)"
  6.2296 +    unfolding mem_interior using \<open>e > 0\<close> by auto
  6.2297 +qed
  6.2298 +
  6.2299 +subsection \<open>Continuity implies uniform continuity on a compact domain.\<close>
  6.2300 +
  6.2301 +text\<open>From the proof of the Heine-Borel theorem: Lemma 2 in section 3.7, page 69 of
  6.2302 +J. C. Burkill and H. Burkill. A Second Course in Mathematical Analysis (CUP, 2002)\<close>
  6.2303 +
  6.2304 +lemma Heine_Borel_lemma:
  6.2305 +  assumes "compact S" and Ssub: "S \<subseteq> \<Union>\<G>" and op: "\<And>G. G \<in> \<G> \<Longrightarrow> open G"
  6.2306 +  obtains e where "0 < e" "\<And>x. x \<in> S \<Longrightarrow> \<exists>G \<in> \<G>. ball x e \<subseteq> G"
  6.2307 +proof -
  6.2308 +  have False if neg: "\<And>e. 0 < e \<Longrightarrow> \<exists>x \<in> S. \<forall>G \<in> \<G>. \<not> ball x e \<subseteq> G"
  6.2309 +  proof -
  6.2310 +    have "\<exists>x \<in> S. \<forall>G \<in> \<G>. \<not> ball x (1 / Suc n) \<subseteq> G" for n
  6.2311 +      using neg by simp
  6.2312 +    then obtain f where "\<And>n. f n \<in> S" and fG: "\<And>G n. G \<in> \<G> \<Longrightarrow> \<not> ball (f n) (1 / Suc n) \<subseteq> G"
  6.2313 +      by metis
  6.2314 +    then obtain l r where "l \<in> S" "strict_mono r" and to_l: "(f \<circ> r) \<longlonglongrightarrow> l"
  6.2315 +      using \<open>compact S\<close> compact_def that by metis
  6.2316 +    then obtain G where "l \<in> G" "G \<in> \<G>"
  6.2317 +      using Ssub by auto
  6.2318 +    then obtain e where "0 < e" and e: "\<And>z. dist z l < e \<Longrightarrow> z \<in> G"
  6.2319 +      using op open_dist by blast
  6.2320 +    obtain N1 where N1: "\<And>n. n \<ge> N1 \<Longrightarrow> dist (f (r n)) l < e/2"
  6.2321 +      using to_l apply (simp add: lim_sequentially)
  6.2322 +      using \<open>0 < e\<close> half_gt_zero that by blast
  6.2323 +    obtain N2 where N2: "of_nat N2 > 2/e"
  6.2324 +      using reals_Archimedean2 by blast
  6.2325 +    obtain x where "x \<in> ball (f (r (max N1 N2))) (1 / real (Suc (r (max N1 N2))))" and "x \<notin> G"
  6.2326 +      using fG [OF \<open>G \<in> \<G>\<close>, of "r (max N1 N2)"] by blast
  6.2327 +    then have "dist (f (r (max N1 N2))) x < 1 / real (Suc (r (max N1 N2)))"
  6.2328 +      by simp
  6.2329 +    also have "... \<le> 1 / real (Suc (max N1 N2))"
  6.2330 +      apply (simp add: divide_simps del: max.bounded_iff)
  6.2331 +      using \<open>strict_mono r\<close> seq_suble by blast
  6.2332 +    also have "... \<le> 1 / real (Suc N2)"
  6.2333 +      by (simp add: field_simps)
  6.2334 +    also have "... < e/2"
  6.2335 +      using N2 \<open>0 < e\<close> by (simp add: field_simps)
  6.2336 +    finally have "dist (f (r (max N1 N2))) x < e / 2" .
  6.2337 +    moreover have "dist (f (r (max N1 N2))) l < e/2"
  6.2338 +      using N1 max.cobounded1 by blast
  6.2339 +    ultimately have "dist x l < e"
  6.2340 +      using dist_triangle_half_r by blast
  6.2341 +    then show ?thesis
  6.2342 +      using e \<open>x \<notin> G\<close> by blast
  6.2343 +  qed
  6.2344 +  then show ?thesis
  6.2345 +    by (meson that)
  6.2346 +qed
  6.2347 +
  6.2348 +lemma compact_uniformly_equicontinuous:
  6.2349 +  assumes "compact S"
  6.2350 +      and cont: "\<And>x e. \<lbrakk>x \<in> S; 0 < e\<rbrakk>
  6.2351 +                        \<Longrightarrow> \<exists>d. 0 < d \<and>
  6.2352 +                                (\<forall>f \<in> \<F>. \<forall>x' \<in> S. dist x' x < d \<longrightarrow> dist (f x') (f x) < e)"
  6.2353 +      and "0 < e"
  6.2354 +  obtains d where "0 < d"
  6.2355 +                  "\<And>f x x'. \<lbrakk>f \<in> \<F>; x \<in> S; x' \<in> S; dist x' x < d\<rbrakk> \<Longrightarrow> dist (f x') (f x) < e"
  6.2356 +proof -
  6.2357 +  obtain d where d_pos: "\<And>x e. \<lbrakk>x \<in> S; 0 < e\<rbrakk> \<Longrightarrow> 0 < d x e"
  6.2358 +     and d_dist : "\<And>x x' e f. \<lbrakk>dist x' x < d x e; x \<in> S; x' \<in> S; 0 < e; f \<in> \<F>\<rbrakk> \<Longrightarrow> dist (f x') (f x) < e"
  6.2359 +    using cont by metis
  6.2360 +  let ?\<G> = "((\<lambda>x. ball x (d x (e / 2))) ` S)"
  6.2361 +  have Ssub: "S \<subseteq> \<Union> ?\<G>"
  6.2362 +    by clarsimp (metis d_pos \<open>0 < e\<close> dist_self half_gt_zero_iff)
  6.2363 +  then obtain k where "0 < k" and k: "\<And>x. x \<in> S \<Longrightarrow> \<exists>G \<in> ?\<G>. ball x k \<subseteq> G"
  6.2364 +    by (rule Heine_Borel_lemma [OF \<open>compact S\<close>]) auto
  6.2365 +  moreover have "dist (f v) (f u) < e" if "f \<in> \<F>" "u \<in> S" "v \<in> S" "dist v u < k" for f u v
  6.2366 +  proof -
  6.2367 +    obtain G where "G \<in> ?\<G>" "u \<in> G" "v \<in> G"
  6.2368 +      using k that
  6.2369 +      by (metis \<open>dist v u < k\<close> \<open>u \<in> S\<close> \<open>0 < k\<close> centre_in_ball subsetD dist_commute mem_ball)
  6.2370 +    then obtain w where w: "dist w u < d w (e / 2)" "dist w v < d w (e / 2)" "w \<in> S"
  6.2371 +      by auto
  6.2372 +    with that d_dist have "dist (f w) (f v) < e/2"
  6.2373 +      by (metis \<open>0 < e\<close> dist_commute half_gt_zero)
  6.2374 +    moreover
  6.2375 +    have "dist (f w) (f u) < e/2"
  6.2376 +      using that d_dist w by (metis \<open>0 < e\<close> dist_commute divide_pos_pos zero_less_numeral)
  6.2377 +    ultimately show ?thesis
  6.2378 +      using dist_triangle_half_r by blast
  6.2379 +  qed
  6.2380 +  ultimately show ?thesis using that by blast
  6.2381 +qed
  6.2382 +
  6.2383 +corollary compact_uniformly_continuous:
  6.2384 +  fixes f :: "'a :: metric_space \<Rightarrow> 'b :: metric_space"
  6.2385 +  assumes f: "continuous_on S f" and S: "compact S"
  6.2386 +  shows "uniformly_continuous_on S f"
  6.2387 +  using f
  6.2388 +    unfolding continuous_on_iff uniformly_continuous_on_def
  6.2389 +    by (force intro: compact_uniformly_equicontinuous [OF S, of "{f}"])
  6.2390 +
  6.2391 +subsection \<open>Topological stuff about the set of Reals\<close>
  6.2392 +
  6.2393 +lemma open_real:
  6.2394 +  fixes s :: "real set"
  6.2395 +  shows "open s \<longleftrightarrow> (\<forall>x \<in> s. \<exists>e>0. \<forall>x'. \<bar>x' - x\<bar> < e --> x' \<in> s)"
  6.2396 +  unfolding open_dist dist_norm by simp
  6.2397 +
  6.2398 +lemma islimpt_approachable_real:
  6.2399 +  fixes s :: "real set"
  6.2400 +  shows "x islimpt s \<longleftrightarrow> (\<forall>e>0. \<exists>x'\<in> s. x' \<noteq> x \<and> \<bar>x' - x\<bar> < e)"
  6.2401 +  unfolding islimpt_approachable dist_norm by simp
  6.2402 +
  6.2403 +lemma closed_real:
  6.2404 +  fixes s :: "real set"
  6.2405 +  shows "closed s \<longleftrightarrow> (\<forall>x. (\<forall>e>0.  \<exists>x' \<in> s. x' \<noteq> x \<and> \<bar>x' - x\<bar> < e) \<longrightarrow> x \<in> s)"
  6.2406 +  unfolding closed_limpt islimpt_approachable dist_norm by simp
  6.2407 +
  6.2408 +lemma continuous_at_real_range:
  6.2409 +  fixes f :: "'a::real_normed_vector \<Rightarrow> real"
  6.2410 +  shows "continuous (at x) f \<longleftrightarrow> (\<forall>e>0. \<exists>d>0. \<forall>x'. norm(x' - x) < d --> \<bar>f x' - f x\<bar> < e)"
  6.2411 +  unfolding continuous_at
  6.2412 +  unfolding Lim_at
  6.2413 +  unfolding dist_norm
  6.2414 +  apply auto
  6.2415 +  apply (erule_tac x=e in allE, auto)
  6.2416 +  apply (rule_tac x=d in exI, auto)
  6.2417 +  apply (erule_tac x=x' in allE, auto)
  6.2418 +  apply (erule_tac x=e in allE, auto)
  6.2419 +  done
  6.2420 +
  6.2421 +lemma continuous_on_real_range:
  6.2422 +  fixes f :: "'a::real_normed_vector \<Rightarrow> real"
  6.2423 +  shows "continuous_on s f \<longleftrightarrow>
  6.2424 +    (\<forall>x \<in> s. \<forall>e>0. \<exists>d>0. (\<forall>x' \<in> s. norm(x' - x) < d \<longrightarrow> \<bar>f x' - f x\<bar> < e))"
  6.2425 +  unfolding continuous_on_iff dist_norm by simp
  6.2426 +
  6.2427 +text \<open>Hence some handy theorems on distance, diameter etc. of/from a set.\<close>
  6.2428 +
  6.2429 +lemma distance_attains_sup:
  6.2430 +  assumes "compact s" "s \<noteq> {}"
  6.2431 +  shows "\<exists>x\<in>s. \<forall>y\<in>s. dist a y \<le> dist a x"
  6.2432 +proof (rule continuous_attains_sup [OF assms])
  6.2433 +  {
  6.2434 +    fix x
  6.2435 +    assume "x\<in>s"
  6.2436 +    have "(dist a \<longlongrightarrow> dist a x) (at x within s)"
  6.2437 +      by (intro tendsto_dist tendsto_const tendsto_ident_at)
  6.2438 +  }
  6.2439 +  then show "continuous_on s (dist a)"
  6.2440 +    unfolding continuous_on ..
  6.2441 +qed
  6.2442 +
  6.2443 +text \<open>For \emph{minimal} distance, we only need closure, not compactness.\<close>
  6.2444 +
  6.2445 +lemma distance_attains_inf:
  6.2446 +  fixes a :: "'a::heine_borel"
  6.2447 +  assumes "closed s" and "s \<noteq> {}"
  6.2448 +  obtains x where "x\<in>s" "\<And>y. y \<in> s \<Longrightarrow> dist a x \<le> dist a y"
  6.2449 +proof -
  6.2450 +  from assms obtain b where "b \<in> s" by auto
  6.2451 +  let ?B = "s \<inter> cball a (dist b a)"
  6.2452 +  have "?B \<noteq> {}" using \<open>b \<in> s\<close>
  6.2453 +    by (auto simp: dist_commute)
  6.2454 +  moreover have "continuous_on ?B (dist a)"
  6.2455 +    by (auto intro!: continuous_at_imp_continuous_on continuous_dist continuous_ident continuous_const)
  6.2456 +  moreover have "compact ?B"
  6.2457 +    by (intro closed_Int_compact \<open>closed s\<close> compact_cball)
  6.2458 +  ultimately obtain x where "x \<in> ?B" "\<forall>y\<in>?B. dist a x \<le> dist a y"
  6.2459 +    by (metis continuous_attains_inf)
  6.2460 +  with that show ?thesis by fastforce
  6.2461 +qed
  6.2462 +
  6.2463 +
  6.2464 +subsection \<open>Cartesian products\<close>
  6.2465 +
  6.2466 +lemma bounded_Times:
  6.2467 +  assumes "bounded s" "bounded t"
  6.2468 +  shows "bounded (s \<times> t)"
  6.2469 +proof -
  6.2470 +  obtain x y a b where "\<forall>z\<in>s. dist x z \<le> a" "\<forall>z\<in>t. dist y z \<le> b"
  6.2471 +    using assms [unfolded bounded_def] by auto
  6.2472 +  then have "\<forall>z\<in>s \<times> t. dist (x, y) z \<le> sqrt (a\<^sup>2 + b\<^sup>2)"
  6.2473 +    by (auto simp: dist_Pair_Pair real_sqrt_le_mono add_mono power_mono)
  6.2474 +  then show ?thesis unfolding bounded_any_center [where a="(x, y)"] by auto
  6.2475 +qed
  6.2476 +
  6.2477 +lemma mem_Times_iff: "x \<in> A \<times> B \<longleftrightarrow> fst x \<in> A \<and> snd x \<in> B"
  6.2478 +  by (induct x) simp
  6.2479 +
  6.2480 +lemma seq_compact_Times: "seq_compact s \<Longrightarrow> seq_compact t \<Longrightarrow> seq_compact (s \<times> t)"
  6.2481 +  unfolding seq_compact_def
  6.2482 +  apply clarify
  6.2483 +  apply (drule_tac x="fst \<circ> f" in spec)
  6.2484 +  apply (drule mp, simp add: mem_Times_iff)
  6.2485 +  apply (clarify, rename_tac l1 r1)
  6.2486 +  apply (drule_tac x="snd \<circ> f \<circ> r1" in spec)
  6.2487 +  apply (drule mp, simp add: mem_Times_iff)
  6.2488 +  apply (clarify, rename_tac l2 r2)
  6.2489 +  apply (rule_tac x="(l1, l2)" in rev_bexI, simp)
  6.2490 +  apply (rule_tac x="r1 \<circ> r2" in exI)
  6.2491 +  apply (rule conjI, simp add: strict_mono_def)
  6.2492 +  apply (drule_tac f=r2 in LIMSEQ_subseq_LIMSEQ, assumption)
  6.2493 +  apply (drule (1) tendsto_Pair) back
  6.2494 +  apply (simp add: o_def)
  6.2495 +  done
  6.2496 +
  6.2497 +lemma compact_Times:
  6.2498 +  assumes "compact s" "compact t"
  6.2499 +  shows "compact (s \<times> t)"
  6.2500 +proof (rule compactI)
  6.2501 +  fix C
  6.2502 +  assume C: "\<forall>t\<in>C. open t" "s \<times> t \<subseteq> \<Union>C"
  6.2503 +  have "\<forall>x\<in>s. \<exists>a. open a \<and> x \<in> a \<and> (\<exists>d\<subseteq>C. finite d \<and> a \<times> t \<subseteq> \<Union>d)"
  6.2504 +  proof
  6.2505 +    fix x
  6.2506 +    assume "x \<in> s"
  6.2507 +    have "\<forall>y\<in>t. \<exists>a b c. c \<in> C \<and> open a \<and> open b \<and> x \<in> a \<and> y \<in> b \<and> a \<times> b \<subseteq> c" (is "\<forall>y\<in>t. ?P y")
  6.2508 +    proof
  6.2509 +      fix y
  6.2510 +      assume "y \<in> t"
  6.2511 +      with \<open>x \<in> s\<close> C obtain c where "c \<in> C" "(x, y) \<in> c" "open c" by auto
  6.2512 +      then show "?P y" by (auto elim!: open_prod_elim)
  6.2513 +    qed
  6.2514 +    then obtain a b c where b: "\<And>y. y \<in> t \<Longrightarrow> open (b y)"
  6.2515 +      and c: "\<And>y. y \<in> t \<Longrightarrow> c y \<in> C \<and> open (a y) \<and> open (b y) \<and> x \<in> a y \<and> y \<in> b y \<and> a y \<times> b y \<subseteq> c y"
  6.2516 +      by metis
  6.2517 +    then have "\<forall>y\<in>t. open (b y)" "t \<subseteq> (\<Union>y\<in>t. b y)" by auto
  6.2518 +    with compactE_image[OF \<open>compact t\<close>] obtain D where D: "D \<subseteq> t" "finite D" "t \<subseteq> (\<Union>y\<in>D. b y)"
  6.2519 +      by metis
  6.2520 +    moreover from D c have "(\<Inter>y\<in>D. a y) \<times> t \<subseteq> (\<Union>y\<in>D. c y)"
  6.2521 +      by (fastforce simp: subset_eq)
  6.2522 +    ultimately show "\<exists>a. open a \<and> x \<in> a \<and> (\<exists>d\<subseteq>C. finite d \<and> a \<times> t \<subseteq> \<Union>d)"
  6.2523 +      using c by (intro exI[of _ "c`D"] exI[of _ "\<Inter>(a`D)"] conjI) (auto intro!: open_INT)
  6.2524 +  qed
  6.2525 +  then obtain a d where a: "\<And>x. x\<in>s \<Longrightarrow> open (a x)" "s \<subseteq> (\<Union>x\<in>s. a x)"
  6.2526 +    and d: "\<And>x. x \<in> s \<Longrightarrow> d x \<subseteq> C \<and> finite (d x) \<and> a x \<times> t \<subseteq> \<Union>d x"
  6.2527 +    unfolding subset_eq UN_iff by metis
  6.2528 +  moreover
  6.2529 +  from compactE_image[OF \<open>compact s\<close> a]
  6.2530 +  obtain e where e: "e \<subseteq> s" "finite e" and s: "s \<subseteq> (\<Union>x\<in>e. a x)"
  6.2531 +    by auto
  6.2532 +  moreover
  6.2533 +  {
  6.2534 +    from s have "s \<times> t \<subseteq> (\<Union>x\<in>e. a x \<times> t)"
  6.2535 +      by auto
  6.2536 +    also have "\<dots> \<subseteq> (\<Union>x\<in>e. \<Union>d x)"
  6.2537 +      using d \<open>e \<subseteq> s\<close> by (intro UN_mono) auto
  6.2538 +    finally have "s \<times> t \<subseteq> (\<Union>x\<in>e. \<Union>d x)" .
  6.2539 +  }
  6.2540 +  ultimately show "\<exists>C'\<subseteq>C. finite C' \<and> s \<times> t \<subseteq> \<Union>C'"
  6.2541 +    by (intro exI[of _ "(\<Union>x\<in>e. d x)"]) (auto simp: subset_eq)
  6.2542 +qed
  6.2543 +
  6.2544 +text\<open>Hence some useful properties follow quite easily.\<close>
  6.2545 +
  6.2546 +lemma compact_scaling:
  6.2547 +  fixes s :: "'a::real_normed_vector set"
  6.2548 +  assumes "compact s"
  6.2549 +  shows "compact ((\<lambda>x. c *\<^sub>R x) ` s)"
  6.2550 +proof -
  6.2551 +  let ?f = "\<lambda>x. scaleR c x"
  6.2552 +  have *: "bounded_linear ?f" by (rule bounded_linear_scaleR_right)
  6.2553 +  show ?thesis
  6.2554 +    using compact_continuous_image[of s ?f] continuous_at_imp_continuous_on[of s ?f]
  6.2555 +    using linear_continuous_at[OF *] assms
  6.2556 +    by auto
  6.2557 +qed
  6.2558 +
  6.2559 +lemma compact_negations:
  6.2560 +  fixes s :: "'a::real_normed_vector set"
  6.2561 +  assumes "compact s"
  6.2562 +  shows "compact ((\<lambda>x. - x) ` s)"
  6.2563 +  using compact_scaling [OF assms, of "- 1"] by auto
  6.2564 +
  6.2565 +lemma compact_sums:
  6.2566 +  fixes s t :: "'a::real_normed_vector set"
  6.2567 +  assumes "compact s"
  6.2568 +    and "compact t"
  6.2569 +  shows "compact {x + y | x y. x \<in> s \<and> y \<in> t}"
  6.2570 +proof -
  6.2571 +  have *: "{x + y | x y. x \<in> s \<and> y \<in> t} = (\<lambda>z. fst z + snd z) ` (s \<times> t)"
  6.2572 +    apply auto
  6.2573 +    unfolding image_iff
  6.2574 +    apply (rule_tac x="(xa, y)" in bexI)
  6.2575 +    apply auto
  6.2576 +    done
  6.2577 +  have "continuous_on (s \<times> t) (\<lambda>z. fst z + snd z)"
  6.2578 +    unfolding continuous_on by (rule ballI) (intro tendsto_intros)
  6.2579 +  then show ?thesis
  6.2580 +    unfolding * using compact_continuous_image compact_Times [OF assms] by auto
  6.2581 +qed
  6.2582 +
  6.2583 +lemma compact_differences:
  6.2584 +  fixes s t :: "'a::real_normed_vector set"
  6.2585 +  assumes "compact s"
  6.2586 +    and "compact t"
  6.2587 +  shows "compact {x - y | x y. x \<in> s \<and> y \<in> t}"
  6.2588 +proof-
  6.2589 +  have "{x - y | x y. x\<in>s \<and> y \<in> t} =  {x + y | x y. x \<in> s \<and> y \<in> (uminus ` t)}"
  6.2590 +    apply auto
  6.2591 +    apply (rule_tac x= xa in exI, auto)
  6.2592 +    done
  6.2593 +  then show ?thesis
  6.2594 +    using compact_sums[OF assms(1) compact_negations[OF assms(2)]] by auto
  6.2595 +qed
  6.2596 +
  6.2597 +lemma compact_translation:
  6.2598 +  fixes s :: "'a::real_normed_vector set"
  6.2599 +  assumes "compact s"
  6.2600 +  shows "compact ((\<lambda>x. a + x) ` s)"
  6.2601 +proof -
  6.2602 +  have "{x + y |x y. x \<in> s \<and> y \<in> {a}} = (\<lambda>x. a + x) ` s"
  6.2603 +    by auto
  6.2604 +  then show ?thesis
  6.2605 +    using compact_sums[OF assms compact_sing[of a]] by auto
  6.2606 +qed
  6.2607 +
  6.2608 +lemma compact_affinity:
  6.2609 +  fixes s :: "'a::real_normed_vector set"
  6.2610 +  assumes "compact s"
  6.2611 +  shows "compact ((\<lambda>x. a + c *\<^sub>R x) ` s)"
  6.2612 +proof -
  6.2613 +  have "op + a ` op *\<^sub>R c ` s = (\<lambda>x. a + c *\<^sub>R x) ` s"
  6.2614 +    by auto
  6.2615 +  then show ?thesis
  6.2616 +    using compact_translation[OF compact_scaling[OF assms], of a c] by auto
  6.2617 +qed
  6.2618 +
  6.2619 +text \<open>Hence we get the following.\<close>
  6.2620 +
  6.2621 +lemma compact_sup_maxdistance:
  6.2622 +  fixes s :: "'a::metric_space set"
  6.2623 +  assumes "compact s"
  6.2624 +    and "s \<noteq> {}"
  6.2625 +  shows "\<exists>x\<in>s. \<exists>y\<in>s. \<forall>u\<in>s. \<forall>v\<in>s. dist u v \<le> dist x y"
  6.2626 +proof -
  6.2627 +  have "compact (s \<times> s)"
  6.2628 +    using \<open>compact s\<close> by (intro compact_Times)
  6.2629 +  moreover have "s \<times> s \<noteq> {}"
  6.2630 +    using \<open>s \<noteq> {}\<close> by auto
  6.2631 +  moreover have "continuous_on (s \<times> s) (\<lambda>x. dist (fst x) (snd x))"
  6.2632 +    by (intro continuous_at_imp_continuous_on ballI continuous_intros)
  6.2633 +  ultimately show ?thesis
  6.2634 +    using continuous_attains_sup[of "s \<times> s" "\<lambda>x. dist (fst x) (snd x)"] by auto
  6.2635 +qed
  6.2636 +
  6.2637 +
  6.2638 +subsection \<open>The diameter of a set.\<close>
  6.2639 +
  6.2640 +definition diameter :: "'a::metric_space set \<Rightarrow> real" where
  6.2641 +  "diameter S = (if S = {} then 0 else SUP (x,y):S\<times>S. dist x y)"
  6.2642 +
  6.2643 +lemma diameter_empty [simp]: "diameter{} = 0"
  6.2644 +  by (auto simp: diameter_def)
  6.2645 +
  6.2646 +lemma diameter_singleton [simp]: "diameter{x} = 0"
  6.2647 +  by (auto simp: diameter_def)
  6.2648 +
  6.2649 +lemma diameter_le:
  6.2650 +  assumes "S \<noteq> {} \<or> 0 \<le> d"
  6.2651 +      and no: "\<And>x y. \<lbrakk>x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> norm(x - y) \<le> d"
  6.2652 +    shows "diameter S \<le> d"
  6.2653 +using assms
  6.2654 +  by (auto simp: dist_norm diameter_def intro: cSUP_least)
  6.2655 +
  6.2656 +lemma diameter_bounded_bound:
  6.2657 +  fixes s :: "'a :: metric_space set"
  6.2658 +  assumes s: "bounded s" "x \<in> s" "y \<in> s"
  6.2659 +  shows "dist x y \<le> diameter s"
  6.2660 +proof -
  6.2661 +  from s obtain z d where z: "\<And>x. x \<in> s \<Longrightarrow> dist z x \<le> d"
  6.2662 +    unfolding bounded_def by auto
  6.2663 +  have "bdd_above (case_prod dist ` (s\<times>s))"
  6.2664 +  proof (intro bdd_aboveI, safe)
  6.2665 +    fix a b
  6.2666 +    assume "a \<in> s" "b \<in> s"
  6.2667 +    with z[of a] z[of b] dist_triangle[of a b z]
  6.2668 +    show "dist a b \<le> 2 * d"
  6.2669 +      by (simp add: dist_commute)
  6.2670 +  qed
  6.2671 +  moreover have "(x,y) \<in> s\<times>s" using s by auto
  6.2672 +  ultimately have "dist x y \<le> (SUP (x,y):s\<times>s. dist x y)"
  6.2673 +    by (rule cSUP_upper2) simp
  6.2674 +  with \<open>x \<in> s\<close> show ?thesis
  6.2675 +    by (auto simp: diameter_def)
  6.2676 +qed
  6.2677 +
  6.2678 +lemma diameter_lower_bounded:
  6.2679 +  fixes s :: "'a :: metric_space set"
  6.2680 +  assumes s: "bounded s"
  6.2681 +    and d: "0 < d" "d < diameter s"
  6.2682 +  shows "\<exists>x\<in>s. \<exists>y\<in>s. d < dist x y"
  6.2683 +proof (rule ccontr)
  6.2684 +  assume contr: "\<not> ?thesis"
  6.2685 +  moreover have "s \<noteq> {}"
  6.2686 +    using d by (auto simp: diameter_def)
  6.2687 +  ultimately have "diameter s \<le> d"
  6.2688 +    by (auto simp: not_less diameter_def intro!: cSUP_least)
  6.2689 +  with \<open>d < diameter s\<close> show False by auto
  6.2690 +qed
  6.2691 +
  6.2692 +lemma diameter_bounded:
  6.2693 +  assumes "bounded s"
  6.2694 +  shows "\<forall>x\<in>s. \<forall>y\<in>s. dist x y \<le> diameter s"
  6.2695 +    and "\<forall>d>0. d < diameter s \<longrightarrow> (\<exists>x\<in>s. \<exists>y\<in>s. dist x y > d)"
  6.2696 +  using diameter_bounded_bound[of s] diameter_lower_bounded[of s] assms
  6.2697 +  by auto
  6.2698 +
  6.2699 +lemma diameter_compact_attained:
  6.2700 +  assumes "compact s"
  6.2701 +    and "s \<noteq> {}"
  6.2702 +  shows "\<exists>x\<in>s. \<exists>y\<in>s. dist x y = diameter s"
  6.2703 +proof -
  6.2704 +  have b: "bounded s" using assms(1)
  6.2705 +    by (rule compact_imp_bounded)
  6.2706 +  then obtain x y where xys: "x\<in>s" "y\<in>s"
  6.2707 +    and xy: "\<forall>u\<in>s. \<forall>v\<in>s. dist u v \<le> dist x y"
  6.2708 +    using compact_sup_maxdistance[OF assms] by auto
  6.2709 +  then have "diameter s \<le> dist x y"
  6.2710 +    unfolding diameter_def
  6.2711 +    apply clarsimp
  6.2712 +    apply (rule cSUP_least, fast+)
  6.2713 +    done
  6.2714 +  then show ?thesis
  6.2715 +    by (metis b diameter_bounded_bound order_antisym xys)
  6.2716 +qed
  6.2717 +
  6.2718 +lemma diameter_ge_0:
  6.2719 +  assumes "bounded S"  shows "0 \<le> diameter S"
  6.2720 +  by (metis all_not_in_conv assms diameter_bounded_bound diameter_empty dist_self order_refl)
  6.2721 +
  6.2722 +lemma diameter_subset:
  6.2723 +  assumes "S \<subseteq> T" "bounded T"
  6.2724 +  shows "diameter S \<le> diameter T"
  6.2725 +proof (cases "S = {} \<or> T = {}")
  6.2726 +  case True
  6.2727 +  with assms show ?thesis
  6.2728 +    by (force simp: diameter_ge_0)
  6.2729 +next
  6.2730 +  case False
  6.2731 +  then have "bdd_above ((\<lambda>x. case x of (x, xa) \<Rightarrow> dist x xa) ` (T \<times> T))"
  6.2732 +    using \<open>bounded T\<close> diameter_bounded_bound by (force simp: bdd_above_def)
  6.2733 +  with False \<open>S \<subseteq> T\<close> show ?thesis
  6.2734 +    apply (simp add: diameter_def)
  6.2735 +    apply (rule cSUP_subset_mono, auto)
  6.2736 +    done
  6.2737 +qed
  6.2738 +
  6.2739 +lemma diameter_closure:
  6.2740 +  assumes "bounded S"
  6.2741 +  shows "diameter(closure S) = diameter S"
  6.2742 +proof (rule order_antisym)
  6.2743 +  have "False" if "diameter S < diameter (closure S)"
  6.2744 +  proof -
  6.2745 +    define d where "d = diameter(closure S) - diameter(S)"
  6.2746 +    have "d > 0"
  6.2747 +      using that by (simp add: d_def)
  6.2748 +    then have "diameter(closure(S)) - d / 2 < diameter(closure(S))"
  6.2749 +      by simp
  6.2750 +    have dd: "diameter (closure S) - d / 2 = (diameter(closure(S)) + diameter(S)) / 2"
  6.2751 +      by (simp add: d_def divide_simps)
  6.2752 +     have bocl: "bounded (closure S)"
  6.2753 +      using assms by blast
  6.2754 +    moreover have "0 \<le> diameter S"
  6.2755 +      using assms diameter_ge_0 by blast
  6.2756 +    ultimately obtain x y where "x \<in> closure S" "y \<in> closure S" and xy: "diameter(closure(S)) - d / 2 < dist x y"
  6.2757 +      using diameter_bounded(2) [OF bocl, rule_format, of "diameter(closure(S)) - d / 2"] \<open>d > 0\<close> d_def by auto
  6.2758 +    then obtain x' y' where x'y': "x' \<in> S" "dist x' x < d/4" "y' \<in> S" "dist y' y < d/4"
  6.2759 +      using closure_approachable
  6.2760 +      by (metis \<open>0 < d\<close> zero_less_divide_iff zero_less_numeral)
  6.2761 +    then have "dist x' y' \<le> diameter S"
  6.2762 +      using assms diameter_bounded_bound by blast
  6.2763 +    with x'y' have "dist x y \<le> d / 4 + diameter S + d / 4"
  6.2764 +      by (meson add_mono_thms_linordered_semiring(1) dist_triangle dist_triangle3 less_eq_real_def order_trans)
  6.2765 +    then show ?thesis
  6.2766 +      using xy d_def by linarith
  6.2767 +  qed
  6.2768 +  then show "diameter (closure S) \<le> diameter S"
  6.2769 +    by fastforce
  6.2770 +  next
  6.2771 +    show "diameter S \<le> diameter (closure S)"
  6.2772 +      by (simp add: assms bounded_closure closure_subset diameter_subset)
  6.2773 +qed
  6.2774 +
  6.2775 +lemma diameter_cball [simp]:
  6.2776 +  fixes a :: "'a::euclidean_space"
  6.2777 +  shows "diameter(cball a r) = (if r < 0 then 0 else 2*r)"
  6.2778 +proof -
  6.2779 +  have "diameter(cball a r) = 2*r" if "r \<ge> 0"
  6.2780 +  proof (rule order_antisym)
  6.2781 +    show "diameter (cball a r) \<le> 2*r"
  6.2782 +    proof (rule diameter_le)
  6.2783 +      fix x y assume "x \<in> cball a r" "y \<in> cball a r"
  6.2784 +      then have "norm (x - a) \<le> r" "norm (a - y) \<le> r"
  6.2785 +        by (auto simp: dist_norm norm_minus_commute)
  6.2786 +      then have "norm (x - y) \<le> r+r"
  6.2787 +        using norm_diff_triangle_le by blast
  6.2788 +      then show "norm (x - y) \<le> 2*r" by simp
  6.2789 +    qed (simp add: that)
  6.2790 +    have "2*r = dist (a + r *\<^sub>R (SOME i. i \<in> Basis)) (a - r *\<^sub>R (SOME i. i \<in> Basis))"
  6.2791 +      apply (simp add: dist_norm)
  6.2792 +      by (metis abs_of_nonneg mult.right_neutral norm_numeral norm_scaleR norm_some_Basis real_norm_def scaleR_2 that)
  6.2793 +    also have "... \<le> diameter (cball a r)"
  6.2794 +      apply (rule diameter_bounded_bound)
  6.2795 +      using that by (auto simp: dist_norm)
  6.2796 +    finally show "2*r \<le> diameter (cball a r)" .
  6.2797 +  qed
  6.2798 +  then show ?thesis by simp
  6.2799 +qed
  6.2800 +
  6.2801 +lemma diameter_ball [simp]:
  6.2802 +  fixes a :: "'a::euclidean_space"
  6.2803 +  shows "diameter(ball a r) = (if r < 0 then 0 else 2*r)"
  6.2804 +proof -
  6.2805 +  have "diameter(ball a r) = 2*r" if "r > 0"
  6.2806 +    by (metis bounded_ball diameter_closure closure_ball diameter_cball less_eq_real_def linorder_not_less that)
  6.2807 +  then show ?thesis
  6.2808 +    by (simp add: diameter_def)
  6.2809 +qed
  6.2810 +
  6.2811 +lemma diameter_closed_interval [simp]: "diameter {a..b} = (if b < a then 0 else b-a)"
  6.2812 +proof -
  6.2813 +  have "{a .. b} = cball ((a+b)/2) ((b-a)/2)"
  6.2814 +    by (auto simp: dist_norm abs_if divide_simps split: if_split_asm)
  6.2815 +  then show ?thesis
  6.2816 +    by simp
  6.2817 +qed
  6.2818 +
  6.2819 +lemma diameter_open_interval [simp]: "diameter {a<..<b} = (if b < a then 0 else b-a)"
  6.2820 +proof -
  6.2821 +  have "{a <..< b} = ball ((a+b)/2) ((b-a)/2)"
  6.2822 +    by (auto simp: dist_norm abs_if divide_simps split: if_split_asm)
  6.2823 +  then show ?thesis
  6.2824 +    by simp
  6.2825 +qed
  6.2826 +
  6.2827 +proposition Lebesgue_number_lemma:
  6.2828 +  assumes "compact S" "\<C> \<noteq> {}" "S \<subseteq> \<Union>\<C>" and ope: "\<And>B. B \<in> \<C> \<Longrightarrow> open B"
  6.2829 +  obtains \<delta> where "0 < \<delta>" "\<And>T. \<lbrakk>T \<subseteq> S; diameter T < \<delta>\<rbrakk> \<Longrightarrow> \<exists>B \<in> \<C>. T \<subseteq> B"
  6.2830 +proof (cases "S = {}")
  6.2831 +  case True
  6.2832 +  then show ?thesis
  6.2833 +    by (metis \<open>\<C> \<noteq> {}\<close> zero_less_one empty_subsetI equals0I subset_trans that)
  6.2834 +next
  6.2835 +  case False
  6.2836 +  { fix x assume "x \<in> S"
  6.2837 +    then obtain C where C: "x \<in> C" "C \<in> \<C>"
  6.2838 +      using \<open>S \<subseteq> \<Union>\<C>\<close> by blast
  6.2839 +    then obtain r where r: "r>0" "ball x (2*r) \<subseteq> C"
  6.2840 +      by (metis mult.commute mult_2_right not_le ope openE real_sum_of_halves zero_le_numeral zero_less_mult_iff)
  6.2841 +    then have "\<exists>r C. r > 0 \<and> ball x (2*r) \<subseteq> C \<and> C \<in> \<C>"
  6.2842 +      using C by blast
  6.2843 +  }
  6.2844 +  then obtain r where r: "\<And>x. x \<in> S \<Longrightarrow> r x > 0 \<and> (\<exists>C \<in> \<C>. ball x (2*r x) \<subseteq> C)"
  6.2845 +    by metis
  6.2846 +  then have "S \<subseteq> (\<Union>x \<in> S. ball x (r x))"
  6.2847 +    by auto
  6.2848 +  then obtain \<T> where "finite \<T>" "S \<subseteq> \<Union>\<T>" and \<T>: "\<T> \<subseteq> (\<lambda>x. ball x (r x)) ` S"
  6.2849 +    by (rule compactE [OF \<open>compact S\<close>]) auto
  6.2850 +  then obtain S0 where "S0 \<subseteq> S" "finite S0" and S0: "\<T> = (\<lambda>x. ball x (r x)) ` S0"
  6.2851 +    by (meson finite_subset_image)
  6.2852 +  then have "S0 \<noteq> {}"
  6.2853 +    using False \<open>S \<subseteq> \<Union>\<T>\<close> by auto
  6.2854 +  define \<delta> where "\<delta> = Inf (r ` S0)"
  6.2855 +  have "\<delta> > 0"
  6.2856 +    using \<open>finite S0\<close> \<open>S0 \<subseteq> S\<close> \<open>S0 \<noteq> {}\<close> r by (auto simp: \<delta>_def finite_less_Inf_iff)
  6.2857 +  show ?thesis
  6.2858 +  proof
  6.2859 +    show "0 < \<delta>"
  6.2860 +      by (simp add: \<open>0 < \<delta>\<close>)
  6.2861 +    show "\<exists>B \<in> \<C>. T \<subseteq> B" if "T \<subseteq> S" and dia: "diameter T < \<delta>" for T
  6.2862 +    proof (cases "T = {}")
  6.2863 +      case True
  6.2864 +      then show ?thesis
  6.2865 +        using \<open>\<C> \<noteq> {}\<close> by blast
  6.2866 +    next
  6.2867 +      case False
  6.2868 +      then obtain y where "y \<in> T" by blast
  6.2869 +      then have "y \<in> S"
  6.2870 +        using \<open>T \<subseteq> S\<close> by auto
  6.2871 +      then obtain x where "x \<in> S0" and x: "y \<in> ball x (r x)"
  6.2872 +        using \<open>S \<subseteq> \<Union>\<T>\<close> S0 that by blast
  6.2873 +      have "ball y \<delta> \<subseteq> ball y (r x)"
  6.2874 +        by (metis \<delta>_def \<open>S0 \<noteq> {}\<close> \<open>finite S0\<close> \<open>x \<in> S0\<close> empty_is_image finite_imageI finite_less_Inf_iff imageI less_irrefl not_le subset_ball)
  6.2875 +      also have "... \<subseteq> ball x (2*r x)"
  6.2876 +        by clarsimp (metis dist_commute dist_triangle_less_add mem_ball mult_2 x)
  6.2877 +      finally obtain C where "C \<in> \<C>" "ball y \<delta> \<subseteq> C"
  6.2878 +        by (meson r \<open>S0 \<subseteq> S\<close> \<open>x \<in> S0\<close> dual_order.trans subsetCE)
  6.2879 +      have "bounded T"
  6.2880 +        using \<open>compact S\<close> bounded_subset compact_imp_bounded \<open>T \<subseteq> S\<close> by blast
  6.2881 +      then have "T \<subseteq> ball y \<delta>"
  6.2882 +        using \<open>y \<in> T\<close> dia diameter_bounded_bound by fastforce
  6.2883 +      then show ?thesis
  6.2884 +        apply (rule_tac x=C in bexI)
  6.2885 +        using \<open>ball y \<delta> \<subseteq> C\<close> \<open>C \<in> \<C>\<close> by auto
  6.2886 +    qed
  6.2887 +  qed
  6.2888 +qed
  6.2889 +
  6.2890 +lemma diameter_cbox:
  6.2891 +  fixes a b::"'a::euclidean_space"
  6.2892 +  shows "(\<forall>i \<in> Basis. a \<bullet> i \<le> b \<bullet> i) \<Longrightarrow> diameter (cbox a b) = dist a b"
  6.2893 +  by (force simp: diameter_def intro!: cSup_eq_maximum setL2_mono
  6.2894 +     simp: euclidean_dist_l2[where 'a='a] cbox_def dist_norm)
  6.2895 +
  6.2896 +subsection \<open>Separation between points and sets\<close>
  6.2897 +
  6.2898 +lemma separate_point_closed:
  6.2899 +  fixes s :: "'a::heine_borel set"
  6.2900 +  assumes "closed s" and "a \<notin> s"
  6.2901 +  shows "\<exists>d>0. \<forall>x\<in>s. d \<le> dist a x"
  6.2902 +proof (cases "s = {}")
  6.2903 +  case True
  6.2904 +  then show ?thesis by(auto intro!: exI[where x=1])
  6.2905 +next
  6.2906 +  case False
  6.2907 +  from assms obtain x where "x\<in>s" "\<forall>y\<in>s. dist a x \<le> dist a y"
  6.2908 +    using \<open>s \<noteq> {}\<close> by (blast intro: distance_attains_inf [of s a])
  6.2909 +  with \<open>x\<in>s\<close> show ?thesis using dist_pos_lt[of a x] and\<open>a \<notin> s\<close>
  6.2910 +    by blast
  6.2911 +qed
  6.2912 +
  6.2913 +lemma separate_compact_closed:
  6.2914 +  fixes s t :: "'a::heine_borel set"
  6.2915 +  assumes "compact s"
  6.2916 +    and t: "closed t" "s \<inter> t = {}"
  6.2917 +  shows "\<exists>d>0. \<forall>x\<in>s. \<forall>y\<in>t. d \<le> dist x y"
  6.2918 +proof cases
  6.2919 +  assume "s \<noteq> {} \<and> t \<noteq> {}"
  6.2920 +  then have "s \<noteq> {}" "t \<noteq> {}" by auto
  6.2921 +  let ?inf = "\<lambda>x. infdist x t"
  6.2922 +  have "continuous_on s ?inf"
  6.2923 +    by (auto intro!: continuous_at_imp_continuous_on continuous_infdist continuous_ident)
  6.2924 +  then obtain x where x: "x \<in> s" "\<forall>y\<in>s. ?inf x \<le> ?inf y"
  6.2925 +    using continuous_attains_inf[OF \<open>compact s\<close> \<open>s \<noteq> {}\<close>] by auto
  6.2926 +  then have "0 < ?inf x"
  6.2927 +    using t \<open>t \<noteq> {}\<close> in_closed_iff_infdist_zero by (auto simp: less_le infdist_nonneg)
  6.2928 +  moreover have "\<forall>x'\<in>s. \<forall>y\<in>t. ?inf x \<le> dist x' y"
  6.2929 +    using x by (auto intro: order_trans infdist_le)
  6.2930 +  ultimately show ?thesis by auto
  6.2931 +qed (auto intro!: exI[of _ 1])
  6.2932 +
  6.2933 +lemma separate_closed_compact:
  6.2934 +  fixes s t :: "'a::heine_borel set"
  6.2935 +  assumes "closed s"
  6.2936 +    and "compact t"
  6.2937 +    and "s \<inter> t = {}"
  6.2938 +  shows "\<exists>d>0. \<forall>x\<in>s. \<forall>y\<in>t. d \<le> dist x y"
  6.2939 +proof -
  6.2940 +  have *: "t \<inter> s = {}"
  6.2941 +    using assms(3) by auto
  6.2942 +  show ?thesis
  6.2943 +    using separate_compact_closed[OF assms(2,1) *] by (force simp: dist_commute)
  6.2944 +qed
  6.2945 +
  6.2946 +
  6.2947 +subsection \<open>Compact sets and the closure operation.\<close>
  6.2948 +
  6.2949 +lemma closed_scaling:
  6.2950 +  fixes S :: "'a::real_normed_vector set"
  6.2951 +  assumes "closed S"
  6.2952 +  shows "closed ((\<lambda>x. c *\<^sub>R x) ` S)"
  6.2953 +proof (cases "c = 0")
  6.2954 +  case True then show ?thesis
  6.2955 +    by (auto simp: image_constant_conv)
  6.2956 +next
  6.2957 +  case False
  6.2958 +  from assms have "closed ((\<lambda>x. inverse c *\<^sub>R x) -` S)"
  6.2959 +    by (simp add: continuous_closed_vimage)
  6.2960 +  also have "(\<lambda>x. inverse c *\<^sub>R x) -` S = (\<lambda>x. c *\<^sub>R x) ` S"
  6.2961 +    using \<open>c \<noteq> 0\<close> by (auto elim: image_eqI [rotated])
  6.2962 +  finally show ?thesis .
  6.2963 +qed
  6.2964 +
  6.2965 +lemma closed_negations:
  6.2966 +  fixes S :: "'a::real_normed_vector set"
  6.2967 +  assumes "closed S"
  6.2968 +  shows "closed ((\<lambda>x. -x) ` S)"
  6.2969 +  using closed_scaling[OF assms, of "- 1"] by simp
  6.2970 +
  6.2971 +lemma compact_closed_sums:
  6.2972 +  fixes S :: "'a::real_normed_vector set"
  6.2973 +  assumes "compact S" and "closed T"
  6.2974 +  shows "closed (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
  6.2975 +proof -
  6.2976 +  let ?S = "{x + y |x y. x \<in> S \<and> y \<in> T}"
  6.2977 +  {
  6.2978 +    fix x l
  6.2979 +    assume as: "\<forall>n. x n \<in> ?S"  "(x \<longlongrightarrow> l) sequentially"
  6.2980 +    from as(1) obtain f where f: "\<forall>n. x n = fst (f n) + snd (f n)"  "\<forall>n. fst (f n) \<in> S"  "\<forall>n. snd (f n) \<in> T"
  6.2981 +      using choice[of "\<lambda>n y. x n = (fst y) + (snd y) \<and> fst y \<in> S \<and> snd y \<in> T"] by auto
  6.2982 +    obtain l' r where "l'\<in>S" and r: "strict_mono r" and lr: "(((\<lambda>n. fst (f n)) \<circ> r) \<longlongrightarrow> l') sequentially"
  6.2983 +      using assms(1)[unfolded compact_def, THEN spec[where x="\<lambda> n. fst (f n)"]] using f(2) by auto
  6.2984 +    have "((\<lambda>n. snd (f (r n))) \<longlongrightarrow> l - l') sequentially"
  6.2985 +      using tendsto_diff[OF LIMSEQ_subseq_LIMSEQ[OF as(2) r] lr] and f(1)
  6.2986 +      unfolding o_def
  6.2987 +      by auto
  6.2988 +    then have "l - l' \<in> T"
  6.2989 +      using assms(2)[unfolded closed_sequential_limits,
  6.2990 +        THEN spec[where x="\<lambda> n. snd (f (r n))"],
  6.2991 +        THEN spec[where x="l - l'"]]
  6.2992 +      using f(3)
  6.2993 +      by auto
  6.2994 +    then have "l \<in> ?S"
  6.2995 +      using \<open>l' \<in> S\<close>
  6.2996 +      apply auto
  6.2997 +      apply (rule_tac x=l' in exI)
  6.2998 +      apply (rule_tac x="l - l'" in exI, auto)
  6.2999 +      done
  6.3000 +  }
  6.3001 +  moreover have "?S = (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
  6.3002 +    by force
  6.3003 +  ultimately show ?thesis
  6.3004 +    unfolding closed_sequential_limits
  6.3005 +    by (metis (no_types, lifting))
  6.3006 +qed
  6.3007 +
  6.3008 +lemma closed_compact_sums:
  6.3009 +  fixes S T :: "'a::real_normed_vector set"
  6.3010 +  assumes "closed S" "compact T"
  6.3011 +  shows "closed (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
  6.3012 +proof -
  6.3013 +  have "(\<Union>x\<in> T. \<Union>y \<in> S. {x + y}) = (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
  6.3014 +    by auto
  6.3015 +  then show ?thesis
  6.3016 +    using compact_closed_sums[OF assms(2,1)] by simp
  6.3017 +qed
  6.3018 +
  6.3019 +lemma compact_closed_differences:
  6.3020 +  fixes S T :: "'a::real_normed_vector set"
  6.3021 +  assumes "compact S" "closed T"
  6.3022 +  shows "closed (\<Union>x\<in> S. \<Union>y \<in> T. {x - y})"
  6.3023 +proof -
  6.3024 +  have "(\<Union>x\<in> S. \<Union>y \<in> uminus ` T. {x + y}) = (\<Union>x\<in> S. \<Union>y \<in> T. {x - y})"
  6.3025 +    by force
  6.3026 +  then show ?thesis
  6.3027 +    using compact_closed_sums[OF assms(1) closed_negations[OF assms(2)]] by auto
  6.3028 +qed
  6.3029 +
  6.3030 +lemma closed_compact_differences:
  6.3031 +  fixes S T :: "'a::real_normed_vector set"
  6.3032 +  assumes "closed S" "compact T"
  6.3033 +  shows "closed (\<Union>x\<in> S. \<Union>y \<in> T. {x - y})"
  6.3034 +proof -
  6.3035 +  have "(\<Union>x\<in> S. \<Union>y \<in> uminus ` T. {x + y}) = {x - y |x y. x \<in> S \<and> y \<in> T}"
  6.3036 +    by auto
  6.3037 + then show ?thesis
  6.3038 +  using closed_compact_sums[OF assms(1) compact_negations[OF assms(2)]] by simp
  6.3039 +qed
  6.3040 +
  6.3041 +lemma closed_translation:
  6.3042 +  fixes a :: "'a::real_normed_vector"
  6.3043 +  assumes "closed S"
  6.3044 +  shows "closed ((\<lambda>x. a + x) ` S)"
  6.3045 +proof -
  6.3046 +  have "(\<Union>x\<in> {a}. \<Union>y \<in> S. {x + y}) = (op + a ` S)" by auto
  6.3047 +  then show ?thesis
  6.3048 +    using compact_closed_sums[OF compact_sing[of a] assms] by auto
  6.3049 +qed
  6.3050 +
  6.3051 +lemma translation_Compl:
  6.3052 +  fixes a :: "'a::ab_group_add"
  6.3053 +  shows "(\<lambda>x. a + x) ` (- t) = - ((\<lambda>x. a + x) ` t)"
  6.3054 +  apply (auto simp: image_iff)
  6.3055 +  apply (rule_tac x="x - a" in bexI, auto)
  6.3056 +  done
  6.3057 +
  6.3058 +lemma translation_UNIV:
  6.3059 +  fixes a :: "'a::ab_group_add"
  6.3060 +  shows "range (\<lambda>x. a + x) = UNIV"
  6.3061 +  apply (auto simp: image_iff)
  6.3062 +  apply (rule_tac x="x - a" in exI, auto)
  6.3063 +  done
  6.3064 +
  6.3065 +lemma translation_diff:
  6.3066 +  fixes a :: "'a::ab_group_add"
  6.3067 +  shows "(\<lambda>x. a + x) ` (s - t) = ((\<lambda>x. a + x) ` s) - ((\<lambda>x. a + x) ` t)"
  6.3068 +  by auto
  6.3069 +
  6.3070 +lemma translation_Int:
  6.3071 +  fixes a :: "'a::ab_group_add"
  6.3072 +  shows "(\<lambda>x. a + x) ` (s \<inter> t) = ((\<lambda>x. a + x) ` s) \<inter> ((\<lambda>x. a + x) ` t)"
  6.3073 +  by auto
  6.3074 +
  6.3075 +lemma closure_translation:
  6.3076 +  fixes a :: "'a::real_normed_vector"
  6.3077 +  shows "closure ((\<lambda>x. a + x) ` s) = (\<lambda>x. a + x) ` (closure s)"
  6.3078 +proof -
  6.3079 +  have *: "op + a ` (- s) = - op + a ` s"
  6.3080 +    apply auto
  6.3081 +    unfolding image_iff
  6.3082 +    apply (rule_tac x="x - a" in bexI, auto)
  6.3083 +    done
  6.3084 +  show ?thesis
  6.3085 +    unfolding closure_interior translation_Compl
  6.3086 +    using interior_translation[of a "- s"]
  6.3087 +    unfolding *
  6.3088 +    by auto
  6.3089 +qed
  6.3090 +
  6.3091 +lemma frontier_translation:
  6.3092 +  fixes a :: "'a::real_normed_vector"
  6.3093 +  shows "frontier((\<lambda>x. a + x) ` s) = (\<lambda>x. a + x) ` (frontier s)"
  6.3094 +  unfolding frontier_def translation_diff interior_translation closure_translation
  6.3095 +  by auto
  6.3096 +
  6.3097 +lemma sphere_translation:
  6.3098 +  fixes a :: "'n::euclidean_space"
  6.3099 +  shows "sphere (a+c) r = op+a ` sphere c r"
  6.3100 +apply safe
  6.3101 +apply (rule_tac x="x-a" in image_eqI)
  6.3102 +apply (auto simp: dist_norm algebra_simps)
  6.3103 +done
  6.3104 +
  6.3105 +lemma cball_translation:
  6.3106 +  fixes a :: "'n::euclidean_space"
  6.3107 +  shows "cball (a+c) r = op+a ` cball c r"
  6.3108 +apply safe
  6.3109 +apply (rule_tac x="x-a" in image_eqI)
  6.3110 +apply (auto simp: dist_norm algebra_simps)
  6.3111 +done
  6.3112 +
  6.3113 +lemma ball_translation:
  6.3114 +  fixes a :: "'n::euclidean_space"
  6.3115 +  shows "ball (a+c) r = op+a ` ball c r"
  6.3116 +apply safe
  6.3117 +apply (rule_tac x="x-a" in image_eqI)
  6.3118 +apply (auto simp: dist_norm algebra_simps)
  6.3119 +done
  6.3120 +
  6.3121 +
  6.3122 +subsection \<open>Closure of halfspaces and hyperplanes\<close>
  6.3123 +
  6.3124 +lemma continuous_on_closed_Collect_le:
  6.3125 +  fixes f g :: "'a::t2_space \<Rightarrow> real"
  6.3126 +  assumes f: "continuous_on s f" and g: "continuous_on s g" and s: "closed s"
  6.3127 +  shows "closed {x \<in> s. f x \<le> g x}"
  6.3128 +proof -
  6.3129 +  have "closed ((\<lambda>x. g x - f x) -` {0..} \<inter> s)"
  6.3130 +    using closed_real_atLeast continuous_on_diff [OF g f]
  6.3131 +    by (simp add: continuous_on_closed_vimage [OF s])
  6.3132 +  also have "((\<lambda>x. g x - f x) -` {0..} \<inter> s) = {x\<in>s. f x \<le> g x}"
  6.3133 +    by auto
  6.3134 +  finally show ?thesis .
  6.3135 +qed
  6.3136 +
  6.3137 +lemma continuous_at_inner: "continuous (at x) (inner a)"
  6.3138 +  unfolding continuous_at by (intro tendsto_intros)
  6.3139 +
  6.3140 +lemma closed_halfspace_le: "closed {x. inner a x \<le> b}"
  6.3141 +  by (simp add: closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3142 +
  6.3143 +lemma closed_halfspace_ge: "closed {x. inner a x \<ge> b}"
  6.3144 +  by (simp add: closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3145 +
  6.3146 +lemma closed_hyperplane: "closed {x. inner a x = b}"
  6.3147 +  by (simp add: closed_Collect_eq continuous_on_inner continuous_on_const continuous_on_id)
  6.3148 +
  6.3149 +lemma closed_halfspace_component_le: "closed {x::'a::euclidean_space. x\<bullet>i \<le> a}"
  6.3150 +  by (simp add: closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3151 +
  6.3152 +lemma closed_halfspace_component_ge: "closed {x::'a::euclidean_space. x\<bullet>i \<ge> a}"
  6.3153 +  by (simp add: closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3154 +
  6.3155 +lemma closed_interval_left:
  6.3156 +  fixes b :: "'a::euclidean_space"
  6.3157 +  shows "closed {x::'a. \<forall>i\<in>Basis. x\<bullet>i \<le> b\<bullet>i}"
  6.3158 +  by (simp add: Collect_ball_eq closed_INT closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3159 +
  6.3160 +lemma closed_interval_right:
  6.3161 +  fixes a :: "'a::euclidean_space"
  6.3162 +  shows "closed {x::'a. \<forall>i\<in>Basis. a\<bullet>i \<le> x\<bullet>i}"
  6.3163 +  by (simp add: Collect_ball_eq closed_INT closed_Collect_le continuous_on_inner continuous_on_const continuous_on_id)
  6.3164 +
  6.3165 +lemma continuous_le_on_closure:
  6.3166 +  fixes a::real
  6.3167 +  assumes f: "continuous_on (closure s) f"
  6.3168 +      and x: "x \<in> closure(s)"
  6.3169 +      and xlo: "\<And>x. x \<in> s ==> f(x) \<le> a"
  6.3170 +    shows "f(x) \<le> a"
  6.3171 +    using image_closure_subset [OF f]
  6.3172 +  using image_closure_subset [OF f] closed_halfspace_le [of "1::real" a] assms
  6.3173 +  by force
  6.3174 +
  6.3175 +lemma continuous_ge_on_closure:
  6.3176 +  fixes a::real
  6.3177 +  assumes f: "continuous_on (closure s) f"
  6.3178 +      and x: "x \<in> closure(s)"
  6.3179 +      and xlo: "\<And>x. x \<in> s ==> f(x) \<ge> a"
  6.3180 +    shows "f(x) \<ge> a"
  6.3181 +  using image_closure_subset [OF f] closed_halfspace_ge [of a "1::real"] assms
  6.3182 +  by force
  6.3183 +
  6.3184 +lemma Lim_component_le:
  6.3185 +  fixes f :: "'a \<Rightarrow> 'b::euclidean_space"
  6.3186 +  assumes "(f \<longlongrightarrow> l) net"
  6.3187 +    and "\<not> (trivial_limit net)"
  6.3188 +    and "eventually (\<lambda>x. f(x)\<bullet>i \<le> b) net"
  6.3189 +  shows "l\<bullet>i \<le> b"
  6.3190 +  by (rule tendsto_le[OF assms(2) tendsto_const tendsto_inner[OF assms(1) tendsto_const] assms(3)])
  6.3191 +
  6.3192 +lemma Lim_component_ge:
  6.3193 +  fixes f :: "'a \<Rightarrow> 'b::euclidean_space"
  6.3194 +  assumes "(f \<longlongrightarrow> l) net"
  6.3195 +    and "\<not> (trivial_limit net)"
  6.3196 +    and "eventually (\<lambda>x. b \<le> (f x)\<bullet>i) net"
  6.3197 +  shows "b \<le> l\<bullet>i"
  6.3198 +  by (rule tendsto_le[OF assms(2) tendsto_inner[OF assms(1) tendsto_const] tendsto_const assms(3)])
  6.3199 +
  6.3200 +lemma Lim_component_eq:
  6.3201 +  fixes f :: "'a \<Rightarrow> 'b::euclidean_space"
  6.3202 +  assumes net: "(f \<longlongrightarrow> l) net" "\<not> trivial_limit net"
  6.3203 +    and ev:"eventually (\<lambda>x. f(x)\<bullet>i = b) net"
  6.3204 +  shows "l\<bullet>i = b"
  6.3205 +  using ev[unfolded order_eq_iff eventually_conj_iff]
  6.3206 +  using Lim_component_ge[OF net, of b i]
  6.3207 +  using Lim_component_le[OF net, of i b]
  6.3208 +  by auto
  6.3209 +
  6.3210 +text \<open>Limits relative to a union.\<close>
  6.3211 +
  6.3212 +lemma eventually_within_Un:
  6.3213 +  "eventually P (at x within (s \<union> t)) \<longleftrightarrow>
  6.3214 +    eventually P (at x within s) \<and> eventually P (at x within t)"
  6.3215 +  unfolding eventually_at_filter
  6.3216 +  by (auto elim!: eventually_rev_mp)
  6.3217 +
  6.3218 +lemma Lim_within_union:
  6.3219 + "(f \<longlongrightarrow> l) (at x within (s \<union> t)) \<longleftrightarrow>
  6.3220 +  (f \<longlongrightarrow> l) (at x within s) \<and> (f \<longlongrightarrow> l) (at x within t)"
  6.3221 +  unfolding tendsto_def
  6.3222 +  by (auto simp: eventually_within_Un)
  6.3223 +
  6.3224 +lemma Lim_topological:
  6.3225 +  "(f \<longlongrightarrow> l) net \<longleftrightarrow>
  6.3226 +    trivial_limit net \<or> (\<forall>S. open S \<longrightarrow> l \<in> S \<longrightarrow> eventually (\<lambda>x. f x \<in> S) net)"
  6.3227 +  unfolding tendsto_def trivial_limit_eq by auto
  6.3228 +
  6.3229 +text \<open>Continuity relative to a union.\<close>
  6.3230 +
  6.3231 +lemma continuous_on_Un_local:
  6.3232 +    "\<lbrakk>closedin (subtopology euclidean (s \<union> t)) s; closedin (subtopology euclidean (s \<union> t)) t;
  6.3233 +      continuous_on s f; continuous_on t f\<rbrakk>
  6.3234 +     \<Longrightarrow> continuous_on (s \<union> t) f"
  6.3235 +  unfolding continuous_on closedin_limpt
  6.3236 +  by (metis Lim_trivial_limit Lim_within_union Un_iff trivial_limit_within)
  6.3237 +
  6.3238 +lemma continuous_on_cases_local:
  6.3239 +     "\<lbrakk>closedin (subtopology euclidean (s \<union> t)) s; closedin (subtopology euclidean (s \<union> t)) t;
  6.3240 +       continuous_on s f; continuous_on t g;
  6.3241 +       \<And>x. \<lbrakk>x \<in> s \<and> ~P x \<or> x \<in> t \<and> P x\<rbrakk> \<Longrightarrow> f x = g x\<rbrakk>
  6.3242 +      \<Longrightarrow> continuous_on (s \<union> t) (\<lambda>x. if P x then f x else g x)"
  6.3243 +  by (rule continuous_on_Un_local) (auto intro: continuous_on_eq)
  6.3244 +
  6.3245 +lemma continuous_on_cases_le:
  6.3246 +  fixes h :: "'a :: topological_space \<Rightarrow> real"
  6.3247 +  assumes "continuous_on {t \<in> s. h t \<le> a} f"
  6.3248 +      and "continuous_on {t \<in> s. a \<le> h t} g"
  6.3249 +      and h: "continuous_on s h"
  6.3250 +      and "\<And>t. \<lbrakk>t \<in> s; h t = a\<rbrakk> \<Longrightarrow> f t = g t"
  6.3251 +    shows "continuous_on s (\<lambda>t. if h t \<le> a then f(t) else g(t))"
  6.3252 +proof -
  6.3253 +  have s: "s = {t \<in> s. h t \<in> atMost a} \<union> {t \<in> s. h t \<in> atLeast a}"
  6.3254 +    by force
  6.3255 +  have 1: "closedin (subtopology euclidean s) {t \<in> s. h t \<in> atMost a}"
  6.3256 +    by (rule continuous_closedin_preimage [OF h closed_atMost])
  6.3257 +  have 2: "closedin (subtopology euclidean s) {t \<in> s. h t \<in> atLeast a}"
  6.3258 +    by (rule continuous_closedin_preimage [OF h closed_atLeast])
  6.3259 +  show ?thesis
  6.3260 +    apply (rule continuous_on_subset [of s, OF _ order_refl])
  6.3261 +    apply (subst s)
  6.3262 +    apply (rule continuous_on_cases_local)
  6.3263 +    using 1 2 s assms apply auto
  6.3264 +    done
  6.3265 +qed
  6.3266 +
  6.3267 +lemma continuous_on_cases_1:
  6.3268 +  fixes s :: "real set"
  6.3269 +  assumes "continuous_on {t \<in> s. t \<le> a} f"
  6.3270 +      and "continuous_on {t \<in> s. a \<le> t} g"
  6.3271 +      and "a \<in> s \<Longrightarrow> f a = g a"
  6.3272 +    shows "continuous_on s (\<lambda>t. if t \<le> a then f(t) else g(t))"
  6.3273 +using assms
  6.3274 +by (auto simp: continuous_on_id intro: continuous_on_cases_le [where h = id, simplified])
  6.3275 +
  6.3276 +text\<open>Some more convenient intermediate-value theorem formulations.\<close>
  6.3277 +
  6.3278 +lemma connected_ivt_hyperplane:
  6.3279 +  assumes "connected s"
  6.3280 +    and "x \<in> s"
  6.3281 +    and "y \<in> s"
  6.3282 +    and "inner a x \<le> b"
  6.3283 +    and "b \<le> inner a y"
  6.3284 +  shows "\<exists>z \<in> s. inner a z = b"
  6.3285 +proof (rule ccontr)
  6.3286 +  assume as:"\<not> (\<exists>z\<in>s. inner a z = b)"
  6.3287 +  let ?A = "{x. inner a x < b}"
  6.3288 +  let ?B = "{x. inner a x > b}"
  6.3289 +  have "open ?A" "open ?B"
  6.3290 +    using open_halfspace_lt and open_halfspace_gt by auto
  6.3291 +  moreover
  6.3292 +  have "?A \<inter> ?B = {}" by auto
  6.3293 +  moreover
  6.3294 +  have "s \<subseteq> ?A \<union> ?B" using as by auto
  6.3295 +  ultimately
  6.3296 +  show False
  6.3297 +    using assms(1)[unfolded connected_def not_ex,
  6.3298 +      THEN spec[where x="?A"], THEN spec[where x="?B"]]
  6.3299 +    using assms(2-5)
  6.3300 +    by auto
  6.3301 +qed
  6.3302 +
  6.3303 +lemma connected_ivt_component:
  6.3304 +  fixes x::"'a::euclidean_space"
  6.3305 +  shows "connected s \<Longrightarrow>
  6.3306 +    x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow>
  6.3307 +    x\<bullet>k \<le> a \<Longrightarrow> a \<le> y\<bullet>k \<Longrightarrow> (\<exists>z\<in>s.  z\<bullet>k = a)"
  6.3308 +  using connected_ivt_hyperplane[of s x y "k::'a" a]
  6.3309 +  by (auto simp: inner_commute)
  6.3310 +
  6.3311 +lemma image_affinity_cbox: fixes m::real
  6.3312 +  fixes a b c :: "'a::euclidean_space"
  6.3313 +  shows "(\<lambda>x. m *\<^sub>R x + c) ` cbox a b =
  6.3314 +    (if cbox a b = {} then {}
  6.3315 +     else (if 0 \<le> m then cbox (m *\<^sub>R a + c) (m *\<^sub>R b + c)
  6.3316 +     else cbox (m *\<^sub>R b + c) (m *\<^sub>R a + c)))"
  6.3317 +proof (cases "m = 0")
  6.3318 +  case True
  6.3319 +  {
  6.3320 +    fix x
  6.3321 +    assume "\<forall>i\<in>Basis. x \<bullet> i \<le> c \<bullet> i" "\<forall>i\<in>Basis. c \<bullet> i \<le> x \<bullet> i"
  6.3322 +    then have "x = c"
  6.3323 +      by (simp add: dual_order.antisym euclidean_eqI)
  6.3324 +  }
  6.3325 +  moreover have "c \<in> cbox (m *\<^sub>R a + c) (m *\<^sub>R b + c)"
  6.3326 +    unfolding True by (auto simp: cbox_sing)
  6.3327 +  ultimately show ?thesis using True by (auto simp: cbox_def)
  6.3328 +next
  6.3329 +  case False
  6.3330 +  {
  6.3331 +    fix y
  6.3332 +    assume "\<forall>i\<in>Basis. a \<bullet> i \<le> y \<bullet> i" "\<forall>i\<in>Basis. y \<bullet> i \<le> b \<bullet> i" "m > 0"
  6.3333 +    then have "\<forall>i\<in>Basis. (m *\<^sub>R a + c) \<bullet> i \<le> (m *\<^sub>R y + c) \<bullet> i" and "\<forall>i\<in>Basis. (m *\<^sub>R y + c) \<bullet> i \<le> (m *\<^sub>R b + c) \<bullet> i"
  6.3334 +      by (auto simp: inner_distrib)
  6.3335 +  }
  6.3336 +  moreover
  6.3337 +  {
  6.3338 +    fix y
  6.3339 +    assume "\<forall>i\<in>Basis. a \<bullet> i \<le> y \<bullet> i" "\<forall>i\<in>Basis. y \<bullet> i \<le> b \<bullet> i" "m < 0"
  6.3340 +    then have "\<forall>i\<in>Basis. (m *\<^sub>R b + c) \<bullet> i \<le> (m *\<^sub>R y + c) \<bullet> i" and "\<forall>i\<in>Basis. (m *\<^sub>R y + c) \<bullet> i \<le> (m *\<^sub>R a + c) \<bullet> i"
  6.3341 +      by (auto simp: mult_left_mono_neg inner_distrib)
  6.3342 +  }
  6.3343 +  moreover
  6.3344 +  {
  6.3345 +    fix y
  6.3346 +    assume "m > 0" and "\<forall>i\<in>Basis. (m *\<^sub>R a + c) \<bullet> i \<le> y \<bullet> i" and "\<forall>i\<in>Basis. y \<bullet> i \<le> (m *\<^sub>R b + c) \<bullet> i"
  6.3347 +    then have "y \<in> (\<lambda>x. m *\<^sub>R x + c) ` cbox a b"
  6.3348 +      unfolding image_iff Bex_def mem_box
  6.3349 +      apply (intro exI[where x="(1 / m) *\<^sub>R (y - c)"])
  6.3350 +      apply (auto simp: pos_le_divide_eq pos_divide_le_eq mult.commute inner_distrib inner_diff_left)
  6.3351 +      done
  6.3352 +  }
  6.3353 +  moreover
  6.3354 +  {
  6.3355 +    fix y
  6.3356 +    assume "\<forall>i\<in>Basis. (m *\<^sub>R b + c) \<bullet> i \<le> y \<bullet> i" "\<forall>i\<in>Basis. y \<bullet> i \<le> (m *\<^sub>R a + c) \<bullet> i" "m < 0"
  6.3357 +    then have "y \<in> (\<lambda>x. m *\<^sub>R x + c) ` cbox a b"
  6.3358 +      unfolding image_iff Bex_def mem_box
  6.3359 +      apply (intro exI[where x="(1 / m) *\<^sub>R (y - c)"])
  6.3360 +      apply (auto simp: neg_le_divide_eq neg_divide_le_eq mult.commute inner_distrib inner_diff_left)
  6.3361 +      done
  6.3362 +  }
  6.3363 +  ultimately show ?thesis using False by (auto simp: cbox_def)
  6.3364 +qed
  6.3365 +
  6.3366 +lemma image_smult_cbox:"(\<lambda>x. m *\<^sub>R (x::_::euclidean_space)) ` cbox a b =
  6.3367 +  (if cbox a b = {} then {} else if 0 \<le> m then cbox (m *\<^sub>R a) (m *\<^sub>R b) else cbox (m *\<^sub>R b) (m *\<^sub>R a))"
  6.3368 +  using image_affinity_cbox[of m 0 a b] by auto
  6.3369 +
  6.3370 +lemma islimpt_greaterThanLessThan1:
  6.3371 +  fixes a b::"'a::{linorder_topology, dense_order}"
  6.3372 +  assumes "a < b"
  6.3373 +  shows  "a islimpt {a<..<b}"
  6.3374 +proof (rule islimptI)
  6.3375 +  fix T
  6.3376 +  assume "open T" "a \<in> T"
  6.3377 +  from open_right[OF this \<open>a < b\<close>]
  6.3378 +  obtain c where c: "a < c" "{a..<c} \<subseteq> T" by auto
  6.3379 +  with assms dense[of a "min c b"]
  6.3380 +  show "\<exists>y\<in>{a<..<b}. y \<in> T \<and> y \<noteq> a"
  6.3381 +    by (metis atLeastLessThan_iff greaterThanLessThan_iff min_less_iff_conj
  6.3382 +      not_le order.strict_implies_order subset_eq)
  6.3383 +qed
  6.3384 +
  6.3385 +lemma islimpt_greaterThanLessThan2:
  6.3386 +  fixes a b::"'a::{linorder_topology, dense_order}"
  6.3387 +  assumes "a < b"
  6.3388 +  shows  "b islimpt {a<..<b}"
  6.3389 +proof (rule islimptI)
  6.3390 +  fix T
  6.3391 +  assume "open T" "b \<in> T"
  6.3392 +  from open_left[OF this \<open>a < b\<close>]
  6.3393 +  obtain c where c: "c < b" "{c<..b} \<subseteq> T" by auto
  6.3394 +  with assms dense[of "max a c" b]
  6.3395 +  show "\<exists>y\<in>{a<..<b}. y \<in> T \<and> y \<noteq> b"
  6.3396 +    by (metis greaterThanAtMost_iff greaterThanLessThan_iff max_less_iff_conj
  6.3397 +      not_le order.strict_implies_order subset_eq)
  6.3398 +qed
  6.3399 +
  6.3400 +lemma closure_greaterThanLessThan[simp]:
  6.3401 +  fixes a b::"'a::{linorder_topology, dense_order}"
  6.3402 +  shows "a < b \<Longrightarrow> closure {a <..< b} = {a .. b}" (is "_ \<Longrightarrow> ?l = ?r")
  6.3403 +proof
  6.3404 +  have "?l \<subseteq> closure ?r"
  6.3405 +    by (rule closure_mono) auto
  6.3406 +  thus "closure {a<..<b} \<subseteq> {a..b}" by simp
  6.3407 +qed (auto simp: closure_def order.order_iff_strict islimpt_greaterThanLessThan1
  6.3408 +  islimpt_greaterThanLessThan2)
  6.3409 +
  6.3410 +lemma closure_greaterThan[simp]:
  6.3411 +  fixes a b::"'a::{no_top, linorder_topology, dense_order}"
  6.3412 +  shows "closure {a<..} = {a..}"
  6.3413 +proof -
  6.3414 +  from gt_ex obtain b where "a < b" by auto
  6.3415 +  hence "{a<..} = {a<..<b} \<union> {b..}" by auto
  6.3416 +  also have "closure \<dots> = {a..}" using \<open>a < b\<close> unfolding closure_Un
  6.3417 +    by auto
  6.3418 +  finally show ?thesis .
  6.3419 +qed
  6.3420 +
  6.3421 +lemma closure_lessThan[simp]:
  6.3422 +  fixes b::"'a::{no_bot, linorder_topology, dense_order}"
  6.3423 +  shows "closure {..<b} = {..b}"
  6.3424 +proof -
  6.3425 +  from lt_ex obtain a where "a < b" by auto
  6.3426 +  hence "{..<b} = {a<..<b} \<union> {..a}" by auto
  6.3427 +  also have "closure \<dots> = {..b}" using \<open>a < b\<close> unfolding closure_Un
  6.3428 +    by auto
  6.3429 +  finally show ?thesis .
  6.3430 +qed
  6.3431 +
  6.3432 +lemma closure_atLeastLessThan[simp]:
  6.3433 +  fixes a b::"'a::{linorder_topology, dense_order}"
  6.3434 +  assumes "a < b"
  6.3435 +  shows "closure {a ..< b} = {a .. b}"
  6.3436 +proof -
  6.3437 +  from assms have "{a ..< b} = {a} \<union> {a <..< b}" by auto
  6.3438 +  also have "closure \<dots> = {a .. b}" unfolding closure_Un
  6.3439 +    by (auto simp: assms less_imp_le)
  6.3440 +  finally show ?thesis .
  6.3441 +qed
  6.3442 +
  6.3443 +lemma closure_greaterThanAtMost[simp]:
  6.3444 +  fixes a b::"'a::{linorder_topology, dense_order}"
  6.3445 +  assumes "a < b"
  6.3446 +  shows "closure {a <.. b} = {a .. b}"
  6.3447 +proof -
  6.3448 +  from assms have "{a <.. b} = {b} \<union> {a <..< b}" by auto
  6.3449 +  also have "closure \<dots> = {a .. b}" unfolding closure_Un
  6.3450 +    by (auto simp: assms less_imp_le)
  6.3451 +  finally show ?thesis .
  6.3452 +qed
  6.3453 +
  6.3454 +
  6.3455 +subsection \<open>Homeomorphisms\<close>
  6.3456 +
  6.3457 +definition "homeomorphism s t f g \<longleftrightarrow>
  6.3458 +  (\<forall>x\<in>s. (g(f x) = x)) \<and> (f ` s = t) \<and> continuous_on s f \<and>
  6.3459 +  (\<forall>y\<in>t. (f(g y) = y)) \<and> (g ` t = s) \<and> continuous_on t g"
  6.3460 +
  6.3461 +lemma homeomorphismI [intro?]:
  6.3462 +  assumes "continuous_on S f" "continuous_on T g"
  6.3463 +          "f ` S \<subseteq> T" "g ` T \<subseteq> S" "\<And>x. x \<in> S \<Longrightarrow> g(f x) = x" "\<And>y. y \<in> T \<Longrightarrow> f(g y) = y"
  6.3464 +    shows "homeomorphism S T f g"
  6.3465 +  using assms by (force simp: homeomorphism_def)
  6.3466 +
  6.3467 +lemma homeomorphism_translation:
  6.3468 +  fixes a :: "'a :: real_normed_vector"
  6.3469 +  shows "homeomorphism (op + a ` S) S (op + (- a)) (op + a)"
  6.3470 +unfolding homeomorphism_def by (auto simp: algebra_simps continuous_intros)
  6.3471 +
  6.3472 +lemma homeomorphism_ident: "homeomorphism T T (\<lambda>a. a) (\<lambda>a. a)"
  6.3473 +  by (rule homeomorphismI) (auto simp: continuous_on_id)
  6.3474 +
  6.3475 +lemma homeomorphism_compose:
  6.3476 +  assumes "homeomorphism S T f g" "homeomorphism T U h k"
  6.3477 +    shows "homeomorphism S U (h o f) (g o k)"
  6.3478 +  using assms
  6.3479 +  unfolding homeomorphism_def
  6.3480 +  by (intro conjI ballI continuous_on_compose) (auto simp: image_comp [symmetric])
  6.3481 +
  6.3482 +lemma homeomorphism_symD: "homeomorphism S t f g \<Longrightarrow> homeomorphism t S g f"
  6.3483 +  by (simp add: homeomorphism_def)
  6.3484 +
  6.3485 +lemma homeomorphism_sym: "homeomorphism S t f g = homeomorphism t S g f"
  6.3486 +  by (force simp: homeomorphism_def)
  6.3487 +
  6.3488 +definition homeomorphic :: "'a::topological_space set \<Rightarrow> 'b::topological_space set \<Rightarrow> bool"
  6.3489 +    (infixr "homeomorphic" 60)
  6.3490 +  where "s homeomorphic t \<equiv> (\<exists>f g. homeomorphism s t f g)"
  6.3491 +
  6.3492 +lemma homeomorphic_empty [iff]:
  6.3493 +     "S homeomorphic {} \<longleftrightarrow> S = {}" "{} homeomorphic S \<longleftrightarrow> S = {}"
  6.3494 +  by (auto simp: homeomorphic_def homeomorphism_def)
  6.3495 +
  6.3496 +lemma homeomorphic_refl: "s homeomorphic s"
  6.3497 +  unfolding homeomorphic_def homeomorphism_def
  6.3498 +  using continuous_on_id
  6.3499 +  apply (rule_tac x = "(\<lambda>x. x)" in exI)
  6.3500 +  apply (rule_tac x = "(\<lambda>x. x)" in exI)
  6.3501 +  apply blast
  6.3502 +  done
  6.3503 +
  6.3504 +lemma homeomorphic_sym: "s homeomorphic t \<longleftrightarrow> t homeomorphic s"
  6.3505 +  unfolding homeomorphic_def homeomorphism_def
  6.3506 +  by blast
  6.3507 +
  6.3508 +lemma homeomorphic_trans [trans]:
  6.3509 +  assumes "S homeomorphic T"
  6.3510 +      and "T homeomorphic U"
  6.3511 +    shows "S homeomorphic U"
  6.3512 +  using assms
  6.3513 +  unfolding homeomorphic_def
  6.3514 +by (metis homeomorphism_compose)
  6.3515 +
  6.3516 +lemma homeomorphic_minimal:
  6.3517 +  "s homeomorphic t \<longleftrightarrow>
  6.3518 +    (\<exists>f g. (\<forall>x\<in>s. f(x) \<in> t \<and> (g(f(x)) = x)) \<and>
  6.3519 +           (\<forall>y\<in>t. g(y) \<in> s \<and> (f(g(y)) = y)) \<and>
  6.3520 +           continuous_on s f \<and> continuous_on t g)"
  6.3521 +   (is "?lhs = ?rhs")
  6.3522 +proof
  6.3523 +  assume ?lhs
  6.3524 +  then show ?rhs
  6.3525 +    by (fastforce simp: homeomorphic_def homeomorphism_def)
  6.3526 +next
  6.3527 +  assume ?rhs
  6.3528 +  then show ?lhs
  6.3529 +    apply clarify
  6.3530 +    unfolding homeomorphic_def homeomorphism_def
  6.3531 +    by (metis equalityI image_subset_iff subsetI)
  6.3532 + qed
  6.3533 +
  6.3534 +lemma homeomorphicI [intro?]:
  6.3535 +   "\<lbrakk>f ` S = T; g ` T = S;
  6.3536 +     continuous_on S f; continuous_on T g;
  6.3537 +     \<And>x. x \<in> S \<Longrightarrow> g(f(x)) = x;
  6.3538 +     \<And>y. y \<in> T \<Longrightarrow> f(g(y)) = y\<rbrakk> \<Longrightarrow> S homeomorphic T"
  6.3539 +unfolding homeomorphic_def homeomorphism_def by metis
  6.3540 +
  6.3541 +lemma homeomorphism_of_subsets:
  6.3542 +   "\<lbrakk>homeomorphism S T f g; S' \<subseteq> S; T'' \<subseteq> T; f ` S' = T'\<rbrakk>
  6.3543 +    \<Longrightarrow> homeomorphism S' T' f g"
  6.3544 +apply (auto simp: homeomorphism_def elim!: continuous_on_subset)
  6.3545 +by (metis subsetD imageI)
  6.3546 +
  6.3547 +lemma homeomorphism_apply1: "\<lbrakk>homeomorphism S T f g; x \<in> S\<rbrakk> \<Longrightarrow> g(f x) = x"
  6.3548 +  by (simp add: homeomorphism_def)
  6.3549 +
  6.3550 +lemma homeomorphism_apply2: "\<lbrakk>homeomorphism S T f g; x \<in> T\<rbrakk> \<Longrightarrow> f(g x) = x"
  6.3551 +  by (simp add: homeomorphism_def)
  6.3552 +
  6.3553 +lemma homeomorphism_image1: "homeomorphism S T f g \<Longrightarrow> f ` S = T"
  6.3554 +  by (simp add: homeomorphism_def)
  6.3555 +
  6.3556 +lemma homeomorphism_image2: "homeomorphism S T f g \<Longrightarrow> g ` T = S"
  6.3557 +  by (simp add: homeomorphism_def)
  6.3558 +
  6.3559 +lemma homeomorphism_cont1: "homeomorphism S T f g \<Longrightarrow> continuous_on S f"
  6.3560 +  by (simp add: homeomorphism_def)
  6.3561 +
  6.3562 +lemma homeomorphism_cont2: "homeomorphism S T f g \<Longrightarrow> continuous_on T g"
  6.3563 +  by (simp add: homeomorphism_def)
  6.3564 +
  6.3565 +lemma continuous_on_no_limpt:
  6.3566 +   "(\<And>x. \<not> x islimpt S) \<Longrightarrow> continuous_on S f"
  6.3567 +  unfolding continuous_on_def
  6.3568 +  by (metis UNIV_I empty_iff eventually_at_topological islimptE open_UNIV tendsto_def trivial_limit_within)
  6.3569 +
  6.3570 +lemma continuous_on_finite:
  6.3571 +  fixes S :: "'a::t1_space set"
  6.3572 +  shows "finite S \<Longrightarrow> continuous_on S f"
  6.3573 +by (metis continuous_on_no_limpt islimpt_finite)
  6.3574 +
  6.3575 +lemma homeomorphic_finite:
  6.3576 +  fixes S :: "'a::t1_space set" and T :: "'b::t1_space set"
  6.3577 +  assumes "finite T"
  6.3578 +  shows "S homeomorphic T \<longleftrightarrow> finite S \<and> finite T \<and> card S = card T" (is "?lhs = ?rhs")
  6.3579 +proof
  6.3580 +  assume "S homeomorphic T"
  6.3581 +  with assms show ?rhs
  6.3582 +    apply (auto simp: homeomorphic_def homeomorphism_def)
  6.3583 +     apply (metis finite_imageI)
  6.3584 +    by (metis card_image_le finite_imageI le_antisym)
  6.3585 +next
  6.3586 +  assume R: ?rhs
  6.3587 +  with finite_same_card_bij obtain h where "bij_betw h S T"
  6.3588 +    by auto
  6.3589 +  with R show ?lhs
  6.3590 +    apply (auto simp: homeomorphic_def homeomorphism_def continuous_on_finite)
  6.3591 +    apply (rule_tac x=h in exI)
  6.3592 +    apply (rule_tac x="inv_into S h" in exI)
  6.3593 +    apply (auto simp:  bij_betw_inv_into_left bij_betw_inv_into_right bij_betw_imp_surj_on inv_into_into bij_betwE)
  6.3594 +    apply (metis bij_betw_def bij_betw_inv_into)
  6.3595 +    done
  6.3596 +qed
  6.3597 +
  6.3598 +text \<open>Relatively weak hypotheses if a set is compact.\<close>
  6.3599 +
  6.3600 +lemma homeomorphism_compact:
  6.3601 +  fixes f :: "'a::topological_space \<Rightarrow> 'b::t2_space"
  6.3602 +  assumes "compact s" "continuous_on s f"  "f ` s = t"  "inj_on f s"
  6.3603 +  shows "\<exists>g. homeomorphism s t f g"
  6.3604 +proof -
  6.3605 +  define g where "g x = (SOME y. y\<in>s \<and> f y = x)" for x
  6.3606 +  have g: "\<forall>x\<in>s. g (f x) = x"
  6.3607 +    using assms(3) assms(4)[unfolded inj_on_def] unfolding g_def by auto
  6.3608 +  {
  6.3609 +    fix y
  6.3610 +    assume "y \<in> t"
  6.3611 +    then obtain x where x:"f x = y" "x\<in>s"
  6.3612 +      using assms(3) by auto
  6.3613 +    then have "g (f x) = x" using g by auto
  6.3614 +    then have "f (g y) = y" unfolding x(1)[symmetric] by auto
  6.3615 +  }
  6.3616 +  then have g':"\<forall>x\<in>t. f (g x) = x" by auto
  6.3617 +  moreover
  6.3618 +  {
  6.3619 +    fix x
  6.3620 +    have "x\<in>s \<Longrightarrow> x \<in> g ` t"
  6.3621 +      using g[THEN bspec[where x=x]]
  6.3622 +      unfolding image_iff
  6.3623 +      using assms(3)
  6.3624 +      by (auto intro!: bexI[where x="f x"])
  6.3625 +    moreover
  6.3626 +    {
  6.3627 +      assume "x\<in>g ` t"
  6.3628 +      then obtain y where y:"y\<in>t" "g y = x" by auto
  6.3629 +      then obtain x' where x':"x'\<in>s" "f x' = y"
  6.3630 +        using assms(3) by auto
  6.3631 +      then have "x \<in> s"
  6.3632 +        unfolding g_def
  6.3633 +        using someI2[of "\<lambda>b. b\<in>s \<and> f b = y" x' "\<lambda>x. x\<in>s"]
  6.3634 +        unfolding y(2)[symmetric] and g_def
  6.3635 +        by auto
  6.3636 +    }
  6.3637 +    ultimately have "x\<in>s \<longleftrightarrow> x \<in> g ` t" ..
  6.3638 +  }
  6.3639 +  then have "g ` t = s" by auto
  6.3640 +  ultimately show ?thesis
  6.3641 +    unfolding homeomorphism_def homeomorphic_def
  6.3642 +    apply (rule_tac x=g in exI)
  6.3643 +    using g and assms(3) and continuous_on_inv[OF assms(2,1), of g, unfolded assms(3)] and assms(2)
  6.3644 +    apply auto
  6.3645 +    done
  6.3646 +qed
  6.3647 +
  6.3648 +lemma homeomorphic_compact:
  6.3649 +  fixes f :: "'a::topological_space \<Rightarrow> 'b::t2_space"
  6.3650 +  shows "compact s \<Longrightarrow> continuous_on s f \<Longrightarrow> (f ` s = t) \<Longrightarrow> inj_on f s \<Longrightarrow> s homeomorphic t"
  6.3651 +  unfolding homeomorphic_def by (metis homeomorphism_compact)
  6.3652 +
  6.3653 +text\<open>Preservation of topological properties.\<close>
  6.3654 +
  6.3655 +lemma homeomorphic_compactness: "s homeomorphic t \<Longrightarrow> (compact s \<longleftrightarrow> compact t)"
  6.3656 +  unfolding homeomorphic_def homeomorphism_def
  6.3657 +  by (metis compact_continuous_image)
  6.3658 +
  6.3659 +text\<open>Results on translation, scaling etc.\<close>
  6.3660 +
  6.3661 +lemma homeomorphic_scaling:
  6.3662 +  fixes s :: "'a::real_normed_vector set"
  6.3663 +  assumes "c \<noteq> 0"
  6.3664 +  shows "s homeomorphic ((\<lambda>x. c *\<^sub>R x) ` s)"
  6.3665 +  unfolding homeomorphic_minimal
  6.3666 +  apply (rule_tac x="\<lambda>x. c *\<^sub>R x" in exI)
  6.3667 +  apply (rule_tac x="\<lambda>x. (1 / c) *\<^sub>R x" in exI)
  6.3668 +  using assms
  6.3669 +  apply (auto simp: continuous_intros)
  6.3670 +  done
  6.3671 +
  6.3672 +lemma homeomorphic_translation:
  6.3673 +  fixes s :: "'a::real_normed_vector set"
  6.3674 +  shows "s homeomorphic ((\<lambda>x. a + x) ` s)"
  6.3675 +  unfolding homeomorphic_minimal
  6.3676 +  apply (rule_tac x="\<lambda>x. a + x" in exI)
  6.3677 +  apply (rule_tac x="\<lambda>x. -a + x" in exI)
  6.3678 +  using continuous_on_add [OF continuous_on_const continuous_on_id, of s a]
  6.3679 +    continuous_on_add [OF continuous_on_const continuous_on_id, of "plus a ` s" "- a"]
  6.3680 +  apply auto
  6.3681 +  done
  6.3682 +
  6.3683 +lemma homeomorphic_affinity:
  6.3684 +  fixes s :: "'a::real_normed_vector set"
  6.3685 +  assumes "c \<noteq> 0"
  6.3686 +  shows "s homeomorphic ((\<lambda>x. a + c *\<^sub>R x) ` s)"
  6.3687 +proof -
  6.3688 +  have *: "op + a ` op *\<^sub>R c ` s = (\<lambda>x. a + c *\<^sub>R x) ` s" by auto
  6.3689 +  show ?thesis
  6.3690 +    using homeomorphic_trans
  6.3691 +    using homeomorphic_scaling[OF assms, of s]
  6.3692 +    using homeomorphic_translation[of "(\<lambda>x. c *\<^sub>R x) ` s" a]
  6.3693 +    unfolding *
  6.3694 +    by auto
  6.3695 +qed
  6.3696 +
  6.3697 +lemma homeomorphic_balls:
  6.3698 +  fixes a b ::"'a::real_normed_vector"
  6.3699 +  assumes "0 < d"  "0 < e"
  6.3700 +  shows "(ball a d) homeomorphic  (ball b e)" (is ?th)
  6.3701 +    and "(cball a d) homeomorphic (cball b e)" (is ?cth)
  6.3702 +proof -
  6.3703 +  show ?th unfolding homeomorphic_minimal
  6.3704 +    apply(rule_tac x="\<lambda>x. b + (e/d) *\<^sub>R (x - a)" in exI)
  6.3705 +    apply(rule_tac x="\<lambda>x. a + (d/e) *\<^sub>R (x - b)" in exI)
  6.3706 +    using assms
  6.3707 +    apply (auto intro!: continuous_intros
  6.3708 +      simp: dist_commute dist_norm pos_divide_less_eq mult_strict_left_mono)
  6.3709 +    done
  6.3710 +  show ?cth unfolding homeomorphic_minimal
  6.3711 +    apply(rule_tac x="\<lambda>x. b + (e/d) *\<^sub>R (x - a)" in exI)
  6.3712 +    apply(rule_tac x="\<lambda>x. a + (d/e) *\<^sub>R (x - b)" in exI)
  6.3713 +    using assms
  6.3714 +    apply (auto intro!: continuous_intros
  6.3715 +      simp: dist_commute dist_norm pos_divide_le_eq mult_strict_left_mono)
  6.3716 +    done
  6.3717 +qed
  6.3718 +
  6.3719 +lemma homeomorphic_spheres:
  6.3720 +  fixes a b ::"'a::real_normed_vector"
  6.3721 +  assumes "0 < d"  "0 < e"
  6.3722 +  shows "(sphere a d) homeomorphic (sphere b e)"
  6.3723 +unfolding homeomorphic_minimal
  6.3724 +    apply(rule_tac x="\<lambda>x. b + (e/d) *\<^sub>R (x - a)" in exI)
  6.3725 +    apply(rule_tac x="\<lambda>x. a + (d/e) *\<^sub>R (x - b)" in exI)
  6.3726 +    using assms
  6.3727 +    apply (auto intro!: continuous_intros
  6.3728 +      simp: dist_commute dist_norm pos_divide_less_eq mult_strict_left_mono)
  6.3729 +    done
  6.3730 +
  6.3731 +lemma homeomorphic_ball01_UNIV:
  6.3732 +  "ball (0::'a::real_normed_vector) 1 homeomorphic (UNIV:: 'a set)"
  6.3733 +  (is "?B homeomorphic ?U")
  6.3734 +proof
  6.3735 +  have "x \<in> (\<lambda>z. z /\<^sub>R (1 - norm z)) ` ball 0 1" for x::'a
  6.3736 +    apply (rule_tac x="x /\<^sub>R (1 + norm x)" in image_eqI)
  6.3737 +     apply (auto simp: divide_simps)
  6.3738 +    using norm_ge_zero [of x] apply linarith+
  6.3739 +    done
  6.3740 +  then show "(\<lambda>z::'a. z /\<^sub>R (1 - norm z)) ` ?B = ?U"
  6.3741 +    by blast
  6.3742 +  have "x \<in> range (\<lambda>z. (1 / (1 + norm z)) *\<^sub>R z)" if "norm x < 1" for x::'a
  6.3743 +    apply (rule_tac x="x /\<^sub>R (1 - norm x)" in image_eqI)
  6.3744 +    using that apply (auto simp: divide_simps)
  6.3745 +    done
  6.3746 +  then show "(\<lambda>z::'a. z /\<^sub>R (1 + norm z)) ` ?U = ?B"
  6.3747 +    by (force simp: divide_simps dest: add_less_zeroD)
  6.3748 +  show "continuous_on (ball 0 1) (\<lambda>z. z /\<^sub>R (1 - norm z))"
  6.3749 +    by (rule continuous_intros | force)+
  6.3750 +  show "continuous_on UNIV (\<lambda>z. z /\<^sub>R (1 + norm z))"
  6.3751 +    apply (intro continuous_intros)
  6.3752 +    apply (metis le_add_same_cancel1 norm_ge_zero not_le zero_less_one)
  6.3753 +    done
  6.3754 +  show "\<And>x. x \<in> ball 0 1 \<Longrightarrow>
  6.3755 +         x /\<^sub>R (1 - norm x) /\<^sub>R (1 + norm (x /\<^sub>R (1 - norm x))) = x"
  6.3756 +    by (auto simp: divide_simps)
  6.3757 +  show "\<And>y. y /\<^sub>R (1 + norm y) /\<^sub>R (1 - norm (y /\<^sub>R (1 + norm y))) = y"
  6.3758 +    apply (auto simp: divide_simps)
  6.3759 +    apply (metis le_add_same_cancel1 norm_ge_zero not_le zero_less_one)
  6.3760 +    done
  6.3761 +qed
  6.3762 +
  6.3763 +proposition homeomorphic_ball_UNIV:
  6.3764 +  fixes a ::"'a::real_normed_vector"
  6.3765 +  assumes "0 < r" shows "ball a r homeomorphic (UNIV:: 'a set)"
  6.3766 +  using assms homeomorphic_ball01_UNIV homeomorphic_balls(1) homeomorphic_trans zero_less_one by blast
  6.3767 +
  6.3768 +
  6.3769 +subsection\<open>Inverse function property for open/closed maps\<close>
  6.3770 +
  6.3771 +lemma continuous_on_inverse_open_map:
  6.3772 +  assumes contf: "continuous_on S f"
  6.3773 +    and imf: "f ` S = T"
  6.3774 +    and injf: "\<And>x. x \<in> S \<Longrightarrow> g (f x) = x"
  6.3775 +    and oo: "\<And>U. openin (subtopology euclidean S) U \<Longrightarrow> openin (subtopology euclidean T) (f ` U)"
  6.3776 +  shows "continuous_on T g"
  6.3777 +proof -
  6.3778 +  from imf injf have gTS: "g ` T = S"
  6.3779 +    by force
  6.3780 +  from imf injf have fU: "U \<subseteq> S \<Longrightarrow> (f ` U) = {x \<in> T. g x \<in> U}" for U
  6.3781 +    by force
  6.3782 +  show ?thesis
  6.3783 +    by (simp add: continuous_on_open [of T g] gTS) (metis openin_imp_subset fU oo)
  6.3784 +qed
  6.3785 +
  6.3786 +lemma continuous_on_inverse_closed_map:
  6.3787 +  assumes contf: "continuous_on S f"
  6.3788 +    and imf: "f ` S = T"
  6.3789 +    and injf: "\<And>x. x \<in> S \<Longrightarrow> g(f x) = x"
  6.3790 +    and oo: "\<And>U. closedin (subtopology euclidean S) U \<Longrightarrow> closedin (subtopology euclidean T) (f ` U)"
  6.3791 +  shows "continuous_on T g"
  6.3792 +proof -
  6.3793 +  from imf injf have gTS: "g ` T = S"
  6.3794 +    by force
  6.3795 +  from imf injf have fU: "U \<subseteq> S \<Longrightarrow> (f ` U) = {x \<in> T. g x \<in> U}" for U
  6.3796 +    by force
  6.3797 +  show ?thesis
  6.3798 +    by (simp add: continuous_on_closed [of T g] gTS) (metis closedin_imp_subset fU oo)
  6.3799 +qed
  6.3800 +
  6.3801 +lemma homeomorphism_injective_open_map:
  6.3802 +  assumes contf: "continuous_on S f"
  6.3803 +    and imf: "f ` S = T"
  6.3804 +    and injf: "inj_on f S"
  6.3805 +    and oo: "\<And>U. openin (subtopology euclidean S) U \<Longrightarrow> openin (subtopology euclidean T) (f ` U)"
  6.3806 +  obtains g where "homeomorphism S T f g"
  6.3807 +proof
  6.3808 +  have "continuous_on T (inv_into S f)"
  6.3809 +    by (metis contf continuous_on_inverse_open_map imf injf inv_into_f_f oo)
  6.3810 +  with imf injf contf show "homeomorphism S T f (inv_into S f)"
  6.3811 +    by (auto simp: homeomorphism_def)
  6.3812 +qed
  6.3813 +
  6.3814 +lemma homeomorphism_injective_closed_map:
  6.3815 +  assumes contf: "continuous_on S f"
  6.3816 +    and imf: "f ` S = T"
  6.3817 +    and injf: "inj_on f S"
  6.3818 +    and oo: "\<And>U. closedin (subtopology euclidean S) U \<Longrightarrow> closedin (subtopology euclidean T) (f ` U)"
  6.3819 +  obtains g where "homeomorphism S T f g"
  6.3820 +proof
  6.3821 +  have "continuous_on T (inv_into S f)"
  6.3822 +    by (metis contf continuous_on_inverse_closed_map imf injf inv_into_f_f oo)
  6.3823 +  with imf injf contf show "homeomorphism S T f (inv_into S f)"
  6.3824 +    by (auto simp: homeomorphism_def)
  6.3825 +qed
  6.3826 +
  6.3827 +lemma homeomorphism_imp_open_map:
  6.3828 +  assumes hom: "homeomorphism S T f g"
  6.3829 +    and oo: "openin (subtopology euclidean S) U"
  6.3830 +  shows "openin (subtopology euclidean T) (f ` U)"
  6.3831 +proof -
  6.3832 +  from hom oo have [simp]: "f ` U = {y. y \<in> T \<and> g y \<in> U}"
  6.3833 +    using openin_subset by (fastforce simp: homeomorphism_def rev_image_eqI)
  6.3834 +  from hom have "continuous_on T g"
  6.3835 +    unfolding homeomorphism_def by blast
  6.3836 +  moreover have "g ` T = S"
  6.3837 +    by (metis hom homeomorphism_def)
  6.3838 +  ultimately show ?thesis
  6.3839 +    by (simp add: continuous_on_open oo)
  6.3840 +qed
  6.3841 +
  6.3842 +lemma homeomorphism_imp_closed_map:
  6.3843 +  assumes hom: "homeomorphism S T f g"
  6.3844 +    and oo: "closedin (subtopology euclidean S) U"
  6.3845 +  shows "closedin (subtopology euclidean T) (f ` U)"
  6.3846 +proof -
  6.3847 +  from hom oo have [simp]: "f ` U = {y. y \<in> T \<and> g y \<in> U}"
  6.3848 +    using closedin_subset by (fastforce simp: homeomorphism_def rev_image_eqI)
  6.3849 +  from hom have "continuous_on T g"
  6.3850 +    unfolding homeomorphism_def by blast
  6.3851 +  moreover have "g ` T = S"
  6.3852 +    by (metis hom homeomorphism_def)
  6.3853 +  ultimately show ?thesis
  6.3854 +    by (simp add: continuous_on_closed oo)
  6.3855 +qed
  6.3856 +
  6.3857 +
  6.3858 +subsection \<open>"Isometry" (up to constant bounds) of injective linear map etc.\<close>
  6.3859 +
  6.3860 +lemma cauchy_isometric:
  6.3861 +  assumes e: "e > 0"
  6.3862 +    and s: "subspace s"
  6.3863 +    and f: "bounded_linear f"
  6.3864 +    and normf: "\<forall>x\<in>s. norm (f x) \<ge> e * norm x"
  6.3865 +    and xs: "\<forall>n. x n \<in> s"
  6.3866 +    and cf: "Cauchy (f \<circ> x)"
  6.3867 +  shows "Cauchy x"
  6.3868 +proof -
  6.3869 +  interpret f: bounded_linear f by fact
  6.3870 +  have "\<exists>N. \<forall>n\<ge>N. norm (x n - x N) < d" if "d > 0" for d :: real
  6.3871 +  proof -
  6.3872 +    from that obtain N where N: "\<forall>n\<ge>N. norm (f (x n) - f (x N)) < e * d"
  6.3873 +      using cf[unfolded Cauchy_def o_def dist_norm, THEN spec[where x="e*d"]] e
  6.3874 +      by auto
  6.3875 +    have "norm (x n - x N) < d" if "n \<ge> N" for n
  6.3876 +    proof -
  6.3877 +      have "e * norm (x n - x N) \<le> norm (f (x n - x N))"
  6.3878 +        using subspace_diff[OF s, of "x n" "x N"]
  6.3879 +        using xs[THEN spec[where x=N]] and xs[THEN spec[where x=n]]
  6.3880 +        using normf[THEN bspec[where x="x n - x N"]]
  6.3881 +        by auto
  6.3882 +      also have "norm (f (x n - x N)) < e * d"
  6.3883 +        using \<open>N \<le> n\<close> N unfolding f.diff[symmetric] by auto
  6.3884 +      finally show ?thesis
  6.3885 +        using \<open>e>0\<close> by simp
  6.3886 +    qed
  6.3887 +    then show ?thesis by auto
  6.3888 +  qed
  6.3889 +  then show ?thesis
  6.3890 +    by (simp add: Cauchy_altdef2 dist_norm)
  6.3891 +qed
  6.3892 +
  6.3893 +lemma complete_isometric_image:
  6.3894 +  assumes "0 < e"
  6.3895 +    and s: "subspace s"
  6.3896 +    and f: "bounded_linear f"
  6.3897 +    and normf: "\<forall>x\<in>s. norm(f x) \<ge> e * norm(x)"
  6.3898 +    and cs: "complete s"
  6.3899 +  shows "complete (f ` s)"
  6.3900 +proof -
  6.3901 +  have "\<exists>l\<in>f ` s. (g \<longlongrightarrow> l) sequentially"
  6.3902 +    if as:"\<forall>n::nat. g n \<in> f ` s" and cfg:"Cauchy g" for g
  6.3903 +  proof -
  6.3904 +    from that obtain x where "\<forall>n. x n \<in> s \<and> g n = f (x n)"
  6.3905 +      using choice[of "\<lambda> n xa. xa \<in> s \<and> g n = f xa"] by auto
  6.3906 +    then have x: "\<forall>n. x n \<in> s" "\<forall>n. g n = f (x n)" by auto
  6.3907 +    then have "f \<circ> x = g" by (simp add: fun_eq_iff)
  6.3908 +    then obtain l where "l\<in>s" and l:"(x \<longlongrightarrow> l) sequentially"
  6.3909 +      using cs[unfolded complete_def, THEN spec[where x=x]]
  6.3910 +      using cauchy_isometric[OF \<open>0 < e\<close> s f normf] and cfg and x(1)
  6.3911 +      by auto
  6.3912 +    then show ?thesis
  6.3913 +      using linear_continuous_at[OF f, unfolded continuous_at_sequentially, THEN spec[where x=x], of l]
  6.3914 +      by (auto simp: \<open>f \<circ> x = g\<close>)
  6.3915 +  qed
  6.3916 +  then show ?thesis
  6.3917 +    unfolding complete_def by auto
  6.3918 +qed
  6.3919 +
  6.3920 +lemma injective_imp_isometric:
  6.3921 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  6.3922 +  assumes s: "closed s" "subspace s"
  6.3923 +    and f: "bounded_linear f" "\<forall>x\<in>s. f x = 0 \<longrightarrow> x = 0"
  6.3924 +  shows "\<exists>e>0. \<forall>x\<in>s. norm (f x) \<ge> e * norm x"
  6.3925 +proof (cases "s \<subseteq> {0::'a}")
  6.3926 +  case True
  6.3927 +  have "norm x \<le> norm (f x)" if "x \<in> s" for x
  6.3928 +  proof -
  6.3929 +    from True that have "x = 0" by auto
  6.3930 +    then show ?thesis by simp
  6.3931 +  qed
  6.3932 +  then show ?thesis
  6.3933 +    by (auto intro!: exI[where x=1])
  6.3934 +next
  6.3935 +  case False
  6.3936 +  interpret f: bounded_linear f by fact
  6.3937 +  from False obtain a where a: "a \<noteq> 0" "a \<in> s"
  6.3938 +    by auto
  6.3939 +  from False have "s \<noteq> {}"
  6.3940 +    by auto
  6.3941 +  let ?S = "{f x| x. x \<in> s \<and> norm x = norm a}"
  6.3942 +  let ?S' = "{x::'a. x\<in>s \<and> norm x = norm a}"
  6.3943 +  let ?S'' = "{x::'a. norm x = norm a}"
  6.3944 +
  6.3945 +  have "?S'' = frontier (cball 0 (norm a))"
  6.3946 +    by (simp add: sphere_def dist_norm)
  6.3947 +  then have "compact ?S''" by (metis compact_cball compact_frontier)
  6.3948 +  moreover have "?S' = s \<inter> ?S''" by auto
  6.3949 +  ultimately have "compact ?S'"
  6.3950 +    using closed_Int_compact[of s ?S''] using s(1) by auto
  6.3951 +  moreover have *:"f ` ?S' = ?S" by auto
  6.3952 +  ultimately have "compact ?S"
  6.3953 +    using compact_continuous_image[OF linear_continuous_on[OF f(1)], of ?S'] by auto
  6.3954 +  then have "closed ?S"
  6.3955 +    using compact_imp_closed by auto
  6.3956 +  moreover from a have "?S \<noteq> {}" by auto
  6.3957 +  ultimately obtain b' where "b'\<in>?S" "\<forall>y\<in>?S. norm b' \<le> norm y"
  6.3958 +    using distance_attains_inf[of ?S 0] unfolding dist_0_norm by auto
  6.3959 +  then obtain b where "b\<in>s"
  6.3960 +    and ba: "norm b = norm a"
  6.3961 +    and b: "\<forall>x\<in>{x \<in> s. norm x = norm a}. norm (f b) \<le> norm (f x)"
  6.3962 +    unfolding *[symmetric] unfolding image_iff by auto
  6.3963 +
  6.3964 +  let ?e = "norm (f b) / norm b"
  6.3965 +  have "norm b > 0"
  6.3966 +    using ba and a and norm_ge_zero by auto
  6.3967 +  moreover have "norm (f b) > 0"
  6.3968 +    using f(2)[THEN bspec[where x=b], OF \<open>b\<in>s\<close>]
  6.3969 +    using \<open>norm b >0\<close> by simp
  6.3970 +  ultimately have "0 < norm (f b) / norm b" by simp
  6.3971 +  moreover
  6.3972 +  have "norm (f b) / norm b * norm x \<le> norm (f x)" if "x\<in>s" for x
  6.3973 +  proof (cases "x = 0")
  6.3974 +    case True
  6.3975 +    then show "norm (f b) / norm b * norm x \<le> norm (f x)"
  6.3976 +      by auto
  6.3977 +  next
  6.3978 +    case False
  6.3979 +    with \<open>a \<noteq> 0\<close> have *: "0 < norm a / norm x"
  6.3980 +      unfolding zero_less_norm_iff[symmetric] by simp
  6.3981 +    have "\<forall>x\<in>s. c *\<^sub>R x \<in> s" for c
  6.3982 +      using s[unfolded subspace_def] by simp
  6.3983 +    with \<open>x \<in> s\<close> \<open>x \<noteq> 0\<close> have "(norm a / norm x) *\<^sub>R x \<in> {x \<in> s. norm x = norm a}"
  6.3984 +      by simp
  6.3985 +    with \<open>x \<noteq> 0\<close> \<open>a \<noteq> 0\<close> show "norm (f b) / norm b * norm x \<le> norm (f x)"
  6.3986 +      using b[THEN bspec[where x="(norm a / norm x) *\<^sub>R x"]]
  6.3987 +      unfolding f.scaleR and ba
  6.3988 +      by (auto simp: mult.commute pos_le_divide_eq pos_divide_le_eq)
  6.3989 +  qed
  6.3990 +  ultimately show ?thesis by auto
  6.3991 +qed
  6.3992 +
  6.3993 +lemma closed_injective_image_subspace:
  6.3994 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  6.3995 +  assumes "subspace s" "bounded_linear f" "\<forall>x\<in>s. f x = 0 \<longrightarrow> x = 0" "closed s"
  6.3996 +  shows "closed(f ` s)"
  6.3997 +proof -
  6.3998 +  obtain e where "e > 0" and e: "\<forall>x\<in>s. e * norm x \<le> norm (f x)"
  6.3999 +    using injective_imp_isometric[OF assms(4,1,2,3)] by auto
  6.4000 +  show ?thesis
  6.4001 +    using complete_isometric_image[OF \<open>e>0\<close> assms(1,2) e] and assms(4)
  6.4002 +    unfolding complete_eq_closed[symmetric] by auto
  6.4003 +qed
  6.4004 +
  6.4005 +
  6.4006 +subsection \<open>Some properties of a canonical subspace\<close>
  6.4007 +
  6.4008 +lemma subspace_substandard: "subspace {x::'a::euclidean_space. (\<forall>i\<in>Basis. P i \<longrightarrow> x\<bullet>i = 0)}"
  6.4009 +  by (auto simp: subspace_def inner_add_left)
  6.4010 +
  6.4011 +lemma closed_substandard: "closed {x::'a::euclidean_space. \<forall>i\<in>Basis. P i \<longrightarrow> x\<bullet>i = 0}"
  6.4012 +  (is "closed ?A")
  6.4013 +proof -
  6.4014 +  let ?D = "{i\<in>Basis. P i}"
  6.4015 +  have "closed (\<Inter>i\<in>?D. {x::'a. x\<bullet>i = 0})"
  6.4016 +    by (simp add: closed_INT closed_Collect_eq continuous_on_inner
  6.4017 +        continuous_on_const continuous_on_id)
  6.4018 +  also have "(\<Inter>i\<in>?D. {x::'a. x\<bullet>i = 0}) = ?A"
  6.4019 +    by auto
  6.4020 +  finally show "closed ?A" .
  6.4021 +qed
  6.4022 +
  6.4023 +lemma dim_substandard:
  6.4024 +  assumes d: "d \<subseteq> Basis"
  6.4025 +  shows "dim {x::'a::euclidean_space. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x\<bullet>i = 0} = card d" (is "dim ?A = _")
  6.4026 +proof (rule dim_unique)
  6.4027 +  from d show "d \<subseteq> ?A"
  6.4028 +    by (auto simp: inner_Basis)
  6.4029 +  from d show "independent d"
  6.4030 +    by (rule independent_mono [OF independent_Basis])
  6.4031 +  have "x \<in> span d" if "\<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0" for x
  6.4032 +  proof -
  6.4033 +    have "finite d"
  6.4034 +      by (rule finite_subset [OF d finite_Basis])
  6.4035 +    then have "(\<Sum>i\<in>d. (x \<bullet> i) *\<^sub>R i) \<in> span d"
  6.4036 +      by (simp add: span_sum span_clauses)
  6.4037 +    also have "(\<Sum>i\<in>d. (x \<bullet> i) *\<^sub>R i) = (\<Sum>i\<in>Basis. (x \<bullet> i) *\<^sub>R i)"
  6.4038 +      by (rule sum.mono_neutral_cong_left [OF finite_Basis d]) (auto simp: that)
  6.4039 +    finally show "x \<in> span d"
  6.4040 +      by (simp only: euclidean_representation)
  6.4041 +  qed
  6.4042 +  then show "?A \<subseteq> span d" by auto
  6.4043 +qed simp
  6.4044 +
  6.4045 +text \<open>Hence closure and completeness of all subspaces.\<close>
  6.4046 +lemma ex_card:
  6.4047 +  assumes "n \<le> card A"
  6.4048 +  shows "\<exists>S\<subseteq>A. card S = n"
  6.4049 +proof (cases "finite A")
  6.4050 +  case True
  6.4051 +  from ex_bij_betw_nat_finite[OF this] obtain f where f: "bij_betw f {0..<card A} A" ..
  6.4052 +  moreover from f \<open>n \<le> card A\<close> have "{..< n} \<subseteq> {..< card A}" "inj_on f {..< n}"
  6.4053 +    by (auto simp: bij_betw_def intro: subset_inj_on)
  6.4054 +  ultimately have "f ` {..< n} \<subseteq> A" "card (f ` {..< n}) = n"
  6.4055 +    by (auto simp: bij_betw_def card_image)
  6.4056 +  then show ?thesis by blast
  6.4057 +next
  6.4058 +  case False
  6.4059 +  with \<open>n \<le> card A\<close> show ?thesis by force
  6.4060 +qed
  6.4061 +
  6.4062 +lemma closed_subspace:
  6.4063 +  fixes s :: "'a::euclidean_space set"
  6.4064 +  assumes "subspace s"
  6.4065 +  shows "closed s"
  6.4066 +proof -
  6.4067 +  have "dim s \<le> card (Basis :: 'a set)"
  6.4068 +    using dim_subset_UNIV by auto
  6.4069 +  with ex_card[OF this] obtain d :: "'a set" where t: "card d = dim s" and d: "d \<subseteq> Basis"
  6.4070 +    by auto
  6.4071 +  let ?t = "{x::'a. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x\<bullet>i = 0}"
  6.4072 +  have "\<exists>f. linear f \<and> f ` {x::'a. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0} = s \<and>
  6.4073 +      inj_on f {x::'a. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0}"
  6.4074 +    using dim_substandard[of d] t d assms
  6.4075 +    by (intro subspace_isomorphism[OF subspace_substandard[of "\<lambda>i. i \<notin> d"]]) (auto simp: inner_Basis)
  6.4076 +  then obtain f where f:
  6.4077 +      "linear f"
  6.4078 +      "f ` {x. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0} = s"
  6.4079 +      "inj_on f {x. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0}"
  6.4080 +    by blast
  6.4081 +  interpret f: bounded_linear f
  6.4082 +    using f by (simp add: linear_conv_bounded_linear)
  6.4083 +  have "x \<in> ?t \<Longrightarrow> f x = 0 \<Longrightarrow> x = 0" for x
  6.4084 +    using f.zero d f(3)[THEN inj_onD, of x 0] by auto
  6.4085 +  moreover have "closed ?t" by (rule closed_substandard)
  6.4086 +  moreover have "subspace ?t" by (rule subspace_substandard)
  6.4087 +  ultimately show ?thesis
  6.4088 +    using closed_injective_image_subspace[of ?t f]
  6.4089 +    unfolding f(2) using f(1) unfolding linear_conv_bounded_linear by auto
  6.4090 +qed
  6.4091 +
  6.4092 +lemma complete_subspace: "subspace s \<Longrightarrow> complete s"
  6.4093 +  for s :: "'a::euclidean_space set"
  6.4094 +  using complete_eq_closed closed_subspace by auto
  6.4095 +
  6.4096 +lemma closed_span [iff]: "closed (span s)"
  6.4097 +  for s :: "'a::euclidean_space set"
  6.4098 +  by (simp add: closed_subspace)
  6.4099 +
  6.4100 +lemma dim_closure [simp]: "dim (closure s) = dim s" (is "?dc = ?d")
  6.4101 +  for s :: "'a::euclidean_space set"
  6.4102 +proof -
  6.4103 +  have "?dc \<le> ?d"
  6.4104 +    using closure_minimal[OF span_inc, of s]
  6.4105 +    using closed_subspace[OF subspace_span, of s]
  6.4106 +    using dim_subset[of "closure s" "span s"]
  6.4107 +    by simp
  6.4108 +  then show ?thesis
  6.4109 +    using dim_subset[OF closure_subset, of s]
  6.4110 +    by simp
  6.4111 +qed
  6.4112 +
  6.4113 +
  6.4114 +subsection \<open>Affine transformations of intervals\<close>
  6.4115 +
  6.4116 +lemma real_affinity_le: "0 < m \<Longrightarrow> m * x + c \<le> y \<longleftrightarrow> x \<le> inverse m * y + - (c / m)"
  6.4117 +  for m :: "'a::linordered_field"
  6.4118 +  by (simp add: field_simps)
  6.4119 +
  6.4120 +lemma real_le_affinity: "0 < m \<Longrightarrow> y \<le> m * x + c \<longleftrightarrow> inverse m * y + - (c / m) \<le> x"
  6.4121 +  for m :: "'a::linordered_field"
  6.4122 +  by (simp add: field_simps)
  6.4123 +
  6.4124 +lemma real_affinity_lt: "0 < m \<Longrightarrow> m * x + c < y \<longleftrightarrow> x < inverse m * y + - (c / m)"
  6.4125 +  for m :: "'a::linordered_field"
  6.4126 +  by (simp add: field_simps)
  6.4127 +
  6.4128 +lemma real_lt_affinity: "0 < m \<Longrightarrow> y < m * x + c \<longleftrightarrow> inverse m * y + - (c / m) < x"
  6.4129 +  for m :: "'a::linordered_field"
  6.4130 +  by (simp add: field_simps)
  6.4131 +
  6.4132 +lemma real_affinity_eq: "m \<noteq> 0 \<Longrightarrow> m * x + c = y \<longleftrightarrow> x = inverse m * y + - (c / m)"
  6.4133 +  for m :: "'a::linordered_field"
  6.4134 +  by (simp add: field_simps)
  6.4135 +
  6.4136 +lemma real_eq_affinity: "m \<noteq> 0 \<Longrightarrow> y = m * x + c  \<longleftrightarrow> inverse m * y + - (c / m) = x"
  6.4137 +  for m :: "'a::linordered_field"
  6.4138 +  by (simp add: field_simps)
  6.4139 +
  6.4140 +
  6.4141 +subsection \<open>Banach fixed point theorem (not really topological ...)\<close>
  6.4142 +
  6.4143 +theorem banach_fix:
  6.4144 +  assumes s: "complete s" "s \<noteq> {}"
  6.4145 +    and c: "0 \<le> c" "c < 1"
  6.4146 +    and f: "f ` s \<subseteq> s"
  6.4147 +    and lipschitz: "\<forall>x\<in>s. \<forall>y\<in>s. dist (f x) (f y) \<le> c * dist x y"
  6.4148 +  shows "\<exists>!x\<in>s. f x = x"
  6.4149 +proof -
  6.4150 +  from c have "1 - c > 0" by simp
  6.4151 +
  6.4152 +  from s(2) obtain z0 where z0: "z0 \<in> s" by blast
  6.4153 +  define z where "z n = (f ^^ n) z0" for n
  6.4154 +  with f z0 have z_in_s: "z n \<in> s" for n :: nat
  6.4155 +    by (induct n) auto
  6.4156 +  define d where "d = dist (z 0) (z 1)"
  6.4157 +
  6.4158 +  have fzn: "f (z n) = z (Suc n)" for n
  6.4159 +    by (simp add: z_def)
  6.4160 +  have cf_z: "dist (z n) (z (Suc n)) \<le> (c ^ n) * d" for n :: nat
  6.4161 +  proof (induct n)
  6.4162 +    case 0
  6.4163 +    then show ?case
  6.4164 +      by (simp add: d_def)
  6.4165 +  next
  6.4166 +    case (Suc m)
  6.4167 +    with \<open>0 \<le> c\<close> have "c * dist (z m) (z (Suc m)) \<le> c ^ Suc m * d"
  6.4168 +      using mult_left_mono[of "dist (z m) (z (Suc m))" "c ^ m * d" c] by simp
  6.4169 +    then show ?case
  6.4170 +      using lipschitz[THEN bspec[where x="z m"], OF z_in_s, THEN bspec[where x="z (Suc m)"], OF z_in_s]
  6.4171 +      by (simp add: fzn mult_le_cancel_left)
  6.4172 +  qed
  6.4173 +
  6.4174 +  have cf_z2: "(1 - c) * dist (z m) (z (m + n)) \<le> (c ^ m) * d * (1 - c ^ n)" for n m :: nat
  6.4175 +  proof (induct n)
  6.4176 +    case 0
  6.4177 +    show ?case by simp
  6.4178 +  next
  6.4179 +    case (Suc k)
  6.4180 +    from c have "(1 - c) * dist (z m) (z (m + Suc k)) \<le>
  6.4181 +        (1 - c) * (dist (z m) (z (m + k)) + dist (z (m + k)) (z (Suc (m + k))))"
  6.4182 +      by (simp add: dist_triangle)
  6.4183 +    also from c cf_z[of "m + k"] have "\<dots> \<le> (1 - c) * (dist (z m) (z (m + k)) + c ^ (m + k) * d)"
  6.4184 +      by simp
  6.4185 +    also from Suc have "\<dots> \<le> c ^ m * d * (1 - c ^ k) + (1 - c) * c ^ (m + k) * d"
  6.4186 +      by (simp add: field_simps)
  6.4187 +    also have "\<dots> = (c ^ m) * (d * (1 - c ^ k) + (1 - c) * c ^ k * d)"
  6.4188 +      by (simp add: power_add field_simps)
  6.4189 +    also from c have "\<dots> \<le> (c ^ m) * d * (1 - c ^ Suc k)"
  6.4190 +      by (simp add: field_simps)
  6.4191 +    finally show ?case by simp
  6.4192 +  qed
  6.4193 +
  6.4194 +  have "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (z m) (z n) < e" if "e > 0" for e
  6.4195 +  proof (cases "d = 0")
  6.4196 +    case True
  6.4197 +    from \<open>1 - c > 0\<close> have "(1 - c) * x \<le> 0 \<longleftrightarrow> x \<le> 0" for x
  6.4198 +      by (metis mult_zero_left mult.commute real_mult_le_cancel_iff1)
  6.4199 +    with c cf_z2[of 0] True have "z n = z0" for n
  6.4200 +      by (simp add: z_def)
  6.4201 +    with \<open>e > 0\<close> show ?thesis by simp
  6.4202 +  next
  6.4203 +    case False
  6.4204 +    with zero_le_dist[of "z 0" "z 1"] have "d > 0"
  6.4205 +      by (metis d_def less_le)
  6.4206 +    with \<open>1 - c > 0\<close> \<open>e > 0\<close> have "0 < e * (1 - c) / d"
  6.4207 +      by simp
  6.4208 +    with c obtain N where N: "c ^ N < e * (1 - c) / d"
  6.4209 +      using real_arch_pow_inv[of "e * (1 - c) / d" c] by auto
  6.4210 +    have *: "dist (z m) (z n) < e" if "m > n" and as: "m \<ge> N" "n \<ge> N" for m n :: nat
  6.4211 +    proof -
  6.4212 +      from c \<open>n \<ge> N\<close> have *: "c ^ n \<le> c ^ N"
  6.4213 +        using power_decreasing[OF \<open>n\<ge>N\<close>, of c] by simp
  6.4214 +      from c \<open>m > n\<close> have "1 - c ^ (m - n) > 0"
  6.4215 +        using power_strict_mono[of c 1 "m - n"] by simp
  6.4216 +      with \<open>d > 0\<close> \<open>0 < 1 - c\<close> have **: "d * (1 - c ^ (m - n)) / (1 - c) > 0"
  6.4217 +        by simp
  6.4218 +      from cf_z2[of n "m - n"] \<open>m > n\<close>
  6.4219 +      have "dist (z m) (z n) \<le> c ^ n * d * (1 - c ^ (m - n)) / (1 - c)"
  6.4220 +        by (simp add: pos_le_divide_eq[OF \<open>1 - c > 0\<close>] mult.commute dist_commute)
  6.4221 +      also have "\<dots> \<le> c ^ N * d * (1 - c ^ (m - n)) / (1 - c)"
  6.4222 +        using mult_right_mono[OF * order_less_imp_le[OF **]]
  6.4223 +        by (simp add: mult.assoc)
  6.4224 +      also have "\<dots> < (e * (1 - c) / d) * d * (1 - c ^ (m - n)) / (1 - c)"
  6.4225 +        using mult_strict_right_mono[OF N **] by (auto simp: mult.assoc)
  6.4226 +      also from c \<open>d > 0\<close> \<open>1 - c > 0\<close> have "\<dots> = e * (1 - c ^ (m - n))"
  6.4227 +        by simp
  6.4228 +      also from c \<open>1 - c ^ (m - n) > 0\<close> \<open>e > 0\<close> have "\<dots> \<le> e"
  6.4229 +        using mult_right_le_one_le[of e "1 - c ^ (m - n)"] by auto
  6.4230 +      finally show ?thesis by simp
  6.4231 +    qed
  6.4232 +    have "dist (z n) (z m) < e" if "N \<le> m" "N \<le> n" for m n :: nat
  6.4233 +    proof (cases "n = m")
  6.4234 +      case True
  6.4235 +      with \<open>e > 0\<close> show ?thesis by simp
  6.4236 +    next
  6.4237 +      case False
  6.4238 +      with *[of n m] *[of m n] and that show ?thesis
  6.4239 +        by (auto simp: dist_commute nat_neq_iff)
  6.4240 +    qed
  6.4241 +    then show ?thesis by auto
  6.4242 +  qed
  6.4243 +  then have "Cauchy z"
  6.4244 +    by (simp add: cauchy_def)
  6.4245 +  then obtain x where "x\<in>s" and x:"(z \<longlongrightarrow> x) sequentially"
  6.4246 +    using s(1)[unfolded compact_def complete_def, THEN spec[where x=z]] and z_in_s by auto
  6.4247 +
  6.4248 +  define e where "e = dist (f x) x"
  6.4249 +  have "e = 0"
  6.4250 +  proof (rule ccontr)
  6.4251 +    assume "e \<noteq> 0"
  6.4252 +    then have "e > 0"
  6.4253 +      unfolding e_def using zero_le_dist[of "f x" x]
  6.4254 +      by (metis dist_eq_0_iff dist_nz e_def)
  6.4255 +    then obtain N where N:"\<forall>n\<ge>N. dist (z n) x < e / 2"
  6.4256 +      using x[unfolded lim_sequentially, THEN spec[where x="e/2"]] by auto
  6.4257 +    then have N':"dist (z N) x < e / 2" by auto
  6.4258 +    have *: "c * dist (z N) x \<le> dist (z N) x"
  6.4259 +      unfolding mult_le_cancel_right2
  6.4260 +      using zero_le_dist[of "z N" x] and c
  6.4261 +      by (metis dist_eq_0_iff dist_nz order_less_asym less_le)
  6.4262 +    have "dist (f (z N)) (f x) \<le> c * dist (z N) x"
  6.4263 +      using lipschitz[THEN bspec[where x="z N"], THEN bspec[where x=x]]
  6.4264 +      using z_in_s[of N] \<open>x\<in>s\<close>
  6.4265 +      using c
  6.4266 +      by auto
  6.4267 +    also have "\<dots> < e / 2"
  6.4268 +      using N' and c using * by auto
  6.4269 +    finally show False
  6.4270 +      unfolding fzn
  6.4271 +      using N[THEN spec[where x="Suc N"]] and dist_triangle_half_r[of "z (Suc N)" "f x" e x]
  6.4272 +      unfolding e_def
  6.4273 +      by auto
  6.4274 +  qed
  6.4275 +  then have "f x = x" by (auto simp: e_def)
  6.4276 +  moreover have "y = x" if "f y = y" "y \<in> s" for y
  6.4277 +  proof -
  6.4278 +    from \<open>x \<in> s\<close> \<open>f x = x\<close> that have "dist x y \<le> c * dist x y"
  6.4279 +      using lipschitz[THEN bspec[where x=x], THEN bspec[where x=y]] by simp
  6.4280 +    with c and zero_le_dist[of x y] have "dist x y = 0"
  6.4281 +      by (simp add: mult_le_cancel_right1)
  6.4282 +    then show ?thesis by simp
  6.4283 +  qed
  6.4284 +  ultimately show ?thesis
  6.4285 +    using \<open>x\<in>s\<close> by blast
  6.4286 +qed
  6.4287 +
  6.4288 +
  6.4289 +subsection \<open>Edelstein fixed point theorem\<close>
  6.4290 +
  6.4291 +theorem edelstein_fix:
  6.4292 +  fixes s :: "'a::metric_space set"
  6.4293 +  assumes s: "compact s" "s \<noteq> {}"
  6.4294 +    and gs: "(g ` s) \<subseteq> s"
  6.4295 +    and dist: "\<forall>x\<in>s. \<forall>y\<in>s. x \<noteq> y \<longrightarrow> dist (g x) (g y) < dist x y"
  6.4296 +  shows "\<exists>!x\<in>s. g x = x"
  6.4297 +proof -
  6.4298 +  let ?D = "(\<lambda>x. (x, x)) ` s"
  6.4299 +  have D: "compact ?D" "?D \<noteq> {}"
  6.4300 +    by (rule compact_continuous_image)
  6.4301 +       (auto intro!: s continuous_Pair continuous_ident simp: continuous_on_eq_continuous_within)
  6.4302 +
  6.4303 +  have "\<And>x y e. x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> 0 < e \<Longrightarrow> dist y x < e \<Longrightarrow> dist (g y) (g x) < e"
  6.4304 +    using dist by fastforce
  6.4305 +  then have "continuous_on s g"
  6.4306 +    by (auto simp: continuous_on_iff)
  6.4307 +  then have cont: "continuous_on ?D (\<lambda>x. dist ((g \<circ> fst) x) (snd x))"
  6.4308 +    unfolding continuous_on_eq_continuous_within
  6.4309 +    by (intro continuous_dist ballI continuous_within_compose)
  6.4310 +       (auto intro!: continuous_fst continuous_snd continuous_ident simp: image_image)
  6.4311 +
  6.4312 +  obtain a where "a \<in> s" and le: "\<And>x. x \<in> s \<Longrightarrow> dist (g a) a \<le> dist (g x) x"
  6.4313 +    using continuous_attains_inf[OF D cont] by auto
  6.4314 +
  6.4315 +  have "g a = a"
  6.4316 +  proof (rule ccontr)
  6.4317 +    assume "g a \<noteq> a"
  6.4318 +    with \<open>a \<in> s\<close> gs have "dist (g (g a)) (g a) < dist (g a) a"
  6.4319 +      by (intro dist[rule_format]) auto
  6.4320 +    moreover have "dist (g a) a \<le> dist (g (g a)) (g a)"
  6.4321 +      using \<open>a \<in> s\<close> gs by (intro le) auto
  6.4322 +    ultimately show False by auto
  6.4323 +  qed
  6.4324 +  moreover have "\<And>x. x \<in> s \<Longrightarrow> g x = x \<Longrightarrow> x = a"
  6.4325 +    using dist[THEN bspec[where x=a]] \<open>g a = a\<close> and \<open>a\<in>s\<close> by auto
  6.4326 +  ultimately show "\<exists>!x\<in>s. g x = x"
  6.4327 +    using \<open>a \<in> s\<close> by blast
  6.4328 +qed
  6.4329 +
  6.4330 +
  6.4331 +lemma cball_subset_cball_iff:
  6.4332 +  fixes a :: "'a :: euclidean_space"
  6.4333 +  shows "cball a r \<subseteq> cball a' r' \<longleftrightarrow> dist a a' + r \<le> r' \<or> r < 0"
  6.4334 +    (is "?lhs \<longleftrightarrow> ?rhs")
  6.4335 +proof
  6.4336 +  assume ?lhs
  6.4337 +  then show ?rhs
  6.4338 +  proof (cases "r < 0")
  6.4339 +    case True
  6.4340 +    then show ?rhs by simp
  6.4341 +  next
  6.4342 +    case False
  6.4343 +    then have [simp]: "r \<ge> 0" by simp
  6.4344 +    have "norm (a - a') + r \<le> r'"
  6.4345 +    proof (cases "a = a'")
  6.4346 +      case True
  6.4347 +      then show ?thesis
  6.4348 +        using subsetD [where c = "a + r *\<^sub>R (SOME i. i \<in> Basis)", OF \<open>?lhs\<close>] subsetD [where c = a, OF \<open>?lhs\<close>]
  6.4349 +        by (force simp: SOME_Basis dist_norm)
  6.4350 +    next
  6.4351 +      case False
  6.4352 +      have "norm (a' - (a + (r / norm (a - a')) *\<^sub>R (a - a'))) = norm (a' - a - (r / norm (a - a')) *\<^sub>R (a - a'))"
  6.4353 +        by (simp add: algebra_simps)
  6.4354 +      also have "... = norm ((-1 - (r / norm (a - a'))) *\<^sub>R (a - a'))"
  6.4355 +        by (simp add: algebra_simps)
  6.4356 +      also from \<open>a \<noteq> a'\<close> have "... = \<bar>- norm (a - a') - r\<bar>"
  6.4357 +        by (simp add: abs_mult_pos field_simps)
  6.4358 +      finally have [simp]: "norm (a' - (a + (r / norm (a - a')) *\<^sub>R (a - a'))) = \<bar>norm (a - a') + r\<bar>"
  6.4359 +        by linarith
  6.4360 +      from \<open>a \<noteq> a'\<close> show ?thesis
  6.4361 +        using subsetD [where c = "a' + (1 + r / norm(a - a')) *\<^sub>R (a - a')", OF \<open>?lhs\<close>]
  6.4362 +        by (simp add: dist_norm scaleR_add_left)
  6.4363 +    qed
  6.4364 +    then show ?rhs
  6.4365 +      by (simp add: dist_norm)
  6.4366 +  qed
  6.4367 +next
  6.4368 +  assume ?rhs
  6.4369 +  then show ?lhs
  6.4370 +    by (auto simp: ball_def dist_norm)
  6.4371 +      (metis add.commute add_le_cancel_right dist_norm dist_triangle3 order_trans)
  6.4372 +qed
  6.4373 +
  6.4374 +lemma cball_subset_ball_iff: "cball a r \<subseteq> ball a' r' \<longleftrightarrow> dist a a' + r < r' \<or> r < 0"
  6.4375 +  (is "?lhs \<longleftrightarrow> ?rhs")
  6.4376 +  for a :: "'a::euclidean_space"
  6.4377 +proof
  6.4378 +  assume ?lhs
  6.4379 +  then show ?rhs
  6.4380 +  proof (cases "r < 0")
  6.4381 +    case True then
  6.4382 +    show ?rhs by simp
  6.4383 +  next
  6.4384 +    case False
  6.4385 +    then have [simp]: "r \<ge> 0" by simp
  6.4386 +    have "norm (a - a') + r < r'"
  6.4387 +    proof (cases "a = a'")
  6.4388 +      case True
  6.4389 +      then show ?thesis
  6.4390 +        using subsetD [where c = "a + r *\<^sub>R (SOME i. i \<in> Basis)", OF \<open>?lhs\<close>] subsetD [where c = a, OF \<open>?lhs\<close>]
  6.4391 +        by (force simp: SOME_Basis dist_norm)
  6.4392 +    next
  6.4393 +      case False
  6.4394 +      have False if "norm (a - a') + r \<ge> r'"
  6.4395 +      proof -
  6.4396 +        from that have "\<bar>r' - norm (a - a')\<bar> \<le> r"
  6.4397 +          by (simp split: abs_split)
  6.4398 +            (metis \<open>0 \<le> r\<close> \<open>?lhs\<close> centre_in_cball dist_commute dist_norm less_asym mem_ball subset_eq)
  6.4399 +        then show ?thesis
  6.4400 +          using subsetD [where c = "a + (r' / norm(a - a') - 1) *\<^sub>R (a - a')", OF \<open>?lhs\<close>] \<open>a \<noteq> a'\<close>
  6.4401 +          by (simp add: dist_norm field_simps)
  6.4402 +            (simp add: diff_divide_distrib scaleR_left_diff_distrib)
  6.4403 +      qed
  6.4404 +      then show ?thesis by force
  6.4405 +    qed
  6.4406 +    then show ?rhs by (simp add: dist_norm)
  6.4407 +  qed
  6.4408 +next
  6.4409 +  assume ?rhs
  6.4410 +  then show ?lhs
  6.4411 +    by (auto simp: ball_def dist_norm)
  6.4412 +      (metis add.commute add_le_cancel_right dist_norm dist_triangle3 le_less_trans)
  6.4413 +qed
  6.4414 +
  6.4415 +lemma ball_subset_cball_iff: "ball a r \<subseteq> cball a' r' \<longleftrightarrow> dist a a' + r \<le> r' \<or> r \<le> 0"
  6.4416 +  (is "?lhs = ?rhs")
  6.4417 +  for a :: "'a::euclidean_space"
  6.4418 +proof (cases "r \<le> 0")
  6.4419 +  case True
  6.4420 +  then show ?thesis
  6.4421 +    using dist_not_less_zero less_le_trans by force
  6.4422 +next
  6.4423 +  case False
  6.4424 +  show ?thesis
  6.4425 +  proof
  6.4426 +    assume ?lhs
  6.4427 +    then have "(cball a r \<subseteq> cball a' r')"
  6.4428 +      by (metis False closed_cball closure_ball closure_closed closure_mono not_less)
  6.4429 +    with False show ?rhs
  6.4430 +      by (fastforce iff: cball_subset_cball_iff)
  6.4431 +  next
  6.4432 +    assume ?rhs
  6.4433 +    with False show ?lhs
  6.4434 +      using ball_subset_cball cball_subset_cball_iff by blast
  6.4435 +  qed
  6.4436 +qed
  6.4437 +
  6.4438 +lemma ball_subset_ball_iff:
  6.4439 +  fixes a :: "'a :: euclidean_space"
  6.4440 +  shows "ball a r \<subseteq> ball a' r' \<longleftrightarrow> dist a a' + r \<le> r' \<or> r \<le> 0"
  6.4441 +        (is "?lhs = ?rhs")
  6.4442 +proof (cases "r \<le> 0")
  6.4443 +  case True then show ?thesis
  6.4444 +    using dist_not_less_zero less_le_trans by force
  6.4445 +next
  6.4446 +  case False show ?thesis
  6.4447 +  proof
  6.4448 +    assume ?lhs
  6.4449 +    then have "0 < r'"
  6.4450 +      by (metis (no_types) False \<open>?lhs\<close> centre_in_ball dist_norm le_less_trans mem_ball norm_ge_zero not_less set_mp)
  6.4451 +    then have "(cball a r \<subseteq> cball a' r')"
  6.4452 +      by (metis False\<open>?lhs\<close> closure_ball closure_mono not_less)
  6.4453 +    then show ?rhs
  6.4454 +      using False cball_subset_cball_iff by fastforce
  6.4455 +  next
  6.4456 +  assume ?rhs then show ?lhs
  6.4457 +    apply (auto simp: ball_def)
  6.4458 +    apply (metis add.commute add_le_cancel_right dist_commute dist_triangle_lt not_le order_trans)
  6.4459 +    using dist_not_less_zero order.strict_trans2 apply blast
  6.4460 +    done
  6.4461 +  qed
  6.4462 +qed
  6.4463 +
  6.4464 +
  6.4465 +lemma ball_eq_ball_iff:
  6.4466 +  fixes x :: "'a :: euclidean_space"
  6.4467 +  shows "ball x d = ball y e \<longleftrightarrow> d \<le> 0 \<and> e \<le> 0 \<or> x=y \<and> d=e"
  6.4468 +        (is "?lhs = ?rhs")
  6.4469 +proof
  6.4470 +  assume ?lhs
  6.4471 +  then show ?rhs
  6.4472 +  proof (cases "d \<le> 0 \<or> e \<le> 0")
  6.4473 +    case True
  6.4474 +      with \<open>?lhs\<close> show ?rhs
  6.4475 +        by safe (simp_all only: ball_eq_empty [of y e, symmetric] ball_eq_empty [of x d, symmetric])
  6.4476 +  next
  6.4477 +    case False
  6.4478 +    with \<open>?lhs\<close> show ?rhs
  6.4479 +      apply (auto simp: set_eq_subset ball_subset_ball_iff dist_norm norm_minus_commute algebra_simps)
  6.4480 +      apply (metis add_le_same_cancel1 le_add_same_cancel1 norm_ge_zero norm_pths(2) order_trans)
  6.4481 +      apply (metis add_increasing2 add_le_imp_le_right eq_iff norm_ge_zero)
  6.4482 +      done
  6.4483 +  qed
  6.4484 +next
  6.4485 +  assume ?rhs then show ?lhs
  6.4486 +    by (auto simp: set_eq_subset ball_subset_ball_iff)
  6.4487 +qed
  6.4488 +
  6.4489 +lemma cball_eq_cball_iff:
  6.4490 +  fixes x :: "'a :: euclidean_space"
  6.4491 +  shows "cball x d = cball y e \<longleftrightarrow> d < 0 \<and> e < 0 \<or> x=y \<and> d=e"
  6.4492 +        (is "?lhs = ?rhs")
  6.4493 +proof
  6.4494 +  assume ?lhs
  6.4495 +  then show ?rhs
  6.4496 +  proof (cases "d < 0 \<or> e < 0")
  6.4497 +    case True
  6.4498 +      with \<open>?lhs\<close> show ?rhs
  6.4499 +        by safe (simp_all only: cball_eq_empty [of y e, symmetric] cball_eq_empty [of x d, symmetric])
  6.4500 +  next
  6.4501 +    case False
  6.4502 +    with \<open>?lhs\<close> show ?rhs
  6.4503 +      apply (auto simp: set_eq_subset cball_subset_cball_iff dist_norm norm_minus_commute algebra_simps)
  6.4504 +      apply (metis add_le_same_cancel1 le_add_same_cancel1 norm_ge_zero norm_pths(2) order_trans)
  6.4505 +      apply (metis add_increasing2 add_le_imp_le_right eq_iff norm_ge_zero)
  6.4506 +      done
  6.4507 +  qed
  6.4508 +next
  6.4509 +  assume ?rhs then show ?lhs
  6.4510 +    by (auto simp: set_eq_subset cball_subset_cball_iff)
  6.4511 +qed
  6.4512 +
  6.4513 +lemma ball_eq_cball_iff:
  6.4514 +  fixes x :: "'a :: euclidean_space"
  6.4515 +  shows "ball x d = cball y e \<longleftrightarrow> d \<le> 0 \<and> e < 0" (is "?lhs = ?rhs")
  6.4516 +proof
  6.4517 +  assume ?lhs
  6.4518 +  then show ?rhs
  6.4519 +    apply (auto simp: set_eq_subset ball_subset_cball_iff cball_subset_ball_iff algebra_simps)
  6.4520 +    apply (metis add_increasing2 add_le_cancel_right add_less_same_cancel1 dist_not_less_zero less_le_trans zero_le_dist)
  6.4521 +    apply (metis add_less_same_cancel1 dist_not_less_zero less_le_trans not_le)
  6.4522 +    using \<open>?lhs\<close> ball_eq_empty cball_eq_empty apply blast+
  6.4523 +    done
  6.4524 +next
  6.4525 +  assume ?rhs then show ?lhs by auto
  6.4526 +qed
  6.4527 +
  6.4528 +lemma cball_eq_ball_iff:
  6.4529 +  fixes x :: "'a :: euclidean_space"
  6.4530 +  shows "cball x d = ball y e \<longleftrightarrow> d < 0 \<and> e \<le> 0"
  6.4531 +  using ball_eq_cball_iff by blast
  6.4532 +
  6.4533 +lemma finite_ball_avoid:
  6.4534 +  fixes S :: "'a :: euclidean_space set"
  6.4535 +  assumes "open S" "finite X" "p \<in> S"
  6.4536 +  shows "\<exists>e>0. \<forall>w\<in>ball p e. w\<in>S \<and> (w\<noteq>p \<longrightarrow> w\<notin>X)"
  6.4537 +proof -
  6.4538 +  obtain e1 where "0 < e1" and e1_b:"ball p e1 \<subseteq> S"
  6.4539 +    using open_contains_ball_eq[OF \<open>open S\<close>] assms by auto
  6.4540 +  obtain e2 where "0 < e2" and "\<forall>x\<in>X. x \<noteq> p \<longrightarrow> e2 \<le> dist p x"
  6.4541 +    using finite_set_avoid[OF \<open>finite X\<close>,of p] by auto
  6.4542 +  hence "\<forall>w\<in>ball p (min e1 e2). w\<in>S \<and> (w\<noteq>p \<longrightarrow> w\<notin>X)" using e1_b by auto
  6.4543 +  thus "\<exists>e>0. \<forall>w\<in>ball p e. w \<in> S \<and> (w \<noteq> p \<longrightarrow> w \<notin> X)" using \<open>e2>0\<close> \<open>e1>0\<close>
  6.4544 +    apply (rule_tac x="min e1 e2" in exI)
  6.4545 +    by auto
  6.4546 +qed
  6.4547 +
  6.4548 +lemma finite_cball_avoid:
  6.4549 +  fixes S :: "'a :: euclidean_space set"
  6.4550 +  assumes "open S" "finite X" "p \<in> S"
  6.4551 +  shows "\<exists>e>0. \<forall>w\<in>cball p e. w\<in>S \<and> (w\<noteq>p \<longrightarrow> w\<notin>X)"
  6.4552 +proof -
  6.4553 +  obtain e1 where "e1>0" and e1: "\<forall>w\<in>ball p e1. w\<in>S \<and> (w\<noteq>p \<longrightarrow> w\<notin>X)"
  6.4554 +    using finite_ball_avoid[OF assms] by auto
  6.4555 +  define e2 where "e2 \<equiv> e1/2"
  6.4556 +  have "e2>0" and "e2 < e1" unfolding e2_def using \<open>e1>0\<close> by auto
  6.4557 +  then have "cball p e2 \<subseteq> ball p e1" by (subst cball_subset_ball_iff,auto)
  6.4558 +  then show "\<exists>e>0. \<forall>w\<in>cball p e. w \<in> S \<and> (w \<noteq> p \<longrightarrow> w \<notin> X)" using \<open>e2>0\<close> e1 by auto
  6.4559 +qed
  6.4560 +
  6.4561 +subsection\<open>Various separability-type properties\<close>
  6.4562 +
  6.4563 +lemma univ_second_countable:
  6.4564 +  obtains \<B> :: "'a::euclidean_space set set"
  6.4565 +  where "countable \<B>" "\<And>C. C \<in> \<B> \<Longrightarrow> open C"
  6.4566 +       "\<And>S. open S \<Longrightarrow> \<exists>U. U \<subseteq> \<B> \<and> S = \<Union>U"
  6.4567 +by (metis ex_countable_basis topological_basis_def)
  6.4568 +
  6.4569 +lemma subset_second_countable:
  6.4570 +  obtains \<B> :: "'a:: euclidean_space set set"
  6.4571 +    where "countable \<B>"
  6.4572 +          "{} \<notin> \<B>"
  6.4573 +          "\<And>C. C \<in> \<B> \<Longrightarrow> openin(subtopology euclidean S) C"
  6.4574 +          "\<And>T. openin(subtopology euclidean S) T \<Longrightarrow> \<exists>\<U>. \<U> \<subseteq> \<B> \<and> T = \<Union>\<U>"
  6.4575 +proof -
  6.4576 +  obtain \<B> :: "'a set set"
  6.4577 +    where "countable \<B>"
  6.4578 +      and opeB: "\<And>C. C \<in> \<B> \<Longrightarrow> openin(subtopology euclidean S) C"
  6.4579 +      and \<B>:    "\<And>T. openin(subtopology euclidean S) T \<Longrightarrow> \<exists>\<U>. \<U> \<subseteq> \<B> \<and> T = \<Union>\<U>"
  6.4580 +  proof -
  6.4581 +    obtain \<C> :: "'a set set"
  6.4582 +      where "countable \<C>" and ope: "\<And>C. C \<in> \<C> \<Longrightarrow> open C"
  6.4583 +        and \<C>: "\<And>S. open S \<Longrightarrow> \<exists>U. U \<subseteq> \<C> \<and> S = \<Union>U"
  6.4584 +      by (metis univ_second_countable that)
  6.4585 +    show ?thesis
  6.4586 +    proof
  6.4587 +      show "countable ((\<lambda>C. S \<inter> C) ` \<C>)"
  6.4588 +        by (simp add: \<open>countable \<C>\<close>)
  6.4589 +      show "\<And>C. C \<in> op \<inter> S ` \<C> \<Longrightarrow> openin (subtopology euclidean S) C"
  6.4590 +        using ope by auto
  6.4591 +      show "\<And>T. openin (subtopology euclidean S) T \<Longrightarrow> \<exists>\<U>\<subseteq>op \<inter> S ` \<C>. T = \<Union>\<U>"
  6.4592 +        by (metis \<C> image_mono inf_Sup openin_open)
  6.4593 +    qed
  6.4594 +  qed
  6.4595 +  show ?thesis
  6.4596 +  proof
  6.4597 +    show "countable (\<B> - {{}})"
  6.4598 +      using \<open>countable \<B>\<close> by blast
  6.4599 +    show "\<And>C. \<lbrakk>C \<in> \<B> - {{}}\<rbrakk> \<Longrightarrow> openin (subtopology euclidean S) C"
  6.4600 +      by (simp add: \<open>\<And>C. C \<in> \<B> \<Longrightarrow> openin (subtopology euclidean S) C\<close>)
  6.4601 +    show "\<exists>\<U>\<subseteq>\<B> - {{}}. T = \<Union>\<U>" if "openin (subtopology euclidean S) T" for T
  6.4602 +      using \<B> [OF that]
  6.4603 +      apply clarify
  6.4604 +      apply (rule_tac x="\<U> - {{}}" in exI, auto)
  6.4605 +        done
  6.4606 +  qed auto
  6.4607 +qed
  6.4608 +
  6.4609 +lemma univ_second_countable_sequence:
  6.4610 +  obtains B :: "nat \<Rightarrow> 'a::euclidean_space set"
  6.4611 +    where "inj B" "\<And>n. open(B n)" "\<And>S. open S \<Longrightarrow> \<exists>k. S = \<Union>{B n |n. n \<in> k}"
  6.4612 +proof -
  6.4613 +  obtain \<B> :: "'a set set"
  6.4614 +  where "countable \<B>"
  6.4615 +    and op: "\<And>C. C \<in> \<B> \<Longrightarrow> open C"
  6.4616 +    and Un: "\<And>S. open S \<Longrightarrow> \<exists>U. U \<subseteq> \<B> \<and> S = \<Union>U"
  6.4617 +    using univ_second_countable by blast
  6.4618 +  have *: "infinite (range (\<lambda>n. ball (0::'a) (inverse(Suc n))))"
  6.4619 +    apply (rule Infinite_Set.range_inj_infinite)
  6.4620 +    apply (simp add: inj_on_def ball_eq_ball_iff)
  6.4621 +    done
  6.4622 +  have "infinite \<B>"
  6.4623 +  proof
  6.4624 +    assume "finite \<B>"
  6.4625 +    then have "finite (Union ` (Pow \<B>))"
  6.4626 +      by simp
  6.4627 +    then have "finite (range (\<lambda>n. ball (0::'a) (inverse(Suc n))))"
  6.4628 +      apply (rule rev_finite_subset)
  6.4629 +      by (metis (no_types, lifting) PowI image_eqI image_subset_iff Un [OF open_ball])
  6.4630 +    with * show False by simp
  6.4631 +  qed
  6.4632 +  obtain f :: "nat \<Rightarrow> 'a set" where "\<B> = range f" "inj f"
  6.4633 +    by (blast intro: countable_as_injective_image [OF \<open>countable \<B>\<close> \<open>infinite \<B>\<close>])
  6.4634 +  have *: "\<exists>k. S = \<Union>{f n |n. n \<in> k}" if "open S" for S
  6.4635 +    using Un [OF that]
  6.4636 +    apply clarify
  6.4637 +    apply (rule_tac x="f-`U" in exI)
  6.4638 +    using \<open>inj f\<close> \<open>\<B> = range f\<close> apply force
  6.4639 +    done
  6.4640 +  show ?thesis
  6.4641 +    apply (rule that [OF \<open>inj f\<close> _ *])
  6.4642 +    apply (auto simp: \<open>\<B> = range f\<close> op)
  6.4643 +    done
  6.4644 +qed
  6.4645 +
  6.4646 +proposition separable:
  6.4647 +  fixes S :: "'a:: euclidean_space set"
  6.4648 +  obtains T where "countable T" "T \<subseteq> S" "S \<subseteq> closure T"
  6.4649 +proof -
  6.4650 +  obtain \<B> :: "'a:: euclidean_space set set"
  6.4651 +    where "countable \<B>"
  6.4652 +      and "{} \<notin> \<B>"
  6.4653 +      and ope: "\<And>C. C \<in> \<B> \<Longrightarrow> openin(subtopology euclidean S) C"
  6.4654 +      and if_ope: "\<And>T. openin(subtopology euclidean S) T \<Longrightarrow> \<exists>\<U>. \<U> \<subseteq> \<B> \<and> T = \<Union>\<U>"
  6.4655 +    by (meson subset_second_countable)
  6.4656 +  then obtain f where f: "\<And>C. C \<in> \<B> \<Longrightarrow> f C \<in> C"
  6.4657 +    by (metis equals0I)
  6.4658 +  show ?thesis
  6.4659 +  proof
  6.4660 +    show "countable (f ` \<B>)"
  6.4661 +      by (simp add: \<open>countable \<B>\<close>)
  6.4662 +    show "f ` \<B> \<subseteq> S"
  6.4663 +      using ope f openin_imp_subset by blast
  6.4664 +    show "S \<subseteq> closure (f ` \<B>)"
  6.4665 +    proof (clarsimp simp: closure_approachable)
  6.4666 +      fix x and e::real
  6.4667 +      assume "x \<in> S" "0 < e"
  6.4668 +      have "openin (subtopology euclidean S) (S \<inter> ball x e)"
  6.4669 +        by (simp add: openin_Int_open)
  6.4670 +      with if_ope obtain \<U> where  \<U>: "\<U> \<subseteq> \<B>" "S \<inter> ball x e = \<Union>\<U>"
  6.4671 +        by meson
  6.4672 +      show "\<exists>C \<in> \<B>. dist (f C) x < e"
  6.4673 +      proof (cases "\<U> = {}")
  6.4674 +        case True
  6.4675 +        then show ?thesis
  6.4676 +          using \<open>0 < e\<close>  \<U> \<open>x \<in> S\<close> by auto
  6.4677 +      next
  6.4678 +        case False
  6.4679 +        then obtain C where "C \<in> \<U>" by blast
  6.4680 +        show ?thesis
  6.4681 +        proof
  6.4682 +          show "dist (f C) x < e"
  6.4683 +            by (metis Int_iff Union_iff \<U> \<open>C \<in> \<U>\<close> dist_commute f mem_ball subsetCE)
  6.4684 +          show "C \<in> \<B>"
  6.4685 +            using \<open>\<U> \<subseteq> \<B>\<close> \<open>C \<in> \<U>\<close> by blast
  6.4686 +        qed
  6.4687 +      qed
  6.4688 +    qed
  6.4689 +  qed
  6.4690 +qed
  6.4691 +
  6.4692 +proposition Lindelof:
  6.4693 +  fixes \<F> :: "'a::euclidean_space set set"
  6.4694 +  assumes \<F>: "\<And>S. S \<in> \<F> \<Longrightarrow> open S"
  6.4695 +  obtains \<F>' where "\<F>' \<subseteq> \<F>" "countable \<F>'" "\<Union>\<F>' = \<Union>\<F>"
  6.4696 +proof -
  6.4697 +  obtain \<B> :: "'a set set"
  6.4698 +    where "countable \<B>" "\<And>C. C \<in> \<B> \<Longrightarrow> open C"
  6.4699 +      and \<B>: "\<And>S. open S \<Longrightarrow> \<exists>U. U \<subseteq> \<B> \<and> S = \<Union>U"
  6.4700 +    using univ_second_countable by blast
  6.4701 +  define \<D> where "\<D> \<equiv> {S. S \<in> \<B> \<and> (\<exists>U. U \<in> \<F> \<and> S \<subseteq> U)}"
  6.4702 +  have "countable \<D>"
  6.4703 +    apply (rule countable_subset [OF _ \<open>countable \<B>\<close>])
  6.4704 +    apply (force simp: \<D>_def)
  6.4705 +    done
  6.4706 +  have "\<And>S. \<exists>U. S \<in> \<D> \<longrightarrow> U \<in> \<F> \<and> S \<subseteq> U"
  6.4707 +    by (simp add: \<D>_def)
  6.4708 +  then obtain G where G: "\<And>S. S \<in> \<D> \<longrightarrow> G S \<in> \<F> \<and> S \<subseteq> G S"
  6.4709 +    by metis
  6.4710 +  have "\<Union>\<F> \<subseteq> \<Union>\<D>"
  6.4711 +    unfolding \<D>_def by (blast dest: \<F> \<B>)
  6.4712 +  moreover have "\<Union>\<D> \<subseteq> \<Union>\<F>"
  6.4713 +    using \<D>_def by blast
  6.4714 +  ultimately have eq1: "\<Union>\<F> = \<Union>\<D>" ..
  6.4715 +  have eq2: "\<Union>\<D> = UNION \<D> G"
  6.4716 +    using G eq1 by auto
  6.4717 +  show ?thesis
  6.4718 +    apply (rule_tac \<F>' = "G ` \<D>" in that)
  6.4719 +    using G \<open>countable \<D>\<close>  apply (auto simp: eq1 eq2)
  6.4720 +    done
  6.4721 +qed
  6.4722 +
  6.4723 +lemma Lindelof_openin:
  6.4724 +  fixes \<F> :: "'a::euclidean_space set set"
  6.4725 +  assumes "\<And>S. S \<in> \<F> \<Longrightarrow> openin (subtopology euclidean U) S"
  6.4726 +  obtains \<F>' where "\<F>' \<subseteq> \<F>" "countable \<F>'" "\<Union>\<F>' = \<Union>\<F>"
  6.4727 +proof -
  6.4728 +  have "\<And>S. S \<in> \<F> \<Longrightarrow> \<exists>T. open T \<and> S = U \<inter> T"
  6.4729 +    using assms by (simp add: openin_open)
  6.4730 +  then obtain tf where tf: "\<And>S. S \<in> \<F> \<Longrightarrow> open (tf S) \<and> (S = U \<inter> tf S)"
  6.4731 +    by metis
  6.4732 +  have [simp]: "\<And>\<F>'. \<F>' \<subseteq> \<F> \<Longrightarrow> \<Union>\<F>' = U \<inter> \<Union>(tf ` \<F>')"
  6.4733 +    using tf by fastforce
  6.4734 +  obtain \<G> where "countable \<G> \<and> \<G> \<subseteq> tf ` \<F>" "\<Union>\<G> = UNION \<F> tf"
  6.4735 +    using tf by (force intro: Lindelof [of "tf ` \<F>"])
  6.4736 +  then obtain \<F>' where \<F>': "\<F>' \<subseteq> \<F>" "countable \<F>'" "\<Union>\<F>' = \<Union>\<F>"
  6.4737 +    by (clarsimp simp add: countable_subset_image)
  6.4738 +  then show ?thesis ..
  6.4739 +qed
  6.4740 +
  6.4741 +lemma countable_disjoint_open_subsets:
  6.4742 +  fixes \<F> :: "'a::euclidean_space set set"
  6.4743 +  assumes "\<And>S. S \<in> \<F> \<Longrightarrow> open S" and pw: "pairwise disjnt \<F>"
  6.4744 +    shows "countable \<F>"
  6.4745 +proof -
  6.4746 +  obtain \<F>' where "\<F>' \<subseteq> \<F>" "countable \<F>'" "\<Union>\<F>' = \<Union>\<F>"
  6.4747 +    by (meson assms Lindelof)
  6.4748 +  with pw have "\<F> \<subseteq> insert {} \<F>'"
  6.4749 +    by (fastforce simp add: pairwise_def disjnt_iff)
  6.4750 +  then show ?thesis
  6.4751 +    by (simp add: \<open>countable \<F>'\<close> countable_subset)
  6.4752 +qed
  6.4753 +
  6.4754 +lemma closedin_compact:
  6.4755 +   "\<lbrakk>compact S; closedin (subtopology euclidean S) T\<rbrakk> \<Longrightarrow> compact T"
  6.4756 +by (metis closedin_closed compact_Int_closed)
  6.4757 +
  6.4758 +lemma closedin_compact_eq:
  6.4759 +  fixes S :: "'a::t2_space set"
  6.4760 +  shows
  6.4761 +   "compact S
  6.4762 +         \<Longrightarrow> (closedin (subtopology euclidean S) T \<longleftrightarrow>
  6.4763 +              compact T \<and> T \<subseteq> S)"
  6.4764 +by (metis closedin_imp_subset closedin_compact closed_subset compact_imp_closed)
  6.4765 +
  6.4766 +lemma continuous_imp_closed_map:
  6.4767 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  6.4768 +  assumes "closedin (subtopology euclidean S) U"
  6.4769 +          "continuous_on S f" "image f S = T" "compact S"
  6.4770 +    shows "closedin (subtopology euclidean T) (image f U)"
  6.4771 +  by (metis assms closedin_compact_eq compact_continuous_image continuous_on_subset subset_image_iff)
  6.4772 +
  6.4773 +lemma continuous_imp_quotient_map:
  6.4774 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  6.4775 +  assumes "continuous_on S f" "image f S = T" "compact S" "U \<subseteq> T"
  6.4776 +    shows "openin (subtopology euclidean S) {x. x \<in> S \<and> f x \<in> U} \<longleftrightarrow>
  6.4777 +           openin (subtopology euclidean T) U"
  6.4778 +  by (metis (no_types, lifting) Collect_cong assms closed_map_imp_quotient_map continuous_imp_closed_map)
  6.4779 +
  6.4780 +
  6.4781 +subsection\<open> Finite intersection property\<close>
  6.4782 +
  6.4783 +text\<open>Also developed in HOL's toplogical spaces theory, but the Heine-Borel type class isn't available there.\<close>
  6.4784 +
  6.4785 +lemma closed_imp_fip:
  6.4786 +  fixes S :: "'a::heine_borel set"
  6.4787 +  assumes "closed S"
  6.4788 +      and T: "T \<in> \<F>" "bounded T"
  6.4789 +      and clof: "\<And>T. T \<in> \<F> \<Longrightarrow> closed T"
  6.4790 +      and none: "\<And>\<F>'. \<lbrakk>finite \<F>'; \<F>' \<subseteq> \<F>\<rbrakk> \<Longrightarrow> S \<inter> \<Inter>\<F>' \<noteq> {}"
  6.4791 +    shows "S \<inter> \<Inter>\<F> \<noteq> {}"
  6.4792 +proof -
  6.4793 +  have "compact (S \<inter> T)"
  6.4794 +    using \<open>closed S\<close> clof compact_eq_bounded_closed T by blast
  6.4795 +  then have "(S \<inter> T) \<inter> \<Inter>\<F> \<noteq> {}"
  6.4796 +    apply (rule compact_imp_fip)
  6.4797 +     apply (simp add: clof)
  6.4798 +    by (metis Int_assoc complete_lattice_class.Inf_insert finite_insert insert_subset none \<open>T \<in> \<F>\<close>)
  6.4799 +  then show ?thesis by blast
  6.4800 +qed
  6.4801 +
  6.4802 +lemma closed_imp_fip_compact:
  6.4803 +  fixes S :: "'a::heine_borel set"
  6.4804 +  shows
  6.4805 +   "\<lbrakk>closed S; \<And>T. T \<in> \<F> \<Longrightarrow> compact T;
  6.4806 +     \<And>\<F>'. \<lbrakk>finite \<F>'; \<F>' \<subseteq> \<F>\<rbrakk> \<Longrightarrow> S \<inter> \<Inter>\<F>' \<noteq> {}\<rbrakk>
  6.4807 +        \<Longrightarrow> S \<inter> \<Inter>\<F> \<noteq> {}"
  6.4808 +by (metis Inf_greatest closed_imp_fip compact_eq_bounded_closed empty_subsetI finite.emptyI inf.orderE)
  6.4809 +
  6.4810 +lemma closed_fip_heine_borel:
  6.4811 +  fixes \<F> :: "'a::heine_borel set set"
  6.4812 +  assumes "closed S" "T \<in> \<F>" "bounded T"
  6.4813 +      and "\<And>T. T \<in> \<F> \<Longrightarrow> closed T"
  6.4814 +      and "\<And>\<F>'. \<lbrakk>finite \<F>'; \<F>' \<subseteq> \<F>\<rbrakk> \<Longrightarrow> \<Inter>\<F>' \<noteq> {}"
  6.4815 +    shows "\<Inter>\<F> \<noteq> {}"
  6.4816 +proof -
  6.4817 +  have "UNIV \<inter> \<Inter>\<F> \<noteq> {}"
  6.4818 +    using assms closed_imp_fip [OF closed_UNIV] by auto
  6.4819 +  then show ?thesis by simp
  6.4820 +qed
  6.4821 +
  6.4822 +lemma compact_fip_heine_borel:
  6.4823 +  fixes \<F> :: "'a::heine_borel set set"
  6.4824 +  assumes clof: "\<And>T. T \<in> \<F> \<Longrightarrow> compact T"
  6.4825 +      and none: "\<And>\<F>'. \<lbrakk>finite \<F>'; \<F>' \<subseteq> \<F>\<rbrakk> \<Longrightarrow> \<Inter>\<F>' \<noteq> {}"
  6.4826 +    shows "\<Inter>\<F> \<noteq> {}"
  6.4827 +by (metis InterI all_not_in_conv clof closed_fip_heine_borel compact_eq_bounded_closed none)
  6.4828 +
  6.4829 +lemma compact_sequence_with_limit:
  6.4830 +  fixes f :: "nat \<Rightarrow> 'a::heine_borel"
  6.4831 +  shows "(f \<longlongrightarrow> l) sequentially \<Longrightarrow> compact (insert l (range f))"
  6.4832 +apply (simp add: compact_eq_bounded_closed, auto)
  6.4833 +apply (simp add: convergent_imp_bounded)
  6.4834 +by (simp add: closed_limpt islimpt_insert sequence_unique_limpt)
  6.4835 +
  6.4836 +
  6.4837 +subsection\<open>Componentwise limits and continuity\<close>
  6.4838 +
  6.4839 +text\<open>But is the premise really necessary? Need to generalise @{thm euclidean_dist_l2}\<close>
  6.4840 +lemma Euclidean_dist_upper: "i \<in> Basis \<Longrightarrow> dist (x \<bullet> i) (y \<bullet> i) \<le> dist x y"
  6.4841 +  by (metis (no_types) member_le_setL2 euclidean_dist_l2 finite_Basis)
  6.4842 +
  6.4843 +text\<open>But is the premise @{term \<open>i \<in> Basis\<close>} really necessary?\<close>
  6.4844 +lemma open_preimage_inner:
  6.4845 +  assumes "open S" "i \<in> Basis"
  6.4846 +    shows "open {x. x \<bullet> i \<in> S}"
  6.4847 +proof (rule openI, simp)
  6.4848 +  fix x
  6.4849 +  assume x: "x \<bullet> i \<in> S"
  6.4850 +  with assms obtain e where "0 < e" and e: "ball (x \<bullet> i) e \<subseteq> S"
  6.4851 +    by (auto simp: open_contains_ball_eq)
  6.4852 +  have "\<exists>e>0. ball (y \<bullet> i) e \<subseteq> S" if dxy: "dist x y < e / 2" for y
  6.4853 +  proof (intro exI conjI)
  6.4854 +    have "dist (x \<bullet> i) (y \<bullet> i) < e / 2"
  6.4855 +      by (meson \<open>i \<in> Basis\<close> dual_order.trans Euclidean_dist_upper not_le that)
  6.4856 +    then have "dist (x \<bullet> i) z < e" if "dist (y \<bullet> i) z < e / 2" for z
  6.4857 +      by (metis dist_commute dist_triangle_half_l that)
  6.4858 +    then have "ball (y \<bullet> i) (e / 2) \<subseteq> ball (x \<bullet> i) e"
  6.4859 +      using mem_ball by blast
  6.4860 +      with e show "ball (y \<bullet> i) (e / 2) \<subseteq> S"
  6.4861 +        by (metis order_trans)
  6.4862 +  qed (simp add: \<open>0 < e\<close>)
  6.4863 +  then show "\<exists>e>0. ball x e \<subseteq> {s. s \<bullet> i \<in> S}"
  6.4864 +    by (metis (no_types, lifting) \<open>0 < e\<close> \<open>open S\<close> half_gt_zero_iff mem_Collect_eq mem_ball open_contains_ball_eq subsetI)
  6.4865 +qed
  6.4866 +
  6.4867 +proposition tendsto_componentwise_iff:
  6.4868 +  fixes f :: "_ \<Rightarrow> 'b::euclidean_space"
  6.4869 +  shows "(f \<longlongrightarrow> l) F \<longleftrightarrow> (\<forall>i \<in> Basis. ((\<lambda>x. (f x \<bullet> i)) \<longlongrightarrow> (l \<bullet> i)) F)"
  6.4870 +         (is "?lhs = ?rhs")
  6.4871 +proof
  6.4872 +  assume ?lhs
  6.4873 +  then show ?rhs
  6.4874 +    unfolding tendsto_def
  6.4875 +    apply clarify
  6.4876 +    apply (drule_tac x="{s. s \<bullet> i \<in> S}" in spec)
  6.4877 +    apply (auto simp: open_preimage_inner)
  6.4878 +    done
  6.4879 +next
  6.4880 +  assume R: ?rhs
  6.4881 +  then have "\<And>e. e > 0 \<Longrightarrow> \<forall>i\<in>Basis. \<forall>\<^sub>F x in F. dist (f x \<bullet> i) (l \<bullet> i) < e"
  6.4882 +    unfolding tendsto_iff by blast
  6.4883 +  then have R': "\<And>e. e > 0 \<Longrightarrow> \<forall>\<^sub>F x in F. \<forall>i\<in>Basis. dist (f x \<bullet> i) (l \<bullet> i) < e"
  6.4884 +      by (simp add: eventually_ball_finite_distrib [symmetric])
  6.4885 +  show ?lhs
  6.4886 +  unfolding tendsto_iff
  6.4887 +  proof clarify
  6.4888 +    fix e::real
  6.4889 +    assume "0 < e"
  6.4890 +    have *: "setL2 (\<lambda>i. dist (f x \<bullet> i) (l \<bullet> i)) Basis < e"
  6.4891 +             if "\<forall>i\<in>Basis. dist (f x \<bullet> i) (l \<bullet> i) < e / real DIM('b)" for x
  6.4892 +    proof -
  6.4893 +      have "setL2 (\<lambda>i. dist (f x \<bullet> i) (l \<bullet> i)) Basis \<le> sum (\<lambda>i. dist (f x \<bullet> i) (l \<bullet> i)) Basis"
  6.4894 +        by (simp add: setL2_le_sum)
  6.4895 +      also have "... < DIM('b) * (e / real DIM('b))"
  6.4896 +        apply (rule sum_bounded_above_strict)
  6.4897 +        using that by auto
  6.4898 +      also have "... = e"
  6.4899 +        by (simp add: field_simps)
  6.4900 +      finally show "setL2 (\<lambda>i. dist (f x \<bullet> i) (l \<bullet> i)) Basis < e" .
  6.4901 +    qed
  6.4902 +    have "\<forall>\<^sub>F x in F. \<forall>i\<in>Basis. dist (f x \<bullet> i) (l \<bullet> i) < e / DIM('b)"
  6.4903 +      apply (rule R')
  6.4904 +      using \<open>0 < e\<close> by simp
  6.4905 +    then show "\<forall>\<^sub>F x in F. dist (f x) l < e"
  6.4906 +      apply (rule eventually_mono)
  6.4907 +      apply (subst euclidean_dist_l2)
  6.4908 +      using * by blast
  6.4909 +  qed
  6.4910 +qed
  6.4911 +
  6.4912 +
  6.4913 +corollary continuous_componentwise:
  6.4914 +   "continuous F f \<longleftrightarrow> (\<forall>i \<in> Basis. continuous F (\<lambda>x. (f x \<bullet> i)))"
  6.4915 +by (simp add: continuous_def tendsto_componentwise_iff [symmetric])
  6.4916 +
  6.4917 +corollary continuous_on_componentwise:
  6.4918 +  fixes S :: "'a :: t2_space set"
  6.4919 +  shows "continuous_on S f \<longleftrightarrow> (\<forall>i \<in> Basis. continuous_on S (\<lambda>x. (f x \<bullet> i)))"
  6.4920 +  apply (simp add: continuous_on_eq_continuous_within)
  6.4921 +  using continuous_componentwise by blast
  6.4922 +
  6.4923 +lemma linear_componentwise_iff:
  6.4924 +     "(linear f') \<longleftrightarrow> (\<forall>i\<in>Basis. linear (\<lambda>x. f' x \<bullet> i))"
  6.4925 +  apply (auto simp: linear_iff inner_left_distrib)
  6.4926 +   apply (metis inner_left_distrib euclidean_eq_iff)
  6.4927 +  by (metis euclidean_eqI inner_scaleR_left)
  6.4928 +
  6.4929 +lemma bounded_linear_componentwise_iff:
  6.4930 +     "(bounded_linear f') \<longleftrightarrow> (\<forall>i\<in>Basis. bounded_linear (\<lambda>x. f' x \<bullet> i))"
  6.4931 +     (is "?lhs = ?rhs")
  6.4932 +proof
  6.4933 +  assume ?lhs then show ?rhs
  6.4934 +    by (simp add: bounded_linear_inner_left_comp)
  6.4935 +next
  6.4936 +  assume ?rhs
  6.4937 +  then have "(\<forall>i\<in>Basis. \<exists>K. \<forall>x. \<bar>f' x \<bullet> i\<bar> \<le> norm x * K)" "linear f'"
  6.4938 +    by (auto simp: bounded_linear_def bounded_linear_axioms_def linear_componentwise_iff [symmetric] ball_conj_distrib)
  6.4939 +  then obtain F where F: "\<And>i x. i \<in> Basis \<Longrightarrow> \<bar>f' x \<bullet> i\<bar> \<le> norm x * F i"
  6.4940 +    by metis
  6.4941 +  have "norm (f' x) \<le> norm x * sum F Basis" for x
  6.4942 +  proof -
  6.4943 +    have "norm (f' x) \<le> (\<Sum>i\<in>Basis. \<bar>f' x \<bullet> i\<bar>)"
  6.4944 +      by (rule norm_le_l1)
  6.4945 +    also have "... \<le> (\<Sum>i\<in>Basis. norm x * F i)"
  6.4946 +      by (metis F sum_mono)
  6.4947 +    also have "... = norm x * sum F Basis"
  6.4948 +      by (simp add: sum_distrib_left)
  6.4949 +    finally show ?thesis .
  6.4950 +  qed
  6.4951 +  then show ?lhs
  6.4952 +    by (force simp: bounded_linear_def bounded_linear_axioms_def \<open>linear f'\<close>)
  6.4953 +qed
  6.4954 +
  6.4955 +subsection\<open>Pasting functions together\<close>
  6.4956 +
  6.4957 +subsubsection\<open>on open sets\<close>
  6.4958 +
  6.4959 +lemma pasting_lemma:
  6.4960 +  fixes f :: "'i \<Rightarrow> 'a::topological_space \<Rightarrow> 'b::topological_space"
  6.4961 +  assumes clo: "\<And>i. i \<in> I \<Longrightarrow> openin (subtopology euclidean S) (T i)"
  6.4962 +      and cont: "\<And>i. i \<in> I \<Longrightarrow> continuous_on (T i) (f i)"
  6.4963 +      and f: "\<And>i j x. \<lbrakk>i \<in> I; j \<in> I; x \<in> S \<inter> T i \<inter> T j\<rbrakk> \<Longrightarrow> f i x = f j x"
  6.4964 +      and g: "\<And>x. x \<in> S \<Longrightarrow> \<exists>j. j \<in> I \<and> x \<in> T j \<and> g x = f j x"
  6.4965 +    shows "continuous_on S g"
  6.4966 +proof (clarsimp simp: continuous_openin_preimage_eq)
  6.4967 +  fix U :: "'b set"
  6.4968 +  assume "open U"
  6.4969 +  have S: "\<And>i. i \<in> I \<Longrightarrow> (T i) \<subseteq> S"
  6.4970 +    using clo openin_imp_subset by blast
  6.4971 +  have *: "{x \<in> S. g x \<in> U} = \<Union>{{x. x \<in> (T i) \<and> (f i x) \<in> U} |i. i \<in> I}"
  6.4972 +    apply (auto simp: dest: S)
  6.4973 +      apply (metis (no_types, lifting) g mem_Collect_eq)
  6.4974 +    using clo f g openin_imp_subset by fastforce
  6.4975 +  show "openin (subtopology euclidean S) {x \<in> S. g x \<in> U}"
  6.4976 +    apply (subst *)
  6.4977 +    apply (rule openin_Union, clarify)
  6.4978 +    apply (metis (full_types) \<open>open U\<close> cont clo openin_trans continuous_openin_preimage_gen)
  6.4979 +    done
  6.4980 +qed
  6.4981 +
  6.4982 +lemma pasting_lemma_exists:
  6.4983 +  fixes f :: "'i \<Rightarrow> 'a::topological_space \<Rightarrow> 'b::topological_space"
  6.4984 +  assumes S: "S \<subseteq> (\<Union>i \<in> I. T i)"
  6.4985 +      and clo: "\<And>i. i \<in> I \<Longrightarrow> openin (subtopology euclidean S) (T i)"
  6.4986 +      and cont: "\<And>i. i \<in> I \<Longrightarrow> continuous_on (T i) (f i)"
  6.4987 +      and f: "\<And>i j x. \<lbrakk>i \<in> I; j \<in> I; x \<in> S \<inter> T i \<inter> T j\<rbrakk> \<Longrightarrow> f i x = f j x"
  6.4988 +    obtains g where "continuous_on S g" "\<And>x i. \<lbrakk>i \<in> I; x \<in> S \<inter> T i\<rbrakk> \<Longrightarrow> g x = f i x"
  6.4989 +proof
  6.4990 +  show "continuous_on S (\<lambda>x. f (SOME i. i \<in> I \<and> x \<in> T i) x)"
  6.4991 +    apply (rule pasting_lemma [OF clo cont])
  6.4992 +     apply (blast intro: f)+
  6.4993 +    apply (metis (mono_tags, lifting) S UN_iff subsetCE someI)
  6.4994 +    done
  6.4995 +next
  6.4996 +  fix x i
  6.4997 +  assume "i \<in> I" "x \<in> S \<inter> T i"
  6.4998 +  then show "f (SOME i. i \<in> I \<and> x \<in> T i) x = f i x"
  6.4999 +    by (metis (no_types, lifting) IntD2 IntI f someI_ex)
  6.5000 +qed
  6.5001 +
  6.5002 +subsubsection\<open>Likewise on closed sets, with a finiteness assumption\<close>
  6.5003 +
  6.5004 +lemma pasting_lemma_closed:
  6.5005 +  fixes f :: "'i \<Rightarrow> 'a::topological_space \<Rightarrow> 'b::topological_space"
  6.5006 +  assumes "finite I"
  6.5007 +      and clo: "\<And>i. i \<in> I \<Longrightarrow> closedin (subtopology euclidean S) (T i)"
  6.5008 +      and cont: "\<And>i. i \<in> I \<Longrightarrow> continuous_on (T i) (f i)"
  6.5009 +      and f: "\<And>i j x. \<lbrakk>i \<in> I; j \<in> I; x \<in> S \<inter> T i \<inter> T j\<rbrakk> \<Longrightarrow> f i x = f j x"
  6.5010 +      and g: "\<And>x. x \<in> S \<Longrightarrow> \<exists>j. j \<in> I \<and> x \<in> T j \<and> g x = f j x"
  6.5011 +    shows "continuous_on S g"
  6.5012 +proof (clarsimp simp: continuous_closedin_preimage_eq)
  6.5013 +  fix U :: "'b set"
  6.5014 +  assume "closed U"
  6.5015 +  have *: "{x \<in> S. g x \<in> U} = \<Union>{{x. x \<in> (T i) \<and> (f i x) \<in> U} |i. i \<in> I}"
  6.5016 +    apply auto
  6.5017 +    apply (metis (no_types, lifting) g mem_Collect_eq)
  6.5018 +    using clo closedin_closed apply blast
  6.5019 +    apply (metis Int_iff f g clo closedin_limpt inf.absorb_iff2)
  6.5020 +    done
  6.5021 +  show "closedin (subtopology euclidean S) {x \<in> S. g x \<in> U}"
  6.5022 +    apply (subst *)
  6.5023 +    apply (rule closedin_Union)
  6.5024 +    using \<open>finite I\<close> apply simp
  6.5025 +    apply (blast intro: \<open>closed U\<close> continuous_closedin_preimage cont clo closedin_trans)
  6.5026 +    done
  6.5027 +qed
  6.5028 +
  6.5029 +lemma pasting_lemma_exists_closed:
  6.5030 +  fixes f :: "'i \<Rightarrow> 'a::topological_space \<Rightarrow> 'b::topological_space"
  6.5031 +  assumes "finite I"
  6.5032 +      and S: "S \<subseteq> (\<Union>i \<in> I. T i)"
  6.5033 +      and clo: "\<And>i. i \<in> I \<Longrightarrow> closedin (subtopology euclidean S) (T i)"
  6.5034 +      and cont: "\<And>i. i \<in> I \<Longrightarrow> continuous_on (T i) (f i)"
  6.5035 +      and f: "\<And>i j x. \<lbrakk>i \<in> I; j \<in> I; x \<in> S \<inter> T i \<inter> T j\<rbrakk> \<Longrightarrow> f i x = f j x"
  6.5036 +    obtains g where "continuous_on S g" "\<And>x i. \<lbrakk>i \<in> I; x \<in> S \<inter> T i\<rbrakk> \<Longrightarrow> g x = f i x"
  6.5037 +proof
  6.5038 +  show "continuous_on S (\<lambda>x. f (SOME i. i \<in> I \<and> x \<in> T i) x)"
  6.5039 +    apply (rule pasting_lemma_closed [OF \<open>finite I\<close> clo cont])
  6.5040 +     apply (blast intro: f)+
  6.5041 +    apply (metis (mono_tags, lifting) S UN_iff subsetCE someI)
  6.5042 +    done
  6.5043 +next
  6.5044 +  fix x i
  6.5045 +  assume "i \<in> I" "x \<in> S \<inter> T i"
  6.5046 +  then show "f (SOME i. i \<in> I \<and> x \<in> T i) x = f i x"
  6.5047 +    by (metis (no_types, lifting) IntD2 IntI f someI_ex)
  6.5048 +qed
  6.5049 +
  6.5050 +lemma tube_lemma:
  6.5051 +  assumes "compact K"
  6.5052 +  assumes "open W"
  6.5053 +  assumes "{x0} \<times> K \<subseteq> W"
  6.5054 +  shows "\<exists>X0. x0 \<in> X0 \<and> open X0 \<and> X0 \<times> K \<subseteq> W"
  6.5055 +proof -
  6.5056 +  {
  6.5057 +    fix y assume "y \<in> K"
  6.5058 +    then have "(x0, y) \<in> W" using assms by auto
  6.5059 +    with \<open>open W\<close>
  6.5060 +    have "\<exists>X0 Y. open X0 \<and> open Y \<and> x0 \<in> X0 \<and> y \<in> Y \<and> X0 \<times> Y \<subseteq> W"
  6.5061 +      by (rule open_prod_elim) blast
  6.5062 +  }
  6.5063 +  then obtain X0 Y where
  6.5064 +    *: "\<forall>y \<in> K. open (X0 y) \<and> open (Y y) \<and> x0 \<in> X0 y \<and> y \<in> Y y \<and> X0 y \<times> Y y \<subseteq> W"
  6.5065 +    by metis
  6.5066 +  from * have "\<forall>t\<in>Y ` K. open t" "K \<subseteq> \<Union>(Y ` K)" by auto
  6.5067 +  with \<open>compact K\<close> obtain CC where CC: "CC \<subseteq> Y ` K" "finite CC" "K \<subseteq> \<Union>CC"
  6.5068 +    by (meson compactE)
  6.5069 +  then obtain c where c: "\<And>C. C \<in> CC \<Longrightarrow> c C \<in> K \<and> C = Y (c C)"
  6.5070 +    by (force intro!: choice)
  6.5071 +  with * CC show ?thesis
  6.5072 +    by (force intro!: exI[where x="\<Inter>C\<in>CC. X0 (c C)"]) (* SLOW *)
  6.5073 +qed
  6.5074 +
  6.5075 +lemma continuous_on_prod_compactE:
  6.5076 +  fixes fx::"'a::topological_space \<times> 'b::topological_space \<Rightarrow> 'c::metric_space"
  6.5077 +    and e::real
  6.5078 +  assumes cont_fx: "continuous_on (U \<times> C) fx"
  6.5079 +  assumes "compact C"
  6.5080 +  assumes [intro]: "x0 \<in> U"
  6.5081 +  notes [continuous_intros] = continuous_on_compose2[OF cont_fx]
  6.5082 +  assumes "e > 0"
  6.5083 +  obtains X0 where "x0 \<in> X0" "open X0"
  6.5084 +    "\<forall>x\<in>X0 \<inter> U. \<forall>t \<in> C. dist (fx (x, t)) (fx (x0, t)) \<le> e"
  6.5085 +proof -
  6.5086 +  define psi where "psi = (\<lambda>(x, t). dist (fx (x, t)) (fx (x0, t)))"
  6.5087 +  define W0 where "W0 = {(x, t) \<in> U \<times> C. psi (x, t) < e}"
  6.5088 +  have W0_eq: "W0 = psi -` {..<e} \<inter> U \<times> C"
  6.5089 +    by (auto simp: vimage_def W0_def)
  6.5090 +  have "open {..<e}" by simp
  6.5091 +  have "continuous_on (U \<times> C) psi"
  6.5092 +    by (auto intro!: continuous_intros simp: psi_def split_beta')
  6.5093 +  from this[unfolded continuous_on_open_invariant, rule_format, OF \<open>open {..<e}\<close>]
  6.5094 +  obtain W where W: "open W" "W \<inter> U \<times> C = W0 \<inter> U \<times> C"
  6.5095 +    unfolding W0_eq by blast
  6.5096 +  have "{x0} \<times> C \<subseteq> W \<inter> U \<times> C"
  6.5097 +    unfolding W
  6.5098 +    by (auto simp: W0_def psi_def \<open>0 < e\<close>)
  6.5099 +  then have "{x0} \<times> C \<subseteq> W" by blast
  6.5100 +  from tube_lemma[OF \<open>compact C\<close> \<open>open W\<close> this]
  6.5101 +  obtain X0 where X0: "x0 \<in> X0" "open X0" "X0 \<times> C \<subseteq> W"
  6.5102 +    by blast
  6.5103 +
  6.5104 +  have "\<forall>x\<in>X0 \<inter> U. \<forall>t \<in> C. dist (fx (x, t)) (fx (x0, t)) \<le> e"
  6.5105 +  proof safe
  6.5106 +    fix x assume x: "x \<in> X0" "x \<in> U"
  6.5107 +    fix t assume t: "t \<in> C"
  6.5108 +    have "dist (fx (x, t)) (fx (x0, t)) = psi (x, t)"
  6.5109 +      by (auto simp: psi_def)
  6.5110 +    also
  6.5111 +    {
  6.5112 +      have "(x, t) \<in> X0 \<times> C"
  6.5113 +        using t x
  6.5114 +        by auto
  6.5115 +      also note \<open>\<dots> \<subseteq> W\<close>
  6.5116 +      finally have "(x, t) \<in> W" .
  6.5117 +      with t x have "(x, t) \<in> W \<inter> U \<times> C"
  6.5118 +        by blast
  6.5119 +      also note \<open>W \<inter> U \<times> C = W0 \<inter> U \<times> C\<close>
  6.5120 +      finally  have "psi (x, t) < e"
  6.5121 +        by (auto simp: W0_def)
  6.5122 +    }
  6.5123 +    finally show "dist (fx (x, t)) (fx (x0, t)) \<le> e" by simp
  6.5124 +  qed
  6.5125 +  from X0(1,2) this show ?thesis ..
  6.5126 +qed
  6.5127 +
  6.5128 +
  6.5129 +subsection\<open>Constancy of a function from a connected set into a finite, disconnected or discrete set\<close>
  6.5130 +
  6.5131 +text\<open>Still missing: versions for a set that is smaller than R, or countable.\<close>
  6.5132 +
  6.5133 +lemma continuous_disconnected_range_constant:
  6.5134 +  assumes S: "connected S"
  6.5135 +      and conf: "continuous_on S f"
  6.5136 +      and fim: "f ` S \<subseteq> t"
  6.5137 +      and cct: "\<And>y. y \<in> t \<Longrightarrow> connected_component_set t y = {y}"
  6.5138 +    shows "\<exists>a. \<forall>x \<in> S. f x = a"
  6.5139 +proof (cases "S = {}")
  6.5140 +  case True then show ?thesis by force
  6.5141 +next
  6.5142 +  case False
  6.5143 +  { fix x assume "x \<in> S"
  6.5144 +    then have "f ` S \<subseteq> {f x}"
  6.5145 +    by (metis connected_continuous_image conf connected_component_maximal fim image_subset_iff rev_image_eqI S cct)
  6.5146 +  }
  6.5147 +  with False show ?thesis
  6.5148 +    by blast
  6.5149 +qed
  6.5150 +
  6.5151 +lemma discrete_subset_disconnected:
  6.5152 +  fixes S :: "'a::topological_space set"
  6.5153 +  fixes t :: "'b::real_normed_vector set"
  6.5154 +  assumes conf: "continuous_on S f"
  6.5155 +      and no: "\<And>x. x \<in> S \<Longrightarrow> \<exists>e>0. \<forall>y. y \<in> S \<and> f y \<noteq> f x \<longrightarrow> e \<le> norm (f y - f x)"
  6.5156 +   shows "f ` S \<subseteq> {y. connected_component_set (f ` S) y = {y}}"
  6.5157 +proof -
  6.5158 +  { fix x assume x: "x \<in> S"
  6.5159 +    then obtain e where "e>0" and ele: "\<And>y. \<lbrakk>y \<in> S; f y \<noteq> f x\<rbrakk> \<Longrightarrow> e \<le> norm (f y - f x)"
  6.5160 +      using conf no [OF x] by auto
  6.5161 +    then have e2: "0 \<le> e / 2"
  6.5162 +      by simp
  6.5163 +    have "f y = f x" if "y \<in> S" and ccs: "f y \<in> connected_component_set (f ` S) (f x)" for y
  6.5164 +      apply (rule ccontr)
  6.5165 +      using connected_closed [of "connected_component_set (f ` S) (f x)"] \<open>e>0\<close>
  6.5166 +      apply (simp add: del: ex_simps)
  6.5167 +      apply (drule spec [where x="cball (f x) (e / 2)"])
  6.5168 +      apply (drule spec [where x="- ball(f x) e"])
  6.5169 +      apply (auto simp: dist_norm open_closed [symmetric] simp del: le_divide_eq_numeral1 dest!: connected_component_in)
  6.5170 +        apply (metis diff_self e2 ele norm_minus_commute norm_zero not_less)
  6.5171 +       using centre_in_cball connected_component_refl_eq e2 x apply blast
  6.5172 +      using ccs
  6.5173 +      apply (force simp: cball_def dist_norm norm_minus_commute dest: ele [OF \<open>y \<in> S\<close>])
  6.5174 +      done
  6.5175 +    moreover have "connected_component_set (f ` S) (f x) \<subseteq> f ` S"
  6.5176 +      by (auto simp: connected_component_in)
  6.5177 +    ultimately have "connected_component_set (f ` S) (f x) = {f x}"
  6.5178 +      by (auto simp: x)
  6.5179 +  }
  6.5180 +  with assms show ?thesis
  6.5181 +    by blast
  6.5182 +qed
  6.5183 +
  6.5184 +lemma finite_implies_discrete:
  6.5185 +  fixes S :: "'a::topological_space set"
  6.5186 +  assumes "finite (f ` S)"
  6.5187 +  shows "(\<forall>x \<in> S. \<exists>e>0. \<forall>y. y \<in> S \<and> f y \<noteq> f x \<longrightarrow> e \<le> norm (f y - f x))"
  6.5188 +proof -
  6.5189 +  have "\<exists>e>0. \<forall>y. y \<in> S \<and> f y \<noteq> f x \<longrightarrow> e \<le> norm (f y - f x)" if "x \<in> S" for x
  6.5190 +  proof (cases "f ` S - {f x} = {}")
  6.5191 +    case True
  6.5192 +    with zero_less_numeral show ?thesis
  6.5193 +      by (fastforce simp add: Set.image_subset_iff cong: conj_cong)
  6.5194 +  next
  6.5195 +    case False
  6.5196 +    then obtain z where z: "z \<in> S" "f z \<noteq> f x"
  6.5197 +      by blast
  6.5198 +    have finn: "finite {norm (z - f x) |z. z \<in> f ` S - {f x}}"
  6.5199 +      using assms by simp
  6.5200 +    then have *: "0 < Inf{norm(z - f x) | z. z \<in> f ` S - {f x}}"
  6.5201 +      apply (rule finite_imp_less_Inf)
  6.5202 +      using z apply force+
  6.5203 +      done
  6.5204 +    show ?thesis
  6.5205 +      by (force intro!: * cInf_le_finite [OF finn])
  6.5206 +  qed
  6.5207 +  with assms show ?thesis
  6.5208 +    by blast
  6.5209 +qed
  6.5210 +
  6.5211 +text\<open>This proof requires the existence of two separate values of the range type.\<close>
  6.5212 +lemma finite_range_constant_imp_connected:
  6.5213 +  assumes "\<And>f::'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1.
  6.5214 +              \<lbrakk>continuous_on S f; finite(f ` S)\<rbrakk> \<Longrightarrow> \<exists>a. \<forall>x \<in> S. f x = a"
  6.5215 +    shows "connected S"
  6.5216 +proof -
  6.5217 +  { fix t u
  6.5218 +    assume clt: "closedin (subtopology euclidean S) t"
  6.5219 +       and clu: "closedin (subtopology euclidean S) u"
  6.5220 +       and tue: "t \<inter> u = {}" and tus: "t \<union> u = S"
  6.5221 +    have conif: "continuous_on S (\<lambda>x. if x \<in> t then 0 else 1)"
  6.5222 +      apply (subst tus [symmetric])
  6.5223 +      apply (rule continuous_on_cases_local)
  6.5224 +      using clt clu tue
  6.5225 +      apply (auto simp: tus continuous_on_const)
  6.5226 +      done
  6.5227 +    have fi: "finite ((\<lambda>x. if x \<in> t then 0 else 1) ` S)"
  6.5228 +      by (rule finite_subset [of _ "{0,1}"]) auto
  6.5229 +    have "t = {} \<or> u = {}"
  6.5230 +      using assms [OF conif fi] tus [symmetric]
  6.5231 +      by (auto simp: Ball_def) (metis IntI empty_iff one_neq_zero tue)
  6.5232 +  }
  6.5233 +  then show ?thesis
  6.5234 +    by (simp add: connected_closedin_eq)
  6.5235 +qed
  6.5236 +
  6.5237 +lemma continuous_disconnected_range_constant_eq:
  6.5238 +      "(connected S \<longleftrightarrow>
  6.5239 +           (\<forall>f::'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1.
  6.5240 +            \<forall>t. continuous_on S f \<and> f ` S \<subseteq> t \<and> (\<forall>y \<in> t. connected_component_set t y = {y})
  6.5241 +            \<longrightarrow> (\<exists>a::'b. \<forall>x \<in> S. f x = a)))" (is ?thesis1)
  6.5242 +  and continuous_discrete_range_constant_eq:
  6.5243 +      "(connected S \<longleftrightarrow>
  6.5244 +         (\<forall>f::'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1.
  6.5245 +          continuous_on S f \<and>
  6.5246 +          (\<forall>x \<in> S. \<exists>e. 0 < e \<and> (\<forall>y. y \<in> S \<and> (f y \<noteq> f x) \<longrightarrow> e \<le> norm(f y - f x)))
  6.5247 +          \<longrightarrow> (\<exists>a::'b. \<forall>x \<in> S. f x = a)))" (is ?thesis2)
  6.5248 +  and continuous_finite_range_constant_eq:
  6.5249 +      "(connected S \<longleftrightarrow>
  6.5250 +         (\<forall>f::'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1.
  6.5251 +          continuous_on S f \<and> finite (f ` S)
  6.5252 +          \<longrightarrow> (\<exists>a::'b. \<forall>x \<in> S. f x = a)))" (is ?thesis3)
  6.5253 +proof -
  6.5254 +  have *: "\<And>s t u v. \<lbrakk>s \<Longrightarrow> t; t \<Longrightarrow> u; u \<Longrightarrow> v; v \<Longrightarrow> s\<rbrakk>
  6.5255 +    \<Longrightarrow> (s \<longleftrightarrow> t) \<and> (s \<longleftrightarrow> u) \<and> (s \<longleftrightarrow> v)"
  6.5256 +    by blast
  6.5257 +  have "?thesis1 \<and> ?thesis2 \<and> ?thesis3"
  6.5258 +    apply (rule *)
  6.5259 +    using continuous_disconnected_range_constant apply metis
  6.5260 +    apply clarify
  6.5261 +    apply (frule discrete_subset_disconnected; blast)
  6.5262 +    apply (blast dest: finite_implies_discrete)
  6.5263 +    apply (blast intro!: finite_range_constant_imp_connected)
  6.5264 +    done
  6.5265 +  then show ?thesis1 ?thesis2 ?thesis3
  6.5266 +    by blast+
  6.5267 +qed
  6.5268 +
  6.5269 +lemma continuous_discrete_range_constant:
  6.5270 +  fixes f :: "'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1"
  6.5271 +  assumes S: "connected S"
  6.5272 +      and "continuous_on S f"
  6.5273 +      and "\<And>x. x \<in> S \<Longrightarrow> \<exists>e>0. \<forall>y. y \<in> S \<and> f y \<noteq> f x \<longrightarrow> e \<le> norm (f y - f x)"
  6.5274 +    obtains a where "\<And>x. x \<in> S \<Longrightarrow> f x = a"
  6.5275 +  using continuous_discrete_range_constant_eq [THEN iffD1, OF S] assms
  6.5276 +  by blast
  6.5277 +
  6.5278 +lemma continuous_finite_range_constant:
  6.5279 +  fixes f :: "'a::topological_space \<Rightarrow> 'b::real_normed_algebra_1"
  6.5280 +  assumes "connected S"
  6.5281 +      and "continuous_on S f"
  6.5282 +      and "finite (f ` S)"
  6.5283 +    obtains a where "\<And>x. x \<in> S \<Longrightarrow> f x = a"
  6.5284 +  using assms continuous_finite_range_constant_eq
  6.5285 +  by blast
  6.5286 +
  6.5287 +
  6.5288 +
  6.5289 +subsection \<open>Continuous Extension\<close>
  6.5290 +
  6.5291 +definition clamp :: "'a::euclidean_space \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a" where
  6.5292 +  "clamp a b x = (if (\<forall>i\<in>Basis. a \<bullet> i \<le> b \<bullet> i)
  6.5293 +    then (\<Sum>i\<in>Basis. (if x\<bullet>i < a\<bullet>i then a\<bullet>i else if x\<bullet>i \<le> b\<bullet>i then x\<bullet>i else b\<bullet>i) *\<^sub>R i)
  6.5294 +    else a)"
  6.5295 +
  6.5296 +lemma clamp_in_interval[simp]:
  6.5297 +  assumes "\<And>i. i \<in> Basis \<Longrightarrow> a \<bullet> i \<le> b \<bullet> i"
  6.5298 +  shows "clamp a b x \<in> cbox a b"
  6.5299 +  unfolding clamp_def
  6.5300 +  using box_ne_empty(1)[of a b] assms by (auto simp: cbox_def)
  6.5301 +
  6.5302 +lemma clamp_cancel_cbox[simp]:
  6.5303 +  fixes x a b :: "'a::euclidean_space"
  6.5304 +  assumes x: "x \<in> cbox a b"
  6.5305 +  shows "clamp a b x = x"
  6.5306 +  using assms
  6.5307 +  by (auto simp: clamp_def mem_box intro!: euclidean_eqI[where 'a='a])
  6.5308 +
  6.5309 +lemma clamp_empty_interval:
  6.5310 +  assumes "i \<in> Basis" "a \<bullet> i > b \<bullet> i"
  6.5311 +  shows "clamp a b = (\<lambda>_. a)"
  6.5312 +  using assms
  6.5313 +  by (force simp: clamp_def[abs_def] split: if_splits intro!: ext)
  6.5314 +
  6.5315 +lemma dist_clamps_le_dist_args:
  6.5316 +  fixes x :: "'a::euclidean_space"
  6.5317 +  shows "dist (clamp a b y) (clamp a b x) \<le> dist y x"
  6.5318 +proof cases
  6.5319 +  assume le: "(\<forall>i\<in>Basis. a \<bullet> i \<le> b \<bullet> i)"
  6.5320 +  then have "(\<Sum>i\<in>Basis. (dist (clamp a b y \<bullet> i) (clamp a b x \<bullet> i))\<^sup>2) \<le>
  6.5321 +    (\<Sum>i\<in>Basis. (dist (y \<bullet> i) (x \<bullet> i))\<^sup>2)"
  6.5322 +    by (auto intro!: sum_mono simp: clamp_def dist_real_def abs_le_square_iff[symmetric])
  6.5323 +  then show ?thesis
  6.5324 +    by (auto intro: real_sqrt_le_mono
  6.5325 +      simp: euclidean_dist_l2[where y=x] euclidean_dist_l2[where y="clamp a b x"] setL2_def)
  6.5326 +qed (auto simp: clamp_def)
  6.5327 +
  6.5328 +lemma clamp_continuous_at:
  6.5329 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::metric_space"
  6.5330 +    and x :: 'a
  6.5331 +  assumes f_cont: "continuous_on (cbox a b) f"
  6.5332 +  shows "continuous (at x) (\<lambda>x. f (clamp a b x))"
  6.5333 +proof cases
  6.5334 +  assume le: "(\<forall>i\<in>Basis. a \<bullet> i \<le> b \<bullet> i)"
  6.5335 +  show ?thesis
  6.5336 +    unfolding continuous_at_eps_delta
  6.5337 +  proof safe
  6.5338 +    fix x :: 'a
  6.5339 +    fix e :: real
  6.5340 +    assume "e > 0"
  6.5341 +    moreover have "clamp a b x \<in> cbox a b"
  6.5342 +      by (simp add: clamp_in_interval le)
  6.5343 +    moreover note f_cont[simplified continuous_on_iff]
  6.5344 +    ultimately
  6.5345 +    obtain d where d: "0 < d"
  6.5346 +      "\<And>x'. x' \<in> cbox a b \<Longrightarrow> dist x' (clamp a b x) < d \<Longrightarrow> dist (f x') (f (clamp a b x)) < e"
  6.5347 +      by force
  6.5348 +    show "\<exists>d>0. \<forall>x'. dist x' x < d \<longrightarrow>
  6.5349 +      dist (f (clamp a b x')) (f (clamp a b x)) < e"
  6.5350 +      using le
  6.5351 +      by (auto intro!: d clamp_in_interval dist_clamps_le_dist_args[THEN le_less_trans])
  6.5352 +  qed
  6.5353 +qed (auto simp: clamp_empty_interval)
  6.5354 +
  6.5355 +lemma clamp_continuous_on:
  6.5356 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::metric_space"
  6.5357 +  assumes f_cont: "continuous_on (cbox a b) f"
  6.5358 +  shows "continuous_on S (\<lambda>x. f (clamp a b x))"
  6.5359 +  using assms
  6.5360 +  by (auto intro: continuous_at_imp_continuous_on clamp_continuous_at)
  6.5361 +
  6.5362 +lemma clamp_bounded:
  6.5363 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::metric_space"
  6.5364 +  assumes bounded: "bounded (f ` (cbox a b))"
  6.5365 +  shows "bounded (range (\<lambda>x. f (clamp a b x)))"
  6.5366 +proof cases
  6.5367 +  assume le: "(\<forall>i\<in>Basis. a \<bullet> i \<le> b \<bullet> i)"
  6.5368 +  from bounded obtain c where f_bound: "\<forall>x\<in>f ` cbox a b. dist undefined x \<le> c"
  6.5369 +    by (auto simp: bounded_any_center[where a=undefined])
  6.5370 +  then show ?thesis
  6.5371 +    by (auto intro!: exI[where x=c] clamp_in_interval[OF le[rule_format]]
  6.5372 +        simp: bounded_any_center[where a=undefined])
  6.5373 +qed (auto simp: clamp_empty_interval image_def)
  6.5374 +
  6.5375 +
  6.5376 +definition ext_cont :: "('a::euclidean_space \<Rightarrow> 'b::metric_space) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'b"
  6.5377 +  where "ext_cont f a b = (\<lambda>x. f (clamp a b x))"
  6.5378 +
  6.5379 +lemma ext_cont_cancel_cbox[simp]:
  6.5380 +  fixes x a b :: "'a::euclidean_space"
  6.5381 +  assumes x: "x \<in> cbox a b"
  6.5382 +  shows "ext_cont f a b x = f x"
  6.5383 +  using assms
  6.5384 +  unfolding ext_cont_def
  6.5385 +  by (auto simp: clamp_def mem_box intro!: euclidean_eqI[where 'a='a] arg_cong[where f=f])
  6.5386 +
  6.5387 +lemma continuous_on_ext_cont[continuous_intros]:
  6.5388 +  "continuous_on (cbox a b) f \<Longrightarrow> continuous_on S (ext_cont f a b)"
  6.5389 +  by (auto intro!: clamp_continuous_on simp: ext_cont_def)
  6.5390 +
  6.5391 +end
     7.1 --- a/src/HOL/Analysis/Convex_Euclidean_Space.thy	Tue Oct 10 14:03:51 2017 +0100
     7.2 +++ b/src/HOL/Analysis/Convex_Euclidean_Space.thy	Tue Oct 10 17:15:37 2017 +0100
     7.3 @@ -10,7 +10,7 @@
     7.4  
     7.5  theory Convex_Euclidean_Space
     7.6  imports
     7.7 -  Topology_Euclidean_Space
     7.8 +  Connected
     7.9    "HOL-Library.Set_Algebras"
    7.10  begin
    7.11  
    7.12 @@ -6717,7 +6717,7 @@
    7.13      done
    7.14    then show ?thesis
    7.15      using connected_ivt_component[of "f ` cbox a b" "f a" "f b" k y]
    7.16 -    by (simp add: Topology_Euclidean_Space.connected_continuous_image assms)
    7.17 +    by (simp add: connected_continuous_image assms)
    7.18  qed
    7.19  
    7.20  lemma ivt_increasing_component_1:
     8.1 --- a/src/HOL/Analysis/Function_Topology.thy	Tue Oct 10 14:03:51 2017 +0100
     8.2 +++ b/src/HOL/Analysis/Function_Topology.thy	Tue Oct 10 17:15:37 2017 +0100
     8.3 @@ -24,7 +24,7 @@
     8.4  This means that type classes can not be used to define such a product if one wants to take the
     8.5  product of different topological spaces (as the type 'a can only be given one structure of
     8.6  topological space using type classes). On the other hand, one can define different topologies (as
     8.7 -introduced in \verb+Topology_Euclidean_Space.thy+) on one type, and these topologies do not need to
     8.8 +introduced in \verb+thy+) on one type, and these topologies do not need to
     8.9  share the same maximal open set. Hence, one can form a product of topologies in this sense, and
    8.10  this works well. The big caveat is that it does not interact well with the main body of
    8.11  topology in Isabelle/HOL defined in terms of type classes... For instance, continuity of maps
     9.1 --- a/src/HOL/Analysis/Further_Topology.thy	Tue Oct 10 14:03:51 2017 +0100
     9.2 +++ b/src/HOL/Analysis/Further_Topology.thy	Tue Oct 10 17:15:37 2017 +0100
     9.3 @@ -1183,7 +1183,7 @@
     9.4                   and hin: "\<And>x. x \<in> C \<inter> K \<Longrightarrow> h x \<in> ball a d \<inter> U"
     9.5      proof (rule homeomorphism_grouping_points_exists_gen [of C "ball a d \<inter> U" "C \<inter> K" "S \<union> C"])
     9.6        show "openin (subtopology euclidean C) (ball a d \<inter> U)"
     9.7 -        by (metis Topology_Euclidean_Space.open_ball \<open>C \<subseteq> U\<close> \<open>ball a d \<inter> U \<subseteq> C\<close> inf.absorb_iff2 inf.orderE inf_assoc open_openin openin_subtopology)
     9.8 +        by (metis open_ball \<open>C \<subseteq> U\<close> \<open>ball a d \<inter> U \<subseteq> C\<close> inf.absorb_iff2 inf.orderE inf_assoc open_openin openin_subtopology)
     9.9        show "openin (subtopology euclidean (affine hull C)) C"
    9.10          by (metis \<open>a \<in> C\<close> \<open>openin (subtopology euclidean U) C\<close> affine_hull_eq affine_hull_openin all_not_in_conv \<open>affine U\<close>)
    9.11        show "ball a d \<inter> U \<noteq> {}"
    10.1 --- a/src/HOL/Analysis/Great_Picard.thy	Tue Oct 10 14:03:51 2017 +0100
    10.2 +++ b/src/HOL/Analysis/Great_Picard.thy	Tue Oct 10 17:15:37 2017 +0100
    10.3 @@ -341,7 +341,7 @@
    10.4        with w have der_gw: "(g has_field_derivative deriv g w) (at w)"
    10.5          by (simp add: field_differentiable_within_open [of _ "ball 0 1"] field_differentiable_derivI)
    10.6        with DERIV_unique [OF der_gw] g' w have "deriv g w = g' w"
    10.7 -        by (metis Topology_Euclidean_Space.open_ball at_within_open ball_subset_cball has_field_derivative_subset subsetCE)
    10.8 +        by (metis open_ball at_within_open ball_subset_cball has_field_derivative_subset subsetCE)
    10.9        then show "cmod (g' w) \<le> 12 / (1 - t)"
   10.10          using g' 12 \<open>t < 1\<close> by (simp add: field_simps)
   10.11      qed
   10.12 @@ -1350,7 +1350,7 @@
   10.13          have lt_Fj: "real x \<le> cmod (\<F> (j x) v)" for x
   10.14            by (metis of_nat_Suc ltF \<open>strict_mono j\<close> add.commute less_eq_real_def less_le_trans nat_le_real_less seq_suble)
   10.15          show "(\<lambda>n. \<G> (j n) v) \<longlonglongrightarrow> 0"
   10.16 -        proof (rule Lim_null_comparison [OF eventually_sequentiallyI seq_harmonic])
   10.17 +        proof (rule Lim_null_comparison [OF eventually_sequentiallyI lim_inverse_n])
   10.18            show "cmod (\<G> (j x) v) \<le> inverse (real x)" if "1 \<le> x" for x
   10.19              using that by (simp add: \<G>_def norm_inverse_le_norm [OF lt_Fj])
   10.20          qed        
    11.1 --- a/src/HOL/Analysis/Homeomorphism.thy	Tue Oct 10 14:03:51 2017 +0100
    11.2 +++ b/src/HOL/Analysis/Homeomorphism.thy	Tue Oct 10 17:15:37 2017 +0100
    11.3 @@ -1084,7 +1084,7 @@
    11.4      have cloS: "closedin (subtopology euclidean U) S"
    11.5        by (metis US closed_closure closedin_closed_Int)
    11.6      have cont: "isCont ((\<lambda>x. setdist {x} (- U)) o fst) z" for z :: "'a \<times> 'b"
    11.7 -      by (rule isCont_o continuous_intros continuous_at_setdist)+
    11.8 +      by (rule continuous_at_compose continuous_intros continuous_at_setdist)+
    11.9      have setdist1D: "setdist {a} (- U) *\<^sub>R b = One \<Longrightarrow> setdist {a} (- U) \<noteq> 0" for a::'a and b::'b
   11.10        by force
   11.11      have *: "r *\<^sub>R b = One \<Longrightarrow> b = (1 / r) *\<^sub>R One" for r and b::'b
    12.1 --- a/src/HOL/Analysis/Ordered_Euclidean_Space.thy	Tue Oct 10 14:03:51 2017 +0100
    12.2 +++ b/src/HOL/Analysis/Ordered_Euclidean_Space.thy	Tue Oct 10 17:15:37 2017 +0100
    12.3 @@ -190,12 +190,12 @@
    12.4  lemma closed_eucl_atMost[simp, intro]:
    12.5    fixes a :: "'a::ordered_euclidean_space"
    12.6    shows "closed {..a}"
    12.7 -  by (simp add: eucl_le_atMost[symmetric])
    12.8 +  by (simp add: closed_interval_left eucl_le_atMost[symmetric])
    12.9  
   12.10  lemma closed_eucl_atLeast[simp, intro]:
   12.11    fixes a :: "'a::ordered_euclidean_space"
   12.12    shows "closed {a..}"
   12.13 -  by (simp add: eucl_le_atLeast[symmetric])
   12.14 +  by (simp add: closed_interval_right eucl_le_atLeast[symmetric])
   12.15  
   12.16  lemma bounded_closed_interval [simp]:
   12.17    fixes a :: "'a::ordered_euclidean_space"
    13.1 --- a/src/HOL/Analysis/Path_Connected.thy	Tue Oct 10 14:03:51 2017 +0100
    13.2 +++ b/src/HOL/Analysis/Path_Connected.thy	Tue Oct 10 17:15:37 2017 +0100
    13.3 @@ -5987,7 +5987,7 @@
    13.4    shows "open S \<Longrightarrow> locally path_connected S"
    13.5  apply (rule locally_mono [of convex])
    13.6  apply (simp_all add: locally_def openin_open_eq convex_imp_path_connected)
    13.7 -apply (meson Topology_Euclidean_Space.open_ball centre_in_ball convex_ball openE order_trans)
    13.8 +apply (meson open_ball centre_in_ball convex_ball openE order_trans)
    13.9  done
   13.10  
   13.11  lemma open_imp_locally_connected:
   13.12 @@ -6029,7 +6029,7 @@
   13.13  apply (clarsimp simp add: locally_path_connected)
   13.14  apply (subst (asm) openin_open)
   13.15  apply clarify
   13.16 -apply (erule (1) Topology_Euclidean_Space.openE)
   13.17 +apply (erule (1) openE)
   13.18  apply (rule_tac x = "S \<inter> ball x e" in exI)
   13.19  apply (force simp: convex_Int convex_imp_path_connected)
   13.20  done
   13.21 @@ -6281,7 +6281,7 @@
   13.22    have "S \<subseteq> u"
   13.23      using S closedin_imp_subset by blast
   13.24    moreover have "u - S = \<Union>c \<union> \<Union>(components (u - S) - c)"
   13.25 -    by (metis Diff_partition Topology_Euclidean_Space.Union_components Union_Un_distrib assms(3))
   13.26 +    by (metis Diff_partition Union_components Union_Un_distrib assms(3))
   13.27    moreover have "disjnt (\<Union>c) (\<Union>(components (u - S) - c))"
   13.28      apply (rule di)
   13.29      by (metis DiffD1 DiffD2 assms(3) components_nonoverlap disjnt_def subsetCE)
   13.30 @@ -7407,7 +7407,7 @@
   13.31          using \<open>\<not> collinear S\<close> collinear_aff_dim by auto
   13.32        then have "\<not> collinear (ball x r \<inter> affine hull S)"
   13.33          apply (simp add: collinear_aff_dim)
   13.34 -        by (metis (no_types, hide_lams) aff_dim_convex_Int_open IntI Topology_Euclidean_Space.open_ball \<open>0 < r\<close> aff_dim_affine_hull affine_affine_hull affine_imp_convex centre_in_ball empty_iff hull_subset inf_commute subsetCE that)
   13.35 +        by (metis (no_types, hide_lams) aff_dim_convex_Int_open IntI open_ball \<open>0 < r\<close> aff_dim_affine_hull affine_affine_hull affine_imp_convex centre_in_ball empty_iff hull_subset inf_commute subsetCE that)
   13.36        then have *: "path_connected ((ball x r \<inter> affine hull S) - T)"
   13.37          by (rule path_connected_convex_diff_countable [OF conv _ \<open>countable T\<close>])
   13.38        have ST: "ball x r \<inter> affine hull S - T \<subseteq> S - T"
    14.1 --- a/src/HOL/Analysis/Riemann_Mapping.thy	Tue Oct 10 14:03:51 2017 +0100
    14.2 +++ b/src/HOL/Analysis/Riemann_Mapping.thy	Tue Oct 10 17:15:37 2017 +0100
    14.3 @@ -1435,7 +1435,7 @@
    14.4        then have "S = g ` (ball 0 1)"
    14.5          by (force simp:)
    14.6        then have "open S"
    14.7 -        by (metis Topology_Euclidean_Space.open_ball g inj_on_def open_mapping_thm3)
    14.8 +        by (metis open_ball g inj_on_def open_mapping_thm3)
    14.9      }
   14.10      with that show "open S" by auto
   14.11    qed
    15.1 --- a/src/HOL/Analysis/Tagged_Division.thy	Tue Oct 10 14:03:51 2017 +0100
    15.2 +++ b/src/HOL/Analysis/Tagged_Division.thy	Tue Oct 10 17:15:37 2017 +0100
    15.3 @@ -6,8 +6,7 @@
    15.4  section \<open>Tagged divisions used for the Henstock-Kurzweil gauge integration\<close>
    15.5  
    15.6  theory Tagged_Division
    15.7 -imports
    15.8 -  Topology_Euclidean_Space
    15.9 +  imports Connected
   15.10  begin
   15.11  
   15.12  term comm_monoid
    16.1 --- a/src/HOL/Analysis/Topology_Euclidean_Space.thy	Tue Oct 10 14:03:51 2017 +0100
    16.2 +++ b/src/HOL/Analysis/Topology_Euclidean_Space.thy	Tue Oct 10 17:15:37 2017 +0100
    16.3 @@ -7,7 +7,7 @@
    16.4  section \<open>Elementary topology in Euclidean space.\<close>
    16.5  
    16.6  theory Topology_Euclidean_Space
    16.7 -imports
    16.8 +imports                                                         
    16.9    "HOL-Library.Indicator_Function"
   16.10    "HOL-Library.Countable_Set"
   16.11    "HOL-Library.FuncSet"
   16.12 @@ -1208,6 +1208,38 @@
   16.13  
   16.14  lemma ball_empty: "e \<le> 0 \<Longrightarrow> ball x e = {}" by simp
   16.15  
   16.16 +lemma closed_cball [iff]: "closed (cball x e)"
   16.17 +proof -
   16.18 +  have "closed (dist x -` {..e})"
   16.19 +    by (intro closed_vimage closed_atMost continuous_intros)
   16.20 +  also have "dist x -` {..e} = cball x e"
   16.21 +    by auto
   16.22 +  finally show ?thesis .
   16.23 +qed
   16.24 +
   16.25 +lemma open_contains_cball: "open S \<longleftrightarrow> (\<forall>x\<in>S. \<exists>e>0.  cball x e \<subseteq> S)"
   16.26 +proof -
   16.27 +  {
   16.28 +    fix x and e::real
   16.29 +    assume "x\<in>S" "e>0" "ball x e \<subseteq> S"
   16.30 +    then have "\<exists>d>0. cball x d \<subseteq> S" unfolding subset_eq by (rule_tac x="e/2" in exI, auto)
   16.31 +  }
   16.32 +  moreover
   16.33 +  {
   16.34 +    fix x and e::real
   16.35 +    assume "x\<in>S" "e>0" "cball x e \<subseteq> S"
   16.36 +    then have "\<exists>d>0. ball x d \<subseteq> S"
   16.37 +      unfolding subset_eq
   16.38 +      apply (rule_tac x="e/2" in exI, auto)
   16.39 +      done
   16.40 +  }
   16.41 +  ultimately show ?thesis
   16.42 +    unfolding open_contains_ball by auto
   16.43 +qed
   16.44 +
   16.45 +lemma open_contains_cball_eq: "open S \<Longrightarrow> (\<forall>x. x \<in> S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S))"
   16.46 +  by (metis open_contains_cball subset_eq order_less_imp_le centre_in_cball)
   16.47 +
   16.48  lemma euclidean_dist_l2:
   16.49    fixes x y :: "'a :: euclidean_space"
   16.50    shows "dist x y = setL2 (\<lambda>i. dist (x \<bullet> i) (y \<bullet> i)) Basis"
   16.51 @@ -1223,7 +1255,6 @@
   16.52  lemma eventually_at_ball': "d > 0 \<Longrightarrow> eventually (\<lambda>t. t \<in> ball z d \<and> t \<noteq> z \<and> t \<in> A) (at z within A)"
   16.53    unfolding eventually_at by (intro exI[of _ d]) (simp_all add: dist_commute)
   16.54  
   16.55 -
   16.56  subsection \<open>Boxes\<close>
   16.57  
   16.58  abbreviation One :: "'a::euclidean_space"
   16.59 @@ -1879,64 +1910,6 @@
   16.60  qed
   16.61  
   16.62  
   16.63 -subsection \<open>Connectedness\<close>
   16.64 -
   16.65 -lemma connected_local:
   16.66 - "connected S \<longleftrightarrow>
   16.67 -  \<not> (\<exists>e1 e2.
   16.68 -      openin (subtopology euclidean S) e1 \<and>
   16.69 -      openin (subtopology euclidean S) e2 \<and>
   16.70 -      S \<subseteq> e1 \<union> e2 \<and>
   16.71 -      e1 \<inter> e2 = {} \<and>
   16.72 -      e1 \<noteq> {} \<and>
   16.73 -      e2 \<noteq> {})"
   16.74 -  unfolding connected_def openin_open
   16.75 -  by safe blast+
   16.76 -
   16.77 -lemma exists_diff:
   16.78 -  fixes P :: "'a set \<Rightarrow> bool"
   16.79 -  shows "(\<exists>S. P (- S)) \<longleftrightarrow> (\<exists>S. P S)"
   16.80 -    (is "?lhs \<longleftrightarrow> ?rhs")
   16.81 -proof -
   16.82 -  have ?rhs if ?lhs
   16.83 -    using that by blast
   16.84 -  moreover have "P (- (- S))" if "P S" for S
   16.85 -  proof -
   16.86 -    have "S = - (- S)" by simp
   16.87 -    with that show ?thesis by metis
   16.88 -  qed
   16.89 -  ultimately show ?thesis by metis
   16.90 -qed
   16.91 -
   16.92 -lemma connected_clopen: "connected S \<longleftrightarrow>
   16.93 -  (\<forall>T. openin (subtopology euclidean S) T \<and>
   16.94 -     closedin (subtopology euclidean S) T \<longrightarrow> T = {} \<or> T = S)" (is "?lhs \<longleftrightarrow> ?rhs")
   16.95 -proof -
   16.96 -  have "\<not> connected S \<longleftrightarrow>
   16.97 -    (\<exists>e1 e2. open e1 \<and> open (- e2) \<and> S \<subseteq> e1 \<union> (- e2) \<and> e1 \<inter> (- e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (- e2) \<inter> S \<noteq> {})"
   16.98 -    unfolding connected_def openin_open closedin_closed
   16.99 -    by (metis double_complement)
  16.100 -  then have th0: "connected S \<longleftrightarrow>
  16.101 -    \<not> (\<exists>e2 e1. closed e2 \<and> open e1 \<and> S \<subseteq> e1 \<union> (- e2) \<and> e1 \<inter> (- e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (- e2) \<inter> S \<noteq> {})"
  16.102 -    (is " _ \<longleftrightarrow> \<not> (\<exists>e2 e1. ?P e2 e1)")
  16.103 -    by (simp add: closed_def) metis
  16.104 -  have th1: "?rhs \<longleftrightarrow> \<not> (\<exists>t' t. closed t'\<and>t = S\<inter>t' \<and> t\<noteq>{} \<and> t\<noteq>S \<and> (\<exists>t'. open t' \<and> t = S \<inter> t'))"
  16.105 -    (is "_ \<longleftrightarrow> \<not> (\<exists>t' t. ?Q t' t)")
  16.106 -    unfolding connected_def openin_open closedin_closed by auto
  16.107 -  have "(\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)" for e2
  16.108 -  proof -
  16.109 -    have "?P e2 e1 \<longleftrightarrow> (\<exists>t. closed e2 \<and> t = S\<inter>e2 \<and> open e1 \<and> t = S\<inter>e1 \<and> t\<noteq>{} \<and> t \<noteq> S)" for e1
  16.110 -      by auto
  16.111 -    then show ?thesis
  16.112 -      by metis
  16.113 -  qed
  16.114 -  then have "\<forall>e2. (\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)"
  16.115 -    by blast
  16.116 -  then show ?thesis
  16.117 -    by (simp add: th0 th1)
  16.118 -qed
  16.119 -
  16.120 -
  16.121  subsection \<open>Limit points\<close>
  16.122  
  16.123  definition (in topological_space) islimpt:: "'a \<Rightarrow> 'a set \<Rightarrow> bool"  (infixr "islimpt" 60)
  16.124 @@ -2511,411 +2484,6 @@
  16.125  qed
  16.126  
  16.127  
  16.128 -subsection \<open>Connected components, considered as a connectedness relation or a set\<close>
  16.129 -
  16.130 -definition "connected_component s x y \<equiv> \<exists>t. connected t \<and> t \<subseteq> s \<and> x \<in> t \<and> y \<in> t"
  16.131 -
  16.132 -abbreviation "connected_component_set s x \<equiv> Collect (connected_component s x)"
  16.133 -
  16.134 -lemma connected_componentI:
  16.135 -  "connected t \<Longrightarrow> t \<subseteq> s \<Longrightarrow> x \<in> t \<Longrightarrow> y \<in> t \<Longrightarrow> connected_component s x y"
  16.136 -  by (auto simp: connected_component_def)
  16.137 -
  16.138 -lemma connected_component_in: "connected_component s x y \<Longrightarrow> x \<in> s \<and> y \<in> s"
  16.139 -  by (auto simp: connected_component_def)
  16.140 -
  16.141 -lemma connected_component_refl: "x \<in> s \<Longrightarrow> connected_component s x x"
  16.142 -  by (auto simp: connected_component_def) (use connected_sing in blast)
  16.143 -
  16.144 -lemma connected_component_refl_eq [simp]: "connected_component s x x \<longleftrightarrow> x \<in> s"
  16.145 -  by (auto simp: connected_component_refl) (auto simp: connected_component_def)
  16.146 -
  16.147 -lemma connected_component_sym: "connected_component s x y \<Longrightarrow> connected_component s y x"
  16.148 -  by (auto simp: connected_component_def)
  16.149 -
  16.150 -lemma connected_component_trans:
  16.151 -  "connected_component s x y \<Longrightarrow> connected_component s y z \<Longrightarrow> connected_component s x z"
  16.152 -  unfolding connected_component_def
  16.153 -  by (metis Int_iff Un_iff Un_subset_iff equals0D connected_Un)
  16.154 -
  16.155 -lemma connected_component_of_subset:
  16.156 -  "connected_component s x y \<Longrightarrow> s \<subseteq> t \<Longrightarrow> connected_component t x y"
  16.157 -  by (auto simp: connected_component_def)
  16.158 -
  16.159 -lemma connected_component_Union: "connected_component_set s x = \<Union>{t. connected t \<and> x \<in> t \<and> t \<subseteq> s}"
  16.160 -  by (auto simp: connected_component_def)
  16.161 -
  16.162 -lemma connected_connected_component [iff]: "connected (connected_component_set s x)"
  16.163 -  by (auto simp: connected_component_Union intro: connected_Union)
  16.164 -
  16.165 -lemma connected_iff_eq_connected_component_set:
  16.166 -  "connected s \<longleftrightarrow> (\<forall>x \<in> s. connected_component_set s x = s)"
  16.167 -proof (cases "s = {}")
  16.168 -  case True
  16.169 -  then show ?thesis by simp
  16.170 -next
  16.171 -  case False
  16.172 -  then obtain x where "x \<in> s" by auto
  16.173 -  show ?thesis
  16.174 -  proof
  16.175 -    assume "connected s"
  16.176 -    then show "\<forall>x \<in> s. connected_component_set s x = s"
  16.177 -      by (force simp: connected_component_def)
  16.178 -  next
  16.179 -    assume "\<forall>x \<in> s. connected_component_set s x = s"
  16.180 -    then show "connected s"
  16.181 -      by (metis \<open>x \<in> s\<close> connected_connected_component)
  16.182 -  qed
  16.183 -qed
  16.184 -
  16.185 -lemma connected_component_subset: "connected_component_set s x \<subseteq> s"
  16.186 -  using connected_component_in by blast
  16.187 -
  16.188 -lemma connected_component_eq_self: "connected s \<Longrightarrow> x \<in> s \<Longrightarrow> connected_component_set s x = s"
  16.189 -  by (simp add: connected_iff_eq_connected_component_set)
  16.190 -
  16.191 -lemma connected_iff_connected_component:
  16.192 -  "connected s \<longleftrightarrow> (\<forall>x \<in> s. \<forall>y \<in> s. connected_component s x y)"
  16.193 -  using connected_component_in by (auto simp: connected_iff_eq_connected_component_set)
  16.194 -
  16.195 -lemma connected_component_maximal:
  16.196 -  "x \<in> t \<Longrightarrow> connected t \<Longrightarrow> t \<subseteq> s \<Longrightarrow> t \<subseteq> (connected_component_set s x)"
  16.197 -  using connected_component_eq_self connected_component_of_subset by blast
  16.198 -
  16.199 -lemma connected_component_mono:
  16.200 -  "s \<subseteq> t \<Longrightarrow> connected_component_set s x \<subseteq> connected_component_set t x"
  16.201 -  by (simp add: Collect_mono connected_component_of_subset)
  16.202 -
  16.203 -lemma connected_component_eq_empty [simp]: "connected_component_set s x = {} \<longleftrightarrow> x \<notin> s"
  16.204 -  using connected_component_refl by (fastforce simp: connected_component_in)
  16.205 -
  16.206 -lemma connected_component_set_empty [simp]: "connected_component_set {} x = {}"
  16.207 -  using connected_component_eq_empty by blast
  16.208 -
  16.209 -lemma connected_component_eq:
  16.210 -  "y \<in> connected_component_set s x \<Longrightarrow> (connected_component_set s y = connected_component_set s x)"
  16.211 -  by (metis (no_types, lifting)
  16.212 -      Collect_cong connected_component_sym connected_component_trans mem_Collect_eq)
  16.213 -
  16.214 -lemma closed_connected_component:
  16.215 -  assumes s: "closed s"
  16.216 -  shows "closed (connected_component_set s x)"
  16.217 -proof (cases "x \<in> s")
  16.218 -  case False
  16.219 -  then show ?thesis
  16.220 -    by (metis connected_component_eq_empty closed_empty)
  16.221 -next
  16.222 -  case True
  16.223 -  show ?thesis
  16.224 -    unfolding closure_eq [symmetric]
  16.225 -  proof
  16.226 -    show "closure (connected_component_set s x) \<subseteq> connected_component_set s x"
  16.227 -      apply (rule connected_component_maximal)
  16.228 -        apply (simp add: closure_def True)
  16.229 -       apply (simp add: connected_imp_connected_closure)
  16.230 -      apply (simp add: s closure_minimal connected_component_subset)
  16.231 -      done
  16.232 -  next
  16.233 -    show "connected_component_set s x \<subseteq> closure (connected_component_set s x)"
  16.234 -      by (simp add: closure_subset)
  16.235 -  qed
  16.236 -qed
  16.237 -
  16.238 -lemma connected_component_disjoint:
  16.239 -  "connected_component_set s a \<inter> connected_component_set s b = {} \<longleftrightarrow>
  16.240 -    a \<notin> connected_component_set s b"
  16.241 -  apply (auto simp: connected_component_eq)
  16.242 -  using connected_component_eq connected_component_sym
  16.243 -  apply blast
  16.244 -  done
  16.245 -
  16.246 -lemma connected_component_nonoverlap:
  16.247 -  "connected_component_set s a \<inter> connected_component_set s b = {} \<longleftrightarrow>
  16.248 -    a \<notin> s \<or> b \<notin> s \<or> connected_component_set s a \<noteq> connected_component_set s b"
  16.249 -  apply (auto simp: connected_component_in)
  16.250 -  using connected_component_refl_eq
  16.251 -    apply blast
  16.252 -   apply (metis connected_component_eq mem_Collect_eq)
  16.253 -  apply (metis connected_component_eq mem_Collect_eq)
  16.254 -  done
  16.255 -
  16.256 -lemma connected_component_overlap:
  16.257 -  "connected_component_set s a \<inter> connected_component_set s b \<noteq> {} \<longleftrightarrow>
  16.258 -    a \<in> s \<and> b \<in> s \<and> connected_component_set s a = connected_component_set s b"
  16.259 -  by (auto simp: connected_component_nonoverlap)
  16.260 -
  16.261 -lemma connected_component_sym_eq: "connected_component s x y \<longleftrightarrow> connected_component s y x"
  16.262 -  using connected_component_sym by blast
  16.263 -
  16.264 -lemma connected_component_eq_eq:
  16.265 -  "connected_component_set s x = connected_component_set s y \<longleftrightarrow>
  16.266 -    x \<notin> s \<and> y \<notin> s \<or> x \<in> s \<and> y \<in> s \<and> connected_component s x y"
  16.267 -  apply (cases "y \<in> s", simp)
  16.268 -   apply (metis connected_component_eq connected_component_eq_empty connected_component_refl_eq mem_Collect_eq)
  16.269 -  apply (cases "x \<in> s", simp)
  16.270 -   apply (metis connected_component_eq_empty)
  16.271 -  using connected_component_eq_empty
  16.272 -  apply blast
  16.273 -  done
  16.274 -
  16.275 -lemma connected_iff_connected_component_eq:
  16.276 -  "connected s \<longleftrightarrow> (\<forall>x \<in> s. \<forall>y \<in> s. connected_component_set s x = connected_component_set s y)"
  16.277 -  by (simp add: connected_component_eq_eq connected_iff_connected_component)
  16.278 -
  16.279 -lemma connected_component_idemp:
  16.280 -  "connected_component_set (connected_component_set s x) x = connected_component_set s x"
  16.281 -  apply (rule subset_antisym)
  16.282 -   apply (simp add: connected_component_subset)
  16.283 -  apply (metis connected_component_eq_empty connected_component_maximal
  16.284 -      connected_component_refl_eq connected_connected_component mem_Collect_eq set_eq_subset)
  16.285 -  done
  16.286 -
  16.287 -lemma connected_component_unique:
  16.288 -  "\<lbrakk>x \<in> c; c \<subseteq> s; connected c;
  16.289 -    \<And>c'. x \<in> c' \<and> c' \<subseteq> s \<and> connected c'
  16.290 -              \<Longrightarrow> c' \<subseteq> c\<rbrakk>
  16.291 -        \<Longrightarrow> connected_component_set s x = c"
  16.292 -apply (rule subset_antisym)
  16.293 -apply (meson connected_component_maximal connected_component_subset connected_connected_component contra_subsetD)
  16.294 -by (simp add: connected_component_maximal)
  16.295 -
  16.296 -lemma joinable_connected_component_eq:
  16.297 -  "\<lbrakk>connected t; t \<subseteq> s;
  16.298 -    connected_component_set s x \<inter> t \<noteq> {};
  16.299 -    connected_component_set s y \<inter> t \<noteq> {}\<rbrakk>
  16.300 -    \<Longrightarrow> connected_component_set s x = connected_component_set s y"
  16.301 -apply (simp add: ex_in_conv [symmetric])
  16.302 -apply (rule connected_component_eq)
  16.303 -by (metis (no_types, hide_lams) connected_component_eq_eq connected_component_in connected_component_maximal subsetD mem_Collect_eq)
  16.304 -
  16.305 -
  16.306 -lemma Union_connected_component: "\<Union>(connected_component_set s ` s) = s"
  16.307 -  apply (rule subset_antisym)
  16.308 -  apply (simp add: SUP_least connected_component_subset)
  16.309 -  using connected_component_refl_eq
  16.310 -  by force
  16.311 -
  16.312 -
  16.313 -lemma complement_connected_component_unions:
  16.314 -    "s - connected_component_set s x =
  16.315 -     \<Union>(connected_component_set s ` s - {connected_component_set s x})"
  16.316 -  apply (subst Union_connected_component [symmetric], auto)
  16.317 -  apply (metis connected_component_eq_eq connected_component_in)
  16.318 -  by (metis connected_component_eq mem_Collect_eq)
  16.319 -
  16.320 -lemma connected_component_intermediate_subset:
  16.321 -        "\<lbrakk>connected_component_set u a \<subseteq> t; t \<subseteq> u\<rbrakk>
  16.322 -        \<Longrightarrow> connected_component_set t a = connected_component_set u a"
  16.323 -  apply (case_tac "a \<in> u")
  16.324 -  apply (simp add: connected_component_maximal connected_component_mono subset_antisym)
  16.325 -  using connected_component_eq_empty by blast
  16.326 -
  16.327 -proposition connected_Times:
  16.328 -  assumes S: "connected S" and T: "connected T"
  16.329 -  shows "connected (S \<times> T)"
  16.330 -proof (clarsimp simp add: connected_iff_connected_component)
  16.331 -  fix x y x' y'
  16.332 -  assume xy: "x \<in> S" "y \<in> T" "x' \<in> S" "y' \<in> T"
  16.333 -  with xy obtain U V where U: "connected U" "U \<subseteq> S" "x \<in> U" "x' \<in> U"
  16.334 -                       and V: "connected V" "V \<subseteq> T" "y \<in> V" "y' \<in> V"
  16.335 -    using S T \<open>x \<in> S\<close> \<open>x' \<in> S\<close> by blast+
  16.336 -  show "connected_component (S \<times> T) (x, y) (x', y')"
  16.337 -    unfolding connected_component_def
  16.338 -  proof (intro exI conjI)
  16.339 -    show "connected ((\<lambda>x. (x, y)) ` U \<union> Pair x' ` V)"
  16.340 -    proof (rule connected_Un)
  16.341 -      have "continuous_on U (\<lambda>x. (x, y))"
  16.342 -        by (intro continuous_intros)
  16.343 -      then show "connected ((\<lambda>x. (x, y)) ` U)"
  16.344 -        by (rule connected_continuous_image) (rule \<open>connected U\<close>)
  16.345 -      have "continuous_on V (Pair x')"
  16.346 -        by (intro continuous_intros)
  16.347 -      then show "connected (Pair x' ` V)"
  16.348 -        by (rule connected_continuous_image) (rule \<open>connected V\<close>)
  16.349 -    qed (use U V in auto)
  16.350 -  qed (use U V in auto)
  16.351 -qed
  16.352 -
  16.353 -corollary connected_Times_eq [simp]:
  16.354 -   "connected (S \<times> T) \<longleftrightarrow> S = {} \<or> T = {} \<or> connected S \<and> connected T"  (is "?lhs = ?rhs")
  16.355 -proof
  16.356 -  assume L: ?lhs
  16.357 -  show ?rhs
  16.358 -  proof (cases "S = {} \<or> T = {}")
  16.359 -    case True
  16.360 -    then show ?thesis by auto
  16.361 -  next
  16.362 -    case False
  16.363 -    have "connected (fst ` (S \<times> T))" "connected (snd ` (S \<times> T))"
  16.364 -      using continuous_on_fst continuous_on_snd continuous_on_id
  16.365 -      by (blast intro: connected_continuous_image [OF _ L])+
  16.366 -    with False show ?thesis
  16.367 -      by auto
  16.368 -  qed
  16.369 -next
  16.370 -  assume ?rhs
  16.371 -  then show ?lhs
  16.372 -    by (auto simp: connected_Times)
  16.373 -qed
  16.374 -
  16.375 -
  16.376 -subsection \<open>The set of connected components of a set\<close>
  16.377 -
  16.378 -definition components:: "'a::topological_space set \<Rightarrow> 'a set set"
  16.379 -  where "components s \<equiv> connected_component_set s ` s"
  16.380 -
  16.381 -lemma components_iff: "s \<in> components u \<longleftrightarrow> (\<exists>x. x \<in> u \<and> s = connected_component_set u x)"
  16.382 -  by (auto simp: components_def)
  16.383 -
  16.384 -lemma componentsI: "x \<in> u \<Longrightarrow> connected_component_set u x \<in> components u"
  16.385 -  by (auto simp: components_def)
  16.386 -
  16.387 -lemma componentsE:
  16.388 -  assumes "s \<in> components u"
  16.389 -  obtains x where "x \<in> u" "s = connected_component_set u x"
  16.390 -  using assms by (auto simp: components_def)
  16.391 -
  16.392 -lemma Union_components [simp]: "\<Union>(components u) = u"
  16.393 -  apply (rule subset_antisym)
  16.394 -  using Union_connected_component components_def apply fastforce
  16.395 -  apply (metis Union_connected_component components_def set_eq_subset)
  16.396 -  done
  16.397 -
  16.398 -lemma pairwise_disjoint_components: "pairwise (\<lambda>X Y. X \<inter> Y = {}) (components u)"
  16.399 -  apply (simp add: pairwise_def)
  16.400 -  apply (auto simp: components_iff)
  16.401 -  apply (metis connected_component_eq_eq connected_component_in)+
  16.402 -  done
  16.403 -
  16.404 -lemma in_components_nonempty: "c \<in> components s \<Longrightarrow> c \<noteq> {}"
  16.405 -    by (metis components_iff connected_component_eq_empty)
  16.406 -
  16.407 -lemma in_components_subset: "c \<in> components s \<Longrightarrow> c \<subseteq> s"
  16.408 -  using Union_components by blast
  16.409 -
  16.410 -lemma in_components_connected: "c \<in> components s \<Longrightarrow> connected c"
  16.411 -  by (metis components_iff connected_connected_component)
  16.412 -
  16.413 -lemma in_components_maximal:
  16.414 -  "c \<in> components s \<longleftrightarrow>
  16.415 -    c \<noteq> {} \<and> c \<subseteq> s \<and> connected c \<and> (\<forall>d. d \<noteq> {} \<and> c \<subseteq> d \<and> d \<subseteq> s \<and> connected d \<longrightarrow> d = c)"
  16.416 -  apply (rule iffI)
  16.417 -   apply (simp add: in_components_nonempty in_components_connected)
  16.418 -   apply (metis (full_types) components_iff connected_component_eq_self connected_component_intermediate_subset connected_component_refl in_components_subset mem_Collect_eq rev_subsetD)
  16.419 -  apply (metis bot.extremum_uniqueI components_iff connected_component_eq_empty connected_component_maximal connected_component_subset connected_connected_component subset_emptyI)
  16.420 -  done
  16.421 -
  16.422 -lemma joinable_components_eq:
  16.423 -  "connected t \<and> t \<subseteq> s \<and> c1 \<in> components s \<and> c2 \<in> components s \<and> c1 \<inter> t \<noteq> {} \<and> c2 \<inter> t \<noteq> {} \<Longrightarrow> c1 = c2"
  16.424 -  by (metis (full_types) components_iff joinable_connected_component_eq)
  16.425 -
  16.426 -lemma closed_components: "\<lbrakk>closed s; c \<in> components s\<rbrakk> \<Longrightarrow> closed c"
  16.427 -  by (metis closed_connected_component components_iff)
  16.428 -
  16.429 -lemma components_nonoverlap:
  16.430 -    "\<lbrakk>c \<in> components s; c' \<in> components s\<rbrakk> \<Longrightarrow> (c \<inter> c' = {}) \<longleftrightarrow> (c \<noteq> c')"
  16.431 -  apply (auto simp: in_components_nonempty components_iff)
  16.432 -    using connected_component_refl apply blast
  16.433 -   apply (metis connected_component_eq_eq connected_component_in)
  16.434 -  by (metis connected_component_eq mem_Collect_eq)
  16.435 -
  16.436 -lemma components_eq: "\<lbrakk>c \<in> components s; c' \<in> components s\<rbrakk> \<Longrightarrow> (c = c' \<longleftrightarrow> c \<inter> c' \<noteq> {})"
  16.437 -  by (metis components_nonoverlap)
  16.438 -
  16.439 -lemma components_eq_empty [simp]: "components s = {} \<longleftrightarrow> s = {}"
  16.440 -  by (simp add: components_def)
  16.441 -
  16.442 -lemma components_empty [simp]: "components {} = {}"
  16.443 -  by simp
  16.444 -
  16.445 -lemma connected_eq_connected_components_eq: "connected s \<longleftrightarrow> (\<forall>c \<in> components s. \<forall>c' \<in> components s. c = c')"
  16.446 -  by (metis (no_types, hide_lams) components_iff connected_component_eq_eq connected_iff_connected_component)
  16.447 -
  16.448 -lemma components_eq_sing_iff: "components s = {s} \<longleftrightarrow> connected s \<and> s \<noteq> {}"
  16.449 -  apply (rule iffI)
  16.450 -  using in_components_connected apply fastforce
  16.451 -  apply safe
  16.452 -  using Union_components apply fastforce
  16.453 -   apply (metis components_iff connected_component_eq_self)
  16.454 -  using in_components_maximal
  16.455 -  apply auto
  16.456 -  done
  16.457 -
  16.458 -lemma components_eq_sing_exists: "(\<exists>a. components s = {a}) \<longleftrightarrow> connected s \<and> s \<noteq> {}"
  16.459 -  apply (rule iffI)
  16.460 -  using connected_eq_connected_components_eq apply fastforce
  16.461 -  apply (metis components_eq_sing_iff)
  16.462 -  done
  16.463 -
  16.464 -lemma connected_eq_components_subset_sing: "connected s \<longleftrightarrow> components s \<subseteq> {s}"
  16.465 -  by (metis Union_components components_empty components_eq_sing_iff connected_empty insert_subset order_refl subset_singletonD)
  16.466 -
  16.467 -lemma connected_eq_components_subset_sing_exists: "connected s \<longleftrightarrow> (\<exists>a. components s \<subseteq> {a})"
  16.468 -  by (metis components_eq_sing_exists connected_eq_components_subset_sing empty_iff subset_iff subset_singletonD)
  16.469 -
  16.470 -lemma in_components_self: "s \<in> components s \<longleftrightarrow> connected s \<and> s \<noteq> {}"
  16.471 -  by (metis components_empty components_eq_sing_iff empty_iff in_components_connected insertI1)
  16.472 -
  16.473 -lemma components_maximal: "\<lbrakk>c \<in> components s; connected t; t \<subseteq> s; c \<inter> t \<noteq> {}\<rbrakk> \<Longrightarrow> t \<subseteq> c"
  16.474 -  apply (simp add: components_def ex_in_conv [symmetric], clarify)
  16.475 -  by (meson connected_component_def connected_component_trans)
  16.476 -
  16.477 -lemma exists_component_superset: "\<lbrakk>t \<subseteq> s; s \<noteq> {}; connected t\<rbrakk> \<Longrightarrow> \<exists>c. c \<in> components s \<and> t \<subseteq> c"
  16.478 -  apply (cases "t = {}", force)
  16.479 -  apply (metis components_def ex_in_conv connected_component_maximal contra_subsetD image_eqI)
  16.480 -  done
  16.481 -
  16.482 -lemma components_intermediate_subset: "\<lbrakk>s \<in> components u; s \<subseteq> t; t \<subseteq> u\<rbrakk> \<Longrightarrow> s \<in> components t"
  16.483 -  apply (auto simp: components_iff)
  16.484 -  apply (metis connected_component_eq_empty connected_component_intermediate_subset)
  16.485 -  done
  16.486 -
  16.487 -lemma in_components_unions_complement: "c \<in> components s \<Longrightarrow> s - c = \<Union>(components s - {c})"
  16.488 -  by (metis complement_connected_component_unions components_def components_iff)
  16.489 -
  16.490 -lemma connected_intermediate_closure:
  16.491 -  assumes cs: "connected s" and st: "s \<subseteq> t" and ts: "t \<subseteq> closure s"
  16.492 -  shows "connected t"
  16.493 -proof (rule connectedI)
  16.494 -  fix A B
  16.495 -  assume A: "open A" and B: "open B" and Alap: "A \<inter> t \<noteq> {}" and Blap: "B \<inter> t \<noteq> {}"
  16.496 -    and disj: "A \<inter> B \<inter> t = {}" and cover: "t \<subseteq> A \<union> B"
  16.497 -  have disjs: "A \<inter> B \<inter> s = {}"
  16.498 -    using disj st by auto
  16.499 -  have "A \<inter> closure s \<noteq> {}"
  16.500 -    using Alap Int_absorb1 ts by blast
  16.501 -  then have Alaps: "A \<inter> s \<noteq> {}"
  16.502 -    by (simp add: A open_Int_closure_eq_empty)
  16.503 -  have "B \<inter> closure s \<noteq> {}"
  16.504 -    using Blap Int_absorb1 ts by blast
  16.505 -  then have Blaps: "B \<inter> s \<noteq> {}"
  16.506 -    by (simp add: B open_Int_closure_eq_empty)
  16.507 -  then show False
  16.508 -    using cs [unfolded connected_def] A B disjs Alaps Blaps cover st
  16.509 -    by blast
  16.510 -qed
  16.511 -
  16.512 -lemma closedin_connected_component: "closedin (subtopology euclidean s) (connected_component_set s x)"
  16.513 -proof (cases "connected_component_set s x = {}")
  16.514 -  case True
  16.515 -  then show ?thesis
  16.516 -    by (metis closedin_empty)
  16.517 -next
  16.518 -  case False
  16.519 -  then obtain y where y: "connected_component s x y"
  16.520 -    by blast
  16.521 -  have *: "connected_component_set s x \<subseteq> s \<inter> closure (connected_component_set s x)"
  16.522 -    by (auto simp: closure_def connected_component_in)
  16.523 -  have "connected_component s x y \<Longrightarrow> s \<inter> closure (connected_component_set s x) \<subseteq> connected_component_set s x"
  16.524 -    apply (rule connected_component_maximal, simp)
  16.525 -    using closure_subset connected_component_in apply fastforce
  16.526 -    using * connected_intermediate_closure apply blast+
  16.527 -    done
  16.528 -  with y * show ?thesis
  16.529 -    by (auto simp: Topology_Euclidean_Space.closedin_closed)
  16.530 -qed
  16.531 -
  16.532 -
  16.533  subsection \<open>Frontier (also known as boundary)\<close>
  16.534  
  16.535  definition "frontier S = closure S - interior S"
  16.536 @@ -3629,477 +3197,6 @@
  16.537  qed
  16.538  
  16.539  
  16.540 -subsection \<open>Infimum Distance\<close>
  16.541 -
  16.542 -definition "infdist x A = (if A = {} then 0 else INF a:A. dist x a)"
  16.543 -
  16.544 -lemma bdd_below_infdist[intro, simp]: "bdd_below (dist x`A)"
  16.545 -  by (auto intro!: zero_le_dist)
  16.546 -
  16.547 -lemma infdist_notempty: "A \<noteq> {} \<Longrightarrow> infdist x A = (INF a:A. dist x a)"
  16.548 -  by (simp add: infdist_def)
  16.549 -
  16.550 -lemma infdist_nonneg: "0 \<le> infdist x A"
  16.551 -  by (auto simp: infdist_def intro: cINF_greatest)
  16.552 -
  16.553 -lemma infdist_le: "a \<in> A \<Longrightarrow> infdist x A \<le> dist x a"
  16.554 -  by (auto intro: cINF_lower simp add: infdist_def)
  16.555 -
  16.556 -lemma infdist_le2: "a \<in> A \<Longrightarrow> dist x a \<le> d \<Longrightarrow> infdist x A \<le> d"
  16.557 -  by (auto intro!: cINF_lower2 simp add: infdist_def)
  16.558 -
  16.559 -lemma infdist_zero[simp]: "a \<in> A \<Longrightarrow> infdist a A = 0"
  16.560 -  by (auto intro!: antisym infdist_nonneg infdist_le2)
  16.561 -
  16.562 -lemma infdist_triangle: "infdist x A \<le> infdist y A + dist x y"
  16.563 -proof (cases "A = {}")
  16.564 -  case True
  16.565 -  then show ?thesis by (simp add: infdist_def)
  16.566 -next
  16.567 -  case False
  16.568 -  then obtain a where "a \<in> A" by auto
  16.569 -  have "infdist x A \<le> Inf {dist x y + dist y a |a. a \<in> A}"
  16.570 -  proof (rule cInf_greatest)
  16.571 -    from \<open>A \<noteq> {}\<close> show "{dist x y + dist y a |a. a \<in> A} \<noteq> {}"
  16.572 -      by simp
  16.573 -    fix d
  16.574 -    assume "d \<in> {dist x y + dist y a |a. a \<in> A}"
  16.575 -    then obtain a where d: "d = dist x y + dist y a" "a \<in> A"
  16.576 -      by auto
  16.577 -    show "infdist x A \<le> d"
  16.578 -      unfolding infdist_notempty[OF \<open>A \<noteq> {}\<close>]
  16.579 -    proof (rule cINF_lower2)
  16.580 -      show "a \<in> A" by fact
  16.581 -      show "dist x a \<le> d"
  16.582 -        unfolding d by (rule dist_triangle)
  16.583 -    qed simp
  16.584 -  qed
  16.585 -  also have "\<dots> = dist x y + infdist y A"
  16.586 -  proof (rule cInf_eq, safe)
  16.587 -    fix a
  16.588 -    assume "a \<in> A"
  16.589 -    then show "dist x y + infdist y A \<le> dist x y + dist y a"
  16.590 -      by (auto intro: infdist_le)
  16.591 -  next
  16.592 -    fix i
  16.593 -    assume inf: "\<And>d. d \<in> {dist x y + dist y a |a. a \<in> A} \<Longrightarrow> i \<le> d"
  16.594 -    then have "i - dist x y \<le> infdist y A"
  16.595 -      unfolding infdist_notempty[OF \<open>A \<noteq> {}\<close>] using \<open>a \<in> A\<close>
  16.596 -      by (intro cINF_greatest) (auto simp: field_simps)
  16.597 -    then show "i \<le> dist x y + infdist y A"
  16.598 -      by simp
  16.599 -  qed
  16.600 -  finally show ?thesis by simp
  16.601 -qed
  16.602 -
  16.603 -lemma in_closure_iff_infdist_zero:
  16.604 -  assumes "A \<noteq> {}"
  16.605 -  shows "x \<in> closure A \<longleftrightarrow> infdist x A = 0"
  16.606 -proof
  16.607 -  assume "x \<in> closure A"
  16.608 -  show "infdist x A = 0"
  16.609 -  proof (rule ccontr)
  16.610 -    assume "infdist x A \<noteq> 0"
  16.611 -    with infdist_nonneg[of x A] have "infdist x A > 0"
  16.612 -      by auto
  16.613 -    then have "ball x (infdist x A) \<inter> closure A = {}"
  16.614 -      apply auto
  16.615 -      apply (metis \<open>x \<in> closure A\<close> closure_approachable dist_commute infdist_le not_less)
  16.616 -      done
  16.617 -    then have "x \<notin> closure A"
  16.618 -      by (metis \<open>0 < infdist x A\<close> centre_in_ball disjoint_iff_not_equal)
  16.619 -    then show False using \<open>x \<in> closure A\<close> by simp
  16.620 -  qed
  16.621 -next
  16.622 -  assume x: "infdist x A = 0"
  16.623 -  then obtain a where "a \<in> A"
  16.624 -    by atomize_elim (metis all_not_in_conv assms)
  16.625 -  show "x \<in> closure A"
  16.626 -    unfolding closure_approachable
  16.627 -    apply safe
  16.628 -  proof (rule ccontr)
  16.629 -    fix e :: real
  16.630 -    assume "e > 0"
  16.631 -    assume "\<not> (\<exists>y\<in>A. dist y x < e)"
  16.632 -    then have "infdist x A \<ge> e" using \<open>a \<in> A\<close>
  16.633 -      unfolding infdist_def
  16.634 -      by (force simp: dist_commute intro: cINF_greatest)
  16.635 -    with x \<open>e > 0\<close> show False by auto
  16.636 -  qed
  16.637 -qed
  16.638 -
  16.639 -lemma in_closed_iff_infdist_zero:
  16.640 -  assumes "closed A" "A \<noteq> {}"
  16.641 -  shows "x \<in> A \<longleftrightarrow> infdist x A = 0"
  16.642 -proof -
  16.643 -  have "x \<in> closure A \<longleftrightarrow> infdist x A = 0"
  16.644 -    by (rule in_closure_iff_infdist_zero) fact
  16.645 -  with assms show ?thesis by simp
  16.646 -qed
  16.647 -
  16.648 -lemma tendsto_infdist [tendsto_intros]:
  16.649 -  assumes f: "(f \<longlongrightarrow> l) F"
  16.650 -  shows "((\<lambda>x. infdist (f x) A) \<longlongrightarrow> infdist l A) F"
  16.651 -proof (rule tendstoI)
  16.652 -  fix e ::real
  16.653 -  assume "e > 0"
  16.654 -  from tendstoD[OF f this]
  16.655 -  show "eventually (\<lambda>x. dist (infdist (f x) A) (infdist l A) < e) F"
  16.656 -  proof (eventually_elim)
  16.657 -    fix x
  16.658 -    from infdist_triangle[of l A "f x"] infdist_triangle[of "f x" A l]
  16.659 -    have "dist (infdist (f x) A) (infdist l A) \<le> dist (f x) l"
  16.660 -      by (simp add: dist_commute dist_real_def)
  16.661 -    also assume "dist (f x) l < e"
  16.662 -    finally show "dist (infdist (f x) A) (infdist l A) < e" .
  16.663 -  qed
  16.664 -qed
  16.665 -
  16.666 -text\<open>Some other lemmas about sequences.\<close>
  16.667 -
  16.668 -lemma sequentially_offset: (* TODO: move to Topological_Spaces.thy *)
  16.669 -  assumes "eventually (\<lambda>i. P i) sequentially"
  16.670 -  shows "eventually (\<lambda>i. P (i + k)) sequentially"
  16.671 -  using assms by (rule eventually_sequentially_seg [THEN iffD2])
  16.672 -
  16.673 -lemma seq_offset_neg: (* TODO: move to Topological_Spaces.thy *)
  16.674 -  "(f \<longlongrightarrow> l) sequentially \<Longrightarrow> ((\<lambda>i. f(i - k)) \<longlongrightarrow> l) sequentially"
  16.675 -  apply (erule filterlim_compose)
  16.676 -  apply (simp add: filterlim_def le_sequentially eventually_filtermap eventually_sequentially, arith)
  16.677 -  done
  16.678 -
  16.679 -lemma seq_harmonic: "((\<lambda>n. inverse (real n)) \<longlongrightarrow> 0) sequentially"
  16.680 -  using LIMSEQ_inverse_real_of_nat by (rule LIMSEQ_imp_Suc) (* TODO: move to Limits.thy *)
  16.681 -
  16.682 -subsection \<open>More properties of closed balls\<close>
  16.683 -
  16.684 -lemma closed_cball [iff]: "closed (cball x e)"
  16.685 -proof -
  16.686 -  have "closed (dist x -` {..e})"
  16.687 -    by (intro closed_vimage closed_atMost continuous_intros)
  16.688 -  also have "dist x -` {..e} = cball x e"
  16.689 -    by auto
  16.690 -  finally show ?thesis .
  16.691 -qed
  16.692 -
  16.693 -lemma open_contains_cball: "open S \<longleftrightarrow> (\<forall>x\<in>S. \<exists>e>0.  cball x e \<subseteq> S)"
  16.694 -proof -
  16.695 -  {
  16.696 -    fix x and e::real
  16.697 -    assume "x\<in>S" "e>0" "ball x e \<subseteq> S"
  16.698 -    then have "\<exists>d>0. cball x d \<subseteq> S" unfolding subset_eq by (rule_tac x="e/2" in exI, auto)
  16.699 -  }
  16.700 -  moreover
  16.701 -  {
  16.702 -    fix x and e::real
  16.703 -    assume "x\<in>S" "e>0" "cball x e \<subseteq> S"
  16.704 -    then have "\<exists>d>0. ball x d \<subseteq> S"
  16.705 -      unfolding subset_eq
  16.706 -      apply (rule_tac x="e/2" in exI, auto)
  16.707 -      done
  16.708 -  }
  16.709 -  ultimately show ?thesis
  16.710 -    unfolding open_contains_ball by auto
  16.711 -qed
  16.712 -
  16.713 -lemma open_contains_cball_eq: "open S \<Longrightarrow> (\<forall>x. x \<in> S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S))"
  16.714 -  by (metis open_contains_cball subset_eq order_less_imp_le centre_in_cball)
  16.715 -
  16.716 -lemma mem_interior_cball: "x \<in> interior S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S)"
  16.717 -  apply (simp add: interior_def, safe)
  16.718 -  apply (force simp: open_contains_cball)
  16.719 -  apply (rule_tac x="ball x e" in exI)
  16.720 -  apply (simp add: subset_trans [OF ball_subset_cball])
  16.721 -  done
  16.722 -
  16.723 -lemma islimpt_ball:
  16.724 -  fixes x y :: "'a::{real_normed_vector,perfect_space}"
  16.725 -  shows "y islimpt ball x e \<longleftrightarrow> 0 < e \<and> y \<in> cball x e"
  16.726 -  (is "?lhs \<longleftrightarrow> ?rhs")
  16.727 -proof
  16.728 -  show ?rhs if ?lhs
  16.729 -  proof
  16.730 -    {
  16.731 -      assume "e \<le> 0"
  16.732 -      then have *: "ball x e = {}"
  16.733 -        using ball_eq_empty[of x e] by auto
  16.734 -      have False using \<open>?lhs\<close>
  16.735 -        unfolding * using islimpt_EMPTY[of y] by auto
  16.736 -    }
  16.737 -    then show "e > 0" by (metis not_less)
  16.738 -    show "y \<in> cball x e"
  16.739 -      using closed_cball[of x e] islimpt_subset[of y "ball x e" "cball x e"]
  16.740 -        ball_subset_cball[of x e] \<open>?lhs\<close>
  16.741 -      unfolding closed_limpt by auto
  16.742 -  qed
  16.743 -  show ?lhs if ?rhs
  16.744 -  proof -
  16.745 -    from that have "e > 0" by auto
  16.746 -    {
  16.747 -      fix d :: real
  16.748 -      assume "d > 0"
  16.749 -      have "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.750 -      proof (cases "d \<le> dist x y")
  16.751 -        case True
  16.752 -        then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.753 -        proof (cases "x = y")
  16.754 -          case True
  16.755 -          then have False
  16.756 -            using \<open>d \<le> dist x y\<close> \<open>d>0\<close> by auto
  16.757 -          then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.758 -            by auto
  16.759 -        next
  16.760 -          case False
  16.761 -          have "dist x (y - (d / (2 * dist y x)) *\<^sub>R (y - x)) =
  16.762 -            norm (x - y + (d / (2 * norm (y - x))) *\<^sub>R (y - x))"
  16.763 -            unfolding mem_cball mem_ball dist_norm diff_diff_eq2 diff_add_eq[symmetric]
  16.764 -            by auto
  16.765 -          also have "\<dots> = \<bar>- 1 + d / (2 * norm (x - y))\<bar> * norm (x - y)"
  16.766 -            using scaleR_left_distrib[of "- 1" "d / (2 * norm (y - x))", symmetric, of "y - x"]
  16.767 -            unfolding scaleR_minus_left scaleR_one
  16.768 -            by (auto simp: norm_minus_commute)
  16.769 -          also have "\<dots> = \<bar>- norm (x - y) + d / 2\<bar>"
  16.770 -            unfolding abs_mult_pos[of "norm (x - y)", OF norm_ge_zero[of "x - y"]]
  16.771 -            unfolding distrib_right using \<open>x\<noteq>y\<close>  by auto
  16.772 -          also have "\<dots> \<le> e - d/2" using \<open>d \<le> dist x y\<close> and \<open>d>0\<close> and \<open>?rhs\<close>
  16.773 -            by (auto simp: dist_norm)
  16.774 -          finally have "y - (d / (2 * dist y x)) *\<^sub>R (y - x) \<in> ball x e" using \<open>d>0\<close>
  16.775 -            by auto
  16.776 -          moreover
  16.777 -          have "(d / (2*dist y x)) *\<^sub>R (y - x) \<noteq> 0"
  16.778 -            using \<open>x\<noteq>y\<close>[unfolded dist_nz] \<open>d>0\<close> unfolding scaleR_eq_0_iff
  16.779 -            by (auto simp: dist_commute)
  16.780 -          moreover
  16.781 -          have "dist (y - (d / (2 * dist y x)) *\<^sub>R (y - x)) y < d"
  16.782 -            unfolding dist_norm
  16.783 -            apply simp
  16.784 -            unfolding norm_minus_cancel
  16.785 -            using \<open>d > 0\<close> \<open>x\<noteq>y\<close>[unfolded dist_nz] dist_commute[of x y]
  16.786 -            unfolding dist_norm
  16.787 -            apply auto
  16.788 -            done
  16.789 -          ultimately show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.790 -            apply (rule_tac x = "y - (d / (2*dist y x)) *\<^sub>R (y - x)" in bexI)
  16.791 -            apply auto
  16.792 -            done
  16.793 -        qed
  16.794 -      next
  16.795 -        case False
  16.796 -        then have "d > dist x y" by auto
  16.797 -        show "\<exists>x' \<in> ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.798 -        proof (cases "x = y")
  16.799 -          case True
  16.800 -          obtain z where **: "z \<noteq> y" "dist z y < min e d"
  16.801 -            using perfect_choose_dist[of "min e d" y]
  16.802 -            using \<open>d > 0\<close> \<open>e>0\<close> by auto
  16.803 -          show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.804 -            unfolding \<open>x = y\<close>
  16.805 -            using \<open>z \<noteq> y\<close> **
  16.806 -            apply (rule_tac x=z in bexI)
  16.807 -            apply (auto simp: dist_commute)
  16.808 -            done
  16.809 -        next
  16.810 -          case False
  16.811 -          then show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  16.812 -            using \<open>d>0\<close> \<open>d > dist x y\<close> \<open>?rhs\<close>
  16.813 -            apply (rule_tac x=x in bexI, auto)
  16.814 -            done
  16.815 -        qed
  16.816 -      qed
  16.817 -    }
  16.818 -    then show ?thesis
  16.819 -      unfolding mem_cball islimpt_approachable mem_ball by auto
  16.820 -  qed
  16.821 -qed
  16.822 -
  16.823 -lemma closure_ball_lemma:
  16.824 -  fixes x y :: "'a::real_normed_vector"
  16.825 -  assumes "x \<noteq> y"
  16.826 -  shows "y islimpt ball x (dist x y)"
  16.827 -proof (rule islimptI)
  16.828 -  fix T
  16.829 -  assume "y \<in> T" "open T"
  16.830 -  then obtain r where "0 < r" "\<forall>z. dist z y < r \<longrightarrow> z \<in> T"
  16.831 -    unfolding open_dist by fast
  16.832 -  (* choose point between x and y, within distance r of y. *)
  16.833 -  define k where "k = min 1 (r / (2 * dist x y))"
  16.834 -  define z where "z = y + scaleR k (x - y)"
  16.835 -  have z_def2: "z = x + scaleR (1 - k) (y - x)"
  16.836 -    unfolding z_def by (simp add: algebra_simps)
  16.837 -  have "dist z y < r"
  16.838 -    unfolding z_def k_def using \<open>0 < r\<close>
  16.839 -    by (simp add: dist_norm min_def)
  16.840 -  then have "z \<in> T"
  16.841 -    using \<open>\<forall>z. dist z y < r \<longrightarrow> z \<in> T\<close> by simp
  16.842 -  have "dist x z < dist x y"
  16.843 -    unfolding z_def2 dist_norm
  16.844 -    apply (simp add: norm_minus_commute)
  16.845 -    apply (simp only: dist_norm [symmetric])
  16.846 -    apply (subgoal_tac "\<bar>1 - k\<bar> * dist x y < 1 * dist x y", simp)
  16.847 -    apply (rule mult_strict_right_mono)
  16.848 -    apply (simp add: k_def \<open>0 < r\<close> \<open>x \<noteq> y\<close>)
  16.849 -    apply (simp add: \<open>x \<noteq> y\<close>)
  16.850 -    done
  16.851 -  then have "z \<in> ball x (dist x y)"
  16.852 -    by simp
  16.853 -  have "z \<noteq> y"
  16.854 -    unfolding z_def k_def using \<open>x \<noteq> y\<close> \<open>0 < r\<close>
  16.855 -    by (simp add: min_def)
  16.856 -  show "\<exists>z\<in>ball x (dist x y). z \<in> T \<and> z \<noteq> y"
  16.857 -    using \<open>z \<in> ball x (dist x y)\<close> \<open>z \<in> T\<close> \<open>z \<noteq> y\<close>
  16.858 -    by fast
  16.859 -qed
  16.860 -
  16.861 -lemma closure_ball [simp]:
  16.862 -  fixes x :: "'a::real_normed_vector"
  16.863 -  shows "0 < e \<Longrightarrow> closure (ball x e) = cball x e"
  16.864 -  apply (rule equalityI)
  16.865 -  apply (rule closure_minimal)
  16.866 -  apply (rule ball_subset_cball)
  16.867 -  apply (rule closed_cball)
  16.868 -  apply (rule subsetI, rename_tac y)
  16.869 -  apply (simp add: le_less [where 'a=real])
  16.870 -  apply (erule disjE)
  16.871 -  apply (rule subsetD [OF closure_subset], simp)
  16.872 -  apply (simp add: closure_def, clarify)
  16.873 -  apply (rule closure_ball_lemma)
  16.874 -  apply (simp add: zero_less_dist_iff)
  16.875 -  done
  16.876 -
  16.877 -(* In a trivial vector space, this fails for e = 0. *)
  16.878 -lemma interior_cball [simp]:
  16.879 -  fixes x :: "'a::{real_normed_vector, perfect_space}"
  16.880 -  shows "interior (cball x e) = ball x e"
  16.881 -proof (cases "e \<ge> 0")
  16.882 -  case False note cs = this
  16.883 -  from cs have null: "ball x e = {}"
  16.884 -    using ball_empty[of e x] by auto
  16.885 -  moreover
  16.886 -  {
  16.887 -    fix y
  16.888 -    assume "y \<in> cball x e"
  16.889 -    then have False
  16.890 -      by (metis ball_eq_empty null cs dist_eq_0_iff dist_le_zero_iff empty_subsetI mem_cball subset_antisym subset_ball)
  16.891 -  }
  16.892 -  then have "cball x e = {}" by auto
  16.893 -  then have "interior (cball x e) = {}"
  16.894 -    using interior_empty by auto
  16.895 -  ultimately show ?thesis by blast
  16.896 -next
  16.897 -  case True note cs = this
  16.898 -  have "ball x e \<subseteq> cball x e"
  16.899 -    using ball_subset_cball by auto
  16.900 -  moreover
  16.901 -  {
  16.902 -    fix S y
  16.903 -    assume as: "S \<subseteq> cball x e" "open S" "y\<in>S"
  16.904 -    then obtain d where "d>0" and d: "\<forall>x'. dist x' y < d \<longrightarrow> x' \<in> S"
  16.905 -      unfolding open_dist by blast
  16.906 -    then obtain xa where xa_y: "xa \<noteq> y" and xa: "dist xa y < d"
  16.907 -      using perfect_choose_dist [of d] by auto
  16.908 -    have "xa \<in> S"
  16.909 -      using d[THEN spec[where x = xa]]
  16.910 -      using xa by (auto simp: dist_commute)
  16.911 -    then have xa_cball: "xa \<in> cball x e"
  16.912 -      using as(1) by auto
  16.913 -    then have "y \<in> ball x e"
  16.914 -    proof (cases "x = y")
  16.915 -      case True
  16.916 -      then have "e > 0" using cs order.order_iff_strict xa_cball xa_y by fastforce
  16.917 -      then show "y \<in> ball x e"
  16.918 -        using \<open>x = y \<close> by simp
  16.919 -    next
  16.920 -      case False
  16.921 -      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) y < d"
  16.922 -        unfolding dist_norm
  16.923 -        using \<open>d>0\<close> norm_ge_zero[of "y - x"] \<open>x \<noteq> y\<close> by auto
  16.924 -      then have *: "y + (d / 2 / dist y x) *\<^sub>R (y - x) \<in> cball x e"
  16.925 -        using d as(1)[unfolded subset_eq] by blast
  16.926 -      have "y - x \<noteq> 0" using \<open>x \<noteq> y\<close> by auto
  16.927 -      hence **:"d / (2 * norm (y - x)) > 0"
  16.928 -        unfolding zero_less_norm_iff[symmetric] using \<open>d>0\<close> by auto
  16.929 -      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) x =
  16.930 -        norm (y + (d / (2 * norm (y - x))) *\<^sub>R y - (d / (2 * norm (y - x))) *\<^sub>R x - x)"
  16.931 -        by (auto simp: dist_norm algebra_simps)
  16.932 -      also have "\<dots> = norm ((1 + d / (2 * norm (y - x))) *\<^sub>R (y - x))"
  16.933 -        by (auto simp: algebra_simps)
  16.934 -      also have "\<dots> = \<bar>1 + d / (2 * norm (y - x))\<bar> * norm (y - x)"
  16.935 -        using ** by auto
  16.936 -      also have "\<dots> = (dist y x) + d/2"
  16.937 -        using ** by (auto simp: distrib_right dist_norm)
  16.938 -      finally have "e \<ge> dist x y +d/2"
  16.939 -        using *[unfolded mem_cball] by (auto simp: dist_commute)
  16.940 -      then show "y \<in> ball x e"
  16.941 -        unfolding mem_ball using \<open>d>0\<close> by auto
  16.942 -    qed
  16.943 -  }
  16.944 -  then have "\<forall>S \<subseteq> cball x e. open S \<longrightarrow> S \<subseteq> ball x e"
  16.945 -    by auto
  16.946 -  ultimately show ?thesis
  16.947 -    using interior_unique[of "ball x e" "cball x e"]
  16.948 -    using open_ball[of x e]
  16.949 -    by auto
  16.950 -qed
  16.951 -
  16.952 -lemma interior_ball [simp]: "interior (ball x e) = ball x e"
  16.953 -  by (simp add: interior_open)
  16.954 -
  16.955 -lemma frontier_ball [simp]:
  16.956 -  fixes a :: "'a::real_normed_vector"
  16.957 -  shows "0 < e \<Longrightarrow> frontier (ball a e) = sphere a e"
  16.958 -  by (force simp: frontier_def)
  16.959 -
  16.960 -lemma frontier_cball [simp]:
  16.961 -  fixes a :: "'a::{real_normed_vector, perfect_space}"
  16.962 -  shows "frontier (cball a e) = sphere a e"
  16.963 -  by (force simp: frontier_def)
  16.964 -
  16.965 -lemma cball_eq_empty [simp]: "cball x e = {} \<longleftrightarrow> e < 0"
  16.966 -  apply (simp add: set_eq_iff not_le)
  16.967 -  apply (metis zero_le_dist dist_self order_less_le_trans)
  16.968 -  done
  16.969 -
  16.970 -lemma cball_empty [simp]: "e < 0 \<Longrightarrow> cball x e = {}"
  16.971 -  by (simp add: cball_eq_empty)
  16.972 -
  16.973 -lemma cball_eq_sing:
  16.974 -  fixes x :: "'a::{metric_space,perfect_space}"
  16.975 -  shows "cball x e = {x} \<longleftrightarrow> e = 0"
  16.976 -proof (rule linorder_cases)
  16.977 -  assume e: "0 < e"
  16.978 -  obtain a where "a \<noteq> x" "dist a x < e"
  16.979 -    using perfect_choose_dist [OF e] by auto
  16.980 -  then have "a \<noteq> x" "dist x a \<le> e"
  16.981 -    by (auto simp: dist_commute)
  16.982 -  with e show ?thesis by (auto simp: set_eq_iff)
  16.983 -qed auto
  16.984 -
  16.985 -lemma cball_sing:
  16.986 -  fixes x :: "'a::metric_space"
  16.987 -  shows "e = 0 \<Longrightarrow> cball x e = {x}"
  16.988 -  by (auto simp: set_eq_iff)
  16.989 -
  16.990 -lemma ball_divide_subset: "d \<ge> 1 \<Longrightarrow> ball x (e/d) \<subseteq> ball x e"
  16.991 -  apply (cases "e \<le> 0")
  16.992 -  apply (simp add: ball_empty divide_simps)
  16.993 -  apply (rule subset_ball)
  16.994 -  apply (simp add: divide_simps)
  16.995 -  done
  16.996 -
  16.997 -lemma ball_divide_subset_numeral: "ball x (e / numeral w) \<subseteq> ball x e"
  16.998 -  using ball_divide_subset one_le_numeral by blast
  16.999 -
 16.1000 -lemma cball_divide_subset: "d \<ge> 1 \<Longrightarrow> cball x (e/d) \<subseteq> cball x e"
 16.1001 -  apply (cases "e < 0")
 16.1002 -  apply (simp add: divide_simps)
 16.1003 -  apply (rule subset_cball)
 16.1004 -  apply (metis div_by_1 frac_le not_le order_refl zero_less_one)
 16.1005 -  done
 16.1006 -
 16.1007 -lemma cball_divide_subset_numeral: "cball x (e / numeral w) \<subseteq> cball x e"
 16.1008 -  using cball_divide_subset one_le_numeral by blast
 16.1009 -
 16.1010 -
 16.1011  subsection \<open>Boundedness\<close>
 16.1012  
 16.1013    (* FIXME: This has to be unified with BSEQ!! *)
 16.1014 @@ -4364,91 +3461,6 @@
 16.1015    by auto
 16.1016  
 16.1017  
 16.1018 -subsection\<open>Some theorems on sups and infs using the notion "bounded".\<close>
 16.1019 -
 16.1020 -lemma bounded_real: "bounded (S::real set) \<longleftrightarrow> (\<exists>a. \<forall>x\<in>S. \<bar>x\<bar> \<le> a)"
 16.1021 -  by (simp add: bounded_iff)
 16.1022 -
 16.1023 -lemma bounded_imp_bdd_above: "bounded S \<Longrightarrow> bdd_above (S :: real set)"
 16.1024 -  by (auto simp: bounded_def bdd_above_def dist_real_def)
 16.1025 -     (metis abs_le_D1 abs_minus_commute diff_le_eq)
 16.1026 -
 16.1027 -lemma bounded_imp_bdd_below: "bounded S \<Longrightarrow> bdd_below (S :: real set)"
 16.1028 -  by (auto simp: bounded_def bdd_below_def dist_real_def)
 16.1029 -     (metis abs_le_D1 add.commute diff_le_eq)
 16.1030 -
 16.1031 -lemma bounded_inner_imp_bdd_above:
 16.1032 -  assumes "bounded s"
 16.1033 -    shows "bdd_above ((\<lambda>x. x \<bullet> a) ` s)"
 16.1034 -by (simp add: assms bounded_imp_bdd_above bounded_linear_image bounded_linear_inner_left)
 16.1035 -
 16.1036 -lemma bounded_inner_imp_bdd_below:
 16.1037 -  assumes "bounded s"
 16.1038 -    shows "bdd_below ((\<lambda>x. x \<bullet> a) ` s)"
 16.1039 -by (simp add: assms bounded_imp_bdd_below bounded_linear_image bounded_linear_inner_left)
 16.1040 -
 16.1041 -lemma bounded_has_Sup:
 16.1042 -  fixes S :: "real set"
 16.1043 -  assumes "bounded S"
 16.1044 -    and "S \<noteq> {}"
 16.1045 -  shows "\<forall>x\<in>S. x \<le> Sup S"
 16.1046 -    and "\<forall>b. (\<forall>x\<in>S. x \<le> b) \<longrightarrow> Sup S \<le> b"
 16.1047 -proof
 16.1048 -  show "\<forall>b. (\<forall>x\<in>S. x \<le> b) \<longrightarrow> Sup S \<le> b"
 16.1049 -    using assms by (metis cSup_least)
 16.1050 -qed (metis cSup_upper assms(1) bounded_imp_bdd_above)
 16.1051 -
 16.1052 -lemma Sup_insert:
 16.1053 -  fixes S :: "real set"
 16.1054 -  shows "bounded S \<Longrightarrow> Sup (insert x S) = (if S = {} then x else max x (Sup S))"
 16.1055 -  by (auto simp: bounded_imp_bdd_above sup_max cSup_insert_If)
 16.1056 -
 16.1057 -lemma Sup_insert_finite:
 16.1058 -  fixes S :: "'a::conditionally_complete_linorder set"
 16.1059 -  shows "finite S \<Longrightarrow> Sup (insert x S) = (if S = {} then x else max x (Sup S))"
 16.1060 -by (simp add: cSup_insert sup_max)
 16.1061 -
 16.1062 -lemma bounded_has_Inf:
 16.1063 -  fixes S :: "real set"
 16.1064 -  assumes "bounded S"
 16.1065 -    and "S \<noteq> {}"
 16.1066 -  shows "\<forall>x\<in>S. x \<ge> Inf S"
 16.1067 -    and "\<forall>b. (\<forall>x\<in>S. x \<ge> b) \<longrightarrow> Inf S \<ge> b"
 16.1068 -proof
 16.1069 -  show "\<forall>b. (\<forall>x\<in>S. x \<ge> b) \<longrightarrow> Inf S \<ge> b"
 16.1070 -    using assms by (metis cInf_greatest)
 16.1071 -qed (metis cInf_lower assms(1) bounded_imp_bdd_below)
 16.1072 -
 16.1073 -lemma Inf_insert:
 16.1074 -  fixes S :: "real set"
 16.1075 -  shows "bounded S \<Longrightarrow> Inf (insert x S) = (if S = {} then x else min x (Inf S))"
 16.1076 -  by (auto simp: bounded_imp_bdd_below inf_min cInf_insert_If)
 16.1077 -
 16.1078 -lemma Inf_insert_finite:
 16.1079 -  fixes S :: "'a::conditionally_complete_linorder set"
 16.1080 -  shows "finite S \<Longrightarrow> Inf (insert x S) = (if S = {} then x else min x (Inf S))"
 16.1081 -by (simp add: cInf_eq_Min)
 16.1082 -
 16.1083 -lemma finite_imp_less_Inf:
 16.1084 -  fixes a :: "'a::conditionally_complete_linorder"
 16.1085 -  shows "\<lbrakk>finite X; x \<in> X; \<And>x. x\<in>X \<Longrightarrow> a < x\<rbrakk> \<Longrightarrow> a < Inf X"
 16.1086 -  by (induction X rule: finite_induct) (simp_all add: cInf_eq_Min Inf_insert_finite)
 16.1087 -
 16.1088 -lemma finite_less_Inf_iff:
 16.1089 -  fixes a :: "'a :: conditionally_complete_linorder"
 16.1090 -  shows "\<lbrakk>finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> a < Inf X \<longleftrightarrow> (\<forall>x \<in> X. a < x)"
 16.1091 -  by (auto simp: cInf_eq_Min)
 16.1092 -
 16.1093 -lemma finite_imp_Sup_less:
 16.1094 -  fixes a :: "'a::conditionally_complete_linorder"
 16.1095 -  shows "\<lbrakk>finite X; x \<in> X; \<And>x. x\<in>X \<Longrightarrow> a > x\<rbrakk> \<Longrightarrow> a > Sup X"
 16.1096 -  by (induction X rule: finite_induct) (simp_all add: cSup_eq_Max Sup_insert_finite)
 16.1097 -
 16.1098 -lemma finite_Sup_less_iff:
 16.1099 -  fixes a :: "'a :: conditionally_complete_linorder"
 16.1100 -  shows "\<lbrakk>finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> a > Sup X \<longleftrightarrow> (\<forall>x \<in> X. a > x)"
 16.1101 -  by (auto simp: cSup_eq_Max)
 16.1102 -
 16.1103  subsection \<open>Compactness\<close>
 16.1104  
 16.1105  subsubsection \<open>Bolzano-Weierstrass property\<close>
 16.1106 @@ -5428,11 +4440,6 @@
 16.1107    shows "compact(closure S) \<longleftrightarrow> bounded S"
 16.1108  by (meson bounded_closure bounded_subset closed_closure closure_subset compact_eq_bounded_closed)
 16.1109  
 16.1110 -lemma compact_components:
 16.1111 -  fixes s :: "'a::heine_borel set"
 16.1112 -  shows "\<lbrakk>compact s; c \<in> components s\<rbrakk> \<Longrightarrow> compact c"
 16.1113 -by (meson bounded_subset closed_components in_components_subset compact_eq_bounded_closed)
 16.1114 -
 16.1115  lemma not_compact_UNIV[simp]:
 16.1116    fixes s :: "'a::{real_normed_vector,perfect_space,heine_borel} set"
 16.1117    shows "~ compact (UNIV::'a set)"
 16.1118 @@ -5591,193 +4598,6 @@
 16.1119      using l r by fast
 16.1120  qed
 16.1121  
 16.1122 -subsubsection \<open>Intersecting chains of compact sets\<close>
 16.1123 -
 16.1124 -proposition bounded_closed_chain:
 16.1125 -  fixes \<F> :: "'a::heine_borel set set"
 16.1126 -  assumes "B \<in> \<F>" "bounded B" and \<F>: "\<And>S. S \<in> \<F> \<Longrightarrow> closed S" and "{} \<notin> \<F>"
 16.1127 -      and chain: "\<And>S T. S \<in> \<F> \<and> T \<in> \<F> \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
 16.1128 -    shows "\<Inter>\<F> \<noteq> {}"
 16.1129 -proof -
 16.1130 -  have "B \<inter> \<Inter>\<F> \<noteq> {}"
 16.1131 -  proof (rule compact_imp_fip)
 16.1132 -    show "compact B" "\<And>T. T \<in> \<F> \<Longrightarrow> closed T"
 16.1133 -      by (simp_all add: assms compact_eq_bounded_closed)
 16.1134 -    show "\<lbrakk>finite \<G>; \<G> \<subseteq> \<F>\<rbrakk> \<Longrightarrow> B \<inter> \<Inter>\<G> \<noteq> {}" for \<G>
 16.1135 -    proof (induction \<G> rule: finite_induct)
 16.1136 -      case empty
 16.1137 -      with assms show ?case by force
 16.1138 -    next
 16.1139 -      case (insert U \<G>)
 16.1140 -      then have "U \<in> \<F>" and ne: "B \<inter> \<Inter>\<G> \<noteq> {}" by auto
 16.1141 -      then consider "B \<subseteq> U" | "U \<subseteq> B"
 16.1142 -          using \<open>B \<in> \<F>\<close> chain by blast
 16.1143 -        then show ?case
 16.1144 -        proof cases
 16.1145 -          case 1
 16.1146 -          then show ?thesis
 16.1147 -            using Int_left_commute ne by auto
 16.1148 -        next
 16.1149 -          case 2
 16.1150 -          have "U \<noteq> {}"
 16.1151 -            using \<open>U \<in> \<F>\<close> \<open>{} \<notin> \<F>\<close> by blast
 16.1152 -          moreover
 16.1153 -          have False if "\<And>x. x \<in> U \<Longrightarrow> \<exists>Y\<in>\<G>. x \<notin> Y"
 16.1154 -          proof -
 16.1155 -            have "\<And>x. x \<in> U \<Longrightarrow> \<exists>Y\<in>\<G>. Y \<subseteq> U"
 16.1156 -              by (metis chain contra_subsetD insert.prems insert_subset that)
 16.1157 -            then obtain Y where "Y \<in> \<G>" "Y \<subseteq> U"
 16.1158 -              by (metis all_not_in_conv \<open>U \<noteq> {}\<close>)
 16.1159 -            moreover obtain x where "x \<in> \<Inter>\<G>"
 16.1160 -              by (metis Int_emptyI ne)
 16.1161 -            ultimately show ?thesis
 16.1162 -              by (metis Inf_lower subset_eq that)
 16.1163 -          qed
 16.1164 -          with 2 show ?thesis
 16.1165 -            by blast
 16.1166 -        qed
 16.1167 -      qed
 16.1168 -  qed
 16.1169 -  then show ?thesis by blast
 16.1170 -qed
 16.1171 -
 16.1172 -corollary compact_chain:
 16.1173 -  fixes \<F> :: "'a::heine_borel set set"
 16.1174 -  assumes "\<And>S. S \<in> \<F> \<Longrightarrow> compact S" "{} \<notin> \<F>"
 16.1175 -          "\<And>S T. S \<in> \<F> \<and> T \<in> \<F> \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
 16.1176 -    shows "\<Inter> \<F> \<noteq> {}"
 16.1177 -proof (cases "\<F> = {}")
 16.1178 -  case True
 16.1179 -  then show ?thesis by auto
 16.1180 -next
 16.1181 -  case False
 16.1182 -  show ?thesis
 16.1183 -    by (metis False all_not_in_conv assms compact_imp_bounded compact_imp_closed bounded_closed_chain)
 16.1184 -qed
 16.1185 -
 16.1186 -lemma compact_nest:
 16.1187 -  fixes F :: "'a::linorder \<Rightarrow> 'b::heine_borel set"
 16.1188 -  assumes F: "\<And>n. compact(F n)" "\<And>n. F n \<noteq> {}" and mono: "\<And>m n. m \<le> n \<Longrightarrow> F n \<subseteq> F m"
 16.1189 -  shows "\<Inter>range F \<noteq> {}"
 16.1190 -proof -
 16.1191 -  have *: "\<And>S T. S \<in> range F \<and> T \<in> range F \<Longrightarrow> S \<subseteq> T \<or> T \<subseteq> S"
 16.1192 -    by (metis mono image_iff le_cases)
 16.1193 -  show ?thesis
 16.1194 -    apply (rule compact_chain [OF _ _ *])
 16.1195 -    using F apply (blast intro: dest: *)+
 16.1196 -    done
 16.1197 -qed
 16.1198 -
 16.1199 -text\<open>The Baire property of dense sets\<close>
 16.1200 -theorem Baire:
 16.1201 -  fixes S::"'a::{real_normed_vector,heine_borel} set"
 16.1202 -  assumes "closed S" "countable \<G>"
 16.1203 -      and ope: "\<And>T. T \<in> \<G> \<Longrightarrow> openin (subtopology euclidean S) T \<and> S \<subseteq> closure T"
 16.1204 - shows "S \<subseteq> closure(\<Inter>\<G>)"
 16.1205 -proof (cases "\<G> = {}")
 16.1206 -  case True
 16.1207 -  then show ?thesis
 16.1208 -    using closure_subset by auto
 16.1209 -next
 16.1210 -  let ?g = "from_nat_into \<G>"
 16.1211 -  case False
 16.1212 -  then have gin: "?g n \<in> \<G>" for n
 16.1213 -    by (simp add: from_nat_into)
 16.1214 -  show ?thesis
 16.1215 -  proof (clarsimp simp: closure_approachable)
 16.1216 -    fix x and e::real
 16.1217 -    assume "x \<in> S" "0 < e"
 16.1218 -    obtain TF where opeF: "\<And>n. openin (subtopology euclidean S) (TF n)"
 16.1219 -               and ne: "\<And>n. TF n \<noteq> {}"
 16.1220 -               and subg: "\<And>n. S \<inter> closure(TF n) \<subseteq> ?g n"
 16.1221 -               and subball: "\<And>n. closure(TF n) \<subseteq> ball x e"
 16.1222 -               and decr: "\<And>n. TF(Suc n) \<subseteq> TF n"
 16.1223 -    proof -
 16.1224 -      have *: "\<exists>Y. (openin (subtopology euclidean S) Y \<and> Y \<noteq> {} \<and>
 16.1225 -                   S \<inter> closure Y \<subseteq> ?g n \<and> closure Y \<subseteq> ball x e) \<and> Y \<subseteq> U"
 16.1226 -        if opeU: "openin (subtopology euclidean S) U" and "U \<noteq> {}" and cloU: "closure U \<subseteq> ball x e" for U n
 16.1227 -      proof -
 16.1228 -        obtain T where T: "open T" "U = T \<inter> S"
 16.1229 -          using \<open>openin (subtopology euclidean S) U\<close> by (auto simp: openin_subtopology)
 16.1230 -        with \<open>U \<noteq> {}\<close> have "T \<inter> closure (?g n) \<noteq> {}"
 16.1231 -          using gin ope by fastforce
 16.1232 -        then have "T \<inter> ?g n \<noteq> {}"
 16.1233 -          using \<open>open T\<close> open_Int_closure_eq_empty by blast
 16.1234 -        then obtain y where "y \<in> U" "y \<in> ?g n"
 16.1235 -          using T ope [of "?g n", OF gin] by (blast dest:  openin_imp_subset)
 16.1236 -        moreover have "openin (subtopology euclidean S) (U \<inter> ?g n)"
 16.1237 -          using gin ope opeU by blast
 16.1238 -        ultimately obtain d where U: "U \<inter> ?g n \<subseteq> S" and "d > 0" and d: "ball y d \<inter> S \<subseteq> U \<inter> ?g n"
 16.1239 -          by (force simp: openin_contains_ball)
 16.1240 -        show ?thesis
 16.1241 -        proof (intro exI conjI)
 16.1242 -          show "openin (subtopology euclidean S) (S \<inter> ball y (d/2))"
 16.1243 -            by (simp add: openin_open_Int)
 16.1244 -          show "S \<inter> ball y (d/2) \<noteq> {}"
 16.1245 -            using \<open>0 < d\<close> \<open>y \<in> U\<close> opeU openin_imp_subset by fastforce
 16.1246 -          have "S \<inter> closure (S \<inter> ball y (d/2)) \<subseteq> S \<inter> closure (ball y (d/2))"
 16.1247 -            using closure_mono by blast
 16.1248 -          also have "... \<subseteq> ?g n"
 16.1249 -            using \<open>d > 0\<close> d by force
 16.1250 -          finally show "S \<inter> closure (S \<inter> ball y (d/2)) \<subseteq> ?g n" .
 16.1251 -          have "closure (S \<inter> ball y (d/2)) \<subseteq> S \<inter> ball y d"
 16.1252 -          proof -
 16.1253 -            have "closure (ball y (d/2)) \<subseteq> ball y d"
 16.1254 -              using \<open>d > 0\<close> by auto
 16.1255 -            then have "closure (S \<inter> ball y (d/2)) \<subseteq> ball y d"
 16.1256 -              by (meson closure_mono inf.cobounded2 subset_trans)
 16.1257 -            then show ?thesis
 16.1258 -              by (simp add: \<open>closed S\<close> closure_minimal)
 16.1259 -          qed
 16.1260 -          also have "...  \<subseteq> ball x e"
 16.1261 -            using cloU closure_subset d by blast
 16.1262 -          finally show "closure (S \<inter> ball y (d/2)) \<subseteq> ball x e" .
 16.1263 -          show "S \<inter> ball y (d/2) \<subseteq> U"
 16.1264 -            using ball_divide_subset_numeral d by blast
 16.1265 -        qed
 16.1266 -      q