merged
authorhaftmann
Mon Oct 26 09:03:57 2009 +0100 (2009-10-26)
changeset 33176d6936fd7cda8
parent 33174 1f2051f41335
parent 33175 2083bde13ce1
child 33177 edbd2c09176b
child 33178 70522979c7be
child 33184 de8cc01e8d9e
child 33189 82a40677c1f8
child 33201 e3d741e9d2fe
merged
src/HOL/IsaMakefile
src/HOL/Library/Convex_Euclidean_Space.thy
src/HOL/Library/Determinants.thy
src/HOL/Library/Euclidean_Space.thy
src/HOL/Library/Finite_Cartesian_Product.thy
src/HOL/Library/Library.thy
src/HOL/Library/Topology_Euclidean_Space.thy
     1.1 --- a/src/HOL/IsaMakefile	Mon Oct 26 08:54:20 2009 +0100
     1.2 +++ b/src/HOL/IsaMakefile	Mon Oct 26 09:03:57 2009 +0100
     1.3 @@ -323,15 +323,14 @@
     1.4  
     1.5  $(LOG)/HOL-Library.gz: $(OUT)/HOL Library/SetsAndFunctions.thy		\
     1.6    Library/Abstract_Rat.thy Library/BigO.thy Library/ContNotDenum.thy	\
     1.7 -  Library/Efficient_Nat.thy Library/Euclidean_Space.thy			\
     1.8 +  Library/Efficient_Nat.thy 			 			\
     1.9    Library/Sum_Of_Squares.thy Library/Sum_Of_Squares/sos_wrapper.ML	\
    1.10    Library/Sum_Of_Squares/sum_of_squares.ML Library/Fset.thy		\
    1.11 -  Library/Convex_Euclidean_Space.thy Library/Glbs.thy			\
    1.12 +  Library/Glbs.thy							\
    1.13    Library/normarith.ML Library/Executable_Set.thy			\
    1.14    Library/Infinite_Set.thy Library/FuncSet.thy				\
    1.15 -  Library/Permutations.thy Library/Determinants.thy Library/Bit.thy	\
    1.16 -  Library/Topology_Euclidean_Space.thy					\
    1.17 -  Library/Finite_Cartesian_Product.thy Library/FrechetDeriv.thy		\
    1.18 +  Library/Permutations.thy Library/Bit.thy				\
    1.19 +  Library/FrechetDeriv.thy		\
    1.20    Library/Fraction_Field.thy Library/Fundamental_Theorem_Algebra.thy	\
    1.21    Library/Inner_Product.thy Library/Kleene_Algebra.thy			\
    1.22    Library/Lattice_Syntax.thy			\
    1.23 @@ -1005,6 +1004,19 @@
    1.24  	@cd TLA; $(ISABELLE_TOOL) usedir $(OUT)/TLA Memory
    1.25  
    1.26  
    1.27 +## HOL-Multivariate_Analysis
    1.28 +
    1.29 +HOL-Multivariate_Analysis: HOL $(OUT)/HOL-Multivariate_Analysis
    1.30 +
    1.31 +$(OUT)/HOL-Multivariate_Analysis: $(OUT)/HOL Multivariate_Analysis/ROOT.ML \
    1.32 +  Multivariate_Analysis/Multivariate_Analysis.thy \
    1.33 +  Multivariate_Analysis/Determinants.thy \
    1.34 +  Multivariate_Analysis/Finite_Cartesian_Product.thy \
    1.35 +  Multivariate_Analysis/Euclidean_Space.thy \
    1.36 +  Multivariate_Analysis/Topology_Euclidean_Space.thy \
    1.37 +  Multivariate_Analysis/Convex_Euclidean_Space.thy
    1.38 +	@cd Multivariate_Analysis; $(ISABELLE_TOOL) usedir -b -g true $(OUT)/HOL HOL-Multivariate_Analysis
    1.39 +
    1.40  ## HOL-Nominal
    1.41  
    1.42  HOL-Nominal: HOL $(OUT)/HOL-Nominal
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/HOL/Library/#Topology_Euclidean_Space.thy#	Mon Oct 26 09:03:57 2009 +0100
     2.3 @@ -0,0 +1,6029 @@
     2.4 +(* Title:      Topology
     2.5 +   Author:     Amine Chaieb, University of Cambridge
     2.6 +   Author:     Robert Himmelmann, TU Muenchen
     2.7 +*)
     2.8 +
     2.9 +header {* Elementary topology in Euclidean space. *}
    2.10 +
    2.11 +theory Topology_Euclidean_Space
    2.12 +imports SEQ Euclidean_Space Product_Vector
    2.13 +begin
    2.14 +
    2.15 +declare fstcart_pastecart[simp] sndcart_pastecart[simp]
    2.16 +
    2.17 +subsection{* General notion of a topology *}
    2.18 +
    2.19 +definition "istopology L \<longleftrightarrow> {} \<in> L \<and> (\<forall>S \<in>L. \<forall>T \<in>L. S \<inter> T \<in> L) \<and> (\<forall>K. K \<subseteq>L \<longrightarrow> \<Union> K \<in> L)"
    2.20 +typedef (open) 'a topology = "{L::('a set) set. istopology L}"
    2.21 +  morphisms "openin" "topology"
    2.22 +  unfolding istopology_def by blast
    2.23 +
    2.24 +lemma istopology_open_in[intro]: "istopology(openin U)"
    2.25 +  using openin[of U] by blast
    2.26 +
    2.27 +lemma topology_inverse': "istopology U \<Longrightarrow> openin (topology U) = U"
    2.28 +  using topology_inverse[unfolded mem_def Collect_def] .
    2.29 +
    2.30 +lemma topology_inverse_iff: "istopology U \<longleftrightarrow> openin (topology U) = U"
    2.31 +  using topology_inverse[of U] istopology_open_in[of "topology U"] by auto
    2.32 +
    2.33 +lemma topology_eq: "T1 = T2 \<longleftrightarrow> (\<forall>S. openin T1 S \<longleftrightarrow> openin T2 S)"
    2.34 +proof-
    2.35 +  {assume "T1=T2" hence "\<forall>S. openin T1 S \<longleftrightarrow> openin T2 S" by simp}
    2.36 +  moreover
    2.37 +  {assume H: "\<forall>S. openin T1 S \<longleftrightarrow> openin T2 S"
    2.38 +    hence "openin T1 = openin T2" by (metis mem_def set_ext)
    2.39 +    hence "topology (openin T1) = topology (openin T2)" by simp
    2.40 +    hence "T1 = T2" unfolding openin_inverse .}
    2.41 +  ultimately show ?thesis by blast
    2.42 +qed
    2.43 +
    2.44 +text{* Infer the "universe" from union of all sets in the topology. *}
    2.45 +
    2.46 +definition "topspace T =  \<Union>{S. openin T S}"
    2.47 +
    2.48 +subsection{* Main properties of open sets *}
    2.49 +
    2.50 +lemma openin_clauses:
    2.51 +  fixes U :: "'a topology"
    2.52 +  shows "openin U {}"
    2.53 +  "\<And>S T. openin U S \<Longrightarrow> openin U T \<Longrightarrow> openin U (S\<inter>T)"
    2.54 +  "\<And>K. (\<forall>S \<in> K. openin U S) \<Longrightarrow> openin U (\<Union>K)"
    2.55 +  using openin[of U] unfolding istopology_def Collect_def mem_def
    2.56 +  by (metis mem_def subset_eq)+
    2.57 +
    2.58 +lemma openin_subset[intro]: "openin U S \<Longrightarrow> S \<subseteq> topspace U"
    2.59 +  unfolding topspace_def by blast
    2.60 +lemma openin_empty[simp]: "openin U {}" by (simp add: openin_clauses)
    2.61 +
    2.62 +lemma openin_Int[intro]: "openin U S \<Longrightarrow> openin U T \<Longrightarrow> openin U (S \<inter> T)"
    2.63 +  by (simp add: openin_clauses)
    2.64 +
    2.65 +lemma openin_Union[intro]: "(\<forall>S \<in>K. openin U S) \<Longrightarrow> openin U (\<Union> K)" by (simp add: openin_clauses)
    2.66 +
    2.67 +lemma openin_Un[intro]: "openin U S \<Longrightarrow> openin U T \<Longrightarrow> openin U (S \<union> T)"
    2.68 +  using openin_Union[of "{S,T}" U] by auto
    2.69 +
    2.70 +lemma openin_topspace[intro, simp]: "openin U (topspace U)" by (simp add: openin_Union topspace_def)
    2.71 +
    2.72 +lemma openin_subopen: "openin U S \<longleftrightarrow> (\<forall>x \<in> S. \<exists>T. openin U T \<and> x \<in> T \<and> T \<subseteq> S)" (is "?lhs \<longleftrightarrow> ?rhs")
    2.73 +proof-
    2.74 +  {assume ?lhs then have ?rhs by auto }
    2.75 +  moreover
    2.76 +  {assume H: ?rhs
    2.77 +    then obtain t where t: "\<forall>x\<in>S. openin U (t x) \<and> x \<in> t x \<and> t x \<subseteq> S"
    2.78 +      unfolding Ball_def ex_simps(6)[symmetric] choice_iff by blast
    2.79 +    from t have th0: "\<forall>x\<in> t`S. openin U x" by auto
    2.80 +    have "\<Union> t`S = S" using t by auto
    2.81 +    with openin_Union[OF th0] have "openin U S" by simp }
    2.82 +  ultimately show ?thesis by blast
    2.83 +qed
    2.84 +
    2.85 +subsection{* Closed sets *}
    2.86 +
    2.87 +definition "closedin U S \<longleftrightarrow> S \<subseteq> topspace U \<and> openin U (topspace U - S)"
    2.88 +
    2.89 +lemma closedin_subset: "closedin U S \<Longrightarrow> S \<subseteq> topspace U" by (metis closedin_def)
    2.90 +lemma closedin_empty[simp]: "closedin U {}" by (simp add: closedin_def)
    2.91 +lemma closedin_topspace[intro,simp]:
    2.92 +  "closedin U (topspace U)" by (simp add: closedin_def)
    2.93 +lemma closedin_Un[intro]: "closedin U S \<Longrightarrow> closedin U T \<Longrightarrow> closedin U (S \<union> T)"
    2.94 +  by (auto simp add: Diff_Un closedin_def)
    2.95 +
    2.96 +lemma Diff_Inter[intro]: "A - \<Inter>S = \<Union> {A - s|s. s\<in>S}" by auto
    2.97 +lemma closedin_Inter[intro]: assumes Ke: "K \<noteq> {}" and Kc: "\<forall>S \<in>K. closedin U S"
    2.98 +  shows "closedin U (\<Inter> K)"  using Ke Kc unfolding closedin_def Diff_Inter by auto
    2.99 +
   2.100 +lemma closedin_Int[intro]: "closedin U S \<Longrightarrow> closedin U T \<Longrightarrow> closedin U (S \<inter> T)"
   2.101 +  using closedin_Inter[of "{S,T}" U] by auto
   2.102 +
   2.103 +lemma Diff_Diff_Int: "A - (A - B) = A \<inter> B" by blast
   2.104 +lemma openin_closedin_eq: "openin U S \<longleftrightarrow> S \<subseteq> topspace U \<and> closedin U (topspace U - S)"
   2.105 +  apply (auto simp add: closedin_def)
   2.106 +  apply (metis openin_subset subset_eq)
   2.107 +  apply (auto simp add: Diff_Diff_Int)
   2.108 +  apply (subgoal_tac "topspace U \<inter> S = S")
   2.109 +  by auto
   2.110 +
   2.111 +lemma openin_closedin:  "S \<subseteq> topspace U \<Longrightarrow> (openin U S \<longleftrightarrow> closedin U (topspace U - S))"
   2.112 +  by (simp add: openin_closedin_eq)
   2.113 +
   2.114 +lemma openin_diff[intro]: assumes oS: "openin U S" and cT: "closedin U T" shows "openin U (S - T)"
   2.115 +proof-
   2.116 +  have "S - T = S \<inter> (topspace U - T)" using openin_subset[of U S]  oS cT
   2.117 +    by (auto simp add: topspace_def openin_subset)
   2.118 +  then show ?thesis using oS cT by (auto simp add: closedin_def)
   2.119 +qed
   2.120 +
   2.121 +lemma closedin_diff[intro]: assumes oS: "closedin U S" and cT: "openin U T" shows "closedin U (S - T)"
   2.122 +proof-
   2.123 +  have "S - T = S \<inter> (topspace U - T)" using closedin_subset[of U S]  oS cT
   2.124 +    by (auto simp add: topspace_def )
   2.125 +  then show ?thesis using oS cT by (auto simp add: openin_closedin_eq)
   2.126 +qed
   2.127 +
   2.128 +subsection{* Subspace topology. *}
   2.129 +
   2.130 +definition "subtopology U V = topology {S \<inter> V |S. openin U S}"
   2.131 +
   2.132 +lemma istopology_subtopology: "istopology {S \<inter> V |S. openin U S}" (is "istopology ?L")
   2.133 +proof-
   2.134 +  have "{} \<in> ?L" by blast
   2.135 +  {fix A B assume A: "A \<in> ?L" and B: "B \<in> ?L"
   2.136 +    from A B obtain Sa and Sb where Sa: "openin U Sa" "A = Sa \<inter> V" and Sb: "openin U Sb" "B = Sb \<inter> V" by blast
   2.137 +    have "A\<inter>B = (Sa \<inter> Sb) \<inter> V" "openin U (Sa \<inter> Sb)"  using Sa Sb by blast+
   2.138 +    then have "A \<inter> B \<in> ?L" by blast}
   2.139 +  moreover
   2.140 +  {fix K assume K: "K \<subseteq> ?L"
   2.141 +    have th0: "?L = (\<lambda>S. S \<inter> V) ` openin U "
   2.142 +      apply (rule set_ext)
   2.143 +      apply (simp add: Ball_def image_iff)
   2.144 +      by (metis mem_def)
   2.145 +    from K[unfolded th0 subset_image_iff]
   2.146 +    obtain Sk where Sk: "Sk \<subseteq> openin U" "K = (\<lambda>S. S \<inter> V) ` Sk" by blast
   2.147 +    have "\<Union>K = (\<Union>Sk) \<inter> V" using Sk by auto
   2.148 +    moreover have "openin U (\<Union> Sk)" using Sk by (auto simp add: subset_eq mem_def)
   2.149 +    ultimately have "\<Union>K \<in> ?L" by blast}
   2.150 +  ultimately show ?thesis unfolding istopology_def by blast
   2.151 +qed
   2.152 +
   2.153 +lemma openin_subtopology:
   2.154 +  "openin (subtopology U V) S \<longleftrightarrow> (\<exists> T. (openin U T) \<and> (S = T \<inter> V))"
   2.155 +  unfolding subtopology_def topology_inverse'[OF istopology_subtopology]
   2.156 +  by (auto simp add: Collect_def)
   2.157 +
   2.158 +lemma topspace_subtopology: "topspace(subtopology U V) = topspace U \<inter> V"
   2.159 +  by (auto simp add: topspace_def openin_subtopology)
   2.160 +
   2.161 +lemma closedin_subtopology:
   2.162 +  "closedin (subtopology U V) S \<longleftrightarrow> (\<exists>T. closedin U T \<and> S = T \<inter> V)"
   2.163 +  unfolding closedin_def topspace_subtopology
   2.164 +  apply (simp add: openin_subtopology)
   2.165 +  apply (rule iffI)
   2.166 +  apply clarify
   2.167 +  apply (rule_tac x="topspace U - T" in exI)
   2.168 +  by auto
   2.169 +
   2.170 +lemma openin_subtopology_refl: "openin (subtopology U V) V \<longleftrightarrow> V \<subseteq> topspace U"
   2.171 +  unfolding openin_subtopology
   2.172 +  apply (rule iffI, clarify)
   2.173 +  apply (frule openin_subset[of U])  apply blast
   2.174 +  apply (rule exI[where x="topspace U"])
   2.175 +  by auto
   2.176 +
   2.177 +lemma subtopology_superset: assumes UV: "topspace U \<subseteq> V"
   2.178 +  shows "subtopology U V = U"
   2.179 +proof-
   2.180 +  {fix S
   2.181 +    {fix T assume T: "openin U T" "S = T \<inter> V"
   2.182 +      from T openin_subset[OF T(1)] UV have eq: "S = T" by blast
   2.183 +      have "openin U S" unfolding eq using T by blast}
   2.184 +    moreover
   2.185 +    {assume S: "openin U S"
   2.186 +      hence "\<exists>T. openin U T \<and> S = T \<inter> V"
   2.187 +	using openin_subset[OF S] UV by auto}
   2.188 +    ultimately have "(\<exists>T. openin U T \<and> S = T \<inter> V) \<longleftrightarrow> openin U S" by blast}
   2.189 +  then show ?thesis unfolding topology_eq openin_subtopology by blast
   2.190 +qed
   2.191 +
   2.192 +
   2.193 +lemma subtopology_topspace[simp]: "subtopology U (topspace U) = U"
   2.194 +  by (simp add: subtopology_superset)
   2.195 +
   2.196 +lemma subtopology_UNIV[simp]: "subtopology U UNIV = U"
   2.197 +  by (simp add: subtopology_superset)
   2.198 +
   2.199 +subsection{* The universal Euclidean versions are what we use most of the time *}
   2.200 +
   2.201 +definition
   2.202 +  euclidean :: "'a::topological_space topology" where
   2.203 +  "euclidean = topology open"
   2.204 +
   2.205 +lemma open_openin: "open S \<longleftrightarrow> openin euclidean S"
   2.206 +  unfolding euclidean_def
   2.207 +  apply (rule cong[where x=S and y=S])
   2.208 +  apply (rule topology_inverse[symmetric])
   2.209 +  apply (auto simp add: istopology_def)
   2.210 +  by (auto simp add: mem_def subset_eq)
   2.211 +
   2.212 +lemma topspace_euclidean: "topspace euclidean = UNIV"
   2.213 +  apply (simp add: topspace_def)
   2.214 +  apply (rule set_ext)
   2.215 +  by (auto simp add: open_openin[symmetric])
   2.216 +
   2.217 +lemma topspace_euclidean_subtopology[simp]: "topspace (subtopology euclidean S) = S"
   2.218 +  by (simp add: topspace_euclidean topspace_subtopology)
   2.219 +
   2.220 +lemma closed_closedin: "closed S \<longleftrightarrow> closedin euclidean S"
   2.221 +  by (simp add: closed_def closedin_def topspace_euclidean open_openin Compl_eq_Diff_UNIV)
   2.222 +
   2.223 +lemma open_subopen: "open S \<longleftrightarrow> (\<forall>x\<in>S. \<exists>T. open T \<and> x \<in> T \<and> T \<subseteq> S)"
   2.224 +  by (simp add: open_openin openin_subopen[symmetric])
   2.225 +
   2.226 +subsection{* Open and closed balls. *}
   2.227 +
   2.228 +definition
   2.229 +  ball :: "'a::metric_space \<Rightarrow> real \<Rightarrow> 'a set" where
   2.230 +  "ball x e = {y. dist x y < e}"
   2.231 +
   2.232 +definition
   2.233 +  cball :: "'a::metric_space \<Rightarrow> real \<Rightarrow> 'a set" where
   2.234 +  "cball x e = {y. dist x y \<le> e}"
   2.235 +
   2.236 +lemma mem_ball[simp]: "y \<in> ball x e \<longleftrightarrow> dist x y < e" by (simp add: ball_def)
   2.237 +lemma mem_cball[simp]: "y \<in> cball x e \<longleftrightarrow> dist x y \<le> e" by (simp add: cball_def)
   2.238 +
   2.239 +lemma mem_ball_0 [simp]:
   2.240 +  fixes x :: "'a::real_normed_vecto"
   2.241 +  shows "x \<in> ball 0 e \<longleftrightarrow> norm x < e"
   2.242 +  by (simp add: dist_norm)
   2.243 +
   2.244 +lemma mem_cball_0 [simp]:
   2.245 +  fixes x :: "'a::real_normed_vector"
   2.246 +  shows "x \<in> cball 0 e \<longleftrightarrow> norm x \<le> e"
   2.247 +  by (simp add: dist_norm)
   2.248 +
   2.249 +lemma centre_in_cball[simp]: "x \<in> cball x e \<longleftrightarrow> 0\<le> e"  by simp
   2.250 +lemma ball_subset_cball[simp,intro]: "ball x e \<subseteq> cball x e" by (simp add: subset_eq)
   2.251 +lemma subset_ball[intro]: "d <= e ==> ball x d \<subseteq> ball x e" by (simp add: subset_eq)
   2.252 +lemma subset_cball[intro]: "d <= e ==> cball x d \<subseteq> cball x e" by (simp add: subset_eq)
   2.253 +lemma ball_max_Un: "ball a (max r s) = ball a r \<union> ball a s"
   2.254 +  by (simp add: expand_set_eq) arith
   2.255 +
   2.256 +lemma ball_min_Int: "ball a (min r s) = ball a r \<inter> ball a s"
   2.257 +  by (simp add: expand_set_eq)
   2.258 +
   2.259 +subsection{* Topological properties of open balls *}
   2.260 +
   2.261 +lemma diff_less_iff: "(a::real) - b > 0 \<longleftrightarrow> a > b"
   2.262 +  "(a::real) - b < 0 \<longleftrightarrow> a < b"
   2.263 +  "a - b < c \<longleftrightarrow> a < c +b" "a - b > c \<longleftrightarrow> a > c +b" by arith+
   2.264 +lemma diff_le_iff: "(a::real) - b \<ge> 0 \<longleftrightarrow> a \<ge> b" "(a::real) - b \<le> 0 \<longleftrightarrow> a \<le> b"
   2.265 +  "a - b \<le> c \<longleftrightarrow> a \<le> c +b" "a - b \<ge> c \<longleftrightarrow> a \<ge> c +b"  by arith+
   2.266 +
   2.267 +lemma open_ball[intro, simp]: "open (ball x e)"
   2.268 +  unfolding open_dist ball_def Collect_def Ball_def mem_def
   2.269 +  unfolding dist_commute
   2.270 +  apply clarify
   2.271 +  apply (rule_tac x="e - dist xa x" in exI)
   2.272 +  using dist_triangle_alt[where z=x]
   2.273 +  apply (clarsimp simp add: diff_less_iff)
   2.274 +  apply atomize
   2.275 +  apply (erule_tac x="y" in allE)
   2.276 +  apply (erule_tac x="xa" in allE)
   2.277 +  by arith
   2.278 +
   2.279 +lemma centre_in_ball[simp]: "x \<in> ball x e \<longleftrightarrow> e > 0" by (metis mem_ball dist_self)
   2.280 +lemma open_contains_ball: "open S \<longleftrightarrow> (\<forall>x\<in>S. \<exists>e>0. ball x e \<subseteq> S)"
   2.281 +  unfolding open_dist subset_eq mem_ball Ball_def dist_commute ..
   2.282 +
   2.283 +lemma open_contains_ball_eq: "open S \<Longrightarrow> \<forall>x. x\<in>S \<longleftrightarrow> (\<exists>e>0. ball x e \<subseteq> S)"
   2.284 +  by (metis open_contains_ball subset_eq centre_in_ball)
   2.285 +
   2.286 +lemma ball_eq_empty[simp]: "ball x e = {} \<longleftrightarrow> e \<le> 0"
   2.287 +  unfolding mem_ball expand_set_eq
   2.288 +  apply (simp add: not_less)
   2.289 +  by (metis zero_le_dist order_trans dist_self)
   2.290 +
   2.291 +lemma ball_empty[intro]: "e \<le> 0 ==> ball x e = {}" by simp
   2.292 +
   2.293 +subsection{* Basic "localization" results are handy for connectedness. *}
   2.294 +
   2.295 +lemma openin_open: "openin (subtopology euclidean U) S \<longleftrightarrow> (\<exists>T. open T \<and> (S = U \<inter> T))"
   2.296 +  by (auto simp add: openin_subtopology open_openin[symmetric])
   2.297 +
   2.298 +lemma openin_open_Int[intro]: "open S \<Longrightarrow> openin (subtopology euclidean U) (U \<inter> S)"
   2.299 +  by (auto simp add: openin_open)
   2.300 +
   2.301 +lemma open_openin_trans[trans]:
   2.302 + "open S \<Longrightarrow> open T \<Longrightarrow> T \<subseteq> S \<Longrightarrow> openin (subtopology euclidean S) T"
   2.303 +  by (metis Int_absorb1  openin_open_Int)
   2.304 +
   2.305 +lemma open_subset:  "S \<subseteq> T \<Longrightarrow> open S \<Longrightarrow> openin (subtopology euclidean T) S"
   2.306 +  by (auto simp add: openin_open)
   2.307 +
   2.308 +lemma closedin_closed: "closedin (subtopology euclidean U) S \<longleftrightarrow> (\<exists>T. closed T \<and> S = U \<inter> T)"
   2.309 +  by (simp add: closedin_subtopology closed_closedin Int_ac)
   2.310 +
   2.311 +lemma closedin_closed_Int: "closed S ==> closedin (subtopology euclidean U) (U \<inter> S)"
   2.312 +  by (metis closedin_closed)
   2.313 +
   2.314 +lemma closed_closedin_trans: "closed S \<Longrightarrow> closed T \<Longrightarrow> T \<subseteq> S \<Longrightarrow> closedin (subtopology euclidean S) T"
   2.315 +  apply (subgoal_tac "S \<inter> T = T" )
   2.316 +  apply auto
   2.317 +  apply (frule closedin_closed_Int[of T S])
   2.318 +  by simp
   2.319 +
   2.320 +lemma closed_subset: "S \<subseteq> T \<Longrightarrow> closed S \<Longrightarrow> closedin (subtopology euclidean T) S"
   2.321 +  by (auto simp add: closedin_closed)
   2.322 +
   2.323 +lemma openin_euclidean_subtopology_iff:
   2.324 +  fixes S U :: "'a::metric_space set"
   2.325 +  shows "openin (subtopology euclidean U) S
   2.326 +  \<longleftrightarrow> S \<subseteq> U \<and> (\<forall>x\<in>S. \<exists>e>0. \<forall>x'\<in>U. dist x' x < e \<longrightarrow> x'\<in> S)" (is "?lhs \<longleftrightarrow> ?rhs")
   2.327 +proof-
   2.328 +  {assume ?lhs hence ?rhs unfolding openin_subtopology open_openin[symmetric]
   2.329 +      by (simp add: open_dist) blast}
   2.330 +  moreover
   2.331 +  {assume SU: "S \<subseteq> U" and H: "\<And>x. x \<in> S \<Longrightarrow> \<exists>e>0. \<forall>x'\<in>U. dist x' x < e \<longrightarrow> x' \<in> S"
   2.332 +    from H obtain d where d: "\<And>x . x\<in> S \<Longrightarrow> d x > 0 \<and> (\<forall>x' \<in> U. dist x' x < d x \<longrightarrow> x' \<in> S)"
   2.333 +      by metis
   2.334 +    let ?T = "\<Union>{B. \<exists>x\<in>S. B = ball x (d x)}"
   2.335 +    have oT: "open ?T" by auto
   2.336 +    { fix x assume "x\<in>S"
   2.337 +      hence "x \<in> \<Union>{B. \<exists>x\<in>S. B = ball x (d x)}"
   2.338 +	apply simp apply(rule_tac x="ball x(d x)" in exI) apply auto
   2.339 +        by (rule d [THEN conjunct1])
   2.340 +      hence "x\<in> ?T \<inter> U" using SU and `x\<in>S` by auto  }
   2.341 +    moreover
   2.342 +    { fix y assume "y\<in>?T"
   2.343 +      then obtain B where "y\<in>B" "B\<in>{B. \<exists>x\<in>S. B = ball x (d x)}" by auto
   2.344 +      then obtain x where "x\<in>S" and x:"y \<in> ball x (d x)" by auto
   2.345 +      assume "y\<in>U"
   2.346 +      hence "y\<in>S" using d[OF `x\<in>S`] and x by(auto simp add: dist_commute) }
   2.347 +    ultimately have "S = ?T \<inter> U" by blast
   2.348 +    with oT have ?lhs unfolding openin_subtopology open_openin[symmetric] by blast}
   2.349 +  ultimately show ?thesis by blast
   2.350 +qed
   2.351 +
   2.352 +text{* These "transitivity" results are handy too. *}
   2.353 +
   2.354 +lemma openin_trans[trans]: "openin (subtopology euclidean T) S \<Longrightarrow> openin (subtopology euclidean U) T
   2.355 +  \<Longrightarrow> openin (subtopology euclidean U) S"
   2.356 +  unfolding open_openin openin_open by blast
   2.357 +
   2.358 +lemma openin_open_trans: "openin (subtopology euclidean T) S \<Longrightarrow> open T \<Longrightarrow> open S"
   2.359 +  by (auto simp add: openin_open intro: openin_trans)
   2.360 +
   2.361 +lemma closedin_trans[trans]:
   2.362 + "closedin (subtopology euclidean T) S \<Longrightarrow>
   2.363 +           closedin (subtopology euclidean U) T
   2.364 +           ==> closedin (subtopology euclidean U) S"
   2.365 +  by (auto simp add: closedin_closed closed_closedin closed_Inter Int_assoc)
   2.366 +
   2.367 +lemma closedin_closed_trans: "closedin (subtopology euclidean T) S \<Longrightarrow> closed T \<Longrightarrow> closed S"
   2.368 +  by (auto simp add: closedin_closed intro: closedin_trans)
   2.369 +
   2.370 +subsection{* Connectedness *}
   2.371 +
   2.372 +definition "connected S \<longleftrightarrow>
   2.373 +  ~(\<exists>e1 e2. open e1 \<and> open e2 \<and> S \<subseteq> (e1 \<union> e2) \<and> (e1 \<inter> e2 \<inter> S = {})
   2.374 +  \<and> ~(e1 \<inter> S = {}) \<and> ~(e2 \<inter> S = {}))"
   2.375 +
   2.376 +lemma connected_local:
   2.377 + "connected S \<longleftrightarrow> ~(\<exists>e1 e2.
   2.378 +                 openin (subtopology euclidean S) e1 \<and>
   2.379 +                 openin (subtopology euclidean S) e2 \<and>
   2.380 +                 S \<subseteq> e1 \<union> e2 \<and>
   2.381 +                 e1 \<inter> e2 = {} \<and>
   2.382 +                 ~(e1 = {}) \<and>
   2.383 +                 ~(e2 = {}))"
   2.384 +unfolding connected_def openin_open by (safe, blast+)
   2.385 +
   2.386 +lemma exists_diff: "(\<exists>S. P(UNIV - S)) \<longleftrightarrow> (\<exists>S. P S)" (is "?lhs \<longleftrightarrow> ?rhs")
   2.387 +proof-
   2.388 +
   2.389 +  {assume "?lhs" hence ?rhs by blast }
   2.390 +  moreover
   2.391 +  {fix S assume H: "P S"
   2.392 +    have "S = UNIV - (UNIV - S)" by auto
   2.393 +    with H have "P (UNIV - (UNIV - S))" by metis }
   2.394 +  ultimately show ?thesis by metis
   2.395 +qed
   2.396 +
   2.397 +lemma connected_clopen: "connected S \<longleftrightarrow>
   2.398 +        (\<forall>T. openin (subtopology euclidean S) T \<and>
   2.399 +            closedin (subtopology euclidean S) T \<longrightarrow> T = {} \<or> T = S)" (is "?lhs \<longleftrightarrow> ?rhs")
   2.400 +proof-
   2.401 +  have " \<not> connected S \<longleftrightarrow> (\<exists>e1 e2. open e1 \<and> open (UNIV - e2) \<and> S \<subseteq> e1 \<union> (UNIV - e2) \<and> e1 \<inter> (UNIV - e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (UNIV - e2) \<inter> S \<noteq> {})"
   2.402 +    unfolding connected_def openin_open closedin_closed
   2.403 +    apply (subst exists_diff) by blast
   2.404 +  hence th0: "connected S \<longleftrightarrow> \<not> (\<exists>e2 e1. closed e2 \<and> open e1 \<and> S \<subseteq> e1 \<union> (UNIV - e2) \<and> e1 \<inter> (UNIV - e2) \<inter> S = {} \<and> e1 \<inter> S \<noteq> {} \<and> (UNIV - e2) \<inter> S \<noteq> {})"
   2.405 +    (is " _ \<longleftrightarrow> \<not> (\<exists>e2 e1. ?P e2 e1)") apply (simp add: closed_def Compl_eq_Diff_UNIV) by metis
   2.406 +
   2.407 +  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'))"
   2.408 +    (is "_ \<longleftrightarrow> \<not> (\<exists>t' t. ?Q t' t)")
   2.409 +    unfolding connected_def openin_open closedin_closed by auto
   2.410 +  {fix e2
   2.411 +    {fix e1 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)"
   2.412 +	by auto}
   2.413 +    then have "(\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)" by metis}
   2.414 +  then have "\<forall>e2. (\<exists>e1. ?P e2 e1) \<longleftrightarrow> (\<exists>t. ?Q e2 t)" by blast
   2.415 +  then show ?thesis unfolding th0 th1 by simp
   2.416 +qed
   2.417 +
   2.418 +lemma connected_empty[simp, intro]: "connected {}"
   2.419 +  by (simp add: connected_def)
   2.420 +
   2.421 +subsection{* Hausdorff and other separation properties *}
   2.422 +
   2.423 +class t0_space =
   2.424 +  assumes t0_space: "x \<noteq> y \<Longrightarrow> \<exists>U. open U \<and> \<not> (x \<in> U \<longleftrightarrow> y \<in> U)"
   2.425 +
   2.426 +class t1_space =
   2.427 +  assumes t1_space: "x \<noteq> y \<Longrightarrow> \<exists>U V. open U \<and> open V \<and> x \<in> U \<and> y \<notin> U \<and> x \<notin> V \<and> y \<in> V"
   2.428 +begin
   2.429 +
   2.430 +subclass t0_space
   2.431 +proof
   2.432 +qed (fast dest: t1_space)
   2.433 +
   2.434 +end
   2.435 +
   2.436 +text {* T2 spaces are also known as Hausdorff spaces. *}
   2.437 +
   2.438 +class t2_space =
   2.439 +  assumes hausdorff: "x \<noteq> y \<Longrightarrow> \<exists>U V. open U \<and> open V \<and> x \<in> U \<and> y \<in> V \<and> U \<inter> V = {}"
   2.440 +begin
   2.441 +
   2.442 +subclass t1_space
   2.443 +proof
   2.444 +qed (fast dest: hausdorff)
   2.445 +
   2.446 +end
   2.447 +
   2.448 +instance metric_space \<subseteq> t2_space
   2.449 +proof
   2.450 +  fix x y :: "'a::metric_space"
   2.451 +  assume xy: "x \<noteq> y"
   2.452 +  let ?U = "ball x (dist x y / 2)"
   2.453 +  let ?V = "ball y (dist x y / 2)"
   2.454 +  have th0: "\<And>d x y z. (d x z :: real) <= d x y + d y z \<Longrightarrow> d y z = d z y
   2.455 +               ==> ~(d x y * 2 < d x z \<and> d z y * 2 < d x z)" by arith
   2.456 +  have "open ?U \<and> open ?V \<and> x \<in> ?U \<and> y \<in> ?V \<and> ?U \<inter> ?V = {}"
   2.457 +    using dist_pos_lt[OF xy] th0[of dist,OF dist_triangle dist_commute]
   2.458 +    by (auto simp add: expand_set_eq)
   2.459 +  then show "\<exists>U V. open U \<and> open V \<and> x \<in> U \<and> y \<in> V \<and> U \<inter> V = {}"
   2.460 +    by blast
   2.461 +qed
   2.462 +
   2.463 +lemma separation_t2:
   2.464 +  fixes x y :: "'a::t2_space"
   2.465 +  shows "x \<noteq> y \<longleftrightarrow> (\<exists>U V. open U \<and> open V \<and> x \<in> U \<and> y \<in> V \<and> U \<inter> V = {})"
   2.466 +  using hausdorff[of x y] by blast
   2.467 +
   2.468 +lemma separation_t1:
   2.469 +  fixes x y :: "'a::t1_space"
   2.470 +  shows "x \<noteq> y \<longleftrightarrow> (\<exists>U V. open U \<and> open V \<and> x \<in>U \<and> y\<notin> U \<and> x\<notin>V \<and> y\<in>V)"
   2.471 +  using t1_space[of x y] by blast
   2.472 +
   2.473 +lemma separation_t0:
   2.474 +  fixes x y :: "'a::t0_space"
   2.475 +  shows "x \<noteq> y \<longleftrightarrow> (\<exists>U. open U \<and> ~(x\<in>U \<longleftrightarrow> y\<in>U))"
   2.476 +  using t0_space[of x y] by blast
   2.477 +
   2.478 +subsection{* Limit points *}
   2.479 +
   2.480 +definition
   2.481 +  islimpt:: "'a::topological_space \<Rightarrow> 'a set \<Rightarrow> bool"
   2.482 +    (infixr "islimpt" 60) where
   2.483 +  "x islimpt S \<longleftrightarrow> (\<forall>T. x\<in>T \<longrightarrow> open T \<longrightarrow> (\<exists>y\<in>S. y\<in>T \<and> y\<noteq>x))"
   2.484 +
   2.485 +lemma islimptI:
   2.486 +  assumes "\<And>T. x \<in> T \<Longrightarrow> open T \<Longrightarrow> \<exists>y\<in>S. y \<in> T \<and> y \<noteq> x"
   2.487 +  shows "x islimpt S"
   2.488 +  using assms unfolding islimpt_def by auto
   2.489 +
   2.490 +lemma islimptE:
   2.491 +  assumes "x islimpt S" and "x \<in> T" and "open T"
   2.492 +  obtains y where "y \<in> S" and "y \<in> T" and "y \<noteq> x"
   2.493 +  using assms unfolding islimpt_def by auto
   2.494 +
   2.495 +lemma islimpt_subset: "x islimpt S \<Longrightarrow> S \<subseteq> T ==> x islimpt T" by (auto simp add: islimpt_def)
   2.496 +
   2.497 +lemma islimpt_approachable:
   2.498 +  fixes x :: "'a::metric_space"
   2.499 +  shows "x islimpt S \<longleftrightarrow> (\<forall>e>0. \<exists>x'\<in>S. x' \<noteq> x \<and> dist x' x < e)"
   2.500 +  unfolding islimpt_def
   2.501 +  apply auto
   2.502 +  apply(erule_tac x="ball x e" in allE)
   2.503 +  apply auto
   2.504 +  apply(rule_tac x=y in bexI)
   2.505 +  apply (auto simp add: dist_commute)
   2.506 +  apply (simp add: open_dist, drule (1) bspec)
   2.507 +  apply (clarify, drule spec, drule (1) mp, auto)
   2.508 +  done
   2.509 +
   2.510 +lemma islimpt_approachable_le:
   2.511 +  fixes x :: "'a::metric_space"
   2.512 +  shows "x islimpt S \<longleftrightarrow> (\<forall>e>0. \<exists>x'\<in> S. x' \<noteq> x \<and> dist x' x <= e)"
   2.513 +  unfolding islimpt_approachable
   2.514 +  using approachable_lt_le[where f="\<lambda>x'. dist x' x" and P="\<lambda>x'. \<not> (x'\<in>S \<and> x'\<noteq>x)"]
   2.515 +  by metis (* FIXME: VERY slow! *)
   2.516 +
   2.517 +class perfect_space =
   2.518 +  (* FIXME: perfect_space should inherit from topological_space *)
   2.519 +  assumes islimpt_UNIV [simp, intro]: "(x::'a::metric_space) islimpt UNIV"
   2.520 +
   2.521 +lemma perfect_choose_dist:
   2.522 +  fixes x :: "'a::perfect_space"
   2.523 +  shows "0 < r \<Longrightarrow> \<exists>a. a \<noteq> x \<and> dist a x < r"
   2.524 +using islimpt_UNIV [of x]
   2.525 +by (simp add: islimpt_approachable)
   2.526 +
   2.527 +instance real :: perfect_space
   2.528 +apply default
   2.529 +apply (rule islimpt_approachable [THEN iffD2])
   2.530 +apply (clarify, rule_tac x="x + e/2" in bexI)
   2.531 +apply (auto simp add: dist_norm)
   2.532 +done
   2.533 +
   2.534 +instance "^" :: (perfect_space, finite) perfect_space
   2.535 +proof
   2.536 +  fix x :: "'a ^ 'b"
   2.537 +  {
   2.538 +    fix e :: real assume "0 < e"
   2.539 +    def a \<equiv> "x $ arbitrary"
   2.540 +    have "a islimpt UNIV" by (rule islimpt_UNIV)
   2.541 +    with `0 < e` obtain b where "b \<noteq> a" and "dist b a < e"
   2.542 +      unfolding islimpt_approachable by auto
   2.543 +    def y \<equiv> "Cart_lambda ((Cart_nth x)(arbitrary := b))"
   2.544 +    from `b \<noteq> a` have "y \<noteq> x"
   2.545 +      unfolding a_def y_def by (simp add: Cart_eq)
   2.546 +    from `dist b a < e` have "dist y x < e"
   2.547 +      unfolding dist_vector_def a_def y_def
   2.548 +      apply simp
   2.549 +      apply (rule le_less_trans [OF setL2_le_setsum [OF zero_le_dist]])
   2.550 +      apply (subst setsum_diff1' [where a=arbitrary], simp, simp, simp)
   2.551 +      done
   2.552 +    from `y \<noteq> x` and `dist y x < e`
   2.553 +    have "\<exists>y\<in>UNIV. y \<noteq> x \<and> dist y x < e" by auto
   2.554 +  }
   2.555 +  then show "x islimpt UNIV" unfolding islimpt_approachable by blast
   2.556 +qed
   2.557 +
   2.558 +lemma closed_limpt: "closed S \<longleftrightarrow> (\<forall>x. x islimpt S \<longrightarrow> x \<in> S)"
   2.559 +  unfolding closed_def
   2.560 +  apply (subst open_subopen)
   2.561 +  apply (simp add: islimpt_def subset_eq Compl_eq_Diff_UNIV)
   2.562 +  by (metis DiffE DiffI UNIV_I insertCI insert_absorb mem_def)
   2.563 +
   2.564 +lemma islimpt_EMPTY[simp]: "\<not> x islimpt {}"
   2.565 +  unfolding islimpt_def by auto
   2.566 +
   2.567 +lemma closed_positive_orthant: "closed {x::real^'n::finite. \<forall>i. 0 \<le>x$i}"
   2.568 +proof-
   2.569 +  let ?U = "UNIV :: 'n set"
   2.570 +  let ?O = "{x::real^'n. \<forall>i. x$i\<ge>0}"
   2.571 +  {fix x:: "real^'n" and i::'n assume H: "\<forall>e>0. \<exists>x'\<in>?O. x' \<noteq> x \<and> dist x' x < e"
   2.572 +    and xi: "x$i < 0"
   2.573 +    from xi have th0: "-x$i > 0" by arith
   2.574 +    from H[rule_format, OF th0] obtain x' where x': "x' \<in>?O" "x' \<noteq> x" "dist x' x < -x $ i" by blast
   2.575 +      have th:" \<And>b a (x::real). abs x <= b \<Longrightarrow> b <= a ==> ~(a + x < 0)" by arith
   2.576 +      have th': "\<And>x (y::real). x < 0 \<Longrightarrow> 0 <= y ==> abs x <= abs (y - x)" by arith
   2.577 +      have th1: "\<bar>x$i\<bar> \<le> \<bar>(x' - x)$i\<bar>" using x'(1) xi
   2.578 +	apply (simp only: vector_component)
   2.579 +	by (rule th') auto
   2.580 +      have th2: "\<bar>dist x x'\<bar> \<ge> \<bar>(x' - x)$i\<bar>" using  component_le_norm[of "x'-x" i]
   2.581 +	apply (simp add: dist_norm) by norm
   2.582 +      from th[OF th1 th2] x'(3) have False by (simp add: dist_commute) }
   2.583 +  then show ?thesis unfolding closed_limpt islimpt_approachable
   2.584 +    unfolding not_le[symmetric] by blast
   2.585 +qed
   2.586 +
   2.587 +lemma finite_set_avoid:
   2.588 +  fixes a :: "'a::metric_space"
   2.589 +  assumes fS: "finite S" shows  "\<exists>d>0. \<forall>x\<in>S. x \<noteq> a \<longrightarrow> d <= dist a x"
   2.590 +proof(induct rule: finite_induct[OF fS])
   2.591 +  case 1 thus ?case apply auto by ferrack
   2.592 +next
   2.593 +  case (2 x F)
   2.594 +  from 2 obtain d where d: "d >0" "\<forall>x\<in>F. x\<noteq>a \<longrightarrow> d \<le> dist a x" by blast
   2.595 +  {assume "x = a" hence ?case using d by auto  }
   2.596 +  moreover
   2.597 +  {assume xa: "x\<noteq>a"
   2.598 +    let ?d = "min d (dist a x)"
   2.599 +    have dp: "?d > 0" using xa d(1) using dist_nz by auto
   2.600 +    from d have d': "\<forall>x\<in>F. x\<noteq>a \<longrightarrow> ?d \<le> dist a x" by auto
   2.601 +    with dp xa have ?case by(auto intro!: exI[where x="?d"]) }
   2.602 +  ultimately show ?case by blast
   2.603 +qed
   2.604 +
   2.605 +lemma islimpt_finite:
   2.606 +  fixes S :: "'a::metric_space set"
   2.607 +  assumes fS: "finite S" shows "\<not> a islimpt S"
   2.608 +  unfolding islimpt_approachable
   2.609 +  using finite_set_avoid[OF fS, of a] by (metis dist_commute  not_le)
   2.610 +
   2.611 +lemma islimpt_Un: "x islimpt (S \<union> T) \<longleftrightarrow> x islimpt S \<or> x islimpt T"
   2.612 +  apply (rule iffI)
   2.613 +  defer
   2.614 +  apply (metis Un_upper1 Un_upper2 islimpt_subset)
   2.615 +  unfolding islimpt_def
   2.616 +  apply (rule ccontr, clarsimp, rename_tac A B)
   2.617 +  apply (drule_tac x="A \<inter> B" in spec)
   2.618 +  apply (auto simp add: open_Int)
   2.619 +  done
   2.620 +
   2.621 +lemma discrete_imp_closed:
   2.622 +  fixes S :: "'a::metric_space set"
   2.623 +  assumes e: "0 < e" and d: "\<forall>x \<in> S. \<forall>y \<in> S. dist y x < e \<longrightarrow> y = x"
   2.624 +  shows "closed S"
   2.625 +proof-
   2.626 +  {fix x assume C: "\<forall>e>0. \<exists>x'\<in>S. x' \<noteq> x \<and> dist x' x < e"
   2.627 +    from e have e2: "e/2 > 0" by arith
   2.628 +    from C[rule_format, OF e2] obtain y where y: "y \<in> S" "y\<noteq>x" "dist y x < e/2" by blast
   2.629 +    let ?m = "min (e/2) (dist x y) "
   2.630 +    from e2 y(2) have mp: "?m > 0" by (simp add: dist_nz[THEN sym])
   2.631 +    from C[rule_format, OF mp] obtain z where z: "z \<in> S" "z\<noteq>x" "dist z x < ?m" by blast
   2.632 +    have th: "dist z y < e" using z y
   2.633 +      by (intro dist_triangle_lt [where z=x], simp)
   2.634 +    from d[rule_format, OF y(1) z(1) th] y z
   2.635 +    have False by (auto simp add: dist_commute)}
   2.636 +  then show ?thesis by (metis islimpt_approachable closed_limpt [where 'a='a])
   2.637 +qed
   2.638 +
   2.639 +subsection{* Interior of a Set *}
   2.640 +definition "interior S = {x. \<exists>T. open T \<and> x \<in> T \<and> T \<subseteq> S}"
   2.641 +
   2.642 +lemma interior_eq: "interior S = S \<longleftrightarrow> open S"
   2.643 +  apply (simp add: expand_set_eq interior_def)
   2.644 +  apply (subst (2) open_subopen) by (safe, blast+)
   2.645 +
   2.646 +lemma interior_open: "open S ==> (interior S = S)" by (metis interior_eq)
   2.647 +
   2.648 +lemma interior_empty[simp]: "interior {} = {}" by (simp add: interior_def)
   2.649 +
   2.650 +lemma open_interior[simp, intro]: "open(interior S)"
   2.651 +  apply (simp add: interior_def)
   2.652 +  apply (subst open_subopen) by blast
   2.653 +
   2.654 +lemma interior_interior[simp]: "interior(interior S) = interior S" by (metis interior_eq open_interior)
   2.655 +lemma interior_subset: "interior S \<subseteq> S" by (auto simp add: interior_def)
   2.656 +lemma subset_interior: "S \<subseteq> T ==> (interior S) \<subseteq> (interior T)" by (auto simp add: interior_def)
   2.657 +lemma interior_maximal: "T \<subseteq> S \<Longrightarrow> open T ==> T \<subseteq> (interior S)" by (auto simp add: interior_def)
   2.658 +lemma interior_unique: "T \<subseteq> S \<Longrightarrow> open T  \<Longrightarrow> (\<forall>T'. T' \<subseteq> S \<and> open T' \<longrightarrow> T' \<subseteq> T) \<Longrightarrow> interior S = T"
   2.659 +  by (metis equalityI interior_maximal interior_subset open_interior)
   2.660 +lemma mem_interior: "x \<in> interior S \<longleftrightarrow> (\<exists>e. 0 < e \<and> ball x e \<subseteq> S)"
   2.661 +  apply (simp add: interior_def)
   2.662 +  by (metis open_contains_ball centre_in_ball open_ball subset_trans)
   2.663 +
   2.664 +lemma open_subset_interior: "open S ==> S \<subseteq> interior T \<longleftrightarrow> S \<subseteq> T"
   2.665 +  by (metis interior_maximal interior_subset subset_trans)
   2.666 +
   2.667 +lemma interior_inter[simp]: "interior(S \<inter> T) = interior S \<inter> interior T"
   2.668 +  apply (rule equalityI, simp)
   2.669 +  apply (metis Int_lower1 Int_lower2 subset_interior)
   2.670 +  by (metis Int_mono interior_subset open_Int open_interior open_subset_interior)
   2.671 +
   2.672 +lemma interior_limit_point [intro]:
   2.673 +  fixes x :: "'a::perfect_space"
   2.674 +  assumes x: "x \<in> interior S" shows "x islimpt S"
   2.675 +proof-
   2.676 +  from x obtain e where e: "e>0" "\<forall>x'. dist x x' < e \<longrightarrow> x' \<in> S"
   2.677 +    unfolding mem_interior subset_eq Ball_def mem_ball by blast
   2.678 +  {
   2.679 +    fix d::real assume d: "d>0"
   2.680 +    let ?m = "min d e"
   2.681 +    have mde2: "0 < ?m" using e(1) d(1) by simp
   2.682 +    from perfect_choose_dist [OF mde2, of x]
   2.683 +    obtain y where "y \<noteq> x" and "dist y x < ?m" by blast
   2.684 +    then have "dist y x < e" "dist y x < d" by simp_all
   2.685 +    from `dist y x < e` e(2) have "y \<in> S" by (simp add: dist_commute)
   2.686 +    have "\<exists>x'\<in>S. x'\<noteq> x \<and> dist x' x < d"
   2.687 +      using `y \<in> S` `y \<noteq> x` `dist y x < d` by fast
   2.688 +  }
   2.689 +  then show ?thesis unfolding islimpt_approachable by blast
   2.690 +qed
   2.691 +
   2.692 +lemma interior_closed_Un_empty_interior:
   2.693 +  assumes cS: "closed S" and iT: "interior T = {}"
   2.694 +  shows "interior(S \<union> T) = interior S"
   2.695 +proof
   2.696 +  show "interior S \<subseteq> interior (S\<union>T)"
   2.697 +    by (rule subset_interior, blast)
   2.698 +next
   2.699 +  show "interior (S \<union> T) \<subseteq> interior S"
   2.700 +  proof
   2.701 +    fix x assume "x \<in> interior (S \<union> T)"
   2.702 +    then obtain R where "open R" "x \<in> R" "R \<subseteq> S \<union> T"
   2.703 +      unfolding interior_def by fast
   2.704 +    show "x \<in> interior S"
   2.705 +    proof (rule ccontr)
   2.706 +      assume "x \<notin> interior S"
   2.707 +      with `x \<in> R` `open R` obtain y where "y \<in> R - S"
   2.708 +        unfolding interior_def expand_set_eq by fast
   2.709 +      from `open R` `closed S` have "open (R - S)" by (rule open_Diff)
   2.710 +      from `R \<subseteq> S \<union> T` have "R - S \<subseteq> T" by fast
   2.711 +      from `y \<in> R - S` `open (R - S)` `R - S \<subseteq> T` `interior T = {}`
   2.712 +      show "False" unfolding interior_def by fast
   2.713 +    qed
   2.714 +  qed
   2.715 +qed
   2.716 +
   2.717 +
   2.718 +subsection{* Closure of a Set *}
   2.719 +
   2.720 +definition "closure S = S \<union> {x | x. x islimpt S}"
   2.721 +
   2.722 +lemma closure_interior: "closure S = UNIV - interior (UNIV - S)"
   2.723 +proof-
   2.724 +  { fix x
   2.725 +    have "x\<in>UNIV - interior (UNIV - S) \<longleftrightarrow> x \<in> closure S"  (is "?lhs = ?rhs")
   2.726 +    proof
   2.727 +      let ?exT = "\<lambda> y. (\<exists>T. open T \<and> y \<in> T \<and> T \<subseteq> UNIV - S)"
   2.728 +      assume "?lhs"
   2.729 +      hence *:"\<not> ?exT x"
   2.730 +	unfolding interior_def
   2.731 +	by simp
   2.732 +      { assume "\<not> ?rhs"
   2.733 +	hence False using *
   2.734 +	  unfolding closure_def islimpt_def
   2.735 +	  by blast
   2.736 +      }
   2.737 +      thus "?rhs"
   2.738 +	by blast
   2.739 +    next
   2.740 +      assume "?rhs" thus "?lhs"
   2.741 +	unfolding closure_def interior_def islimpt_def
   2.742 +	by blast
   2.743 +    qed
   2.744 +  }
   2.745 +  thus ?thesis
   2.746 +    by blast
   2.747 +qed
   2.748 +
   2.749 +lemma interior_closure: "interior S = UNIV - (closure (UNIV - S))"
   2.750 +proof-
   2.751 +  { fix x
   2.752 +    have "x \<in> interior S \<longleftrightarrow> x \<in> UNIV - (closure (UNIV - S))"
   2.753 +      unfolding interior_def closure_def islimpt_def
   2.754 +      by blast (* FIXME: VERY slow! *)
   2.755 +  }
   2.756 +  thus ?thesis
   2.757 +    by blast
   2.758 +qed
   2.759 +
   2.760 +lemma closed_closure[simp, intro]: "closed (closure S)"
   2.761 +proof-
   2.762 +  have "closed (UNIV - interior (UNIV -S))" by blast
   2.763 +  thus ?thesis using closure_interior[of S] by simp
   2.764 +qed
   2.765 +
   2.766 +lemma closure_hull: "closure S = closed hull S"
   2.767 +proof-
   2.768 +  have "S \<subseteq> closure S"
   2.769 +    unfolding closure_def
   2.770 +    by blast
   2.771 +  moreover
   2.772 +  have "closed (closure S)"
   2.773 +    using closed_closure[of S]
   2.774 +    by assumption
   2.775 +  moreover
   2.776 +  { fix t
   2.777 +    assume *:"S \<subseteq> t" "closed t"
   2.778 +    { fix x
   2.779 +      assume "x islimpt S"
   2.780 +      hence "x islimpt t" using *(1)
   2.781 +	using islimpt_subset[of x, of S, of t]
   2.782 +	by blast
   2.783 +    }
   2.784 +    with * have "closure S \<subseteq> t"
   2.785 +      unfolding closure_def
   2.786 +      using closed_limpt[of t]
   2.787 +      by auto
   2.788 +  }
   2.789 +  ultimately show ?thesis
   2.790 +    using hull_unique[of S, of "closure S", of closed]
   2.791 +    unfolding mem_def
   2.792 +    by simp
   2.793 +qed
   2.794 +
   2.795 +lemma closure_eq: "closure S = S \<longleftrightarrow> closed S"
   2.796 +  unfolding closure_hull
   2.797 +  using hull_eq[of closed, unfolded mem_def, OF  closed_Inter, of S]
   2.798 +  by (metis mem_def subset_eq)
   2.799 +
   2.800 +lemma closure_closed[simp]: "closed S \<Longrightarrow> closure S = S"
   2.801 +  using closure_eq[of S]
   2.802 +  by simp
   2.803 +
   2.804 +lemma closure_closure[simp]: "closure (closure S) = closure S"
   2.805 +  unfolding closure_hull
   2.806 +  using hull_hull[of closed S]
   2.807 +  by assumption
   2.808 +
   2.809 +lemma closure_subset: "S \<subseteq> closure S"
   2.810 +  unfolding closure_hull
   2.811 +  using hull_subset[of S closed]
   2.812 +  by assumption
   2.813 +
   2.814 +lemma subset_closure: "S \<subseteq> T \<Longrightarrow> closure S \<subseteq> closure T"
   2.815 +  unfolding closure_hull
   2.816 +  using hull_mono[of S T closed]
   2.817 +  by assumption
   2.818 +
   2.819 +lemma closure_minimal: "S \<subseteq> T \<Longrightarrow>  closed T \<Longrightarrow> closure S \<subseteq> T"
   2.820 +  using hull_minimal[of S T closed]
   2.821 +  unfolding closure_hull mem_def
   2.822 +  by simp
   2.823 +
   2.824 +lemma closure_unique: "S \<subseteq> T \<and> closed T \<and> (\<forall> T'. S \<subseteq> T' \<and> closed T' \<longrightarrow> T \<subseteq> T') \<Longrightarrow> closure S = T"
   2.825 +  using hull_unique[of S T closed]
   2.826 +  unfolding closure_hull mem_def
   2.827 +  by simp
   2.828 +
   2.829 +lemma closure_empty[simp]: "closure {} = {}"
   2.830 +  using closed_empty closure_closed[of "{}"]
   2.831 +  by simp
   2.832 +
   2.833 +lemma closure_univ[simp]: "closure UNIV = UNIV"
   2.834 +  using closure_closed[of UNIV]
   2.835 +  by simp
   2.836 +
   2.837 +lemma closure_eq_empty: "closure S = {} \<longleftrightarrow> S = {}"
   2.838 +  using closure_empty closure_subset[of S]
   2.839 +  by blast
   2.840 +
   2.841 +lemma closure_subset_eq: "closure S \<subseteq> S \<longleftrightarrow> closed S"
   2.842 +  using closure_eq[of S] closure_subset[of S]
   2.843 +  by simp
   2.844 +
   2.845 +lemma open_inter_closure_eq_empty:
   2.846 +  "open S \<Longrightarrow> (S \<inter> closure T) = {} \<longleftrightarrow> S \<inter> T = {}"
   2.847 +  using open_subset_interior[of S "UNIV - T"]
   2.848 +  using interior_subset[of "UNIV - T"]
   2.849 +  unfolding closure_interior
   2.850 +  by auto
   2.851 +
   2.852 +lemma open_inter_closure_subset:
   2.853 +  "open S \<Longrightarrow> (S \<inter> (closure T)) \<subseteq> closure(S \<inter> T)"
   2.854 +proof
   2.855 +  fix x
   2.856 +  assume as: "open S" "x \<in> S \<inter> closure T"
   2.857 +  { assume *:"x islimpt T"
   2.858 +    have "x islimpt (S \<inter> T)"
   2.859 +    proof (rule islimptI)
   2.860 +      fix A
   2.861 +      assume "x \<in> A" "open A"
   2.862 +      with as have "x \<in> A \<inter> S" "open (A \<inter> S)"
   2.863 +        by (simp_all add: open_Int)
   2.864 +      with * obtain y where "y \<in> T" "y \<in> A \<inter> S" "y \<noteq> x"
   2.865 +        by (rule islimptE)
   2.866 +      hence "y \<in> S \<inter> T" "y \<in> A \<and> y \<noteq> x"
   2.867 +        by simp_all
   2.868 +      thus "\<exists>y\<in>(S \<inter> T). y \<in> A \<and> y \<noteq> x" ..
   2.869 +    qed
   2.870 +  }
   2.871 +  then show "x \<in> closure (S \<inter> T)" using as
   2.872 +    unfolding closure_def
   2.873 +    by blast
   2.874 +qed
   2.875 +
   2.876 +lemma closure_complement: "closure(UNIV - S) = UNIV - interior(S)"
   2.877 +proof-
   2.878 +  have "S = UNIV - (UNIV - S)"
   2.879 +    by auto
   2.880 +  thus ?thesis
   2.881 +    unfolding closure_interior
   2.882 +    by auto
   2.883 +qed
   2.884 +
   2.885 +lemma interior_complement: "interior(UNIV - S) = UNIV - closure(S)"
   2.886 +  unfolding closure_interior
   2.887 +  by blast
   2.888 +
   2.889 +subsection{* Frontier (aka boundary) *}
   2.890 +
   2.891 +definition "frontier S = closure S - interior S"
   2.892 +
   2.893 +lemma frontier_closed: "closed(frontier S)"
   2.894 +  by (simp add: frontier_def closed_Diff)
   2.895 +
   2.896 +lemma frontier_closures: "frontier S = (closure S) \<inter> (closure(UNIV - S))"
   2.897 +  by (auto simp add: frontier_def interior_closure)
   2.898 +
   2.899 +lemma frontier_straddle:
   2.900 +  fixes a :: "'a::metric_space"
   2.901 +  shows "a \<in> frontier S \<longleftrightarrow> (\<forall>e>0. (\<exists>x\<in>S. dist a x < e) \<and> (\<exists>x. x \<notin> S \<and> dist a x < e))" (is "?lhs \<longleftrightarrow> ?rhs")
   2.902 +proof
   2.903 +  assume "?lhs"
   2.904 +  { fix e::real
   2.905 +    assume "e > 0"
   2.906 +    let ?rhse = "(\<exists>x\<in>S. dist a x < e) \<and> (\<exists>x. x \<notin> S \<and> dist a x < e)"
   2.907 +    { assume "a\<in>S"
   2.908 +      have "\<exists>x\<in>S. dist a x < e" using `e>0` `a\<in>S` by(rule_tac x=a in bexI) auto
   2.909 +      moreover have "\<exists>x. x \<notin> S \<and> dist a x < e" using `?lhs` `a\<in>S`
   2.910 +	unfolding frontier_closures closure_def islimpt_def using `e>0`
   2.911 +	by (auto, erule_tac x="ball a e" in allE, auto)
   2.912 +      ultimately have ?rhse by auto
   2.913 +    }
   2.914 +    moreover
   2.915 +    { assume "a\<notin>S"
   2.916 +      hence ?rhse using `?lhs`
   2.917 +	unfolding frontier_closures closure_def islimpt_def
   2.918 +	using open_ball[of a e] `e > 0`
   2.919 +	by (auto, erule_tac x = "ball a e" in allE, auto) (* FIXME: VERY slow! *)
   2.920 +    }
   2.921 +    ultimately have ?rhse by auto
   2.922 +  }
   2.923 +  thus ?rhs by auto
   2.924 +next
   2.925 +  assume ?rhs
   2.926 +  moreover
   2.927 +  { fix T assume "a\<notin>S" and
   2.928 +    as:"\<forall>e>0. (\<exists>x\<in>S. dist a x < e) \<and> (\<exists>x. x \<notin> S \<and> dist a x < e)" "a \<notin> S" "a \<in> T" "open T"
   2.929 +    from `open T` `a \<in> T` have "\<exists>e>0. ball a e \<subseteq> T" unfolding open_contains_ball[of T] by auto
   2.930 +    then obtain e where "e>0" "ball a e \<subseteq> T" by auto
   2.931 +    then obtain y where y:"y\<in>S" "dist a y < e"  using as(1) by auto
   2.932 +    have "\<exists>y\<in>S. y \<in> T \<and> y \<noteq> a"
   2.933 +      using `dist a y < e` `ball a e \<subseteq> T` unfolding ball_def using `y\<in>S` `a\<notin>S` by auto
   2.934 +  }
   2.935 +  hence "a \<in> closure S" unfolding closure_def islimpt_def using `?rhs` by auto
   2.936 +  moreover
   2.937 +  { fix T assume "a \<in> T"  "open T" "a\<in>S"
   2.938 +    then obtain e where "e>0" and balle: "ball a e \<subseteq> T" unfolding open_contains_ball using `?rhs` by auto
   2.939 +    obtain x where "x \<notin> S" "dist a x < e" using `?rhs` using `e>0` by auto
   2.940 +    hence "\<exists>y\<in>UNIV - S. y \<in> T \<and> y \<noteq> a" using balle `a\<in>S` unfolding ball_def by (rule_tac x=x in bexI)auto
   2.941 +  }
   2.942 +  hence "a islimpt (UNIV - S) \<or> a\<notin>S" unfolding islimpt_def by auto
   2.943 +  ultimately show ?lhs unfolding frontier_closures using closure_def[of "UNIV - S"] by auto
   2.944 +qed
   2.945 +
   2.946 +lemma frontier_subset_closed: "closed S \<Longrightarrow> frontier S \<subseteq> S"
   2.947 +  by (metis frontier_def closure_closed Diff_subset)
   2.948 +
   2.949 +lemma frontier_empty: "frontier {} = {}"
   2.950 +  by (simp add: frontier_def closure_empty)
   2.951 +
   2.952 +lemma frontier_subset_eq: "frontier S \<subseteq> S \<longleftrightarrow> closed S"
   2.953 +proof-
   2.954 +  { assume "frontier S \<subseteq> S"
   2.955 +    hence "closure S \<subseteq> S" using interior_subset unfolding frontier_def by auto
   2.956 +    hence "closed S" using closure_subset_eq by auto
   2.957 +  }
   2.958 +  thus ?thesis using frontier_subset_closed[of S] by auto
   2.959 +qed
   2.960 +
   2.961 +lemma frontier_complement: "frontier(UNIV - S) = frontier S"
   2.962 +  by (auto simp add: frontier_def closure_complement interior_complement)
   2.963 +
   2.964 +lemma frontier_disjoint_eq: "frontier S \<inter> S = {} \<longleftrightarrow> open S"
   2.965 +  using frontier_complement frontier_subset_eq[of "UNIV - S"]
   2.966 +  unfolding open_closed Compl_eq_Diff_UNIV by auto
   2.967 +
   2.968 +subsection{* Common nets and The "within" modifier for nets. *}
   2.969 +
   2.970 +definition
   2.971 +  at_infinity :: "'a::real_normed_vector net" where
   2.972 +  "at_infinity = Abs_net (range (\<lambda>r. {x. r \<le> norm x}))"
   2.973 +
   2.974 +definition
   2.975 +  indirection :: "'a::real_normed_vector \<Rightarrow> 'a \<Rightarrow> 'a net" (infixr "indirection" 70) where
   2.976 +  "a indirection v = (at a) within {b. \<exists>c\<ge>0. b - a = scaleR c v}"
   2.977 +
   2.978 +text{* Prove That They are all nets. *}
   2.979 +
   2.980 +lemma Rep_net_at_infinity:
   2.981 +  "Rep_net at_infinity = range (\<lambda>r. {x. r \<le> norm x})"
   2.982 +unfolding at_infinity_def
   2.983 +apply (rule Abs_net_inverse')
   2.984 +apply (rule image_nonempty, simp)
   2.985 +apply (clarsimp, rename_tac r s)
   2.986 +apply (rule_tac x="max r s" in exI, auto)
   2.987 +done
   2.988 +
   2.989 +lemma within_UNIV: "net within UNIV = net"
   2.990 +  by (simp add: Rep_net_inject [symmetric] Rep_net_within)
   2.991 +
   2.992 +subsection{* Identify Trivial limits, where we can't approach arbitrarily closely. *}
   2.993 +
   2.994 +definition
   2.995 +  trivial_limit :: "'a net \<Rightarrow> bool" where
   2.996 +  "trivial_limit net \<longleftrightarrow> {} \<in> Rep_net net"
   2.997 +
   2.998 +lemma trivial_limit_within:
   2.999 +  shows "trivial_limit (at a within S) \<longleftrightarrow> \<not> a islimpt S"
  2.1000 +proof
  2.1001 +  assume "trivial_limit (at a within S)"
  2.1002 +  thus "\<not> a islimpt S"
  2.1003 +    unfolding trivial_limit_def
  2.1004 +    unfolding Rep_net_within Rep_net_at
  2.1005 +    unfolding islimpt_def
  2.1006 +    apply (clarsimp simp add: expand_set_eq)
  2.1007 +    apply (rename_tac T, rule_tac x=T in exI)
  2.1008 +    apply (clarsimp, drule_tac x=y in spec, simp)
  2.1009 +    done
  2.1010 +next
  2.1011 +  assume "\<not> a islimpt S"
  2.1012 +  thus "trivial_limit (at a within S)"
  2.1013 +    unfolding trivial_limit_def
  2.1014 +    unfolding Rep_net_within Rep_net_at
  2.1015 +    unfolding islimpt_def
  2.1016 +    apply (clarsimp simp add: image_image)
  2.1017 +    apply (rule_tac x=T in image_eqI)
  2.1018 +    apply (auto simp add: expand_set_eq)
  2.1019 +    done
  2.1020 +qed
  2.1021 +
  2.1022 +lemma trivial_limit_at_iff: "trivial_limit (at a) \<longleftrightarrow> \<not> a islimpt UNIV"
  2.1023 +  using trivial_limit_within [of a UNIV]
  2.1024 +  by (simp add: within_UNIV)
  2.1025 +
  2.1026 +lemma trivial_limit_at:
  2.1027 +  fixes a :: "'a::perfect_space"
  2.1028 +  shows "\<not> trivial_limit (at a)"
  2.1029 +  by (simp add: trivial_limit_at_iff)
  2.1030 +
  2.1031 +lemma trivial_limit_at_infinity:
  2.1032 +  "\<not> trivial_limit (at_infinity :: ('a::{real_normed_vector,zero_neq_one}) net)"
  2.1033 +  (* FIXME: find a more appropriate type class *)
  2.1034 +  unfolding trivial_limit_def Rep_net_at_infinity
  2.1035 +  apply (clarsimp simp add: expand_set_eq)
  2.1036 +  apply (drule_tac x="scaleR r (sgn 1)" in spec)
  2.1037 +  apply (simp add: norm_sgn)
  2.1038 +  done
  2.1039 +
  2.1040 +lemma trivial_limit_sequentially: "\<not> trivial_limit sequentially"
  2.1041 +  by (auto simp add: trivial_limit_def Rep_net_sequentially)
  2.1042 +
  2.1043 +subsection{* Some property holds "sufficiently close" to the limit point. *}
  2.1044 +
  2.1045 +lemma eventually_at: (* FIXME: this replaces Limits.eventually_at *)
  2.1046 +  "eventually P (at a) \<longleftrightarrow> (\<exists>d>0. \<forall>x. 0 < dist x a \<and> dist x a < d \<longrightarrow> P x)"
  2.1047 +unfolding eventually_at dist_nz by auto
  2.1048 +
  2.1049 +lemma eventually_at_infinity:
  2.1050 +  "eventually P at_infinity \<longleftrightarrow> (\<exists>b. \<forall>x. norm x >= b \<longrightarrow> P x)"
  2.1051 +unfolding eventually_def Rep_net_at_infinity by auto
  2.1052 +
  2.1053 +lemma eventually_within: "eventually P (at a within S) \<longleftrightarrow>
  2.1054 +        (\<exists>d>0. \<forall>x\<in>S. 0 < dist x a \<and> dist x a < d \<longrightarrow> P x)"
  2.1055 +unfolding eventually_within eventually_at dist_nz by auto
  2.1056 +
  2.1057 +lemma eventually_within_le: "eventually P (at a within S) \<longleftrightarrow>
  2.1058 +        (\<exists>d>0. \<forall>x\<in>S. 0 < dist x a \<and> dist x a <= d \<longrightarrow> P x)" (is "?lhs = ?rhs")
  2.1059 +unfolding eventually_within
  2.1060 +apply safe
  2.1061 +apply (rule_tac x="d/2" in exI, simp)
  2.1062 +apply (rule_tac x="d" in exI, simp)
  2.1063 +done
  2.1064 +
  2.1065 +lemma eventually_happens: "eventually P net ==> trivial_limit net \<or> (\<exists>x. P x)"
  2.1066 +  unfolding eventually_def trivial_limit_def
  2.1067 +  using Rep_net_nonempty [of net] by auto
  2.1068 +
  2.1069 +lemma always_eventually: "(\<forall>x. P x) ==> eventually P net"
  2.1070 +  unfolding eventually_def trivial_limit_def
  2.1071 +  using Rep_net_nonempty [of net] by auto
  2.1072 +
  2.1073 +lemma trivial_limit_eventually: "trivial_limit net \<Longrightarrow> eventually P net"
  2.1074 +  unfolding trivial_limit_def eventually_def by auto
  2.1075 +
  2.1076 +lemma eventually_False: "eventually (\<lambda>x. False) net \<longleftrightarrow> trivial_limit net"
  2.1077 +  unfolding trivial_limit_def eventually_def by auto
  2.1078 +
  2.1079 +lemma trivial_limit_eq: "trivial_limit net \<longleftrightarrow> (\<forall>P. eventually P net)"
  2.1080 +  apply (safe elim!: trivial_limit_eventually)
  2.1081 +  apply (simp add: eventually_False [symmetric])
  2.1082 +  done
  2.1083 +
  2.1084 +text{* Combining theorems for "eventually" *}
  2.1085 +
  2.1086 +lemma eventually_conjI:
  2.1087 +  "\<lbrakk>eventually (\<lambda>x. P x) net; eventually (\<lambda>x. Q x) net\<rbrakk>
  2.1088 +    \<Longrightarrow> eventually (\<lambda>x. P x \<and> Q x) net"
  2.1089 +by (rule eventually_conj)
  2.1090 +
  2.1091 +lemma eventually_rev_mono:
  2.1092 +  "eventually P net \<Longrightarrow> (\<forall>x. P x \<longrightarrow> Q x) \<Longrightarrow> eventually Q net"
  2.1093 +using eventually_mono [of P Q] by fast
  2.1094 +
  2.1095 +lemma eventually_and: " eventually (\<lambda>x. P x \<and> Q x) net \<longleftrightarrow> eventually P net \<and> eventually Q net"
  2.1096 +  by (auto intro!: eventually_conjI elim: eventually_rev_mono)
  2.1097 +
  2.1098 +lemma eventually_false: "eventually (\<lambda>x. False) net \<longleftrightarrow> trivial_limit net"
  2.1099 +  by (auto simp add: eventually_False)
  2.1100 +
  2.1101 +lemma not_eventually: "(\<forall>x. \<not> P x ) \<Longrightarrow> ~(trivial_limit net) ==> ~(eventually (\<lambda>x. P x) net)"
  2.1102 +  by (simp add: eventually_False)
  2.1103 +
  2.1104 +subsection{* Limits, defined as vacuously true when the limit is trivial. *}
  2.1105 +
  2.1106 +  text{* Notation Lim to avoid collition with lim defined in analysis *}
  2.1107 +definition
  2.1108 +  Lim :: "'a net \<Rightarrow> ('a \<Rightarrow> 'b::t2_space) \<Rightarrow> 'b" where
  2.1109 +  "Lim net f = (THE l. (f ---> l) net)"
  2.1110 +
  2.1111 +lemma Lim:
  2.1112 + "(f ---> l) net \<longleftrightarrow>
  2.1113 +        trivial_limit net \<or>
  2.1114 +        (\<forall>e>0. eventually (\<lambda>x. dist (f x) l < e) net)"
  2.1115 +  unfolding tendsto_iff trivial_limit_eq by auto
  2.1116 +
  2.1117 +
  2.1118 +text{* Show that they yield usual definitions in the various cases. *}
  2.1119 +
  2.1120 +lemma Lim_within_le: "(f ---> l)(at a within S) \<longleftrightarrow>
  2.1121 +           (\<forall>e>0. \<exists>d>0. \<forall>x\<in>S. 0 < dist x a  \<and> dist x a  <= d \<longrightarrow> dist (f x) l < e)"
  2.1122 +  by (auto simp add: tendsto_iff eventually_within_le)
  2.1123 +
  2.1124 +lemma Lim_within: "(f ---> l) (at a within S) \<longleftrightarrow>
  2.1125 +        (\<forall>e >0. \<exists>d>0. \<forall>x \<in> S. 0 < dist x a  \<and> dist x a  < d  \<longrightarrow> dist (f x) l < e)"
  2.1126 +  by (auto simp add: tendsto_iff eventually_within)
  2.1127 +
  2.1128 +lemma Lim_at: "(f ---> l) (at a) \<longleftrightarrow>
  2.1129 +        (\<forall>e >0. \<exists>d>0. \<forall>x. 0 < dist x a  \<and> dist x a  < d  \<longrightarrow> dist (f x) l < e)"
  2.1130 +  by (auto simp add: tendsto_iff eventually_at)
  2.1131 +
  2.1132 +lemma Lim_at_iff_LIM: "(f ---> l) (at a) \<longleftrightarrow> f -- a --> l"
  2.1133 +  unfolding Lim_at LIM_def by (simp only: zero_less_dist_iff)
  2.1134 +
  2.1135 +lemma Lim_at_infinity:
  2.1136 +  "(f ---> l) at_infinity \<longleftrightarrow> (\<forall>e>0. \<exists>b. \<forall>x. norm x >= b \<longrightarrow> dist (f x) l < e)"
  2.1137 +  by (auto simp add: tendsto_iff eventually_at_infinity)
  2.1138 +
  2.1139 +lemma Lim_sequentially:
  2.1140 + "(S ---> l) sequentially \<longleftrightarrow>
  2.1141 +          (\<forall>e>0. \<exists>N. \<forall>n\<ge>N. dist (S n) l < e)"
  2.1142 +  by (auto simp add: tendsto_iff eventually_sequentially)
  2.1143 +
  2.1144 +lemma Lim_sequentially_iff_LIMSEQ: "(S ---> l) sequentially \<longleftrightarrow> S ----> l"
  2.1145 +  unfolding Lim_sequentially LIMSEQ_def ..
  2.1146 +
  2.1147 +lemma Lim_eventually: "eventually (\<lambda>x. f x = l) net \<Longrightarrow> (f ---> l) net"
  2.1148 +  by (rule topological_tendstoI, auto elim: eventually_rev_mono)
  2.1149 +
  2.1150 +text{* The expected monotonicity property. *}
  2.1151 +
  2.1152 +lemma Lim_within_empty: "(f ---> l) (net within {})"
  2.1153 +  unfolding tendsto_def Limits.eventually_within by simp
  2.1154 +
  2.1155 +lemma Lim_within_subset: "(f ---> l) (net within S) \<Longrightarrow> T \<subseteq> S \<Longrightarrow> (f ---> l) (net within T)"
  2.1156 +  unfolding tendsto_def Limits.eventually_within
  2.1157 +  by (auto elim!: eventually_elim1)
  2.1158 +
  2.1159 +lemma Lim_Un: assumes "(f ---> l) (net within S)" "(f ---> l) (net within T)"
  2.1160 +  shows "(f ---> l) (net within (S \<union> T))"
  2.1161 +  using assms unfolding tendsto_def Limits.eventually_within
  2.1162 +  apply clarify
  2.1163 +  apply (drule spec, drule (1) mp, drule (1) mp)
  2.1164 +  apply (drule spec, drule (1) mp, drule (1) mp)
  2.1165 +  apply (auto elim: eventually_elim2)
  2.1166 +  done
  2.1167 +
  2.1168 +lemma Lim_Un_univ:
  2.1169 + "(f ---> l) (net within S) \<Longrightarrow> (f ---> l) (net within T) \<Longrightarrow>  S \<union> T = UNIV
  2.1170 +        ==> (f ---> l) net"
  2.1171 +  by (metis Lim_Un within_UNIV)
  2.1172 +
  2.1173 +text{* Interrelations between restricted and unrestricted limits. *}
  2.1174 +
  2.1175 +lemma Lim_at_within: "(f ---> l) net ==> (f ---> l)(net within S)"
  2.1176 +  (* FIXME: rename *)
  2.1177 +  unfolding tendsto_def Limits.eventually_within
  2.1178 +  apply (clarify, drule spec, drule (1) mp, drule (1) mp)
  2.1179 +  by (auto elim!: eventually_elim1)
  2.1180 +
  2.1181 +lemma Lim_within_open:
  2.1182 +  fixes f :: "'a::topological_space \<Rightarrow> 'b::topological_space"
  2.1183 +  assumes"a \<in> S" "open S"
  2.1184 +  shows "(f ---> l)(at a within S) \<longleftrightarrow> (f ---> l)(at a)" (is "?lhs \<longleftrightarrow> ?rhs")
  2.1185 +proof
  2.1186 +  assume ?lhs
  2.1187 +  { fix A assume "open A" "l \<in> A"
  2.1188 +    with `?lhs` have "eventually (\<lambda>x. f x \<in> A) (at a within S)"
  2.1189 +      by (rule topological_tendstoD)
  2.1190 +    hence "eventually (\<lambda>x. x \<in> S \<longrightarrow> f x \<in> A) (at a)"
  2.1191 +      unfolding Limits.eventually_within .
  2.1192 +    then obtain T where "open T" "a \<in> T" "\<forall>x\<in>T. x \<noteq> a \<longrightarrow> x \<in> S \<longrightarrow> f x \<in> A"
  2.1193 +      unfolding eventually_at_topological by fast
  2.1194 +    hence "open (T \<inter> S)" "a \<in> T \<inter> S" "\<forall>x\<in>(T \<inter> S). x \<noteq> a \<longrightarrow> f x \<in> A"
  2.1195 +      using assms by auto
  2.1196 +    hence "\<exists>T. open T \<and> a \<in> T \<and> (\<forall>x\<in>T. x \<noteq> a \<longrightarrow> f x \<in> A)"
  2.1197 +      by fast
  2.1198 +    hence "eventually (\<lambda>x. f x \<in> A) (at a)"
  2.1199 +      unfolding eventually_at_topological .
  2.1200 +  }
  2.1201 +  thus ?rhs by (rule topological_tendstoI)
  2.1202 +next
  2.1203 +  assume ?rhs
  2.1204 +  thus ?lhs by (rule Lim_at_within)
  2.1205 +qed
  2.1206 +
  2.1207 +text{* Another limit point characterization. *}
  2.1208 +
  2.1209 +lemma islimpt_sequential:
  2.1210 +  fixes x :: "'a::metric_space" (* FIXME: generalize to topological_space *)
  2.1211 +  shows "x islimpt S \<longleftrightarrow> (\<exists>f. (\<forall>n::nat. f n \<in> S -{x}) \<and> (f ---> x) sequentially)"
  2.1212 +    (is "?lhs = ?rhs")
  2.1213 +proof
  2.1214 +  assume ?lhs
  2.1215 +  then obtain f where f:"\<forall>y. y>0 \<longrightarrow> f y \<in> S \<and> f y \<noteq> x \<and> dist (f y) x < y"
  2.1216 +    unfolding islimpt_approachable using choice[of "\<lambda>e y. e>0 \<longrightarrow> y\<in>S \<and> y\<noteq>x \<and> dist y x < e"] by auto
  2.1217 +  { fix n::nat
  2.1218 +    have "f (inverse (real n + 1)) \<in> S - {x}" using f by auto
  2.1219 +  }
  2.1220 +  moreover
  2.1221 +  { fix e::real assume "e>0"
  2.1222 +    hence "\<exists>N::nat. inverse (real (N + 1)) < e" using real_arch_inv[of e] apply (auto simp add: Suc_pred') apply(rule_tac x="n - 1" in exI) by auto
  2.1223 +    then obtain N::nat where "inverse (real (N + 1)) < e" by auto
  2.1224 +    hence "\<forall>n\<ge>N. inverse (real n + 1) < e" by (auto, metis Suc_le_mono le_SucE less_imp_inverse_less nat_le_real_less order_less_trans real_of_nat_Suc real_of_nat_Suc_gt_zero)
  2.1225 +    moreover have "\<forall>n\<ge>N. dist (f (inverse (real n + 1))) x < (inverse (real n + 1))" using f `e>0` by auto
  2.1226 +    ultimately have "\<exists>N::nat. \<forall>n\<ge>N. dist (f (inverse (real n + 1))) x < e" apply(rule_tac x=N in exI) apply auto apply(erule_tac x=n in allE)+ by auto
  2.1227 +  }
  2.1228 +  hence " ((\<lambda>n. f (inverse (real n + 1))) ---> x) sequentially"
  2.1229 +    unfolding Lim_sequentially using f by auto
  2.1230 +  ultimately show ?rhs apply (rule_tac x="(\<lambda>n::nat. f (inverse (real n + 1)))" in exI) by auto
  2.1231 +next
  2.1232 +  assume ?rhs
  2.1233 +  then obtain f::"nat\<Rightarrow>'a"  where f:"(\<forall>n. f n \<in> S - {x})" "(\<forall>e>0. \<exists>N. \<forall>n\<ge>N. dist (f n) x < e)" unfolding Lim_sequentially by auto
  2.1234 +  { fix e::real assume "e>0"
  2.1235 +    then obtain N where "dist (f N) x < e" using f(2) by auto
  2.1236 +    moreover have "f N\<in>S" "f N \<noteq> x" using f(1) by auto
  2.1237 +    ultimately have "\<exists>x'\<in>S. x' \<noteq> x \<and> dist x' x < e" by auto
  2.1238 +  }
  2.1239 +  thus ?lhs unfolding islimpt_approachable by auto
  2.1240 +qed
  2.1241 +
  2.1242 +text{* Basic arithmetical combining theorems for limits. *}
  2.1243 +
  2.1244 +lemma Lim_linear:
  2.1245 +  assumes "(f ---> l) net" "bounded_linear h"
  2.1246 +  shows "((\<lambda>x. h (f x)) ---> h l) net"
  2.1247 +using `bounded_linear h` `(f ---> l) net`
  2.1248 +by (rule bounded_linear.tendsto)
  2.1249 +
  2.1250 +lemma Lim_ident_at: "((\<lambda>x. x) ---> a) (at a)"
  2.1251 +  unfolding tendsto_def Limits.eventually_at_topological by fast
  2.1252 +
  2.1253 +lemma Lim_const: "((\<lambda>x. a) ---> a) net"
  2.1254 +  by (rule tendsto_const)
  2.1255 +
  2.1256 +lemma Lim_cmul:
  2.1257 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1258 +  shows "(f ---> l) net ==> ((\<lambda>x. c *\<^sub>R f x) ---> c *\<^sub>R l) net"
  2.1259 +  by (intro tendsto_intros)
  2.1260 +
  2.1261 +lemma Lim_neg:
  2.1262 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1263 +  shows "(f ---> l) net ==> ((\<lambda>x. -(f x)) ---> -l) net"
  2.1264 +  by (rule tendsto_minus)
  2.1265 +
  2.1266 +lemma Lim_add: fixes f :: "'a \<Rightarrow> 'b::real_normed_vector" shows
  2.1267 + "(f ---> l) net \<Longrightarrow> (g ---> m) net \<Longrightarrow> ((\<lambda>x. f(x) + g(x)) ---> l + m) net"
  2.1268 +  by (rule tendsto_add)
  2.1269 +
  2.1270 +lemma Lim_sub:
  2.1271 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1272 +  shows "(f ---> l) net \<Longrightarrow> (g ---> m) net \<Longrightarrow> ((\<lambda>x. f(x) - g(x)) ---> l - m) net"
  2.1273 +  by (rule tendsto_diff)
  2.1274 +
  2.1275 +lemma Lim_null:
  2.1276 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1277 +  shows "(f ---> l) net \<longleftrightarrow> ((\<lambda>x. f(x) - l) ---> 0) net" by (simp add: Lim dist_norm)
  2.1278 +
  2.1279 +lemma Lim_null_norm:
  2.1280 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1281 +  shows "(f ---> 0) net \<longleftrightarrow> ((\<lambda>x. norm(f x)) ---> 0) net"
  2.1282 +  by (simp add: Lim dist_norm)
  2.1283 +
  2.1284 +lemma Lim_null_comparison:
  2.1285 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1286 +  assumes "eventually (\<lambda>x. norm (f x) \<le> g x) net" "(g ---> 0) net"
  2.1287 +  shows "(f ---> 0) net"
  2.1288 +proof(simp add: tendsto_iff, rule+)
  2.1289 +  fix e::real assume "0<e"
  2.1290 +  { fix x
  2.1291 +    assume "norm (f x) \<le> g x" "dist (g x) 0 < e"
  2.1292 +    hence "dist (f x) 0 < e" by (simp add: dist_norm)
  2.1293 +  }
  2.1294 +  thus "eventually (\<lambda>x. dist (f x) 0 < e) net"
  2.1295 +    using eventually_and[of "\<lambda>x. norm(f x) <= g x" "\<lambda>x. dist (g x) 0 < e" net]
  2.1296 +    using eventually_mono[of "(\<lambda>x. norm (f x) \<le> g x \<and> dist (g x) 0 < e)" "(\<lambda>x. dist (f x) 0 < e)" net]
  2.1297 +    using assms `e>0` unfolding tendsto_iff by auto
  2.1298 +qed
  2.1299 +
  2.1300 +lemma Lim_component:
  2.1301 +  fixes f :: "'a \<Rightarrow> 'b::metric_space ^ 'n::finite"
  2.1302 +  shows "(f ---> l) net \<Longrightarrow> ((\<lambda>a. f a $i) ---> l$i) net"
  2.1303 +  unfolding tendsto_iff
  2.1304 +  apply (clarify)
  2.1305 +  apply (drule spec, drule (1) mp)
  2.1306 +  apply (erule eventually_elim1)
  2.1307 +  apply (erule le_less_trans [OF dist_nth_le])
  2.1308 +  done
  2.1309 +
  2.1310 +lemma Lim_transform_bound:
  2.1311 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1312 +  fixes g :: "'a \<Rightarrow> 'c::real_normed_vector"
  2.1313 +  assumes "eventually (\<lambda>n. norm(f n) <= norm(g n)) net"  "(g ---> 0) net"
  2.1314 +  shows "(f ---> 0) net"
  2.1315 +proof (rule tendstoI)
  2.1316 +  fix e::real assume "e>0"
  2.1317 +  { fix x
  2.1318 +    assume "norm (f x) \<le> norm (g x)" "dist (g x) 0 < e"
  2.1319 +    hence "dist (f x) 0 < e" by (simp add: dist_norm)}
  2.1320 +  thus "eventually (\<lambda>x. dist (f x) 0 < e) net"
  2.1321 +    using eventually_and[of "\<lambda>x. norm (f x) \<le> norm (g x)" "\<lambda>x. dist (g x) 0 < e" net]
  2.1322 +    using eventually_mono[of "\<lambda>x. norm (f x) \<le> norm (g x) \<and> dist (g x) 0 < e" "\<lambda>x. dist (f x) 0 < e" net]
  2.1323 +    using assms `e>0` unfolding tendsto_iff by blast
  2.1324 +qed
  2.1325 +
  2.1326 +text{* Deducing things about the limit from the elements. *}
  2.1327 +
  2.1328 +lemma Lim_in_closed_set:
  2.1329 +  assumes "closed S" "eventually (\<lambda>x. f(x) \<in> S) net" "\<not>(trivial_limit net)" "(f ---> l) net"
  2.1330 +  shows "l \<in> S"
  2.1331 +proof (rule ccontr)
  2.1332 +  assume "l \<notin> S"
  2.1333 +  with `closed S` have "open (- S)" "l \<in> - S"
  2.1334 +    by (simp_all add: open_Compl)
  2.1335 +  with assms(4) have "eventually (\<lambda>x. f x \<in> - S) net"
  2.1336 +    by (rule topological_tendstoD)
  2.1337 +  with assms(2) have "eventually (\<lambda>x. False) net"
  2.1338 +    by (rule eventually_elim2) simp
  2.1339 +  with assms(3) show "False"
  2.1340 +    by (simp add: eventually_False)
  2.1341 +qed
  2.1342 +
  2.1343 +text{* Need to prove closed(cball(x,e)) before deducing this as a corollary. *}
  2.1344 +
  2.1345 +lemma Lim_dist_ubound:
  2.1346 +  assumes "\<not>(trivial_limit net)" "(f ---> l) net" "eventually (\<lambda>x. dist a (f x) <= e) net"
  2.1347 +  shows "dist a l <= e"
  2.1348 +proof (rule ccontr)
  2.1349 +  assume "\<not> dist a l \<le> e"
  2.1350 +  then have "0 < dist a l - e" by simp
  2.1351 +  with assms(2) have "eventually (\<lambda>x. dist (f x) l < dist a l - e) net"
  2.1352 +    by (rule tendstoD)
  2.1353 +  with assms(3) have "eventually (\<lambda>x. dist a (f x) \<le> e \<and> dist (f x) l < dist a l - e) net"
  2.1354 +    by (rule eventually_conjI)
  2.1355 +  then obtain w where "dist a (f w) \<le> e" "dist (f w) l < dist a l - e"
  2.1356 +    using assms(1) eventually_happens by auto
  2.1357 +  hence "dist a (f w) + dist (f w) l < e + (dist a l - e)"
  2.1358 +    by (rule add_le_less_mono)
  2.1359 +  hence "dist a (f w) + dist (f w) l < dist a l"
  2.1360 +    by simp
  2.1361 +  also have "\<dots> \<le> dist a (f w) + dist (f w) l"
  2.1362 +    by (rule dist_triangle)
  2.1363 +  finally show False by simp
  2.1364 +qed
  2.1365 +
  2.1366 +lemma Lim_norm_ubound:
  2.1367 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1368 +  assumes "\<not>(trivial_limit net)" "(f ---> l) net" "eventually (\<lambda>x. norm(f x) <= e) net"
  2.1369 +  shows "norm(l) <= e"
  2.1370 +proof (rule ccontr)
  2.1371 +  assume "\<not> norm l \<le> e"
  2.1372 +  then have "0 < norm l - e" by simp
  2.1373 +  with assms(2) have "eventually (\<lambda>x. dist (f x) l < norm l - e) net"
  2.1374 +    by (rule tendstoD)
  2.1375 +  with assms(3) have "eventually (\<lambda>x. norm (f x) \<le> e \<and> dist (f x) l < norm l - e) net"
  2.1376 +    by (rule eventually_conjI)
  2.1377 +  then obtain w where "norm (f w) \<le> e" "dist (f w) l < norm l - e"
  2.1378 +    using assms(1) eventually_happens by auto
  2.1379 +  hence "norm (f w - l) < norm l - e" "norm (f w) \<le> e" by (simp_all add: dist_norm)
  2.1380 +  hence "norm (f w - l) + norm (f w) < norm l" by simp
  2.1381 +  hence "norm (f w - l - f w) < norm l" by (rule le_less_trans [OF norm_triangle_ineq4])
  2.1382 +  thus False using `\<not> norm l \<le> e` by simp
  2.1383 +qed
  2.1384 +
  2.1385 +lemma Lim_norm_lbound:
  2.1386 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.1387 +  assumes "\<not> (trivial_limit net)"  "(f ---> l) net"  "eventually (\<lambda>x. e <= norm(f x)) net"
  2.1388 +  shows "e \<le> norm l"
  2.1389 +proof (rule ccontr)
  2.1390 +  assume "\<not> e \<le> norm l"
  2.1391 +  then have "0 < e - norm l" by simp
  2.1392 +  with assms(2) have "eventually (\<lambda>x. dist (f x) l < e - norm l) net"
  2.1393 +    by (rule tendstoD)
  2.1394 +  with assms(3) have "eventually (\<lambda>x. e \<le> norm (f x) \<and> dist (f x) l < e - norm l) net"
  2.1395 +    by (rule eventually_conjI)
  2.1396 +  then obtain w where "e \<le> norm (f w)" "dist (f w) l < e - norm l"
  2.1397 +    using assms(1) eventually_happens by auto
  2.1398 +  hence "norm (f w - l) + norm l < e" "e \<le> norm (f w)" by (simp_all add: dist_norm)
  2.1399 +  hence "norm (f w - l) + norm l < norm (f w)" by (rule less_le_trans)
  2.1400 +  hence "norm (f w - l + l) < norm (f w)" by (rule le_less_trans [OF norm_triangle_ineq])
  2.1401 +  thus False by simp
  2.1402 +qed
  2.1403 +
  2.1404 +text{* Uniqueness of the limit, when nontrivial. *}
  2.1405 +
  2.1406 +lemma Lim_unique:
  2.1407 +  fixes f :: "'a \<Rightarrow> 'b::t2_space"
  2.1408 +  assumes "\<not> trivial_limit net"  "(f ---> l) net"  "(f ---> l') net"
  2.1409 +  shows "l = l'"
  2.1410 +proof (rule ccontr)
  2.1411 +  assume "l \<noteq> l'"
  2.1412 +  obtain U V where "open U" "open V" "l \<in> U" "l' \<in> V" "U \<inter> V = {}"
  2.1413 +    using hausdorff [OF `l \<noteq> l'`] by fast
  2.1414 +  have "eventually (\<lambda>x. f x \<in> U) net"
  2.1415 +    using `(f ---> l) net` `open U` `l \<in> U` by (rule topological_tendstoD)
  2.1416 +  moreover
  2.1417 +  have "eventually (\<lambda>x. f x \<in> V) net"
  2.1418 +    using `(f ---> l') net` `open V` `l' \<in> V` by (rule topological_tendstoD)
  2.1419 +  ultimately
  2.1420 +  have "eventually (\<lambda>x. False) net"
  2.1421 +  proof (rule eventually_elim2)
  2.1422 +    fix x
  2.1423 +    assume "f x \<in> U" "f x \<in> V"
  2.1424 +    hence "f x \<in> U \<inter> V" by simp
  2.1425 +    with `U \<inter> V = {}` show "False" by simp
  2.1426 +  qed
  2.1427 +  with `\<not> trivial_limit net` show "False"
  2.1428 +    by (simp add: eventually_False)
  2.1429 +qed
  2.1430 +
  2.1431 +lemma tendsto_Lim:
  2.1432 +  fixes f :: "'a \<Rightarrow> 'b::t2_space"
  2.1433 +  shows "~(trivial_limit net) \<Longrightarrow> (f ---> l) net ==> Lim net f = l"
  2.1434 +  unfolding Lim_def using Lim_unique[of net f] by auto
  2.1435 +
  2.1436 +text{* Limit under bilinear function *}
  2.1437 +
  2.1438 +lemma Lim_bilinear:
  2.1439 +  assumes "(f ---> l) net" and "(g ---> m) net" and "bounded_bilinear h"
  2.1440 +  shows "((\<lambda>x. h (f x) (g x)) ---> (h l m)) net"
  2.1441 +using `bounded_bilinear h` `(f ---> l) net` `(g ---> m) net`
  2.1442 +by (rule bounded_bilinear.tendsto)
  2.1443 +
  2.1444 +text{* These are special for limits out of the same vector space. *}
  2.1445 +
  2.1446 +lemma Lim_within_id: "(id ---> a) (at a within s)"
  2.1447 +  unfolding tendsto_def Limits.eventually_within eventually_at_topological
  2.1448 +  by auto
  2.1449 +
  2.1450 +lemma Lim_at_id: "(id ---> a) (at a)"
  2.1451 +apply (subst within_UNIV[symmetric]) by (simp add: Lim_within_id)
  2.1452 +
  2.1453 +lemma Lim_at_zero:
  2.1454 +  fixes a :: "'a::real_normed_vector"
  2.1455 +  fixes l :: "'b::topological_space"
  2.1456 +  shows "(f ---> l) (at a) \<longleftrightarrow> ((\<lambda>x. f(a + x)) ---> l) (at 0)" (is "?lhs = ?rhs")
  2.1457 +proof
  2.1458 +  assume "?lhs"
  2.1459 +  { fix S assume "open S" "l \<in> S"
  2.1460 +    with `?lhs` have "eventually (\<lambda>x. f x \<in> S) (at a)"
  2.1461 +      by (rule topological_tendstoD)
  2.1462 +    then obtain d where d: "d>0" "\<forall>x. x \<noteq> a \<and> dist x a < d \<longrightarrow> f x \<in> S"
  2.1463 +      unfolding Limits.eventually_at by fast
  2.1464 +    { fix x::"'a" assume "x \<noteq> 0 \<and> dist x 0 < d"
  2.1465 +      hence "f (a + x) \<in> S" using d
  2.1466 +      apply(erule_tac x="x+a" in allE)
  2.1467 +      by(auto simp add: comm_monoid_add.mult_commute dist_norm dist_commute)
  2.1468 +    }
  2.1469 +    hence "\<exists>d>0. \<forall>x. x \<noteq> 0 \<and> dist x 0 < d \<longrightarrow> f (a + x) \<in> S"
  2.1470 +      using d(1) by auto
  2.1471 +    hence "eventually (\<lambda>x. f (a + x) \<in> S) (at 0)"
  2.1472 +      unfolding Limits.eventually_at .
  2.1473 +  }
  2.1474 +  thus "?rhs" by (rule topological_tendstoI)
  2.1475 +next
  2.1476 +  assume "?rhs"
  2.1477 +  { fix S assume "open S" "l \<in> S"
  2.1478 +    with `?rhs` have "eventually (\<lambda>x. f (a + x) \<in> S) (at 0)"
  2.1479 +      by (rule topological_tendstoD)
  2.1480 +    then obtain d where d: "d>0" "\<forall>x. x \<noteq> 0 \<and> dist x 0 < d \<longrightarrow> f (a + x) \<in> S"
  2.1481 +      unfolding Limits.eventually_at by fast
  2.1482 +    { fix x::"'a" assume "x \<noteq> a \<and> dist x a < d"
  2.1483 +      hence "f x \<in> S" using d apply(erule_tac x="x-a" in allE)
  2.1484 +	by(auto simp add: comm_monoid_add.mult_commute dist_norm dist_commute)
  2.1485 +    }
  2.1486 +    hence "\<exists>d>0. \<forall>x. x \<noteq> a \<and> dist x a < d \<longrightarrow> f x \<in> S" using d(1) by auto
  2.1487 +    hence "eventually (\<lambda>x. f x \<in> S) (at a)" unfolding Limits.eventually_at .
  2.1488 +  }
  2.1489 +  thus "?lhs" by (rule topological_tendstoI)
  2.1490 +qed
  2.1491 +
  2.1492 +text{* It's also sometimes useful to extract the limit point from the net.  *}
  2.1493 +
  2.1494 +definition
  2.1495 +  netlimit :: "'a::t2_space net \<Rightarrow> 'a" where
  2.1496 +  "netlimit net = (SOME a. ((\<lambda>x. x) ---> a) net)"
  2.1497 +
  2.1498 +lemma netlimit_within:
  2.1499 +  assumes "\<not> trivial_limit (at a within S)"
  2.1500 +  shows "netlimit (at a within S) = a"
  2.1501 +unfolding netlimit_def
  2.1502 +apply (rule some_equality)
  2.1503 +apply (rule Lim_at_within)
  2.1504 +apply (rule Lim_ident_at)
  2.1505 +apply (erule Lim_unique [OF assms])
  2.1506 +apply (rule Lim_at_within)
  2.1507 +apply (rule Lim_ident_at)
  2.1508 +done
  2.1509 +
  2.1510 +lemma netlimit_at:
  2.1511 +  fixes a :: "'a::perfect_space"
  2.1512 +  shows "netlimit (at a) = a"
  2.1513 +  apply (subst within_UNIV[symmetric])
  2.1514 +  using netlimit_within[of a UNIV]
  2.1515 +  by (simp add: trivial_limit_at within_UNIV)
  2.1516 +
  2.1517 +text{* Transformation of limit. *}
  2.1518 +
  2.1519 +lemma Lim_transform:
  2.1520 +  fixes f g :: "'a::type \<Rightarrow> 'b::real_normed_vector"
  2.1521 +  assumes "((\<lambda>x. f x - g x) ---> 0) net" "(f ---> l) net"
  2.1522 +  shows "(g ---> l) net"
  2.1523 +proof-
  2.1524 +  from assms have "((\<lambda>x. f x - g x - f x) ---> 0 - l) net" using Lim_sub[of "\<lambda>x. f x - g x" 0 net f l] by auto
  2.1525 +  thus "?thesis" using Lim_neg [of "\<lambda> x. - g x" "-l" net] by auto
  2.1526 +qed
  2.1527 +
  2.1528 +lemma Lim_transform_eventually:
  2.1529 +  "eventually (\<lambda>x. f x = g x) net \<Longrightarrow> (f ---> l) net ==> (g ---> l) net"
  2.1530 +  apply (rule topological_tendstoI)
  2.1531 +  apply (drule (2) topological_tendstoD)
  2.1532 +  apply (erule (1) eventually_elim2, simp)
  2.1533 +  done
  2.1534 +
  2.1535 +lemma Lim_transform_within:
  2.1536 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1537 +  assumes "0 < d" "(\<forall>x'\<in>S. 0 < dist x' x \<and> dist x' x < d \<longrightarrow> f x' = g x')"
  2.1538 +          "(f ---> l) (at x within S)"
  2.1539 +  shows   "(g ---> l) (at x within S)"
  2.1540 +  using assms(1,3) unfolding Lim_within
  2.1541 +  apply -
  2.1542 +  apply (clarify, rename_tac e)
  2.1543 +  apply (drule_tac x=e in spec, clarsimp, rename_tac r)
  2.1544 +  apply (rule_tac x="min d r" in exI, clarsimp, rename_tac y)
  2.1545 +  apply (drule_tac x=y in bspec, assumption, clarsimp)
  2.1546 +  apply (simp add: assms(2))
  2.1547 +  done
  2.1548 +
  2.1549 +lemma Lim_transform_at:
  2.1550 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1551 +  shows "0 < d \<Longrightarrow> (\<forall>x'. 0 < dist x' x \<and> dist x' x < d \<longrightarrow> f x' = g x') \<Longrightarrow>
  2.1552 +  (f ---> l) (at x) ==> (g ---> l) (at x)"
  2.1553 +  apply (subst within_UNIV[symmetric])
  2.1554 +  using Lim_transform_within[of d UNIV x f g l]
  2.1555 +  by (auto simp add: within_UNIV)
  2.1556 +
  2.1557 +text{* Common case assuming being away from some crucial point like 0. *}
  2.1558 +
  2.1559 +lemma Lim_transform_away_within:
  2.1560 +  fixes a b :: "'a::metric_space"
  2.1561 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1562 +  assumes "a\<noteq>b" "\<forall>x\<in> S. x \<noteq> a \<and> x \<noteq> b \<longrightarrow> f x = g x"
  2.1563 +  and "(f ---> l) (at a within S)"
  2.1564 +  shows "(g ---> l) (at a within S)"
  2.1565 +proof-
  2.1566 +  have "\<forall>x'\<in>S. 0 < dist x' a \<and> dist x' a < dist a b \<longrightarrow> f x' = g x'" using assms(2)
  2.1567 +    apply auto apply(erule_tac x=x' in ballE) by (auto simp add: dist_commute)
  2.1568 +  thus ?thesis using Lim_transform_within[of "dist a b" S a f g l] using assms(1,3) unfolding dist_nz by auto
  2.1569 +qed
  2.1570 +
  2.1571 +lemma Lim_transform_away_at:
  2.1572 +  fixes a b :: "'a::metric_space"
  2.1573 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1574 +  assumes ab: "a\<noteq>b" and fg: "\<forall>x. x \<noteq> a \<and> x \<noteq> b \<longrightarrow> f x = g x"
  2.1575 +  and fl: "(f ---> l) (at a)"
  2.1576 +  shows "(g ---> l) (at a)"
  2.1577 +  using Lim_transform_away_within[OF ab, of UNIV f g l] fg fl
  2.1578 +  by (auto simp add: within_UNIV)
  2.1579 +
  2.1580 +text{* Alternatively, within an open set. *}
  2.1581 +
  2.1582 +lemma Lim_transform_within_open:
  2.1583 +  fixes a :: "'a::metric_space"
  2.1584 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1585 +  assumes "open S"  "a \<in> S"  "\<forall>x\<in>S. x \<noteq> a \<longrightarrow> f x = g x"  "(f ---> l) (at a)"
  2.1586 +  shows "(g ---> l) (at a)"
  2.1587 +proof-
  2.1588 +  from assms(1,2) obtain e::real where "e>0" and e:"ball a e \<subseteq> S" unfolding open_contains_ball by auto
  2.1589 +  hence "\<forall>x'. 0 < dist x' a \<and> dist x' a < e \<longrightarrow> f x' = g x'" using assms(3)
  2.1590 +    unfolding ball_def subset_eq apply auto apply(erule_tac x=x' in allE) apply(erule_tac x=x' in ballE) by(auto simp add: dist_commute)
  2.1591 +  thus ?thesis using Lim_transform_at[of e a f g l] `e>0` assms(4) by auto
  2.1592 +qed
  2.1593 +
  2.1594 +text{* A congruence rule allowing us to transform limits assuming not at point. *}
  2.1595 +
  2.1596 +(* FIXME: Only one congruence rule for tendsto can be used at a time! *)
  2.1597 +
  2.1598 +lemma Lim_cong_within[cong add]:
  2.1599 +  fixes a :: "'a::metric_space"
  2.1600 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1601 +  shows "(\<And>x. x \<noteq> a \<Longrightarrow> f x = g x) ==> ((\<lambda>x. f x) ---> l) (at a within S) \<longleftrightarrow> ((g ---> l) (at a within S))"
  2.1602 +  by (simp add: Lim_within dist_nz[symmetric])
  2.1603 +
  2.1604 +lemma Lim_cong_at[cong add]:
  2.1605 +  fixes a :: "'a::metric_space"
  2.1606 +  fixes l :: "'b::metric_space" (* TODO: generalize *)
  2.1607 +  shows "(\<And>x. x \<noteq> a ==> f x = g x) ==> (((\<lambda>x. f x) ---> l) (at a) \<longleftrightarrow> ((g ---> l) (at a)))"
  2.1608 +  by (simp add: Lim_at dist_nz[symmetric])
  2.1609 +
  2.1610 +text{* Useful lemmas on closure and set of possible sequential limits.*}
  2.1611 +
  2.1612 +lemma closure_sequential:
  2.1613 +  fixes l :: "'a::metric_space" (* TODO: generalize *)
  2.1614 +  shows "l \<in> closure S \<longleftrightarrow> (\<exists>x. (\<forall>n. x n \<in> S) \<and> (x ---> l) sequentially)" (is "?lhs = ?rhs")
  2.1615 +proof
  2.1616 +  assume "?lhs" moreover
  2.1617 +  { assume "l \<in> S"
  2.1618 +    hence "?rhs" using Lim_const[of l sequentially] by auto
  2.1619 +  } moreover
  2.1620 +  { assume "l islimpt S"
  2.1621 +    hence "?rhs" unfolding islimpt_sequential by auto
  2.1622 +  } ultimately
  2.1623 +  show "?rhs" unfolding closure_def by auto
  2.1624 +next
  2.1625 +  assume "?rhs"
  2.1626 +  thus "?lhs" unfolding closure_def unfolding islimpt_sequential by auto
  2.1627 +qed
  2.1628 +
  2.1629 +lemma closed_sequential_limits:
  2.1630 +  fixes S :: "'a::metric_space set"
  2.1631 +  shows "closed S \<longleftrightarrow> (\<forall>x l. (\<forall>n. x n \<in> S) \<and> (x ---> l) sequentially \<longrightarrow> l \<in> S)"
  2.1632 +  unfolding closed_limpt
  2.1633 +  using closure_sequential [where 'a='a] closure_closed [where 'a='a] closed_limpt [where 'a='a] islimpt_sequential [where 'a='a] mem_delete [where 'a='a]
  2.1634 +  by metis
  2.1635 +
  2.1636 +lemma closure_approachable:
  2.1637 +  fixes S :: "'a::metric_space set"
  2.1638 +  shows "x \<in> closure S \<longleftrightarrow> (\<forall>e>0. \<exists>y\<in>S. dist y x < e)"
  2.1639 +  apply (auto simp add: closure_def islimpt_approachable)
  2.1640 +  by (metis dist_self)
  2.1641 +
  2.1642 +lemma closed_approachable:
  2.1643 +  fixes S :: "'a::metric_space set"
  2.1644 +  shows "closed S ==> (\<forall>e>0. \<exists>y\<in>S. dist y x < e) \<longleftrightarrow> x \<in> S"
  2.1645 +  by (metis closure_closed closure_approachable)
  2.1646 +
  2.1647 +text{* Some other lemmas about sequences. *}
  2.1648 +
  2.1649 +lemma seq_offset:
  2.1650 +  fixes l :: "'a::metric_space" (* TODO: generalize *)
  2.1651 +  shows "(f ---> l) sequentially ==> ((\<lambda>i. f( i + k)) ---> l) sequentially"
  2.1652 +  apply (auto simp add: Lim_sequentially)
  2.1653 +  by (metis trans_le_add1 )
  2.1654 +
  2.1655 +lemma seq_offset_neg:
  2.1656 +  "(f ---> l) sequentially ==> ((\<lambda>i. f(i - k)) ---> l) sequentially"
  2.1657 +  apply (rule topological_tendstoI)
  2.1658 +  apply (drule (2) topological_tendstoD)
  2.1659 +  apply (simp only: eventually_sequentially)
  2.1660 +  apply (subgoal_tac "\<And>N k (n::nat). N + k <= n ==> N <= n - k")
  2.1661 +  apply metis
  2.1662 +  by arith
  2.1663 +
  2.1664 +lemma seq_offset_rev:
  2.1665 +  "((\<lambda>i. f(i + k)) ---> l) sequentially ==> (f ---> l) sequentially"
  2.1666 +  apply (rule topological_tendstoI)
  2.1667 +  apply (drule (2) topological_tendstoD)
  2.1668 +  apply (simp only: eventually_sequentially)
  2.1669 +  apply (subgoal_tac "\<And>N k (n::nat). N + k <= n ==> N <= n - k \<and> (n - k) + k = n")
  2.1670 +  by metis arith
  2.1671 +
  2.1672 +lemma seq_harmonic: "((\<lambda>n. inverse (real n)) ---> 0) sequentially"
  2.1673 +proof-
  2.1674 +  { fix e::real assume "e>0"
  2.1675 +    hence "\<exists>N::nat. \<forall>n::nat\<ge>N. inverse (real n) < e"
  2.1676 +      using real_arch_inv[of e] apply auto apply(rule_tac x=n in exI)
  2.1677 +      by (metis not_le le_imp_inverse_le not_less real_of_nat_gt_zero_cancel_iff real_of_nat_less_iff xt1(7))
  2.1678 +  }
  2.1679 +  thus ?thesis unfolding Lim_sequentially dist_norm by simp
  2.1680 +qed
  2.1681 +
  2.1682 +text{* More properties of closed balls. *}
  2.1683 +
  2.1684 +lemma closed_cball: "closed (cball x e)"
  2.1685 +unfolding cball_def closed_def
  2.1686 +unfolding Collect_neg_eq [symmetric] not_le
  2.1687 +apply (clarsimp simp add: open_dist, rename_tac y)
  2.1688 +apply (rule_tac x="dist x y - e" in exI, clarsimp)
  2.1689 +apply (rename_tac x')
  2.1690 +apply (cut_tac x=x and y=x' and z=y in dist_triangle)
  2.1691 +apply simp
  2.1692 +done
  2.1693 +
  2.1694 +lemma open_contains_cball: "open S \<longleftrightarrow> (\<forall>x\<in>S. \<exists>e>0.  cball x e \<subseteq> S)"
  2.1695 +proof-
  2.1696 +  { fix x and e::real assume "x\<in>S" "e>0" "ball x e \<subseteq> S"
  2.1697 +    hence "\<exists>d>0. cball x d \<subseteq> S" unfolding subset_eq by (rule_tac x="e/2" in exI, auto)
  2.1698 +  } moreover
  2.1699 +  { fix x and e::real assume "x\<in>S" "e>0" "cball x e \<subseteq> S"
  2.1700 +    hence "\<exists>d>0. ball x d \<subseteq> S" unfolding subset_eq apply(rule_tac x="e/2" in exI) by auto
  2.1701 +  } ultimately
  2.1702 +  show ?thesis unfolding open_contains_ball by auto
  2.1703 +qed
  2.1704 +
  2.1705 +lemma open_contains_cball_eq: "open S ==> (\<forall>x. x \<in> S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S))"
  2.1706 +  by (metis open_contains_cball subset_eq order_less_imp_le centre_in_cball mem_def)
  2.1707 +
  2.1708 +lemma mem_interior_cball: "x \<in> interior S \<longleftrightarrow> (\<exists>e>0. cball x e \<subseteq> S)"
  2.1709 +  apply (simp add: interior_def, safe)
  2.1710 +  apply (force simp add: open_contains_cball)
  2.1711 +  apply (rule_tac x="ball x e" in exI)
  2.1712 +  apply (simp add: open_ball centre_in_ball subset_trans [OF ball_subset_cball])
  2.1713 +  done
  2.1714 +
  2.1715 +lemma islimpt_ball:
  2.1716 +  fixes x y :: "'a::{real_normed_vector,perfect_space}"
  2.1717 +  shows "y islimpt ball x e \<longleftrightarrow> 0 < e \<and> y \<in> cball x e" (is "?lhs = ?rhs")
  2.1718 +proof
  2.1719 +  assume "?lhs"
  2.1720 +  { assume "e \<le> 0"
  2.1721 +    hence *:"ball x e = {}" using ball_eq_empty[of x e] by auto
  2.1722 +    have False using `?lhs` unfolding * using islimpt_EMPTY[of y] by auto
  2.1723 +  }
  2.1724 +  hence "e > 0" by (metis not_less)
  2.1725 +  moreover
  2.1726 +  have "y \<in> cball x e" using closed_cball[of x e] islimpt_subset[of y "ball x e" "cball x e"] ball_subset_cball[of x e] `?lhs` unfolding closed_limpt by auto
  2.1727 +  ultimately show "?rhs" by auto
  2.1728 +next
  2.1729 +  assume "?rhs" hence "e>0"  by auto
  2.1730 +  { fix d::real assume "d>0"
  2.1731 +    have "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  2.1732 +    proof(cases "d \<le> dist x y")
  2.1733 +      case True thus "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  2.1734 +      proof(cases "x=y")
  2.1735 +	case True hence False using `d \<le> dist x y` `d>0` by auto
  2.1736 +	thus "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d" by auto
  2.1737 +      next
  2.1738 +	case False
  2.1739 +
  2.1740 +	have "dist x (y - (d / (2 * dist y x)) *\<^sub>R (y - x))
  2.1741 +	      = norm (x - y + (d / (2 * norm (y - x))) *\<^sub>R (y - x))"
  2.1742 +	  unfolding mem_cball mem_ball dist_norm diff_diff_eq2 diff_add_eq[THEN sym] by auto
  2.1743 +	also have "\<dots> = \<bar>- 1 + d / (2 * norm (x - y))\<bar> * norm (x - y)"
  2.1744 +	  using scaleR_left_distrib[of "- 1" "d / (2 * norm (y - x))", THEN sym, of "y - x"]
  2.1745 +	  unfolding scaleR_minus_left scaleR_one
  2.1746 +	  by (auto simp add: norm_minus_commute)
  2.1747 +	also have "\<dots> = \<bar>- norm (x - y) + d / 2\<bar>"
  2.1748 +	  unfolding abs_mult_pos[of "norm (x - y)", OF norm_ge_zero[of "x - y"]]
  2.1749 +	  unfolding real_add_mult_distrib using `x\<noteq>y`[unfolded dist_nz, unfolded dist_norm] by auto
  2.1750 +	also have "\<dots> \<le> e - d/2" using `d \<le> dist x y` and `d>0` and `?rhs` by(auto simp add: dist_norm)
  2.1751 +	finally have "y - (d / (2 * dist y x)) *\<^sub>R (y - x) \<in> ball x e" using `d>0` by auto
  2.1752 +
  2.1753 +	moreover
  2.1754 +
  2.1755 +	have "(d / (2*dist y x)) *\<^sub>R (y - x) \<noteq> 0"
  2.1756 +	  using `x\<noteq>y`[unfolded dist_nz] `d>0` unfolding scaleR_eq_0_iff by (auto simp add: dist_commute)
  2.1757 +	moreover
  2.1758 +	have "dist (y - (d / (2 * dist y x)) *\<^sub>R (y - x)) y < d" unfolding dist_norm apply simp unfolding norm_minus_cancel
  2.1759 +	  using `d>0` `x\<noteq>y`[unfolded dist_nz] dist_commute[of x y]
  2.1760 +	  unfolding dist_norm by auto
  2.1761 +	ultimately show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d" by (rule_tac  x="y - (d / (2*dist y x)) *\<^sub>R (y - x)" in bexI) auto
  2.1762 +      qed
  2.1763 +    next
  2.1764 +      case False hence "d > dist x y" by auto
  2.1765 +      show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  2.1766 +      proof(cases "x=y")
  2.1767 +	case True
  2.1768 +	obtain z where **: "z \<noteq> y" "dist z y < min e d"
  2.1769 +          using perfect_choose_dist[of "min e d" y]
  2.1770 +	  using `d > 0` `e>0` by auto
  2.1771 +	show "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  2.1772 +          unfolding `x = y`
  2.1773 +          using `z \<noteq> y` **
  2.1774 +          by (rule_tac x=z in bexI, auto simp add: dist_commute)
  2.1775 +      next
  2.1776 +	case False thus "\<exists>x'\<in>ball x e. x' \<noteq> y \<and> dist x' y < d"
  2.1777 +	  using `d>0` `d > dist x y` `?rhs` by(rule_tac x=x in bexI, auto)
  2.1778 +      qed
  2.1779 +    qed  }
  2.1780 +  thus "?lhs" unfolding mem_cball islimpt_approachable mem_ball by auto
  2.1781 +qed
  2.1782 +
  2.1783 +lemma closure_ball_lemma:
  2.1784 +  fixes x y :: "'a::real_normed_vector"
  2.1785 +  assumes "x \<noteq> y" shows "y islimpt ball x (dist x y)"
  2.1786 +proof (rule islimptI)
  2.1787 +  fix T assume "y \<in> T" "open T"
  2.1788 +  then obtain r where "0 < r" "\<forall>z. dist z y < r \<longrightarrow> z \<in> T"
  2.1789 +    unfolding open_dist by fast
  2.1790 +  (* choose point between x and y, within distance r of y. *)
  2.1791 +  def k \<equiv> "min 1 (r / (2 * dist x y))"
  2.1792 +  def z \<equiv> "y + scaleR k (x - y)"
  2.1793 +  have z_def2: "z = x + scaleR (1 - k) (y - x)"
  2.1794 +    unfolding z_def by (simp add: algebra_simps)
  2.1795 +  have "dist z y < r"
  2.1796 +    unfolding z_def k_def using `0 < r`
  2.1797 +    by (simp add: dist_norm min_def)
  2.1798 +  hence "z \<in> T" using `\<forall>z. dist z y < r \<longrightarrow> z \<in> T` by simp
  2.1799 +  have "dist x z < dist x y"
  2.1800 +    unfolding z_def2 dist_norm
  2.1801 +    apply (simp add: norm_minus_commute)
  2.1802 +    apply (simp only: dist_norm [symmetric])
  2.1803 +    apply (subgoal_tac "\<bar>1 - k\<bar> * dist x y < 1 * dist x y", simp)
  2.1804 +    apply (rule mult_strict_right_mono)
  2.1805 +    apply (simp add: k_def divide_pos_pos zero_less_dist_iff `0 < r` `x \<noteq> y`)
  2.1806 +    apply (simp add: zero_less_dist_iff `x \<noteq> y`)
  2.1807 +    done
  2.1808 +  hence "z \<in> ball x (dist x y)" by simp
  2.1809 +  have "z \<noteq> y"
  2.1810 +    unfolding z_def k_def using `x \<noteq> y` `0 < r`
  2.1811 +    by (simp add: min_def)
  2.1812 +  show "\<exists>z\<in>ball x (dist x y). z \<in> T \<and> z \<noteq> y"
  2.1813 +    using `z \<in> ball x (dist x y)` `z \<in> T` `z \<noteq> y`
  2.1814 +    by fast
  2.1815 +qed
  2.1816 +
  2.1817 +lemma closure_ball:
  2.1818 +  fixes x :: "'a::real_normed_vector"
  2.1819 +  shows "0 < e \<Longrightarrow> closure (ball x e) = cball x e"
  2.1820 +apply (rule equalityI)
  2.1821 +apply (rule closure_minimal)
  2.1822 +apply (rule ball_subset_cball)
  2.1823 +apply (rule closed_cball)
  2.1824 +apply (rule subsetI, rename_tac y)
  2.1825 +apply (simp add: le_less [where 'a=real])
  2.1826 +apply (erule disjE)
  2.1827 +apply (rule subsetD [OF closure_subset], simp)
  2.1828 +apply (simp add: closure_def)
  2.1829 +apply clarify
  2.1830 +apply (rule closure_ball_lemma)
  2.1831 +apply (simp add: zero_less_dist_iff)
  2.1832 +done
  2.1833 +
  2.1834 +(* In a trivial vector space, this fails for e = 0. *)
  2.1835 +lemma interior_cball:
  2.1836 +  fixes x :: "'a::{real_normed_vector, perfect_space}"
  2.1837 +  shows "interior (cball x e) = ball x e"
  2.1838 +proof(cases "e\<ge>0")
  2.1839 +  case False note cs = this
  2.1840 +  from cs have "ball x e = {}" using ball_empty[of e x] by auto moreover
  2.1841 +  { fix y assume "y \<in> cball x e"
  2.1842 +    hence False unfolding mem_cball using dist_nz[of x y] cs by auto  }
  2.1843 +  hence "cball x e = {}" by auto
  2.1844 +  hence "interior (cball x e) = {}" using interior_empty by auto
  2.1845 +  ultimately show ?thesis by blast
  2.1846 +next
  2.1847 +  case True note cs = this
  2.1848 +  have "ball x e \<subseteq> cball x e" using ball_subset_cball by auto moreover
  2.1849 +  { fix S y assume as: "S \<subseteq> cball x e" "open S" "y\<in>S"
  2.1850 +    then obtain d where "d>0" and d:"\<forall>x'. dist x' y < d \<longrightarrow> x' \<in> S" unfolding open_dist by blast
  2.1851 +
  2.1852 +    then obtain xa where xa_y: "xa \<noteq> y" and xa: "dist xa y < d"
  2.1853 +      using perfect_choose_dist [of d] by auto
  2.1854 +    have "xa\<in>S" using d[THEN spec[where x=xa]] using xa by(auto simp add: dist_commute)
  2.1855 +    hence xa_cball:"xa \<in> cball x e" using as(1) by auto
  2.1856 +
  2.1857 +    hence "y \<in> ball x e" proof(cases "x = y")
  2.1858 +      case True
  2.1859 +      hence "e>0" using xa_y[unfolded dist_nz] xa_cball[unfolded mem_cball] by (auto simp add: dist_commute)
  2.1860 +      thus "y \<in> ball x e" using `x = y ` by simp
  2.1861 +    next
  2.1862 +      case False
  2.1863 +      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) y < d" unfolding dist_norm
  2.1864 +	using `d>0` norm_ge_zero[of "y - x"] `x \<noteq> y` by auto
  2.1865 +      hence *:"y + (d / 2 / dist y x) *\<^sub>R (y - x) \<in> cball x e" using d as(1)[unfolded subset_eq] by blast
  2.1866 +      have "y - x \<noteq> 0" using `x \<noteq> y` by auto
  2.1867 +      hence **:"d / (2 * norm (y - x)) > 0" unfolding zero_less_norm_iff[THEN sym]
  2.1868 +	using `d>0` divide_pos_pos[of d "2*norm (y - x)"] by auto
  2.1869 +
  2.1870 +      have "dist (y + (d / 2 / dist y x) *\<^sub>R (y - x)) x = norm (y + (d / (2 * norm (y - x))) *\<^sub>R y - (d / (2 * norm (y - x))) *\<^sub>R x - x)"
  2.1871 +        by (auto simp add: dist_norm algebra_simps)
  2.1872 +      also have "\<dots> = norm ((1 + d / (2 * norm (y - x))) *\<^sub>R (y - x))"
  2.1873 +        by (auto simp add: algebra_simps)
  2.1874 +      also have "\<dots> = \<bar>1 + d / (2 * norm (y - x))\<bar> * norm (y - x)"
  2.1875 +        using ** by auto
  2.1876 +      also have "\<dots> = (dist y x) + d/2"using ** by (auto simp add: left_distrib dist_norm)
  2.1877 +      finally have "e \<ge> dist x y +d/2" using *[unfolded mem_cball] by (auto simp add: dist_commute)
  2.1878 +      thus "y \<in> ball x e" unfolding mem_ball using `d>0` by auto
  2.1879 +    qed  }
  2.1880 +  hence "\<forall>S \<subseteq> cball x e. open S \<longrightarrow> S \<subseteq> ball x e" by auto
  2.1881 +  ultimately show ?thesis using interior_unique[of "ball x e" "cball x e"] using open_ball[of x e] by auto
  2.1882 +qed
  2.1883 +
  2.1884 +lemma frontier_ball:
  2.1885 +  fixes a :: "'a::real_normed_vector"
  2.1886 +  shows "0 < e ==> frontier(ball a e) = {x. dist a x = e}"
  2.1887 +  apply (simp add: frontier_def closure_ball interior_open open_ball order_less_imp_le)
  2.1888 +  apply (simp add: expand_set_eq)
  2.1889 +  by arith
  2.1890 +
  2.1891 +lemma frontier_cball:
  2.1892 +  fixes a :: "'a::{real_normed_vector, perfect_space}"
  2.1893 +  shows "frontier(cball a e) = {x. dist a x = e}"
  2.1894 +  apply (simp add: frontier_def interior_cball closed_cball closure_closed order_less_imp_le)
  2.1895 +  apply (simp add: expand_set_eq)
  2.1896 +  by arith
  2.1897 +
  2.1898 +lemma cball_eq_empty: "(cball x e = {}) \<longleftrightarrow> e < 0"
  2.1899 +  apply (simp add: expand_set_eq not_le)
  2.1900 +  by (metis zero_le_dist dist_self order_less_le_trans)
  2.1901 +lemma cball_empty: "e < 0 ==> cball x e = {}" by (simp add: cball_eq_empty)
  2.1902 +
  2.1903 +lemma cball_eq_sing:
  2.1904 +  fixes x :: "'a::perfect_space"
  2.1905 +  shows "(cball x e = {x}) \<longleftrightarrow> e = 0"
  2.1906 +proof (rule linorder_cases)
  2.1907 +  assume e: "0 < e"
  2.1908 +  obtain a where "a \<noteq> x" "dist a x < e"
  2.1909 +    using perfect_choose_dist [OF e] by auto
  2.1910 +  hence "a \<noteq> x" "dist x a \<le> e" by (auto simp add: dist_commute)
  2.1911 +  with e show ?thesis by (auto simp add: expand_set_eq)
  2.1912 +qed auto
  2.1913 +
  2.1914 +lemma cball_sing:
  2.1915 +  fixes x :: "'a::metric_space"
  2.1916 +  shows "e = 0 ==> cball x e = {x}"
  2.1917 +  by (auto simp add: expand_set_eq)
  2.1918 +
  2.1919 +text{* For points in the interior, localization of limits makes no difference.   *}
  2.1920 +
  2.1921 +lemma eventually_within_interior:
  2.1922 +  assumes "x \<in> interior S"
  2.1923 +  shows "eventually P (at x within S) \<longleftrightarrow> eventually P (at x)" (is "?lhs = ?rhs")
  2.1924 +proof-
  2.1925 +  from assms obtain T where T: "open T" "x \<in> T" "T \<subseteq> S"
  2.1926 +    unfolding interior_def by fast
  2.1927 +  { assume "?lhs"
  2.1928 +    then obtain A where "open A" "x \<in> A" "\<forall>y\<in>A. y \<noteq> x \<longrightarrow> y \<in> S \<longrightarrow> P y"
  2.1929 +      unfolding Limits.eventually_within Limits.eventually_at_topological
  2.1930 +      by auto
  2.1931 +    with T have "open (A \<inter> T)" "x \<in> A \<inter> T" "\<forall>y\<in>(A \<inter> T). y \<noteq> x \<longrightarrow> P y"
  2.1932 +      by auto
  2.1933 +    then have "?rhs"
  2.1934 +      unfolding Limits.eventually_at_topological by auto
  2.1935 +  } moreover
  2.1936 +  { assume "?rhs" hence "?lhs"
  2.1937 +      unfolding Limits.eventually_within
  2.1938 +      by (auto elim: eventually_elim1)
  2.1939 +  } ultimately
  2.1940 +  show "?thesis" ..
  2.1941 +qed
  2.1942 +
  2.1943 +lemma lim_within_interior:
  2.1944 +  "x \<in> interior S \<Longrightarrow> (f ---> l) (at x within S) \<longleftrightarrow> (f ---> l) (at x)"
  2.1945 +  unfolding tendsto_def by (simp add: eventually_within_interior)
  2.1946 +
  2.1947 +lemma netlimit_within_interior:
  2.1948 +  fixes x :: "'a::{perfect_space, real_normed_vector}"
  2.1949 +    (* FIXME: generalize to perfect_space *)
  2.1950 +  assumes "x \<in> interior S"
  2.1951 +  shows "netlimit(at x within S) = x" (is "?lhs = ?rhs")
  2.1952 +proof-
  2.1953 +  from assms obtain e::real where e:"e>0" "ball x e \<subseteq> S" using open_interior[of S] unfolding open_contains_ball using interior_subset[of S] by auto
  2.1954 +  hence "\<not> trivial_limit (at x within S)" using islimpt_subset[of x "ball x e" S] unfolding trivial_limit_within islimpt_ball centre_in_cball by auto
  2.1955 +  thus ?thesis using netlimit_within by auto
  2.1956 +qed
  2.1957 +
  2.1958 +subsection{* Boundedness. *}
  2.1959 +
  2.1960 +  (* FIXME: This has to be unified with BSEQ!! *)
  2.1961 +definition
  2.1962 +  bounded :: "'a::metric_space set \<Rightarrow> bool" where
  2.1963 +  "bounded S \<longleftrightarrow> (\<exists>x e. \<forall>y\<in>S. dist x y \<le> e)"
  2.1964 +
  2.1965 +lemma bounded_any_center: "bounded S \<longleftrightarrow> (\<exists>e. \<forall>y\<in>S. dist a y \<le> e)"
  2.1966 +unfolding bounded_def
  2.1967 +apply safe
  2.1968 +apply (rule_tac x="dist a x + e" in exI, clarify)
  2.1969 +apply (drule (1) bspec)
  2.1970 +apply (erule order_trans [OF dist_triangle add_left_mono])
  2.1971 +apply auto
  2.1972 +done
  2.1973 +
  2.1974 +lemma bounded_iff: "bounded S \<longleftrightarrow> (\<exists>a. \<forall>x\<in>S. norm x \<le> a)"
  2.1975 +unfolding bounded_any_center [where a=0]
  2.1976 +by (simp add: dist_norm)
  2.1977 +
  2.1978 +lemma bounded_empty[simp]: "bounded {}" by (simp add: bounded_def)
  2.1979 +lemma bounded_subset: "bounded T \<Longrightarrow> S \<subseteq> T ==> bounded S"
  2.1980 +  by (metis bounded_def subset_eq)
  2.1981 +
  2.1982 +lemma bounded_interior[intro]: "bounded S ==> bounded(interior S)"
  2.1983 +  by (metis bounded_subset interior_subset)
  2.1984 +
  2.1985 +lemma bounded_closure[intro]: assumes "bounded S" shows "bounded(closure S)"
  2.1986 +proof-
  2.1987 +  from assms obtain x and a where a: "\<forall>y\<in>S. dist x y \<le> a" unfolding bounded_def by auto
  2.1988 +  { fix y assume "y \<in> closure S"
  2.1989 +    then obtain f where f: "\<forall>n. f n \<in> S"  "(f ---> y) sequentially"
  2.1990 +      unfolding closure_sequential by auto
  2.1991 +    have "\<forall>n. f n \<in> S \<longrightarrow> dist x (f n) \<le> a" using a by simp
  2.1992 +    hence "eventually (\<lambda>n. dist x (f n) \<le> a) sequentially"
  2.1993 +      by (rule eventually_mono, simp add: f(1))
  2.1994 +    have "dist x y \<le> a"
  2.1995 +      apply (rule Lim_dist_ubound [of sequentially f])
  2.1996 +      apply (rule trivial_limit_sequentially)
  2.1997 +      apply (rule f(2))
  2.1998 +      apply fact
  2.1999 +      done
  2.2000 +  }
  2.2001 +  thus ?thesis unfolding bounded_def by auto
  2.2002 +qed
  2.2003 +
  2.2004 +lemma bounded_cball[simp,intro]: "bounded (cball x e)"
  2.2005 +  apply (simp add: bounded_def)
  2.2006 +  apply (rule_tac x=x in exI)
  2.2007 +  apply (rule_tac x=e in exI)
  2.2008 +  apply auto
  2.2009 +  done
  2.2010 +
  2.2011 +lemma bounded_ball[simp,intro]: "bounded(ball x e)"
  2.2012 +  by (metis ball_subset_cball bounded_cball bounded_subset)
  2.2013 +
  2.2014 +lemma finite_imp_bounded[intro]: assumes "finite S" shows "bounded S"
  2.2015 +proof-
  2.2016 +  { fix a F assume as:"bounded F"
  2.2017 +    then obtain x e where "\<forall>y\<in>F. dist x y \<le> e" unfolding bounded_def by auto
  2.2018 +    hence "\<forall>y\<in>(insert a F). dist x y \<le> max e (dist x a)" by auto
  2.2019 +    hence "bounded (insert a F)" unfolding bounded_def by (intro exI)
  2.2020 +  }
  2.2021 +  thus ?thesis using finite_induct[of S bounded]  using bounded_empty assms by auto
  2.2022 +qed
  2.2023 +
  2.2024 +lemma bounded_Un[simp]: "bounded (S \<union> T) \<longleftrightarrow> bounded S \<and> bounded T"
  2.2025 +  apply (auto simp add: bounded_def)
  2.2026 +  apply (rename_tac x y r s)
  2.2027 +  apply (rule_tac x=x in exI)
  2.2028 +  apply (rule_tac x="max r (dist x y + s)" in exI)
  2.2029 +  apply (rule ballI, rename_tac z, safe)
  2.2030 +  apply (drule (1) bspec, simp)
  2.2031 +  apply (drule (1) bspec)
  2.2032 +  apply (rule min_max.le_supI2)
  2.2033 +  apply (erule order_trans [OF dist_triangle add_left_mono])
  2.2034 +  done
  2.2035 +
  2.2036 +lemma bounded_Union[intro]: "finite F \<Longrightarrow> (\<forall>S\<in>F. bounded S) \<Longrightarrow> bounded(\<Union>F)"
  2.2037 +  by (induct rule: finite_induct[of F], auto)
  2.2038 +
  2.2039 +lemma bounded_pos: "bounded S \<longleftrightarrow> (\<exists>b>0. \<forall>x\<in> S. norm x <= b)"
  2.2040 +  apply (simp add: bounded_iff)
  2.2041 +  apply (subgoal_tac "\<And>x (y::real). 0 < 1 + abs y \<and> (x <= y \<longrightarrow> x <= 1 + abs y)")
  2.2042 +  by metis arith
  2.2043 +
  2.2044 +lemma bounded_Int[intro]: "bounded S \<or> bounded T \<Longrightarrow> bounded (S \<inter> T)"
  2.2045 +  by (metis Int_lower1 Int_lower2 bounded_subset)
  2.2046 +
  2.2047 +lemma bounded_diff[intro]: "bounded S ==> bounded (S - T)"
  2.2048 +apply (metis Diff_subset bounded_subset)
  2.2049 +done
  2.2050 +
  2.2051 +lemma bounded_insert[intro]:"bounded(insert x S) \<longleftrightarrow> bounded S"
  2.2052 +  by (metis Diff_cancel Un_empty_right Un_insert_right bounded_Un bounded_subset finite.emptyI finite_imp_bounded infinite_remove subset_insertI)
  2.2053 +
  2.2054 +lemma not_bounded_UNIV[simp, intro]:
  2.2055 +  "\<not> bounded (UNIV :: 'a::{real_normed_vector, perfect_space} set)"
  2.2056 +proof(auto simp add: bounded_pos not_le)
  2.2057 +  obtain x :: 'a where "x \<noteq> 0"
  2.2058 +    using perfect_choose_dist [OF zero_less_one] by fast
  2.2059 +  fix b::real  assume b: "b >0"
  2.2060 +  have b1: "b +1 \<ge> 0" using b by simp
  2.2061 +  with `x \<noteq> 0` have "b < norm (scaleR (b + 1) (sgn x))"
  2.2062 +    by (simp add: norm_sgn)
  2.2063 +  then show "\<exists>x::'a. b < norm x" ..
  2.2064 +qed
  2.2065 +
  2.2066 +lemma bounded_linear_image:
  2.2067 +  assumes "bounded S" "bounded_linear f"
  2.2068 +  shows "bounded(f ` S)"
  2.2069 +proof-
  2.2070 +  from assms(1) obtain b where b:"b>0" "\<forall>x\<in>S. norm x \<le> b" unfolding bounded_pos by auto
  2.2071 +  from assms(2) obtain B where B:"B>0" "\<forall>x. norm (f x) \<le> B * norm x" using bounded_linear.pos_bounded by (auto simp add: mult_ac)
  2.2072 +  { fix x assume "x\<in>S"
  2.2073 +    hence "norm x \<le> b" using b by auto
  2.2074 +    hence "norm (f x) \<le> B * b" using B(2) apply(erule_tac x=x in allE)
  2.2075 +      by (metis B(1) B(2) real_le_trans real_mult_le_cancel_iff2)
  2.2076 +  }
  2.2077 +  thus ?thesis unfolding bounded_pos apply(rule_tac x="b*B" in exI)
  2.2078 +    using b B real_mult_order[of b B] by (auto simp add: real_mult_commute)
  2.2079 +qed
  2.2080 +
  2.2081 +lemma bounded_scaling:
  2.2082 +  fixes S :: "'a::real_normed_vector set"
  2.2083 +  shows "bounded S \<Longrightarrow> bounded ((\<lambda>x. c *\<^sub>R x) ` S)"
  2.2084 +  apply (rule bounded_linear_image, assumption)
  2.2085 +  apply (rule scaleR.bounded_linear_right)
  2.2086 +  done
  2.2087 +
  2.2088 +lemma bounded_translation:
  2.2089 +  fixes S :: "'a::real_normed_vector set"
  2.2090 +  assumes "bounded S" shows "bounded ((\<lambda>x. a + x) ` S)"
  2.2091 +proof-
  2.2092 +  from assms obtain b where b:"b>0" "\<forall>x\<in>S. norm x \<le> b" unfolding bounded_pos by auto
  2.2093 +  { fix x assume "x\<in>S"
  2.2094 +    hence "norm (a + x) \<le> b + norm a" using norm_triangle_ineq[of a x] b by auto
  2.2095 +  }
  2.2096 +  thus ?thesis unfolding bounded_pos using norm_ge_zero[of a] b(1) using add_strict_increasing[of b 0 "norm a"]
  2.2097 +    by (auto intro!: add exI[of _ "b + norm a"])
  2.2098 +qed
  2.2099 +
  2.2100 +
  2.2101 +text{* Some theorems on sups and infs using the notion "bounded". *}
  2.2102 +
  2.2103 +lemma bounded_real:
  2.2104 +  fixes S :: "real set"
  2.2105 +  shows "bounded S \<longleftrightarrow>  (\<exists>a. \<forall>x\<in>S. abs x <= a)"
  2.2106 +  by (simp add: bounded_iff)
  2.2107 +
  2.2108 +lemma bounded_has_rsup: assumes "bounded S" "S \<noteq> {}"
  2.2109 +  shows "\<forall>x\<in>S. x <= rsup S" and "\<forall>b. (\<forall>x\<in>S. x <= b) \<longrightarrow> rsup S <= b"
  2.2110 +proof
  2.2111 +  fix x assume "x\<in>S"
  2.2112 +  from assms(1) obtain a where a:"\<forall>x\<in>S. \<bar>x\<bar> \<le> a" unfolding bounded_real by auto
  2.2113 +  hence *:"S *<= a" using setleI[of S a] by (metis abs_le_interval_iff mem_def)
  2.2114 +  thus "x \<le> rsup S" using rsup[OF `S\<noteq>{}`] using assms(1)[unfolded bounded_real] using isLubD2[of UNIV S "rsup S" x] using `x\<in>S` by auto
  2.2115 +next
  2.2116 +  show "\<forall>b. (\<forall>x\<in>S. x \<le> b) \<longrightarrow> rsup S \<le> b" using assms
  2.2117 +  using rsup[of S, unfolded isLub_def isUb_def leastP_def setle_def setge_def]
  2.2118 +  apply (auto simp add: bounded_real)
  2.2119 +  by (auto simp add: isLub_def isUb_def leastP_def setle_def setge_def)
  2.2120 +qed
  2.2121 +
  2.2122 +lemma rsup_insert: assumes "bounded S"
  2.2123 +  shows "rsup(insert x S) = (if S = {} then x else max x (rsup S))"
  2.2124 +proof(cases "S={}")
  2.2125 +  case True thus ?thesis using rsup_finite_in[of "{x}"] by auto
  2.2126 +next
  2.2127 +  let ?S = "insert x S"
  2.2128 +  case False
  2.2129 +  hence *:"\<forall>x\<in>S. x \<le> rsup S" using bounded_has_rsup(1)[of S] using assms by auto
  2.2130 +  hence "insert x S *<= max x (rsup S)" unfolding setle_def by auto
  2.2131 +  hence "isLub UNIV ?S (rsup ?S)" using rsup[of ?S] by auto
  2.2132 +  moreover
  2.2133 +  have **:"isUb UNIV ?S (max x (rsup S))" unfolding isUb_def setle_def using * by auto
  2.2134 +  { fix y assume as:"isUb UNIV (insert x S) y"
  2.2135 +    hence "max x (rsup S) \<le> y" unfolding isUb_def using rsup_le[OF `S\<noteq>{}`]
  2.2136 +      unfolding setle_def by auto  }
  2.2137 +  hence "max x (rsup S) <=* isUb UNIV (insert x S)" unfolding setge_def Ball_def mem_def by auto
  2.2138 +  hence "isLub UNIV ?S (max x (rsup S))" using ** isLubI2[of UNIV ?S "max x (rsup S)"] unfolding Collect_def by auto
  2.2139 +  ultimately show ?thesis using real_isLub_unique[of UNIV ?S] using `S\<noteq>{}` by auto
  2.2140 +qed
  2.2141 +
  2.2142 +lemma sup_insert_finite: "finite S \<Longrightarrow> rsup(insert x S) = (if S = {} then x else max x (rsup S))"
  2.2143 +  apply (rule rsup_insert)
  2.2144 +  apply (rule finite_imp_bounded)
  2.2145 +  by simp
  2.2146 +
  2.2147 +lemma bounded_has_rinf:
  2.2148 +  assumes "bounded S"  "S \<noteq> {}"
  2.2149 +  shows "\<forall>x\<in>S. x >= rinf S" and "\<forall>b. (\<forall>x\<in>S. x >= b) \<longrightarrow> rinf S >= b"
  2.2150 +proof
  2.2151 +  fix x assume "x\<in>S"
  2.2152 +  from assms(1) obtain a where a:"\<forall>x\<in>S. \<bar>x\<bar> \<le> a" unfolding bounded_real by auto
  2.2153 +  hence *:"- a <=* S" using setgeI[of S "-a"] unfolding abs_le_interval_iff by auto
  2.2154 +  thus "x \<ge> rinf S" using rinf[OF `S\<noteq>{}`] using isGlbD2[of UNIV S "rinf S" x] using `x\<in>S` by auto
  2.2155 +next
  2.2156 +  show "\<forall>b. (\<forall>x\<in>S. x >= b) \<longrightarrow> rinf S \<ge> b" using assms
  2.2157 +  using rinf[of S, unfolded isGlb_def isLb_def greatestP_def setle_def setge_def]
  2.2158 +  apply (auto simp add: bounded_real)
  2.2159 +  by (auto simp add: isGlb_def isLb_def greatestP_def setle_def setge_def)
  2.2160 +qed
  2.2161 +
  2.2162 +(* TODO: Move this to RComplete.thy -- would need to include Glb into RComplete *)
  2.2163 +lemma real_isGlb_unique: "[| isGlb R S x; isGlb R S y |] ==> x = (y::real)"
  2.2164 +  apply (frule isGlb_isLb)
  2.2165 +  apply (frule_tac x = y in isGlb_isLb)
  2.2166 +  apply (blast intro!: order_antisym dest!: isGlb_le_isLb)
  2.2167 +  done
  2.2168 +
  2.2169 +lemma rinf_insert: assumes "bounded S"
  2.2170 +  shows "rinf(insert x S) = (if S = {} then x else min x (rinf S))" (is "?lhs = ?rhs")
  2.2171 +proof(cases "S={}")
  2.2172 +  case True thus ?thesis using rinf_finite_in[of "{x}"] by auto
  2.2173 +next
  2.2174 +  let ?S = "insert x S"
  2.2175 +  case False
  2.2176 +  hence *:"\<forall>x\<in>S. x \<ge> rinf S" using bounded_has_rinf(1)[of S] using assms by auto
  2.2177 +  hence "min x (rinf S) <=* insert x S" unfolding setge_def by auto
  2.2178 +  hence "isGlb UNIV ?S (rinf ?S)" using rinf[of ?S] by auto
  2.2179 +  moreover
  2.2180 +  have **:"isLb UNIV ?S (min x (rinf S))" unfolding isLb_def setge_def using * by auto
  2.2181 +  { fix y assume as:"isLb UNIV (insert x S) y"
  2.2182 +    hence "min x (rinf S) \<ge> y" unfolding isLb_def using rinf_ge[OF `S\<noteq>{}`]
  2.2183 +      unfolding setge_def by auto  }
  2.2184 +  hence "isLb UNIV (insert x S) *<= min x (rinf S)" unfolding setle_def Ball_def mem_def by auto
  2.2185 +  hence "isGlb UNIV ?S (min x (rinf S))" using ** isGlbI2[of UNIV ?S "min x (rinf S)"] unfolding Collect_def by auto
  2.2186 +  ultimately show ?thesis using real_isGlb_unique[of UNIV ?S] using `S\<noteq>{}` by auto
  2.2187 +qed
  2.2188 +
  2.2189 +lemma inf_insert_finite: "finite S ==> rinf(insert x S) = (if S = {} then x else min x (rinf S))"
  2.2190 +  by (rule rinf_insert, rule finite_imp_bounded, simp)
  2.2191 +
  2.2192 +subsection{* Compactness (the definition is the one based on convegent subsequences). *}
  2.2193 +
  2.2194 +definition
  2.2195 +  compact :: "'a::metric_space set \<Rightarrow> bool" where (* TODO: generalize *)
  2.2196 +  "compact S \<longleftrightarrow>
  2.2197 +   (\<forall>f. (\<forall>n. f n \<in> S) \<longrightarrow>
  2.2198 +       (\<exists>l\<in>S. \<exists>r. subseq r \<and> ((f o r) ---> l) sequentially))"
  2.2199 +
  2.2200 +text {*
  2.2201 +  A metric space (or topological vector space) is said to have the
  2.2202 +  Heine-Borel property if every closed and bounded subset is compact.
  2.2203 +*}
  2.2204 +
  2.2205 +class heine_borel =
  2.2206 +  assumes bounded_imp_convergent_subsequence:
  2.2207 +    "bounded s \<Longrightarrow> \<forall>n. f n \<in> s
  2.2208 +      \<Longrightarrow> \<exists>l r. subseq r \<and> ((f \<circ> r) ---> l) sequentially"
  2.2209 +
  2.2210 +lemma bounded_closed_imp_compact:
  2.2211 +  fixes s::"'a::heine_borel set"
  2.2212 +  assumes "bounded s" and "closed s" shows "compact s"
  2.2213 +proof (unfold compact_def, clarify)
  2.2214 +  fix f :: "nat \<Rightarrow> 'a" assume f: "\<forall>n. f n \<in> s"
  2.2215 +  obtain l r where r: "subseq r" and l: "((f \<circ> r) ---> l) sequentially"
  2.2216 +    using bounded_imp_convergent_subsequence [OF `bounded s` `\<forall>n. f n \<in> s`] by auto
  2.2217 +  from f have fr: "\<forall>n. (f \<circ> r) n \<in> s" by simp
  2.2218 +  have "l \<in> s" using `closed s` fr l
  2.2219 +    unfolding closed_sequential_limits by blast
  2.2220 +  show "\<exists>l\<in>s. \<exists>r. subseq r \<and> ((f \<circ> r) ---> l) sequentially"
  2.2221 +    using `l \<in> s` r l by blast
  2.2222 +qed
  2.2223 +
  2.2224 +lemma subseq_bigger: assumes "subseq r" shows "n \<le> r n"
  2.2225 +proof(induct n)
  2.2226 +  show "0 \<le> r 0" by auto
  2.2227 +next
  2.2228 +  fix n assume "n \<le> r n"
  2.2229 +  moreover have "r n < r (Suc n)"
  2.2230 +    using assms [unfolded subseq_def] by auto
  2.2231 +  ultimately show "Suc n \<le> r (Suc n)" by auto
  2.2232 +qed
  2.2233 +
  2.2234 +lemma eventually_subseq:
  2.2235 +  assumes r: "subseq r"
  2.2236 +  shows "eventually P sequentially \<Longrightarrow> eventually (\<lambda>n. P (r n)) sequentially"
  2.2237 +unfolding eventually_sequentially
  2.2238 +by (metis subseq_bigger [OF r] le_trans)
  2.2239 +
  2.2240 +lemma lim_subseq:
  2.2241 +  "subseq r \<Longrightarrow> (s ---> l) sequentially \<Longrightarrow> ((s o r) ---> l) sequentially"
  2.2242 +unfolding tendsto_def eventually_sequentially o_def
  2.2243 +by (metis subseq_bigger le_trans)
  2.2244 +
  2.2245 +lemma num_Axiom: "EX! g. g 0 = e \<and> (\<forall>n. g (Suc n) = f n (g n))"
  2.2246 +  unfolding Ex1_def
  2.2247 +  apply (rule_tac x="nat_rec e f" in exI)
  2.2248 +  apply (rule conjI)+
  2.2249 +apply (rule def_nat_rec_0, simp)
  2.2250 +apply (rule allI, rule def_nat_rec_Suc, simp)
  2.2251 +apply (rule allI, rule impI, rule ext)
  2.2252 +apply (erule conjE)
  2.2253 +apply (induct_tac x)
  2.2254 +apply (simp add: nat_rec_0)
  2.2255 +apply (erule_tac x="n" in allE)
  2.2256 +apply (simp)
  2.2257 +done
  2.2258 +
  2.2259 +lemma convergent_bounded_increasing: fixes s ::"nat\<Rightarrow>real"
  2.2260 +  assumes "incseq s" and "\<forall>n. abs(s n) \<le> b"
  2.2261 +  shows "\<exists> l. \<forall>e::real>0. \<exists> N. \<forall>n \<ge> N.  abs(s n - l) < e"
  2.2262 +proof-
  2.2263 +  have "isUb UNIV (range s) b" using assms(2) and abs_le_D1 unfolding isUb_def and setle_def by auto
  2.2264 +  then obtain t where t:"isLub UNIV (range s) t" using reals_complete[of "range s" ] by auto
  2.2265 +  { fix e::real assume "e>0" and as:"\<forall>N. \<exists>n\<ge>N. \<not> \<bar>s n - t\<bar> < e"
  2.2266 +    { fix n::nat
  2.2267 +      obtain N where "N\<ge>n" and n:"\<bar>s N - t\<bar> \<ge> e" using as[THEN spec[where x=n]] by auto
  2.2268 +      have "t \<ge> s N" using isLub_isUb[OF t, unfolded isUb_def setle_def] by auto
  2.2269 +      with n have "s N \<le> t - e" using `e>0` by auto
  2.2270 +      hence "s n \<le> t - e" using assms(1)[unfolded incseq_def, THEN spec[where x=n], THEN spec[where x=N]] using `n\<le>N` by auto  }
  2.2271 +    hence "isUb UNIV (range s) (t - e)" unfolding isUb_def and setle_def by auto
  2.2272 +    hence False using isLub_le_isUb[OF t, of "t - e"] and `e>0` by auto  }
  2.2273 +  thus ?thesis by blast
  2.2274 +qed
  2.2275 +
  2.2276 +lemma convergent_bounded_monotone: fixes s::"nat \<Rightarrow> real"
  2.2277 +  assumes "\<forall>n. abs(s n) \<le> b" and "monoseq s"
  2.2278 +  shows "\<exists>l. \<forall>e::real>0. \<exists>N. \<forall>n\<ge>N. abs(s n - l) < e"
  2.2279 +  using convergent_bounded_increasing[of s b] assms using convergent_bounded_increasing[of "\<lambda>n. - s n" b]
  2.2280 +  unfolding monoseq_def incseq_def
  2.2281 +  apply auto unfolding minus_add_distrib[THEN sym, unfolded diff_minus[THEN sym]]
  2.2282 +  unfolding abs_minus_cancel by(rule_tac x="-l" in exI)auto
  2.2283 +
  2.2284 +lemma compact_real_lemma:
  2.2285 +  assumes "\<forall>n::nat. abs(s n) \<le> b"
  2.2286 +  shows "\<exists>(l::real) r. subseq r \<and> ((s \<circ> r) ---> l) sequentially"
  2.2287 +proof-
  2.2288 +  obtain r where r:"subseq r" "monoseq (\<lambda>n. s (r n))"
  2.2289 +    using seq_monosub[of s] by auto
  2.2290 +  thus ?thesis using convergent_bounded_monotone[of "\<lambda>n. s (r n)" b] and assms
  2.2291 +    unfolding tendsto_iff dist_norm eventually_sequentially by auto
  2.2292 +qed
  2.2293 +
  2.2294 +instance real :: heine_borel
  2.2295 +proof
  2.2296 +  fix s :: "real set" and f :: "nat \<Rightarrow> real"
  2.2297 +  assume s: "bounded s" and f: "\<forall>n. f n \<in> s"
  2.2298 +  then obtain b where b: "\<forall>n. abs (f n) \<le> b"
  2.2299 +    unfolding bounded_iff by auto
  2.2300 +  obtain l :: real and r :: "nat \<Rightarrow> nat" where
  2.2301 +    r: "subseq r" and l: "((f \<circ> r) ---> l) sequentially"
  2.2302 +    using compact_real_lemma [OF b] by auto
  2.2303 +  thus "\<exists>l r. subseq r \<and> ((f \<circ> r) ---> l) sequentially"
  2.2304 +    by auto
  2.2305 +qed
  2.2306 +
  2.2307 +lemma bounded_component: "bounded s \<Longrightarrow> bounded ((\<lambda>x. x $ i) ` s)"
  2.2308 +unfolding bounded_def
  2.2309 +apply clarify
  2.2310 +apply (rule_tac x="x $ i" in exI)
  2.2311 +apply (rule_tac x="e" in exI)
  2.2312 +apply clarify
  2.2313 +apply (rule order_trans [OF dist_nth_le], simp)
  2.2314 +done
  2.2315 +
  2.2316 +lemma compact_lemma:
  2.2317 +  fixes f :: "nat \<Rightarrow> 'a::heine_borel ^ 'n::finite"
  2.2318 +  assumes "bounded s" and "\<forall>n. f n \<in> s"
  2.2319 +  shows "\<forall>d.
  2.2320 +        \<exists>l r. subseq r \<and>
  2.2321 +        (\<forall>e>0. eventually (\<lambda>n. \<forall>i\<in>d. dist (f (r n) $ i) (l $ i) < e) sequentially)"
  2.2322 +proof
  2.2323 +  fix d::"'n set" have "finite d" by simp
  2.2324 +  thus "\<exists>l::'a ^ 'n. \<exists>r. subseq r \<and>
  2.2325 +      (\<forall>e>0. eventually (\<lambda>n. \<forall>i\<in>d. dist (f (r n) $ i) (l $ i) < e) sequentially)"
  2.2326 +  proof(induct d) case empty thus ?case unfolding subseq_def by auto
  2.2327 +  next case (insert k d)
  2.2328 +    have s': "bounded ((\<lambda>x. x $ k) ` s)" using `bounded s` by (rule bounded_component)
  2.2329 +    obtain l1::"'a^'n" and r1 where r1:"subseq r1" and lr1:"\<forall>e>0. eventually (\<lambda>n. \<forall>i\<in>d. dist (f (r1 n) $ i) (l1 $ i) < e) sequentially"
  2.2330 +      using insert(3) by auto
  2.2331 +    have f': "\<forall>n. f (r1 n) $ k \<in> (\<lambda>x. x $ k) ` s" using `\<forall>n. f n \<in> s` by simp
  2.2332 +    obtain l2 r2 where r2:"subseq r2" and lr2:"((\<lambda>i. f (r1 (r2 i)) $ k) ---> l2) sequentially"
  2.2333 +      using bounded_imp_convergent_subsequence[OF s' f'] unfolding o_def by auto
  2.2334 +    def r \<equiv> "r1 \<circ> r2" have r:"subseq r"
  2.2335 +      using r1 and r2 unfolding r_def o_def subseq_def by auto
  2.2336 +    moreover
  2.2337 +    def l \<equiv> "(\<chi> i. if i = k then l2 else l1$i)::'a^'n"
  2.2338 +    { fix e::real assume "e>0"
  2.2339 +      from lr1 `e>0` have N1:"eventually (\<lambda>n. \<forall>i\<in>d. dist (f (r1 n) $ i) (l1 $ i) < e) sequentially" by blast
  2.2340 +      from lr2 `e>0` have N2:"eventually (\<lambda>n. dist (f (r1 (r2 n)) $ k) l2 < e) sequentially" by (rule tendstoD)
  2.2341 +      from r2 N1 have N1': "eventually (\<lambda>n. \<forall>i\<in>d. dist (f (r1 (r2 n)) $ i) (l1 $ i) < e) sequentially"
  2.2342 +        by (rule eventually_subseq)
  2.2343 +      have "eventually (\<lambda>n. \<forall>i\<in>(insert k d). dist (f (r n) $ i) (l $ i) < e) sequentially"
  2.2344 +        using N1' N2 by (rule eventually_elim2, simp add: l_def r_def)
  2.2345 +    }
  2.2346 +    ultimately show ?case by auto
  2.2347 +  qed
  2.2348 +qed
  2.2349 +
  2.2350 +instance "^" :: (heine_borel, finite) heine_borel
  2.2351 +proof
  2.2352 +  fix s :: "('a ^ 'b) set" and f :: "nat \<Rightarrow> 'a ^ 'b"
  2.2353 +  assume s: "bounded s" and f: "\<forall>n. f n \<in> s"
  2.2354 +  then obtain l r where r: "subseq r"
  2.2355 +    and l: "\<forall>e>0. eventually (\<lambda>n. \<forall>i\<in>UNIV. dist (f (r n) $ i) (l $ i) < e) sequentially"
  2.2356 +    using compact_lemma [OF s f] by blast
  2.2357 +  let ?d = "UNIV::'b set"
  2.2358 +  { fix e::real assume "e>0"
  2.2359 +    hence "0 < e / (real_of_nat (card ?d))"
  2.2360 +      using zero_less_card_finite using divide_pos_pos[of e, of "real_of_nat (card ?d)"] by auto
  2.2361 +    with l have "eventually (\<lambda>n. \<forall>i. dist (f (r n) $ i) (l $ i) < e / (real_of_nat (card ?d))) sequentially"
  2.2362 +      by simp
  2.2363 +    moreover
  2.2364 +    { fix n assume n: "\<forall>i. dist (f (r n) $ i) (l $ i) < e / (real_of_nat (card ?d))"
  2.2365 +      have "dist (f (r n)) l \<le> (\<Sum>i\<in>?d. dist (f (r n) $ i) (l $ i))"
  2.2366 +        unfolding dist_vector_def using zero_le_dist by (rule setL2_le_setsum)
  2.2367 +      also have "\<dots> < (\<Sum>i\<in>?d. e / (real_of_nat (card ?d)))"
  2.2368 +        by (rule setsum_strict_mono) (simp_all add: n)
  2.2369 +      finally have "dist (f (r n)) l < e" by simp
  2.2370 +    }
  2.2371 +    ultimately have "eventually (\<lambda>n. dist (f (r n)) l < e) sequentially"
  2.2372 +      by (rule eventually_elim1)
  2.2373 +  }
  2.2374 +  hence *:"((f \<circ> r) ---> l) sequentially" unfolding o_def tendsto_iff by simp
  2.2375 +  with r show "\<exists>l r. subseq r \<and> ((f \<circ> r) ---> l) sequentially" by auto
  2.2376 +qed
  2.2377 +
  2.2378 +lemma bounded_fst: "bounded s \<Longrightarrow> bounded (fst ` s)"
  2.2379 +unfolding bounded_def
  2.2380 +apply clarify
  2.2381 +apply (rule_tac x="a" in exI)
  2.2382 +apply (rule_tac x="e" in exI)
  2.2383 +apply clarsimp
  2.2384 +apply (drule (1) bspec)
  2.2385 +apply (simp add: dist_Pair_Pair)
  2.2386 +apply (erule order_trans [OF real_sqrt_sum_squares_ge1])
  2.2387 +done
  2.2388 +
  2.2389 +lemma bounded_snd: "bounded s \<Longrightarrow> bounded (snd ` s)"
  2.2390 +unfolding bounded_def
  2.2391 +apply clarify
  2.2392 +apply (rule_tac x="b" in exI)
  2.2393 +apply (rule_tac x="e" in exI)
  2.2394 +apply clarsimp
  2.2395 +apply (drule (1) bspec)
  2.2396 +apply (simp add: dist_Pair_Pair)
  2.2397 +apply (erule order_trans [OF real_sqrt_sum_squares_ge2])
  2.2398 +done
  2.2399 +
  2.2400 +instance "*" :: (heine_borel, heine_borel) heine_borel
  2.2401 +proof
  2.2402 +  fix s :: "('a * 'b) set" and f :: "nat \<Rightarrow> 'a * 'b"
  2.2403 +  assume s: "bounded s" and f: "\<forall>n. f n \<in> s"
  2.2404 +  from s have s1: "bounded (fst ` s)" by (rule bounded_fst)
  2.2405 +  from f have f1: "\<forall>n. fst (f n) \<in> fst ` s" by simp
  2.2406 +  obtain l1 r1 where r1: "subseq r1"
  2.2407 +    and l1: "((\<lambda>n. fst (f (r1 n))) ---> l1) sequentially"
  2.2408 +    using bounded_imp_convergent_subsequence [OF s1 f1]
  2.2409 +    unfolding o_def by fast
  2.2410 +  from s have s2: "bounded (snd ` s)" by (rule bounded_snd)
  2.2411 +  from f have f2: "\<forall>n. snd (f (r1 n)) \<in> snd ` s" by simp
  2.2412 +  obtain l2 r2 where r2: "subseq r2"
  2.2413 +    and l2: "((\<lambda>n. snd (f (r1 (r2 n)))) ---> l2) sequentially"
  2.2414 +    using bounded_imp_convergent_subsequence [OF s2 f2]
  2.2415 +    unfolding o_def by fast
  2.2416 +  have l1': "((\<lambda>n. fst (f (r1 (r2 n)))) ---> l1) sequentially"
  2.2417 +    using lim_subseq [OF r2 l1] unfolding o_def .
  2.2418 +  have l: "((f \<circ> (r1 \<circ> r2)) ---> (l1, l2)) sequentially"
  2.2419 +    using tendsto_Pair [OF l1' l2] unfolding o_def by simp
  2.2420 +  have r: "subseq (r1 \<circ> r2)"
  2.2421 +    using r1 r2 unfolding subseq_def by simp
  2.2422 +  show "\<exists>l r. subseq r \<and> ((f \<circ> r) ---> l) sequentially"
  2.2423 +    using l r by fast
  2.2424 +qed
  2.2425 +
  2.2426 +subsection{* Completeness. *}
  2.2427 +
  2.2428 +lemma cauchy_def:
  2.2429 +  "Cauchy s \<longleftrightarrow> (\<forall>e>0. \<exists>N. \<forall>m n. m \<ge> N \<and> n \<ge> N --> dist(s m)(s n) < e)"
  2.2430 +unfolding Cauchy_def by blast
  2.2431 +
  2.2432 +definition
  2.2433 +  complete :: "'a::metric_space set \<Rightarrow> bool" where
  2.2434 +  "complete s \<longleftrightarrow> (\<forall>f. (\<forall>n. f n \<in> s) \<and> Cauchy f
  2.2435 +                      --> (\<exists>l \<in> s. (f ---> l) sequentially))"
  2.2436 +
  2.2437 +lemma cauchy: "Cauchy s \<longleftrightarrow> (\<forall>e>0.\<exists> N::nat. \<forall>n\<ge>N. dist(s n)(s N) < e)" (is "?lhs = ?rhs")
  2.2438 +proof-
  2.2439 +  { assume ?rhs
  2.2440 +    { fix e::real
  2.2441 +      assume "e>0"
  2.2442 +      with `?rhs` obtain N where N:"\<forall>n\<ge>N. dist (s n) (s N) < e/2"
  2.2443 +	by (erule_tac x="e/2" in allE) auto
  2.2444 +      { fix n m
  2.2445 +	assume nm:"N \<le> m \<and> N \<le> n"
  2.2446 +	hence "dist (s m) (s n) < e" using N
  2.2447 +	  using dist_triangle_half_l[of "s m" "s N" "e" "s n"]
  2.2448 +	  by blast
  2.2449 +      }
  2.2450 +      hence "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (s m) (s n) < e"
  2.2451 +	by blast
  2.2452 +    }
  2.2453 +    hence ?lhs
  2.2454 +      unfolding cauchy_def
  2.2455 +      by blast
  2.2456 +  }
  2.2457 +  thus ?thesis
  2.2458 +    unfolding cauchy_def
  2.2459 +    using dist_triangle_half_l
  2.2460 +    by blast
  2.2461 +qed
  2.2462 +
  2.2463 +lemma convergent_imp_cauchy:
  2.2464 + "(s ---> l) sequentially ==> Cauchy s"
  2.2465 +proof(simp only: cauchy_def, rule, rule)
  2.2466 +  fix e::real assume "e>0" "(s ---> l) sequentially"
  2.2467 +  then obtain N::nat where N:"\<forall>n\<ge>N. dist (s n) l < e/2" unfolding Lim_sequentially by(erule_tac x="e/2" in allE) auto
  2.2468 +  thus "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (s m) (s n) < e"  using dist_triangle_half_l[of _ l e _] by (rule_tac x=N in exI) auto
  2.2469 +qed
  2.2470 +
  2.2471 +lemma cauchy_imp_bounded: assumes "Cauchy s" shows "bounded {y. (\<exists>n::nat. y = s n)}"
  2.2472 +proof-
  2.2473 +  from assms obtain N::nat where "\<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (s m) (s n) < 1" unfolding cauchy_def apply(erule_tac x= 1 in allE) by auto
  2.2474 +  hence N:"\<forall>n. N \<le> n \<longrightarrow> dist (s N) (s n) < 1" by auto
  2.2475 +  moreover
  2.2476 +  have "bounded (s ` {0..N})" using finite_imp_bounded[of "s ` {1..N}"] by auto
  2.2477 +  then obtain a where a:"\<forall>x\<in>s ` {0..N}. dist (s N) x \<le> a"
  2.2478 +    unfolding bounded_any_center [where a="s N"] by auto
  2.2479 +  ultimately show "?thesis"
  2.2480 +    unfolding bounded_any_center [where a="s N"]
  2.2481 +    apply(rule_tac x="max a 1" in exI) apply auto
  2.2482 +    apply(erule_tac x=n in allE) apply(erule_tac x=n in ballE) by auto
  2.2483 +qed
  2.2484 +
  2.2485 +lemma compact_imp_complete: assumes "compact s" shows "complete s"
  2.2486 +proof-
  2.2487 +  { fix f assume as: "(\<forall>n::nat. f n \<in> s)" "Cauchy f"
  2.2488 +    from as(1) obtain l r where lr: "l\<in>s" "subseq r" "((f \<circ> r) ---> l) sequentially" using assms unfolding compact_def by blast
  2.2489 +
  2.2490 +    note lr' = subseq_bigger [OF lr(2)]
  2.2491 +
  2.2492 +    { fix e::real assume "e>0"
  2.2493 +      from as(2) obtain N where N:"\<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (f m) (f n) < e/2" unfolding cauchy_def using `e>0` apply (erule_tac x="e/2" in allE) by auto
  2.2494 +      from lr(3)[unfolded Lim_sequentially, THEN spec[where x="e/2"]] obtain M where M:"\<forall>n\<ge>M. dist ((f \<circ> r) n) l < e/2" using `e>0` by auto
  2.2495 +      { fix n::nat assume n:"n \<ge> max N M"
  2.2496 +	have "dist ((f \<circ> r) n) l < e/2" using n M by auto
  2.2497 +	moreover have "r n \<ge> N" using lr'[of n] n by auto
  2.2498 +	hence "dist (f n) ((f \<circ> r) n) < e / 2" using N using n by auto
  2.2499 +	ultimately have "dist (f n) l < e" using dist_triangle_half_r[of "f (r n)" "f n" e l] by (auto simp add: dist_commute)  }
  2.2500 +      hence "\<exists>N. \<forall>n\<ge>N. dist (f n) l < e" by blast  }
  2.2501 +    hence "\<exists>l\<in>s. (f ---> l) sequentially" using `l\<in>s` unfolding Lim_sequentially by auto  }
  2.2502 +  thus ?thesis unfolding complete_def by auto
  2.2503 +qed
  2.2504 +
  2.2505 +instance heine_borel < complete_space
  2.2506 +proof
  2.2507 +  fix f :: "nat \<Rightarrow> 'a" assume "Cauchy f"
  2.2508 +  hence "bounded (range f)" unfolding image_def
  2.2509 +    using cauchy_imp_bounded [of f] by auto
  2.2510 +  hence "compact (closure (range f))"
  2.2511 +    using bounded_closed_imp_compact [of "closure (range f)"] by auto
  2.2512 +  hence "complete (closure (range f))"
  2.2513 +    using compact_imp_complete by auto
  2.2514 +  moreover have "\<forall>n. f n \<in> closure (range f)"
  2.2515 +    using closure_subset [of "range f"] by auto
  2.2516 +  ultimately have "\<exists>l\<in>closure (range f). (f ---> l) sequentially"
  2.2517 +    using `Cauchy f` unfolding complete_def by auto
  2.2518 +  then show "convergent f"
  2.2519 +    unfolding convergent_def LIMSEQ_conv_tendsto [symmetric] by auto
  2.2520 +qed
  2.2521 +
  2.2522 +lemma complete_univ: "complete (UNIV :: 'a::complete_space set)"
  2.2523 +proof(simp add: complete_def, rule, rule)
  2.2524 +  fix f :: "nat \<Rightarrow> 'a" assume "Cauchy f"
  2.2525 +  hence "convergent f" by (rule Cauchy_convergent)
  2.2526 +  hence "\<exists>l. f ----> l" unfolding convergent_def .  
  2.2527 +  thus "\<exists>l. (f ---> l) sequentially" unfolding LIMSEQ_conv_tendsto .
  2.2528 +qed
  2.2529 +
  2.2530 +lemma complete_imp_closed: assumes "complete s" shows "closed s"
  2.2531 +proof -
  2.2532 +  { fix x assume "x islimpt s"
  2.2533 +    then obtain f where f: "\<forall>n. f n \<in> s - {x}" "(f ---> x) sequentially"
  2.2534 +      unfolding islimpt_sequential by auto
  2.2535 +    then obtain l where l: "l\<in>s" "(f ---> l) sequentially"
  2.2536 +      using `complete s`[unfolded complete_def] using convergent_imp_cauchy[of f x] by auto
  2.2537 +    hence "x \<in> s"  using Lim_unique[of sequentially f l x] trivial_limit_sequentially f(2) by auto
  2.2538 +  }
  2.2539 +  thus "closed s" unfolding closed_limpt by auto
  2.2540 +qed
  2.2541 +
  2.2542 +lemma complete_eq_closed:
  2.2543 +  fixes s :: "'a::complete_space set"
  2.2544 +  shows "complete s \<longleftrightarrow> closed s" (is "?lhs = ?rhs")
  2.2545 +proof
  2.2546 +  assume ?lhs thus ?rhs by (rule complete_imp_closed)
  2.2547 +next
  2.2548 +  assume ?rhs
  2.2549 +  { fix f assume as:"\<forall>n::nat. f n \<in> s" "Cauchy f"
  2.2550 +    then obtain l where "(f ---> l) sequentially" using complete_univ[unfolded complete_def, THEN spec[where x=f]] by auto
  2.2551 +    hence "\<exists>l\<in>s. (f ---> l) sequentially" using `?rhs`[unfolded closed_sequential_limits, THEN spec[where x=f], THEN spec[where x=l]] using as(1) by auto  }
  2.2552 +  thus ?lhs unfolding complete_def by auto
  2.2553 +qed
  2.2554 +
  2.2555 +lemma convergent_eq_cauchy:
  2.2556 +  fixes s :: "nat \<Rightarrow> 'a::complete_space"
  2.2557 +  shows "(\<exists>l. (s ---> l) sequentially) \<longleftrightarrow> Cauchy s" (is "?lhs = ?rhs")
  2.2558 +proof
  2.2559 +  assume ?lhs then obtain l where "(s ---> l) sequentially" by auto
  2.2560 +  thus ?rhs using convergent_imp_cauchy by auto
  2.2561 +next
  2.2562 +  assume ?rhs thus ?lhs using complete_univ[unfolded complete_def, THEN spec[where x=s]] by auto
  2.2563 +qed
  2.2564 +
  2.2565 +lemma convergent_imp_bounded:
  2.2566 +  fixes s :: "nat \<Rightarrow> 'a::metric_space"
  2.2567 +  shows "(s ---> l) sequentially ==> bounded (s ` (UNIV::(nat set)))"
  2.2568 +  using convergent_imp_cauchy[of s]
  2.2569 +  using cauchy_imp_bounded[of s]
  2.2570 +  unfolding image_def
  2.2571 +  by auto
  2.2572 +
  2.2573 +subsection{* Total boundedness. *}
  2.2574 +
  2.2575 +fun helper_1::"('a::metric_space set) \<Rightarrow> real \<Rightarrow> nat \<Rightarrow> 'a" where
  2.2576 +  "helper_1 s e n = (SOME y::'a. y \<in> s \<and> (\<forall>m<n. \<not> (dist (helper_1 s e m) y < e)))"
  2.2577 +declare helper_1.simps[simp del]
  2.2578 +
  2.2579 +lemma compact_imp_totally_bounded:
  2.2580 +  assumes "compact s"
  2.2581 +  shows "\<forall>e>0. \<exists>k. finite k \<and> k \<subseteq> s \<and> s \<subseteq> (\<Union>((\<lambda>x. ball x e) ` k))"
  2.2582 +proof(rule, rule, rule ccontr)
  2.2583 +  fix e::real assume "e>0" and assm:"\<not> (\<exists>k. finite k \<and> k \<subseteq> s \<and> s \<subseteq> \<Union>(\<lambda>x. ball x e) ` k)"
  2.2584 +  def x \<equiv> "helper_1 s e"
  2.2585 +  { fix n
  2.2586 +    have "x n \<in> s \<and> (\<forall>m<n. \<not> dist (x m) (x n) < e)"
  2.2587 +    proof(induct_tac rule:nat_less_induct)
  2.2588 +      fix n  def Q \<equiv> "(\<lambda>y. y \<in> s \<and> (\<forall>m<n. \<not> dist (x m) y < e))"
  2.2589 +      assume as:"\<forall>m<n. x m \<in> s \<and> (\<forall>ma<m. \<not> dist (x ma) (x m) < e)"
  2.2590 +      have "\<not> s \<subseteq> (\<Union>x\<in>x ` {0..<n}. ball x e)" using assm apply simp apply(erule_tac x="x ` {0 ..< n}" in allE) using as by auto
  2.2591 +      then obtain z where z:"z\<in>s" "z \<notin> (\<Union>x\<in>x ` {0..<n}. ball x e)" unfolding subset_eq by auto
  2.2592 +      have "Q (x n)" unfolding x_def and helper_1.simps[of s e n]
  2.2593 +	apply(rule someI2[where a=z]) unfolding x_def[symmetric] and Q_def using z by auto
  2.2594 +      thus "x n \<in> s \<and> (\<forall>m<n. \<not> dist (x m) (x n) < e)" unfolding Q_def by auto
  2.2595 +    qed }
  2.2596 +  hence "\<forall>n::nat. x n \<in> s" and x:"\<forall>n. \<forall>m < n. \<not> (dist (x m) (x n) < e)" by blast+
  2.2597 +  then obtain l r where "l\<in>s" and r:"subseq r" and "((x \<circ> r) ---> l) sequentially" using assms(1)[unfolded compact_def, THEN spec[where x=x]] by auto
  2.2598 +  from this(3) have "Cauchy (x \<circ> r)" using convergent_imp_cauchy by auto
  2.2599 +  then obtain N::nat where N:"\<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist ((x \<circ> r) m) ((x \<circ> r) n) < e" unfolding cauchy_def using `e>0` by auto
  2.2600 +  show False
  2.2601 +    using N[THEN spec[where x=N], THEN spec[where x="N+1"]]
  2.2602 +    using r[unfolded subseq_def, THEN spec[where x=N], THEN spec[where x="N+1"]]
  2.2603 +    using x[THEN spec[where x="r (N+1)"], THEN spec[where x="r (N)"]] by auto
  2.2604 +qed
  2.2605 +
  2.2606 +subsection{* Heine-Borel theorem (following Burkill \& Burkill vol. 2) *}
  2.2607 +
  2.2608 +lemma heine_borel_lemma: fixes s::"'a::metric_space set"
  2.2609 +  assumes "compact s"  "s \<subseteq> (\<Union> t)"  "\<forall>b \<in> t. open b"
  2.2610 +  shows "\<exists>e>0. \<forall>x \<in> s. \<exists>b \<in> t. ball x e \<subseteq> b"
  2.2611 +proof(rule ccontr)
  2.2612 +  assume "\<not> (\<exists>e>0. \<forall>x\<in>s. \<exists>b\<in>t. ball x e \<subseteq> b)"
  2.2613 +  hence cont:"\<forall>e>0. \<exists>x\<in>s. \<forall>xa\<in>t. \<not> (ball x e \<subseteq> xa)" by auto
  2.2614 +  { fix n::nat
  2.2615 +    have "1 / real (n + 1) > 0" by auto
  2.2616 +    hence "\<exists>x. x\<in>s \<and> (\<forall>xa\<in>t. \<not> (ball x (inverse (real (n+1))) \<subseteq> xa))" using cont unfolding Bex_def by auto }
  2.2617 +  hence "\<forall>n::nat. \<exists>x. x \<in> s \<and> (\<forall>xa\<in>t. \<not> ball x (inverse (real (n + 1))) \<subseteq> xa)" by auto
  2.2618 +  then obtain f where f:"\<forall>n::nat. f n \<in> s \<and> (\<forall>xa\<in>t. \<not> ball (f n) (inverse (real (n + 1))) \<subseteq> xa)"
  2.2619 +    using choice[of "\<lambda>n::nat. \<lambda>x. x\<in>s \<and> (\<forall>xa\<in>t. \<not> ball x (inverse (real (n + 1))) \<subseteq> xa)"] by auto
  2.2620 +
  2.2621 +  then obtain l r where l:"l\<in>s" and r:"subseq r" and lr:"((f \<circ> r) ---> l) sequentially"
  2.2622 +    using assms(1)[unfolded compact_def, THEN spec[where x=f]] by auto
  2.2623 +
  2.2624 +  obtain b where "l\<in>b" "b\<in>t" using assms(2) and l by auto
  2.2625 +  then obtain e where "e>0" and e:"\<forall>z. dist z l < e \<longrightarrow> z\<in>b"
  2.2626 +    using assms(3)[THEN bspec[where x=b]] unfolding open_dist by auto
  2.2627 +
  2.2628 +  then obtain N1 where N1:"\<forall>n\<ge>N1. dist ((f \<circ> r) n) l < e / 2"
  2.2629 +    using lr[unfolded Lim_sequentially, THEN spec[where x="e/2"]] by auto
  2.2630 +
  2.2631 +  obtain N2::nat where N2:"N2>0" "inverse (real N2) < e /2" using real_arch_inv[of "e/2"] and `e>0` by auto
  2.2632 +  have N2':"inverse (real (r (N1 + N2) +1 )) < e/2"
  2.2633 +    apply(rule order_less_trans) apply(rule less_imp_inverse_less) using N2
  2.2634 +    using subseq_bigger[OF r, of "N1 + N2"] by auto
  2.2635 +
  2.2636 +  def x \<equiv> "(f (r (N1 + N2)))"
  2.2637 +  have x:"\<not> ball x (inverse (real (r (N1 + N2) + 1))) \<subseteq> b" unfolding x_def
  2.2638 +    using f[THEN spec[where x="r (N1 + N2)"]] using `b\<in>t` by auto
  2.2639 +  have "\<exists>y\<in>ball x (inverse (real (r (N1 + N2) + 1))). y\<notin>b" apply(rule ccontr) using x by auto
  2.2640 +  then obtain y where y:"y \<in> ball x (inverse (real (r (N1 + N2) + 1)))" "y \<notin> b" by auto
  2.2641 +
  2.2642 +  have "dist x l < e/2" using N1 unfolding x_def o_def by auto
  2.2643 +  hence "dist y l < e" using y N2' using dist_triangle[of y l x]by (auto simp add:dist_commute)
  2.2644 +
  2.2645 +  thus False using e and `y\<notin>b` by auto
  2.2646 +qed
  2.2647 +
  2.2648 +lemma compact_imp_heine_borel: "compact s ==> (\<forall>f. (\<forall>t \<in> f. open t) \<and> s \<subseteq> (\<Union> f)
  2.2649 +               \<longrightarrow> (\<exists>f'. f' \<subseteq> f \<and> finite f' \<and> s \<subseteq> (\<Union> f')))"
  2.2650 +proof clarify
  2.2651 +  fix f assume "compact s" " \<forall>t\<in>f. open t" "s \<subseteq> \<Union>f"
  2.2652 +  then obtain e::real where "e>0" and "\<forall>x\<in>s. \<exists>b\<in>f. ball x e \<subseteq> b" using heine_borel_lemma[of s f] by auto
  2.2653 +  hence "\<forall>x\<in>s. \<exists>b. b\<in>f \<and> ball x e \<subseteq> b" by auto
  2.2654 +  hence "\<exists>bb. \<forall>x\<in>s. bb x \<in>f \<and> ball x e \<subseteq> bb x" using bchoice[of s "\<lambda>x b. b\<in>f \<and> ball x e \<subseteq> b"] by auto
  2.2655 +  then obtain  bb where bb:"\<forall>x\<in>s. (bb x) \<in> f \<and> ball x e \<subseteq> (bb x)" by blast
  2.2656 +
  2.2657 +  from `compact s` have  "\<exists> k. finite k \<and> k \<subseteq> s \<and> s \<subseteq> \<Union>(\<lambda>x. ball x e) ` k" using compact_imp_totally_bounded[of s] `e>0` by auto
  2.2658 +  then obtain k where k:"finite k" "k \<subseteq> s" "s \<subseteq> \<Union>(\<lambda>x. ball x e) ` k" by auto
  2.2659 +
  2.2660 +  have "finite (bb ` k)" using k(1) by auto
  2.2661 +  moreover
  2.2662 +  { fix x assume "x\<in>s"
  2.2663 +    hence "x\<in>\<Union>(\<lambda>x. ball x e) ` k" using k(3)  unfolding subset_eq by auto
  2.2664 +    hence "\<exists>X\<in>bb ` k. x \<in> X" using bb k(2) by blast
  2.2665 +    hence "x \<in> \<Union>(bb ` k)" using  Union_iff[of x "bb ` k"] by auto
  2.2666 +  }
  2.2667 +  ultimately show "\<exists>f'\<subseteq>f. finite f' \<and> s \<subseteq> \<Union>f'" using bb k(2) by (rule_tac x="bb ` k" in exI) auto
  2.2668 +qed
  2.2669 +
  2.2670 +subsection{* Bolzano-Weierstrass property. *}
  2.2671 +
  2.2672 +lemma heine_borel_imp_bolzano_weierstrass:
  2.2673 +  assumes "\<forall>f. (\<forall>t \<in> f. open t) \<and> s \<subseteq> (\<Union> f) --> (\<exists>f'. f' \<subseteq> f \<and> finite f' \<and> s \<subseteq> (\<Union> f'))"
  2.2674 +          "infinite t"  "t \<subseteq> s"
  2.2675 +  shows "\<exists>x \<in> s. x islimpt t"
  2.2676 +proof(rule ccontr)
  2.2677 +  assume "\<not> (\<exists>x \<in> s. x islimpt t)"
  2.2678 +  then obtain f where f:"\<forall>x\<in>s. x \<in> f x \<and> open (f x) \<and> (\<forall>y\<in>t. y \<in> f x \<longrightarrow> y = x)" unfolding islimpt_def
  2.2679 +    using bchoice[of s "\<lambda> x T. x \<in> T \<and> open T \<and> (\<forall>y\<in>t. y \<in> T \<longrightarrow> y = x)"] by auto
  2.2680 +  obtain g where g:"g\<subseteq>{t. \<exists>x. x \<in> s \<and> t = f x}" "finite g" "s \<subseteq> \<Union>g"
  2.2681 +    using assms(1)[THEN spec[where x="{t. \<exists>x. x\<in>s \<and> t = f x}"]] using f by auto
  2.2682 +  from g(1,3) have g':"\<forall>x\<in>g. \<exists>xa \<in> s. x = f xa" by auto
  2.2683 +  { fix x y assume "x\<in>t" "y\<in>t" "f x = f y"
  2.2684 +    hence "x \<in> f x"  "y \<in> f x \<longrightarrow> y = x" using f[THEN bspec[where x=x]] and `t\<subseteq>s` by auto
  2.2685 +    hence "x = y" using `f x = f y` and f[THEN bspec[where x=y]] and `y\<in>t` and `t\<subseteq>s` by auto  }
  2.2686 +  hence "infinite (f ` t)" using assms(2) using finite_imageD[unfolded inj_on_def, of f t] by auto
  2.2687 +  moreover
  2.2688 +  { fix x assume "x\<in>t" "f x \<notin> g"
  2.2689 +    from g(3) assms(3) `x\<in>t` obtain h where "h\<in>g" and "x\<in>h" by auto
  2.2690 +    then obtain y where "y\<in>s" "h = f y" using g'[THEN bspec[where x=h]] by auto
  2.2691 +    hence "y = x" using f[THEN bspec[where x=y]] and `x\<in>t` and `x\<in>h`[unfolded `h = f y`] by auto
  2.2692 +    hence False using `f x \<notin> g` `h\<in>g` unfolding `h = f y` by auto  }
  2.2693 +  hence "f ` t \<subseteq> g" by auto
  2.2694 +  ultimately show False using g(2) using finite_subset by auto
  2.2695 +qed
  2.2696 +
  2.2697 +subsection{* Complete the chain of compactness variants. *}
  2.2698 +
  2.2699 +primrec helper_2::"(real \<Rightarrow> 'a::metric_space) \<Rightarrow> nat \<Rightarrow> 'a" where
  2.2700 +  "helper_2 beyond 0 = beyond 0" |
  2.2701 +  "helper_2 beyond (Suc n) = beyond (dist arbitrary (helper_2 beyond n) + 1 )"
  2.2702 +
  2.2703 +lemma bolzano_weierstrass_imp_bounded: fixes s::"'a::metric_space set"
  2.2704 +  assumes "\<forall>t. infinite t \<and> t \<subseteq> s --> (\<exists>x \<in> s. x islimpt t)"
  2.2705 +  shows "bounded s"
  2.2706 +proof(rule ccontr)
  2.2707 +  assume "\<not> bounded s"
  2.2708 +  then obtain beyond where "\<forall>a. beyond a \<in>s \<and> \<not> dist arbitrary (beyond a) \<le> a"
  2.2709 +    unfolding bounded_any_center [where a=arbitrary]
  2.2710 +    apply simp using choice[of "\<lambda>a x. x\<in>s \<and> \<not> dist arbitrary x \<le> a"] by auto
  2.2711 +  hence beyond:"\<And>a. beyond a \<in>s" "\<And>a. dist arbitrary (beyond a) > a"
  2.2712 +    unfolding linorder_not_le by auto
  2.2713 +  def x \<equiv> "helper_2 beyond"
  2.2714 +
  2.2715 +  { fix m n ::nat assume "m<n"
  2.2716 +    hence "dist arbitrary (x m) + 1 < dist arbitrary (x n)"
  2.2717 +    proof(induct n)
  2.2718 +      case 0 thus ?case by auto
  2.2719 +    next
  2.2720 +      case (Suc n)
  2.2721 +      have *:"dist arbitrary (x n) + 1 < dist arbitrary (x (Suc n))"
  2.2722 +        unfolding x_def and helper_2.simps
  2.2723 +	using beyond(2)[of "dist arbitrary (helper_2 beyond n) + 1"] by auto
  2.2724 +      thus ?case proof(cases "m < n")
  2.2725 +	case True thus ?thesis using Suc and * by auto
  2.2726 +      next
  2.2727 +	case False hence "m = n" using Suc(2) by auto
  2.2728 +	thus ?thesis using * by auto
  2.2729 +      qed
  2.2730 +    qed  } note * = this
  2.2731 +  { fix m n ::nat assume "m\<noteq>n"
  2.2732 +    have "1 < dist (x m) (x n)"
  2.2733 +    proof(cases "m<n")
  2.2734 +      case True
  2.2735 +      hence "1 < dist arbitrary (x n) - dist arbitrary (x m)" using *[of m n] by auto
  2.2736 +      thus ?thesis using dist_triangle [of arbitrary "x n" "x m"] by arith
  2.2737 +    next
  2.2738 +      case False hence "n<m" using `m\<noteq>n` by auto
  2.2739 +      hence "1 < dist arbitrary (x m) - dist arbitrary (x n)" using *[of n m] by auto
  2.2740 +      thus ?thesis using dist_triangle2 [of arbitrary "x m" "x n"] by arith
  2.2741 +    qed  } note ** = this
  2.2742 +  { fix a b assume "x a = x b" "a \<noteq> b"
  2.2743 +    hence False using **[of a b] by auto  }
  2.2744 +  hence "inj x" unfolding inj_on_def by auto
  2.2745 +  moreover
  2.2746 +  { fix n::nat
  2.2747 +    have "x n \<in> s"
  2.2748 +    proof(cases "n = 0")
  2.2749 +      case True thus ?thesis unfolding x_def using beyond by auto
  2.2750 +    next
  2.2751 +      case False then obtain z where "n = Suc z" using not0_implies_Suc by auto
  2.2752 +      thus ?thesis unfolding x_def using beyond by auto
  2.2753 +    qed  }
  2.2754 +  ultimately have "infinite (range x) \<and> range x \<subseteq> s" unfolding x_def using range_inj_infinite[of "helper_2 beyond"] using beyond(1) by auto
  2.2755 +
  2.2756 +  then obtain l where "l\<in>s" and l:"l islimpt range x" using assms[THEN spec[where x="range x"]] by auto
  2.2757 +  then obtain y where "x y \<noteq> l" and y:"dist (x y) l < 1/2" unfolding islimpt_approachable apply(erule_tac x="1/2" in allE) by auto
  2.2758 +  then obtain z where "x z \<noteq> l" and z:"dist (x z) l < dist (x y) l" using l[unfolded islimpt_approachable, THEN spec[where x="dist (x y) l"]]
  2.2759 +    unfolding dist_nz by auto
  2.2760 +  show False using y and z and dist_triangle_half_l[of "x y" l 1 "x z"] and **[of y z] by auto
  2.2761 +qed
  2.2762 +
  2.2763 +lemma sequence_infinite_lemma:
  2.2764 +  fixes l :: "'a::metric_space" (* TODO: generalize *)
  2.2765 +  assumes "\<forall>n::nat. (f n  \<noteq> l)"  "(f ---> l) sequentially"
  2.2766 +  shows "infinite {y. (\<exists> n. y = f n)}"
  2.2767 +proof(rule ccontr)
  2.2768 +  let ?A = "(\<lambda>x. dist x l) ` {y. \<exists>n. y = f n}"
  2.2769 +  assume "\<not> infinite {y. \<exists>n. y = f n}"
  2.2770 +  hence **:"finite ?A" "?A \<noteq> {}" by auto
  2.2771 +  obtain k where k:"dist (f k) l = Min ?A" using Min_in[OF **] by auto
  2.2772 +  have "0 < Min ?A" using assms(1) unfolding dist_nz unfolding Min_gr_iff[OF **] by auto
  2.2773 +  then obtain N where "dist (f N) l < Min ?A" using assms(2)[unfolded Lim_sequentially, THEN spec[where x="Min ?A"]] by auto
  2.2774 +  moreover have "dist (f N) l \<in> ?A" by auto
  2.2775 +  ultimately show False using Min_le[OF **(1), of "dist (f N) l"] by auto
  2.2776 +qed
  2.2777 +
  2.2778 +lemma sequence_unique_limpt:
  2.2779 +  fixes l :: "'a::metric_space" (* TODO: generalize *)
  2.2780 +  assumes "\<forall>n::nat. (f n \<noteq> l)"  "(f ---> l) sequentially"  "l' islimpt {y.  (\<exists>n. y = f n)}"
  2.2781 +  shows "l' = l"
  2.2782 +proof(rule ccontr)
  2.2783 +  def e \<equiv> "dist l' l"
  2.2784 +  assume "l' \<noteq> l" hence "e>0" unfolding dist_nz e_def by auto
  2.2785 +  then obtain N::nat where N:"\<forall>n\<ge>N. dist (f n) l < e / 2"
  2.2786 +    using assms(2)[unfolded Lim_sequentially, THEN spec[where x="e/2"]] by auto
  2.2787 +  def d \<equiv> "Min (insert (e/2) ((\<lambda>n. if dist (f n) l' = 0 then e/2 else dist (f n) l') ` {0 .. N}))"
  2.2788 +  have "d>0" using `e>0` unfolding d_def e_def using zero_le_dist[of _ l', unfolded order_le_less] by auto
  2.2789 +  obtain k where k:"f k \<noteq> l'"  "dist (f k) l' < d" using `d>0` and assms(3)[unfolded islimpt_approachable, THEN spec[where x="d"]] by auto
  2.2790 +  have "k\<ge>N" using k(1)[unfolded dist_nz] using k(2)[unfolded d_def]
  2.2791 +    by force
  2.2792 +  hence "dist l' l < e" using N[THEN spec[where x=k]] using k(2)[unfolded d_def] and dist_triangle_half_r[of "f k" l' e l] by auto
  2.2793 +  thus False unfolding e_def by auto
  2.2794 +qed
  2.2795 +
  2.2796 +lemma bolzano_weierstrass_imp_closed:
  2.2797 +  fixes s :: "'a::metric_space set" (* TODO: can this be generalized? *)
  2.2798 +  assumes "\<forall>t. infinite t \<and> t \<subseteq> s --> (\<exists>x \<in> s. x islimpt t)"
  2.2799 +  shows "closed s"
  2.2800 +proof-
  2.2801 +  { fix x l assume as: "\<forall>n::nat. x n \<in> s" "(x ---> l) sequentially"
  2.2802 +    hence "l \<in> s"
  2.2803 +    proof(cases "\<forall>n. x n \<noteq> l")
  2.2804 +      case False thus "l\<in>s" using as(1) by auto
  2.2805 +    next
  2.2806 +      case True note cas = this
  2.2807 +      with as(2) have "infinite {y. \<exists>n. y = x n}" using sequence_infinite_lemma[of x l] by auto
  2.2808 +      then obtain l' where "l'\<in>s" "l' islimpt {y. \<exists>n. y = x n}" using assms[THEN spec[where x="{y. \<exists>n. y = x n}"]] as(1) by auto
  2.2809 +      thus "l\<in>s" using sequence_unique_limpt[of x l l'] using as cas by auto
  2.2810 +    qed  }
  2.2811 +  thus ?thesis unfolding closed_sequential_limits by fast
  2.2812 +qed
  2.2813 +
  2.2814 +text{* Hence express everything as an equivalence.   *}
  2.2815 +
  2.2816 +lemma compact_eq_heine_borel:
  2.2817 +  fixes s :: "'a::heine_borel set"
  2.2818 +  shows "compact s \<longleftrightarrow>
  2.2819 +           (\<forall>f. (\<forall>t \<in> f. open t) \<and> s \<subseteq> (\<Union> f)
  2.2820 +               --> (\<exists>f'. f' \<subseteq> f \<and> finite f' \<and> s \<subseteq> (\<Union> f')))" (is "?lhs = ?rhs")
  2.2821 +proof
  2.2822 +  assume ?lhs thus ?rhs using compact_imp_heine_borel[of s] by blast
  2.2823 +next
  2.2824 +  assume ?rhs
  2.2825 +  hence "\<forall>t. infinite t \<and> t \<subseteq> s \<longrightarrow> (\<exists>x\<in>s. x islimpt t)"
  2.2826 +    by (blast intro: heine_borel_imp_bolzano_weierstrass[of s])
  2.2827 +  thus ?lhs using bolzano_weierstrass_imp_bounded[of s] bolzano_weierstrass_imp_closed[of s] bounded_closed_imp_compact[of s] by blast
  2.2828 +qed
  2.2829 +
  2.2830 +lemma compact_eq_bolzano_weierstrass:
  2.2831 +  fixes s :: "'a::heine_borel set"
  2.2832 +  shows "compact s \<longleftrightarrow> (\<forall>t. infinite t \<and> t \<subseteq> s --> (\<exists>x \<in> s. x islimpt t))" (is "?lhs = ?rhs")
  2.2833 +proof
  2.2834 +  assume ?lhs thus ?rhs unfolding compact_eq_heine_borel using heine_borel_imp_bolzano_weierstrass[of s] by auto
  2.2835 +next
  2.2836 +  assume ?rhs thus ?lhs using bolzano_weierstrass_imp_bounded bolzano_weierstrass_imp_closed bounded_closed_imp_compact by auto
  2.2837 +qed
  2.2838 +
  2.2839 +lemma compact_eq_bounded_closed:
  2.2840 +  fixes s :: "'a::heine_borel set"
  2.2841 +  shows "compact s \<longleftrightarrow> bounded s \<and> closed s"  (is "?lhs = ?rhs")
  2.2842 +proof
  2.2843 +  assume ?lhs thus ?rhs unfolding compact_eq_bolzano_weierstrass using bolzano_weierstrass_imp_bounded bolzano_weierstrass_imp_closed by auto
  2.2844 +next
  2.2845 +  assume ?rhs thus ?lhs using bounded_closed_imp_compact by auto
  2.2846 +qed
  2.2847 +
  2.2848 +lemma compact_imp_bounded:
  2.2849 +  fixes s :: "'a::metric_space set"
  2.2850 +  shows "compact s ==> bounded s"
  2.2851 +proof -
  2.2852 +  assume "compact s"
  2.2853 +  hence "\<forall>f. (\<forall>t\<in>f. open t) \<and> s \<subseteq> \<Union>f \<longrightarrow> (\<exists>f'\<subseteq>f. finite f' \<and> s \<subseteq> \<Union>f')"
  2.2854 +    by (rule compact_imp_heine_borel)
  2.2855 +  hence "\<forall>t. infinite t \<and> t \<subseteq> s \<longrightarrow> (\<exists>x \<in> s. x islimpt t)"
  2.2856 +    using heine_borel_imp_bolzano_weierstrass[of s] by auto
  2.2857 +  thus "bounded s"
  2.2858 +    by (rule bolzano_weierstrass_imp_bounded)
  2.2859 +qed
  2.2860 +
  2.2861 +lemma compact_imp_closed:
  2.2862 +  fixes s :: "'a::metric_space set"
  2.2863 +  shows "compact s ==> closed s"
  2.2864 +proof -
  2.2865 +  assume "compact s"
  2.2866 +  hence "\<forall>f. (\<forall>t\<in>f. open t) \<and> s \<subseteq> \<Union>f \<longrightarrow> (\<exists>f'\<subseteq>f. finite f' \<and> s \<subseteq> \<Union>f')"
  2.2867 +    by (rule compact_imp_heine_borel)
  2.2868 +  hence "\<forall>t. infinite t \<and> t \<subseteq> s \<longrightarrow> (\<exists>x \<in> s. x islimpt t)"
  2.2869 +    using heine_borel_imp_bolzano_weierstrass[of s] by auto
  2.2870 +  thus "closed s"
  2.2871 +    by (rule bolzano_weierstrass_imp_closed)
  2.2872 +qed
  2.2873 +
  2.2874 +text{* In particular, some common special cases. *}
  2.2875 +
  2.2876 +lemma compact_empty[simp]:
  2.2877 + "compact {}"
  2.2878 +  unfolding compact_def
  2.2879 +  by simp
  2.2880 +
  2.2881 +(* TODO: can any of the next 3 lemmas be generalized to metric spaces? *)
  2.2882 +
  2.2883 +  (* FIXME : Rename *)
  2.2884 +lemma compact_union[intro]:
  2.2885 +  fixes s t :: "'a::heine_borel set"
  2.2886 +  shows "compact s \<Longrightarrow> compact t ==> compact (s \<union> t)"
  2.2887 +  unfolding compact_eq_bounded_closed
  2.2888 +  using bounded_Un[of s t]
  2.2889 +  using closed_Un[of s t]
  2.2890 +  by simp
  2.2891 +
  2.2892 +lemma compact_inter[intro]:
  2.2893 +  fixes s t :: "'a::heine_borel set"
  2.2894 +  shows "compact s \<Longrightarrow> compact t ==> compact (s \<inter> t)"
  2.2895 +  unfolding compact_eq_bounded_closed
  2.2896 +  using bounded_Int[of s t]
  2.2897 +  using closed_Int[of s t]
  2.2898 +  by simp
  2.2899 +
  2.2900 +lemma compact_inter_closed[intro]:
  2.2901 +  fixes s t :: "'a::heine_borel set"
  2.2902 +  shows "compact s \<Longrightarrow> closed t ==> compact (s \<inter> t)"
  2.2903 +  unfolding compact_eq_bounded_closed
  2.2904 +  using closed_Int[of s t]
  2.2905 +  using bounded_subset[of "s \<inter> t" s]
  2.2906 +  by blast
  2.2907 +
  2.2908 +lemma closed_inter_compact[intro]:
  2.2909 +  fixes s t :: "'a::heine_borel set"
  2.2910 +  shows "closed s \<Longrightarrow> compact t ==> compact (s \<inter> t)"
  2.2911 +proof-
  2.2912 +  assume "closed s" "compact t"
  2.2913 +  moreover
  2.2914 +  have "s \<inter> t = t \<inter> s" by auto ultimately
  2.2915 +  show ?thesis
  2.2916 +    using compact_inter_closed[of t s]
  2.2917 +    by auto
  2.2918 +qed
  2.2919 +
  2.2920 +lemma closed_sing [simp]:
  2.2921 +  fixes a :: "'a::metric_space"
  2.2922 +  shows "closed {a}"
  2.2923 +  apply (clarsimp simp add: closed_def open_dist)
  2.2924 +  apply (rule ccontr)
  2.2925 +  apply (drule_tac x="dist x a" in spec)
  2.2926 +  apply (simp add: dist_nz dist_commute)
  2.2927 +  done
  2.2928 +
  2.2929 +lemma finite_imp_closed:
  2.2930 +  fixes s :: "'a::metric_space set"
  2.2931 +  shows "finite s ==> closed s"
  2.2932 +proof (induct set: finite)
  2.2933 +  case empty show "closed {}" by simp
  2.2934 +next
  2.2935 +  case (insert x F)
  2.2936 +  hence "closed ({x} \<union> F)" by (simp only: closed_Un closed_sing)
  2.2937 +  thus "closed (insert x F)" by simp
  2.2938 +qed
  2.2939 +
  2.2940 +lemma finite_imp_compact:
  2.2941 +  fixes s :: "'a::heine_borel set"
  2.2942 +  shows "finite s ==> compact s"
  2.2943 +  unfolding compact_eq_bounded_closed
  2.2944 +  using finite_imp_closed finite_imp_bounded
  2.2945 +  by blast
  2.2946 +
  2.2947 +lemma compact_sing [simp]: "compact {a}"
  2.2948 +  unfolding compact_def o_def subseq_def
  2.2949 +  by (auto simp add: tendsto_const)
  2.2950 +
  2.2951 +lemma compact_cball[simp]:
  2.2952 +  fixes x :: "'a::heine_borel"
  2.2953 +  shows "compact(cball x e)"
  2.2954 +  using compact_eq_bounded_closed bounded_cball closed_cball
  2.2955 +  by blast
  2.2956 +
  2.2957 +lemma compact_frontier_bounded[intro]:
  2.2958 +  fixes s :: "'a::heine_borel set"
  2.2959 +  shows "bounded s ==> compact(frontier s)"
  2.2960 +  unfolding frontier_def
  2.2961 +  using compact_eq_bounded_closed
  2.2962 +  by blast
  2.2963 +
  2.2964 +lemma compact_frontier[intro]:
  2.2965 +  fixes s :: "'a::heine_borel set"
  2.2966 +  shows "compact s ==> compact (frontier s)"
  2.2967 +  using compact_eq_bounded_closed compact_frontier_bounded
  2.2968 +  by blast
  2.2969 +
  2.2970 +lemma frontier_subset_compact:
  2.2971 +  fixes s :: "'a::heine_borel set"
  2.2972 +  shows "compact s ==> frontier s \<subseteq> s"
  2.2973 +  using frontier_subset_closed compact_eq_bounded_closed
  2.2974 +  by blast
  2.2975 +
  2.2976 +lemma open_delete:
  2.2977 +  fixes s :: "'a::metric_space set"
  2.2978 +  shows "open s ==> open(s - {x})"
  2.2979 +  using open_Diff[of s "{x}"] closed_sing
  2.2980 +  by blast
  2.2981 +
  2.2982 +text{* Finite intersection property. I could make it an equivalence in fact. *}
  2.2983 +
  2.2984 +lemma compact_imp_fip:
  2.2985 +  fixes s :: "'a::heine_borel set"
  2.2986 +  assumes "compact s"  "\<forall>t \<in> f. closed t"
  2.2987 +        "\<forall>f'. finite f' \<and> f' \<subseteq> f --> (s \<inter> (\<Inter> f') \<noteq> {})"
  2.2988 +  shows "s \<inter> (\<Inter> f) \<noteq> {}"
  2.2989 +proof
  2.2990 +  assume as:"s \<inter> (\<Inter> f) = {}"
  2.2991 +  hence "s \<subseteq> \<Union>op - UNIV ` f" by auto
  2.2992 +  moreover have "Ball (op - UNIV ` f) open" using open_Diff closed_Diff using assms(2) by auto
  2.2993 +  ultimately obtain f' where f':"f' \<subseteq> op - UNIV ` f"  "finite f'"  "s \<subseteq> \<Union>f'" using assms(1)[unfolded compact_eq_heine_borel, THEN spec[where x="(\<lambda>t. UNIV - t) ` f"]] by auto
  2.2994 +  hence "finite (op - UNIV ` f') \<and> op - UNIV ` f' \<subseteq> f" by(auto simp add: Diff_Diff_Int)
  2.2995 +  hence "s \<inter> \<Inter>op - UNIV ` f' \<noteq> {}" using assms(3)[THEN spec[where x="op - UNIV ` f'"]] by auto
  2.2996 +  thus False using f'(3) unfolding subset_eq and Union_iff by blast
  2.2997 +qed
  2.2998 +
  2.2999 +subsection{* Bounded closed nest property (proof does not use Heine-Borel).            *}
  2.3000 +
  2.3001 +lemma bounded_closed_nest:
  2.3002 +  assumes "\<forall>n. closed(s n)" "\<forall>n. (s n \<noteq> {})"
  2.3003 +  "(\<forall>m n. m \<le> n --> s n \<subseteq> s m)"  "bounded(s 0)"
  2.3004 +  shows "\<exists>a::'a::heine_borel. \<forall>n::nat. a \<in> s(n)"
  2.3005 +proof-
  2.3006 +  from assms(2) obtain x where x:"\<forall>n::nat. x n \<in> s n" using choice[of "\<lambda>n x. x\<in> s n"] by auto
  2.3007 +  from assms(4,1) have *:"compact (s 0)" using bounded_closed_imp_compact[of "s 0"] by auto
  2.3008 +
  2.3009 +  then obtain l r where lr:"l\<in>s 0" "subseq r" "((x \<circ> r) ---> l) sequentially"
  2.3010 +    unfolding compact_def apply(erule_tac x=x in allE)  using x using assms(3) by blast
  2.3011 +
  2.3012 +  { fix n::nat
  2.3013 +    { fix e::real assume "e>0"
  2.3014 +      with lr(3) obtain N where N:"\<forall>m\<ge>N. dist ((x \<circ> r) m) l < e" unfolding Lim_sequentially by auto
  2.3015 +      hence "dist ((x \<circ> r) (max N n)) l < e" by auto
  2.3016 +      moreover
  2.3017 +      have "r (max N n) \<ge> n" using lr(2) using subseq_bigger[of r "max N n"] by auto
  2.3018 +      hence "(x \<circ> r) (max N n) \<in> s n"
  2.3019 +	using x apply(erule_tac x=n in allE)
  2.3020 +	using x apply(erule_tac x="r (max N n)" in allE)
  2.3021 +	using assms(3) apply(erule_tac x=n in allE)apply( erule_tac x="r (max N n)" in allE) by auto
  2.3022 +      ultimately have "\<exists>y\<in>s n. dist y l < e" by auto
  2.3023 +    }
  2.3024 +    hence "l \<in> s n" using closed_approachable[of "s n" l] assms(1) by blast
  2.3025 +  }
  2.3026 +  thus ?thesis by auto
  2.3027 +qed
  2.3028 +
  2.3029 +text{* Decreasing case does not even need compactness, just completeness.        *}
  2.3030 +
  2.3031 +lemma decreasing_closed_nest:
  2.3032 +  assumes "\<forall>n. closed(s n)"
  2.3033 +          "\<forall>n. (s n \<noteq> {})"
  2.3034 +          "\<forall>m n. m \<le> n --> s n \<subseteq> s m"
  2.3035 +          "\<forall>e>0. \<exists>n. \<forall>x \<in> (s n). \<forall> y \<in> (s n). dist x y < e"
  2.3036 +  shows "\<exists>a::'a::heine_borel. \<forall>n::nat. a \<in> s n"
  2.3037 +proof-
  2.3038 +  have "\<forall>n. \<exists> x. x\<in>s n" using assms(2) by auto
  2.3039 +  hence "\<exists>t. \<forall>n. t n \<in> s n" using choice[of "\<lambda> n x. x \<in> s n"] by auto
  2.3040 +  then obtain t where t: "\<forall>n. t n \<in> s n" by auto
  2.3041 +  { fix e::real assume "e>0"
  2.3042 +    then obtain N where N:"\<forall>x\<in>s N. \<forall>y\<in>s N. dist x y < e" using assms(4) by auto
  2.3043 +    { fix m n ::nat assume "N \<le> m \<and> N \<le> n"
  2.3044 +      hence "t m \<in> s N" "t n \<in> s N" using assms(3) t unfolding  subset_eq t by blast+
  2.3045 +      hence "dist (t m) (t n) < e" using N by auto
  2.3046 +    }
  2.3047 +    hence "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (t m) (t n) < e" by auto
  2.3048 +  }
  2.3049 +  hence  "Cauchy t" unfolding cauchy_def by auto
  2.3050 +  then obtain l where l:"(t ---> l) sequentially" using complete_univ unfolding complete_def by auto
  2.3051 +  { fix n::nat
  2.3052 +    { fix e::real assume "e>0"
  2.3053 +      then obtain N::nat where N:"\<forall>n\<ge>N. dist (t n) l < e" using l[unfolded Lim_sequentially] by auto
  2.3054 +      have "t (max n N) \<in> s n" using assms(3) unfolding subset_eq apply(erule_tac x=n in allE) apply (erule_tac x="max n N" in allE) using t by auto
  2.3055 +      hence "\<exists>y\<in>s n. dist y l < e" apply(rule_tac x="t (max n N)" in bexI) using N by auto
  2.3056 +    }
  2.3057 +    hence "l \<in> s n" using closed_approachable[of "s n" l] assms(1) by auto
  2.3058 +  }
  2.3059 +  then show ?thesis by auto
  2.3060 +qed
  2.3061 +
  2.3062 +text{* Strengthen it to the intersection actually being a singleton.             *}
  2.3063 +
  2.3064 +lemma decreasing_closed_nest_sing:
  2.3065 +  assumes "\<forall>n. closed(s n)"
  2.3066 +          "\<forall>n. s n \<noteq> {}"
  2.3067 +          "\<forall>m n. m \<le> n --> s n \<subseteq> s m"
  2.3068 +          "\<forall>e>0. \<exists>n. \<forall>x \<in> (s n). \<forall> y\<in>(s n). dist x y < e"
  2.3069 +  shows "\<exists>a::'a::heine_borel. \<Inter> {t. (\<exists>n::nat. t = s n)} = {a}"
  2.3070 +proof-
  2.3071 +  obtain a where a:"\<forall>n. a \<in> s n" using decreasing_closed_nest[of s] using assms by auto
  2.3072 +  { fix b assume b:"b \<in> \<Inter>{t. \<exists>n. t = s n}"
  2.3073 +    { fix e::real assume "e>0"
  2.3074 +      hence "dist a b < e" using assms(4 )using b using a by blast
  2.3075 +    }
  2.3076 +    hence "dist a b = 0" by (metis dist_eq_0_iff dist_nz real_less_def)
  2.3077 +  }
  2.3078 +  with a have "\<Inter>{t. \<exists>n. t = s n} = {a}"  by auto
  2.3079 +  thus ?thesis by auto
  2.3080 +qed
  2.3081 +
  2.3082 +text{* Cauchy-type criteria for uniform convergence. *}
  2.3083 +
  2.3084 +lemma uniformly_convergent_eq_cauchy: fixes s::"nat \<Rightarrow> 'b \<Rightarrow> 'a::heine_borel" shows
  2.3085 + "(\<exists>l. \<forall>e>0. \<exists>N. \<forall>n x. N \<le> n \<and> P x --> dist(s n x)(l x) < e) \<longleftrightarrow>
  2.3086 +  (\<forall>e>0. \<exists>N. \<forall>m n x. N \<le> m \<and> N \<le> n \<and> P x  --> dist (s m x) (s n x) < e)" (is "?lhs = ?rhs")
  2.3087 +proof(rule)
  2.3088 +  assume ?lhs
  2.3089 +  then obtain l where l:"\<forall>e>0. \<exists>N. \<forall>n x. N \<le> n \<and> P x \<longrightarrow> dist (s n x) (l x) < e" by auto
  2.3090 +  { fix e::real assume "e>0"
  2.3091 +    then obtain N::nat where N:"\<forall>n x. N \<le> n \<and> P x \<longrightarrow> dist (s n x) (l x) < e / 2" using l[THEN spec[where x="e/2"]] by auto
  2.3092 +    { fix n m::nat and x::"'b" assume "N \<le> m \<and> N \<le> n \<and> P x"
  2.3093 +      hence "dist (s m x) (s n x) < e"
  2.3094 +	using N[THEN spec[where x=m], THEN spec[where x=x]]
  2.3095 +	using N[THEN spec[where x=n], THEN spec[where x=x]]
  2.3096 +	using dist_triangle_half_l[of "s m x" "l x" e "s n x"] by auto  }
  2.3097 +    hence "\<exists>N. \<forall>m n x. N \<le> m \<and> N \<le> n \<and> P x  --> dist (s m x) (s n x) < e"  by auto  }
  2.3098 +  thus ?rhs by auto
  2.3099 +next
  2.3100 +  assume ?rhs
  2.3101 +  hence "\<forall>x. P x \<longrightarrow> Cauchy (\<lambda>n. s n x)" unfolding cauchy_def apply auto by (erule_tac x=e in allE)auto
  2.3102 +  then obtain l where l:"\<forall>x. P x \<longrightarrow> ((\<lambda>n. s n x) ---> l x) sequentially" unfolding convergent_eq_cauchy[THEN sym]
  2.3103 +    using choice[of "\<lambda>x l. P x \<longrightarrow> ((\<lambda>n. s n x) ---> l) sequentially"] by auto
  2.3104 +  { fix e::real assume "e>0"
  2.3105 +    then obtain N where N:"\<forall>m n x. N \<le> m \<and> N \<le> n \<and> P x \<longrightarrow> dist (s m x) (s n x) < e/2"
  2.3106 +      using `?rhs`[THEN spec[where x="e/2"]] by auto
  2.3107 +    { fix x assume "P x"
  2.3108 +      then obtain M where M:"\<forall>n\<ge>M. dist (s n x) (l x) < e/2"
  2.3109 +	using l[THEN spec[where x=x], unfolded Lim_sequentially] using `e>0` by(auto elim!: allE[where x="e/2"])
  2.3110 +      fix n::nat assume "n\<ge>N"
  2.3111 +      hence "dist(s n x)(l x) < e"  using `P x`and N[THEN spec[where x=n], THEN spec[where x="N+M"], THEN spec[where x=x]]
  2.3112 +	using M[THEN spec[where x="N+M"]] and dist_triangle_half_l[of "s n x" "s (N+M) x" e "l x"] by (auto simp add: dist_commute)  }
  2.3113 +    hence "\<exists>N. \<forall>n x. N \<le> n \<and> P x \<longrightarrow> dist(s n x)(l x) < e" by auto }
  2.3114 +  thus ?lhs by auto
  2.3115 +qed
  2.3116 +
  2.3117 +lemma uniformly_cauchy_imp_uniformly_convergent:
  2.3118 +  fixes s :: "nat \<Rightarrow> 'a \<Rightarrow> 'b::heine_borel"
  2.3119 +  assumes "\<forall>e>0.\<exists>N. \<forall>m (n::nat) x. N \<le> m \<and> N \<le> n \<and> P x --> dist(s m x)(s n x) < e"
  2.3120 +          "\<forall>x. P x --> (\<forall>e>0. \<exists>N. \<forall>n. N \<le> n --> dist(s n x)(l x) < e)"
  2.3121 +  shows "\<forall>e>0. \<exists>N. \<forall>n x. N \<le> n \<and> P x --> dist(s n x)(l x) < e"
  2.3122 +proof-
  2.3123 +  obtain l' where l:"\<forall>e>0. \<exists>N. \<forall>n x. N \<le> n \<and> P x \<longrightarrow> dist (s n x) (l' x) < e"
  2.3124 +    using assms(1) unfolding uniformly_convergent_eq_cauchy[THEN sym] by auto
  2.3125 +  moreover
  2.3126 +  { fix x assume "P x"
  2.3127 +    hence "l x = l' x" using Lim_unique[OF trivial_limit_sequentially, of "\<lambda>n. s n x" "l x" "l' x"]
  2.3128 +      using l and assms(2) unfolding Lim_sequentially by blast  }
  2.3129 +  ultimately show ?thesis by auto
  2.3130 +qed
  2.3131 +
  2.3132 +subsection{* Define continuity over a net to take in restrictions of the set. *}
  2.3133 +
  2.3134 +definition
  2.3135 +  continuous :: "'a::t2_space net \<Rightarrow> ('a \<Rightarrow> 'b::topological_space) \<Rightarrow> bool" where
  2.3136 +  "continuous net f \<longleftrightarrow> (f ---> f(netlimit net)) net"
  2.3137 +
  2.3138 +lemma continuous_trivial_limit:
  2.3139 + "trivial_limit net ==> continuous net f"
  2.3140 +  unfolding continuous_def tendsto_def trivial_limit_eq by auto
  2.3141 +
  2.3142 +lemma continuous_within: "continuous (at x within s) f \<longleftrightarrow> (f ---> f(x)) (at x within s)"
  2.3143 +  unfolding continuous_def
  2.3144 +  unfolding tendsto_def
  2.3145 +  using netlimit_within[of x s]
  2.3146 +  by (cases "trivial_limit (at x within s)") (auto simp add: trivial_limit_eventually)
  2.3147 +
  2.3148 +lemma continuous_at: "continuous (at x) f \<longleftrightarrow> (f ---> f(x)) (at x)"
  2.3149 +  using continuous_within [of x UNIV f] by (simp add: within_UNIV)
  2.3150 +
  2.3151 +lemma continuous_at_within:
  2.3152 +  assumes "continuous (at x) f"  shows "continuous (at x within s) f"
  2.3153 +  using assms unfolding continuous_at continuous_within
  2.3154 +  by (rule Lim_at_within)
  2.3155 +
  2.3156 +text{* Derive the epsilon-delta forms, which we often use as "definitions" *}
  2.3157 +
  2.3158 +lemma continuous_within_eps_delta:
  2.3159 +  "continuous (at x within s) f \<longleftrightarrow> (\<forall>e>0. \<exists>d>0. \<forall>x'\<in> s.  dist x' x < d --> dist (f x') (f x) < e)"
  2.3160 +  unfolding continuous_within and Lim_within
  2.3161 +  apply auto unfolding dist_nz[THEN sym] apply(auto elim!:allE) apply(rule_tac x=d in exI) by auto
  2.3162 +
  2.3163 +lemma continuous_at_eps_delta: "continuous (at x) f \<longleftrightarrow>  (\<forall>e>0. \<exists>d>0.
  2.3164 +                           \<forall>x'. dist x' x < d --> dist(f x')(f x) < e)"
  2.3165 +  using continuous_within_eps_delta[of x UNIV f]
  2.3166 +  unfolding within_UNIV by blast
  2.3167 +
  2.3168 +text{* Versions in terms of open balls. *}
  2.3169 +
  2.3170 +lemma continuous_within_ball:
  2.3171 + "continuous (at x within s) f \<longleftrightarrow> (\<forall>e>0. \<exists>d>0.
  2.3172 +                            f ` (ball x d \<inter> s) \<subseteq> ball (f x) e)" (is "?lhs = ?rhs")
  2.3173 +proof
  2.3174 +  assume ?lhs
  2.3175 +  { fix e::real assume "e>0"
  2.3176 +    then obtain d where d: "d>0" "\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e"
  2.3177 +      using `?lhs`[unfolded continuous_within Lim_within] by auto
  2.3178 +    { fix y assume "y\<in>f ` (ball x d \<inter> s)"
  2.3179 +      hence "y \<in> ball (f x) e" using d(2) unfolding dist_nz[THEN sym]
  2.3180 +	apply (auto simp add: dist_commute mem_ball) apply(erule_tac x=xa in ballE) apply auto using `e>0` by auto
  2.3181 +    }
  2.3182 +    hence "\<exists>d>0. f ` (ball x d \<inter> s) \<subseteq> ball (f x) e" using `d>0` unfolding subset_eq ball_def by (auto simp add: dist_commute)  }
  2.3183 +  thus ?rhs by auto
  2.3184 +next
  2.3185 +  assume ?rhs thus ?lhs unfolding continuous_within Lim_within ball_def subset_eq
  2.3186 +    apply (auto simp add: dist_commute) apply(erule_tac x=e in allE) by auto
  2.3187 +qed
  2.3188 +
  2.3189 +lemma continuous_at_ball:
  2.3190 +  "continuous (at x) f \<longleftrightarrow> (\<forall>e>0. \<exists>d>0. f ` (ball x d) \<subseteq> ball (f x) e)" (is "?lhs = ?rhs")
  2.3191 +proof
  2.3192 +  assume ?lhs thus ?rhs unfolding continuous_at Lim_at subset_eq Ball_def Bex_def image_iff mem_ball
  2.3193 +    apply auto apply(erule_tac x=e in allE) apply auto apply(rule_tac x=d in exI) apply auto apply(erule_tac x=xa in allE) apply (auto simp add: dist_commute dist_nz)
  2.3194 +    unfolding dist_nz[THEN sym] by auto
  2.3195 +next
  2.3196 +  assume ?rhs thus ?lhs unfolding continuous_at Lim_at subset_eq Ball_def Bex_def image_iff mem_ball
  2.3197 +    apply auto apply(erule_tac x=e in allE) apply auto apply(rule_tac x=d in exI) apply auto apply(erule_tac x="f xa" in allE) by (auto simp add: dist_commute dist_nz)
  2.3198 +qed
  2.3199 +
  2.3200 +text{* For setwise continuity, just start from the epsilon-delta definitions. *}
  2.3201 +
  2.3202 +definition
  2.3203 +  continuous_on :: "'a::metric_space set \<Rightarrow> ('a \<Rightarrow> 'b::metric_space) \<Rightarrow> bool" where
  2.3204 +  "continuous_on s f \<longleftrightarrow> (\<forall>x \<in> s. \<forall>e>0. \<exists>d::real>0. \<forall>x' \<in> s. dist x' x < d --> dist (f x') (f x) < e)"
  2.3205 +
  2.3206 +
  2.3207 +definition
  2.3208 +  uniformly_continuous_on ::
  2.3209 +    "'a::metric_space set \<Rightarrow> ('a \<Rightarrow> 'b::metric_space) \<Rightarrow> bool" where
  2.3210 +  "uniformly_continuous_on s f \<longleftrightarrow>
  2.3211 +        (\<forall>e>0. \<exists>d>0. \<forall>x\<in>s. \<forall> x'\<in>s. dist x' x < d
  2.3212 +                           --> dist (f x') (f x) < e)"
  2.3213 +
  2.3214 +text{* Some simple consequential lemmas. *}
  2.3215 +
  2.3216 +lemma uniformly_continuous_imp_continuous:
  2.3217 + " uniformly_continuous_on s f ==> continuous_on s f"
  2.3218 +  unfolding uniformly_continuous_on_def continuous_on_def by blast
  2.3219 +
  2.3220 +lemma continuous_at_imp_continuous_within:
  2.3221 + "continuous (at x) f ==> continuous (at x within s) f"
  2.3222 +  unfolding continuous_within continuous_at using Lim_at_within by auto
  2.3223 +
  2.3224 +lemma continuous_at_imp_continuous_on: assumes "(\<forall>x \<in> s. continuous (at x) f)"
  2.3225 +  shows "continuous_on s f"
  2.3226 +proof(simp add: continuous_at continuous_on_def, rule, rule, rule)
  2.3227 +  fix x and e::real assume "x\<in>s" "e>0"
  2.3228 +  hence "eventually (\<lambda>xa. dist (f xa) (f x) < e) (at x)" using assms unfolding continuous_at tendsto_iff by auto
  2.3229 +  then obtain d where d:"d>0" "\<forall>xa. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e" unfolding eventually_at by auto
  2.3230 +  { fix x' assume "\<not> 0 < dist x' x"
  2.3231 +    hence "x=x'"
  2.3232 +      using dist_nz[of x' x] by auto
  2.3233 +    hence "dist (f x') (f x) < e" using `e>0` by auto
  2.3234 +  }
  2.3235 +  thus "\<exists>d>0. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (f x') (f x) < e" using d by auto
  2.3236 +qed
  2.3237 +
  2.3238 +lemma continuous_on_eq_continuous_within:
  2.3239 + "continuous_on s f \<longleftrightarrow> (\<forall>x \<in> s. continuous (at x within s) f)" (is "?lhs = ?rhs")
  2.3240 +proof
  2.3241 +  assume ?rhs
  2.3242 +  { fix x assume "x\<in>s"
  2.3243 +    fix e::real assume "e>0"
  2.3244 +    assume "\<exists>d>0. \<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e"
  2.3245 +    then obtain d where "d>0" and d:"\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e" by auto
  2.3246 +    { fix x' assume as:"x'\<in>s" "dist x' x < d"
  2.3247 +      hence "dist (f x') (f x) < e" using `e>0` d `x'\<in>s` dist_eq_0_iff[of x' x] zero_le_dist[of x' x] as(2) by (metis dist_eq_0_iff dist_nz) }
  2.3248 +    hence "\<exists>d>0. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (f x') (f x) < e" using `d>0` by auto
  2.3249 +  }
  2.3250 +  thus ?lhs using `?rhs` unfolding continuous_on_def continuous_within Lim_within by auto
  2.3251 +next
  2.3252 +  assume ?lhs
  2.3253 +  thus ?rhs unfolding continuous_on_def continuous_within Lim_within by blast
  2.3254 +qed
  2.3255 +
  2.3256 +lemma continuous_on:
  2.3257 + "continuous_on s f \<longleftrightarrow> (\<forall>x \<in> s. (f ---> f(x)) (at x within s))"
  2.3258 +  by (auto simp add: continuous_on_eq_continuous_within continuous_within)
  2.3259 +
  2.3260 +lemma continuous_on_eq_continuous_at:
  2.3261 + "open s ==> (continuous_on s f \<longleftrightarrow> (\<forall>x \<in> s. continuous (at x) f))"
  2.3262 +  by (auto simp add: continuous_on continuous_at Lim_within_open)
  2.3263 +
  2.3264 +lemma continuous_within_subset:
  2.3265 + "continuous (at x within s) f \<Longrightarrow> t \<subseteq> s
  2.3266 +             ==> continuous (at x within t) f"
  2.3267 +  unfolding continuous_within by(metis Lim_within_subset)
  2.3268 +
  2.3269 +lemma continuous_on_subset:
  2.3270 + "continuous_on s f \<Longrightarrow> t \<subseteq> s ==> continuous_on t f"
  2.3271 +  unfolding continuous_on by (metis subset_eq Lim_within_subset)
  2.3272 +
  2.3273 +lemma continuous_on_interior:
  2.3274 + "continuous_on s f \<Longrightarrow> x \<in> interior s ==> continuous (at x) f"
  2.3275 +unfolding interior_def
  2.3276 +apply simp
  2.3277 +by (meson continuous_on_eq_continuous_at continuous_on_subset)
  2.3278 +
  2.3279 +lemma continuous_on_eq:
  2.3280 + "(\<forall>x \<in> s. f x = g x) \<Longrightarrow> continuous_on s f
  2.3281 +           ==> continuous_on s g"
  2.3282 +  by (simp add: continuous_on_def)
  2.3283 +
  2.3284 +text{* Characterization of various kinds of continuity in terms of sequences.  *}
  2.3285 +
  2.3286 +(* \<longrightarrow> could be generalized, but \<longleftarrow> requires metric space *)
  2.3287 +lemma continuous_within_sequentially:
  2.3288 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  2.3289 +  shows "continuous (at a within s) f \<longleftrightarrow>
  2.3290 +                (\<forall>x. (\<forall>n::nat. x n \<in> s) \<and> (x ---> a) sequentially
  2.3291 +                     --> ((f o x) ---> f a) sequentially)" (is "?lhs = ?rhs")
  2.3292 +proof
  2.3293 +  assume ?lhs
  2.3294 +  { fix x::"nat \<Rightarrow> 'a" assume x:"\<forall>n. x n \<in> s" "\<forall>e>0. \<exists>N. \<forall>n\<ge>N. dist (x n) a < e"
  2.3295 +    fix e::real assume "e>0"
  2.3296 +    from `?lhs` obtain d where "d>0" and d:"\<forall>x\<in>s. 0 < dist x a \<and> dist x a < d \<longrightarrow> dist (f x) (f a) < e" unfolding continuous_within Lim_within using `e>0` by auto
  2.3297 +    from x(2) `d>0` obtain N where N:"\<forall>n\<ge>N. dist (x n) a < d" by auto
  2.3298 +    hence "\<exists>N. \<forall>n\<ge>N. dist ((f \<circ> x) n) (f a) < e"
  2.3299 +      apply(rule_tac  x=N in exI) using N d  apply auto using x(1)
  2.3300 +      apply(erule_tac x=n in allE) apply(erule_tac x=n in allE)
  2.3301 +      apply(erule_tac x="x n" in ballE)  apply auto unfolding dist_nz[THEN sym] apply auto using `e>0` by auto
  2.3302 +  }
  2.3303 +  thus ?rhs unfolding continuous_within unfolding Lim_sequentially by simp
  2.3304 +next
  2.3305 +  assume ?rhs
  2.3306 +  { fix e::real assume "e>0"
  2.3307 +    assume "\<not> (\<exists>d>0. \<forall>x\<in>s. 0 < dist x a \<and> dist x a < d \<longrightarrow> dist (f x) (f a) < e)"
  2.3308 +    hence "\<forall>d. \<exists>x. d>0 \<longrightarrow> x\<in>s \<and> (0 < dist x a \<and> dist x a < d \<and> \<not> dist (f x) (f a) < e)" by blast
  2.3309 +    then obtain x where x:"\<forall>d>0. x d \<in> s \<and> (0 < dist (x d) a \<and> dist (x d) a < d \<and> \<not> dist (f (x d)) (f a) < e)"
  2.3310 +      using choice[of "\<lambda>d x.0<d \<longrightarrow> x\<in>s \<and> (0 < dist x a \<and> dist x a < d \<and> \<not> dist (f x) (f a) < e)"] by auto
  2.3311 +    { fix d::real assume "d>0"
  2.3312 +      hence "\<exists>N::nat. inverse (real (N + 1)) < d" using real_arch_inv[of d] by (auto, rule_tac x="n - 1" in exI)auto
  2.3313 +      then obtain N::nat where N:"inverse (real (N + 1)) < d" by auto
  2.3314 +      { fix n::nat assume n:"n\<ge>N"
  2.3315 +	hence "dist (x (inverse (real (n + 1)))) a < inverse (real (n + 1))" using x[THEN spec[where x="inverse (real (n + 1))"]] by auto
  2.3316 +	moreover have "inverse (real (n + 1)) < d" using N n by (auto, metis Suc_le_mono le_SucE less_imp_inverse_less nat_le_real_less order_less_trans real_of_nat_Suc real_of_nat_Suc_gt_zero)
  2.3317 +	ultimately have "dist (x (inverse (real (n + 1)))) a < d" by auto
  2.3318 +      }
  2.3319 +      hence "\<exists>N::nat. \<forall>n\<ge>N. dist (x (inverse (real (n + 1)))) a < d" by auto
  2.3320 +    }
  2.3321 +    hence "(\<forall>n::nat. x (inverse (real (n + 1))) \<in> s) \<and> (\<forall>e>0. \<exists>N::nat. \<forall>n\<ge>N. dist (x (inverse (real (n + 1)))) a < e)" using x by auto
  2.3322 +    hence "\<forall>e>0. \<exists>N::nat. \<forall>n\<ge>N. dist (f (x (inverse (real (n + 1))))) (f a) < e"  using `?rhs`[THEN spec[where x="\<lambda>n::nat. x (inverse (real (n+1)))"], unfolded Lim_sequentially] by auto
  2.3323 +    hence "False" apply(erule_tac x=e in allE) using `e>0` using x by auto
  2.3324 +  }
  2.3325 +  thus ?lhs  unfolding continuous_within unfolding Lim_within unfolding Lim_sequentially by blast
  2.3326 +qed
  2.3327 +
  2.3328 +lemma continuous_at_sequentially:
  2.3329 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  2.3330 +  shows "continuous (at a) f \<longleftrightarrow> (\<forall>x. (x ---> a) sequentially
  2.3331 +                  --> ((f o x) ---> f a) sequentially)"
  2.3332 +  using continuous_within_sequentially[of a UNIV f] unfolding within_UNIV by auto
  2.3333 +
  2.3334 +lemma continuous_on_sequentially:
  2.3335 + "continuous_on s f \<longleftrightarrow>  (\<forall>x. \<forall>a \<in> s. (\<forall>n. x(n) \<in> s) \<and> (x ---> a) sequentially
  2.3336 +                    --> ((f o x) ---> f(a)) sequentially)" (is "?lhs = ?rhs")
  2.3337 +proof
  2.3338 +  assume ?rhs thus ?lhs using continuous_within_sequentially[of _ s f] unfolding continuous_on_eq_continuous_within by auto
  2.3339 +next
  2.3340 +  assume ?lhs thus ?rhs unfolding continuous_on_eq_continuous_within using continuous_within_sequentially[of _ s f] by auto
  2.3341 +qed
  2.3342 +
  2.3343 +lemma uniformly_continuous_on_sequentially:
  2.3344 +  fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
  2.3345 +  shows "uniformly_continuous_on s f \<longleftrightarrow> (\<forall>x y. (\<forall>n. x n \<in> s) \<and> (\<forall>n. y n \<in> s) \<and>
  2.3346 +                    ((\<lambda>n. x n - y n) ---> 0) sequentially
  2.3347 +                    \<longrightarrow> ((\<lambda>n. f(x n) - f(y n)) ---> 0) sequentially)" (is "?lhs = ?rhs")
  2.3348 +proof
  2.3349 +  assume ?lhs
  2.3350 +  { fix x y assume x:"\<forall>n. x n \<in> s" and y:"\<forall>n. y n \<in> s" and xy:"((\<lambda>n. x n - y n) ---> 0) sequentially"
  2.3351 +    { fix e::real assume "e>0"
  2.3352 +      then obtain d where "d>0" and d:"\<forall>x\<in>s. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (f x') (f x) < e"
  2.3353 +	using `?lhs`[unfolded uniformly_continuous_on_def, THEN spec[where x=e]] by auto
  2.3354 +      obtain N where N:"\<forall>n\<ge>N. norm (x n - y n - 0) < d" using xy[unfolded Lim_sequentially dist_norm] and `d>0` by auto
  2.3355 +      { fix n assume "n\<ge>N"
  2.3356 +	hence "norm (f (x n) - f (y n) - 0) < e"
  2.3357 +	  using N[THEN spec[where x=n]] using d[THEN bspec[where x="x n"], THEN bspec[where x="y n"]] using x and y
  2.3358 +	  unfolding dist_commute and dist_norm by simp  }
  2.3359 +      hence "\<exists>N. \<forall>n\<ge>N. norm (f (x n) - f (y n) - 0) < e"  by auto  }
  2.3360 +    hence "((\<lambda>n. f(x n) - f(y n)) ---> 0) sequentially" unfolding Lim_sequentially and dist_norm by auto  }
  2.3361 +  thus ?rhs by auto
  2.3362 +next
  2.3363 +  assume ?rhs
  2.3364 +  { assume "\<not> ?lhs"
  2.3365 +    then obtain e where "e>0" "\<forall>d>0. \<exists>x\<in>s. \<exists>x'\<in>s. dist x' x < d \<and> \<not> dist (f x') (f x) < e" unfolding uniformly_continuous_on_def by auto
  2.3366 +    then obtain fa where fa:"\<forall>x.  0 < x \<longrightarrow> fst (fa x) \<in> s \<and> snd (fa x) \<in> s \<and> dist (fst (fa x)) (snd (fa x)) < x \<and> \<not> dist (f (fst (fa x))) (f (snd (fa x))) < e"
  2.3367 +      using choice[of "\<lambda>d x. d>0 \<longrightarrow> fst x \<in> s \<and> snd x \<in> s \<and> dist (snd x) (fst x) < d \<and> \<not> dist (f (snd x)) (f (fst x)) < e"] unfolding Bex_def
  2.3368 +      by (auto simp add: dist_commute)
  2.3369 +    def x \<equiv> "\<lambda>n::nat. fst (fa (inverse (real n + 1)))"
  2.3370 +    def y \<equiv> "\<lambda>n::nat. snd (fa (inverse (real n + 1)))"
  2.3371 +    have xyn:"\<forall>n. x n \<in> s \<and> y n \<in> s" and xy0:"\<forall>n. dist (x n) (y n) < inverse (real n + 1)" and fxy:"\<forall>n. \<not> dist (f (x n)) (f (y n)) < e"
  2.3372 +      unfolding x_def and y_def using fa by auto
  2.3373 +    have 1:"\<And>(x::'a) y. dist (x - y) 0 = dist x y" unfolding dist_norm by auto
  2.3374 +    have 2:"\<And>(x::'b) y. dist (x - y) 0 = dist x y" unfolding dist_norm by auto
  2.3375 +    { fix e::real assume "e>0"
  2.3376 +      then obtain N::nat where "N \<noteq> 0" and N:"0 < inverse (real N) \<and> inverse (real N) < e" unfolding real_arch_inv[of e]   by auto
  2.3377 +      { fix n::nat assume "n\<ge>N"
  2.3378 +	hence "inverse (real n + 1) < inverse (real N)" using real_of_nat_ge_zero and `N\<noteq>0` by auto
  2.3379 +	also have "\<dots> < e" using N by auto
  2.3380 +	finally have "inverse (real n + 1) < e" by auto
  2.3381 +	hence "dist (x n - y n) 0 < e" unfolding 1 using xy0[THEN spec[where x=n]] by auto  }
  2.3382 +      hence "\<exists>N. \<forall>n\<ge>N. dist (x n - y n) 0 < e" by auto  }
  2.3383 +    hence "\<forall>e>0. \<exists>N. \<forall>n\<ge>N. dist (f (x n) - f (y n)) 0 < e" using `?rhs`[THEN spec[where x=x], THEN spec[where x=y]] and xyn unfolding Lim_sequentially by auto
  2.3384 +    hence False unfolding 2 using fxy and `e>0` by auto  }
  2.3385 +  thus ?lhs unfolding uniformly_continuous_on_def by blast
  2.3386 +qed
  2.3387 +
  2.3388 +text{* The usual transformation theorems. *}
  2.3389 +
  2.3390 +lemma continuous_transform_within:
  2.3391 +  fixes f g :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  2.3392 +  assumes "0 < d" "x \<in> s" "\<forall>x' \<in> s. dist x' x < d --> f x' = g x'"
  2.3393 +          "continuous (at x within s) f"
  2.3394 +  shows "continuous (at x within s) g"
  2.3395 +proof-
  2.3396 +  { fix e::real assume "e>0"
  2.3397 +    then obtain d' where d':"d'>0" "\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d' \<longrightarrow> dist (f xa) (f x) < e" using assms(4) unfolding continuous_within Lim_within by auto
  2.3398 +    { fix x' assume "x'\<in>s" "0 < dist x' x" "dist x' x < (min d d')"
  2.3399 +      hence "dist (f x') (g x) < e" using assms(2,3) apply(erule_tac x=x in ballE) using d' by auto  }
  2.3400 +    hence "\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < (min d d') \<longrightarrow> dist (f xa) (g x) < e" by blast
  2.3401 +    hence "\<exists>d>0. \<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (g x) < e" using `d>0` `d'>0` by(rule_tac x="min d d'" in exI)auto  }
  2.3402 +  hence "(f ---> g x) (at x within s)" unfolding Lim_within using assms(1) by auto
  2.3403 +  thus ?thesis unfolding continuous_within using Lim_transform_within[of d s x f g "g x"] using assms by blast
  2.3404 +qed
  2.3405 +
  2.3406 +lemma continuous_transform_at:
  2.3407 +  fixes f g :: "'a::metric_space \<Rightarrow> 'b::metric_space"
  2.3408 +  assumes "0 < d" "\<forall>x'. dist x' x < d --> f x' = g x'"
  2.3409 +          "continuous (at x) f"
  2.3410 +  shows "continuous (at x) g"
  2.3411 +proof-
  2.3412 +  { fix e::real assume "e>0"
  2.3413 +    then obtain d' where d':"d'>0" "\<forall>xa. 0 < dist xa x \<and> dist xa x < d' \<longrightarrow> dist (f xa) (f x) < e" using assms(3) unfolding continuous_at Lim_at by auto
  2.3414 +    { fix x' assume "0 < dist x' x" "dist x' x < (min d d')"
  2.3415 +      hence "dist (f x') (g x) < e" using assms(2) apply(erule_tac x=x in allE) using d' by auto
  2.3416 +    }
  2.3417 +    hence "\<forall>xa. 0 < dist xa x \<and> dist xa x < (min d d') \<longrightarrow> dist (f xa) (g x) < e" by blast
  2.3418 +    hence "\<exists>d>0. \<forall>xa. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (g x) < e" using `d>0` `d'>0` by(rule_tac x="min d d'" in exI)auto
  2.3419 +  }
  2.3420 +  hence "(f ---> g x) (at x)" unfolding Lim_at using assms(1) by auto
  2.3421 +  thus ?thesis unfolding continuous_at using Lim_transform_at[of d x f g "g x"] using assms by blast
  2.3422 +qed
  2.3423 +
  2.3424 +text{* Combination results for pointwise continuity. *}
  2.3425 +
  2.3426 +lemma continuous_const: "continuous net (\<lambda>x. c)"
  2.3427 +  by (auto simp add: continuous_def Lim_const)
  2.3428 +
  2.3429 +lemma continuous_cmul:
  2.3430 +  fixes f :: "'a::t2_space \<Rightarrow> 'b::real_normed_vector"
  2.3431 +  shows "continuous net f ==> continuous net (\<lambda>x. c *\<^sub>R f x)"
  2.3432 +  by (auto simp add: continuous_def Lim_cmul)
  2.3433 +
  2.3434 +lemma continuous_neg:
  2.3435 +  fixes f :: "'a::t2_space \<Rightarrow> 'b::real_normed_vector"
  2.3436 +  shows "continuous net f ==> continuous net (\<lambda>x. -(f x))"
  2.3437 +  by (auto simp add: continuous_def Lim_neg)
  2.3438 +
  2.3439 +lemma continuous_add:
  2.3440 +  fixes f g :: "'a::t2_space \<Rightarrow> 'b::real_normed_vector"
  2.3441 +  shows "continuous net f \<Longrightarrow> continuous net g \<Longrightarrow> continuous net (\<lambda>x. f x + g x)"
  2.3442 +  by (auto simp add: continuous_def Lim_add)
  2.3443 +
  2.3444 +lemma continuous_sub:
  2.3445 +  fixes f g :: "'a::t2_space \<Rightarrow> 'b::real_normed_vector"
  2.3446 +  shows "continuous net f \<Longrightarrow> continuous net g \<Longrightarrow> continuous net (\<lambda>x. f x - g x)"
  2.3447 +  by (auto simp add: continuous_def Lim_sub)
  2.3448 +
  2.3449 +text{* Same thing for setwise continuity. *}
  2.3450 +
  2.3451 +lemma continuous_on_const:
  2.3452 + "continuous_on s (\<lambda>x. c)"
  2.3453 +  unfolding continuous_on_eq_continuous_within using continuous_const by blast
  2.3454 +
  2.3455 +lemma continuous_on_cmul:
  2.3456 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3457 +  shows "continuous_on s f ==>  continuous_on s (\<lambda>x. c *\<^sub>R (f x))"
  2.3458 +  unfolding continuous_on_eq_continuous_within using continuous_cmul by blast
  2.3459 +
  2.3460 +lemma continuous_on_neg:
  2.3461 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3462 +  shows "continuous_on s f \<Longrightarrow> continuous_on s (\<lambda>x. - f x)"
  2.3463 +  unfolding continuous_on_eq_continuous_within using continuous_neg by blast
  2.3464 +
  2.3465 +lemma continuous_on_add:
  2.3466 +  fixes f g :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3467 +  shows "continuous_on s f \<Longrightarrow> continuous_on s g
  2.3468 +           \<Longrightarrow> continuous_on s (\<lambda>x. f x + g x)"
  2.3469 +  unfolding continuous_on_eq_continuous_within using continuous_add by blast
  2.3470 +
  2.3471 +lemma continuous_on_sub:
  2.3472 +  fixes f g :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3473 +  shows "continuous_on s f \<Longrightarrow> continuous_on s g
  2.3474 +           \<Longrightarrow> continuous_on s (\<lambda>x. f x - g x)"
  2.3475 +  unfolding continuous_on_eq_continuous_within using continuous_sub by blast
  2.3476 +
  2.3477 +text{* Same thing for uniform continuity, using sequential formulations. *}
  2.3478 +
  2.3479 +lemma uniformly_continuous_on_const:
  2.3480 + "uniformly_continuous_on s (\<lambda>x. c)"
  2.3481 +  unfolding uniformly_continuous_on_def by simp
  2.3482 +
  2.3483 +lemma uniformly_continuous_on_cmul:
  2.3484 +  fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
  2.3485 +    (* FIXME: generalize 'a to metric_space *)
  2.3486 +  assumes "uniformly_continuous_on s f"
  2.3487 +  shows "uniformly_continuous_on s (\<lambda>x. c *\<^sub>R f(x))"
  2.3488 +proof-
  2.3489 +  { fix x y assume "((\<lambda>n. f (x n) - f (y n)) ---> 0) sequentially"
  2.3490 +    hence "((\<lambda>n. c *\<^sub>R f (x n) - c *\<^sub>R f (y n)) ---> 0) sequentially"
  2.3491 +      using Lim_cmul[of "(\<lambda>n. f (x n) - f (y n))" 0 sequentially c]
  2.3492 +      unfolding scaleR_zero_right scaleR_right_diff_distrib by auto
  2.3493 +  }
  2.3494 +  thus ?thesis using assms unfolding uniformly_continuous_on_sequentially by auto
  2.3495 +qed
  2.3496 +
  2.3497 +lemma dist_minus:
  2.3498 +  fixes x y :: "'a::real_normed_vector"
  2.3499 +  shows "dist (- x) (- y) = dist x y"
  2.3500 +  unfolding dist_norm minus_diff_minus norm_minus_cancel ..
  2.3501 +
  2.3502 +lemma uniformly_continuous_on_neg:
  2.3503 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3504 +  shows "uniformly_continuous_on s f
  2.3505 +         ==> uniformly_continuous_on s (\<lambda>x. -(f x))"
  2.3506 +  unfolding uniformly_continuous_on_def dist_minus .
  2.3507 +
  2.3508 +lemma uniformly_continuous_on_add:
  2.3509 +  fixes f g :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector" (* FIXME: generalize 'a *)
  2.3510 +  assumes "uniformly_continuous_on s f" "uniformly_continuous_on s g"
  2.3511 +  shows "uniformly_continuous_on s (\<lambda>x. f x + g x)"
  2.3512 +proof-
  2.3513 +  {  fix x y assume "((\<lambda>n. f (x n) - f (y n)) ---> 0) sequentially"
  2.3514 +                    "((\<lambda>n. g (x n) - g (y n)) ---> 0) sequentially"
  2.3515 +    hence "((\<lambda>xa. f (x xa) - f (y xa) + (g (x xa) - g (y xa))) ---> 0 + 0) sequentially"
  2.3516 +      using Lim_add[of "\<lambda> n. f (x n) - f (y n)" 0  sequentially "\<lambda> n. g (x n) - g (y n)" 0] by auto
  2.3517 +    hence "((\<lambda>n. f (x n) + g (x n) - (f (y n) + g (y n))) ---> 0) sequentially" unfolding Lim_sequentially and add_diff_add [symmetric] by auto  }
  2.3518 +  thus ?thesis using assms unfolding uniformly_continuous_on_sequentially by auto
  2.3519 +qed
  2.3520 +
  2.3521 +lemma uniformly_continuous_on_sub:
  2.3522 +  fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector" (* FIXME: generalize 'a *)
  2.3523 +  shows "uniformly_continuous_on s f \<Longrightarrow> uniformly_continuous_on s g
  2.3524 +           ==> uniformly_continuous_on s  (\<lambda>x. f x - g x)"
  2.3525 +  unfolding ab_diff_minus
  2.3526 +  using uniformly_continuous_on_add[of s f "\<lambda>x. - g x"]
  2.3527 +  using uniformly_continuous_on_neg[of s g] by auto
  2.3528 +
  2.3529 +text{* Identity function is continuous in every sense. *}
  2.3530 +
  2.3531 +lemma continuous_within_id:
  2.3532 + "continuous (at a within s) (\<lambda>x. x)"
  2.3533 +  unfolding continuous_within by (rule Lim_at_within [OF Lim_ident_at])
  2.3534 +
  2.3535 +lemma continuous_at_id:
  2.3536 + "continuous (at a) (\<lambda>x. x)"
  2.3537 +  unfolding continuous_at by (rule Lim_ident_at)
  2.3538 +
  2.3539 +lemma continuous_on_id:
  2.3540 + "continuous_on s (\<lambda>x. x)"
  2.3541 +  unfolding continuous_on Lim_within by auto
  2.3542 +
  2.3543 +lemma uniformly_continuous_on_id:
  2.3544 + "uniformly_continuous_on s (\<lambda>x. x)"
  2.3545 +  unfolding uniformly_continuous_on_def by auto
  2.3546 +
  2.3547 +text{* Continuity of all kinds is preserved under composition. *}
  2.3548 +
  2.3549 +lemma continuous_within_compose:
  2.3550 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3551 +  fixes g :: "'b::metric_space \<Rightarrow> 'c::metric_space"
  2.3552 +  assumes "continuous (at x within s) f"   "continuous (at (f x) within f ` s) g"
  2.3553 +  shows "continuous (at x within s) (g o f)"
  2.3554 +proof-
  2.3555 +  { fix e::real assume "e>0"
  2.3556 +    with assms(2)[unfolded continuous_within Lim_within] obtain d  where "d>0" and d:"\<forall>xa\<in>f ` s. 0 < dist xa (f x) \<and> dist xa (f x) < d \<longrightarrow> dist (g xa) (g (f x)) < e" by auto
  2.3557 +    from assms(1)[unfolded continuous_within Lim_within] obtain d' where "d'>0" and d':"\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d' \<longrightarrow> dist (f xa) (f x) < d" using `d>0` by auto
  2.3558 +    { fix y assume as:"y\<in>s"  "0 < dist y x"  "dist y x < d'"
  2.3559 +      hence "dist (f y) (f x) < d" using d'[THEN bspec[where x=y]] by (auto simp add:dist_commute)
  2.3560 +      hence "dist (g (f y)) (g (f x)) < e" using as(1) d[THEN bspec[where x="f y"]] unfolding dist_nz[THEN sym] using `e>0` by auto   }
  2.3561 +    hence "\<exists>d>0. \<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (g (f xa)) (g (f x)) < e" using `d'>0` by auto  }
  2.3562 +  thus ?thesis unfolding continuous_within Lim_within by auto
  2.3563 +qed
  2.3564 +
  2.3565 +lemma continuous_at_compose:
  2.3566 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3567 +  fixes g :: "'b::metric_space \<Rightarrow> 'c::metric_space"
  2.3568 +  assumes "continuous (at x) f"  "continuous (at (f x)) g"
  2.3569 +  shows "continuous (at x) (g o f)"
  2.3570 +proof-
  2.3571 +  have " continuous (at (f x) within range f) g" using assms(2) using continuous_within_subset[of "f x" UNIV g "range f", unfolded within_UNIV] by auto
  2.3572 +  thus ?thesis using assms(1) using continuous_within_compose[of x UNIV f g, unfolded within_UNIV] by auto
  2.3573 +qed
  2.3574 +
  2.3575 +lemma continuous_on_compose:
  2.3576 + "continuous_on s f \<Longrightarrow> continuous_on (f ` s) g \<Longrightarrow> continuous_on s (g o f)"
  2.3577 +  unfolding continuous_on_eq_continuous_within using continuous_within_compose[of _ s f g] by auto
  2.3578 +
  2.3579 +lemma uniformly_continuous_on_compose:
  2.3580 +  assumes "uniformly_continuous_on s f"  "uniformly_continuous_on (f ` s) g"
  2.3581 +  shows "uniformly_continuous_on s (g o f)"
  2.3582 +proof-
  2.3583 +  { fix e::real assume "e>0"
  2.3584 +    then obtain d where "d>0" and d:"\<forall>x\<in>f ` s. \<forall>x'\<in>f ` s. dist x' x < d \<longrightarrow> dist (g x') (g x) < e" using assms(2) unfolding uniformly_continuous_on_def by auto
  2.3585 +    obtain d' where "d'>0" "\<forall>x\<in>s. \<forall>x'\<in>s. dist x' x < d' \<longrightarrow> dist (f x') (f x) < d" using `d>0` using assms(1) unfolding uniformly_continuous_on_def by auto
  2.3586 +    hence "\<exists>d>0. \<forall>x\<in>s. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist ((g \<circ> f) x') ((g \<circ> f) x) < e" using `d>0` using d by auto  }
  2.3587 +  thus ?thesis using assms unfolding uniformly_continuous_on_def by auto
  2.3588 +qed
  2.3589 +
  2.3590 +text{* Continuity in terms of open preimages. *}
  2.3591 +
  2.3592 +lemma continuous_at_open:
  2.3593 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3594 +  shows "continuous (at x) f \<longleftrightarrow> (\<forall>t. open t \<and> f x \<in> t --> (\<exists>s. open s \<and> x \<in> s \<and> (\<forall>x' \<in> s. (f x') \<in> t)))" (is "?lhs = ?rhs")
  2.3595 +proof
  2.3596 +  assume ?lhs
  2.3597 +  { fix t assume as: "open t" "f x \<in> t"
  2.3598 +    then obtain e where "e>0" and e:"ball (f x) e \<subseteq> t" unfolding open_contains_ball by auto
  2.3599 +
  2.3600 +    obtain d where "d>0" and d:"\<forall>y. 0 < dist y x \<and> dist y x < d \<longrightarrow> dist (f y) (f x) < e" using `e>0` using `?lhs`[unfolded continuous_at Lim_at open_dist] by auto
  2.3601 +
  2.3602 +    have "open (ball x d)" using open_ball by auto
  2.3603 +    moreover have "x \<in> ball x d" unfolding centre_in_ball using `d>0` by simp
  2.3604 +    moreover
  2.3605 +    { fix x' assume "x'\<in>ball x d" hence "f x' \<in> t"
  2.3606 +	using e[unfolded subset_eq Ball_def mem_ball, THEN spec[where x="f x'"]]    d[THEN spec[where x=x']]
  2.3607 +	unfolding mem_ball apply (auto simp add: dist_commute)
  2.3608 +	unfolding dist_nz[THEN sym] using as(2) by auto  }
  2.3609 +    hence "\<forall>x'\<in>ball x d. f x' \<in> t" by auto
  2.3610 +    ultimately have "\<exists>s. open s \<and> x \<in> s \<and> (\<forall>x'\<in>s. f x' \<in> t)"
  2.3611 +      apply(rule_tac x="ball x d" in exI) by simp  }
  2.3612 +  thus ?rhs by auto
  2.3613 +next
  2.3614 +  assume ?rhs
  2.3615 +  { fix e::real assume "e>0"
  2.3616 +    then obtain s where s: "open s"  "x \<in> s"  "\<forall>x'\<in>s. f x' \<in> ball (f x) e" using `?rhs`[unfolded continuous_at Lim_at, THEN spec[where x="ball (f x) e"]]
  2.3617 +      unfolding centre_in_ball[of "f x" e, THEN sym] by auto
  2.3618 +    then obtain d where "d>0" and d:"ball x d \<subseteq> s" unfolding open_contains_ball by auto
  2.3619 +    { fix y assume "0 < dist y x \<and> dist y x < d"
  2.3620 +      hence "dist (f y) (f x) < e" using d[unfolded subset_eq Ball_def mem_ball, THEN spec[where x=y]]
  2.3621 +	using s(3)[THEN bspec[where x=y], unfolded mem_ball] by (auto simp add: dist_commute)  }
  2.3622 +    hence "\<exists>d>0. \<forall>xa. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e" using `d>0` by auto  }
  2.3623 +  thus ?lhs unfolding continuous_at Lim_at by auto
  2.3624 +qed
  2.3625 +
  2.3626 +lemma continuous_on_open:
  2.3627 + "continuous_on s f \<longleftrightarrow>
  2.3628 +        (\<forall>t. openin (subtopology euclidean (f ` s)) t
  2.3629 +            --> openin (subtopology euclidean s) {x \<in> s. f x \<in> t})" (is "?lhs = ?rhs")
  2.3630 +proof
  2.3631 +  assume ?lhs
  2.3632 +  { fix t assume as:"openin (subtopology euclidean (f ` s)) t"
  2.3633 +    have "{x \<in> s. f x \<in> t} \<subseteq> s" using as[unfolded openin_euclidean_subtopology_iff] by auto
  2.3634 +    moreover
  2.3635 +    { fix x assume as':"x\<in>{x \<in> s. f x \<in> t}"
  2.3636 +      then obtain e where e: "e>0" "\<forall>x'\<in>f ` s. dist x' (f x) < e \<longrightarrow> x' \<in> t" using as[unfolded openin_euclidean_subtopology_iff, THEN conjunct2, THEN bspec[where x="f x"]] by auto
  2.3637 +      from this(1) obtain d where d: "d>0" "\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e" using `?lhs`[unfolded continuous_on Lim_within, THEN bspec[where x=x]] using as' by auto
  2.3638 +      have "\<exists>e>0. \<forall>x'\<in>s. dist x' x < e \<longrightarrow> x' \<in> {x \<in> s. f x \<in> t}" using d e unfolding dist_nz[THEN sym] by (rule_tac x=d in exI, auto)  }
  2.3639 +    ultimately have "openin (subtopology euclidean s) {x \<in> s. f x \<in> t}" unfolding openin_euclidean_subtopology_iff by auto  }
  2.3640 +  thus ?rhs unfolding continuous_on Lim_within using openin by auto
  2.3641 +next
  2.3642 +  assume ?rhs
  2.3643 +  { fix e::real and x assume "x\<in>s" "e>0"
  2.3644 +    { fix xa x' assume "dist (f xa) (f x) < e" "xa \<in> s" "x' \<in> s" "dist (f xa) (f x') < e - dist (f xa) (f x)"
  2.3645 +      hence "dist (f x') (f x) < e" using dist_triangle[of "f x'" "f x" "f xa"]
  2.3646 +	by (auto simp add: dist_commute)  }
  2.3647 +    hence "ball (f x) e \<inter> f ` s \<subseteq> f ` s \<and> (\<forall>xa\<in>ball (f x) e \<inter> f ` s. \<exists>ea>0. \<forall>x'\<in>f ` s. dist x' xa < ea \<longrightarrow> x' \<in> ball (f x) e \<inter> f ` s)" apply auto
  2.3648 +      apply(rule_tac x="e - dist (f xa) (f x)" in exI) using `e>0` by (auto simp add: dist_commute)
  2.3649 +    hence "\<forall>xa\<in>{xa \<in> s. f xa \<in> ball (f x) e \<inter> f ` s}. \<exists>ea>0. \<forall>x'\<in>s. dist x' xa < ea \<longrightarrow> x' \<in> {xa \<in> s. f xa \<in> ball (f x) e \<inter> f ` s}"
  2.3650 +      using `?rhs`[unfolded openin_euclidean_subtopology_iff, THEN spec[where x="ball (f x) e \<inter> f ` s"]] by auto
  2.3651 +    hence "\<exists>d>0. \<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < e" apply(erule_tac x=x in ballE) apply auto using `e>0` `x\<in>s` by (auto simp add: dist_commute)  }
  2.3652 +  thus ?lhs unfolding continuous_on Lim_within by auto
  2.3653 +qed
  2.3654 +
  2.3655 +(* ------------------------------------------------------------------------- *)
  2.3656 +(* Similarly in terms of closed sets.                                        *)
  2.3657 +(* ------------------------------------------------------------------------- *)
  2.3658 +
  2.3659 +lemma continuous_on_closed:
  2.3660 + "continuous_on s f \<longleftrightarrow>  (\<forall>t. closedin (subtopology euclidean (f ` s)) t  --> closedin (subtopology euclidean s) {x \<in> s. f x \<in> t})" (is "?lhs = ?rhs")
  2.3661 +proof
  2.3662 +  assume ?lhs
  2.3663 +  { fix t
  2.3664 +    have *:"s - {x \<in> s. f x \<in> f ` s - t} = {x \<in> s. f x \<in> t}" by auto
  2.3665 +    have **:"f ` s - (f ` s - (f ` s - t)) = f ` s - t" by auto
  2.3666 +    assume as:"closedin (subtopology euclidean (f ` s)) t"
  2.3667 +    hence "closedin (subtopology euclidean (f ` s)) (f ` s - (f ` s - t))" unfolding closedin_def topspace_euclidean_subtopology unfolding ** by auto
  2.3668 +    hence "closedin (subtopology euclidean s) {x \<in> s. f x \<in> t}" using `?lhs`[unfolded continuous_on_open, THEN spec[where x="(f ` s) - t"]]
  2.3669 +      unfolding openin_closedin_eq topspace_euclidean_subtopology unfolding * by auto  }
  2.3670 +  thus ?rhs by auto
  2.3671 +next
  2.3672 +  assume ?rhs
  2.3673 +  { fix t
  2.3674 +    have *:"s - {x \<in> s. f x \<in> f ` s - t} = {x \<in> s. f x \<in> t}" by auto
  2.3675 +    assume as:"openin (subtopology euclidean (f ` s)) t"
  2.3676 +    hence "openin (subtopology euclidean s) {x \<in> s. f x \<in> t}" using `?rhs`[THEN spec[where x="(f ` s) - t"]]
  2.3677 +      unfolding openin_closedin_eq topspace_euclidean_subtopology *[THEN sym] closedin_subtopology by auto }
  2.3678 +  thus ?lhs unfolding continuous_on_open by auto
  2.3679 +qed
  2.3680 +
  2.3681 +text{* Half-global and completely global cases.                                  *}
  2.3682 +
  2.3683 +lemma continuous_open_in_preimage:
  2.3684 +  assumes "continuous_on s f"  "open t"
  2.3685 +  shows "openin (subtopology euclidean s) {x \<in> s. f x \<in> t}"
  2.3686 +proof-
  2.3687 +  have *:"\<forall>x. x \<in> s \<and> f x \<in> t \<longleftrightarrow> x \<in> s \<and> f x \<in> (t \<inter> f ` s)" by auto
  2.3688 +  have "openin (subtopology euclidean (f ` s)) (t \<inter> f ` s)"
  2.3689 +    using openin_open_Int[of t "f ` s", OF assms(2)] unfolding openin_open by auto
  2.3690 +  thus ?thesis using assms(1)[unfolded continuous_on_open, THEN spec[where x="t \<inter> f ` s"]] using * by auto
  2.3691 +qed
  2.3692 +
  2.3693 +lemma continuous_closed_in_preimage:
  2.3694 +  assumes "continuous_on s f"  "closed t"
  2.3695 +  shows "closedin (subtopology euclidean s) {x \<in> s. f x \<in> t}"
  2.3696 +proof-
  2.3697 +  have *:"\<forall>x. x \<in> s \<and> f x \<in> t \<longleftrightarrow> x \<in> s \<and> f x \<in> (t \<inter> f ` s)" by auto
  2.3698 +  have "closedin (subtopology euclidean (f ` s)) (t \<inter> f ` s)"
  2.3699 +    using closedin_closed_Int[of t "f ` s", OF assms(2)] unfolding Int_commute by auto
  2.3700 +  thus ?thesis
  2.3701 +    using assms(1)[unfolded continuous_on_closed, THEN spec[where x="t \<inter> f ` s"]] using * by auto
  2.3702 +qed
  2.3703 +
  2.3704 +lemma continuous_open_preimage:
  2.3705 +  assumes "continuous_on s f" "open s" "open t"
  2.3706 +  shows "open {x \<in> s. f x \<in> t}"
  2.3707 +proof-
  2.3708 +  obtain T where T: "open T" "{x \<in> s. f x \<in> t} = s \<inter> T"
  2.3709 +    using continuous_open_in_preimage[OF assms(1,3)] unfolding openin_open by auto
  2.3710 +  thus ?thesis using open_Int[of s T, OF assms(2)] by auto
  2.3711 +qed
  2.3712 +
  2.3713 +lemma continuous_closed_preimage:
  2.3714 +  assumes "continuous_on s f" "closed s" "closed t"
  2.3715 +  shows "closed {x \<in> s. f x \<in> t}"
  2.3716 +proof-
  2.3717 +  obtain T where T: "closed T" "{x \<in> s. f x \<in> t} = s \<inter> T"
  2.3718 +    using continuous_closed_in_preimage[OF assms(1,3)] unfolding closedin_closed by auto
  2.3719 +  thus ?thesis using closed_Int[of s T, OF assms(2)] by auto
  2.3720 +qed
  2.3721 +
  2.3722 +lemma continuous_open_preimage_univ:
  2.3723 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3724 +  shows "\<forall>x. continuous (at x) f \<Longrightarrow> open s \<Longrightarrow> open {x. f x \<in> s}"
  2.3725 +  using continuous_open_preimage[of UNIV f s] open_UNIV continuous_at_imp_continuous_on by auto
  2.3726 +
  2.3727 +lemma continuous_closed_preimage_univ:
  2.3728 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3729 +  shows "(\<forall>x. continuous (at x) f) \<Longrightarrow> closed s ==> closed {x. f x \<in> s}"
  2.3730 +  using continuous_closed_preimage[of UNIV f s] closed_UNIV continuous_at_imp_continuous_on by auto
  2.3731 +
  2.3732 +lemma continuous_open_vimage:
  2.3733 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3734 +  shows "\<forall>x. continuous (at x) f \<Longrightarrow> open s \<Longrightarrow> open (f -` s)"
  2.3735 +  unfolding vimage_def by (rule continuous_open_preimage_univ)
  2.3736 +
  2.3737 +lemma continuous_closed_vimage:
  2.3738 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3739 +  shows "\<forall>x. continuous (at x) f \<Longrightarrow> closed s \<Longrightarrow> closed (f -` s)"
  2.3740 +  unfolding vimage_def by (rule continuous_closed_preimage_univ)
  2.3741 +
  2.3742 +text{* Equality of continuous functions on closure and related results.          *}
  2.3743 +
  2.3744 +lemma continuous_closed_in_preimage_constant:
  2.3745 + "continuous_on s f ==> closedin (subtopology euclidean s) {x \<in> s. f x = a}"
  2.3746 +  using continuous_closed_in_preimage[of s f "{a}"] closed_sing by auto
  2.3747 +
  2.3748 +lemma continuous_closed_preimage_constant:
  2.3749 + "continuous_on s f \<Longrightarrow> closed s ==> closed {x \<in> s. f x = a}"
  2.3750 +  using continuous_closed_preimage[of s f "{a}"] closed_sing by auto
  2.3751 +
  2.3752 +lemma continuous_constant_on_closure:
  2.3753 +  assumes "continuous_on (closure s) f"
  2.3754 +          "\<forall>x \<in> s. f x = a"
  2.3755 +  shows "\<forall>x \<in> (closure s). f x = a"
  2.3756 +    using continuous_closed_preimage_constant[of "closure s" f a]
  2.3757 +    assms closure_minimal[of s "{x \<in> closure s. f x = a}"] closure_subset unfolding subset_eq by auto
  2.3758 +
  2.3759 +lemma image_closure_subset:
  2.3760 +  assumes "continuous_on (closure s) f"  "closed t"  "(f ` s) \<subseteq> t"
  2.3761 +  shows "f ` (closure s) \<subseteq> t"
  2.3762 +proof-
  2.3763 +  have "s \<subseteq> {x \<in> closure s. f x \<in> t}" using assms(3) closure_subset by auto
  2.3764 +  moreover have "closed {x \<in> closure s. f x \<in> t}"
  2.3765 +    using continuous_closed_preimage[OF assms(1)] and assms(2) by auto
  2.3766 +  ultimately have "closure s = {x \<in> closure s . f x \<in> t}"
  2.3767 +    using closure_minimal[of s "{x \<in> closure s. f x \<in> t}"] by auto
  2.3768 +  thus ?thesis by auto
  2.3769 +qed
  2.3770 +
  2.3771 +lemma continuous_on_closure_norm_le:
  2.3772 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.3773 +  assumes "continuous_on (closure s) f"  "\<forall>y \<in> s. norm(f y) \<le> b"  "x \<in> (closure s)"
  2.3774 +  shows "norm(f x) \<le> b"
  2.3775 +proof-
  2.3776 +  have *:"f ` s \<subseteq> cball 0 b" using assms(2)[unfolded mem_cball_0[THEN sym]] by auto
  2.3777 +  show ?thesis
  2.3778 +    using image_closure_subset[OF assms(1) closed_cball[of 0 b] *] assms(3)
  2.3779 +    unfolding subset_eq apply(erule_tac x="f x" in ballE) by (auto simp add: dist_norm)
  2.3780 +qed
  2.3781 +
  2.3782 +text{* Making a continuous function avoid some value in a neighbourhood.         *}
  2.3783 +
  2.3784 +lemma continuous_within_avoid:
  2.3785 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3786 +  assumes "continuous (at x within s) f"  "x \<in> s"  "f x \<noteq> a"
  2.3787 +  shows "\<exists>e>0. \<forall>y \<in> s. dist x y < e --> f y \<noteq> a"
  2.3788 +proof-
  2.3789 +  obtain d where "d>0" and d:"\<forall>xa\<in>s. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> dist (f xa) (f x) < dist (f x) a"
  2.3790 +    using assms(1)[unfolded continuous_within Lim_within, THEN spec[where x="dist (f x) a"]] assms(3)[unfolded dist_nz] by auto
  2.3791 +  { fix y assume " y\<in>s"  "dist x y < d"
  2.3792 +    hence "f y \<noteq> a" using d[THEN bspec[where x=y]] assms(3)[unfolded dist_nz]
  2.3793 +      apply auto unfolding dist_nz[THEN sym] by (auto simp add: dist_commute) }
  2.3794 +  thus ?thesis using `d>0` by auto
  2.3795 +qed
  2.3796 +
  2.3797 +lemma continuous_at_avoid:
  2.3798 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::metric_space" (* FIXME: generalize *)
  2.3799 +  assumes "continuous (at x) f"  "f x \<noteq> a"
  2.3800 +  shows "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> f y \<noteq> a"
  2.3801 +using assms using continuous_within_avoid[of x UNIV f a, unfolded within_UNIV] by auto
  2.3802 +
  2.3803 +lemma continuous_on_avoid:
  2.3804 +  assumes "continuous_on s f"  "x \<in> s"  "f x \<noteq> a"
  2.3805 +  shows "\<exists>e>0. \<forall>y \<in> s. dist x y < e \<longrightarrow> f y \<noteq> a"
  2.3806 +using assms(1)[unfolded continuous_on_eq_continuous_within, THEN bspec[where x=x], OF assms(2)]  continuous_within_avoid[of x s f a]  assms(2,3) by auto
  2.3807 +
  2.3808 +lemma continuous_on_open_avoid:
  2.3809 +  assumes "continuous_on s f"  "open s"  "x \<in> s"  "f x \<noteq> a"
  2.3810 +  shows "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> f y \<noteq> a"
  2.3811 +using assms(1)[unfolded continuous_on_eq_continuous_at[OF assms(2)], THEN bspec[where x=x], OF assms(3)]  continuous_at_avoid[of x f a]  assms(3,4) by auto
  2.3812 +
  2.3813 +text{* Proving a function is constant by proving open-ness of level set.         *}
  2.3814 +
  2.3815 +lemma continuous_levelset_open_in_cases:
  2.3816 + "connected s \<Longrightarrow> continuous_on s f \<Longrightarrow>
  2.3817 +        openin (subtopology euclidean s) {x \<in> s. f x = a}
  2.3818 +        ==> (\<forall>x \<in> s. f x \<noteq> a) \<or> (\<forall>x \<in> s. f x = a)"
  2.3819 +unfolding connected_clopen using continuous_closed_in_preimage_constant by auto
  2.3820 +
  2.3821 +lemma continuous_levelset_open_in:
  2.3822 + "connected s \<Longrightarrow> continuous_on s f \<Longrightarrow>
  2.3823 +        openin (subtopology euclidean s) {x \<in> s. f x = a} \<Longrightarrow>
  2.3824 +        (\<exists>x \<in> s. f x = a)  ==> (\<forall>x \<in> s. f x = a)"
  2.3825 +using continuous_levelset_open_in_cases[of s f ]
  2.3826 +by meson
  2.3827 +
  2.3828 +lemma continuous_levelset_open:
  2.3829 +  assumes "connected s"  "continuous_on s f"  "open {x \<in> s. f x = a}"  "\<exists>x \<in> s.  f x = a"
  2.3830 +  shows "\<forall>x \<in> s. f x = a"
  2.3831 +using continuous_levelset_open_in[OF assms(1,2), of a, unfolded openin_open] using assms (3,4) by auto
  2.3832 +
  2.3833 +text{* Some arithmetical combinations (more to prove).                           *}
  2.3834 +
  2.3835 +lemma open_scaling[intro]:
  2.3836 +  fixes s :: "'a::real_normed_vector set"
  2.3837 +  assumes "c \<noteq> 0"  "open s"
  2.3838 +  shows "open((\<lambda>x. c *\<^sub>R x) ` s)"
  2.3839 +proof-
  2.3840 +  { fix x assume "x \<in> s"
  2.3841 +    then obtain e where "e>0" and e:"\<forall>x'. dist x' x < e \<longrightarrow> x' \<in> s" using assms(2)[unfolded open_dist, THEN bspec[where x=x]] by auto
  2.3842 +    have "e * abs c > 0" using assms(1)[unfolded zero_less_abs_iff[THEN sym]] using real_mult_order[OF `e>0`] by auto
  2.3843 +    moreover
  2.3844 +    { fix y assume "dist y (c *\<^sub>R x) < e * \<bar>c\<bar>"
  2.3845 +      hence "norm ((1 / c) *\<^sub>R y - x) < e" unfolding dist_norm
  2.3846 +	using norm_scaleR[of c "(1 / c) *\<^sub>R y - x", unfolded scaleR_right_diff_distrib, unfolded scaleR_scaleR] assms(1)
  2.3847 +	  assms(1)[unfolded zero_less_abs_iff[THEN sym]] by (simp del:zero_less_abs_iff)
  2.3848 +      hence "y \<in> op *\<^sub>R c ` s" using rev_image_eqI[of "(1 / c) *\<^sub>R y" s y "op *\<^sub>R c"]  e[THEN spec[where x="(1 / c) *\<^sub>R y"]]  assms(1) unfolding dist_norm scaleR_scaleR by auto  }
  2.3849 +    ultimately have "\<exists>e>0. \<forall>x'. dist x' (c *\<^sub>R x) < e \<longrightarrow> x' \<in> op *\<^sub>R c ` s" apply(rule_tac x="e * abs c" in exI) by auto  }
  2.3850 +  thus ?thesis unfolding open_dist by auto
  2.3851 +qed
  2.3852 +
  2.3853 +lemma minus_image_eq_vimage:
  2.3854 +  fixes A :: "'a::ab_group_add set"
  2.3855 +  shows "(\<lambda>x. - x) ` A = (\<lambda>x. - x) -` A"
  2.3856 +  by (auto intro!: image_eqI [where f="\<lambda>x. - x"])
  2.3857 +
  2.3858 +lemma open_negations:
  2.3859 +  fixes s :: "'a::real_normed_vector set"
  2.3860 +  shows "open s ==> open ((\<lambda> x. -x) ` s)"
  2.3861 +  unfolding scaleR_minus1_left [symmetric]
  2.3862 +  by (rule open_scaling, auto)
  2.3863 +
  2.3864 +lemma open_translation:
  2.3865 +  fixes s :: "'a::real_normed_vector set"
  2.3866 +  assumes "open s"  shows "open((\<lambda>x. a + x) ` s)"
  2.3867 +proof-
  2.3868 +  { fix x have "continuous (at x) (\<lambda>x. x - a)" using continuous_sub[of "at x" "\<lambda>x. x" "\<lambda>x. a"] continuous_at_id[of x] continuous_const[of "at x" a] by auto  }
  2.3869 +  moreover have "{x. x - a \<in> s}  = op + a ` s" apply auto unfolding image_iff apply(rule_tac x="x - a" in bexI) by auto
  2.3870 +  ultimately show ?thesis using continuous_open_preimage_univ[of "\<lambda>x. x - a" s] using assms by auto
  2.3871 +qed
  2.3872 +
  2.3873 +lemma open_affinity:
  2.3874 +  fixes s :: "'a::real_normed_vector set"
  2.3875 +  assumes "open s"  "c \<noteq> 0"
  2.3876 +  shows "open ((\<lambda>x. a + c *\<^sub>R x) ` s)"
  2.3877 +proof-
  2.3878 +  have *:"(\<lambda>x. a + c *\<^sub>R x) = (\<lambda>x. a + x) \<circ> (\<lambda>x. c *\<^sub>R x)" unfolding o_def ..
  2.3879 +  have "op + a ` op *\<^sub>R c ` s = (op + a \<circ> op *\<^sub>R c) ` s" by auto
  2.3880 +  thus ?thesis using assms open_translation[of "op *\<^sub>R c ` s" a] unfolding * by auto
  2.3881 +qed
  2.3882 +
  2.3883 +lemma interior_translation:
  2.3884 +  fixes s :: "'a::real_normed_vector set"
  2.3885 +  shows "interior ((\<lambda>x. a + x) ` s) = (\<lambda>x. a + x) ` (interior s)"
  2.3886 +proof (rule set_ext, rule)
  2.3887 +  fix x assume "x \<in> interior (op + a ` s)"
  2.3888 +  then obtain e where "e>0" and e:"ball x e \<subseteq> op + a ` s" unfolding mem_interior by auto
  2.3889 +  hence "ball (x - a) e \<subseteq> s" unfolding subset_eq Ball_def mem_ball dist_norm apply auto apply(erule_tac x="a + xa" in allE) unfolding ab_group_add_class.diff_diff_eq[THEN sym] by auto
  2.3890 +  thus "x \<in> op + a ` interior s" unfolding image_iff apply(rule_tac x="x - a" in bexI) unfolding mem_interior using `e > 0` by auto
  2.3891 +next
  2.3892 +  fix x assume "x \<in> op + a ` interior s"
  2.3893 +  then obtain y e where "e>0" and e:"ball y e \<subseteq> s" and y:"x = a + y" unfolding image_iff Bex_def mem_interior by auto
  2.3894 +  { fix z have *:"a + y - z = y + a - z" by auto
  2.3895 +    assume "z\<in>ball x e"
  2.3896 +    hence "z - a \<in> s" using e[unfolded subset_eq, THEN bspec[where x="z - a"]] unfolding mem_ball dist_norm y ab_group_add_class.diff_diff_eq2 * by auto
  2.3897 +    hence "z \<in> op + a ` s" unfolding image_iff by(auto intro!: bexI[where x="z - a"])  }
  2.3898 +  hence "ball x e \<subseteq> op + a ` s" unfolding subset_eq by auto
  2.3899 +  thus "x \<in> interior (op + a ` s)" unfolding mem_interior using `e>0` by auto
  2.3900 +qed
  2.3901 +
  2.3902 +subsection {* Preservation of compactness and connectedness under continuous function.  *}
  2.3903 +
  2.3904 +lemma compact_continuous_image:
  2.3905 +  assumes "continuous_on s f"  "compact s"
  2.3906 +  shows "compact(f ` s)"
  2.3907 +proof-
  2.3908 +  { fix x assume x:"\<forall>n::nat. x n \<in> f ` s"
  2.3909 +    then obtain y where y:"\<forall>n. y n \<in> s \<and> x n = f (y n)" unfolding image_iff Bex_def using choice[of "\<lambda>n xa. xa \<in> s \<and> x n = f xa"] by auto
  2.3910 +    then obtain l r where "l\<in>s" and r:"subseq r" and lr:"((y \<circ> r) ---> l) sequentially" using assms(2)[unfolded compact_def, THEN spec[where x=y]] by auto
  2.3911 +    { fix e::real assume "e>0"
  2.3912 +      then obtain d where "d>0" and d:"\<forall>x'\<in>s. dist x' l < d \<longrightarrow> dist (f x') (f l) < e" using assms(1)[unfolded continuous_on_def, THEN bspec[where x=l], OF `l\<in>s`] by auto
  2.3913 +      then obtain N::nat where N:"\<forall>n\<ge>N. dist ((y \<circ> r) n) l < d" using lr[unfolded Lim_sequentially, THEN spec[where x=d]] by auto
  2.3914 +      { fix n::nat assume "n\<ge>N" hence "dist ((x \<circ> r) n) (f l) < e" using N[THEN spec[where x=n]] d[THEN bspec[where x="y (r n)"]] y[THEN spec[where x="r n"]] by auto  }
  2.3915 +      hence "\<exists>N. \<forall>n\<ge>N. dist ((x \<circ> r) n) (f l) < e" by auto  }
  2.3916 +    hence "\<exists>l\<in>f ` s. \<exists>r. subseq r \<and> ((x \<circ> r) ---> l) sequentially" unfolding Lim_sequentially using r lr `l\<in>s` by auto  }
  2.3917 +  thus ?thesis unfolding compact_def by auto
  2.3918 +qed
  2.3919 +
  2.3920 +lemma connected_continuous_image:
  2.3921 +  assumes "continuous_on s f"  "connected s"
  2.3922 +  shows "connected(f ` s)"
  2.3923 +proof-
  2.3924 +  { fix T assume as: "T \<noteq> {}"  "T \<noteq> f ` s"  "openin (subtopology euclidean (f ` s)) T"  "closedin (subtopology euclidean (f ` s)) T"
  2.3925 +    have "{x \<in> s. f x \<in> T} = {} \<or> {x \<in> s. f x \<in> T} = s"
  2.3926 +      using assms(1)[unfolded continuous_on_open, THEN spec[where x=T]]
  2.3927 +      using assms(1)[unfolded continuous_on_closed, THEN spec[where x=T]]
  2.3928 +      using assms(2)[unfolded connected_clopen, THEN spec[where x="{x \<in> s. f x \<in> T}"]] as(3,4) by auto
  2.3929 +    hence False using as(1,2)
  2.3930 +      using as(4)[unfolded closedin_def topspace_euclidean_subtopology] by auto }
  2.3931 +  thus ?thesis unfolding connected_clopen by auto
  2.3932 +qed
  2.3933 +
  2.3934 +text{* Continuity implies uniform continuity on a compact domain.                *}
  2.3935 +
  2.3936 +lemma compact_uniformly_continuous:
  2.3937 +  assumes "continuous_on s f"  "compact s"
  2.3938 +  shows "uniformly_continuous_on s f"
  2.3939 +proof-
  2.3940 +    { fix x assume x:"x\<in>s"
  2.3941 +      hence "\<forall>xa. \<exists>y. 0 < xa \<longrightarrow> (y > 0 \<and> (\<forall>x'\<in>s. dist x' x < y \<longrightarrow> dist (f x') (f x) < xa))" using assms(1)[unfolded continuous_on_def, THEN bspec[where x=x]] by auto
  2.3942 +      hence "\<exists>fa. \<forall>xa>0. \<forall>x'\<in>s. fa xa > 0 \<and> (dist x' x < fa xa \<longrightarrow> dist (f x') (f x) < xa)" using choice[of "\<lambda>e d. e>0 \<longrightarrow> d>0 \<and>(\<forall>x'\<in>s. (dist x' x < d \<longrightarrow> dist (f x') (f x) < e))"] by auto  }
  2.3943 +    then have "\<forall>x\<in>s. \<exists>y. \<forall>xa. 0 < xa \<longrightarrow> (\<forall>x'\<in>s. y xa > 0 \<and> (dist x' x < y xa \<longrightarrow> dist (f x') (f x) < xa))" by auto
  2.3944 +    then obtain d where d:"\<forall>e>0. \<forall>x\<in>s. \<forall>x'\<in>s. d x e > 0 \<and> (dist x' x < d x e \<longrightarrow> dist (f x') (f x) < e)"
  2.3945 +      using bchoice[of s "\<lambda>x fa. \<forall>xa>0. \<forall>x'\<in>s. fa xa > 0 \<and> (dist x' x < fa xa \<longrightarrow> dist (f x') (f x) < xa)"] by blast
  2.3946 +
  2.3947 +  { fix e::real assume "e>0"
  2.3948 +
  2.3949 +    { fix x assume "x\<in>s" hence "x \<in> ball x (d x (e / 2))" unfolding centre_in_ball using d[THEN spec[where x="e/2"]] using `e>0` by auto  }
  2.3950 +    hence "s \<subseteq> \<Union>{ball x (d x (e / 2)) |x. x \<in> s}" unfolding subset_eq by auto
  2.3951 +    moreover
  2.3952 +    { fix b assume "b\<in>{ball x (d x (e / 2)) |x. x \<in> s}" hence "open b" by auto  }
  2.3953 +    ultimately obtain ea where "ea>0" and ea:"\<forall>x\<in>s. \<exists>b\<in>{ball x (d x (e / 2)) |x. x \<in> s}. ball x ea \<subseteq> b" using heine_borel_lemma[OF assms(2), of "{ball x (d x (e / 2)) | x. x\<in>s }"] by auto
  2.3954 +
  2.3955 +    { fix x y assume "x\<in>s" "y\<in>s" and as:"dist y x < ea"
  2.3956 +      obtain z where "z\<in>s" and z:"ball x ea \<subseteq> ball z (d z (e / 2))" using ea[THEN bspec[where x=x]] and `x\<in>s` by auto
  2.3957 +      hence "x\<in>ball z (d z (e / 2))" using `ea>0` unfolding subset_eq by auto
  2.3958 +      hence "dist (f z) (f x) < e / 2" using d[THEN spec[where x="e/2"]] and `e>0` and `x\<in>s` and `z\<in>s`
  2.3959 +	by (auto  simp add: dist_commute)
  2.3960 +      moreover have "y\<in>ball z (d z (e / 2))" using as and `ea>0` and z[unfolded subset_eq]
  2.3961 +	by (auto simp add: dist_commute)
  2.3962 +      hence "dist (f z) (f y) < e / 2" using d[THEN spec[where x="e/2"]] and `e>0` and `y\<in>s` and `z\<in>s`
  2.3963 +	by (auto  simp add: dist_commute)
  2.3964 +      ultimately have "dist (f y) (f x) < e" using dist_triangle_half_r[of "f z" "f x" e "f y"]
  2.3965 +	by (auto simp add: dist_commute)  }
  2.3966 +    then have "\<exists>d>0. \<forall>x\<in>s. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (f x') (f x) < e" using `ea>0` by auto  }
  2.3967 +  thus ?thesis unfolding uniformly_continuous_on_def by auto
  2.3968 +qed
  2.3969 +
  2.3970 +text{* Continuity of inverse function on compact domain. *}
  2.3971 +
  2.3972 +lemma continuous_on_inverse:
  2.3973 +  fixes f :: "'a::heine_borel \<Rightarrow> 'b::heine_borel"
  2.3974 +    (* TODO: can this be generalized more? *)
  2.3975 +  assumes "continuous_on s f"  "compact s"  "\<forall>x \<in> s. g (f x) = x"
  2.3976 +  shows "continuous_on (f ` s) g"
  2.3977 +proof-
  2.3978 +  have *:"g ` f ` s = s" using assms(3) by (auto simp add: image_iff)
  2.3979 +  { fix t assume t:"closedin (subtopology euclidean (g ` f ` s)) t"
  2.3980 +    then obtain T where T: "closed T" "t = s \<inter> T" unfolding closedin_closed unfolding * by auto
  2.3981 +    have "continuous_on (s \<inter> T) f" using continuous_on_subset[OF assms(1), of "s \<inter> t"]
  2.3982 +      unfolding T(2) and Int_left_absorb by auto
  2.3983 +    moreover have "compact (s \<inter> T)"
  2.3984 +      using assms(2) unfolding compact_eq_bounded_closed
  2.3985 +      using bounded_subset[of s "s \<inter> T"] and T(1) by auto
  2.3986 +    ultimately have "closed (f ` t)" using T(1) unfolding T(2)
  2.3987 +      using compact_continuous_image [of "s \<inter> T" f] unfolding compact_eq_bounded_closed by auto
  2.3988 +    moreover have "{x \<in> f ` s. g x \<in> t} = f ` s \<inter> f ` t" using assms(3) unfolding T(2) by auto
  2.3989 +    ultimately have "closedin (subtopology euclidean (f ` s)) {x \<in> f ` s. g x \<in> t}"
  2.3990 +      unfolding closedin_closed by auto  }
  2.3991 +  thus ?thesis unfolding continuous_on_closed by auto
  2.3992 +qed
  2.3993 +
  2.3994 +subsection{* A uniformly convergent limit of continuous functions is continuous.       *}
  2.3995 +
  2.3996 +lemma norm_triangle_lt:
  2.3997 +  fixes x y :: "'a::real_normed_vector"
  2.3998 +  shows "norm x + norm y < e \<Longrightarrow> norm (x + y) < e"
  2.3999 +by (rule le_less_trans [OF norm_triangle_ineq])
  2.4000 +
  2.4001 +lemma continuous_uniform_limit:
  2.4002 +  fixes f :: "'a \<Rightarrow> 'b::metric_space \<Rightarrow> 'c::real_normed_vector"
  2.4003 +  assumes "\<not> (trivial_limit net)"  "eventually (\<lambda>n. continuous_on s (f n)) net"
  2.4004 +  "\<forall>e>0. eventually (\<lambda>n. \<forall>x \<in> s. norm(f n x - g x) < e) net"
  2.4005 +  shows "continuous_on s g"
  2.4006 +proof-
  2.4007 +  { fix x and e::real assume "x\<in>s" "e>0"
  2.4008 +    have "eventually (\<lambda>n. \<forall>x\<in>s. norm (f n x - g x) < e / 3) net" using `e>0` assms(3)[THEN spec[where x="e/3"]] by auto
  2.4009 +    then obtain n where n:"\<forall>xa\<in>s. norm (f n xa - g xa) < e / 3"  "continuous_on s (f n)"
  2.4010 +      using eventually_and[of "(\<lambda>n. \<forall>x\<in>s. norm (f n x - g x) < e / 3)" "(\<lambda>n. continuous_on s (f n))" net] assms(1,2) eventually_happens by blast
  2.4011 +    have "e / 3 > 0" using `e>0` by auto
  2.4012 +    then obtain d where "d>0" and d:"\<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (f n x') (f n x) < e / 3"
  2.4013 +      using n(2)[unfolded continuous_on_def, THEN bspec[where x=x], OF `x\<in>s`, THEN spec[where x="e/3"]] by blast
  2.4014 +    { fix y assume "y\<in>s" "dist y x < d"
  2.4015 +      hence "dist (f n y) (f n x) < e / 3" using d[THEN bspec[where x=y]] by auto
  2.4016 +      hence "norm (f n y - g x) < 2 * e / 3" using norm_triangle_lt[of "f n y - f n x" "f n x - g x" "2*e/3"]
  2.4017 +	using n(1)[THEN bspec[where x=x], OF `x\<in>s`] unfolding dist_norm unfolding ab_group_add_class.ab_diff_minus by auto
  2.4018 +      hence "dist (g y) (g x) < e" unfolding dist_norm using n(1)[THEN bspec[where x=y], OF `y\<in>s`]
  2.4019 +	unfolding norm_minus_cancel[of "f n y - g y", THEN sym] using norm_triangle_lt[of "f n y - g x" "g y - f n y" e] by (auto simp add: uminus_add_conv_diff)  }
  2.4020 +    hence "\<exists>d>0. \<forall>x'\<in>s. dist x' x < d \<longrightarrow> dist (g x') (g x) < e" using `d>0` by auto  }
  2.4021 +  thus ?thesis unfolding continuous_on_def by auto
  2.4022 +qed
  2.4023 +
  2.4024 +subsection{* Topological properties of linear functions.                               *}
  2.4025 +
  2.4026 +lemma linear_lim_0:
  2.4027 +  assumes "bounded_linear f" shows "(f ---> 0) (at (0))"
  2.4028 +proof-
  2.4029 +  interpret f: bounded_linear f by fact
  2.4030 +  have "(f ---> f 0) (at 0)"
  2.4031 +    using tendsto_ident_at by (rule f.tendsto)
  2.4032 +  thus ?thesis unfolding f.zero .
  2.4033 +qed
  2.4034 +
  2.4035 +lemma linear_continuous_at:
  2.4036 +  assumes "bounded_linear f"  shows "continuous (at a) f"
  2.4037 +  unfolding continuous_at using assms
  2.4038 +  apply (rule bounded_linear.tendsto)
  2.4039 +  apply (rule tendsto_ident_at)
  2.4040 +  done
  2.4041 +
  2.4042 +lemma linear_continuous_within:
  2.4043 +  shows "bounded_linear f ==> continuous (at x within s) f"
  2.4044 +  using continuous_at_imp_continuous_within[of x f s] using linear_continuous_at[of f] by auto
  2.4045 +
  2.4046 +lemma linear_continuous_on:
  2.4047 +  shows "bounded_linear f ==> continuous_on s f"
  2.4048 +  using continuous_at_imp_continuous_on[of s f] using linear_continuous_at[of f] by auto
  2.4049 +
  2.4050 +text{* Also bilinear functions, in composition form.                             *}
  2.4051 +
  2.4052 +lemma bilinear_continuous_at_compose:
  2.4053 +  shows "continuous (at x) f \<Longrightarrow> continuous (at x) g \<Longrightarrow> bounded_bilinear h
  2.4054 +        ==> continuous (at x) (\<lambda>x. h (f x) (g x))"
  2.4055 +  unfolding continuous_at using Lim_bilinear[of f "f x" "(at x)" g "g x" h] by auto
  2.4056 +
  2.4057 +lemma bilinear_continuous_within_compose:
  2.4058 +  shows "continuous (at x within s) f \<Longrightarrow> continuous (at x within s) g \<Longrightarrow> bounded_bilinear h
  2.4059 +        ==> continuous (at x within s) (\<lambda>x. h (f x) (g x))"
  2.4060 +  unfolding continuous_within using Lim_bilinear[of f "f x"] by auto
  2.4061 +
  2.4062 +lemma bilinear_continuous_on_compose:
  2.4063 +  shows "continuous_on s f \<Longrightarrow> continuous_on s g \<Longrightarrow> bounded_bilinear h
  2.4064 +             ==> continuous_on s (\<lambda>x. h (f x) (g x))"
  2.4065 +  unfolding continuous_on_eq_continuous_within apply auto apply(erule_tac x=x in ballE) apply auto apply(erule_tac x=x in ballE) apply auto
  2.4066 +  using bilinear_continuous_within_compose[of _ s f g h] by auto
  2.4067 +
  2.4068 +subsection{* Topological stuff lifted from and dropped to R                            *}
  2.4069 +
  2.4070 +
  2.4071 +lemma open_real:
  2.4072 +  fixes s :: "real set" shows
  2.4073 + "open s \<longleftrightarrow>
  2.4074 +        (\<forall>x \<in> s. \<exists>e>0. \<forall>x'. abs(x' - x) < e --> x' \<in> s)" (is "?lhs = ?rhs")
  2.4075 +  unfolding open_dist dist_norm by simp
  2.4076 +
  2.4077 +lemma islimpt_approachable_real:
  2.4078 +  fixes s :: "real set"
  2.4079 +  shows "x islimpt s \<longleftrightarrow> (\<forall>e>0.  \<exists>x'\<in> s. x' \<noteq> x \<and> abs(x' - x) < e)"
  2.4080 +  unfolding islimpt_approachable dist_norm by simp
  2.4081 +
  2.4082 +lemma closed_real:
  2.4083 +  fixes s :: "real set"
  2.4084 +  shows "closed s \<longleftrightarrow>
  2.4085 +        (\<forall>x. (\<forall>e>0.  \<exists>x' \<in> s. x' \<noteq> x \<and> abs(x' - x) < e)
  2.4086 +            --> x \<in> s)"
  2.4087 +  unfolding closed_limpt islimpt_approachable dist_norm by simp
  2.4088 +
  2.4089 +lemma continuous_at_real_range:
  2.4090 +  fixes f :: "'a::real_normed_vector \<Rightarrow> real"
  2.4091 +  shows "continuous (at x) f \<longleftrightarrow> (\<forall>e>0. \<exists>d>0.
  2.4092 +        \<forall>x'. norm(x' - x) < d --> abs(f x' - f x) < e)"
  2.4093 +  unfolding continuous_at unfolding Lim_at
  2.4094 +  unfolding dist_nz[THEN sym] unfolding dist_norm apply auto
  2.4095 +  apply(erule_tac x=e in allE) apply auto apply (rule_tac x=d in exI) apply auto apply (erule_tac x=x' in allE) apply auto
  2.4096 +  apply(erule_tac x=e in allE) by auto
  2.4097 +
  2.4098 +lemma continuous_on_real_range:
  2.4099 +  fixes f :: "'a::real_normed_vector \<Rightarrow> real"
  2.4100 +  shows "continuous_on s f \<longleftrightarrow> (\<forall>x \<in> s. \<forall>e>0. \<exists>d>0. (\<forall>x' \<in> s. norm(x' - x) < d --> abs(f x' - f x) < e))"
  2.4101 +  unfolding continuous_on_def dist_norm by simp
  2.4102 +
  2.4103 +lemma continuous_at_norm: "continuous (at x) norm"
  2.4104 +  unfolding continuous_at by (intro tendsto_intros)
  2.4105 +
  2.4106 +lemma continuous_on_norm: "continuous_on s norm"
  2.4107 +unfolding continuous_on by (intro ballI tendsto_intros)
  2.4108 +
  2.4109 +lemma continuous_at_component: "continuous (at a) (\<lambda>x. x $ i)"
  2.4110 +unfolding continuous_at by (intro tendsto_intros)
  2.4111 +
  2.4112 +lemma continuous_on_component: "continuous_on s (\<lambda>x. x $ i)"
  2.4113 +unfolding continuous_on by (intro ballI tendsto_intros)
  2.4114 +
  2.4115 +lemma continuous_at_infnorm: "continuous (at x) infnorm"
  2.4116 +  unfolding continuous_at Lim_at o_def unfolding dist_norm
  2.4117 +  apply auto apply (rule_tac x=e in exI) apply auto
  2.4118 +  using order_trans[OF real_abs_sub_infnorm infnorm_le_norm, of _ x] by (metis xt1(7))
  2.4119 +
  2.4120 +text{* Hence some handy theorems on distance, diameter etc. of/from a set.       *}
  2.4121 +
  2.4122 +lemma compact_attains_sup:
  2.4123 +  fixes s :: "real set"
  2.4124 +  assumes "compact s"  "s \<noteq> {}"
  2.4125 +  shows "\<exists>x \<in> s. \<forall>y \<in> s. y \<le> x"
  2.4126 +proof-
  2.4127 +  from assms(1) have a:"bounded s" "closed s" unfolding compact_eq_bounded_closed by auto
  2.4128 +  { fix e::real assume as: "\<forall>x\<in>s. x \<le> rsup s" "rsup s \<notin> s"  "0 < e" "\<forall>x'\<in>s. x' = rsup s \<or> \<not> rsup s - x' < e"
  2.4129 +    have "isLub UNIV s (rsup s)" using rsup[OF assms(2)] unfolding setle_def using as(1) by auto
  2.4130 +    moreover have "isUb UNIV s (rsup s - e)" unfolding isUb_def unfolding setle_def using as(4,2) by auto
  2.4131 +    ultimately have False using isLub_le_isUb[of UNIV s "rsup s" "rsup s - e"] using `e>0` by auto  }
  2.4132 +  thus ?thesis using bounded_has_rsup(1)[OF a(1) assms(2)] using a(2)[unfolded closed_real, THEN spec[where x="rsup s"]]
  2.4133 +    apply(rule_tac x="rsup s" in bexI) by auto
  2.4134 +qed
  2.4135 +
  2.4136 +lemma compact_attains_inf:
  2.4137 +  fixes s :: "real set"
  2.4138 +  assumes "compact s" "s \<noteq> {}"  shows "\<exists>x \<in> s. \<forall>y \<in> s. x \<le> y"
  2.4139 +proof-
  2.4140 +  from assms(1) have a:"bounded s" "closed s" unfolding compact_eq_bounded_closed by auto
  2.4141 +  { fix e::real assume as: "\<forall>x\<in>s. x \<ge> rinf s"  "rinf s \<notin> s"  "0 < e"
  2.4142 +      "\<forall>x'\<in>s. x' = rinf s \<or> \<not> abs (x' - rinf s) < e"
  2.4143 +    have "isGlb UNIV s (rinf s)" using rinf[OF assms(2)] unfolding setge_def using as(1) by auto
  2.4144 +    moreover
  2.4145 +    { fix x assume "x \<in> s"
  2.4146 +      hence *:"abs (x - rinf s) = x - rinf s" using as(1)[THEN bspec[where x=x]] by auto
  2.4147 +      have "rinf s + e \<le> x" using as(4)[THEN bspec[where x=x]] using as(2) `x\<in>s` unfolding * by auto }
  2.4148 +    hence "isLb UNIV s (rinf s + e)" unfolding isLb_def and setge_def by auto
  2.4149 +    ultimately have False using isGlb_le_isLb[of UNIV s "rinf s" "rinf s + e"] using `e>0` by auto  }
  2.4150 +  thus ?thesis using bounded_has_rinf(1)[OF a(1) assms(2)] using a(2)[unfolded closed_real, THEN spec[where x="rinf s"]]
  2.4151 +    apply(rule_tac x="rinf s" in bexI) by auto
  2.4152 +qed
  2.4153 +
  2.4154 +lemma continuous_attains_sup:
  2.4155 +  fixes f :: "'a::metric_space \<Rightarrow> real"
  2.4156 +  shows "compact s \<Longrightarrow> s \<noteq> {} \<Longrightarrow> continuous_on s f
  2.4157 +        ==> (\<exists>x \<in> s. \<forall>y \<in> s.  f y \<le> f x)"
  2.4158 +  using compact_attains_sup[of "f ` s"]
  2.4159 +  using compact_continuous_image[of s f] by auto
  2.4160 +
  2.4161 +lemma continuous_attains_inf:
  2.4162 +  fixes f :: "'a::metric_space \<Rightarrow> real"
  2.4163 +  shows "compact s \<Longrightarrow> s \<noteq> {} \<Longrightarrow> continuous_on s f
  2.4164 +        \<Longrightarrow> (\<exists>x \<in> s. \<forall>y \<in> s. f x \<le> f y)"
  2.4165 +  using compact_attains_inf[of "f ` s"]
  2.4166 +  using compact_continuous_image[of s f] by auto
  2.4167 +
  2.4168 +lemma distance_attains_sup:
  2.4169 +  assumes "compact s" "s \<noteq> {}"
  2.4170 +  shows "\<exists>x \<in> s. \<forall>y \<in> s. dist a y \<le> dist a x"
  2.4171 +proof (rule continuous_attains_sup [OF assms])
  2.4172 +  { fix x assume "x\<in>s"
  2.4173 +    have "(dist a ---> dist a x) (at x within s)"
  2.4174 +      by (intro tendsto_dist tendsto_const Lim_at_within Lim_ident_at)
  2.4175 +  }
  2.4176 +  thus "continuous_on s (dist a)"
  2.4177 +    unfolding continuous_on ..
  2.4178 +qed
  2.4179 +
  2.4180 +text{* For *minimal* distance, we only need closure, not compactness.            *}
  2.4181 +
  2.4182 +lemma distance_attains_inf:
  2.4183 +  fixes a :: "'a::heine_borel"
  2.4184 +  assumes "closed s"  "s \<noteq> {}"
  2.4185 +  shows "\<exists>x \<in> s. \<forall>y \<in> s. dist a x \<le> dist a y"
  2.4186 +proof-
  2.4187 +  from assms(2) obtain b where "b\<in>s" by auto
  2.4188 +  let ?B = "cball a (dist b a) \<inter> s"
  2.4189 +  have "b \<in> ?B" using `b\<in>s` by (simp add: dist_commute)
  2.4190 +  hence "?B \<noteq> {}" by auto
  2.4191 +  moreover
  2.4192 +  { fix x assume "x\<in>?B"
  2.4193 +    fix e::real assume "e>0"
  2.4194 +    { fix x' assume "x'\<in>?B" and as:"dist x' x < e"
  2.4195 +      from as have "\<bar>dist a x' - dist a x\<bar> < e"
  2.4196 +        unfolding abs_less_iff minus_diff_eq
  2.4197 +        using dist_triangle2 [of a x' x]
  2.4198 +        using dist_triangle [of a x x']
  2.4199 +        by arith
  2.4200 +    }
  2.4201 +    hence "\<exists>d>0. \<forall>x'\<in>?B. dist x' x < d \<longrightarrow> \<bar>dist a x' - dist a x\<bar> < e"
  2.4202 +      using `e>0` by auto
  2.4203 +  }
  2.4204 +  hence "continuous_on (cball a (dist b a) \<inter> s) (dist a)"
  2.4205 +    unfolding continuous_on Lim_within dist_norm real_norm_def
  2.4206 +    by fast
  2.4207 +  moreover have "compact ?B"
  2.4208 +    using compact_cball[of a "dist b a"]
  2.4209 +    unfolding compact_eq_bounded_closed
  2.4210 +    using bounded_Int and closed_Int and assms(1) by auto
  2.4211 +  ultimately obtain x where "x\<in>cball a (dist b a) \<inter> s" "\<forall>y\<in>cball a (dist b a) \<inter> s. dist a x \<le> dist a y"
  2.4212 +    using continuous_attains_inf[of ?B "dist a"] by fastsimp
  2.4213 +  thus ?thesis by fastsimp
  2.4214 +qed
  2.4215 +
  2.4216 +subsection{* We can now extend limit compositions to consider the scalar multiplier.   *}
  2.4217 +
  2.4218 +lemma Lim_mul:
  2.4219 +  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  2.4220 +  assumes "(c ---> d) net"  "(f ---> l) net"
  2.4221 +  shows "((\<lambda>x. c(x) *\<^sub>R f x) ---> (d *\<^sub>R l)) net"
  2.4222 +  using assms by (rule scaleR.tendsto)
  2.4223 +
  2.4224 +lemma Lim_vmul:
  2.4225 +  fixes c :: "'a \<Rightarrow> real" and v :: "'b::real_normed_vector"
  2.4226 +  shows "(c ---> d) net ==> ((\<lambda>x. c(x) *\<^sub>R v) ---> d *\<^sub>R v) net"
  2.4227 +  by (intro tendsto_intros)
  2.4228 +
  2.4229 +lemma continuous_vmul:
  2.4230 +  fixes c :: "'a::metric_space \<Rightarrow> real" and v :: "'b::real_normed_vector"
  2.4231 +  shows "continuous net c ==> continuous net (\<lambda>x. c(x) *\<^sub>R v)"
  2.4232 +  unfolding continuous_def using Lim_vmul[of c] by auto
  2.4233 +
  2.4234 +lemma continuous_mul:
  2.4235 +  fixes c :: "'a::metric_space \<Rightarrow> real"
  2.4236 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.4237 +  shows "continuous net c \<Longrightarrow> continuous net f
  2.4238 +             ==> continuous net (\<lambda>x. c(x) *\<^sub>R f x) "
  2.4239 +  unfolding continuous_def by (intro tendsto_intros)
  2.4240 +
  2.4241 +lemma continuous_on_vmul:
  2.4242 +  fixes c :: "'a::metric_space \<Rightarrow> real" and v :: "'b::real_normed_vector"
  2.4243 +  shows "continuous_on s c ==> continuous_on s (\<lambda>x. c(x) *\<^sub>R v)"
  2.4244 +  unfolding continuous_on_eq_continuous_within using continuous_vmul[of _ c] by auto
  2.4245 +
  2.4246 +lemma continuous_on_mul:
  2.4247 +  fixes c :: "'a::metric_space \<Rightarrow> real"
  2.4248 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_vector"
  2.4249 +  shows "continuous_on s c \<Longrightarrow> continuous_on s f
  2.4250 +             ==> continuous_on s (\<lambda>x. c(x) *\<^sub>R f x)"
  2.4251 +  unfolding continuous_on_eq_continuous_within using continuous_mul[of _ c] by auto
  2.4252 +
  2.4253 +text{* And so we have continuity of inverse.                                     *}
  2.4254 +
  2.4255 +lemma Lim_inv:
  2.4256 +  fixes f :: "'a \<Rightarrow> real"
  2.4257 +  assumes "(f ---> l) (net::'a net)"  "l \<noteq> 0"
  2.4258 +  shows "((inverse o f) ---> inverse l) net"
  2.4259 +  unfolding o_def using assms by (rule tendsto_inverse)
  2.4260 +
  2.4261 +lemma continuous_inv:
  2.4262 +  fixes f :: "'a::metric_space \<Rightarrow> real"
  2.4263 +  shows "continuous net f \<Longrightarrow> f(netlimit net) \<noteq> 0
  2.4264 +           ==> continuous net (inverse o f)"
  2.4265 +  unfolding continuous_def using Lim_inv by auto
  2.4266 +
  2.4267 +lemma continuous_at_within_inv:
  2.4268 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_field"
  2.4269 +  assumes "continuous (at a within s) f" "f a \<noteq> 0"
  2.4270 +  shows "continuous (at a within s) (inverse o f)"
  2.4271 +  using assms unfolding continuous_within o_def
  2.4272 +  by (intro tendsto_intros)
  2.4273 +
  2.4274 +lemma continuous_at_inv:
  2.4275 +  fixes f :: "'a::metric_space \<Rightarrow> 'b::real_normed_field"
  2.4276 +  shows "continuous (at a) f \<Longrightarrow> f a \<noteq> 0
  2.4277 +         ==> continuous (at a) (inverse o f) "
  2.4278 +  using within_UNIV[THEN sym, of "at a"] using continuous_at_within_inv[of a UNIV] by auto
  2.4279 +
  2.4280 +subsection{* Preservation properties for pasted sets.                                  *}
  2.4281 +
  2.4282 +lemma bounded_pastecart:
  2.4283 +  fixes s :: "('a::real_normed_vector ^ _) set" (* FIXME: generalize to metric_space *)
  2.4284 +  assumes "bounded s" "bounded t"
  2.4285 +  shows "bounded { pastecart x y | x y . (x \<in> s \<and> y \<in> t)}"
  2.4286 +proof-
  2.4287 +  obtain a b where ab:"\<forall>x\<in>s. norm x \<le> a" "\<forall>x\<in>t. norm x \<le> b" using assms[unfolded bounded_iff] by auto
  2.4288 +  { fix x y assume "x\<in>s" "y\<in>t"
  2.4289 +    hence "norm x \<le> a" "norm y \<le> b" using ab by auto
  2.4290 +    hence "norm (pastecart x y) \<le> a + b" using norm_pastecart[of x y] by auto }
  2.4291 +  thus ?thesis unfolding bounded_iff by auto
  2.4292 +qed
  2.4293 +
  2.4294 +lemma bounded_Times:
  2.4295 +  assumes "bounded s" "bounded t" shows "bounded (s \<times> t)"
  2.4296 +proof-
  2.4297 +  obtain x y a b where "\<forall>z\<in>s. dist x z \<le> a" "\<forall>z\<in>t. dist y z \<le> b"
  2.4298 +    using assms [unfolded bounded_def] by auto
  2.4299 +  then have "\<forall>z\<in>s \<times> t. dist (x, y) z \<le> sqrt (a\<twosuperior> + b\<twosuperior>)"
  2.4300 +    by (auto simp add: dist_Pair_Pair real_sqrt_le_mono add_mono power_mono)
  2.4301 +  thus ?thesis unfolding bounded_any_center [where a="(x, y)"] by auto
  2.4302 +qed
  2.4303 +
  2.4304 +lemma closed_pastecart:
  2.4305 +  fixes s :: "(real ^ 'a::finite) set" (* FIXME: generalize *)
  2.4306 +  assumes "closed s"  "closed t"
  2.4307 +  shows "closed {pastecart x y | x y . x \<in> s \<and> y \<in> t}"
  2.4308 +proof-
  2.4309 +  { fix x l assume as:"\<forall>n::nat. x n \<in> {pastecart x y |x y. x \<in> s \<and> y \<in> t}"  "(x ---> l) sequentially"
  2.4310 +    { fix n::nat have "fstcart (x n) \<in> s" "sndcart (x n) \<in> t" using as(1)[THEN spec[where x=n]] by auto } note * = this
  2.4311 +    moreover
  2.4312 +    { fix e::real assume "e>0"
  2.4313 +      then obtain N::nat where N:"\<forall>n\<ge>N. dist (x n) l < e" using as(2)[unfolded Lim_sequentially, THEN spec[where x=e]] by auto
  2.4314 +      { fix n::nat assume "n\<ge>N"
  2.4315 +	hence "dist (fstcart (x n)) (fstcart l) < e" "dist (sndcart (x n)) (sndcart l) < e"
  2.4316 +	  using N[THEN spec[where x=n]] dist_fstcart[of "x n" l] dist_sndcart[of "x n" l] by auto   }
  2.4317 +      hence "\<exists>N. \<forall>n\<ge>N. dist (fstcart (x n)) (fstcart l) < e" "\<exists>N. \<forall>n\<ge>N. dist (sndcart (x n)) (sndcart l) < e" by auto  }
  2.4318 +    ultimately have "fstcart l \<in> s" "sndcart l \<in> t"
  2.4319 +      using assms(1)[unfolded closed_sequential_limits, THEN spec[where x="\<lambda>n. fstcart (x n)"], THEN spec[where x="fstcart l"]]
  2.4320 +      using assms(2)[unfolded closed_sequential_limits, THEN spec[where x="\<lambda>n. sndcart (x n)"], THEN spec[where x="sndcart l"]]
  2.4321 +      unfolding Lim_sequentially by auto
  2.4322 +    hence "l \<in> {pastecart x y |x y. x \<in> s \<and> y \<in> t}" using pastecart_fst_snd[THEN sym, of l] by auto  }
  2.4323 +  thus ?thesis unfolding closed_sequential_limits by auto
  2.4324 +qed
  2.4325 +
  2.4326 +lemma compact_pastecart:
  2.4327 +  fixes s t :: "(real ^ _) set"
  2.4328 +  shows "compact s \<Longrightarrow> compact t ==> compact {pastecart x y | x y . x \<in> s \<and> y \<in> t}"
  2.4329 +  unfolding compact_eq_bounded_closed using bounded_pastecart[of s t] closed_pastecart[of s t] by auto
  2.4330 +
  2.4331 +lemma mem_Times_iff: "x \<in> A \<times> B \<longleftrightarrow> fst x \<in> A \<and> snd x \<in> B"
  2.4332 +by (induct x) simp
  2.4333 +
  2.4334 +lemma compact_Times: "compact s \<Longrightarrow> compact t \<Longrightarrow> compact (s \<times> t)"
  2.4335 +unfolding compact_def
  2.4336 +apply clarify
  2.4337 +apply (drule_tac x="fst \<circ> f" in spec)
  2.4338 +apply (drule mp, simp add: mem_Times_iff)
  2.4339 +apply (clarify, rename_tac l1 r1)
  2.4340 +apply (drule_tac x="snd \<circ> f \<circ> r1" in spec)
  2.4341 +apply (drule mp, simp add: mem_Times_iff)
  2.4342 +apply (clarify, rename_tac l2 r2)
  2.4343 +apply (rule_tac x="(l1, l2)" in rev_bexI, simp)
  2.4344 +apply (rule_tac x="r1 \<circ> r2" in exI)
  2.4345 +apply (rule conjI, simp add: subseq_def)
  2.4346 +apply (drule_tac r=r2 in lim_subseq [COMP swap_prems_rl], assumption)
  2.4347 +apply (drule (1) tendsto_Pair) back
  2.4348 +apply (simp add: o_def)
  2.4349 +done
  2.4350 +
  2.4351 +text{* Hence some useful properties follow quite easily.                         *}
  2.4352 +
  2.4353 +lemma compact_scaling:
  2.4354 +  fixes s :: "'a::real_normed_vector set"
  2.4355 +  assumes "compact s"  shows "compact ((\<lambda>x. c *\<^sub>R x) ` s)"
  2.4356 +proof-
  2.4357 +  let ?f = "\<lambda>x. scaleR c x"
  2.4358 +  have *:"bounded_linear ?f" by (rule scaleR.bounded_linear_right)
  2.4359 +  show ?thesis using compact_continuous_image[of s ?f] continuous_at_imp_continuous_on[of s ?f]
  2.4360 +    using linear_continuous_at[OF *] assms by auto
  2.4361 +qed
  2.4362 +
  2.4363 +lemma compact_negations:
  2.4364 +  fixes s :: "'a::real_normed_vector set"
  2.4365 +  assumes "compact s"  shows "compact ((\<lambda>x. -x) ` s)"
  2.4366 +  using compact_scaling [OF assms, of "- 1"] by auto
  2.4367 +
  2.4368 +lemma compact_sums:
  2.4369 +  fixes s t :: "'a::real_normed_vector set"
  2.4370 +  assumes "compact s"  "compact t"  shows "compact {x + y | x y. x \<in> s \<and> y \<in> t}"
  2.4371 +proof-
  2.4372 +  have *:"{x + y | x y. x \<in> s \<and> y \<in> t} = (\<lambda>z. fst z + snd z) ` (s \<times> t)"
  2.4373 +    apply auto unfolding image_iff apply(rule_tac x="(xa, y)" in bexI) by auto
  2.4374 +  have "continuous_on (s \<times> t) (\<lambda>z. fst z + snd z)"
  2.4375 +    unfolding continuous_on by (rule ballI) (intro tendsto_intros)
  2.4376 +  thus ?thesis unfolding * using compact_continuous_image compact_Times [OF assms] by auto
  2.4377 +qed
  2.4378 +
  2.4379 +lemma compact_differences:
  2.4380 +  fixes s t :: "'a::real_normed_vector set"
  2.4381 +  assumes "compact s" "compact t"  shows "compact {x - y | x y. x \<in> s \<and> y \<in> t}"
  2.4382 +proof-
  2.4383 +  have "{x - y | x y. x\<in>s \<and> y \<in> t} =  {x + y | x y. x \<in> s \<and> y \<in> (uminus ` t)}"
  2.4384 +    apply auto apply(rule_tac x= xa in exI) apply auto apply(rule_tac x=xa in exI) by auto
  2.4385 +  thus ?thesis using compact_sums[OF assms(1) compact_negations[OF assms(2)]] by auto
  2.4386 +qed
  2.4387 +
  2.4388 +lemma compact_translation:
  2.4389 +  fixes s :: "'a::real_normed_vector set"
  2.4390 +  assumes "compact s"  shows "compact ((\<lambda>x. a + x) ` s)"
  2.4391 +proof-
  2.4392 +  have "{x + y |x y. x \<in> s \<and> y \<in> {a}} = (\<lambda>x. a + x) ` s" by auto
  2.4393 +  thus ?thesis using compact_sums[OF assms compact_sing[of a]] by auto
  2.4394 +qed
  2.4395 +
  2.4396 +lemma compact_affinity:
  2.4397 +  fixes s :: "'a::real_normed_vector set"
  2.4398 +  assumes "compact s"  shows "compact ((\<lambda>x. a + c *\<^sub>R x) ` s)"
  2.4399 +proof-
  2.4400 +  have "op + a ` op *\<^sub>R c ` s = (\<lambda>x. a + c *\<^sub>R x) ` s" by auto
  2.4401 +  thus ?thesis using compact_translation[OF compact_scaling[OF assms], of a c] by auto
  2.4402 +qed
  2.4403 +
  2.4404 +text{* Hence we get the following.                                               *}
  2.4405 +
  2.4406 +lemma compact_sup_maxdistance:
  2.4407 +  fixes s :: "'a::real_normed_vector set"
  2.4408 +  assumes "compact s"  "s \<noteq> {}"
  2.4409 +  shows "\<exists>x\<in>s. \<exists>y\<in>s. \<forall>u\<in>s. \<forall>v\<in>s. norm(u - v) \<le> norm(x - y)"
  2.4410 +proof-
  2.4411 +  have "{x - y | x y . x\<in>s \<and> y\<in>s} \<noteq> {}" using `s \<noteq> {}` by auto
  2.4412 +  then obtain x where x:"x\<in>{x - y |x y. x \<in> s \<and> y \<in> s}"  "\<forall>y\<in>{x - y |x y. x \<in> s \<and> y \<in> s}. norm y \<le> norm x"
  2.4413 +    using compact_differences[OF assms(1) assms(1)]
  2.4414 +    using distance_attains_sup[where 'a="'a", unfolded dist_norm, of "{x - y | x y . x\<in>s \<and> y\<in>s}" 0] by(auto simp add: norm_minus_cancel)
  2.4415 +  from x(1) obtain a b where "a\<in>s" "b\<in>s" "x = a - b" by auto
  2.4416 +  thus ?thesis using x(2)[unfolded `x = a - b`] by blast
  2.4417 +qed
  2.4418 +
  2.4419 +text{* We can state this in terms of diameter of a set.                          *}
  2.4420 +
  2.4421 +definition "diameter s = (if s = {} then 0::real else rsup {norm(x - y) | x y. x \<in> s \<and> y \<in> s})"
  2.4422 +  (* TODO: generalize to class metric_space *)
  2.4423 +
  2.4424 +lemma diameter_bounded:
  2.4425 +  assumes "bounded s"
  2.4426 +  shows "\<forall>x\<in>s. \<forall>y\<in>s. norm(x - y) \<le> diameter s"
  2.4427 +        "\<forall>d>0. d < diameter s --> (\<exists>x\<in>s. \<exists>y\<in>s. norm(x - y) > d)"
  2.4428 +proof-
  2.4429 +  let ?D = "{norm (x - y) |x y. x \<in> s \<and> y \<in> s}"
  2.4430 +  obtain a where a:"\<forall>x\<in>s. norm x \<le> a" using assms[unfolded bounded_iff] by auto
  2.4431 +  { fix x y assume "x \<in> s" "y \<in> s"
  2.4432 +    hence "norm (x - y) \<le> 2 * a" using norm_triangle_ineq[of x "-y", unfolded norm_minus_cancel] a[THEN bspec[where x=x]] a[THEN bspec[where x=y]] by (auto simp add: ring_simps)  }
  2.4433 +  note * = this
  2.4434 +  { fix x y assume "x\<in>s" "y\<in>s"  hence "s \<noteq> {}" by auto
  2.4435 +    have lub:"isLub UNIV ?D (rsup ?D)" using * rsup[of ?D] using `s\<noteq>{}` unfolding setle_def by auto
  2.4436 +    have "norm(x - y) \<le> diameter s" unfolding diameter_def using `s\<noteq>{}` *[OF `x\<in>s` `y\<in>s`] `x\<in>s` `y\<in>s` isLubD1[OF lub] unfolding setle_def by auto  }
  2.4437 +  moreover
  2.4438 +  { fix d::real assume "d>0" "d < diameter s"
  2.4439 +    hence "s\<noteq>{}" unfolding diameter_def by auto
  2.4440 +    hence lub:"isLub UNIV ?D (rsup ?D)" using * rsup[of ?D] unfolding setle_def by auto
  2.4441 +    have "\<exists>d' \<in> ?D. d' > d"
  2.4442 +    proof(rule ccontr)
  2.4443 +      assume "\<not> (\<exists>d'\<in>{norm (x - y) |x y. x \<in> s \<and> y \<in> s}. d < d')"
  2.4444 +      hence as:"\<forall>d'\<in>?D. d' \<le> d" apply auto apply(erule_tac x="norm (x - y)" in allE) by auto
  2.4445 +      hence "isUb UNIV ?D d" unfolding isUb_def unfolding setle_def by auto
  2.4446 +      thus False using `d < diameter s` `s\<noteq>{}` isLub_le_isUb[OF lub, of d] unfolding diameter_def  by auto
  2.4447 +    qed
  2.4448 +    hence "\<exists>x\<in>s. \<exists>y\<in>s. norm(x - y) > d" by auto  }
  2.4449 +  ultimately show "\<forall>x\<in>s. \<forall>y\<in>s. norm(x - y) \<le> diameter s"
  2.4450 +        "\<forall>d>0. d < diameter s --> (\<exists>x\<in>s. \<exists>y\<in>s. norm(x - y) > d)" by auto
  2.4451 +qed
  2.4452 +
  2.4453 +lemma diameter_bounded_bound:
  2.4454 + "bounded s \<Longrightarrow> x \<in> s \<Longrightarrow> y \<in> s ==> norm(x - y) \<le> diameter s"
  2.4455 +  using diameter_bounded by blast
  2.4456 +
  2.4457 +lemma diameter_compact_attained:
  2.4458 +  fixes s :: "'a::real_normed_vector set"
  2.4459 +  assumes "compact s"  "s \<noteq> {}"
  2.4460 +  shows "\<exists>x\<in>s. \<exists>y\<in>s. (norm(x - y) = diameter s)"
  2.4461 +proof-
  2.4462 +  have b:"bounded s" using assms(1) by (rule compact_imp_bounded)
  2.4463 +  then obtain x y where xys:"x\<in>s" "y\<in>s" and xy:"\<forall>u\<in>s. \<forall>v\<in>s. norm (u - v) \<le> norm (x - y)" using compact_sup_maxdistance[OF assms] by auto
  2.4464 +  hence "diameter s \<le> norm (x - y)" using rsup_le[of "{norm (x - y) |x y. x \<in> s \<and> y \<in> s}" "norm (x - y)"]
  2.4465 +    unfolding setle_def and diameter_def by auto
  2.4466 +  thus ?thesis using diameter_bounded(1)[OF b, THEN bspec[where x=x], THEN bspec[where x=y], OF xys] and xys by auto
  2.4467 +qed
  2.4468 +
  2.4469 +text{* Related results with closure as the conclusion.                           *}
  2.4470 +
  2.4471 +lemma closed_scaling:
  2.4472 +  fixes s :: "'a::real_normed_vector set"
  2.4473 +  assumes "closed s" shows "closed ((\<lambda>x. c *\<^sub>R x) ` s)"
  2.4474 +proof(cases "s={}")
  2.4475 +  case True thus ?thesis by auto
  2.4476 +next
  2.4477 +  case False
  2.4478 +  show ?thesis
  2.4479 +  proof(cases "c=0")
  2.4480 +    have *:"(\<lambda>x. 0) ` s = {0}" using `s\<noteq>{}` by auto
  2.4481 +    case True thus ?thesis apply auto unfolding * using closed_sing by auto
  2.4482 +  next
  2.4483 +    case False
  2.4484 +    { fix x l assume as:"\<forall>n::nat. x n \<in> scaleR c ` s"  "(x ---> l) sequentially"
  2.4485 +      { fix n::nat have "scaleR (1 / c) (x n) \<in> s"
  2.4486 +          using as(1)[THEN spec[where x=n]]
  2.4487 +          using `c\<noteq>0` by (auto simp add: vector_smult_assoc)
  2.4488 +      }
  2.4489 +      moreover
  2.4490 +      { fix e::real assume "e>0"
  2.4491 +	hence "0 < e *\<bar>c\<bar>"  using `c\<noteq>0` mult_pos_pos[of e "abs c"] by auto
  2.4492 +	then obtain N where "\<forall>n\<ge>N. dist (x n) l < e * \<bar>c\<bar>"
  2.4493 +          using as(2)[unfolded Lim_sequentially, THEN spec[where x="e * abs c"]] by auto
  2.4494 +	hence "\<exists>N. \<forall>n\<ge>N. dist (scaleR (1 / c) (x n)) (scaleR (1 / c) l) < e"
  2.4495 +          unfolding dist_norm unfolding scaleR_right_diff_distrib[THEN sym]
  2.4496 +	  using mult_imp_div_pos_less[of "abs c" _ e] `c\<noteq>0` by auto  }
  2.4497 +      hence "((\<lambda>n. scaleR (1 / c) (x n)) ---> scaleR (1 / c) l) sequentially" unfolding Lim_sequentially by auto
  2.4498 +      ultimately have "l \<in> scaleR c ` s"
  2.4499 +        using assms[unfolded closed_sequential_limits, THEN spec[where x="\<lambda>n. scaleR (1/c) (x n)"], THEN spec[where x="scaleR (1/c) l"]]
  2.4500 +	unfolding image_iff using `c\<noteq>0` apply(rule_tac x="scaleR (1 / c) l" in bexI) by auto  }
  2.4501 +    thus ?thesis unfolding closed_sequential_limits by fast
  2.4502 +  qed
  2.4503 +qed
  2.4504 +
  2.4505 +lemma closed_negations:
  2.4506 +  fixes s :: "'a::real_normed_vector set"
  2.4507 +  assumes "closed s"  shows "closed ((\<lambda>x. -x) ` s)"
  2.4508 +  using closed_scaling[OF assms, of "- 1"] by simp
  2.4509 +
  2.4510 +lemma compact_closed_sums:
  2.4511 +  fixes s :: "'a::real_normed_vector set"
  2.4512 +  assumes "compact s"  "closed t"  shows "closed {x + y | x y. x \<in> s \<and> y \<in> t}"
  2.4513 +proof-
  2.4514 +  let ?S = "{x + y |x y. x \<in> s \<and> y \<in> t}"
  2.4515 +  { fix x l assume as:"\<forall>n. x n \<in> ?S"  "(x ---> l) sequentially"
  2.4516 +    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"
  2.4517 +      using choice[of "\<lambda>n y. x n = (fst y) + (snd y) \<and> fst y \<in> s \<and> snd y \<in> t"] by auto
  2.4518 +    obtain l' r where "l'\<in>s" and r:"subseq r" and lr:"(((\<lambda>n. fst (f n)) \<circ> r) ---> l') sequentially"
  2.4519 +      using assms(1)[unfolded compact_def, THEN spec[where x="\<lambda> n. fst (f n)"]] using f(2) by auto
  2.4520 +    have "((\<lambda>n. snd (f (r n))) ---> l - l') sequentially"
  2.4521 +      using Lim_sub[OF lim_subseq[OF r as(2)] lr] and f(1) unfolding o_def by auto
  2.4522 +    hence "l - l' \<in> t"
  2.4523 +      using assms(2)[unfolded closed_sequential_limits, THEN spec[where x="\<lambda> n. snd (f (r n))"], THEN spec[where x="l - l'"]]
  2.4524 +      using f(3) by auto
  2.4525 +    hence "l \<in> ?S" using `l' \<in> s` apply auto apply(rule_tac x=l' in exI) apply(rule_tac x="l - l'" in exI) by auto
  2.4526 +  }
  2.4527 +  thus ?thesis unfolding closed_sequential_limits by fast
  2.4528 +qed
  2.4529 +
  2.4530 +lemma closed_compact_sums:
  2.4531 +  fixes s t :: "'a::real_normed_vector set"
  2.4532 +  assumes "closed s"  "compact t"
  2.4533 +  shows "closed {x + y | x y. x \<in> s \<and> y \<in> t}"
  2.4534 +proof-
  2.4535 +  have "{x + y |x y. x \<in> t \<and> y \<in> s} = {x + y |x y. x \<in> s \<and> y \<in> t}" apply auto
  2.4536 +    apply(rule_tac x=y in exI) apply auto apply(rule_tac x=y in exI) by auto
  2.4537 +  thus ?thesis using compact_closed_sums[OF assms(2,1)] by simp
  2.4538 +qed
  2.4539 +
  2.4540 +lemma compact_closed_differences:
  2.4541 +  fixes s t :: "'a::real_normed_vector set"
  2.4542 +  assumes "compact s"  "closed t"
  2.4543 +  shows "closed {x - y | x y. x \<in> s \<and> y \<in> t}"
  2.4544 +proof-
  2.4545 +  have "{x + y |x y. x \<in> s \<and> y \<in> uminus ` t} =  {x - y |x y. x \<in> s \<and> y \<in> t}"
  2.4546 +    apply auto apply(rule_tac x=xa in exI) apply auto apply(rule_tac x=xa in exI) by auto
  2.4547 +  thus ?thesis using compact_closed_sums[OF assms(1) closed_negations[OF assms(2)]] by auto
  2.4548 +qed
  2.4549 +
  2.4550 +lemma closed_compact_differences:
  2.4551 +  fixes s t :: "'a::real_normed_vector set"
  2.4552 +  assumes "closed s" "compact t"
  2.4553 +  shows "closed {x - y | x y. x \<in> s \<and> y \<in> t}"
  2.4554 +proof-
  2.4555 +  have "{x + y |x y. x \<in> s \<and> y \<in> uminus ` t} = {x - y |x y. x \<in> s \<and> y \<in> t}"
  2.4556 +    apply auto apply(rule_tac x=xa in exI) apply auto apply(rule_tac x=xa in exI) by auto
  2.4557 + thus ?thesis using closed_compact_sums[OF assms(1) compact_negations[OF assms(2)]] by simp
  2.4558 +qed
  2.4559 +
  2.4560 +lemma closed_translation:
  2.4561 +  fixes a :: "'a::real_normed_vector"
  2.4562 +  assumes "closed s"  shows "closed ((\<lambda>x. a + x) ` s)"
  2.4563 +proof-
  2.4564 +  have "{a + y |y. y \<in> s} = (op + a ` s)" by auto
  2.4565 +  thus ?thesis using compact_closed_sums[OF compact_sing[of a] assms] by auto
  2.4566 +qed
  2.4567 +
  2.4568 +lemma translation_UNIV:
  2.4569 +  fixes a :: "'a::ab_group_add" shows "range (\<lambda>x. a + x) = UNIV"
  2.4570 +  apply (auto simp add: image_iff) apply(rule_tac x="x - a" in exI) by auto
  2.4571 +
  2.4572 +lemma translation_diff:
  2.4573 +  fixes a :: "'a::ab_group_add"
  2.4574 +  shows "(\<lambda>x. a + x) ` (s - t) = ((\<lambda>x. a + x) ` s) - ((\<lambda>x. a + x) ` t)"
  2.4575 +  by auto
  2.4576 +
  2.4577 +lemma closure_translation:
  2.4578 +  fixes a :: "'a::real_normed_vector"
  2.4579 +  shows "closure ((\<lambda>x. a + x) ` s) = (\<lambda>x. a + x) ` (closure s)"
  2.4580 +proof-
  2.4581 +  have *:"op + a ` (UNIV - s) = UNIV - op + a ` s"
  2.4582 +    apply auto unfolding image_iff apply(rule_tac x="x - a" in bexI) by auto
  2.4583 +  show ?thesis unfolding closure_interior translation_diff translation_UNIV
  2.4584 +    using interior_translation[of a "UNIV - s"] unfolding * by auto
  2.4585 +qed
  2.4586 +
  2.4587 +lemma frontier_translation:
  2.4588 +  fixes a :: "'a::real_normed_vector"
  2.4589 +  shows "frontier((\<lambda>x. a + x) ` s) = (\<lambda>x. a + x) ` (frontier s)"
  2.4590 +  unfolding frontier_def translation_diff interior_translation closure_translation by auto
  2.4591 +
  2.4592 +subsection{* Separation between points and sets.                                       *}
  2.4593 +
  2.4594 +lemma separate_point_closed:
  2.4595 +  fixes s :: "'a::heine_borel set"
  2.4596 +  shows "closed s \<Longrightarrow> a \<notin> s  ==> (\<exists>d>0. \<forall>x\<in>s. d \<le> dist a x)"
  2.4597 +proof(cases "s = {}")
  2.4598 +  case True
  2.4599 +  thus ?thesis by(auto intro!: exI[where x=1])
  2.4600 +next
  2.4601 +  case False
  2.4602 +  assume "closed s" "a \<notin> s"
  2.4603 +  then obtain x where "x\<in>s" "\<forall>y\<in>s. dist a x \<le> dist a y" using `s \<noteq> {}` distance_attains_inf [of s a] by blast
  2.4604 +  with `x\<in>s` show ?thesis using dist_pos_lt[of a x] and`a \<notin> s` by blast
  2.4605 +qed
  2.4606 +
  2.4607 +lemma separate_compact_closed:
  2.4608 +  fixes s t :: "'a::{heine_borel, real_normed_vector} set"
  2.4609 +    (* TODO: does this generalize to heine_borel? *)
  2.4610 +  assumes "compact s" and "closed t" and "s \<inter> t = {}"
  2.4611 +  shows "\<exists>d>0. \<forall>x\<in>s. \<forall>y\<in>t. d \<le> dist x y"
  2.4612 +proof-
  2.4613 +  have "0 \<notin> {x - y |x y. x \<in> s \<and> y \<in> t}" using assms(3) by auto
  2.4614 +  then obtain d where "d>0" and d:"\<forall>x\<in>{x - y |x y. x \<in> s \<and> y \<in> t}. d \<le> dist 0 x"
  2.4615 +    using separate_point_closed[OF compact_closed_differences[OF assms(1,2)], of 0] by auto
  2.4616 +  { fix x y assume "x\<in>s" "y\<in>t"
  2.4617 +    hence "x - y \<in> {x - y |x y. x \<in> s \<and> y \<in> t}" by auto
  2.4618 +    hence "d \<le> dist (x - y) 0" using d[THEN bspec[where x="x - y"]] using dist_commute
  2.4619 +      by (auto  simp add: dist_commute)
  2.4620 +    hence "d \<le> dist x y" unfolding dist_norm by auto  }
  2.4621 +  thus ?thesis using `d>0` by auto
  2.4622 +qed
  2.4623 +
  2.4624 +lemma separate_closed_compact:
  2.4625 +  fixes s t :: "'a::{heine_borel, real_normed_vector} set"
  2.4626 +  assumes "closed s" and "compact t" and "s \<inter> t = {}"
  2.4627 +  shows "\<exists>d>0. \<forall>x\<in>s. \<forall>y\<in>t. d \<le> dist x y"
  2.4628 +proof-
  2.4629 +  have *:"t \<inter> s = {}" using assms(3) by auto
  2.4630 +  show ?thesis using separate_compact_closed[OF assms(2,1) *]
  2.4631 +    apply auto apply(rule_tac x=d in exI) apply auto apply (erule_tac x=y in ballE)
  2.4632 +    by (auto simp add: dist_commute)
  2.4633 +qed
  2.4634 +
  2.4635 +(* A cute way of denoting open and closed intervals using overloading.       *)
  2.4636 +
  2.4637 +lemma interval: fixes a :: "'a::ord^'n::finite" shows
  2.4638 +  "{a <..< b} = {x::'a^'n. \<forall>i. a$i < x$i \<and> x$i < b$i}" and
  2.4639 +  "{a .. b} = {x::'a^'n. \<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i}"
  2.4640 +  by (auto simp add: expand_set_eq vector_less_def vector_less_eq_def)
  2.4641 +
  2.4642 +lemma mem_interval: fixes a :: "'a::ord^'n::finite" shows
  2.4643 +  "x \<in> {a<..<b} \<longleftrightarrow> (\<forall>i. a$i < x$i \<and> x$i < b$i)"
  2.4644 +  "x \<in> {a .. b} \<longleftrightarrow> (\<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i)"
  2.4645 +  using interval[of a b] by(auto simp add: expand_set_eq vector_less_def vector_less_eq_def)
  2.4646 +
  2.4647 +lemma mem_interval_1: fixes x :: "real^1" shows
  2.4648 + "(x \<in> {a .. b} \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 x \<and> dest_vec1 x \<le> dest_vec1 b)"
  2.4649 + "(x \<in> {a<..<b} \<longleftrightarrow> dest_vec1 a < dest_vec1 x \<and> dest_vec1 x < dest_vec1 b)"
  2.4650 +by(simp_all add: Cart_eq vector_less_def vector_less_eq_def dest_vec1_def forall_1)
  2.4651 +
  2.4652 +lemma interval_eq_empty: fixes a :: "real^'n::finite" shows
  2.4653 + "({a <..< b} = {} \<longleftrightarrow> (\<exists>i. b$i \<le> a$i))" (is ?th1) and
  2.4654 + "({a  ..  b} = {} \<longleftrightarrow> (\<exists>i. b$i < a$i))" (is ?th2)
  2.4655 +proof-
  2.4656 +  { fix i x assume as:"b$i \<le> a$i" and x:"x\<in>{a <..< b}"
  2.4657 +    hence "a $ i < x $ i \<and> x $ i < b $ i" unfolding mem_interval by auto
  2.4658 +    hence "a$i < b$i" by auto
  2.4659 +    hence False using as by auto  }
  2.4660 +  moreover
  2.4661 +  { assume as:"\<forall>i. \<not> (b$i \<le> a$i)"
  2.4662 +    let ?x = "(1/2) *\<^sub>R (a + b)"
  2.4663 +    { fix i
  2.4664 +      have "a$i < b$i" using as[THEN spec[where x=i]] by auto
  2.4665 +      hence "a$i < ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i < b$i"
  2.4666 +	unfolding vector_smult_component and vector_add_component
  2.4667 +	by (auto simp add: less_divide_eq_number_of1)  }
  2.4668 +    hence "{a <..< b} \<noteq> {}" using mem_interval(1)[of "?x" a b] by auto  }
  2.4669 +  ultimately show ?th1 by blast
  2.4670 +
  2.4671 +  { fix i x assume as:"b$i < a$i" and x:"x\<in>{a .. b}"
  2.4672 +    hence "a $ i \<le> x $ i \<and> x $ i \<le> b $ i" unfolding mem_interval by auto
  2.4673 +    hence "a$i \<le> b$i" by auto
  2.4674 +    hence False using as by auto  }
  2.4675 +  moreover
  2.4676 +  { assume as:"\<forall>i. \<not> (b$i < a$i)"
  2.4677 +    let ?x = "(1/2) *\<^sub>R (a + b)"
  2.4678 +    { fix i
  2.4679 +      have "a$i \<le> b$i" using as[THEN spec[where x=i]] by auto
  2.4680 +      hence "a$i \<le> ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i \<le> b$i"
  2.4681 +	unfolding vector_smult_component and vector_add_component
  2.4682 +	by (auto simp add: less_divide_eq_number_of1)  }
  2.4683 +    hence "{a .. b} \<noteq> {}" using mem_interval(2)[of "?x" a b] by auto  }
  2.4684 +  ultimately show ?th2 by blast
  2.4685 +qed
  2.4686 +
  2.4687 +lemma interval_ne_empty: fixes a :: "real^'n::finite" shows
  2.4688 +  "{a  ..  b} \<noteq> {} \<longleftrightarrow> (\<forall>i. a$i \<le> b$i)" and
  2.4689 +  "{a <..< b} \<noteq> {} \<longleftrightarrow> (\<forall>i. a$i < b$i)"
  2.4690 +  unfolding interval_eq_empty[of a b] by (auto simp add: not_less not_le) (* BH: Why doesn't just "auto" work here? *)
  2.4691 +
  2.4692 +lemma subset_interval_imp: fixes a :: "real^'n::finite" shows
  2.4693 + "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> {c .. d} \<subseteq> {a .. b}" and
  2.4694 + "(\<forall>i. a$i < c$i \<and> d$i < b$i) \<Longrightarrow> {c .. d} \<subseteq> {a<..<b}" and
  2.4695 + "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> {c<..<d} \<subseteq> {a .. b}" and
  2.4696 + "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> {c<..<d} \<subseteq> {a<..<b}"
  2.4697 +  unfolding subset_eq[unfolded Ball_def] unfolding mem_interval
  2.4698 +  by (auto intro: order_trans less_le_trans le_less_trans less_imp_le) (* BH: Why doesn't just "auto" work here? *)
  2.4699 +
  2.4700 +lemma interval_sing: fixes a :: "'a::linorder^'n::finite" shows
  2.4701 + "{a .. a} = {a} \<and> {a<..<a} = {}"
  2.4702 +apply(auto simp add: expand_set_eq vector_less_def vector_less_eq_def Cart_eq)
  2.4703 +apply (simp add: order_eq_iff)
  2.4704 +apply (auto simp add: not_less less_imp_le)
  2.4705 +done
  2.4706 +
  2.4707 +lemma interval_open_subset_closed:  fixes a :: "'a::preorder^'n::finite" shows
  2.4708 + "{a<..<b} \<subseteq> {a .. b}"
  2.4709 +proof(simp add: subset_eq, rule)
  2.4710 +  fix x
  2.4711 +  assume x:"x \<in>{a<..<b}"
  2.4712 +  { fix i
  2.4713 +    have "a $ i \<le> x $ i"
  2.4714 +      using x order_less_imp_le[of "a$i" "x$i"]
  2.4715 +      by(simp add: expand_set_eq vector_less_def vector_less_eq_def Cart_eq)
  2.4716 +  }
  2.4717 +  moreover
  2.4718 +  { fix i
  2.4719 +    have "x $ i \<le> b $ i"
  2.4720 +      using x order_less_imp_le[of "x$i" "b$i"]
  2.4721 +      by(simp add: expand_set_eq vector_less_def vector_less_eq_def Cart_eq)
  2.4722 +  }
  2.4723 +  ultimately
  2.4724 +  show "a \<le> x \<and> x \<le> b"
  2.4725 +    by(simp add: expand_set_eq vector_less_def vector_less_eq_def Cart_eq)
  2.4726 +qed
  2.4727 +
  2.4728 +lemma subset_interval: fixes a :: "real^'n::finite" shows
  2.4729 + "{c .. d} \<subseteq> {a .. b} \<longleftrightarrow> (\<forall>i. c$i \<le> d$i) --> (\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i)" (is ?th1) and
  2.4730 + "{c .. d} \<subseteq> {a<..<b} \<longleftrightarrow> (\<forall>i. c$i \<le> d$i) --> (\<forall>i. a$i < c$i \<and> d$i < b$i)" (is ?th2) and
  2.4731 + "{c<..<d} \<subseteq> {a .. b} \<longleftrightarrow> (\<forall>i. c$i < d$i) --> (\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i)" (is ?th3) and
  2.4732 + "{c<..<d} \<subseteq> {a<..<b} \<longleftrightarrow> (\<forall>i. c$i < d$i) --> (\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i)" (is ?th4)
  2.4733 +proof-
  2.4734 +  show ?th1 unfolding subset_eq and Ball_def and mem_interval by (auto intro: order_trans)
  2.4735 +  show ?th2 unfolding subset_eq and Ball_def and mem_interval by (auto intro: le_less_trans less_le_trans order_trans less_imp_le)
  2.4736 +  { assume as: "{c<..<d} \<subseteq> {a .. b}" "\<forall>i. c$i < d$i"
  2.4737 +    hence "{c<..<d} \<noteq> {}" unfolding interval_eq_empty by (auto, drule_tac x=i in spec, simp) (* BH: Why doesn't just "auto" work? *)
  2.4738 +    fix i
  2.4739 +    (** TODO combine the following two parts as done in the HOL_light version. **)
  2.4740 +    { let ?x = "(\<chi> j. (if j=i then ((min (a$j) (d$j))+c$j)/2 else (c$j+d$j)/2))::real^'n"
  2.4741 +      assume as2: "a$i > c$i"
  2.4742 +      { fix j
  2.4743 +	have "c $ j < ?x $ j \<and> ?x $ j < d $ j" unfolding Cart_lambda_beta
  2.4744 +	  apply(cases "j=i") using as(2)[THEN spec[where x=j]]
  2.4745 +	  by (auto simp add: less_divide_eq_number_of1 as2)  }
  2.4746 +      hence "?x\<in>{c<..<d}" unfolding mem_interval by auto
  2.4747 +      moreover
  2.4748 +      have "?x\<notin>{a .. b}"
  2.4749 +	unfolding mem_interval apply auto apply(rule_tac x=i in exI)
  2.4750 +	using as(2)[THEN spec[where x=i]] and as2
  2.4751 +	by (auto simp add: less_divide_eq_number_of1)
  2.4752 +      ultimately have False using as by auto  }
  2.4753 +    hence "a$i \<le> c$i" by(rule ccontr)auto
  2.4754 +    moreover
  2.4755 +    { let ?x = "(\<chi> j. (if j=i then ((max (b$j) (c$j))+d$j)/2 else (c$j+d$j)/2))::real^'n"
  2.4756 +      assume as2: "b$i < d$i"
  2.4757 +      { fix j
  2.4758 +	have "d $ j > ?x $ j \<and> ?x $ j > c $ j" unfolding Cart_lambda_beta
  2.4759 +	  apply(cases "j=i") using as(2)[THEN spec[where x=j]]
  2.4760 +	  by (auto simp add: less_divide_eq_number_of1 as2)  }
  2.4761 +      hence "?x\<in>{c<..<d}" unfolding mem_interval by auto
  2.4762 +      moreover
  2.4763 +      have "?x\<notin>{a .. b}"
  2.4764 +	unfolding mem_interval apply auto apply(rule_tac x=i in exI)
  2.4765 +	using as(2)[THEN spec[where x=i]] and as2
  2.4766 +	by (auto simp add: less_divide_eq_number_of1)
  2.4767 +      ultimately have False using as by auto  }
  2.4768 +    hence "b$i \<ge> d$i" by(rule ccontr)auto
  2.4769 +    ultimately
  2.4770 +    have "a$i \<le> c$i \<and> d$i \<le> b$i" by auto
  2.4771 +  } note part1 = this
  2.4772 +  thus ?th3 unfolding subset_eq and Ball_def and mem_interval apply auto apply (erule_tac x=ia in allE, simp)+ by (erule_tac x=i in allE, erule_tac x=i in allE, simp)+
  2.4773 +  { assume as:"{c<..<d} \<subseteq> {a<..<b}" "\<forall>i. c$i < d$i"
  2.4774 +    fix i
  2.4775 +    from as(1) have "{c<..<d} \<subseteq> {a..b}" using interval_open_subset_closed[of a b] by auto
  2.4776 +    hence "a$i \<le> c$i \<and> d$i \<le> b$i" using part1 and as(2) by auto  } note * = this
  2.4777 +  thus ?th4 unfolding subset_eq and Ball_def and mem_interval apply auto apply (erule_tac x=ia in allE, simp)+ by (erule_tac x=i in allE, erule_tac x=i in allE, simp)+
  2.4778 +qed
  2.4779 +
  2.4780 +lemma disjoint_interval: fixes a::"real^'n::finite" shows
  2.4781 +  "{a .. b} \<inter> {c .. d} = {} \<longleftrightarrow> (\<exists>i. (b$i < a$i \<or> d$i < c$i \<or> b$i < c$i \<or> d$i < a$i))" (is ?th1) and
  2.4782 +  "{a .. b} \<inter> {c<..<d} = {} \<longleftrightarrow> (\<exists>i. (b$i < a$i \<or> d$i \<le> c$i \<or> b$i \<le> c$i \<or> d$i \<le> a$i))" (is ?th2) and
  2.4783 +  "{a<..<b} \<inter> {c .. d} = {} \<longleftrightarrow> (\<exists>i. (b$i \<le> a$i \<or> d$i < c$i \<or> b$i \<le> c$i \<or> d$i \<le> a$i))" (is ?th3) and
  2.4784 +  "{a<..<b} \<inter> {c<..<d} = {} \<longleftrightarrow> (\<exists>i. (b$i \<le> a$i \<or> d$i \<le> c$i \<or> b$i \<le> c$i \<or> d$i \<le> a$i))" (is ?th4)
  2.4785 +proof-
  2.4786 +  let ?z = "(\<chi> i. ((max (a$i) (c$i)) + (min (b$i) (d$i))) / 2)::real^'n"
  2.4787 +  show ?th1 ?th2 ?th3 ?th4
  2.4788 +  unfolding expand_set_eq and Int_iff and empty_iff and mem_interval and all_conj_distrib[THEN sym] and eq_False
  2.4789 +  apply (auto elim!: allE[where x="?z"])
  2.4790 +  apply ((rule_tac x=x in exI, force) | (rule_tac x=i in exI, force))+
  2.4791 +  done
  2.4792 +qed
  2.4793 +
  2.4794 +lemma inter_interval: fixes a :: "'a::linorder^'n::finite" shows
  2.4795 + "{a .. b} \<inter> {c .. d} =  {(\<chi> i. max (a$i) (c$i)) .. (\<chi> i. min (b$i) (d$i))}"
  2.4796 +  unfolding expand_set_eq and Int_iff and mem_interval
  2.4797 +  by (auto simp add: less_divide_eq_number_of1 intro!: bexI)
  2.4798 +
  2.4799 +(* Moved interval_open_subset_closed a bit upwards *)
  2.4800 +
  2.4801 +lemma open_interval_lemma: fixes x :: "real" shows
  2.4802 + "a < x \<Longrightarrow> x < b ==> (\<exists>d>0. \<forall>x'. abs(x' - x) < d --> a < x' \<and> x' < b)"
  2.4803 +  by(rule_tac x="min (x - a) (b - x)" in exI, auto)
  2.4804 +
  2.4805 +lemma open_interval: fixes a :: "real^'n::finite" shows "open {a<..<b}"
  2.4806 +proof-
  2.4807 +  { fix x assume x:"x\<in>{a<..<b}"
  2.4808 +    { fix i
  2.4809 +      have "\<exists>d>0. \<forall>x'. abs (x' - (x$i)) < d \<longrightarrow> a$i < x' \<and> x' < b$i"
  2.4810 +	using x[unfolded mem_interval, THEN spec[where x=i]]
  2.4811 +	using open_interval_lemma[of "a$i" "x$i" "b$i"] by auto  }
  2.4812 +
  2.4813 +    hence "\<forall>i. \<exists>d>0. \<forall>x'. abs (x' - (x$i)) < d \<longrightarrow> a$i < x' \<and> x' < b$i" by auto
  2.4814 +    then obtain d where d:"\<forall>i. 0 < d i \<and> (\<forall>x'. \<bar>x' - x $ i\<bar> < d i \<longrightarrow> a $ i < x' \<and> x' < b $ i)"
  2.4815 +      using bchoice[of "UNIV" "\<lambda>i d. d>0 \<and> (\<forall>x'. \<bar>x' - x $ i\<bar> < d \<longrightarrow> a $ i < x' \<and> x' < b $ i)"] by auto
  2.4816 +
  2.4817 +    let ?d = "Min (range d)"
  2.4818 +    have **:"finite (range d)" "range d \<noteq> {}" by auto
  2.4819 +    have "?d>0" unfolding Min_gr_iff[OF **] using d by auto
  2.4820 +    moreover
  2.4821 +    { fix x' assume as:"dist x' x < ?d"
  2.4822 +      { fix i
  2.4823 +	have "\<bar>x'$i - x $ i\<bar> < d i"
  2.4824 +	  using norm_bound_component_lt[OF as[unfolded dist_norm], of i]
  2.4825 +	  unfolding vector_minus_component and Min_gr_iff[OF **] by auto
  2.4826 +	hence "a $ i < x' $ i" "x' $ i < b $ i" using d[THEN spec[where x=i]] by auto  }
  2.4827 +      hence "a < x' \<and> x' < b" unfolding vector_less_def by auto  }
  2.4828 +    ultimately have "\<exists>e>0. \<forall>x'. dist x' x < e \<longrightarrow> x' \<in> {a<..<b}" by (auto, rule_tac x="?d" in exI, simp)
  2.4829 +  }
  2.4830 +  thus ?thesis unfolding open_dist using open_interval_lemma by auto
  2.4831 +qed
  2.4832 +
  2.4833 +lemma closed_interval: fixes a :: "real^'n::finite" shows "closed {a .. b}"
  2.4834 +proof-
  2.4835 +  { fix x i assume as:"\<forall>e>0. \<exists>x'\<in>{a..b}. x' \<noteq> x \<and> dist x' x < e"(* and xab:"a$i > x$i \<or> b$i < x$i"*)
  2.4836 +    { assume xa:"a$i > x$i"
  2.4837 +      with as obtain y where y:"y\<in>{a..b}" "y \<noteq> x" "dist y x < a$i - x$i" by(erule_tac x="a$i - x$i" in allE)auto
  2.4838 +      hence False unfolding mem_interval and dist_norm
  2.4839 +	using component_le_norm[of "y-x" i, unfolded vector_minus_component] and xa by(auto elim!: allE[where x=i])
  2.4840 +    } hence "a$i \<le> x$i" by(rule ccontr)auto
  2.4841 +    moreover
  2.4842 +    { assume xb:"b$i < x$i"
  2.4843 +      with as obtain y where y:"y\<in>{a..b}" "y \<noteq> x" "dist y x < x$i - b$i" by(erule_tac x="x$i - b$i" in allE)auto
  2.4844 +      hence False unfolding mem_interval and dist_norm
  2.4845 +	using component_le_norm[of "y-x" i, unfolded vector_minus_component] and xb by(auto elim!: allE[where x=i])
  2.4846 +    } hence "x$i \<le> b$i" by(rule ccontr)auto
  2.4847 +    ultimately
  2.4848 +    have "a $ i \<le> x $ i \<and> x $ i \<le> b $ i" by auto }
  2.4849 +  thus ?thesis unfolding closed_limpt islimpt_approachable mem_interval by auto
  2.4850 +qed
  2.4851 +
  2.4852 +lemma interior_closed_interval: fixes a :: "real^'n::finite" shows
  2.4853 + "interior {a .. b} = {a<..<b}" (is "?L = ?R")
  2.4854 +proof(rule subset_antisym)
  2.4855 +  show "?R \<subseteq> ?L" using interior_maximal[OF interval_open_subset_closed open_interval] by auto
  2.4856 +next
  2.4857 +  { fix x assume "\<exists>T. open T \<and> x \<in> T \<and> T \<subseteq> {a..b}"
  2.4858 +    then obtain s where s:"open s" "x \<in> s" "s \<subseteq> {a..b}" by auto
  2.4859 +    then obtain e where "e>0" and e:"\<forall>x'. dist x' x < e \<longrightarrow> x' \<in> {a..b}" unfolding open_dist and subset_eq by auto
  2.4860 +    { fix i
  2.4861 +      have "dist (x - (e / 2) *\<^sub>R basis i) x < e"
  2.4862 +	   "dist (x + (e / 2) *\<^sub>R basis i) x < e"
  2.4863 +	unfolding dist_norm apply auto
  2.4864 +	unfolding norm_minus_cancel using norm_basis[of i] and `e>0` by auto
  2.4865 +      hence "a $ i \<le> (x - (e / 2) *\<^sub>R basis i) $ i"
  2.4866 +                    "(x + (e / 2) *\<^sub>R basis i) $ i \<le> b $ i"
  2.4867 +	using e[THEN spec[where x="x - (e/2) *\<^sub>R basis i"]]
  2.4868 +	and   e[THEN spec[where x="x + (e/2) *\<^sub>R basis i"]]
  2.4869 +	unfolding mem_interval by (auto elim!: allE[where x=i])
  2.4870 +      hence "a $ i < x $ i" and "x $ i < b $ i"
  2.4871 +	unfolding vector_minus_component and vector_add_component
  2.4872 +	unfolding vector_smult_component and basis_component using `e>0` by auto   }
  2.4873 +    hence "x \<in> {a<..<b}" unfolding mem_interval by auto  }
  2.4874 +  thus "?L \<subseteq> ?R" unfolding interior_def and subset_eq by auto
  2.4875 +qed
  2.4876 +
  2.4877 +lemma bounded_closed_interval: fixes a :: "real^'n::finite" shows
  2.4878 + "bounded {a .. b}"
  2.4879 +proof-
  2.4880 +  let ?b = "\<Sum>i\<in>UNIV. \<bar>a$i\<bar> + \<bar>b$i\<bar>"
  2.4881 +  { fix x::"real^'n" assume x:"\<forall>i. a $ i \<le> x $ i \<and> x $ i \<le> b $ i"
  2.4882 +    { fix i
  2.4883 +      have "\<bar>x$i\<bar> \<le> \<bar>a$i\<bar> + \<bar>b$i\<bar>" using x[THEN spec[where x=i]] by auto  }
  2.4884 +    hence "(\<Sum>i\<in>UNIV. \<bar>x $ i\<bar>) \<le> ?b" by(rule setsum_mono)
  2.4885 +    hence "norm x \<le> ?b" using norm_le_l1[of x] by auto  }
  2.4886 +  thus ?thesis unfolding interval and bounded_iff by auto
  2.4887 +qed
  2.4888 +
  2.4889 +lemma bounded_interval: fixes a :: "real^'n::finite" shows
  2.4890 + "bounded {a .. b} \<and> bounded {a<..<b}"
  2.4891 +  using bounded_closed_interval[of a b]
  2.4892 +  using interval_open_subset_closed[of a b]
  2.4893 +  using bounded_subset[of "{a..b}" "{a<..<b}"]
  2.4894 +  by simp
  2.4895 +
  2.4896 +lemma not_interval_univ: fixes a :: "real^'n::finite" shows
  2.4897 + "({a .. b} \<noteq> UNIV) \<and> ({a<..<b} \<noteq> UNIV)"
  2.4898 +  using bounded_interval[of a b]
  2.4899 +  by auto
  2.4900 +
  2.4901 +lemma compact_interval: fixes a :: "real^'n::finite" shows
  2.4902 + "compact {a .. b}"
  2.4903 +  using bounded_closed_imp_compact using bounded_interval[of a b] using closed_interval[of a b] by auto
  2.4904 +
  2.4905 +lemma open_interval_midpoint: fixes a :: "real^'n::finite"
  2.4906 +  assumes "{a<..<b} \<noteq> {}" shows "((1/2) *\<^sub>R (a + b)) \<in> {a<..<b}"
  2.4907 +proof-
  2.4908 +  { fix i
  2.4909 +    have "a $ i < ((1 / 2) *\<^sub>R (a + b)) $ i \<and> ((1 / 2) *\<^sub>R (a + b)) $ i < b $ i"
  2.4910 +      using assms[unfolded interval_ne_empty, THEN spec[where x=i]]
  2.4911 +      unfolding vector_smult_component and vector_add_component
  2.4912 +      by(auto simp add: less_divide_eq_number_of1)  }
  2.4913 +  thus ?thesis unfolding mem_interval by auto
  2.4914 +qed
  2.4915 +
  2.4916 +lemma open_closed_interval_convex: fixes x :: "real^'n::finite"
  2.4917 +  assumes x:"x \<in> {a<..<b}" and y:"y \<in> {a .. b}" and e:"0 < e" "e \<le> 1"
  2.4918 +  shows "(e *\<^sub>R x + (1 - e) *\<^sub>R y) \<in> {a<..<b}"
  2.4919 +proof-
  2.4920 +  { fix i
  2.4921 +    have "a $ i = e * a$i + (1 - e) * a$i" unfolding left_diff_distrib by simp
  2.4922 +    also have "\<dots> < e * x $ i + (1 - e) * y $ i" apply(rule add_less_le_mono)
  2.4923 +      using e unfolding mult_less_cancel_left and mult_le_cancel_left apply simp_all
  2.4924 +      using x unfolding mem_interval  apply simp
  2.4925 +      using y unfolding mem_interval  apply simp
  2.4926 +      done
  2.4927 +    finally have "a $ i < (e *\<^sub>R x + (1 - e) *\<^sub>R y) $ i" by auto
  2.4928 +    moreover {
  2.4929 +    have "b $ i = e * b$i + (1 - e) * b$i" unfolding left_diff_distrib by simp
  2.4930 +    also have "\<dots> > e * x $ i + (1 - e) * y $ i" apply(rule add_less_le_mono)
  2.4931 +      using e unfolding mult_less_cancel_left and mult_le_cancel_left apply simp_all
  2.4932 +      using x unfolding mem_interval  apply simp
  2.4933 +      using y unfolding mem_interval  apply simp
  2.4934 +      done
  2.4935 +    finally have "(e *\<^sub>R x + (1 - e) *\<^sub>R y) $ i < b $ i" by auto
  2.4936 +    } ultimately have "a $ i < (e *\<^sub>R x + (1 - e) *\<^sub>R y) $ i \<and> (e *\<^sub>R x + (1 - e) *\<^sub>R y) $ i < b $ i" by auto }
  2.4937 +  thus ?thesis unfolding mem_interval by auto
  2.4938 +qed
  2.4939 +
  2.4940 +lemma closure_open_interval: fixes a :: "real^'n::finite"
  2.4941 +  assumes "{a<..<b} \<noteq> {}"
  2.4942 +  shows "closure {a<..<b} = {a .. b}"
  2.4943 +proof-
  2.4944 +  have ab:"a < b" using assms[unfolded interval_ne_empty] unfolding vector_less_def by auto
  2.4945 +  let ?c = "(1 / 2) *\<^sub>R (a + b)"
  2.4946 +  { fix x assume as:"x \<in> {a .. b}"
  2.4947 +    def f == "\<lambda>n::nat. x + (inverse (real n + 1)) *\<^sub>R (?c - x)"
  2.4948 +    { fix n assume fn:"f n < b \<longrightarrow> a < f n \<longrightarrow> f n = x" and xc:"x \<noteq> ?c"
  2.4949 +      have *:"0 < inverse (real n + 1)" "inverse (real n + 1) \<le> 1" unfolding inverse_le_1_iff by auto
  2.4950 +      have "(inverse (real n + 1)) *\<^sub>R ((1 / 2) *\<^sub>R (a + b)) + (1 - inverse (real n + 1)) *\<^sub>R x =
  2.4951 +	x + (inverse (real n + 1)) *\<^sub>R (((1 / 2) *\<^sub>R (a + b)) - x)"
  2.4952 +        by (auto simp add: algebra_simps)
  2.4953 +      hence "f n < b" and "a < f n" using open_closed_interval_convex[OF open_interval_midpoint[OF assms] as *] unfolding f_def by auto
  2.4954 +      hence False using fn unfolding f_def using xc by(auto simp add: vector_mul_lcancel vector_ssub_ldistrib)  }
  2.4955 +    moreover
  2.4956 +    { assume "\<not> (f ---> x) sequentially"
  2.4957 +      { fix e::real assume "e>0"
  2.4958 +	hence "\<exists>N::nat. inverse (real (N + 1)) < e" using real_arch_inv[of e] apply (auto simp add: Suc_pred') apply(rule_tac x="n - 1" in exI) by auto
  2.4959 +	then obtain N::nat where "inverse (real (N + 1)) < e" by auto
  2.4960 +	hence "\<forall>n\<ge>N. inverse (real n + 1) < e" by (auto, metis Suc_le_mono le_SucE less_imp_inverse_less nat_le_real_less order_less_trans real_of_nat_Suc real_of_nat_Suc_gt_zero)
  2.4961 +	hence "\<exists>N::nat. \<forall>n\<ge>N. inverse (real n + 1) < e" by auto  }
  2.4962 +      hence "((\<lambda>n. inverse (real n + 1)) ---> 0) sequentially"
  2.4963 +	unfolding Lim_sequentially by(auto simp add: dist_norm)
  2.4964 +      hence "(f ---> x) sequentially" unfolding f_def
  2.4965 +	using Lim_add[OF Lim_const, of "\<lambda>n::nat. (inverse (real n + 1)) *\<^sub>R ((1 / 2) *\<^sub>R (a + b) - x)" 0 sequentially x]
  2.4966 +	using Lim_vmul[of "\<lambda>n::nat. inverse (real n + 1)" 0 sequentially "((1 / 2) *\<^sub>R (a + b) - x)"] by auto  }
  2.4967 +    ultimately have "x \<in> closure {a<..<b}"
  2.4968 +      using as and open_interval_midpoint[OF assms] unfolding closure_def unfolding islimpt_sequential by(cases "x=?c")auto  }
  2.4969 +  thus ?thesis using closure_minimal[OF interval_open_subset_closed closed_interval, of a b] by blast
  2.4970 +qed
  2.4971 +
  2.4972 +lemma bounded_subset_open_interval_symmetric: fixes s::"(real^'n::finite) set"
  2.4973 +  assumes "bounded s"  shows "\<exists>a. s \<subseteq> {-a<..<a}"
  2.4974 +proof-
  2.4975 +  obtain b where "b>0" and b:"\<forall>x\<in>s. norm x \<le> b" using assms[unfolded bounded_pos] by auto
  2.4976 +  def a \<equiv> "(\<chi> i. b+1)::real^'n"
  2.4977 +  { fix x assume "x\<in>s"
  2.4978 +    fix i
  2.4979 +    have "(-a)$i < x$i" and "x$i < a$i" using b[THEN bspec[where x=x], OF `x\<in>s`] and component_le_norm[of x i]
  2.4980 +      unfolding vector_uminus_component and a_def and Cart_lambda_beta by auto
  2.4981 +  }
  2.4982 +  thus ?thesis by(auto intro: exI[where x=a] simp add: vector_less_def)
  2.4983 +qed
  2.4984 +
  2.4985 +lemma bounded_subset_open_interval:
  2.4986 +  fixes s :: "(real ^ 'n::finite) set"
  2.4987 +  shows "bounded s ==> (\<exists>a b. s \<subseteq> {a<..<b})"
  2.4988 +  by (auto dest!: bounded_subset_open_interval_symmetric)
  2.4989 +
  2.4990 +lemma bounded_subset_closed_interval_symmetric:
  2.4991 +  fixes s :: "(real ^ 'n::finite) set"
  2.4992 +  assumes "bounded s" shows "\<exists>a. s \<subseteq> {-a .. a}"
  2.4993 +proof-
  2.4994 +  obtain a where "s \<subseteq> {- a<..<a}" using bounded_subset_open_interval_symmetric[OF assms] by auto
  2.4995 +  thus ?thesis using interval_open_subset_closed[of "-a" a] by auto
  2.4996 +qed
  2.4997 +
  2.4998 +lemma bounded_subset_closed_interval:
  2.4999 +  fixes s :: "(real ^ 'n::finite) set"
  2.5000 +  shows "bounded s ==> (\<exists>a b. s \<subseteq> {a .. b})"
  2.5001 +  using bounded_subset_closed_interval_symmetric[of s] by auto
  2.5002 +
  2.5003 +lemma frontier_closed_interval:
  2.5004 +  fixes a b :: "real ^ _"
  2.5005 +  shows "frontier {a .. b} = {a .. b} - {a<..<b}"
  2.5006 +  unfolding frontier_def unfolding interior_closed_interval and closure_closed[OF closed_interval] ..
  2.5007 +
  2.5008 +lemma frontier_open_interval:
  2.5009 +  fixes a b :: "real ^ _"
  2.5010 +  shows "frontier {a<..<b} = (if {a<..<b} = {} then {} else {a .. b} - {a<..<b})"
  2.5011 +proof(cases "{a<..<b} = {}")
  2.5012 +  case True thus ?thesis using frontier_empty by auto
  2.5013 +next
  2.5014 +  case False thus ?thesis unfolding frontier_def and closure_open_interval[OF False] and interior_open[OF open_interval] by auto
  2.5015 +qed
  2.5016 +
  2.5017 +lemma inter_interval_mixed_eq_empty: fixes a :: "real^'n::finite"
  2.5018 +  assumes "{c<..<d} \<noteq> {}"  shows "{a<..<b} \<inter> {c .. d} = {} \<longleftrightarrow> {a<..<b} \<inter> {c<..<d} = {}"
  2.5019 +  unfolding closure_open_interval[OF assms, THEN sym] unfolding open_inter_closure_eq_empty[OF open_interval] ..
  2.5020 +
  2.5021 +
  2.5022 +(* Some special cases for intervals in R^1.                                  *)
  2.5023 +
  2.5024 +lemma all_1: "(\<forall>x::1. P x) \<longleftrightarrow> P 1"
  2.5025 +  by (metis num1_eq_iff)
  2.5026 +
  2.5027 +lemma ex_1: "(\<exists>x::1. P x) \<longleftrightarrow> P 1"
  2.5028 +  by auto (metis num1_eq_iff)
  2.5029 +
  2.5030 +lemma interval_cases_1: fixes x :: "real^1" shows
  2.5031 + "x \<in> {a .. b} ==> x \<in> {a<..<b} \<or> (x = a) \<or> (x = b)"
  2.5032 +  by(simp add:  Cart_eq vector_less_def vector_less_eq_def all_1, auto)
  2.5033 +
  2.5034 +lemma in_interval_1: fixes x :: "real^1" shows
  2.5035 + "(x \<in> {a .. b} \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 x \<and> dest_vec1 x \<le> dest_vec1 b) \<and>
  2.5036 +  (x \<in> {a<..<b} \<longleftrightarrow> dest_vec1 a < dest_vec1 x \<and> dest_vec1 x < dest_vec1 b)"
  2.5037 +by(simp add: Cart_eq vector_less_def vector_less_eq_def all_1 dest_vec1_def)
  2.5038 +
  2.5039 +lemma interval_eq_empty_1: fixes a :: "real^1" shows
  2.5040 +  "{a .. b} = {} \<longleftrightarrow> dest_vec1 b < dest_vec1 a"
  2.5041 +  "{a<..<b} = {} \<longleftrightarrow> dest_vec1 b \<le> dest_vec1 a"
  2.5042 +  unfolding interval_eq_empty and ex_1 and dest_vec1_def by auto
  2.5043 +
  2.5044 +lemma subset_interval_1: fixes a :: "real^1" shows
  2.5045 + "({a .. b} \<subseteq> {c .. d} \<longleftrightarrow>  dest_vec1 b < dest_vec1 a \<or>
  2.5046 +                dest_vec1 c \<le> dest_vec1 a \<and> dest_vec1 a \<le> dest_vec1 b \<and> dest_vec1 b \<le> dest_vec1 d)"
  2.5047 + "({a .. b} \<subseteq> {c<..<d} \<longleftrightarrow>  dest_vec1 b < dest_vec1 a \<or>
  2.5048 +                dest_vec1 c < dest_vec1 a \<and> dest_vec1 a \<le> dest_vec1 b \<and> dest_vec1 b < dest_vec1 d)"
  2.5049 + "({a<..<b} \<subseteq> {c .. d} \<longleftrightarrow>  dest_vec1 b \<le> dest_vec1 a \<or>
  2.5050 +                dest_vec1 c \<le> dest_vec1 a \<and> dest_vec1 a < dest_vec1 b \<and> dest_vec1 b \<le> dest_vec1 d)"
  2.5051 + "({a<..<b} \<subseteq> {c<..<d} \<longleftrightarrow> dest_vec1 b \<le> dest_vec1 a \<or>
  2.5052 +                dest_vec1 c \<le> dest_vec1 a \<and> dest_vec1 a < dest_vec1 b \<and> dest_vec1 b \<le> dest_vec1 d)"
  2.5053 +  unfolding subset_interval[of a b c d] unfolding all_1 and dest_vec1_def by auto
  2.5054 +
  2.5055 +lemma eq_interval_1: fixes a :: "real^1" shows
  2.5056 + "{a .. b} = {c .. d} \<longleftrightarrow>
  2.5057 +          dest_vec1 b < dest_vec1 a \<and> dest_vec1 d < dest_vec1 c \<or>
  2.5058 +          dest_vec1 a = dest_vec1 c \<and> dest_vec1 b = dest_vec1 d"
  2.5059 +using set_eq_subset[of "{a .. b}" "{c .. d}"]
  2.5060 +using subset_interval_1(1)[of a b c d]
  2.5061 +using subset_interval_1(1)[of c d a b]
  2.5062 +by auto (* FIXME: slow *)
  2.5063 +
  2.5064 +lemma disjoint_interval_1: fixes a :: "real^1" shows
  2.5065 +  "{a .. b} \<inter> {c .. d} = {} \<longleftrightarrow> dest_vec1 b < dest_vec1 a \<or> dest_vec1 d < dest_vec1 c  \<or>  dest_vec1 b < dest_vec1 c \<or> dest_vec1 d < dest_vec1 a"
  2.5066 +  "{a .. b} \<inter> {c<..<d} = {} \<longleftrightarrow> dest_vec1 b < dest_vec1 a \<or> dest_vec1 d \<le> dest_vec1 c  \<or>  dest_vec1 b \<le> dest_vec1 c \<or> dest_vec1 d \<le> dest_vec1 a"
  2.5067 +  "{a<..<b} \<inter> {c .. d} = {} \<longleftrightarrow> dest_vec1 b \<le> dest_vec1 a \<or> dest_vec1 d < dest_vec1 c  \<or>  dest_vec1 b \<le> dest_vec1 c \<or> dest_vec1 d \<le> dest_vec1 a"
  2.5068 +  "{a<..<b} \<inter> {c<..<d} = {} \<longleftrightarrow> dest_vec1 b \<le> dest_vec1 a \<or> dest_vec1 d \<le> dest_vec1 c  \<or>  dest_vec1 b \<le> dest_vec1 c \<or> dest_vec1 d \<le> dest_vec1 a"
  2.5069 +  unfolding disjoint_interval and dest_vec1_def ex_1 by auto
  2.5070 +
  2.5071 +lemma open_closed_interval_1: fixes a :: "real^1" shows
  2.5072 + "{a<..<b} = {a .. b} - {a, b}"
  2.5073 +  unfolding expand_set_eq apply simp unfolding vector_less_def and vector_less_eq_def and all_1 and dest_vec1_eq[THEN sym] and dest_vec1_def by auto
  2.5074 +
  2.5075 +lemma closed_open_interval_1: "dest_vec1 (a::real^1) \<le> dest_vec1 b ==> {a .. b} = {a<..<b} \<union> {a,b}"
  2.5076 +  unfolding expand_set_eq apply simp unfolding vector_less_def and vector_less_eq_def and all_1 and dest_vec1_eq[THEN sym] and dest_vec1_def by auto
  2.5077 +
  2.5078 +(* Some stuff for half-infinite intervals too; FIXME: notation?  *)
  2.5079 +
  2.5080 +lemma closed_interval_left: fixes b::"real^'n::finite"
  2.5081 +  shows "closed {x::real^'n. \<forall>i. x$i \<le> b$i}"
  2.5082 +proof-
  2.5083 +  { fix i
  2.5084 +    fix x::"real^'n" assume x:"\<forall>e>0. \<exists>x'\<in>{x. \<forall>i. x $ i \<le> b $ i}. x' \<noteq> x \<and> dist x' x < e"
  2.5085 +    { assume "x$i > b$i"
  2.5086 +      then obtain y where "y $ i \<le> b $ i"  "y \<noteq> x"  "dist y x < x$i - b$i" using x[THEN spec[where x="x$i - b$i"]] by auto
  2.5087 +      hence False using component_le_norm[of "y - x" i] unfolding dist_norm and vector_minus_component by auto   }
  2.5088 +    hence "x$i \<le> b$i" by(rule ccontr)auto  }
  2.5089 +  thus ?thesis unfolding closed_limpt unfolding islimpt_approachable by blast
  2.5090 +qed
  2.5091 +
  2.5092 +lemma closed_interval_right: fixes a::"real^'n::finite"
  2.5093 +  shows "closed {x::real^'n. \<forall>i. a$i \<le> x$i}"
  2.5094 +proof-
  2.5095 +  { fix i
  2.5096 +    fix x::"real^'n" assume x:"\<forall>e>0. \<exists>x'\<in>{x. \<forall>i. a $ i \<le> x $ i}. x' \<noteq> x \<and> dist x' x < e"
  2.5097 +    { assume "a$i > x$i"
  2.5098 +      then obtain y where "a $ i \<le> y $ i"  "y \<noteq> x"  "dist y x < a$i - x$i" using x[THEN spec[where x="a$i - x$i"]] by auto
  2.5099 +      hence False using component_le_norm[of "y - x" i] unfolding dist_norm and vector_minus_component by auto   }
  2.5100 +    hence "a$i \<le> x$i" by(rule ccontr)auto  }
  2.5101 +  thus ?thesis unfolding closed_limpt unfolding islimpt_approachable by blast
  2.5102 +qed
  2.5103 +
  2.5104 +subsection{* Intervals in general, including infinite and mixtures of open and closed. *}
  2.5105 +
  2.5106 +definition "is_interval s \<longleftrightarrow> (\<forall>a\<in>s. \<forall>b\<in>s. \<forall>x. (\<forall>i. ((a$i \<le> x$i \<and> x$i \<le> b$i) \<or> (b$i \<le> x$i \<and> x$i \<le> a$i)))  \<longrightarrow> x \<in> s)"
  2.5107 +
  2.5108 +lemma is_interval_interval: "is_interval {a .. b::real^'n::finite}" (is ?th1) "is_interval {a<..<b}" (is ?th2) proof - 
  2.5109 +  have *:"\<And>x y z::real. x < y \<Longrightarrow> y < z \<Longrightarrow> x < z" by auto
  2.5110 +  show ?th1 ?th2  unfolding is_interval_def mem_interval Ball_def atLeastAtMost_iff
  2.5111 +    by(meson real_le_trans le_less_trans less_le_trans *)+ qed
  2.5112 +
  2.5113 +lemma is_interval_empty:
  2.5114 + "is_interval {}"
  2.5115 +  unfolding is_interval_def
  2.5116 +  by simp
  2.5117 +
  2.5118 +lemma is_interval_univ:
  2.5119 + "is_interval UNIV"
  2.5120 +  unfolding is_interval_def
  2.5121 +  by simp
  2.5122 +
  2.5123 +subsection{* Closure of halfspaces and hyperplanes.                                    *}
  2.5124 +
  2.5125 +lemma Lim_inner:
  2.5126 +  assumes "(f ---> l) net"  shows "((\<lambda>y. inner a (f y)) ---> inner a l) net"
  2.5127 +  by (intro tendsto_intros assms)
  2.5128 +
  2.5129 +lemma continuous_at_inner: "continuous (at x) (inner a)"
  2.5130 +  unfolding continuous_at by (intro tendsto_intros)
  2.5131 +
  2.5132 +lemma continuous_on_inner:
  2.5133 +  fixes s :: "'a::real_inner set"
  2.5134 +  shows "continuous_on s (inner a)"
  2.5135 +  unfolding continuous_on by (rule ballI) (intro tendsto_intros)
  2.5136 +
  2.5137 +lemma closed_halfspace_le: "closed {x. inner a x \<le> b}"
  2.5138 +proof-
  2.5139 +  have "\<forall>x. continuous (at x) (inner a)"
  2.5140 +    unfolding continuous_at by (rule allI) (intro tendsto_intros)
  2.5141 +  hence "closed (inner a -` {..b})"
  2.5142 +    using closed_real_atMost by (rule continuous_closed_vimage)
  2.5143 +  moreover have "{x. inner a x \<le> b} = inner a -` {..b}" by auto
  2.5144 +  ultimately show ?thesis by simp
  2.5145 +qed
  2.5146 +
  2.5147 +lemma closed_halfspace_ge: "closed {x. inner a x \<ge> b}"
  2.5148 +  using closed_halfspace_le[of "-a" "-b"] unfolding inner_minus_left by auto
  2.5149 +
  2.5150 +lemma closed_hyperplane: "closed {x. inner a x = b}"
  2.5151 +proof-
  2.5152 +  have "{x. inner a x = b} = {x. inner a x \<ge> b} \<inter> {x. inner a x \<le> b}" by auto
  2.5153 +  thus ?thesis using closed_halfspace_le[of a b] and closed_halfspace_ge[of b a] using closed_Int by auto
  2.5154 +qed
  2.5155 +
  2.5156 +lemma closed_halfspace_component_le:
  2.5157 +  shows "closed {x::real^'n::finite. x$i \<le> a}"
  2.5158 +  using closed_halfspace_le[of "(basis i)::real^'n" a] unfolding inner_basis[OF assms] by auto
  2.5159 +
  2.5160 +lemma closed_halfspace_component_ge:
  2.5161 +  shows "closed {x::real^'n::finite. x$i \<ge> a}"
  2.5162 +  using closed_halfspace_ge[of a "(basis i)::real^'n"] unfolding inner_basis[OF assms] by auto
  2.5163 +
  2.5164 +text{* Openness of halfspaces.                                                   *}
  2.5165 +
  2.5166 +lemma open_halfspace_lt: "open {x. inner a x < b}"
  2.5167 +proof-
  2.5168 +  have "UNIV - {x. b \<le> inner a x} = {x. inner a x < b}" by auto
  2.5169 +  thus ?thesis using closed_halfspace_ge[unfolded closed_def Compl_eq_Diff_UNIV, of b a] by auto
  2.5170 +qed
  2.5171 +
  2.5172 +lemma open_halfspace_gt: "open {x. inner a x > b}"
  2.5173 +proof-
  2.5174 +  have "UNIV - {x. b \<ge> inner a x} = {x. inner a x > b}" by auto
  2.5175 +  thus ?thesis using closed_halfspace_le[unfolded closed_def Compl_eq_Diff_UNIV, of a b] by auto
  2.5176 +qed
  2.5177 +
  2.5178 +lemma open_halfspace_component_lt:
  2.5179 +  shows "open {x::real^'n::finite. x$i < a}"
  2.5180 +  using open_halfspace_lt[of "(basis i)::real^'n" a] unfolding inner_basis[OF assms] by auto
  2.5181 +
  2.5182 +lemma open_halfspace_component_gt:
  2.5183 +  shows "open {x::real^'n::finite. x$i  > a}"
  2.5184 +  using open_halfspace_gt[of a "(basis i)::real^'n"] unfolding inner_basis[OF assms] by auto
  2.5185 +
  2.5186 +text{* This gives a simple derivation of limit component bounds.                 *}
  2.5187 +
  2.5188 +lemma Lim_component_le: fixes f :: "'a \<Rightarrow> real^'n::finite"
  2.5189 +  assumes "(f ---> l) net" "\<not> (trivial_limit net)"  "eventually (\<lambda>x. f(x)$i \<le> b) net"
  2.5190 +  shows "l$i \<le> b"
  2.5191 +proof-
  2.5192 +  { fix x have "x \<in> {x::real^'n. inner (basis i) x \<le> b} \<longleftrightarrow> x$i \<le> b" unfolding inner_basis by auto } note * = this
  2.5193 +  show ?thesis using Lim_in_closed_set[of "{x. inner (basis i) x \<le> b}" f net l] unfolding *
  2.5194 +    using closed_halfspace_le[of "(basis i)::real^'n" b] and assms(1,2,3) by auto
  2.5195 +qed
  2.5196 +
  2.5197 +lemma Lim_component_ge: fixes f :: "'a \<Rightarrow> real^'n::finite"
  2.5198 +  assumes "(f ---> l) net"  "\<not> (trivial_limit net)"  "eventually (\<lambda>x. b \<le> (f x)$i) net"
  2.5199 +  shows "b \<le> l$i"
  2.5200 +proof-
  2.5201 +  { fix x have "x \<in> {x::real^'n. inner (basis i) x \<ge> b} \<longleftrightarrow> x$i \<ge> b" unfolding inner_basis by auto } note * = this
  2.5202 +  show ?thesis using Lim_in_closed_set[of "{x. inner (basis i) x \<ge> b}" f net l] unfolding *
  2.5203 +    using closed_halfspace_ge[of b "(basis i)::real^'n"] and assms(1,2,3) by auto
  2.5204 +qed
  2.5205 +
  2.5206 +lemma Lim_component_eq: fixes f :: "'a \<Rightarrow> real^'n::finite"
  2.5207 +  assumes net:"(f ---> l) net" "~(trivial_limit net)" and ev:"eventually (\<lambda>x. f(x)$i = b) net"
  2.5208 +  shows "l$i = b"
  2.5209 +  using ev[unfolded order_eq_iff eventually_and] using Lim_component_ge[OF net, of b i] and Lim_component_le[OF net, of i b] by auto
  2.5210 +
  2.5211 +lemma Lim_drop_le: fixes f :: "'a \<Rightarrow> real^1" shows
  2.5212 +  "(f ---> l) net \<Longrightarrow> ~(trivial_limit net) \<Longrightarrow> eventually (\<lambda>x. dest_vec1 (f x) \<le> b) net ==> dest_vec1 l \<le> b"
  2.5213 +  using Lim_component_le[of f l net 1 b] unfolding dest_vec1_def by auto
  2.5214 +
  2.5215 +lemma Lim_drop_ge: fixes f :: "'a \<Rightarrow> real^1" shows
  2.5216 + "(f ---> l) net \<Longrightarrow> ~(trivial_limit net) \<Longrightarrow> eventually (\<lambda>x. b \<le> dest_vec1 (f x)) net ==> b \<le> dest_vec1 l"
  2.5217 +  using Lim_component_ge[of f l net b 1] unfolding dest_vec1_def by auto
  2.5218 +
  2.5219 +text{* Limits relative to a union.                                               *}
  2.5220 +
  2.5221 +lemma eventually_within_Un:
  2.5222 +  "eventually P (net within (s \<union> t)) \<longleftrightarrow>
  2.5223 +    eventually P (net within s) \<and> eventually P (net within t)"
  2.5224 +  unfolding Limits.eventually_within
  2.5225 +  by (auto elim!: eventually_rev_mp)
  2.5226 +
  2.5227 +lemma Lim_within_union:
  2.5228 + "(f ---> l) (net within (s \<union> t)) \<longleftrightarrow>
  2.5229 +  (f ---> l) (net within s) \<and> (f ---> l) (net within t)"
  2.5230 +  unfolding tendsto_def
  2.5231 +  by (auto simp add: eventually_within_Un)
  2.5232 +
  2.5233 +lemma continuous_on_union:
  2.5234 +  assumes "closed s" "closed t" "continuous_on s f" "continuous_on t f"
  2.5235 +  shows "continuous_on (s \<union> t) f"
  2.5236 +  using assms unfolding continuous_on unfolding Lim_within_union
  2.5237 +  unfolding Lim unfolding trivial_limit_within unfolding closed_limpt by auto
  2.5238 +
  2.5239 +lemma continuous_on_cases:
  2.5240 +  assumes "closed s" "closed t" "continuous_on s f" "continuous_on t g"
  2.5241 +          "\<forall>x. (x\<in>s \<and> \<not> P x) \<or> (x \<in> t \<and> P x) \<longrightarrow> f x = g x"
  2.5242 +  shows "continuous_on (s \<union> t) (\<lambda>x. if P x then f x else g x)"
  2.5243 +proof-
  2.5244 +  let ?h = "(\<lambda>x. if P x then f x else g x)"
  2.5245 +  have "\<forall>x\<in>s. f x = (if P x then f x else g x)" using assms(5) by auto
  2.5246 +  hence "continuous_on s ?h" using continuous_on_eq[of s f ?h] using assms(3) by auto
  2.5247 +  moreover
  2.5248 +  have "\<forall>x\<in>t. g x = (if P x then f x else g x)" using assms(5) by auto
  2.5249 +  hence "continuous_on t ?h" using continuous_on_eq[of t g ?h] using assms(4) by auto
  2.5250 +  ultimately show ?thesis using continuous_on_union[OF assms(1,2), of ?h] by auto
  2.5251 +qed
  2.5252 +
  2.5253 +
  2.5254 +text{* Some more convenient intermediate-value theorem formulations.             *}
  2.5255 +
  2.5256 +lemma connected_ivt_hyperplane:
  2.5257 +  assumes "connected s" "x \<in> s" "y \<in> s" "inner a x \<le> b" "b \<le> inner a y"
  2.5258 +  shows "\<exists>z \<in> s. inner a z = b"
  2.5259 +proof(rule ccontr)
  2.5260 +  assume as:"\<not> (\<exists>z\<in>s. inner a z = b)"
  2.5261 +  let ?A = "{x. inner a x < b}"
  2.5262 +  let ?B = "{x. inner a x > b}"
  2.5263 +  have "open ?A" "open ?B" using open_halfspace_lt and open_halfspace_gt by auto
  2.5264 +  moreover have "?A \<inter> ?B = {}" by auto
  2.5265 +  moreover have "s \<subseteq> ?A \<union> ?B" using as by auto
  2.5266 +  ultimately show False using assms(1)[unfolded connected_def not_ex, THEN spec[where x="?A"], THEN spec[where x="?B"]] and assms(2-5) by auto
  2.5267 +qed
  2.5268 +
  2.5269 +lemma connected_ivt_component: fixes x::"real^'n::finite" shows
  2.5270 + "connected s \<Longrightarrow> x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> x$k \<le> a \<Longrightarrow> a \<le> y$k \<Longrightarrow> (\<exists>z\<in>s.  z$k = a)"
  2.5271 +  using connected_ivt_hyperplane[of s x y "(basis k)::real^'n" a] by (auto simp add: inner_basis)
  2.5272 +
  2.5273 +text{* Also more convenient formulations of monotone convergence.                *}
  2.5274 +
  2.5275 +lemma bounded_increasing_convergent: fixes s::"nat \<Rightarrow> real^1"
  2.5276 +  assumes "bounded {s n| n::nat. True}"  "\<forall>n. dest_vec1(s n) \<le> dest_vec1(s(Suc n))"
  2.5277 +  shows "\<exists>l. (s ---> l) sequentially"
  2.5278 +proof-
  2.5279 +  obtain a where a:"\<forall>n. \<bar>dest_vec1 (s n)\<bar> \<le>  a" using assms(1)[unfolded bounded_iff abs_dest_vec1] by auto
  2.5280 +  { fix m::nat
  2.5281 +    have "\<And> n. n\<ge>m \<longrightarrow> dest_vec1 (s m) \<le> dest_vec1 (s n)"
  2.5282 +      apply(induct_tac n) apply simp using assms(2) apply(erule_tac x="na" in allE) by(auto simp add: not_less_eq_eq)  }
  2.5283 +  hence "\<forall>m n. m \<le> n \<longrightarrow> dest_vec1 (s m) \<le> dest_vec1 (s n)" by auto
  2.5284 +  then obtain l where "\<forall>e>0. \<exists>N. \<forall>n\<ge>N. \<bar>dest_vec1 (s n) - l\<bar> < e" using convergent_bounded_monotone[OF a] unfolding monoseq_def by auto
  2.5285 +  thus ?thesis unfolding Lim_sequentially apply(rule_tac x="vec1 l" in exI)
  2.5286 +    unfolding dist_norm unfolding abs_dest_vec1 and dest_vec1_sub by auto
  2.5287 +qed
  2.5288 +
  2.5289 +subsection{* Basic homeomorphism definitions.                                          *}
  2.5290 +
  2.5291 +definition "homeomorphism s t f g \<equiv>
  2.5292 +     (\<forall>x\<in>s. (g(f x) = x)) \<and> (f ` s = t) \<and> continuous_on s f \<and>
  2.5293 +     (\<forall>y\<in>t. (f(g y) = y)) \<and> (g ` t = s) \<and> continuous_on t g"
  2.5294 +
  2.5295 +definition
  2.5296 +  homeomorphic :: "'a::metric_space set \<Rightarrow> 'b::metric_space set \<Rightarrow> bool"
  2.5297 +    (infixr "homeomorphic" 60) where
  2.5298 +  homeomorphic_def: "s homeomorphic t \<equiv> (\<exists>f g. homeomorphism s t f g)"
  2.5299 +
  2.5300 +lemma homeomorphic_refl: "s homeomorphic s"
  2.5301 +  unfolding homeomorphic_def
  2.5302 +  unfolding homeomorphism_def
  2.5303 +  using continuous_on_id
  2.5304 +  apply(rule_tac x = "(\<lambda>x. x)" in exI)
  2.5305 +  apply(rule_tac x = "(\<lambda>x. x)" in exI)
  2.5306 +  by blast
  2.5307 +
  2.5308 +lemma homeomorphic_sym:
  2.5309 + "s homeomorphic t \<longleftrightarrow> t homeomorphic s"
  2.5310 +unfolding homeomorphic_def
  2.5311 +unfolding homeomorphism_def
  2.5312 +by blast (* FIXME: slow *)
  2.5313 +
  2.5314 +lemma homeomorphic_trans:
  2.5315 +  assumes "s homeomorphic t" "t homeomorphic u" shows "s homeomorphic u"
  2.5316 +proof-
  2.5317 +  obtain f1 g1 where fg1:"\<forall>x\<in>s. g1 (f1 x) = x"  "f1 ` s = t" "continuous_on s f1" "\<forall>y\<in>t. f1 (g1 y) = y" "g1 ` t = s" "continuous_on t g1"
  2.5318 +    using assms(1) unfolding homeomorphic_def homeomorphism_def by auto
  2.5319 +  obtain f2 g2 where fg2:"\<forall>x\<in>t. g2 (f2 x) = x"  "f2 ` t = u" "continuous_on t f2" "\<forall>y\<in>u. f2 (g2 y) = y" "g2 ` u = t" "continuous_on u g2"
  2.5320 +    using assms(2) unfolding homeomorphic_def homeomorphism_def by auto
  2.5321 +
  2.5322 +  { fix x assume "x\<in>s" hence "(g1 \<circ> g2) ((f2 \<circ> f1) x) = x" using fg1(1)[THEN bspec[where x=x]] and fg2(1)[THEN bspec[where x="f1 x"]] and fg1(2) by auto }
  2.5323 +  moreover have "(f2 \<circ> f1) ` s = u" using fg1(2) fg2(2) by auto
  2.5324 +  moreover have "continuous_on s (f2 \<circ> f1)" using continuous_on_compose[OF fg1(3)] and fg2(3) unfolding fg1(2) by auto
  2.5325 +  moreover { fix y assume "y\<in>u" hence "(f2 \<circ> f1) ((g1 \<circ> g2) y) = y" using fg2(4)[THEN bspec[where x=y]] and fg1(4)[THEN bspec[where x="g2 y"]] and fg2(5) by auto }
  2.5326 +  moreover have "(g1 \<circ> g2) ` u = s" using fg1(5) fg2(5) by auto
  2.5327 +  moreover have "continuous_on u (g1 \<circ> g2)" using continuous_on_compose[OF fg2(6)] and fg1(6)  unfolding fg2(5) by auto
  2.5328 +  ultimately show ?thesis unfolding homeomorphic_def homeomorphism_def apply(rule_tac x="f2 \<circ> f1" in exI) apply(rule_tac x="g1 \<circ> g2" in exI) by auto
  2.5329 +qed
  2.5330 +
  2.5331 +lemma homeomorphic_minimal:
  2.5332 + "s homeomorphic t \<longleftrightarrow>
  2.5333 +    (\<exists>f g. (\<forall>x\<in>s. f(x) \<in> t \<and> (g(f(x)) = x)) \<and>
  2.5334 +           (\<forall>y\<in>t. g(y) \<in> s \<and> (f(g(y)) = y)) \<and>
  2.5335 +           continuous_on s f \<and> continuous_on t g)"
  2.5336 +unfolding homeomorphic_def homeomorphism_def
  2.5337 +apply auto apply (rule_tac x=f in exI) apply (rule_tac x=g in exI)
  2.5338 +apply auto apply (rule_tac x=f in exI) apply (rule_tac x=g in exI) apply auto
  2.5339 +unfolding image_iff
  2.5340 +apply(erule_tac x="g x" in ballE) apply(erule_tac x="x" in ballE)
  2.5341 +apply auto apply(rule_tac x="g x" in bexI) apply auto
  2.5342 +apply(erule_tac x="f x" in ballE) apply(erule_tac x="x" in ballE)
  2.5343 +apply auto apply(rule_tac x="f x" in bexI) by auto
  2.5344 +
  2.5345 +subsection{* Relatively weak hypotheses if a set is compact.                           *}
  2.5346 +
  2.5347 +definition "inv_on f s = (\<lambda>x. SOME y. y\<in>s \<and> f y = x)"
  2.5348 +
  2.5349 +lemma assumes "inj_on f s" "x\<in>s"
  2.5350 +  shows "inv_on f s (f x) = x"
  2.5351 + using assms unfolding inj_on_def inv_on_def by auto
  2.5352 +
  2.5353 +lemma homeomorphism_compact:
  2.5354 +  fixes f :: "'a::heine_borel \<Rightarrow> 'b::heine_borel"
  2.5355 +    (* class constraint due to continuous_on_inverse *)
  2.5356 +  assumes "compact s" "continuous_on s f"  "f ` s = t"  "inj_on f s"
  2.5357 +  shows "\<exists>g. homeomorphism s t f g"
  2.5358 +proof-
  2.5359 +  def g \<equiv> "\<lambda>x. SOME y. y\<in>s \<and> f y = x"
  2.5360 +  have g:"\<forall>x\<in>s. g (f x) = x" using assms(3) assms(4)[unfolded inj_on_def] unfolding g_def by auto
  2.5361 +  { fix y assume "y\<in>t"
  2.5362 +    then obtain x where x:"f x = y" "x\<in>s" using assms(3) by auto
  2.5363 +    hence "g (f x) = x" using g by auto
  2.5364 +    hence "f (g y) = y" unfolding x(1)[THEN sym] by auto  }
  2.5365 +  hence g':"\<forall>x\<in>t. f (g x) = x" by auto
  2.5366 +  moreover
  2.5367 +  { fix x
  2.5368 +    have "x\<in>s \<Longrightarrow> x \<in> g ` t" using g[THEN bspec[where x=x]] unfolding image_iff using assms(3) by(auto intro!: bexI[where x="f x"])
  2.5369 +    moreover
  2.5370 +    { assume "x\<in>g ` t"
  2.5371 +      then obtain y where y:"y\<in>t" "g y = x" by auto
  2.5372 +      then obtain x' where x':"x'\<in>s" "f x' = y" using assms(3) by auto
  2.5373 +      hence "x \<in> s" unfolding g_def using someI2[of "\<lambda>b. b\<in>s \<and> f b = y" x' "\<lambda>x. x\<in>s"] unfolding y(2)[THEN sym] and g_def by auto }
  2.5374 +    ultimately have "x\<in>s \<longleftrightarrow> x \<in> g ` t" by auto  }
  2.5375 +  hence "g ` t = s" by auto
  2.5376 +  ultimately
  2.5377 +  show ?thesis unfolding homeomorphism_def homeomorphic_def
  2.5378 +    apply(rule_tac x=g in exI) using g and assms(3) and continuous_on_inverse[OF assms(2,1), of g, unfolded assms(3)] and assms(2) by auto
  2.5379 +qed
  2.5380 +
  2.5381 +lemma homeomorphic_compact:
  2.5382 +  fixes f :: "'a::heine_borel \<Rightarrow> 'b::heine_borel"
  2.5383 +    (* class constraint due to continuous_on_inverse *)
  2.5384 +  shows "compact s \<Longrightarrow> continuous_on s f \<Longrightarrow> (f ` s = t) \<Longrightarrow> inj_on f s
  2.5385 +          \<Longrightarrow> s homeomorphic t"
  2.5386 +  unfolding homeomorphic_def by(metis homeomorphism_compact)
  2.5387 +
  2.5388 +text{* Preservation of topological properties.                                   *}
  2.5389 +
  2.5390 +lemma homeomorphic_compactness:
  2.5391 + "s homeomorphic t ==> (compact s \<longleftrightarrow> compact t)"
  2.5392 +unfolding homeomorphic_def homeomorphism_def
  2.5393 +by (metis compact_continuous_image)
  2.5394 +
  2.5395 +text{* Results on translation, scaling etc.                                      *}
  2.5396 +
  2.5397 +lemma homeomorphic_scaling:
  2.5398 +  fixes s :: "'a::real_normed_vector set"
  2.5399 +  assumes "c \<noteq> 0"  shows "s homeomorphic ((\<lambda>x. c *\<^sub>R x) ` s)"
  2.5400 +  unfolding homeomorphic_minimal
  2.5401 +  apply(rule_tac x="\<lambda>x. c *\<^sub>R x" in exI)
  2.5402 +  apply(rule_tac x="\<lambda>x. (1 / c) *\<^sub>R x" in exI)
  2.5403 +  using assms apply auto
  2.5404 +  using continuous_on_cmul[OF continuous_on_id] by auto
  2.5405 +
  2.5406 +lemma homeomorphic_translation:
  2.5407 +  fixes s :: "'a::real_normed_vector set"
  2.5408 +  shows "s homeomorphic ((\<lambda>x. a + x) ` s)"
  2.5409 +  unfolding homeomorphic_minimal
  2.5410 +  apply(rule_tac x="\<lambda>x. a + x" in exI)
  2.5411 +  apply(rule_tac x="\<lambda>x. -a + x" in exI)
  2.5412 +  using continuous_on_add[OF continuous_on_const continuous_on_id] by auto
  2.5413 +
  2.5414 +lemma homeomorphic_affinity:
  2.5415 +  fixes s :: "'a::real_normed_vector set"
  2.5416 +  assumes "c \<noteq> 0"  shows "s homeomorphic ((\<lambda>x. a + c *\<^sub>R x) ` s)"
  2.5417 +proof-
  2.5418 +  have *:"op + a ` op *\<^sub>R c ` s = (\<lambda>x. a + c *\<^sub>R x) ` s" by auto
  2.5419 +  show ?thesis
  2.5420 +    using homeomorphic_trans
  2.5421 +    using homeomorphic_scaling[OF assms, of s]
  2.5422 +    using homeomorphic_translation[of "(\<lambda>x. c *\<^sub>R x) ` s" a] unfolding * by auto
  2.5423 +qed
  2.5424 +
  2.5425 +lemma homeomorphic_balls:
  2.5426 +  fixes a b ::"'a::real_normed_vector" (* FIXME: generalize to metric_space *)
  2.5427 +  assumes "0 < d"  "0 < e"
  2.5428 +  shows "(ball a d) homeomorphic  (ball b e)" (is ?th)
  2.5429 +        "(cball a d) homeomorphic (cball b e)" (is ?cth)
  2.5430 +proof-
  2.5431 +  have *:"\<bar>e / d\<bar> > 0" "\<bar>d / e\<bar> >0" using assms using divide_pos_pos by auto
  2.5432 +  show ?th unfolding homeomorphic_minimal
  2.5433 +    apply(rule_tac x="\<lambda>x. b + (e/d) *\<^sub>R (x - a)" in exI)
  2.5434 +    apply(rule_tac x="\<lambda>x. a + (d/e) *\<^sub>R (x - b)" in exI)
  2.5435 +    using assms apply (auto simp add: dist_commute)
  2.5436 +    unfolding dist_norm
  2.5437 +    apply (auto simp add: pos_divide_less_eq mult_strict_left_mono)
  2.5438 +    unfolding continuous_on
  2.5439 +    by (intro ballI tendsto_intros, simp, assumption)+
  2.5440 +next
  2.5441 +  have *:"\<bar>e / d\<bar> > 0" "\<bar>d / e\<bar> >0" using assms using divide_pos_pos by auto
  2.5442 +  show ?cth unfolding homeomorphic_minimal
  2.5443 +    apply(rule_tac x="\<lambda>x. b + (e/d) *\<^sub>R (x - a)" in exI)
  2.5444 +    apply(rule_tac x="\<lambda>x. a + (d/e) *\<^sub>R (x - b)" in exI)
  2.5445 +    using assms apply (auto simp add: dist_commute)
  2.5446 +    unfolding dist_norm
  2.5447 +    apply (auto simp add: pos_divide_le_eq)
  2.5448 +    unfolding continuous_on
  2.5449 +    by (intro ballI tendsto_intros, simp, assumption)+
  2.5450 +qed
  2.5451 +
  2.5452 +text{* "Isometry" (up to constant bounds) of injective linear map etc.           *}
  2.5453 +
  2.5454 +lemma cauchy_isometric:
  2.5455 +  fixes x :: "nat \<Rightarrow> real ^ 'n::finite"
  2.5456 +  assumes e:"0 < e" and s:"subspace s" and f:"bounded_linear f" and normf:"\<forall>x\<in>s. norm(f x) \<ge> e * norm(x)" and xs:"\<forall>n::nat. x n \<in> s" and cf:"Cauchy(f o x)"
  2.5457 +  shows "Cauchy x"
  2.5458 +proof-
  2.5459 +  interpret f: bounded_linear f by fact
  2.5460 +  { fix d::real assume "d>0"
  2.5461 +    then obtain N where N:"\<forall>n\<ge>N. norm (f (x n) - f (x N)) < e * d"
  2.5462 +      using cf[unfolded cauchy o_def dist_norm, THEN spec[where x="e*d"]] and e and mult_pos_pos[of e d] by auto
  2.5463 +    { fix n assume "n\<ge>N"
  2.5464 +      hence "norm (f (x n - x N)) < e * d" using N[THEN spec[where x=n]] unfolding f.diff[THEN sym] by auto
  2.5465 +      moreover have "e * norm (x n - x N) \<le> norm (f (x n - x N))"
  2.5466 +	using subspace_sub[OF s, of "x n" "x N"] using xs[THEN spec[where x=N]] and xs[THEN spec[where x=n]]
  2.5467 +	using normf[THEN bspec[where x="x n - x N"]] by auto
  2.5468 +      ultimately have "norm (x n - x N) < d" using `e>0`
  2.5469 +	using mult_left_less_imp_less[of e "norm (x n - x N)" d] by auto   }
  2.5470 +    hence "\<exists>N. \<forall>n\<ge>N. norm (x n - x N) < d" by auto }
  2.5471 +  thus ?thesis unfolding cauchy and dist_norm by auto
  2.5472 +qed
  2.5473 +
  2.5474 +lemma complete_isometric_image:
  2.5475 +  fixes f :: "real ^ _ \<Rightarrow> real ^ _"
  2.5476 +  assumes "0 < e" and s:"subspace s" and f:"bounded_linear f" and normf:"\<forall>x\<in>s. norm(f x) \<ge> e * norm(x)" and cs:"complete s"
  2.5477 +  shows "complete(f ` s)"
  2.5478 +proof-
  2.5479 +  { fix g assume as:"\<forall>n::nat. g n \<in> f ` s" and cfg:"Cauchy g"
  2.5480 +    then obtain x where "\<forall>n. x n \<in> s \<and> g n = f (x n)" unfolding image_iff and Bex_def
  2.5481 +      using choice[of "\<lambda> n xa. xa \<in> s \<and> g n = f xa"] by auto
  2.5482 +    hence x:"\<forall>n. x n \<in> s"  "\<forall>n. g n = f (x n)" by auto
  2.5483 +    hence "f \<circ> x = g" unfolding expand_fun_eq by auto
  2.5484 +    then obtain l where "l\<in>s" and l:"(x ---> l) sequentially"
  2.5485 +      using cs[unfolded complete_def, THEN spec[where x="x"]]
  2.5486 +      using cauchy_isometric[OF `0<e` s f normf] and cfg and x(1) by auto
  2.5487 +    hence "\<exists>l\<in>f ` s. (g ---> l) sequentially"
  2.5488 +      using linear_continuous_at[OF f, unfolded continuous_at_sequentially, THEN spec[where x=x], of l]
  2.5489 +      unfolding `f \<circ> x = g` by auto  }
  2.5490 +  thus ?thesis unfolding complete_def by auto
  2.5491 +qed
  2.5492 +
  2.5493 +lemma dist_0_norm:
  2.5494 +  fixes x :: "'a::real_normed_vector"
  2.5495 +  shows "dist 0 x = norm x"
  2.5496 +unfolding dist_norm by simp
  2.5497 +
  2.5498 +lemma injective_imp_isometric: fixes f::"real^'m::finite \<Rightarrow> real^'n::finite"
  2.5499 +  assumes s:"closed s"  "subspace s"  and f:"bounded_linear f" "\<forall>x\<in>s. (f x = 0) \<longrightarrow> (x = 0)"
  2.5500 +  shows "\<exists>e>0. \<forall>x\<in>s. norm (f x) \<ge> e * norm(x)"
  2.5501 +proof(cases "s \<subseteq> {0::real^'m}")
  2.5502 +  case True
  2.5503 +  { fix x assume "x \<in> s"
  2.5504 +    hence "x = 0" using True by auto
  2.5505 +    hence "norm x \<le> norm (f x)" by auto  }
  2.5506 +  thus ?thesis by(auto intro!: exI[where x=1])
  2.5507 +next
  2.5508 +  interpret f: bounded_linear f by fact
  2.5509 +  case False
  2.5510 +  then obtain a where a:"a\<noteq>0" "a\<in>s" by auto
  2.5511 +  from False have "s \<noteq> {}" by auto
  2.5512 +  let ?S = "{f x| x. (x \<in> s \<and> norm x = norm a)}"
  2.5513 +  let ?S' = "{x::real^'m. x\<in>s \<and> norm x = norm a}"
  2.5514 +  let ?S'' = "{x::real^'m. norm x = norm a}"
  2.5515 +
  2.5516 +  have "?S'' = frontier(cball 0 (norm a))" unfolding frontier_cball and dist_norm by (auto simp add: norm_minus_cancel)
  2.5517 +  hence "compact ?S''" using compact_frontier[OF compact_cball, of 0 "norm a"] by auto
  2.5518 +  moreover have "?S' = s \<inter> ?S''" by auto
  2.5519 +  ultimately have "compact ?S'" using closed_inter_compact[of s ?S''] using s(1) by auto
  2.5520 +  moreover have *:"f ` ?S' = ?S" by auto
  2.5521 +  ultimately have "compact ?S" using compact_continuous_image[OF linear_continuous_on[OF f(1)], of ?S'] by auto
  2.5522 +  hence "closed ?S" using compact_imp_closed by auto
  2.5523 +  moreover have "?S \<noteq> {}" using a by auto
  2.5524 +  ultimately obtain b' where "b'\<in>?S" "\<forall>y\<in>?S. norm b' \<le> norm y" using distance_attains_inf[of ?S 0] unfolding dist_0_norm by auto
  2.5525 +  then obtain b where "b\<in>s" and ba:"norm b = norm a" and b:"\<forall>x\<in>{x \<in> s. norm x = norm a}. norm (f b) \<le> norm (f x)" unfolding *[THEN sym] unfolding image_iff by auto
  2.5526 +
  2.5527 +  let ?e = "norm (f b) / norm b"
  2.5528 +  have "norm b > 0" using ba and a and norm_ge_zero by auto
  2.5529 +  moreover have "norm (f b) > 0" using f(2)[THEN bspec[where x=b], OF `b\<in>s`] using `norm b >0` unfolding zero_less_norm_iff by auto
  2.5530 +  ultimately have "0 < norm (f b) / norm b" by(simp only: divide_pos_pos)
  2.5531 +  moreover
  2.5532 +  { fix x assume "x\<in>s"
  2.5533 +    hence "norm (f b) / norm b * norm x \<le> norm (f x)"
  2.5534 +    proof(cases "x=0")
  2.5535 +      case True thus "norm (f b) / norm b * norm x \<le> norm (f x)" by auto
  2.5536 +    next
  2.5537 +      case False
  2.5538 +      hence *:"0 < norm a / norm x" using `a\<noteq>0` unfolding zero_less_norm_iff[THEN sym] by(simp only: divide_pos_pos)
  2.5539 +      have "\<forall>c. \<forall>x\<in>s. c *\<^sub>R x \<in> s" using s[unfolded subspace_def smult_conv_scaleR] by auto
  2.5540 +      hence "(norm a / norm x) *\<^sub>R x \<in> {x \<in> s. norm x = norm a}" using `x\<in>s` and `x\<noteq>0` by auto
  2.5541 +      thus "norm (f b) / norm b * norm x \<le> norm (f x)" using b[THEN bspec[where x="(norm a / norm x) *\<^sub>R x"]]
  2.5542 +	unfolding f.scaleR and ba using `x\<noteq>0` `a\<noteq>0`
  2.5543 +	by (auto simp add: real_mult_commute pos_le_divide_eq pos_divide_le_eq)
  2.5544 +    qed }
  2.5545 +  ultimately
  2.5546 +  show ?thesis by auto
  2.5547 +qed
  2.5548 +
  2.5549 +lemma closed_injective_image_subspace:
  2.5550 +  fixes f :: "real ^ _ \<Rightarrow> real ^ _"
  2.5551 +  assumes "subspace s" "bounded_linear f" "\<forall>x\<in>s. f x = 0 --> x = 0" "closed s"
  2.5552 +  shows "closed(f ` s)"
  2.5553 +proof-
  2.5554 +  obtain e where "e>0" and e:"\<forall>x\<in>s. e * norm x \<le> norm (f x)" using injective_imp_isometric[OF assms(4,1,2,3)] by auto
  2.5555 +  show ?thesis using complete_isometric_image[OF `e>0` assms(1,2) e] and assms(4)
  2.5556 +    unfolding complete_eq_closed[THEN sym] by auto
  2.5557 +qed
  2.5558 +
  2.5559 +subsection{* Some properties of a canonical subspace.                                  *}
  2.5560 +
  2.5561 +lemma subspace_substandard:
  2.5562 + "subspace {x::real^'n. (\<forall>i. P i \<longrightarrow> x$i = 0)}"
  2.5563 +  unfolding subspace_def by(auto simp add: vector_add_component vector_smult_component elim!: ballE)
  2.5564 +
  2.5565 +lemma closed_substandard:
  2.5566 + "closed {x::real^'n::finite. \<forall>i. P i --> x$i = 0}" (is "closed ?A")
  2.5567 +proof-
  2.5568 +  let ?D = "{i. P i}"
  2.5569 +  let ?Bs = "{{x::real^'n. inner (basis i) x = 0}| i. i \<in> ?D}"
  2.5570 +  { fix x
  2.5571 +    { assume "x\<in>?A"
  2.5572 +      hence x:"\<forall>i\<in>?D. x $ i = 0" by auto
  2.5573 +      hence "x\<in> \<Inter> ?Bs" by(auto simp add: inner_basis x) }
  2.5574 +    moreover
  2.5575 +    { assume x:"x\<in>\<Inter>?Bs"
  2.5576 +      { fix i assume i:"i \<in> ?D"
  2.5577 +	then obtain B where BB:"B \<in> ?Bs" and B:"B = {x::real^'n. inner (basis i) x = 0}" by auto
  2.5578 +	hence "x $ i = 0" unfolding B using x unfolding inner_basis by auto  }
  2.5579 +      hence "x\<in>?A" by auto }
  2.5580 +    ultimately have "x\<in>?A \<longleftrightarrow> x\<in> \<Inter>?Bs" by auto }
  2.5581 +  hence "?A = \<Inter> ?Bs" by auto
  2.5582 +  thus ?thesis by(auto simp add: closed_Inter closed_hyperplane)
  2.5583 +qed
  2.5584 +
  2.5585 +lemma dim_substandard:
  2.5586 +  shows "dim {x::real^'n::finite. \<forall>i. i \<notin> d \<longrightarrow> x$i = 0} = card d" (is "dim ?A = _")
  2.5587 +proof-
  2.5588 +  let ?D = "UNIV::'n set"
  2.5589 +  let ?B = "(basis::'n\<Rightarrow>real^'n) ` d"
  2.5590 +
  2.5591 +    let ?bas = "basis::'n \<Rightarrow> real^'n"
  2.5592 +
  2.5593 +  have "?B \<subseteq> ?A" by auto
  2.5594 +
  2.5595 +  moreover
  2.5596 +  { fix x::"real^'n" assume "x\<in>?A"
  2.5597 +    with finite[of d]
  2.5598 +    have "x\<in> span ?B"
  2.5599 +    proof(induct d arbitrary: x)
  2.5600 +      case empty hence "x=0" unfolding Cart_eq by auto
  2.5601 +      thus ?case using subspace_0[OF subspace_span[of "{}"]] by auto
  2.5602 +    next
  2.5603 +      case (insert k F)
  2.5604 +      hence *:"\<forall>i. i \<notin> insert k F \<longrightarrow> x $ i = 0" by auto
  2.5605 +      have **:"F \<subseteq> insert k F" by auto
  2.5606 +      def y \<equiv> "x - x$k *\<^sub>R basis k"
  2.5607 +      have y:"x = y + (x$k) *\<^sub>R basis k" unfolding y_def by auto
  2.5608 +      { fix i assume i':"i \<notin> F"
  2.5609 +	hence "y $ i = 0" unfolding y_def unfolding vector_minus_component
  2.5610 +	  and vector_smult_component and basis_component
  2.5611 +	  using *[THEN spec[where x=i]] by auto }
  2.5612 +      hence "y \<in> span (basis ` (insert k F))" using insert(3)
  2.5613 +	using span_mono[of "?bas ` F" "?bas ` (insert k F)"]
  2.5614 +	using image_mono[OF **, of basis] by auto
  2.5615 +      moreover
  2.5616 +      have "basis k \<in> span (?bas ` (insert k F))" by(rule span_superset, auto)
  2.5617 +      hence "x$k *\<^sub>R basis k \<in> span (?bas ` (insert k F))"
  2.5618 +        using span_mul [where 'a=real, unfolded smult_conv_scaleR] by auto
  2.5619 +      ultimately
  2.5620 +      have "y + x$k *\<^sub>R basis k \<in> span (?bas ` (insert k F))"
  2.5621 +	using span_add by auto
  2.5622 +      thus ?case using y by auto
  2.5623 +    qed
  2.5624 +  }
  2.5625 +  hence "?A \<subseteq> span ?B" by auto
  2.5626 +
  2.5627 +  moreover
  2.5628 +  { fix x assume "x \<in> ?B"
  2.5629 +    hence "x\<in>{(basis i)::real^'n |i. i \<in> ?D}" using assms by auto  }
  2.5630 +  hence "independent ?B" using independent_mono[OF independent_stdbasis, of ?B] and assms by auto
  2.5631 +
  2.5632 +  moreover
  2.5633 +  have "d \<subseteq> ?D" unfolding subset_eq using assms by auto
  2.5634 +  hence *:"inj_on (basis::'n\<Rightarrow>real^'n) d" using subset_inj_on[OF basis_inj, of "d"] by auto
  2.5635 +  have "?B hassize (card d)" unfolding hassize_def and card_image[OF *] by auto
  2.5636 +
  2.5637 +  ultimately show ?thesis using dim_unique[of "basis ` d" ?A] by auto
  2.5638 +qed
  2.5639 +
  2.5640 +text{* Hence closure and completeness of all subspaces.                          *}
  2.5641 +
  2.5642 +lemma closed_subspace_lemma: "n \<le> card (UNIV::'n::finite set) \<Longrightarrow> \<exists>A::'n set. card A = n"
  2.5643 +apply (induct n)
  2.5644 +apply (rule_tac x="{}" in exI, simp)
  2.5645 +apply clarsimp
  2.5646 +apply (subgoal_tac "\<exists>x. x \<notin> A")
  2.5647 +apply (erule exE)
  2.5648 +apply (rule_tac x="insert x A" in exI, simp)
  2.5649 +apply (subgoal_tac "A \<noteq> UNIV", auto)
  2.5650 +done
  2.5651 +
  2.5652 +lemma closed_subspace: fixes s::"(real^'n::finite) set"
  2.5653 +  assumes "subspace s" shows "closed s"
  2.5654 +proof-
  2.5655 +  have "dim s \<le> card (UNIV :: 'n set)" using dim_subset_univ by auto
  2.5656 +  then obtain d::"'n set" where t: "card d = dim s"
  2.5657 +    using closed_subspace_lemma by auto
  2.5658 +  let ?t = "{x::real^'n. \<forall>i. i \<notin> d \<longrightarrow> x$i = 0}"
  2.5659 +  obtain f where f:"bounded_linear f"  "f ` ?t = s" "inj_on f ?t"
  2.5660 +    using subspace_isomorphism[unfolded linear_conv_bounded_linear, OF subspace_substandard[of "\<lambda>i. i \<notin> d"] assms]
  2.5661 +    using dim_substandard[of d] and t by auto
  2.5662 +  interpret f: bounded_linear f by fact
  2.5663 +  have "\<forall>x\<in>?t. f x = 0 \<longrightarrow> x = 0" using f.zero using f(3)[unfolded inj_on_def]
  2.5664 +    by(erule_tac x=0 in ballE) auto
  2.5665 +  moreover have "closed ?t" using closed_substandard .
  2.5666 +  moreover have "subspace ?t" using subspace_substandard .
  2.5667 +  ultimately show ?thesis using closed_injective_image_subspace[of ?t f]
  2.5668 +    unfolding f(2) using f(1) by auto
  2.5669 +qed
  2.5670 +
  2.5671 +lemma complete_subspace:
  2.5672 +  fixes s :: "(real ^ _) set" shows "subspace s ==> complete s"
  2.5673 +  using complete_eq_closed closed_subspace
  2.5674 +  by auto
  2.5675 +
  2.5676 +lemma dim_closure:
  2.5677 +  fixes s :: "(real ^ _) set"
  2.5678 +  shows "dim(closure s) = dim s" (is "?dc = ?d")
  2.5679 +proof-
  2.5680 +  have "?dc \<le> ?d" using closure_minimal[OF span_inc, of s]
  2.5681 +    using closed_subspace[OF subspace_span, of s]
  2.5682 +    using dim_subset[of "closure s" "span s"] unfolding dim_span by auto
  2.5683 +  thus ?thesis using dim_subset[OF closure_subset, of s] by auto
  2.5684 +qed
  2.5685 +
  2.5686 +text{* Affine transformations of intervals.                                      *}
  2.5687 +
  2.5688 +lemma affinity_inverses:
  2.5689 +  assumes m0: "m \<noteq> (0::'a::field)"
  2.5690 +  shows "(\<lambda>x. m *s x + c) o (\<lambda>x. inverse(m) *s x + (-(inverse(m) *s c))) = id"
  2.5691 +  "(\<lambda>x. inverse(m) *s x + (-(inverse(m) *s c))) o (\<lambda>x. m *s x + c) = id"
  2.5692 +  using m0
  2.5693 +apply (auto simp add: expand_fun_eq vector_add_ldistrib vector_smult_assoc)
  2.5694 +by (simp add: vector_smult_lneg[symmetric] vector_smult_assoc vector_sneg_minus1[symmetric])
  2.5695 +
  2.5696 +lemma real_affinity_le:
  2.5697 + "0 < (m::'a::ordered_field) ==> (m * x + c \<le> y \<longleftrightarrow> x \<le> inverse(m) * y + -(c / m))"
  2.5698 +  by (simp add: field_simps inverse_eq_divide)
  2.5699 +
  2.5700 +lemma real_le_affinity:
  2.5701 + "0 < (m::'a::ordered_field) ==> (y \<le> m * x + c \<longleftrightarrow> inverse(m) * y + -(c / m) \<le> x)"
  2.5702 +  by (simp add: field_simps inverse_eq_divide)
  2.5703 +
  2.5704 +lemma real_affinity_lt:
  2.5705 + "0 < (m::'a::ordered_field) ==> (m * x + c < y \<longleftrightarrow> x < inverse(m) * y + -(c / m))"
  2.5706 +  by (simp add: field_simps inverse_eq_divide)
  2.5707 +
  2.5708 +lemma real_lt_affinity:
  2.5709 + "0 < (m::'a::ordered_field) ==> (y < m * x + c \<longleftrightarrow> inverse(m) * y + -(c / m) < x)"
  2.5710 +  by (simp add: field_simps inverse_eq_divide)
  2.5711 +
  2.5712 +lemma real_affinity_eq:
  2.5713 + "(m::'a::ordered_field) \<noteq> 0 ==> (m * x + c = y \<longleftrightarrow> x = inverse(m) * y + -(c / m))"
  2.5714 +  by (simp add: field_simps inverse_eq_divide)
  2.5715 +
  2.5716 +lemma real_eq_affinity:
  2.5717 + "(m::'a::ordered_field) \<noteq> 0 ==> (y = m * x + c  \<longleftrightarrow> inverse(m) * y + -(c / m) = x)"
  2.5718 +  by (simp add: field_simps inverse_eq_divide)
  2.5719 +
  2.5720 +lemma vector_affinity_eq:
  2.5721 +  assumes m0: "(m::'a::field) \<noteq> 0"
  2.5722 +  shows "m *s x + c = y \<longleftrightarrow> x = inverse m *s y + -(inverse m *s c)"
  2.5723 +proof
  2.5724 +  assume h: "m *s x + c = y"
  2.5725 +  hence "m *s x = y - c" by (simp add: ring_simps)
  2.5726 +  hence "inverse m *s (m *s x) = inverse m *s (y - c)" by simp
  2.5727 +  then show "x = inverse m *s y + - (inverse m *s c)"
  2.5728 +    using m0 by (simp add: vector_smult_assoc vector_ssub_ldistrib)
  2.5729 +next
  2.5730 +  assume h: "x = inverse m *s y + - (inverse m *s c)"
  2.5731 +  show "m *s x + c = y" unfolding h diff_minus[symmetric]
  2.5732 +    using m0 by (simp add: vector_smult_assoc vector_ssub_ldistrib)
  2.5733 +qed
  2.5734 +
  2.5735 +lemma vector_eq_affinity:
  2.5736 + "(m::'a::field) \<noteq> 0 ==> (y = m *s x + c \<longleftrightarrow> inverse(m) *s y + -(inverse(m) *s c) = x)"
  2.5737 +  using vector_affinity_eq[where m=m and x=x and y=y and c=c]
  2.5738 +  by metis
  2.5739 +
  2.5740 +lemma image_affinity_interval: fixes m::real
  2.5741 +  fixes a b c :: "real^'n::finite"
  2.5742 +  shows "(\<lambda>x. m *\<^sub>R x + c) ` {a .. b} =
  2.5743 +            (if {a .. b} = {} then {}
  2.5744 +            else (if 0 \<le> m then {m *\<^sub>R a + c .. m *\<^sub>R b + c}
  2.5745 +            else {m *\<^sub>R b + c .. m *\<^sub>R a + c}))"
  2.5746 +proof(cases "m=0")
  2.5747 +  { fix x assume "x \<le> c" "c \<le> x"
  2.5748 +    hence "x=c" unfolding vector_less_eq_def and Cart_eq by (auto intro: order_antisym) }
  2.5749 +  moreover case True
  2.5750 +  moreover have "c \<in> {m *\<^sub>R a + c..m *\<^sub>R b + c}" unfolding True by(auto simp add: vector_less_eq_def)
  2.5751 +  ultimately show ?thesis by auto
  2.5752 +next
  2.5753 +  case False
  2.5754 +  { fix y assume "a \<le> y" "y \<le> b" "m > 0"
  2.5755 +    hence "m *\<^sub>R a + c \<le> m *\<^sub>R y + c"  "m *\<^sub>R y + c \<le> m *\<^sub>R b + c"
  2.5756 +      unfolding vector_less_eq_def by(auto simp add: vector_smult_component vector_add_component)
  2.5757 +  } moreover
  2.5758 +  { fix y assume "a \<le> y" "y \<le> b" "m < 0"
  2.5759 +    hence "m *\<^sub>R b + c \<le> m *\<^sub>R y + c"  "m *\<^sub>R y + c \<le> m *\<^sub>R a + c"
  2.5760 +      unfolding vector_less_eq_def by(auto simp add: vector_smult_component vector_add_component mult_left_mono_neg elim!:ballE)
  2.5761 +  } moreover
  2.5762 +  { fix y assume "m > 0"  "m *\<^sub>R a + c \<le> y"  "y \<le> m *\<^sub>R b + c"
  2.5763 +    hence "y \<in> (\<lambda>x. m *\<^sub>R x + c) ` {a..b}"
  2.5764 +      unfolding image_iff Bex_def mem_interval vector_less_eq_def
  2.5765 +      apply(auto simp add: vector_smult_component vector_add_component vector_minus_component vector_smult_assoc pth_3[symmetric]
  2.5766 +	intro!: exI[where x="(1 / m) *\<^sub>R (y - c)"])
  2.5767 +      by(auto simp add: pos_le_divide_eq pos_divide_le_eq real_mult_commute diff_le_iff)
  2.5768 +  } moreover
  2.5769 +  { fix y assume "m *\<^sub>R b + c \<le> y" "y \<le> m *\<^sub>R a + c" "m < 0"
  2.5770 +    hence "y \<in> (\<lambda>x. m *\<^sub>R x + c) ` {a..b}"
  2.5771 +      unfolding image_iff Bex_def mem_interval vector_less_eq_def
  2.5772 +      apply(auto simp add: vector_smult_component vector_add_component vector_minus_component vector_smult_assoc pth_3[symmetric]
  2.5773 +	intro!: exI[where x="(1 / m) *\<^sub>R (y - c)"])
  2.5774 +      by(auto simp add: neg_le_divide_eq neg_divide_le_eq real_mult_commute diff_le_iff)
  2.5775 +  }
  2.5776 +  ultimately show ?thesis using False by auto
  2.5777 +qed
  2.5778 +
  2.5779 +lemma image_smult_interval:"(\<lambda>x. m *\<^sub>R (x::real^'n::finite)) ` {a..b} =
  2.5780 +  (if {a..b} = {} then {} else if 0 \<le> m then {m *\<^sub>R a..m *\<^sub>R b} else {m *\<^sub>R b..m *\<^sub>R a})"
  2.5781 +  using image_affinity_interval[of m 0 a b] by auto
  2.5782 +
  2.5783 +subsection{* Banach fixed point theorem (not really topological...) *}
  2.5784 +
  2.5785 +lemma banach_fix:
  2.5786 +  assumes s:"complete s" "s \<noteq> {}" and c:"0 \<le> c" "c < 1" and f:"(f ` s) \<subseteq> s" and
  2.5787 +          lipschitz:"\<forall>x\<in>s. \<forall>y\<in>s. dist (f x) (f y) \<le> c * dist x y"
  2.5788 +  shows "\<exists>! x\<in>s. (f x = x)"
  2.5789 +proof-
  2.5790 +  have "1 - c > 0" using c by auto
  2.5791 +
  2.5792 +  from s(2) obtain z0 where "z0 \<in> s" by auto
  2.5793 +  def z \<equiv> "\<lambda>n. (f ^^ n) z0"
  2.5794 +  { fix n::nat
  2.5795 +    have "z n \<in> s" unfolding z_def
  2.5796 +    proof(induct n) case 0 thus ?case using `z0 \<in>s` by auto
  2.5797 +    next case Suc thus ?case using f by auto qed }
  2.5798 +  note z_in_s = this
  2.5799 +
  2.5800 +  def d \<equiv> "dist (z 0) (z 1)"
  2.5801 +
  2.5802 +  have fzn:"\<And>n. f (z n) = z (Suc n)" unfolding z_def by auto
  2.5803 +  { fix n::nat
  2.5804 +    have "dist (z n) (z (Suc n)) \<le> (c ^ n) * d"
  2.5805 +    proof(induct n)
  2.5806 +      case 0 thus ?case unfolding d_def by auto
  2.5807 +    next
  2.5808 +      case (Suc m)
  2.5809 +      hence "c * dist (z m) (z (Suc m)) \<le> c ^ Suc m * d"
  2.5810 +	using `0 \<le> c` using mult_mono1_class.mult_mono1[of "dist (z m) (z (Suc m))" "c ^ m * d" c] by auto
  2.5811 +      thus ?case using lipschitz[THEN bspec[where x="z m"], OF z_in_s, THEN bspec[where x="z (Suc m)"], OF z_in_s]
  2.5812 +	unfolding fzn and mult_le_cancel_left by auto
  2.5813 +    qed
  2.5814 +  } note cf_z = this
  2.5815 +
  2.5816 +  { fix n m::nat
  2.5817 +    have "(1 - c) * dist (z m) (z (m+n)) \<le> (c ^ m) * d * (1 - c ^ n)"
  2.5818 +    proof(induct n)
  2.5819 +      case 0 show ?case by auto
  2.5820 +    next
  2.5821 +      case (Suc k)
  2.5822 +      have "(1 - c) * dist (z m) (z (m + Suc k)) \<le> (1 - c) * (dist (z m) (z (m + k)) + dist (z (m + k)) (z (Suc (m + k))))"
  2.5823 +	using dist_triangle and c by(auto simp add: dist_triangle)
  2.5824 +      also have "\<dots> \<le> (1 - c) * (dist (z m) (z (m + k)) + c ^ (m + k) * d)"
  2.5825 +	using cf_z[of "m + k"] and c by auto
  2.5826 +      also have "\<dots> \<le> c ^ m * d * (1 - c ^ k) + (1 - c) * c ^ (m + k) * d"
  2.5827 +	using Suc by (auto simp add: ring_simps)
  2.5828 +      also have "\<dots> = (c ^ m) * (d * (1 - c ^ k) + (1 - c) * c ^ k * d)"
  2.5829 +	unfolding power_add by (auto simp add: ring_simps)
  2.5830 +      also have "\<dots> \<le> (c ^ m) * d * (1 - c ^ Suc k)"
  2.5831 +	using c by (auto simp add: ring_simps)
  2.5832 +      finally show ?case by auto
  2.5833 +    qed
  2.5834 +  } note cf_z2 = this
  2.5835 +  { fix e::real assume "e>0"
  2.5836 +    hence "\<exists>N. \<forall>m n. N \<le> m \<and> N \<le> n \<longrightarrow> dist (z m) (z n) < e"
  2.5837 +    proof(cases "d = 0")
  2.5838 +      case True
  2.5839 +      hence "\<And>n. z n = z0" using cf_z2[of 0] and c unfolding z_def by (auto simp add: pos_prod_le[OF `1 - c > 0`])
  2.5840 +      thus ?thesis using `e>0` by auto
  2.5841 +    next
  2.5842 +      case False hence "d>0" unfolding d_def using zero_le_dist[of "z 0" "z 1"]
  2.5843 +	by (metis False d_def real_less_def)
  2.5844 +      hence "0 < e * (1 - c) / d" using `e>0` and `1-c>0`
  2.5845 +	using divide_pos_pos[of "e * (1 - c)" d] and mult_pos_pos[of e "1 - c"] by auto
  2.5846 +      then obtain N where N:"c ^ N < e * (1 - c) / d" using real_arch_pow_inv[of "e * (1 - c) / d" c] and c by auto
  2.5847 +      { fix m n::nat assume "m>n" and as:"m\<ge>N" "n\<ge>N"
  2.5848 +	have *:"c ^ n \<le> c ^ N" using `n\<ge>N` and c using power_decreasing[OF `n\<ge>N`, of c] by auto
  2.5849 +	have "1 - c ^ (m - n) > 0" using c and power_strict_mono[of c 1 "m - n"] using `m>n` by auto
  2.5850 +	hence **:"d * (1 - c ^ (m - n)) / (1 - c) > 0"
  2.5851 +	  using real_mult_order[OF `d>0`, of "1 - c ^ (m - n)"]
  2.5852 +	  using divide_pos_pos[of "d * (1 - c ^ (m - n))" "1 - c"]
  2.5853 +	  using `0 < 1 - c` by auto
  2.5854 +
  2.5855 +	have "dist (z m) (z n) \<le> c ^ n * d * (1 - c ^ (m - n)) / (1 - c)"
  2.5856 +	  using cf_z2[of n "m - n"] and `m>n` unfolding pos_le_divide_eq[OF `1-c>0`]
  2.5857 +	  by (auto simp add: real_mult_commute dist_commute)
  2.5858 +	also have "\<dots> \<le> c ^ N * d * (1 - c ^ (m - n)) / (1 - c)"
  2.5859 +	  using mult_right_mono[OF * order_less_imp_le[OF **]]
  2.5860 +	  unfolding real_mult_assoc by auto
  2.5861 +	also have "\<dots> < (e * (1 - c) / d) * d * (1 - c ^ (m - n)) / (1 - c)"
  2.5862 +	  using mult_strict_right_mono[OF N **] unfolding real_mult_assoc by auto
  2.5863 +	also have "\<dots> = e * (1 - c ^ (m - n))" using c and `d>0` and `1 - c > 0` by auto
  2.5864 +	also have "\<dots> \<le> e" using c and `1 - c ^ (m - n) > 0` and `e>0` using mult_right_le_one_le[of e "1 - c ^ (m - n)"] by auto
  2.5865 +	finally have  "dist (z m) (z n) < e" by auto
  2.5866 +      } note * = this
  2.5867 +      { fix m n::nat assume as:"N\<le>m" "N\<le>n"
  2.5868 +	hence "dist (z n) (z m) < e"
  2.5869 +	proof(cases "n = m")
  2.5870 +	  case True thus ?thesis using `e>0` by auto
  2.5871 +	next
  2.5872 +	  case False thus ?thesis using as and *[of n m] *[of m n] unfolding nat_neq_iff by (auto simp add: dist_commute)
  2.5873 +	qed }
  2.5874 +      thus ?thesis by auto
  2.5875 +    qed
  2.5876 +  }
  2.5877 +  hence "Cauchy z" unfolding cauchy_def by auto
  2.5878 +  then obtain x where "x\<in>s" and x:"(z ---> x) sequentially" using s(1)[unfolded compact_def complete_def, THEN spec[where x=z]] and z_in_s by auto
  2.5879 +
  2.5880 +  def e \<equiv> "dist (f x) x"
  2.5881 +  have "e = 0" proof(rule ccontr)
  2.5882 +    assume "e \<noteq> 0" hence "e>0" unfolding e_def using zero_le_dist[of "f x" x]
  2.5883 +      by (metis dist_eq_0_iff dist_nz e_def)
  2.5884 +    then obtain N where N:"\<forall>n\<ge>N. dist (z n) x < e / 2"
  2.5885 +      using x[unfolded Lim_sequentially, THEN spec[where x="e/2"]] by auto
  2.5886 +    hence N':"dist (z N) x < e / 2" by auto
  2.5887 +
  2.5888 +    have *:"c * dist (z N) x \<le> dist (z N) x" unfolding mult_le_cancel_right2
  2.5889 +      using zero_le_dist[of "z N" x] and c
  2.5890 +      by (metis dist_eq_0_iff dist_nz order_less_asym real_less_def)
  2.5891 +    have "dist (f (z N)) (f x) \<le> c * dist (z N) x" using lipschitz[THEN bspec[where x="z N"], THEN bspec[where x=x]]
  2.5892 +      using z_in_s[of N] `x\<in>s` using c by auto
  2.5893 +    also have "\<dots> < e / 2" using N' and c using * by auto
  2.5894 +    finally show False unfolding fzn
  2.5895 +      using N[THEN spec[where x="Suc N"]] and dist_triangle_half_r[of "z (Suc N)" "f x" e x]
  2.5896 +      unfolding e_def by auto
  2.5897 +  qed
  2.5898 +  hence "f x = x" unfolding e_def by auto
  2.5899 +  moreover
  2.5900 +  { fix y assume "f y = y" "y\<in>s"
  2.5901 +    hence "dist x y \<le> c * dist x y" using lipschitz[THEN bspec[where x=x], THEN bspec[where x=y]]
  2.5902 +      using `x\<in>s` and `f x = x` by auto
  2.5903 +    hence "dist x y = 0" unfolding mult_le_cancel_right1
  2.5904 +      using c and zero_le_dist[of x y] by auto
  2.5905 +    hence "y = x" by auto
  2.5906 +  }
  2.5907 +  ultimately show ?thesis unfolding Bex1_def using `x\<in>s` by blast+
  2.5908 +qed
  2.5909 +
  2.5910 +subsection{* Edelstein fixed point theorem.                                            *}
  2.5911 +
  2.5912 +lemma edelstein_fix:
  2.5913 +  fixes s :: "'a::real_normed_vector set"
  2.5914 +  assumes s:"compact s" "s \<noteq> {}" and gs:"(g ` s) \<subseteq> s"
  2.5915 +      and dist:"\<forall>x\<in>s. \<forall>y\<in>s. x \<noteq> y \<longrightarrow> dist (g x) (g y) < dist x y"
  2.5916 +  shows "\<exists>! x\<in>s. g x = x"
  2.5917 +proof(cases "\<exists>x\<in>s. g x \<noteq> x")
  2.5918 +  obtain x where "x\<in>s" using s(2) by auto
  2.5919 +  case False hence g:"\<forall>x\<in>s. g x = x" by auto
  2.5920 +  { fix y assume "y\<in>s"
  2.5921 +    hence "x = y" using `x\<in>s` and dist[THEN bspec[where x=x], THEN bspec[where x=y]]
  2.5922 +      unfolding g[THEN bspec[where x=x], OF `x\<in>s`]
  2.5923 +      unfolding g[THEN bspec[where x=y], OF `y\<in>s`] by auto  }
  2.5924 +  thus ?thesis unfolding Bex1_def using `x\<in>s` and g by blast+
  2.5925 +next
  2.5926 +  case True
  2.5927 +  then obtain x where [simp]:"x\<in>s" and "g x \<noteq> x" by auto
  2.5928 +  { fix x y assume "x \<in> s" "y \<in> s"
  2.5929 +    hence "dist (g x) (g y) \<le> dist x y"
  2.5930 +      using dist[THEN bspec[where x=x], THEN bspec[where x=y]] by auto } note dist' = this
  2.5931 +  def y \<equiv> "g x"
  2.5932 +  have [simp]:"y\<in>s" unfolding y_def using gs[unfolded image_subset_iff] and `x\<in>s` by blast
  2.5933 +  def f \<equiv> "\<lambda>n. g ^^ n"
  2.5934 +  have [simp]:"\<And>n z. g (f n z) = f (Suc n) z" unfolding f_def by auto
  2.5935 +  have [simp]:"\<And>z. f 0 z = z" unfolding f_def by auto
  2.5936 +  { fix n::nat and z assume "z\<in>s"
  2.5937 +    have "f n z \<in> s" unfolding f_def
  2.5938 +    proof(induct n)
  2.5939 +      case 0 thus ?case using `z\<in>s` by simp
  2.5940 +    next
  2.5941 +      case (Suc n) thus ?case using gs[unfolded image_subset_iff] by auto
  2.5942 +    qed } note fs = this
  2.5943 +  { fix m n ::nat assume "m\<le>n"
  2.5944 +    fix w z assume "w\<in>s" "z\<in>s"
  2.5945 +    have "dist (f n w) (f n z) \<le> dist (f m w) (f m z)" using `m\<le>n`
  2.5946 +    proof(induct n)
  2.5947 +      case 0 thus ?case by auto
  2.5948 +    next
  2.5949 +      case (Suc n)
  2.5950 +      thus ?case proof(cases "m\<le>n")
  2.5951 +	case True thus ?thesis using Suc(1)
  2.5952 +	  using dist'[OF fs fs, OF `w\<in>s` `z\<in>s`, of n n] by auto
  2.5953 +      next
  2.5954 +	case False hence mn:"m = Suc n" using Suc(2) by simp
  2.5955 +	show ?thesis unfolding mn  by auto
  2.5956 +      qed
  2.5957 +    qed } note distf = this
  2.5958 +
  2.5959 +  def h \<equiv> "\<lambda>n. (f n x, f n y)"
  2.5960 +  let ?s2 = "s \<times> s"
  2.5961 +  obtain l r where "l\<in>?s2" and r:"subseq r" and lr:"((h \<circ> r) ---> l) sequentially"
  2.5962 +    using compact_Times [OF s(1) s(1), unfolded compact_def, THEN spec[where x=h]] unfolding  h_def
  2.5963 +    using fs[OF `x\<in>s`] and fs[OF `y\<in>s`] by blast
  2.5964 +  def a \<equiv> "fst l" def b \<equiv> "snd l"
  2.5965 +  have lab:"l = (a, b)" unfolding a_def b_def by simp
  2.5966 +  have [simp]:"a\<in>s" "b\<in>s" unfolding a_def b_def using `l\<in>?s2` by auto
  2.5967 +
  2.5968 +  have lima:"((fst \<circ> (h \<circ> r)) ---> a) sequentially"
  2.5969 +   and limb:"((snd \<circ> (h \<circ> r)) ---> b) sequentially"
  2.5970 +    using lr
  2.5971 +    unfolding o_def a_def b_def by (simp_all add: tendsto_intros)
  2.5972 +
  2.5973 +  { fix n::nat
  2.5974 +    have *:"\<And>fx fy (x::'a) y. dist fx fy \<le> dist x y \<Longrightarrow> \<not> (dist (fx - fy) (a - b) < dist a b - dist x y)" unfolding dist_norm by norm
  2.5975 +    { fix x y :: 'a
  2.5976 +      have "dist (-x) (-y) = dist x y" unfolding dist_norm
  2.5977 +	using norm_minus_cancel[of "x - y"] by (auto simp add: uminus_add_conv_diff) } note ** = this
  2.5978 +
  2.5979 +    { assume as:"dist a b > dist (f n x) (f n y)"
  2.5980 +      then obtain Na Nb where "\<forall>m\<ge>Na. dist (f (r m) x) a < (dist a b - dist (f n x) (f n y)) / 2"
  2.5981 +	and "\<forall>m\<ge>Nb. dist (f (r m) y) b < (dist a b - dist (f n x) (f n y)) / 2"
  2.5982 +	using lima limb unfolding h_def Lim_sequentially by (fastsimp simp del: less_divide_eq_number_of1)
  2.5983 +      hence "dist (f (r (Na + Nb + n)) x - f (r (Na + Nb + n)) y) (a - b) < dist a b - dist (f n x) (f n y)"
  2.5984 +	apply(erule_tac x="Na+Nb+n" in allE)
  2.5985 +	apply(erule_tac x="Na+Nb+n" in allE) apply simp
  2.5986 +	using dist_triangle_add_half[of a "f (r (Na + Nb + n)) x" "dist a b - dist (f n x) (f n y)"
  2.5987 +          "-b"  "- f (r (Na + Nb + n)) y"]
  2.5988 +	unfolding ** unfolding group_simps(12) by (auto simp add: dist_commute)
  2.5989 +      moreover
  2.5990 +      have "dist (f (r (Na + Nb + n)) x - f (r (Na + Nb + n)) y) (a - b) \<ge> dist a b - dist (f n x) (f n y)"
  2.5991 +	using distf[of n "r (Na+Nb+n)", OF _ `x\<in>s` `y\<in>s`]
  2.5992 +	using subseq_bigger[OF r, of "Na+Nb+n"]
  2.5993 +	using *[of "f (r (Na + Nb + n)) x" "f (r (Na + Nb + n)) y" "f n x" "f n y"] by auto
  2.5994 +      ultimately have False by simp
  2.5995 +    }
  2.5996 +    hence "dist a b \<le> dist (f n x) (f n y)" by(rule ccontr)auto }
  2.5997 +  note ab_fn = this
  2.5998 +
  2.5999 +  have [simp]:"a = b" proof(rule ccontr)
  2.6000 +    def e \<equiv> "dist a b - dist (g a) (g b)"
  2.6001 +    assume "a\<noteq>b" hence "e > 0" unfolding e_def using dist by fastsimp
  2.6002 +    hence "\<exists>n. dist (f n x) a < e/2 \<and> dist (f n y) b < e/2"
  2.6003 +      using lima limb unfolding Lim_sequentially
  2.6004 +      apply (auto elim!: allE[where x="e/2"]) apply(rule_tac x="r (max N Na)" in exI) unfolding h_def by fastsimp
  2.6005 +    then obtain n where n:"dist (f n x) a < e/2 \<and> dist (f n y) b < e/2" by auto
  2.6006 +    have "dist (f (Suc n) x) (g a) \<le> dist (f n x) a"
  2.6007 +      using dist[THEN bspec[where x="f n x"], THEN bspec[where x="a"]] and fs by auto
  2.6008 +    moreover have "dist (f (Suc n) y) (g b) \<le> dist (f n y) b"
  2.6009 +      using dist[THEN bspec[where x="f n y"], THEN bspec[where x="b"]] and fs by auto
  2.6010 +    ultimately have "dist (f (Suc n) x) (g a) + dist (f (Suc n) y) (g b) < e" using n by auto
  2.6011 +    thus False unfolding e_def using ab_fn[of "Suc n"] by norm
  2.6012 +  qed
  2.6013 +
  2.6014 +  have [simp]:"\<And>n. f (Suc n) x = f n y" unfolding f_def y_def by(induct_tac n)auto
  2.6015 +  { fix x y assume "x\<in>s" "y\<in>s" moreover
  2.6016 +    fix e::real assume "e>0" ultimately
  2.6017 +    have "dist y x < e \<longrightarrow> dist (g y) (g x) < e" using dist by fastsimp }
  2.6018 +  hence "continuous_on s g" unfolding continuous_on_def by auto
  2.6019 +
  2.6020 +  hence "((snd \<circ> h \<circ> r) ---> g a) sequentially" unfolding continuous_on_sequentially
  2.6021 +    apply (rule allE[where x="\<lambda>n. (fst \<circ> h \<circ> r) n"]) apply (erule ballE[where x=a])
  2.6022 +    using lima unfolding h_def o_def using fs[OF `x\<in>s`] by (auto simp add: y_def)
  2.6023 +  hence "g a = a" using Lim_unique[OF trivial_limit_sequentially limb, of "g a"]
  2.6024 +    unfolding `a=b` and o_assoc by auto
  2.6025 +  moreover
  2.6026 +  { fix x assume "x\<in>s" "g x = x" "x\<noteq>a"
  2.6027 +    hence "False" using dist[THEN bspec[where x=a], THEN bspec[where x=x]]
  2.6028 +      using `g a = a` and `a\<in>s` by auto  }
  2.6029 +  ultimately show "\<exists>!x\<in>s. g x = x" unfolding Bex1_def using `a\<in>s` by blast
  2.6030 +qed
  2.6031 +
  2.6032 +end
     3.1 --- a/src/HOL/Library/Convex_Euclidean_Space.thy	Mon Oct 26 08:54:20 2009 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,3371 +0,0 @@
     3.4 -(*  Title:      HOL/Library/Convex_Euclidean_Space.thy
     3.5 -    Author:     Robert Himmelmann, TU Muenchen
     3.6 -*)
     3.7 -
     3.8 -header {* Convex sets, functions and related things. *}
     3.9 -
    3.10 -theory Convex_Euclidean_Space
    3.11 -imports Topology_Euclidean_Space
    3.12 -begin
    3.13 -
    3.14 -
    3.15 -(* ------------------------------------------------------------------------- *)
    3.16 -(* To be moved elsewhere                                                     *)
    3.17 -(* ------------------------------------------------------------------------- *)
    3.18 -
    3.19 -declare vector_add_ldistrib[simp] vector_ssub_ldistrib[simp] vector_smult_assoc[simp] vector_smult_rneg[simp]
    3.20 -declare vector_sadd_rdistrib[simp] vector_sub_rdistrib[simp]
    3.21 -declare dot_ladd[simp] dot_radd[simp] dot_lsub[simp] dot_rsub[simp]
    3.22 -declare dot_lmult[simp] dot_rmult[simp] dot_lneg[simp] dot_rneg[simp]
    3.23 -declare UNIV_1[simp]
    3.24 -
    3.25 -term "(x::real^'n \<Rightarrow> real) 0"
    3.26 -
    3.27 -lemma dim1in[intro]:"Suc 0 \<in> {1::nat .. CARD(1)}" by auto
    3.28 -
    3.29 -lemmas vector_component_simps = vector_minus_component vector_smult_component vector_add_component vector_less_eq_def Cart_lambda_beta dest_vec1_def basis_component vector_uminus_component
    3.30 -
    3.31 -lemmas continuous_intros = continuous_add continuous_vmul continuous_cmul continuous_const continuous_sub continuous_at_id continuous_within_id
    3.32 -
    3.33 -lemmas continuous_on_intros = continuous_on_add continuous_on_const continuous_on_id continuous_on_compose continuous_on_cmul continuous_on_neg continuous_on_sub
    3.34 -  uniformly_continuous_on_add uniformly_continuous_on_const uniformly_continuous_on_id uniformly_continuous_on_compose uniformly_continuous_on_cmul uniformly_continuous_on_neg uniformly_continuous_on_sub
    3.35 -
    3.36 -lemma dest_vec1_simps[simp]: fixes a::"real^1"
    3.37 -  shows "a$1 = 0 \<longleftrightarrow> a = 0" (*"a \<le> 1 \<longleftrightarrow> dest_vec1 a \<le> 1" "0 \<le> a \<longleftrightarrow> 0 \<le> dest_vec1 a"*)
    3.38 -  "a \<le> b \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 b" "dest_vec1 (1::real^1) = 1"
    3.39 -  by(auto simp add:vector_component_simps all_1 Cart_eq)
    3.40 -
    3.41 -lemma nequals0I:"x\<in>A \<Longrightarrow> A \<noteq> {}" by auto
    3.42 -
    3.43 -lemma norm_not_0:"(x::real^'n::finite)\<noteq>0 \<Longrightarrow> norm x \<noteq> 0" by auto
    3.44 -
    3.45 -lemma setsum_delta_notmem: assumes "x\<notin>s"
    3.46 -  shows "setsum (\<lambda>y. if (y = x) then P x else Q y) s = setsum Q s"
    3.47 -        "setsum (\<lambda>y. if (x = y) then P x else Q y) s = setsum Q s"
    3.48 -        "setsum (\<lambda>y. if (y = x) then P y else Q y) s = setsum Q s"
    3.49 -        "setsum (\<lambda>y. if (x = y) then P y else Q y) s = setsum Q s"
    3.50 -  apply(rule_tac [!] setsum_cong2) using assms by auto
    3.51 -
    3.52 -lemma setsum_delta'':
    3.53 -  fixes s::"'a::real_vector set" assumes "finite s"
    3.54 -  shows "(\<Sum>x\<in>s. (if y = x then f x else 0) *\<^sub>R x) = (if y\<in>s then (f y) *\<^sub>R y else 0)"
    3.55 -proof-
    3.56 -  have *:"\<And>x y. (if y = x then f x else (0::real)) *\<^sub>R x = (if x=y then (f x) *\<^sub>R x else 0)" by auto
    3.57 -  show ?thesis unfolding * using setsum_delta[OF assms, of y "\<lambda>x. f x *\<^sub>R x"] by auto
    3.58 -qed
    3.59 -
    3.60 -lemma not_disjointI:"x\<in>A \<Longrightarrow> x\<in>B \<Longrightarrow> A \<inter> B \<noteq> {}" by blast
    3.61 -
    3.62 -lemma if_smult:"(if P then x else (y::real)) *\<^sub>R v = (if P then x *\<^sub>R v else y *\<^sub>R v)" by auto
    3.63 -
    3.64 -lemma mem_interval_1: fixes x :: "real^1" shows
    3.65 - "(x \<in> {a .. b} \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 x \<and> dest_vec1 x \<le> dest_vec1 b)"
    3.66 - "(x \<in> {a<..<b} \<longleftrightarrow> dest_vec1 a < dest_vec1 x \<and> dest_vec1 x < dest_vec1 b)"
    3.67 -by(simp_all add: Cart_eq vector_less_def vector_less_eq_def dest_vec1_def all_1)
    3.68 -
    3.69 -lemma image_smult_interval:"(\<lambda>x. m *\<^sub>R (x::real^'n::finite)) ` {a..b} =
    3.70 -  (if {a..b} = {} then {} else if 0 \<le> m then {m *\<^sub>R a..m *\<^sub>R b} else {m *\<^sub>R b..m *\<^sub>R a})"
    3.71 -  using image_affinity_interval[of m 0 a b] by auto
    3.72 -
    3.73 -lemma dest_vec1_inverval:
    3.74 -  "dest_vec1 ` {a .. b} = {dest_vec1 a .. dest_vec1 b}"
    3.75 -  "dest_vec1 ` {a<.. b} = {dest_vec1 a<.. dest_vec1 b}"
    3.76 -  "dest_vec1 ` {a ..<b} = {dest_vec1 a ..<dest_vec1 b}"
    3.77 -  "dest_vec1 ` {a<..<b} = {dest_vec1 a<..<dest_vec1 b}"
    3.78 -  apply(rule_tac [!] equalityI)
    3.79 -  unfolding subset_eq Ball_def Bex_def mem_interval_1 image_iff
    3.80 -  apply(rule_tac [!] allI)apply(rule_tac [!] impI)
    3.81 -  apply(rule_tac[2] x="vec1 x" in exI)apply(rule_tac[4] x="vec1 x" in exI)
    3.82 -  apply(rule_tac[6] x="vec1 x" in exI)apply(rule_tac[8] x="vec1 x" in exI)
    3.83 -  by (auto simp add: vector_less_def vector_less_eq_def all_1 dest_vec1_def
    3.84 -    vec1_dest_vec1[unfolded dest_vec1_def One_nat_def])
    3.85 -
    3.86 -lemma dest_vec1_setsum: assumes "finite S"
    3.87 -  shows " dest_vec1 (setsum f S) = setsum (\<lambda>x. dest_vec1 (f x)) S"
    3.88 -  using dest_vec1_sum[OF assms] by auto
    3.89 -
    3.90 -lemma dist_triangle_eq:
    3.91 -  fixes x y z :: "real ^ _"
    3.92 -  shows "dist x z = dist x y + dist y z \<longleftrightarrow> norm (x - y) *\<^sub>R (y - z) = norm (y - z) *\<^sub>R (x - y)"
    3.93 -proof- have *:"x - y + (y - z) = x - z" by auto
    3.94 -  show ?thesis unfolding dist_norm norm_triangle_eq[of "x - y" "y - z", unfolded smult_conv_scaleR *]
    3.95 -    by(auto simp add:norm_minus_commute) qed
    3.96 -
    3.97 -lemma norm_eqI:"x = y \<Longrightarrow> norm x = norm y" by auto 
    3.98 -lemma norm_minus_eqI:"(x::real^'n::finite) = - y \<Longrightarrow> norm x = norm y" by auto
    3.99 -
   3.100 -lemma Min_grI: assumes "finite A" "A \<noteq> {}" "\<forall>a\<in>A. x < a" shows "x < Min A"
   3.101 -  unfolding Min_gr_iff[OF assms(1,2)] using assms(3) by auto
   3.102 -
   3.103 -lemma dimindex_ge_1:"CARD(_::finite) \<ge> 1"
   3.104 -  using one_le_card_finite by auto
   3.105 -
   3.106 -lemma real_dimindex_ge_1:"real (CARD('n::finite)) \<ge> 1" 
   3.107 -  by(metis dimindex_ge_1 linorder_not_less real_eq_of_nat real_le_trans real_of_nat_1 real_of_nat_le_iff) 
   3.108 -
   3.109 -lemma real_dimindex_gt_0:"real (CARD('n::finite)) > 0" apply(rule less_le_trans[OF _ real_dimindex_ge_1]) by auto
   3.110 -
   3.111 -subsection {* Affine set and affine hull.*}
   3.112 -
   3.113 -definition
   3.114 -  affine :: "'a::real_vector set \<Rightarrow> bool" where
   3.115 -  "affine s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u v. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s)"
   3.116 -
   3.117 -lemma affine_alt: "affine s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u::real. (1 - u) *\<^sub>R x + u *\<^sub>R y \<in> s)"
   3.118 -proof- have *:"\<And>u v ::real. u + v = 1 \<longleftrightarrow> v = 1 - u" by auto
   3.119 -  { fix x y assume "x\<in>s" "y\<in>s"
   3.120 -    hence "(\<forall>u v::real. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s) \<longleftrightarrow> (\<forall>u::real. (1 - u) *\<^sub>R x + u *\<^sub>R y \<in> s)" apply auto 
   3.121 -      apply(erule_tac[!] x="1 - u" in allE) unfolding * by auto  }
   3.122 -  thus ?thesis unfolding affine_def by auto qed
   3.123 -
   3.124 -lemma affine_empty[intro]: "affine {}"
   3.125 -  unfolding affine_def by auto
   3.126 -
   3.127 -lemma affine_sing[intro]: "affine {x}"
   3.128 -  unfolding affine_alt by (auto simp add: scaleR_left_distrib [symmetric])
   3.129 -
   3.130 -lemma affine_UNIV[intro]: "affine UNIV"
   3.131 -  unfolding affine_def by auto
   3.132 -
   3.133 -lemma affine_Inter: "(\<forall>s\<in>f. affine s) \<Longrightarrow> affine (\<Inter> f)"
   3.134 -  unfolding affine_def by auto 
   3.135 -
   3.136 -lemma affine_Int: "affine s \<Longrightarrow> affine t \<Longrightarrow> affine (s \<inter> t)"
   3.137 -  unfolding affine_def by auto
   3.138 -
   3.139 -lemma affine_affine_hull: "affine(affine hull s)"
   3.140 -  unfolding hull_def using affine_Inter[of "{t \<in> affine. s \<subseteq> t}"]
   3.141 -  unfolding mem_def by auto
   3.142 -
   3.143 -lemma affine_hull_eq[simp]: "(affine hull s = s) \<longleftrightarrow> affine s"
   3.144 -proof-
   3.145 -  { fix f assume "f \<subseteq> affine"
   3.146 -    hence "affine (\<Inter>f)" using affine_Inter[of f] unfolding subset_eq mem_def by auto  }
   3.147 -  thus ?thesis using hull_eq[unfolded mem_def, of affine s] by auto
   3.148 -qed
   3.149 -
   3.150 -lemma setsum_restrict_set'': assumes "finite A"
   3.151 -  shows "setsum f {x \<in> A. P x} = (\<Sum>x\<in>A. if P x  then f x else 0)"
   3.152 -  unfolding mem_def[of _ P, symmetric] unfolding setsum_restrict_set'[OF assms] ..
   3.153 -
   3.154 -subsection {* Some explicit formulations (from Lars Schewe). *}
   3.155 -
   3.156 -lemma affine: fixes V::"'a::real_vector set"
   3.157 -  shows "affine V \<longleftrightarrow> (\<forall>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> V \<and> setsum u s = 1 \<longrightarrow> (setsum (\<lambda>x. (u x) *\<^sub>R x)) s \<in> V)"
   3.158 -unfolding affine_def apply rule apply(rule, rule, rule) apply(erule conjE)+ 
   3.159 -defer apply(rule, rule, rule, rule, rule) proof-
   3.160 -  fix x y u v assume as:"x \<in> V" "y \<in> V" "u + v = (1::real)"
   3.161 -    "\<forall>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> V \<and> setsum u s = 1 \<longrightarrow> (\<Sum>x\<in>s. u x *\<^sub>R x) \<in> V"
   3.162 -  thus "u *\<^sub>R x + v *\<^sub>R y \<in> V" apply(cases "x=y")
   3.163 -    using as(4)[THEN spec[where x="{x,y}"], THEN spec[where x="\<lambda>w. if w = x then u else v"]] and as(1-3) 
   3.164 -    by(auto simp add: scaleR_left_distrib[THEN sym])
   3.165 -next
   3.166 -  fix s u assume as:"\<forall>x\<in>V. \<forall>y\<in>V. \<forall>u v. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> V"
   3.167 -    "finite s" "s \<noteq> {}" "s \<subseteq> V" "setsum u s = (1::real)"
   3.168 -  def n \<equiv> "card s"
   3.169 -  have "card s = 0 \<or> card s = 1 \<or> card s = 2 \<or> card s > 2" by auto
   3.170 -  thus "(\<Sum>x\<in>s. u x *\<^sub>R x) \<in> V" proof(auto simp only: disjE)
   3.171 -    assume "card s = 2" hence "card s = Suc (Suc 0)" by auto
   3.172 -    then obtain a b where "s = {a, b}" unfolding card_Suc_eq by auto
   3.173 -    thus ?thesis using as(1)[THEN bspec[where x=a], THEN bspec[where x=b]] using as(4,5)
   3.174 -      by(auto simp add: setsum_clauses(2))
   3.175 -  next assume "card s > 2" thus ?thesis using as and n_def proof(induct n arbitrary: u s)
   3.176 -      case (Suc n) fix s::"'a set" and u::"'a \<Rightarrow> real"
   3.177 -      assume IA:"\<And>u s.  \<lbrakk>2 < card s; \<forall>x\<in>V. \<forall>y\<in>V. \<forall>u v. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> V; finite s;
   3.178 -               s \<noteq> {}; s \<subseteq> V; setsum u s = 1; n \<equiv> card s \<rbrakk> \<Longrightarrow> (\<Sum>x\<in>s. u x *\<^sub>R x) \<in> V" and
   3.179 -        as:"Suc n \<equiv> card s" "2 < card s" "\<forall>x\<in>V. \<forall>y\<in>V. \<forall>u v. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> V"
   3.180 -           "finite s" "s \<noteq> {}" "s \<subseteq> V" "setsum u s = 1"
   3.181 -      have "\<exists>x\<in>s. u x \<noteq> 1" proof(rule_tac ccontr)
   3.182 -        assume " \<not> (\<exists>x\<in>s. u x \<noteq> 1)" hence "setsum u s = real_of_nat (card s)" unfolding card_eq_setsum by auto
   3.183 -        thus False using as(7) and `card s > 2` by (metis Numeral1_eq1_nat less_0_number_of less_int_code(15)
   3.184 -          less_nat_number_of not_less_iff_gr_or_eq of_nat_1 of_nat_eq_iff pos2 rel_simps(4)) qed
   3.185 -      then obtain x where x:"x\<in>s" "u x \<noteq> 1" by auto
   3.186 -
   3.187 -      have c:"card (s - {x}) = card s - 1" apply(rule card_Diff_singleton) using `x\<in>s` as(4) by auto
   3.188 -      have *:"s = insert x (s - {x})" "finite (s - {x})" using `x\<in>s` and as(4) by auto
   3.189 -      have **:"setsum u (s - {x}) = 1 - u x"
   3.190 -        using setsum_clauses(2)[OF *(2), of u x, unfolded *(1)[THEN sym] as(7)] by auto
   3.191 -      have ***:"inverse (1 - u x) * setsum u (s - {x}) = 1" unfolding ** using `u x \<noteq> 1` by auto
   3.192 -      have "(\<Sum>xa\<in>s - {x}. (inverse (1 - u x) * u xa) *\<^sub>R xa) \<in> V" proof(cases "card (s - {x}) > 2")
   3.193 -        case True hence "s - {x} \<noteq> {}" "card (s - {x}) = n" unfolding c and as(1)[symmetric] proof(rule_tac ccontr) 
   3.194 -          assume "\<not> s - {x} \<noteq> {}" hence "card (s - {x}) = 0" unfolding card_0_eq[OF *(2)] by simp 
   3.195 -          thus False using True by auto qed auto
   3.196 -        thus ?thesis apply(rule_tac IA[of "s - {x}" "\<lambda>y. (inverse (1 - u x) * u y)"])
   3.197 -        unfolding setsum_right_distrib[THEN sym] using as and *** and True by auto
   3.198 -      next case False hence "card (s - {x}) = Suc (Suc 0)" using as(2) and c by auto
   3.199 -        then obtain a b where "(s - {x}) = {a, b}" "a\<noteq>b" unfolding card_Suc_eq by auto
   3.200 -        thus ?thesis using as(3)[THEN bspec[where x=a], THEN bspec[where x=b]]
   3.201 -          using *** *(2) and `s \<subseteq> V` unfolding setsum_right_distrib by(auto simp add: setsum_clauses(2)) qed
   3.202 -      thus "(\<Sum>x\<in>s. u x *\<^sub>R x) \<in> V" unfolding scaleR_scaleR[THEN sym] and scaleR_right.setsum [symmetric]
   3.203 -         apply(subst *) unfolding setsum_clauses(2)[OF *(2)]
   3.204 -         using as(3)[THEN bspec[where x=x], THEN bspec[where x="(inverse (1 - u x)) *\<^sub>R (\<Sum>xa\<in>s - {x}. u xa *\<^sub>R xa)"], 
   3.205 -         THEN spec[where x="u x"], THEN spec[where x="1 - u x"]] and rev_subsetD[OF `x\<in>s` `s\<subseteq>V`] and `u x \<noteq> 1` by auto
   3.206 -    qed auto
   3.207 -  next assume "card s = 1" then obtain a where "s={a}" by(auto simp add: card_Suc_eq)
   3.208 -    thus ?thesis using as(4,5) by simp
   3.209 -  qed(insert `s\<noteq>{}` `finite s`, auto)
   3.210 -qed
   3.211 -
   3.212 -lemma affine_hull_explicit:
   3.213 -  "affine hull p = {y. \<exists>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum u s = 1 \<and> setsum (\<lambda>v. (u v) *\<^sub>R v) s = y}"
   3.214 -  apply(rule hull_unique) apply(subst subset_eq) prefer 3 apply rule unfolding mem_Collect_eq and mem_def[of _ affine]
   3.215 -  apply (erule exE)+ apply(erule conjE)+ prefer 2 apply rule proof-
   3.216 -  fix x assume "x\<in>p" thus "\<exists>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = x"
   3.217 -    apply(rule_tac x="{x}" in exI, rule_tac x="\<lambda>x. 1" in exI) by auto
   3.218 -next
   3.219 -  fix t x s u assume as:"p \<subseteq> t" "affine t" "finite s" "s \<noteq> {}" "s \<subseteq> p" "setsum u s = 1" "(\<Sum>v\<in>s. u v *\<^sub>R v) = x" 
   3.220 -  thus "x \<in> t" using as(2)[unfolded affine, THEN spec[where x=s], THEN spec[where x=u]] by auto
   3.221 -next
   3.222 -  show "affine {y. \<exists>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y}" unfolding affine_def
   3.223 -    apply(rule,rule,rule,rule,rule) unfolding mem_Collect_eq proof-
   3.224 -    fix u v ::real assume uv:"u + v = 1"
   3.225 -    fix x assume "\<exists>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = x"
   3.226 -    then obtain sx ux where x:"finite sx" "sx \<noteq> {}" "sx \<subseteq> p" "setsum ux sx = 1" "(\<Sum>v\<in>sx. ux v *\<^sub>R v) = x" by auto
   3.227 -    fix y assume "\<exists>s u. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
   3.228 -    then obtain sy uy where y:"finite sy" "sy \<noteq> {}" "sy \<subseteq> p" "setsum uy sy = 1" "(\<Sum>v\<in>sy. uy v *\<^sub>R v) = y" by auto
   3.229 -    have xy:"finite (sx \<union> sy)" using x(1) y(1) by auto
   3.230 -    have **:"(sx \<union> sy) \<inter> sx = sx" "(sx \<union> sy) \<inter> sy = sy" by auto
   3.231 -    show "\<exists>s ua. finite s \<and> s \<noteq> {} \<and> s \<subseteq> p \<and> setsum ua s = 1 \<and> (\<Sum>v\<in>s. ua v *\<^sub>R v) = u *\<^sub>R x + v *\<^sub>R y"
   3.232 -      apply(rule_tac x="sx \<union> sy" in exI)
   3.233 -      apply(rule_tac x="\<lambda>a. (if a\<in>sx then u * ux a else 0) + (if a\<in>sy then v * uy a else 0)" in exI)
   3.234 -      unfolding scaleR_left_distrib setsum_addf if_smult scaleR_zero_left  ** setsum_restrict_set[OF xy, THEN sym]
   3.235 -      unfolding scaleR_scaleR[THEN sym] scaleR_right.setsum [symmetric] and setsum_right_distrib[THEN sym]
   3.236 -      unfolding x y using x(1-3) y(1-3) uv by simp qed qed
   3.237 -
   3.238 -lemma affine_hull_finite:
   3.239 -  assumes "finite s"
   3.240 -  shows "affine hull s = {y. \<exists>u. setsum u s = 1 \<and> setsum (\<lambda>v. u v *\<^sub>R v) s = y}"
   3.241 -  unfolding affine_hull_explicit and expand_set_eq and mem_Collect_eq apply (rule,rule)
   3.242 -  apply(erule exE)+ apply(erule conjE)+ defer apply(erule exE) apply(erule conjE) proof-
   3.243 -  fix x u assume "setsum u s = 1" "(\<Sum>v\<in>s. u v *\<^sub>R v) = x"
   3.244 -  thus "\<exists>sa u. finite sa \<and> \<not> (\<forall>x. (x \<in> sa) = (x \<in> {})) \<and> sa \<subseteq> s \<and> setsum u sa = 1 \<and> (\<Sum>v\<in>sa. u v *\<^sub>R v) = x"
   3.245 -    apply(rule_tac x=s in exI, rule_tac x=u in exI) using assms by auto
   3.246 -next
   3.247 -  fix x t u assume "t \<subseteq> s" hence *:"s \<inter> t = t" by auto
   3.248 -  assume "finite t" "\<not> (\<forall>x. (x \<in> t) = (x \<in> {}))" "setsum u t = 1" "(\<Sum>v\<in>t. u v *\<^sub>R v) = x"
   3.249 -  thus "\<exists>u. setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = x" apply(rule_tac x="\<lambda>x. if x\<in>t then u x else 0" in exI)
   3.250 -    unfolding if_smult scaleR_zero_left and setsum_restrict_set[OF assms, THEN sym] and * by auto qed
   3.251 -
   3.252 -subsection {* Stepping theorems and hence small special cases. *}
   3.253 -
   3.254 -lemma affine_hull_empty[simp]: "affine hull {} = {}"
   3.255 -  apply(rule hull_unique) unfolding mem_def by auto
   3.256 -
   3.257 -lemma affine_hull_finite_step:
   3.258 -  fixes y :: "'a::real_vector"
   3.259 -  shows "(\<exists>u. setsum u {} = w \<and> setsum (\<lambda>x. u x *\<^sub>R x) {} = y) \<longleftrightarrow> w = 0 \<and> y = 0" (is ?th1)
   3.260 -  "finite s \<Longrightarrow> (\<exists>u. setsum u (insert a s) = w \<and> setsum (\<lambda>x. u x *\<^sub>R x) (insert a s) = y) \<longleftrightarrow>
   3.261 -                (\<exists>v u. setsum u s = w - v \<and> setsum (\<lambda>x. u x *\<^sub>R x) s = y - v *\<^sub>R a)" (is "?as \<Longrightarrow> (?lhs = ?rhs)")
   3.262 -proof-
   3.263 -  show ?th1 by simp
   3.264 -  assume ?as 
   3.265 -  { assume ?lhs
   3.266 -    then obtain u where u:"setsum u (insert a s) = w \<and> (\<Sum>x\<in>insert a s. u x *\<^sub>R x) = y" by auto
   3.267 -    have ?rhs proof(cases "a\<in>s")
   3.268 -      case True hence *:"insert a s = s" by auto
   3.269 -      show ?thesis using u[unfolded *] apply(rule_tac x=0 in exI) by auto
   3.270 -    next
   3.271 -      case False thus ?thesis apply(rule_tac x="u a" in exI) using u and `?as` by auto 
   3.272 -    qed  } moreover
   3.273 -  { assume ?rhs
   3.274 -    then obtain v u where vu:"setsum u s = w - v"  "(\<Sum>x\<in>s. u x *\<^sub>R x) = y - v *\<^sub>R a" by auto
   3.275 -    have *:"\<And>x M. (if x = a then v else M) *\<^sub>R x = (if x = a then v *\<^sub>R x else M *\<^sub>R x)" by auto
   3.276 -    have ?lhs proof(cases "a\<in>s")
   3.277 -      case True thus ?thesis
   3.278 -        apply(rule_tac x="\<lambda>x. (if x=a then v else 0) + u x" in exI)
   3.279 -        unfolding setsum_clauses(2)[OF `?as`]  apply simp
   3.280 -        unfolding scaleR_left_distrib and setsum_addf 
   3.281 -        unfolding vu and * and scaleR_zero_left
   3.282 -        by (auto simp add: setsum_delta[OF `?as`])
   3.283 -    next
   3.284 -      case False 
   3.285 -      hence **:"\<And>x. x \<in> s \<Longrightarrow> u x = (if x = a then v else u x)"
   3.286 -               "\<And>x. x \<in> s \<Longrightarrow> u x *\<^sub>R x = (if x = a then v *\<^sub>R x else u x *\<^sub>R x)" by auto
   3.287 -      from False show ?thesis
   3.288 -        apply(rule_tac x="\<lambda>x. if x=a then v else u x" in exI)
   3.289 -        unfolding setsum_clauses(2)[OF `?as`] and * using vu
   3.290 -        using setsum_cong2[of s "\<lambda>x. u x *\<^sub>R x" "\<lambda>x. if x = a then v *\<^sub>R x else u x *\<^sub>R x", OF **(2)]
   3.291 -        using setsum_cong2[of s u "\<lambda>x. if x = a then v else u x", OF **(1)] by auto  
   3.292 -    qed }
   3.293 -  ultimately show "?lhs = ?rhs" by blast
   3.294 -qed
   3.295 -
   3.296 -lemma affine_hull_2:
   3.297 -  fixes a b :: "'a::real_vector"
   3.298 -  shows "affine hull {a,b} = {u *\<^sub>R a + v *\<^sub>R b| u v. (u + v = 1)}" (is "?lhs = ?rhs")
   3.299 -proof-
   3.300 -  have *:"\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::real)" 
   3.301 -         "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::'a)" by auto
   3.302 -  have "?lhs = {y. \<exists>u. setsum u {a, b} = 1 \<and> (\<Sum>v\<in>{a, b}. u v *\<^sub>R v) = y}"
   3.303 -    using affine_hull_finite[of "{a,b}"] by auto
   3.304 -  also have "\<dots> = {y. \<exists>v u. u b = 1 - v \<and> u b *\<^sub>R b = y - v *\<^sub>R a}"
   3.305 -    by(simp add: affine_hull_finite_step(2)[of "{b}" a]) 
   3.306 -  also have "\<dots> = ?rhs" unfolding * by auto
   3.307 -  finally show ?thesis by auto
   3.308 -qed
   3.309 -
   3.310 -lemma affine_hull_3:
   3.311 -  fixes a b c :: "'a::real_vector"
   3.312 -  shows "affine hull {a,b,c} = { u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c| u v w. u + v + w = 1}" (is "?lhs = ?rhs")
   3.313 -proof-
   3.314 -  have *:"\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::real)" 
   3.315 -         "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::'a)" by auto
   3.316 -  show ?thesis apply(simp add: affine_hull_finite affine_hull_finite_step)
   3.317 -    unfolding * apply auto
   3.318 -    apply(rule_tac x=v in exI) apply(rule_tac x=va in exI) apply auto
   3.319 -    apply(rule_tac x=u in exI) by(auto intro!: exI)
   3.320 -qed
   3.321 -
   3.322 -subsection {* Some relations between affine hull and subspaces. *}
   3.323 -
   3.324 -lemma affine_hull_insert_subset_span:
   3.325 -  fixes a :: "real ^ _"
   3.326 -  shows "affine hull (insert a s) \<subseteq> {a + v| v . v \<in> span {x - a | x . x \<in> s}}"
   3.327 -  unfolding subset_eq Ball_def unfolding affine_hull_explicit span_explicit mem_Collect_eq smult_conv_scaleR
   3.328 -  apply(rule,rule) apply(erule exE)+ apply(erule conjE)+ proof-
   3.329 -  fix x t u assume as:"finite t" "t \<noteq> {}" "t \<subseteq> insert a s" "setsum u t = 1" "(\<Sum>v\<in>t. u v *\<^sub>R v) = x"
   3.330 -  have "(\<lambda>x. x - a) ` (t - {a}) \<subseteq> {x - a |x. x \<in> s}" using as(3) by auto
   3.331 -  thus "\<exists>v. x = a + v \<and> (\<exists>S u. finite S \<and> S \<subseteq> {x - a |x. x \<in> s} \<and> (\<Sum>v\<in>S. u v *\<^sub>R v) = v)"
   3.332 -    apply(rule_tac x="x - a" in exI)
   3.333 -    apply (rule conjI, simp)
   3.334 -    apply(rule_tac x="(\<lambda>x. x - a) ` (t - {a})" in exI)
   3.335 -    apply(rule_tac x="\<lambda>x. u (x + a)" in exI)
   3.336 -    apply (rule conjI) using as(1) apply simp
   3.337 -    apply (erule conjI)
   3.338 -    using as(1)
   3.339 -    apply (simp add: setsum_reindex[unfolded inj_on_def] scaleR_right_diff_distrib setsum_subtractf scaleR_left.setsum[THEN sym] setsum_diff1 scaleR_left_diff_distrib)
   3.340 -    unfolding as by simp qed
   3.341 -
   3.342 -lemma affine_hull_insert_span:
   3.343 -  fixes a :: "real ^ _"
   3.344 -  assumes "a \<notin> s"
   3.345 -  shows "affine hull (insert a s) =
   3.346 -            {a + v | v . v \<in> span {x - a | x.  x \<in> s}}"
   3.347 -  apply(rule, rule affine_hull_insert_subset_span) unfolding subset_eq Ball_def
   3.348 -  unfolding affine_hull_explicit and mem_Collect_eq proof(rule,rule,erule exE,erule conjE)
   3.349 -  fix y v assume "y = a + v" "v \<in> span {x - a |x. x \<in> s}"
   3.350 -  then obtain t u where obt:"finite t" "t \<subseteq> {x - a |x. x \<in> s}" "a + (\<Sum>v\<in>t. u v *\<^sub>R v) = y" unfolding span_explicit smult_conv_scaleR by auto
   3.351 -  def f \<equiv> "(\<lambda>x. x + a) ` t"
   3.352 -  have f:"finite f" "f \<subseteq> s" "(\<Sum>v\<in>f. u (v - a) *\<^sub>R (v - a)) = y - a" unfolding f_def using obt 
   3.353 -    by(auto simp add: setsum_reindex[unfolded inj_on_def])
   3.354 -  have *:"f \<inter> {a} = {}" "f \<inter> - {a} = f" using f(2) assms by auto
   3.355 -  show "\<exists>sa u. finite sa \<and> sa \<noteq> {} \<and> sa \<subseteq> insert a s \<and> setsum u sa = 1 \<and> (\<Sum>v\<in>sa. u v *\<^sub>R v) = y"
   3.356 -    apply(rule_tac x="insert a f" in exI)
   3.357 -    apply(rule_tac x="\<lambda>x. if x=a then 1 - setsum (\<lambda>x. u (x - a)) f else u (x - a)" in exI)
   3.358 -    using assms and f unfolding setsum_clauses(2)[OF f(1)] and if_smult
   3.359 -    unfolding setsum_cases[OF f(1), of "{a}", unfolded singleton_iff] and *
   3.360 -    by (auto simp add: setsum_subtractf scaleR_left.setsum algebra_simps) qed
   3.361 -
   3.362 -lemma affine_hull_span:
   3.363 -  fixes a :: "real ^ _"
   3.364 -  assumes "a \<in> s"
   3.365 -  shows "affine hull s = {a + v | v. v \<in> span {x - a | x. x \<in> s - {a}}}"
   3.366 -  using affine_hull_insert_span[of a "s - {a}", unfolded insert_Diff[OF assms]] by auto
   3.367 -
   3.368 -subsection {* Convexity. *}
   3.369 -
   3.370 -definition
   3.371 -  convex :: "'a::real_vector set \<Rightarrow> bool" where
   3.372 -  "convex s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u\<ge>0. \<forall>v\<ge>0. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s)"
   3.373 -
   3.374 -lemma convex_alt: "convex s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u. 0 \<le> u \<and> u \<le> 1 \<longrightarrow> ((1 - u) *\<^sub>R x + u *\<^sub>R y) \<in> s)"
   3.375 -proof- have *:"\<And>u v::real. u + v = 1 \<longleftrightarrow> u = 1 - v" by auto
   3.376 -  show ?thesis unfolding convex_def apply auto
   3.377 -    apply(erule_tac x=x in ballE) apply(erule_tac x=y in ballE) apply(erule_tac x="1 - u" in allE)
   3.378 -    by (auto simp add: *) qed
   3.379 -
   3.380 -lemma mem_convex:
   3.381 -  assumes "convex s" "a \<in> s" "b \<in> s" "0 \<le> u" "u \<le> 1"
   3.382 -  shows "((1 - u) *\<^sub>R a + u *\<^sub>R b) \<in> s"
   3.383 -  using assms unfolding convex_alt by auto
   3.384 -
   3.385 -lemma convex_empty[intro]: "convex {}"
   3.386 -  unfolding convex_def by simp
   3.387 -
   3.388 -lemma convex_singleton[intro]: "convex {a}"
   3.389 -  unfolding convex_def by (auto simp add:scaleR_left_distrib[THEN sym])
   3.390 -
   3.391 -lemma convex_UNIV[intro]: "convex UNIV"
   3.392 -  unfolding convex_def by auto
   3.393 -
   3.394 -lemma convex_Inter: "(\<forall>s\<in>f. convex s) ==> convex(\<Inter> f)"
   3.395 -  unfolding convex_def by auto
   3.396 -
   3.397 -lemma convex_Int: "convex s \<Longrightarrow> convex t \<Longrightarrow> convex (s \<inter> t)"
   3.398 -  unfolding convex_def by auto
   3.399 -
   3.400 -lemma convex_halfspace_le: "convex {x. inner a x \<le> b}"
   3.401 -  unfolding convex_def apply auto
   3.402 -  unfolding inner_add inner_scaleR
   3.403 -  by (metis real_convex_bound_le)
   3.404 -
   3.405 -lemma convex_halfspace_ge: "convex {x. inner a x \<ge> b}"
   3.406 -proof- have *:"{x. inner a x \<ge> b} = {x. inner (-a) x \<le> -b}" by auto
   3.407 -  show ?thesis apply(unfold *) using convex_halfspace_le[of "-a" "-b"] by auto qed
   3.408 -
   3.409 -lemma convex_hyperplane: "convex {x. inner a x = b}"
   3.410 -proof-
   3.411 -  have *:"{x. inner a x = b} = {x. inner a x \<le> b} \<inter> {x. inner a x \<ge> b}" by auto
   3.412 -  show ?thesis unfolding * apply(rule convex_Int)
   3.413 -    using convex_halfspace_le convex_halfspace_ge by auto
   3.414 -qed
   3.415 -
   3.416 -lemma convex_halfspace_lt: "convex {x. inner a x < b}"
   3.417 -  unfolding convex_def
   3.418 -  by(auto simp add: real_convex_bound_lt inner_add)
   3.419 -
   3.420 -lemma convex_halfspace_gt: "convex {x. inner a x > b}"
   3.421 -   using convex_halfspace_lt[of "-a" "-b"] by auto
   3.422 -
   3.423 -lemma convex_positive_orthant: "convex {x::real^'n::finite. (\<forall>i. 0 \<le> x$i)}"
   3.424 -  unfolding convex_def apply auto apply(erule_tac x=i in allE)+
   3.425 -  apply(rule add_nonneg_nonneg) by(auto simp add: mult_nonneg_nonneg)
   3.426 -
   3.427 -subsection {* Explicit expressions for convexity in terms of arbitrary sums. *}
   3.428 -
   3.429 -lemma convex: "convex s \<longleftrightarrow>
   3.430 -  (\<forall>(k::nat) u x. (\<forall>i. 1\<le>i \<and> i\<le>k \<longrightarrow> 0 \<le> u i \<and> x i \<in>s) \<and> (setsum u {1..k} = 1)
   3.431 -           \<longrightarrow> setsum (\<lambda>i. u i *\<^sub>R x i) {1..k} \<in> s)"
   3.432 -  unfolding convex_def apply rule apply(rule allI)+ defer apply(rule ballI)+ apply(rule allI)+ proof(rule,rule,rule,rule)
   3.433 -  fix x y u v assume as:"\<forall>(k::nat) u x. (\<forall>i. 1 \<le> i \<and> i \<le> k \<longrightarrow> 0 \<le> u i \<and> x i \<in> s) \<and> setsum u {1..k} = 1 \<longrightarrow> (\<Sum>i = 1..k. u i *\<^sub>R x i) \<in> s"
   3.434 -    "x \<in> s" "y \<in> s" "0 \<le> u" "0 \<le> v" "u + v = (1::real)"
   3.435 -  show "u *\<^sub>R x + v *\<^sub>R y \<in> s" using as(1)[THEN spec[where x=2], THEN spec[where x="\<lambda>n. if n=1 then u else v"], THEN spec[where x="\<lambda>n. if n=1 then x else y"]] and as(2-)
   3.436 -    by (auto simp add: setsum_head_Suc) 
   3.437 -next
   3.438 -  fix k u x assume as:"\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u\<ge>0. \<forall>v\<ge>0. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s" 
   3.439 -  show "(\<forall>i::nat. 1 \<le> i \<and> i \<le> k \<longrightarrow> 0 \<le> u i \<and> x i \<in> s) \<and> setsum u {1..k} = 1 \<longrightarrow> (\<Sum>i = 1..k. u i *\<^sub>R x i) \<in> s" apply(rule,erule conjE) proof(induct k arbitrary: u)
   3.440 -  case (Suc k) show ?case proof(cases "u (Suc k) = 1")
   3.441 -    case True hence "(\<Sum>i = Suc 0..k. u i *\<^sub>R x i) = 0" apply(rule_tac setsum_0') apply(rule ccontr) unfolding ball_simps apply(erule bexE) proof-
   3.442 -      fix i assume i:"i \<in> {Suc 0..k}" "u i *\<^sub>R x i \<noteq> 0"
   3.443 -      hence ui:"u i \<noteq> 0" by auto
   3.444 -      hence "setsum (\<lambda>k. if k=i then u i else 0) {1 .. k} \<le> setsum u {1 .. k}" apply(rule_tac setsum_mono) using Suc(2) by auto
   3.445 -      hence "setsum u {1 .. k} \<ge> u i" using i(1) by(auto simp add: setsum_delta) 
   3.446 -      hence "setsum u {1 .. k} > 0"  using ui apply(rule_tac less_le_trans[of _ "u i"]) using Suc(2)[THEN spec[where x=i]] and i(1) by auto
   3.447 -      thus False using Suc(3) unfolding setsum_cl_ivl_Suc and True by simp qed
   3.448 -    thus ?thesis unfolding setsum_cl_ivl_Suc using True and Suc(2) by auto
   3.449 -  next
   3.450 -    have *:"setsum u {1..k} = 1 - u (Suc k)" using Suc(3)[unfolded setsum_cl_ivl_Suc] by auto
   3.451 -    have **:"u (Suc k) \<le> 1" apply(rule ccontr) unfolding not_le using Suc(3) using setsum_nonneg[of "{1..k}" u] using Suc(2) by auto
   3.452 -    have ***:"\<And>i k. (u i / (1 - u (Suc k))) *\<^sub>R x i = (inverse (1 - u (Suc k))) *\<^sub>R (u i *\<^sub>R x i)" unfolding real_divide_def by (auto simp add: algebra_simps)
   3.453 -    case False hence nn:"1 - u (Suc k) \<noteq> 0" by auto
   3.454 -    have "(\<Sum>i = 1..k. (u i / (1 - u (Suc k))) *\<^sub>R x i) \<in> s" apply(rule Suc(1)) unfolding setsum_divide_distrib[THEN sym] and *
   3.455 -      apply(rule_tac allI) apply(rule,rule) apply(rule divide_nonneg_pos) using nn Suc(2) ** by auto
   3.456 -    hence "(1 - u (Suc k)) *\<^sub>R (\<Sum>i = 1..k. (u i / (1 - u (Suc k))) *\<^sub>R x i) + u (Suc k) *\<^sub>R x (Suc k) \<in> s"
   3.457 -      apply(rule as[THEN bspec, THEN bspec, THEN spec, THEN mp, THEN spec, THEN mp, THEN mp]) using Suc(2)[THEN spec[where x="Suc k"]] and ** by auto
   3.458 -    thus ?thesis unfolding setsum_cl_ivl_Suc and *** and scaleR_right.setsum [symmetric] using nn by auto qed qed auto qed
   3.459 -
   3.460 -
   3.461 -lemma convex_explicit:
   3.462 -  fixes s :: "'a::real_vector set"
   3.463 -  shows "convex s \<longleftrightarrow>
   3.464 -  (\<forall>t u. finite t \<and> t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and> setsum u t = 1 \<longrightarrow> setsum (\<lambda>x. u x *\<^sub>R x) t \<in> s)"
   3.465 -  unfolding convex_def apply(rule,rule,rule) apply(subst imp_conjL,rule) defer apply(rule,rule,rule,rule,rule,rule,rule) proof-
   3.466 -  fix x y u v assume as:"\<forall>t u. finite t \<and> t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and> setsum u t = 1 \<longrightarrow> (\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s" "x \<in> s" "y \<in> s" "0 \<le> u" "0 \<le> v" "u + v = (1::real)"
   3.467 -  show "u *\<^sub>R x + v *\<^sub>R y \<in> s" proof(cases "x=y")
   3.468 -    case True show ?thesis unfolding True and scaleR_left_distrib[THEN sym] using as(3,6) by auto next
   3.469 -    case False thus ?thesis using as(1)[THEN spec[where x="{x,y}"], THEN spec[where x="\<lambda>z. if z=x then u else v"]] and as(2-) by auto qed
   3.470 -next 
   3.471 -  fix t u assume asm:"\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u\<ge>0. \<forall>v\<ge>0. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s" "finite (t::'a set)"
   3.472 -  (*"finite t" "t \<subseteq> s" "\<forall>x\<in>t. (0::real) \<le> u x" "setsum u t = 1"*)
   3.473 -  from this(2) have "\<forall>u. t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and> setsum u t = 1 \<longrightarrow> (\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s" apply(induct_tac t rule:finite_induct)
   3.474 -    prefer 3 apply (rule,rule) apply(erule conjE)+ proof-
   3.475 -    fix x f u assume ind:"\<forall>u. f \<subseteq> s \<and> (\<forall>x\<in>f. 0 \<le> u x) \<and> setsum u f = 1 \<longrightarrow> (\<Sum>x\<in>f. u x *\<^sub>R x) \<in> s"
   3.476 -    assume as:"finite f" "x \<notin> f" "insert x f \<subseteq> s" "\<forall>x\<in>insert x f. 0 \<le> u x" "setsum u (insert x f) = (1::real)"
   3.477 -    show "(\<Sum>x\<in>insert x f. u x *\<^sub>R x) \<in> s" proof(cases "u x = 1")
   3.478 -      case True hence "setsum (\<lambda>x. u x *\<^sub>R x) f = 0" apply(rule_tac setsum_0') apply(rule ccontr) unfolding ball_simps apply(erule bexE) proof-
   3.479 -        fix y assume y:"y \<in> f" "u y *\<^sub>R y \<noteq> 0"
   3.480 -        hence uy:"u y \<noteq> 0" by auto
   3.481 -        hence "setsum (\<lambda>k. if k=y then u y else 0) f \<le> setsum u f" apply(rule_tac setsum_mono) using as(4) by auto
   3.482 -        hence "setsum u f \<ge> u y" using y(1) and as(1) by(auto simp add: setsum_delta) 
   3.483 -        hence "setsum u f > 0" using uy apply(rule_tac less_le_trans[of _ "u y"]) using as(4) and y(1) by auto
   3.484 -        thus False using as(2,5) unfolding setsum_clauses(2)[OF as(1)] and True by auto qed
   3.485 -      thus ?thesis unfolding setsum_clauses(2)[OF as(1)] using as(2,3) unfolding True by auto
   3.486 -    next
   3.487 -      have *:"setsum u f = setsum u (insert x f) - u x" using as(2) unfolding setsum_clauses(2)[OF as(1)] by auto
   3.488 -      have **:"u x \<le> 1" apply(rule ccontr) unfolding not_le using as(5)[unfolded setsum_clauses(2)[OF as(1)]] and as(2)
   3.489 -        using setsum_nonneg[of f u] and as(4) by auto
   3.490 -      case False hence "inverse (1 - u x) *\<^sub>R (\<Sum>x\<in>f. u x *\<^sub>R x) \<in> s" unfolding scaleR_right.setsum and scaleR_scaleR
   3.491 -        apply(rule_tac ind[THEN spec, THEN mp]) apply rule defer apply rule apply rule apply(rule mult_nonneg_nonneg)
   3.492 -        unfolding setsum_right_distrib[THEN sym] and * using as and ** by auto
   3.493 -      hence "u x *\<^sub>R x + (1 - u x) *\<^sub>R ((inverse (1 - u x)) *\<^sub>R setsum (\<lambda>x. u x *\<^sub>R x) f) \<in>s" 
   3.494 -        apply(rule_tac asm(1)[THEN bspec, THEN bspec, THEN spec, THEN mp, THEN spec, THEN mp, THEN mp]) using as and ** False by auto 
   3.495 -      thus ?thesis unfolding setsum_clauses(2)[OF as(1)] using as(2) and False by auto qed
   3.496 -  qed auto thus "t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and> setsum u t = 1 \<longrightarrow> (\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s" by auto
   3.497 -qed
   3.498 -
   3.499 -lemma convex_finite: assumes "finite s"
   3.500 -  shows "convex s \<longleftrightarrow> (\<forall>u. (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1
   3.501 -                      \<longrightarrow> setsum (\<lambda>x. u x *\<^sub>R x) s \<in> s)"
   3.502 -  unfolding convex_explicit apply(rule, rule, rule) defer apply(rule,rule,rule)apply(erule conjE)+ proof-
   3.503 -  fix t u assume as:"\<forall>u. (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<longrightarrow> (\<Sum>x\<in>s. u x *\<^sub>R x) \<in> s" " finite t" "t \<subseteq> s" "\<forall>x\<in>t. 0 \<le> u x" "setsum u t = (1::real)"
   3.504 -  have *:"s \<inter> t = t" using as(3) by auto
   3.505 -  show "(\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s" using as(1)[THEN spec[where x="\<lambda>x. if x\<in>t then u x else 0"]]
   3.506 -    unfolding if_smult and setsum_cases[OF assms] and * using as(2-) by auto
   3.507 -qed (erule_tac x=s in allE, erule_tac x=u in allE, auto)
   3.508 -
   3.509 -subsection {* Cones. *}
   3.510 -
   3.511 -definition
   3.512 -  cone :: "'a::real_vector set \<Rightarrow> bool" where
   3.513 -  "cone s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>c\<ge>0. (c *\<^sub>R x) \<in> s)"
   3.514 -
   3.515 -lemma cone_empty[intro, simp]: "cone {}"
   3.516 -  unfolding cone_def by auto
   3.517 -
   3.518 -lemma cone_univ[intro, simp]: "cone UNIV"
   3.519 -  unfolding cone_def by auto