src/HOL/Analysis/Path_Connected.thy
author wenzelm
Mon Mar 25 17:21:26 2019 +0100 (2 months ago)
changeset 69981 3dced198b9ec
parent 69939 812ce526da33
child 69986 f2d327275065
permissions -rw-r--r--
more strict AFP properties;
     1 (*  Title:      HOL/Analysis/Path_Connected.thy
     2     Authors:    LC Paulson and Robert Himmelmann (TU Muenchen), based on material from HOL Light
     3 *)
     4 
     5 section \<open>Path-Connectedness\<close>
     6 
     7 theory Path_Connected
     8   imports Starlike
     9 begin
    10 
    11 subsection \<open>Paths and Arcs\<close>
    12 
    13 definition%important path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    14   where "path g \<longleftrightarrow> continuous_on {0..1} g"
    15 
    16 definition%important pathstart :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> 'a"
    17   where "pathstart g = g 0"
    18 
    19 definition%important pathfinish :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> 'a"
    20   where "pathfinish g = g 1"
    21 
    22 definition%important path_image :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> 'a set"
    23   where "path_image g = g ` {0 .. 1}"
    24 
    25 definition%important reversepath :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> real \<Rightarrow> 'a"
    26   where "reversepath g = (\<lambda>x. g(1 - x))"
    27 
    28 definition%important joinpaths :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> (real \<Rightarrow> 'a) \<Rightarrow> real \<Rightarrow> 'a"
    29     (infixr "+++" 75)
    30   where "g1 +++ g2 = (\<lambda>x. if x \<le> 1/2 then g1 (2 * x) else g2 (2 * x - 1))"
    31 
    32 definition%important simple_path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    33   where "simple_path g \<longleftrightarrow>
    34      path g \<and> (\<forall>x\<in>{0..1}. \<forall>y\<in>{0..1}. g x = g y \<longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0)"
    35 
    36 definition%important arc :: "(real \<Rightarrow> 'a :: topological_space) \<Rightarrow> bool"
    37   where "arc g \<longleftrightarrow> path g \<and> inj_on g {0..1}"
    38 
    39 
    40 subsection%unimportant\<open>Invariance theorems\<close>
    41 
    42 lemma path_eq: "path p \<Longrightarrow> (\<And>t. t \<in> {0..1} \<Longrightarrow> p t = q t) \<Longrightarrow> path q"
    43   using continuous_on_eq path_def by blast
    44 
    45 lemma path_continuous_image: "path g \<Longrightarrow> continuous_on (path_image g) f \<Longrightarrow> path(f \<circ> g)"
    46   unfolding path_def path_image_def
    47   using continuous_on_compose by blast
    48 
    49 lemma path_translation_eq:
    50   fixes g :: "real \<Rightarrow> 'a :: real_normed_vector"
    51   shows "path((\<lambda>x. a + x) \<circ> g) = path g"
    52 proof -
    53   have g: "g = (\<lambda>x. -a + x) \<circ> ((\<lambda>x. a + x) \<circ> g)"
    54     by (rule ext) simp
    55   show ?thesis
    56     unfolding path_def
    57     apply safe
    58     apply (subst g)
    59     apply (rule continuous_on_compose)
    60     apply (auto intro: continuous_intros)
    61     done
    62 qed
    63 
    64 lemma path_linear_image_eq:
    65   fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
    66    assumes "linear f" "inj f"
    67      shows "path(f \<circ> g) = path g"
    68 proof -
    69   from linear_injective_left_inverse [OF assms]
    70   obtain h where h: "linear h" "h \<circ> f = id"
    71     by blast
    72   then have g: "g = h \<circ> (f \<circ> g)"
    73     by (metis comp_assoc id_comp)
    74   show ?thesis
    75     unfolding path_def
    76     using h assms
    77     by (metis g continuous_on_compose linear_continuous_on linear_conv_bounded_linear)
    78 qed
    79 
    80 lemma pathstart_translation: "pathstart((\<lambda>x. a + x) \<circ> g) = a + pathstart g"
    81   by (simp add: pathstart_def)
    82 
    83 lemma pathstart_linear_image_eq: "linear f \<Longrightarrow> pathstart(f \<circ> g) = f(pathstart g)"
    84   by (simp add: pathstart_def)
    85 
    86 lemma pathfinish_translation: "pathfinish((\<lambda>x. a + x) \<circ> g) = a + pathfinish g"
    87   by (simp add: pathfinish_def)
    88 
    89 lemma pathfinish_linear_image: "linear f \<Longrightarrow> pathfinish(f \<circ> g) = f(pathfinish g)"
    90   by (simp add: pathfinish_def)
    91 
    92 lemma path_image_translation: "path_image((\<lambda>x. a + x) \<circ> g) = (\<lambda>x. a + x) ` (path_image g)"
    93   by (simp add: image_comp path_image_def)
    94 
    95 lemma path_image_linear_image: "linear f \<Longrightarrow> path_image(f \<circ> g) = f ` (path_image g)"
    96   by (simp add: image_comp path_image_def)
    97 
    98 lemma reversepath_translation: "reversepath((\<lambda>x. a + x) \<circ> g) = (\<lambda>x. a + x) \<circ> reversepath g"
    99   by (rule ext) (simp add: reversepath_def)
   100 
   101 lemma reversepath_linear_image: "linear f \<Longrightarrow> reversepath(f \<circ> g) = f \<circ> reversepath g"
   102   by (rule ext) (simp add: reversepath_def)
   103 
   104 lemma joinpaths_translation:
   105     "((\<lambda>x. a + x) \<circ> g1) +++ ((\<lambda>x. a + x) \<circ> g2) = (\<lambda>x. a + x) \<circ> (g1 +++ g2)"
   106   by (rule ext) (simp add: joinpaths_def)
   107 
   108 lemma joinpaths_linear_image: "linear f \<Longrightarrow> (f \<circ> g1) +++ (f \<circ> g2) = f \<circ> (g1 +++ g2)"
   109   by (rule ext) (simp add: joinpaths_def)
   110 
   111 lemma simple_path_translation_eq:
   112   fixes g :: "real \<Rightarrow> 'a::euclidean_space"
   113   shows "simple_path((\<lambda>x. a + x) \<circ> g) = simple_path g"
   114   by (simp add: simple_path_def path_translation_eq)
   115 
   116 lemma simple_path_linear_image_eq:
   117   fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
   118   assumes "linear f" "inj f"
   119     shows "simple_path(f \<circ> g) = simple_path g"
   120   using assms inj_on_eq_iff [of f]
   121   by (auto simp: path_linear_image_eq simple_path_def path_translation_eq)
   122 
   123 lemma arc_translation_eq:
   124   fixes g :: "real \<Rightarrow> 'a::euclidean_space"
   125   shows "arc((\<lambda>x. a + x) \<circ> g) = arc g"
   126   by (auto simp: arc_def inj_on_def path_translation_eq)
   127 
   128 lemma arc_linear_image_eq:
   129   fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
   130    assumes "linear f" "inj f"
   131      shows  "arc(f \<circ> g) = arc g"
   132   using assms inj_on_eq_iff [of f]
   133   by (auto simp: arc_def inj_on_def path_linear_image_eq)
   134 
   135 
   136 subsection%unimportant\<open>Basic lemmas about paths\<close>
   137 
   138 lemma pathin_iff_path_real [simp]: "pathin euclideanreal g \<longleftrightarrow> path g"
   139   by (simp add: pathin_def path_def)
   140 
   141 lemma continuous_on_path: "path f \<Longrightarrow> t \<subseteq> {0..1} \<Longrightarrow> continuous_on t f"
   142   using continuous_on_subset path_def by blast
   143 
   144 lemma arc_imp_simple_path: "arc g \<Longrightarrow> simple_path g"
   145   by (simp add: arc_def inj_on_def simple_path_def)
   146 
   147 lemma arc_imp_path: "arc g \<Longrightarrow> path g"
   148   using arc_def by blast
   149 
   150 lemma arc_imp_inj_on: "arc g \<Longrightarrow> inj_on g {0..1}"
   151   by (auto simp: arc_def)
   152 
   153 lemma simple_path_imp_path: "simple_path g \<Longrightarrow> path g"
   154   using simple_path_def by blast
   155 
   156 lemma simple_path_cases: "simple_path g \<Longrightarrow> arc g \<or> pathfinish g = pathstart g"
   157   unfolding simple_path_def arc_def inj_on_def pathfinish_def pathstart_def
   158   by force
   159 
   160 lemma simple_path_imp_arc: "simple_path g \<Longrightarrow> pathfinish g \<noteq> pathstart g \<Longrightarrow> arc g"
   161   using simple_path_cases by auto
   162 
   163 lemma arc_distinct_ends: "arc g \<Longrightarrow> pathfinish g \<noteq> pathstart g"
   164   unfolding arc_def inj_on_def pathfinish_def pathstart_def
   165   by fastforce
   166 
   167 lemma arc_simple_path: "arc g \<longleftrightarrow> simple_path g \<and> pathfinish g \<noteq> pathstart g"
   168   using arc_distinct_ends arc_imp_simple_path simple_path_cases by blast
   169 
   170 lemma simple_path_eq_arc: "pathfinish g \<noteq> pathstart g \<Longrightarrow> (simple_path g = arc g)"
   171   by (simp add: arc_simple_path)
   172 
   173 lemma path_image_const [simp]: "path_image (\<lambda>t. a) = {a}"
   174   by (force simp: path_image_def)
   175 
   176 lemma path_image_nonempty [simp]: "path_image g \<noteq> {}"
   177   unfolding path_image_def image_is_empty box_eq_empty
   178   by auto
   179 
   180 lemma pathstart_in_path_image[intro]: "pathstart g \<in> path_image g"
   181   unfolding pathstart_def path_image_def
   182   by auto
   183 
   184 lemma pathfinish_in_path_image[intro]: "pathfinish g \<in> path_image g"
   185   unfolding pathfinish_def path_image_def
   186   by auto
   187 
   188 lemma connected_path_image[intro]: "path g \<Longrightarrow> connected (path_image g)"
   189   unfolding path_def path_image_def
   190   using connected_continuous_image connected_Icc by blast
   191 
   192 lemma compact_path_image[intro]: "path g \<Longrightarrow> compact (path_image g)"
   193   unfolding path_def path_image_def
   194   using compact_continuous_image connected_Icc by blast
   195 
   196 lemma reversepath_reversepath[simp]: "reversepath (reversepath g) = g"
   197   unfolding reversepath_def
   198   by auto
   199 
   200 lemma pathstart_reversepath[simp]: "pathstart (reversepath g) = pathfinish g"
   201   unfolding pathstart_def reversepath_def pathfinish_def
   202   by auto
   203 
   204 lemma pathfinish_reversepath[simp]: "pathfinish (reversepath g) = pathstart g"
   205   unfolding pathstart_def reversepath_def pathfinish_def
   206   by auto
   207 
   208 lemma pathstart_join[simp]: "pathstart (g1 +++ g2) = pathstart g1"
   209   unfolding pathstart_def joinpaths_def pathfinish_def
   210   by auto
   211 
   212 lemma pathfinish_join[simp]: "pathfinish (g1 +++ g2) = pathfinish g2"
   213   unfolding pathstart_def joinpaths_def pathfinish_def
   214   by auto
   215 
   216 lemma path_image_reversepath[simp]: "path_image (reversepath g) = path_image g"
   217 proof -
   218   have *: "\<And>g. path_image (reversepath g) \<subseteq> path_image g"
   219     unfolding path_image_def subset_eq reversepath_def Ball_def image_iff
   220     by force
   221   show ?thesis
   222     using *[of g] *[of "reversepath g"]
   223     unfolding reversepath_reversepath
   224     by auto
   225 qed
   226 
   227 lemma path_reversepath [simp]: "path (reversepath g) \<longleftrightarrow> path g"
   228 proof -
   229   have *: "\<And>g. path g \<Longrightarrow> path (reversepath g)"
   230     unfolding path_def reversepath_def
   231     apply (rule continuous_on_compose[unfolded o_def, of _ "\<lambda>x. 1 - x"])
   232     apply (auto intro: continuous_intros continuous_on_subset[of "{0..1}"])
   233     done
   234   show ?thesis
   235     using *[of "reversepath g"] *[of g]
   236     unfolding reversepath_reversepath
   237     by (rule iffI)
   238 qed
   239 
   240 lemma arc_reversepath:
   241   assumes "arc g" shows "arc(reversepath g)"
   242 proof -
   243   have injg: "inj_on g {0..1}"
   244     using assms
   245     by (simp add: arc_def)
   246   have **: "\<And>x y::real. 1-x = 1-y \<Longrightarrow> x = y"
   247     by simp
   248   show ?thesis
   249     using assms  by (clarsimp simp: arc_def intro!: inj_onI) (simp add: inj_onD reversepath_def **)
   250 qed
   251 
   252 lemma simple_path_reversepath: "simple_path g \<Longrightarrow> simple_path (reversepath g)"
   253   apply (simp add: simple_path_def)
   254   apply (force simp: reversepath_def)
   255   done
   256 
   257 lemmas reversepath_simps =
   258   path_reversepath path_image_reversepath pathstart_reversepath pathfinish_reversepath
   259 
   260 lemma path_join[simp]:
   261   assumes "pathfinish g1 = pathstart g2"
   262   shows "path (g1 +++ g2) \<longleftrightarrow> path g1 \<and> path g2"
   263   unfolding path_def pathfinish_def pathstart_def
   264 proof safe
   265   assume cont: "continuous_on {0..1} (g1 +++ g2)"
   266   have g1: "continuous_on {0..1} g1 \<longleftrightarrow> continuous_on {0..1} ((g1 +++ g2) \<circ> (\<lambda>x. x / 2))"
   267     by (intro continuous_on_cong refl) (auto simp: joinpaths_def)
   268   have g2: "continuous_on {0..1} g2 \<longleftrightarrow> continuous_on {0..1} ((g1 +++ g2) \<circ> (\<lambda>x. x / 2 + 1/2))"
   269     using assms
   270     by (intro continuous_on_cong refl) (auto simp: joinpaths_def pathfinish_def pathstart_def)
   271   show "continuous_on {0..1} g1" and "continuous_on {0..1} g2"
   272     unfolding g1 g2
   273     by (auto intro!: continuous_intros continuous_on_subset[OF cont] simp del: o_apply)
   274 next
   275   assume g1g2: "continuous_on {0..1} g1" "continuous_on {0..1} g2"
   276   have 01: "{0 .. 1} = {0..1/2} \<union> {1/2 .. 1::real}"
   277     by auto
   278   {
   279     fix x :: real
   280     assume "0 \<le> x" and "x \<le> 1"
   281     then have "x \<in> (\<lambda>x. x * 2) ` {0..1 / 2}"
   282       by (intro image_eqI[where x="x/2"]) auto
   283   }
   284   note 1 = this
   285   {
   286     fix x :: real
   287     assume "0 \<le> x" and "x \<le> 1"
   288     then have "x \<in> (\<lambda>x. x * 2 - 1) ` {1 / 2..1}"
   289       by (intro image_eqI[where x="x/2 + 1/2"]) auto
   290   }
   291   note 2 = this
   292   show "continuous_on {0..1} (g1 +++ g2)"
   293     using assms
   294     unfolding joinpaths_def 01
   295     apply (intro continuous_on_cases closed_atLeastAtMost g1g2[THEN continuous_on_compose2] continuous_intros)
   296     apply (auto simp: field_simps pathfinish_def pathstart_def intro!: 1 2)
   297     done
   298 qed
   299 
   300 
   301 subsection%unimportant \<open>Path Images\<close>
   302 
   303 lemma bounded_path_image: "path g \<Longrightarrow> bounded(path_image g)"
   304   by (simp add: compact_imp_bounded compact_path_image)
   305 
   306 lemma closed_path_image:
   307   fixes g :: "real \<Rightarrow> 'a::t2_space"
   308   shows "path g \<Longrightarrow> closed(path_image g)"
   309   by (metis compact_path_image compact_imp_closed)
   310 
   311 lemma connected_simple_path_image: "simple_path g \<Longrightarrow> connected(path_image g)"
   312   by (metis connected_path_image simple_path_imp_path)
   313 
   314 lemma compact_simple_path_image: "simple_path g \<Longrightarrow> compact(path_image g)"
   315   by (metis compact_path_image simple_path_imp_path)
   316 
   317 lemma bounded_simple_path_image: "simple_path g \<Longrightarrow> bounded(path_image g)"
   318   by (metis bounded_path_image simple_path_imp_path)
   319 
   320 lemma closed_simple_path_image:
   321   fixes g :: "real \<Rightarrow> 'a::t2_space"
   322   shows "simple_path g \<Longrightarrow> closed(path_image g)"
   323   by (metis closed_path_image simple_path_imp_path)
   324 
   325 lemma connected_arc_image: "arc g \<Longrightarrow> connected(path_image g)"
   326   by (metis connected_path_image arc_imp_path)
   327 
   328 lemma compact_arc_image: "arc g \<Longrightarrow> compact(path_image g)"
   329   by (metis compact_path_image arc_imp_path)
   330 
   331 lemma bounded_arc_image: "arc g \<Longrightarrow> bounded(path_image g)"
   332   by (metis bounded_path_image arc_imp_path)
   333 
   334 lemma closed_arc_image:
   335   fixes g :: "real \<Rightarrow> 'a::t2_space"
   336   shows "arc g \<Longrightarrow> closed(path_image g)"
   337   by (metis closed_path_image arc_imp_path)
   338 
   339 lemma path_image_join_subset: "path_image (g1 +++ g2) \<subseteq> path_image g1 \<union> path_image g2"
   340   unfolding path_image_def joinpaths_def
   341   by auto
   342 
   343 lemma subset_path_image_join:
   344   assumes "path_image g1 \<subseteq> s"
   345     and "path_image g2 \<subseteq> s"
   346   shows "path_image (g1 +++ g2) \<subseteq> s"
   347   using path_image_join_subset[of g1 g2] and assms
   348   by auto
   349 
   350 lemma path_image_join:
   351     "pathfinish g1 = pathstart g2 \<Longrightarrow> path_image(g1 +++ g2) = path_image g1 \<union> path_image g2"
   352   apply (rule subset_antisym [OF path_image_join_subset])
   353   apply (auto simp: pathfinish_def pathstart_def path_image_def joinpaths_def image_def)
   354   apply (drule sym)
   355   apply (rule_tac x="xa/2" in bexI, auto)
   356   apply (rule ccontr)
   357   apply (drule_tac x="(xa+1)/2" in bspec)
   358   apply (auto simp: field_simps)
   359   apply (drule_tac x="1/2" in bspec, auto)
   360   done
   361 
   362 lemma not_in_path_image_join:
   363   assumes "x \<notin> path_image g1"
   364     and "x \<notin> path_image g2"
   365   shows "x \<notin> path_image (g1 +++ g2)"
   366   using assms and path_image_join_subset[of g1 g2]
   367   by auto
   368 
   369 lemma pathstart_compose: "pathstart(f \<circ> p) = f(pathstart p)"
   370   by (simp add: pathstart_def)
   371 
   372 lemma pathfinish_compose: "pathfinish(f \<circ> p) = f(pathfinish p)"
   373   by (simp add: pathfinish_def)
   374 
   375 lemma path_image_compose: "path_image (f \<circ> p) = f ` (path_image p)"
   376   by (simp add: image_comp path_image_def)
   377 
   378 lemma path_compose_join: "f \<circ> (p +++ q) = (f \<circ> p) +++ (f \<circ> q)"
   379   by (rule ext) (simp add: joinpaths_def)
   380 
   381 lemma path_compose_reversepath: "f \<circ> reversepath p = reversepath(f \<circ> p)"
   382   by (rule ext) (simp add: reversepath_def)
   383 
   384 lemma joinpaths_eq:
   385   "(\<And>t. t \<in> {0..1} \<Longrightarrow> p t = p' t) \<Longrightarrow>
   386    (\<And>t. t \<in> {0..1} \<Longrightarrow> q t = q' t)
   387    \<Longrightarrow>  t \<in> {0..1} \<Longrightarrow> (p +++ q) t = (p' +++ q') t"
   388   by (auto simp: joinpaths_def)
   389 
   390 lemma simple_path_inj_on: "simple_path g \<Longrightarrow> inj_on g {0<..<1}"
   391   by (auto simp: simple_path_def path_image_def inj_on_def less_eq_real_def Ball_def)
   392 
   393 
   394 subsection%unimportant\<open>Simple paths with the endpoints removed\<close>
   395 
   396 lemma simple_path_endless:
   397     "simple_path c \<Longrightarrow> path_image c - {pathstart c,pathfinish c} = c ` {0<..<1}"
   398   apply (auto simp: simple_path_def path_image_def pathstart_def pathfinish_def Ball_def Bex_def image_def)
   399   apply (metis eq_iff le_less_linear)
   400   apply (metis leD linear)
   401   using less_eq_real_def zero_le_one apply blast
   402   using less_eq_real_def zero_le_one apply blast
   403   done
   404 
   405 lemma connected_simple_path_endless:
   406     "simple_path c \<Longrightarrow> connected(path_image c - {pathstart c,pathfinish c})"
   407 apply (simp add: simple_path_endless)
   408 apply (rule connected_continuous_image)
   409 apply (meson continuous_on_subset greaterThanLessThan_subseteq_atLeastAtMost_iff le_numeral_extra(3) le_numeral_extra(4) path_def simple_path_imp_path)
   410 by auto
   411 
   412 lemma nonempty_simple_path_endless:
   413     "simple_path c \<Longrightarrow> path_image c - {pathstart c,pathfinish c} \<noteq> {}"
   414   by (simp add: simple_path_endless)
   415 
   416 
   417 subsection%unimportant\<open>The operations on paths\<close>
   418 
   419 lemma path_image_subset_reversepath: "path_image(reversepath g) \<le> path_image g"
   420   by (auto simp: path_image_def reversepath_def)
   421 
   422 lemma path_imp_reversepath: "path g \<Longrightarrow> path(reversepath g)"
   423   apply (auto simp: path_def reversepath_def)
   424   using continuous_on_compose [of "{0..1}" "\<lambda>x. 1 - x" g]
   425   apply (auto simp: continuous_on_op_minus)
   426   done
   427 
   428 lemma half_bounded_equal: "1 \<le> x * 2 \<Longrightarrow> x * 2 \<le> 1 \<longleftrightarrow> x = (1/2::real)"
   429   by simp
   430 
   431 lemma continuous_on_joinpaths:
   432   assumes "continuous_on {0..1} g1" "continuous_on {0..1} g2" "pathfinish g1 = pathstart g2"
   433     shows "continuous_on {0..1} (g1 +++ g2)"
   434 proof -
   435   have *: "{0..1::real} = {0..1/2} \<union> {1/2..1}"
   436     by auto
   437   have gg: "g2 0 = g1 1"
   438     by (metis assms(3) pathfinish_def pathstart_def)
   439   have 1: "continuous_on {0..1/2} (g1 +++ g2)"
   440     apply (rule continuous_on_eq [of _ "g1 \<circ> (\<lambda>x. 2*x)"])
   441     apply (rule continuous_intros | simp add: joinpaths_def assms)+
   442     done
   443   have "continuous_on {1/2..1} (g2 \<circ> (\<lambda>x. 2*x-1))"
   444     apply (rule continuous_on_subset [of "{1/2..1}"])
   445     apply (rule continuous_intros | simp add: image_affinity_atLeastAtMost_diff assms)+
   446     done
   447   then have 2: "continuous_on {1/2..1} (g1 +++ g2)"
   448     apply (rule continuous_on_eq [of "{1/2..1}" "g2 \<circ> (\<lambda>x. 2*x-1)"])
   449     apply (rule assms continuous_intros | simp add: joinpaths_def mult.commute half_bounded_equal gg)+
   450     done
   451   show ?thesis
   452     apply (subst *)
   453     apply (rule continuous_on_closed_Un)
   454     using 1 2
   455     apply auto
   456     done
   457 qed
   458 
   459 lemma path_join_imp: "\<lbrakk>path g1; path g2; pathfinish g1 = pathstart g2\<rbrakk> \<Longrightarrow> path(g1 +++ g2)"
   460   by (simp add: path_join)
   461 
   462 lemma simple_path_join_loop:
   463   assumes "arc g1" "arc g2"
   464           "pathfinish g1 = pathstart g2"  "pathfinish g2 = pathstart g1"
   465           "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   466   shows "simple_path(g1 +++ g2)"
   467 proof -
   468   have injg1: "inj_on g1 {0..1}"
   469     using assms
   470     by (simp add: arc_def)
   471   have injg2: "inj_on g2 {0..1}"
   472     using assms
   473     by (simp add: arc_def)
   474   have g12: "g1 1 = g2 0"
   475    and g21: "g2 1 = g1 0"
   476    and sb:  "g1 ` {0..1} \<inter> g2 ` {0..1} \<subseteq> {g1 0, g2 0}"
   477     using assms
   478     by (simp_all add: arc_def pathfinish_def pathstart_def path_image_def)
   479   { fix x and y::real
   480     assume xyI: "x = 1 \<longrightarrow> y \<noteq> 0"
   481        and xy: "x \<le> 1" "0 \<le> y" " y * 2 \<le> 1" "\<not> x * 2 \<le> 1" "g2 (2 * x - 1) = g1 (2 * y)"
   482     have g1im: "g1 (2 * y) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   483       using xy
   484       apply simp
   485       apply (rule_tac x="2 * x - 1" in image_eqI, auto)
   486       done
   487     have False
   488       using subsetD [OF sb g1im] xy
   489       apply auto
   490       apply (drule inj_onD [OF injg1])
   491       using g21 [symmetric] xyI
   492       apply (auto dest: inj_onD [OF injg2])
   493       done
   494    } note * = this
   495   { fix x and y::real
   496     assume xy: "y \<le> 1" "0 \<le> x" "\<not> y * 2 \<le> 1" "x * 2 \<le> 1" "g1 (2 * x) = g2 (2 * y - 1)"
   497     have g1im: "g1 (2 * x) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   498       using xy
   499       apply simp
   500       apply (rule_tac x="2 * x" in image_eqI, auto)
   501       done
   502     have "x = 0 \<and> y = 1"
   503       using subsetD [OF sb g1im] xy
   504       apply auto
   505       apply (force dest: inj_onD [OF injg1])
   506       using  g21 [symmetric]
   507       apply (auto dest: inj_onD [OF injg2])
   508       done
   509    } note ** = this
   510   show ?thesis
   511     using assms
   512     apply (simp add: arc_def simple_path_def path_join, clarify)
   513     apply (simp add: joinpaths_def split: if_split_asm)
   514     apply (force dest: inj_onD [OF injg1])
   515     apply (metis *)
   516     apply (metis **)
   517     apply (force dest: inj_onD [OF injg2])
   518     done
   519 qed
   520 
   521 lemma arc_join:
   522   assumes "arc g1" "arc g2"
   523           "pathfinish g1 = pathstart g2"
   524           "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g2}"
   525     shows "arc(g1 +++ g2)"
   526 proof -
   527   have injg1: "inj_on g1 {0..1}"
   528     using assms
   529     by (simp add: arc_def)
   530   have injg2: "inj_on g2 {0..1}"
   531     using assms
   532     by (simp add: arc_def)
   533   have g11: "g1 1 = g2 0"
   534    and sb:  "g1 ` {0..1} \<inter> g2 ` {0..1} \<subseteq> {g2 0}"
   535     using assms
   536     by (simp_all add: arc_def pathfinish_def pathstart_def path_image_def)
   537   { fix x and y::real
   538     assume xy: "x \<le> 1" "0 \<le> y" " y * 2 \<le> 1" "\<not> x * 2 \<le> 1" "g2 (2 * x - 1) = g1 (2 * y)"
   539     have g1im: "g1 (2 * y) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   540       using xy
   541       apply simp
   542       apply (rule_tac x="2 * x - 1" in image_eqI, auto)
   543       done
   544     have False
   545       using subsetD [OF sb g1im] xy
   546       by (auto dest: inj_onD [OF injg2])
   547    } note * = this
   548   show ?thesis
   549     apply (simp add: arc_def inj_on_def)
   550     apply (clarsimp simp add: arc_imp_path assms path_join)
   551     apply (simp add: joinpaths_def split: if_split_asm)
   552     apply (force dest: inj_onD [OF injg1])
   553     apply (metis *)
   554     apply (metis *)
   555     apply (force dest: inj_onD [OF injg2])
   556     done
   557 qed
   558 
   559 lemma reversepath_joinpaths:
   560     "pathfinish g1 = pathstart g2 \<Longrightarrow> reversepath(g1 +++ g2) = reversepath g2 +++ reversepath g1"
   561   unfolding reversepath_def pathfinish_def pathstart_def joinpaths_def
   562   by (rule ext) (auto simp: mult.commute)
   563 
   564 
   565 subsection%unimportant\<open>Some reversed and "if and only if" versions of joining theorems\<close>
   566 
   567 lemma path_join_path_ends:
   568   fixes g1 :: "real \<Rightarrow> 'a::metric_space"
   569   assumes "path(g1 +++ g2)" "path g2"
   570     shows "pathfinish g1 = pathstart g2"
   571 proof (rule ccontr)
   572   define e where "e = dist (g1 1) (g2 0)"
   573   assume Neg: "pathfinish g1 \<noteq> pathstart g2"
   574   then have "0 < dist (pathfinish g1) (pathstart g2)"
   575     by auto
   576   then have "e > 0"
   577     by (metis e_def pathfinish_def pathstart_def)
   578   then obtain d1 where "d1 > 0"
   579        and d1: "\<And>x'. \<lbrakk>x'\<in>{0..1}; norm x' < d1\<rbrakk> \<Longrightarrow> dist (g2 x') (g2 0) < e/2"
   580     using assms(2) unfolding path_def continuous_on_iff
   581     apply (drule_tac x=0 in bspec, simp)
   582     by (metis half_gt_zero_iff norm_conv_dist)
   583   obtain d2 where "d2 > 0"
   584        and d2: "\<And>x'. \<lbrakk>x'\<in>{0..1}; dist x' (1/2) < d2\<rbrakk>
   585                       \<Longrightarrow> dist ((g1 +++ g2) x') (g1 1) < e/2"
   586     using assms(1) \<open>e > 0\<close> unfolding path_def continuous_on_iff
   587     apply (drule_tac x="1/2" in bspec, simp)
   588     apply (drule_tac x="e/2" in spec)
   589     apply (force simp: joinpaths_def)
   590     done
   591   have int01_1: "min (1/2) (min d1 d2) / 2 \<in> {0..1}"
   592     using \<open>d1 > 0\<close> \<open>d2 > 0\<close> by (simp add: min_def)
   593   have dist1: "norm (min (1 / 2) (min d1 d2) / 2) < d1"
   594     using \<open>d1 > 0\<close> \<open>d2 > 0\<close> by (simp add: min_def dist_norm)
   595   have int01_2: "1/2 + min (1/2) (min d1 d2) / 4 \<in> {0..1}"
   596     using \<open>d1 > 0\<close> \<open>d2 > 0\<close> by (simp add: min_def)
   597   have dist2: "dist (1 / 2 + min (1 / 2) (min d1 d2) / 4) (1 / 2) < d2"
   598     using \<open>d1 > 0\<close> \<open>d2 > 0\<close> by (simp add: min_def dist_norm)
   599   have [simp]: "\<not> min (1 / 2) (min d1 d2) \<le> 0"
   600     using \<open>d1 > 0\<close> \<open>d2 > 0\<close> by (simp add: min_def)
   601   have "dist (g2 (min (1 / 2) (min d1 d2) / 2)) (g1 1) < e/2"
   602        "dist (g2 (min (1 / 2) (min d1 d2) / 2)) (g2 0) < e/2"
   603     using d1 [OF int01_1 dist1] d2 [OF int01_2 dist2] by (simp_all add: joinpaths_def)
   604   then have "dist (g1 1) (g2 0) < e/2 + e/2"
   605     using dist_triangle_half_r e_def by blast
   606   then show False
   607     by (simp add: e_def [symmetric])
   608 qed
   609 
   610 lemma path_join_eq [simp]:
   611   fixes g1 :: "real \<Rightarrow> 'a::metric_space"
   612   assumes "path g1" "path g2"
   613     shows "path(g1 +++ g2) \<longleftrightarrow> pathfinish g1 = pathstart g2"
   614   using assms by (metis path_join_path_ends path_join_imp)
   615 
   616 lemma simple_path_joinE:
   617   assumes "simple_path(g1 +++ g2)" and "pathfinish g1 = pathstart g2"
   618   obtains "arc g1" "arc g2"
   619           "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   620 proof -
   621   have *: "\<And>x y. \<lbrakk>0 \<le> x; x \<le> 1; 0 \<le> y; y \<le> 1; (g1 +++ g2) x = (g1 +++ g2) y\<rbrakk>
   622                \<Longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0"
   623     using assms by (simp add: simple_path_def)
   624   have "path g1"
   625     using assms path_join simple_path_imp_path by blast
   626   moreover have "inj_on g1 {0..1}"
   627   proof (clarsimp simp: inj_on_def)
   628     fix x y
   629     assume "g1 x = g1 y" "0 \<le> x" "x \<le> 1" "0 \<le> y" "y \<le> 1"
   630     then show "x = y"
   631       using * [of "x/2" "y/2"] by (simp add: joinpaths_def split_ifs)
   632   qed
   633   ultimately have "arc g1"
   634     using assms  by (simp add: arc_def)
   635   have [simp]: "g2 0 = g1 1"
   636     using assms by (metis pathfinish_def pathstart_def)
   637   have "path g2"
   638     using assms path_join simple_path_imp_path by blast
   639   moreover have "inj_on g2 {0..1}"
   640   proof (clarsimp simp: inj_on_def)
   641     fix x y
   642     assume "g2 x = g2 y" "0 \<le> x" "x \<le> 1" "0 \<le> y" "y \<le> 1"
   643     then show "x = y"
   644       using * [of "(x + 1) / 2" "(y + 1) / 2"]
   645       by (force simp: joinpaths_def split_ifs divide_simps)
   646   qed
   647   ultimately have "arc g2"
   648     using assms  by (simp add: arc_def)
   649   have "g2 y = g1 0 \<or> g2 y = g1 1"
   650        if "g1 x = g2 y" "0 \<le> x" "x \<le> 1" "0 \<le> y" "y \<le> 1" for x y
   651       using * [of "x / 2" "(y + 1) / 2"] that
   652       by (auto simp: joinpaths_def split_ifs divide_simps)
   653   then have "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   654     by (fastforce simp: pathstart_def pathfinish_def path_image_def)
   655   with \<open>arc g1\<close> \<open>arc g2\<close> show ?thesis using that by blast
   656 qed
   657 
   658 lemma simple_path_join_loop_eq:
   659   assumes "pathfinish g2 = pathstart g1" "pathfinish g1 = pathstart g2"
   660     shows "simple_path(g1 +++ g2) \<longleftrightarrow>
   661              arc g1 \<and> arc g2 \<and> path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   662 by (metis assms simple_path_joinE simple_path_join_loop)
   663 
   664 lemma arc_join_eq:
   665   assumes "pathfinish g1 = pathstart g2"
   666     shows "arc(g1 +++ g2) \<longleftrightarrow>
   667            arc g1 \<and> arc g2 \<and> path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g2}"
   668            (is "?lhs = ?rhs")
   669 proof
   670   assume ?lhs
   671   then have "simple_path(g1 +++ g2)" by (rule arc_imp_simple_path)
   672   then have *: "\<And>x y. \<lbrakk>0 \<le> x; x \<le> 1; 0 \<le> y; y \<le> 1; (g1 +++ g2) x = (g1 +++ g2) y\<rbrakk>
   673                \<Longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0"
   674     using assms by (simp add: simple_path_def)
   675   have False if "g1 0 = g2 u" "0 \<le> u" "u \<le> 1" for u
   676     using * [of 0 "(u + 1) / 2"] that assms arc_distinct_ends [OF \<open>?lhs\<close>]
   677     by (auto simp: joinpaths_def pathstart_def pathfinish_def split_ifs divide_simps)
   678   then have n1: "pathstart g1 \<notin> path_image g2"
   679     unfolding pathstart_def path_image_def
   680     using atLeastAtMost_iff by blast
   681   show ?rhs using \<open>?lhs\<close>
   682     apply (rule simple_path_joinE [OF arc_imp_simple_path assms])
   683     using n1 by force
   684 next
   685   assume ?rhs then show ?lhs
   686     using assms
   687     by (fastforce simp: pathfinish_def pathstart_def intro!: arc_join)
   688 qed
   689 
   690 lemma arc_join_eq_alt:
   691         "pathfinish g1 = pathstart g2
   692         \<Longrightarrow> (arc(g1 +++ g2) \<longleftrightarrow>
   693              arc g1 \<and> arc g2 \<and>
   694              path_image g1 \<inter> path_image g2 = {pathstart g2})"
   695 using pathfinish_in_path_image by (fastforce simp: arc_join_eq)
   696 
   697 
   698 subsection%unimportant\<open>The joining of paths is associative\<close>
   699 
   700 lemma path_assoc:
   701     "\<lbrakk>pathfinish p = pathstart q; pathfinish q = pathstart r\<rbrakk>
   702      \<Longrightarrow> path(p +++ (q +++ r)) \<longleftrightarrow> path((p +++ q) +++ r)"
   703 by simp
   704 
   705 lemma simple_path_assoc:
   706   assumes "pathfinish p = pathstart q" "pathfinish q = pathstart r"
   707     shows "simple_path (p +++ (q +++ r)) \<longleftrightarrow> simple_path ((p +++ q) +++ r)"
   708 proof (cases "pathstart p = pathfinish r")
   709   case True show ?thesis
   710   proof
   711     assume "simple_path (p +++ q +++ r)"
   712     with assms True show "simple_path ((p +++ q) +++ r)"
   713       by (fastforce simp add: simple_path_join_loop_eq arc_join_eq path_image_join
   714                     dest: arc_distinct_ends [of r])
   715   next
   716     assume 0: "simple_path ((p +++ q) +++ r)"
   717     with assms True have q: "pathfinish r \<notin> path_image q"
   718       using arc_distinct_ends
   719       by (fastforce simp add: simple_path_join_loop_eq arc_join_eq path_image_join)
   720     have "pathstart r \<notin> path_image p"
   721       using assms
   722       by (metis 0 IntI arc_distinct_ends arc_join_eq_alt empty_iff insert_iff
   723               pathfinish_in_path_image pathfinish_join simple_path_joinE)
   724     with assms 0 q True show "simple_path (p +++ q +++ r)"
   725       by (auto simp: simple_path_join_loop_eq arc_join_eq path_image_join
   726                dest!: subsetD [OF _ IntI])
   727   qed
   728 next
   729   case False
   730   { fix x :: 'a
   731     assume a: "path_image p \<inter> path_image q \<subseteq> {pathstart q}"
   732               "(path_image p \<union> path_image q) \<inter> path_image r \<subseteq> {pathstart r}"
   733               "x \<in> path_image p" "x \<in> path_image r"
   734     have "pathstart r \<in> path_image q"
   735       by (metis assms(2) pathfinish_in_path_image)
   736     with a have "x = pathstart q"
   737       by blast
   738   }
   739   with False assms show ?thesis
   740     by (auto simp: simple_path_eq_arc simple_path_join_loop_eq arc_join_eq path_image_join)
   741 qed
   742 
   743 lemma arc_assoc:
   744      "\<lbrakk>pathfinish p = pathstart q; pathfinish q = pathstart r\<rbrakk>
   745       \<Longrightarrow> arc(p +++ (q +++ r)) \<longleftrightarrow> arc((p +++ q) +++ r)"
   746 by (simp add: arc_simple_path simple_path_assoc)
   747 
   748 subsubsection%unimportant\<open>Symmetry and loops\<close>
   749 
   750 lemma path_sym:
   751     "\<lbrakk>pathfinish p = pathstart q; pathfinish q = pathstart p\<rbrakk> \<Longrightarrow> path(p +++ q) \<longleftrightarrow> path(q +++ p)"
   752   by auto
   753 
   754 lemma simple_path_sym:
   755     "\<lbrakk>pathfinish p = pathstart q; pathfinish q = pathstart p\<rbrakk>
   756      \<Longrightarrow> simple_path(p +++ q) \<longleftrightarrow> simple_path(q +++ p)"
   757 by (metis (full_types) inf_commute insert_commute simple_path_joinE simple_path_join_loop)
   758 
   759 lemma path_image_sym:
   760     "\<lbrakk>pathfinish p = pathstart q; pathfinish q = pathstart p\<rbrakk>
   761      \<Longrightarrow> path_image(p +++ q) = path_image(q +++ p)"
   762 by (simp add: path_image_join sup_commute)
   763 
   764 
   765 subsection\<open>Subpath\<close>
   766 
   767 definition%important subpath :: "real \<Rightarrow> real \<Rightarrow> (real \<Rightarrow> 'a) \<Rightarrow> real \<Rightarrow> 'a::real_normed_vector"
   768   where "subpath a b g \<equiv> \<lambda>x. g((b - a) * x + a)"
   769 
   770 lemma path_image_subpath_gen:
   771   fixes g :: "_ \<Rightarrow> 'a::real_normed_vector"
   772   shows "path_image(subpath u v g) = g ` (closed_segment u v)"
   773   by (auto simp add: closed_segment_real_eq path_image_def subpath_def)
   774 
   775 lemma path_image_subpath:
   776   fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   777   shows "path_image(subpath u v g) = (if u \<le> v then g ` {u..v} else g ` {v..u})"
   778   by (simp add: path_image_subpath_gen closed_segment_eq_real_ivl)
   779 
   780 lemma path_image_subpath_commute:
   781   fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   782   shows "path_image(subpath u v g) = path_image(subpath v u g)"
   783   by (simp add: path_image_subpath_gen closed_segment_eq_real_ivl)
   784 
   785 lemma path_subpath [simp]:
   786   fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   787   assumes "path g" "u \<in> {0..1}" "v \<in> {0..1}"
   788     shows "path(subpath u v g)"
   789 proof -
   790   have "continuous_on {0..1} (g \<circ> (\<lambda>x. ((v-u) * x+ u)))"
   791     apply (rule continuous_intros | simp)+
   792     apply (simp add: image_affinity_atLeastAtMost [where c=u])
   793     using assms
   794     apply (auto simp: path_def continuous_on_subset)
   795     done
   796   then show ?thesis
   797     by (simp add: path_def subpath_def)
   798 qed
   799 
   800 lemma pathstart_subpath [simp]: "pathstart(subpath u v g) = g(u)"
   801   by (simp add: pathstart_def subpath_def)
   802 
   803 lemma pathfinish_subpath [simp]: "pathfinish(subpath u v g) = g(v)"
   804   by (simp add: pathfinish_def subpath_def)
   805 
   806 lemma subpath_trivial [simp]: "subpath 0 1 g = g"
   807   by (simp add: subpath_def)
   808 
   809 lemma subpath_reversepath: "subpath 1 0 g = reversepath g"
   810   by (simp add: reversepath_def subpath_def)
   811 
   812 lemma reversepath_subpath: "reversepath(subpath u v g) = subpath v u g"
   813   by (simp add: reversepath_def subpath_def algebra_simps)
   814 
   815 lemma subpath_translation: "subpath u v ((\<lambda>x. a + x) \<circ> g) = (\<lambda>x. a + x) \<circ> subpath u v g"
   816   by (rule ext) (simp add: subpath_def)
   817 
   818 lemma subpath_linear_image: "linear f \<Longrightarrow> subpath u v (f \<circ> g) = f \<circ> subpath u v g"
   819   by (rule ext) (simp add: subpath_def)
   820 
   821 lemma affine_ineq:
   822   fixes x :: "'a::linordered_idom"
   823   assumes "x \<le> 1" "v \<le> u"
   824     shows "v + x * u \<le> u + x * v"
   825 proof -
   826   have "(1-x)*(u-v) \<ge> 0"
   827     using assms by auto
   828   then show ?thesis
   829     by (simp add: algebra_simps)
   830 qed
   831 
   832 lemma sum_le_prod1:
   833   fixes a::real shows "\<lbrakk>a \<le> 1; b \<le> 1\<rbrakk> \<Longrightarrow> a + b \<le> 1 + a * b"
   834 by (metis add.commute affine_ineq less_eq_real_def mult.right_neutral)
   835 
   836 lemma simple_path_subpath_eq:
   837   "simple_path(subpath u v g) \<longleftrightarrow>
   838      path(subpath u v g) \<and> u\<noteq>v \<and>
   839      (\<forall>x y. x \<in> closed_segment u v \<and> y \<in> closed_segment u v \<and> g x = g y
   840                 \<longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u)"
   841     (is "?lhs = ?rhs")
   842 proof (rule iffI)
   843   assume ?lhs
   844   then have p: "path (\<lambda>x. g ((v - u) * x + u))"
   845         and sim: "(\<And>x y. \<lbrakk>x\<in>{0..1}; y\<in>{0..1}; g ((v - u) * x + u) = g ((v - u) * y + u)\<rbrakk>
   846                   \<Longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0)"
   847     by (auto simp: simple_path_def subpath_def)
   848   { fix x y
   849     assume "x \<in> closed_segment u v" "y \<in> closed_segment u v" "g x = g y"
   850     then have "x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   851     using sim [of "(x-u)/(v-u)" "(y-u)/(v-u)"] p
   852     by (auto simp: closed_segment_real_eq image_affinity_atLeastAtMost divide_simps
   853        split: if_split_asm)
   854   } moreover
   855   have "path(subpath u v g) \<and> u\<noteq>v"
   856     using sim [of "1/3" "2/3"] p
   857     by (auto simp: subpath_def)
   858   ultimately show ?rhs
   859     by metis
   860 next
   861   assume ?rhs
   862   then
   863   have d1: "\<And>x y. \<lbrakk>g x = g y; u \<le> x; x \<le> v; u \<le> y; y \<le> v\<rbrakk> \<Longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   864    and d2: "\<And>x y. \<lbrakk>g x = g y; v \<le> x; x \<le> u; v \<le> y; y \<le> u\<rbrakk> \<Longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   865    and ne: "u < v \<or> v < u"
   866    and psp: "path (subpath u v g)"
   867     by (auto simp: closed_segment_real_eq image_affinity_atLeastAtMost)
   868   have [simp]: "\<And>x. u + x * v = v + x * u \<longleftrightarrow> u=v \<or> x=1"
   869     by algebra
   870   show ?lhs using psp ne
   871     unfolding simple_path_def subpath_def
   872     by (fastforce simp add: algebra_simps affine_ineq mult_left_mono crossproduct_eq dest: d1 d2)
   873 qed
   874 
   875 lemma arc_subpath_eq:
   876   "arc(subpath u v g) \<longleftrightarrow> path(subpath u v g) \<and> u\<noteq>v \<and> inj_on g (closed_segment u v)"
   877     (is "?lhs = ?rhs")
   878 proof (rule iffI)
   879   assume ?lhs
   880   then have p: "path (\<lambda>x. g ((v - u) * x + u))"
   881         and sim: "(\<And>x y. \<lbrakk>x\<in>{0..1}; y\<in>{0..1}; g ((v - u) * x + u) = g ((v - u) * y + u)\<rbrakk>
   882                   \<Longrightarrow> x = y)"
   883     by (auto simp: arc_def inj_on_def subpath_def)
   884   { fix x y
   885     assume "x \<in> closed_segment u v" "y \<in> closed_segment u v" "g x = g y"
   886     then have "x = y"
   887     using sim [of "(x-u)/(v-u)" "(y-u)/(v-u)"] p
   888     by (force simp: inj_on_def closed_segment_real_eq image_affinity_atLeastAtMost divide_simps
   889        split: if_split_asm)
   890   } moreover
   891   have "path(subpath u v g) \<and> u\<noteq>v"
   892     using sim [of "1/3" "2/3"] p
   893     by (auto simp: subpath_def)
   894   ultimately show ?rhs
   895     unfolding inj_on_def
   896     by metis
   897 next
   898   assume ?rhs
   899   then
   900   have d1: "\<And>x y. \<lbrakk>g x = g y; u \<le> x; x \<le> v; u \<le> y; y \<le> v\<rbrakk> \<Longrightarrow> x = y"
   901    and d2: "\<And>x y. \<lbrakk>g x = g y; v \<le> x; x \<le> u; v \<le> y; y \<le> u\<rbrakk> \<Longrightarrow> x = y"
   902    and ne: "u < v \<or> v < u"
   903    and psp: "path (subpath u v g)"
   904     by (auto simp: inj_on_def closed_segment_real_eq image_affinity_atLeastAtMost)
   905   show ?lhs using psp ne
   906     unfolding arc_def subpath_def inj_on_def
   907     by (auto simp: algebra_simps affine_ineq mult_left_mono crossproduct_eq dest: d1 d2)
   908 qed
   909 
   910 
   911 lemma simple_path_subpath:
   912   assumes "simple_path g" "u \<in> {0..1}" "v \<in> {0..1}" "u \<noteq> v"
   913   shows "simple_path(subpath u v g)"
   914   using assms
   915   apply (simp add: simple_path_subpath_eq simple_path_imp_path)
   916   apply (simp add: simple_path_def closed_segment_real_eq image_affinity_atLeastAtMost, fastforce)
   917   done
   918 
   919 lemma arc_simple_path_subpath:
   920     "\<lbrakk>simple_path g; u \<in> {0..1}; v \<in> {0..1}; g u \<noteq> g v\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   921   by (force intro: simple_path_subpath simple_path_imp_arc)
   922 
   923 lemma arc_subpath_arc:
   924     "\<lbrakk>arc g; u \<in> {0..1}; v \<in> {0..1}; u \<noteq> v\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   925   by (meson arc_def arc_imp_simple_path arc_simple_path_subpath inj_onD)
   926 
   927 lemma arc_simple_path_subpath_interior:
   928     "\<lbrakk>simple_path g; u \<in> {0..1}; v \<in> {0..1}; u \<noteq> v; \<bar>u-v\<bar> < 1\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   929     apply (rule arc_simple_path_subpath)
   930     apply (force simp: simple_path_def)+
   931     done
   932 
   933 lemma path_image_subpath_subset:
   934     "\<lbrakk>u \<in> {0..1}; v \<in> {0..1}\<rbrakk> \<Longrightarrow> path_image(subpath u v g) \<subseteq> path_image g"
   935   apply (simp add: closed_segment_real_eq image_affinity_atLeastAtMost path_image_subpath)
   936   apply (auto simp: path_image_def)
   937   done  
   938 
   939 lemma join_subpaths_middle: "subpath (0) ((1 / 2)) p +++ subpath ((1 / 2)) 1 p = p"
   940   by (rule ext) (simp add: joinpaths_def subpath_def divide_simps)
   941 
   942 
   943 subsection%unimportant\<open>There is a subpath to the frontier\<close>
   944 
   945 lemma subpath_to_frontier_explicit:
   946     fixes S :: "'a::metric_space set"
   947     assumes g: "path g" and "pathfinish g \<notin> S"
   948     obtains u where "0 \<le> u" "u \<le> 1"
   949                 "\<And>x. 0 \<le> x \<and> x < u \<Longrightarrow> g x \<in> interior S"
   950                 "(g u \<notin> interior S)" "(u = 0 \<or> g u \<in> closure S)"
   951 proof -
   952   have gcon: "continuous_on {0..1} g"     using g by (simp add: path_def)
   953   then have com: "compact ({0..1} \<inter> {u. g u \<in> closure (- S)})"
   954     apply (simp add: Int_commute [of "{0..1}"] compact_eq_bounded_closed closed_vimage_Int [unfolded vimage_def])
   955     using compact_eq_bounded_closed apply fastforce
   956     done
   957   have "1 \<in> {u. g u \<in> closure (- S)}"
   958     using assms by (simp add: pathfinish_def closure_def)
   959   then have dis: "{0..1} \<inter> {u. g u \<in> closure (- S)} \<noteq> {}"
   960     using atLeastAtMost_iff zero_le_one by blast
   961   then obtain u where "0 \<le> u" "u \<le> 1" and gu: "g u \<in> closure (- S)"
   962                   and umin: "\<And>t. \<lbrakk>0 \<le> t; t \<le> 1; g t \<in> closure (- S)\<rbrakk> \<Longrightarrow> u \<le> t"
   963     using compact_attains_inf [OF com dis] by fastforce
   964   then have umin': "\<And>t. \<lbrakk>0 \<le> t; t \<le> 1; t < u\<rbrakk> \<Longrightarrow>  g t \<in> S"
   965     using closure_def by fastforce
   966   { assume "u \<noteq> 0"
   967     then have "u > 0" using \<open>0 \<le> u\<close> by auto
   968     { fix e::real assume "e > 0"
   969       obtain d where "d>0" and d: "\<And>x'. \<lbrakk>x' \<in> {0..1}; dist x' u \<le> d\<rbrakk> \<Longrightarrow> dist (g x') (g u) < e"
   970         using continuous_onE [OF gcon _ \<open>e > 0\<close>] \<open>0 \<le> _\<close> \<open>_ \<le> 1\<close> atLeastAtMost_iff by auto
   971       have *: "dist (max 0 (u - d / 2)) u \<le> d"
   972         using \<open>0 \<le> u\<close> \<open>u \<le> 1\<close> \<open>d > 0\<close> by (simp add: dist_real_def)
   973       have "\<exists>y\<in>S. dist y (g u) < e"
   974         using \<open>0 < u\<close> \<open>u \<le> 1\<close> \<open>d > 0\<close>
   975         by (force intro: d [OF _ *] umin')
   976     }
   977     then have "g u \<in> closure S"
   978       by (simp add: frontier_def closure_approachable)
   979   }
   980   then show ?thesis
   981     apply (rule_tac u=u in that)
   982     apply (auto simp: \<open>0 \<le> u\<close> \<open>u \<le> 1\<close> gu interior_closure umin)
   983     using \<open>_ \<le> 1\<close> interior_closure umin apply fastforce
   984     done
   985 qed
   986 
   987 lemma subpath_to_frontier_strong:
   988     assumes g: "path g" and "pathfinish g \<notin> S"
   989     obtains u where "0 \<le> u" "u \<le> 1" "g u \<notin> interior S"
   990                     "u = 0 \<or> (\<forall>x. 0 \<le> x \<and> x < 1 \<longrightarrow> subpath 0 u g x \<in> interior S)  \<and>  g u \<in> closure S"
   991 proof -
   992   obtain u where "0 \<le> u" "u \<le> 1"
   993              and gxin: "\<And>x. 0 \<le> x \<and> x < u \<Longrightarrow> g x \<in> interior S"
   994              and gunot: "(g u \<notin> interior S)" and u0: "(u = 0 \<or> g u \<in> closure S)"
   995     using subpath_to_frontier_explicit [OF assms] by blast
   996   show ?thesis
   997     apply (rule that [OF \<open>0 \<le> u\<close> \<open>u \<le> 1\<close>])
   998     apply (simp add: gunot)
   999     using \<open>0 \<le> u\<close> u0 by (force simp: subpath_def gxin)
  1000 qed
  1001 
  1002 lemma subpath_to_frontier:
  1003     assumes g: "path g" and g0: "pathstart g \<in> closure S" and g1: "pathfinish g \<notin> S"
  1004     obtains u where "0 \<le> u" "u \<le> 1" "g u \<in> frontier S" "(path_image(subpath 0 u g) - {g u}) \<subseteq> interior S"
  1005 proof -
  1006   obtain u where "0 \<le> u" "u \<le> 1"
  1007              and notin: "g u \<notin> interior S"
  1008              and disj: "u = 0 \<or>
  1009                         (\<forall>x. 0 \<le> x \<and> x < 1 \<longrightarrow> subpath 0 u g x \<in> interior S) \<and> g u \<in> closure S"
  1010     using subpath_to_frontier_strong [OF g g1] by blast
  1011   show ?thesis
  1012     apply (rule that [OF \<open>0 \<le> u\<close> \<open>u \<le> 1\<close>])
  1013     apply (metis DiffI disj frontier_def g0 notin pathstart_def)
  1014     using \<open>0 \<le> u\<close> g0 disj
  1015     apply (simp add: path_image_subpath_gen)
  1016     apply (auto simp: closed_segment_eq_real_ivl pathstart_def pathfinish_def subpath_def)
  1017     apply (rename_tac y)
  1018     apply (drule_tac x="y/u" in spec)
  1019     apply (auto split: if_split_asm)
  1020     done
  1021 qed
  1022 
  1023 lemma exists_path_subpath_to_frontier:
  1024     fixes S :: "'a::real_normed_vector set"
  1025     assumes "path g" "pathstart g \<in> closure S" "pathfinish g \<notin> S"
  1026     obtains h where "path h" "pathstart h = pathstart g" "path_image h \<subseteq> path_image g"
  1027                     "path_image h - {pathfinish h} \<subseteq> interior S"
  1028                     "pathfinish h \<in> frontier S"
  1029 proof -
  1030   obtain u where u: "0 \<le> u" "u \<le> 1" "g u \<in> frontier S" "(path_image(subpath 0 u g) - {g u}) \<subseteq> interior S"
  1031     using subpath_to_frontier [OF assms] by blast
  1032   show ?thesis
  1033     apply (rule that [of "subpath 0 u g"])
  1034     using assms u
  1035     apply (simp_all add: path_image_subpath)
  1036     apply (simp add: pathstart_def)
  1037     apply (force simp: closed_segment_eq_real_ivl path_image_def)
  1038     done
  1039 qed
  1040 
  1041 lemma exists_path_subpath_to_frontier_closed:
  1042     fixes S :: "'a::real_normed_vector set"
  1043     assumes S: "closed S" and g: "path g" and g0: "pathstart g \<in> S" and g1: "pathfinish g \<notin> S"
  1044     obtains h where "path h" "pathstart h = pathstart g" "path_image h \<subseteq> path_image g \<inter> S"
  1045                     "pathfinish h \<in> frontier S"
  1046 proof -
  1047   obtain h where h: "path h" "pathstart h = pathstart g" "path_image h \<subseteq> path_image g"
  1048                     "path_image h - {pathfinish h} \<subseteq> interior S"
  1049                     "pathfinish h \<in> frontier S"
  1050     using exists_path_subpath_to_frontier [OF g _ g1] closure_closed [OF S] g0 by auto
  1051   show ?thesis
  1052     apply (rule that [OF \<open>path h\<close>])
  1053     using assms h
  1054     apply auto
  1055     apply (metis Diff_single_insert frontier_subset_eq insert_iff interior_subset subset_iff)
  1056     done
  1057 qed
  1058 
  1059 
  1060 subsection \<open>Shift Path to Start at Some Given Point\<close>
  1061 
  1062 definition%important shiftpath :: "real \<Rightarrow> (real \<Rightarrow> 'a::topological_space) \<Rightarrow> real \<Rightarrow> 'a"
  1063   where "shiftpath a f = (\<lambda>x. if (a + x) \<le> 1 then f (a + x) else f (a + x - 1))"
  1064 
  1065 lemma pathstart_shiftpath: "a \<le> 1 \<Longrightarrow> pathstart (shiftpath a g) = g a"
  1066   unfolding pathstart_def shiftpath_def by auto
  1067 
  1068 lemma pathfinish_shiftpath:
  1069   assumes "0 \<le> a"
  1070     and "pathfinish g = pathstart g"
  1071   shows "pathfinish (shiftpath a g) = g a"
  1072   using assms
  1073   unfolding pathstart_def pathfinish_def shiftpath_def
  1074   by auto
  1075 
  1076 lemma endpoints_shiftpath:
  1077   assumes "pathfinish g = pathstart g"
  1078     and "a \<in> {0 .. 1}"
  1079   shows "pathfinish (shiftpath a g) = g a"
  1080     and "pathstart (shiftpath a g) = g a"
  1081   using assms
  1082   by (auto intro!: pathfinish_shiftpath pathstart_shiftpath)
  1083 
  1084 lemma closed_shiftpath:
  1085   assumes "pathfinish g = pathstart g"
  1086     and "a \<in> {0..1}"
  1087   shows "pathfinish (shiftpath a g) = pathstart (shiftpath a g)"
  1088   using endpoints_shiftpath[OF assms]
  1089   by auto
  1090 
  1091 lemma path_shiftpath:
  1092   assumes "path g"
  1093     and "pathfinish g = pathstart g"
  1094     and "a \<in> {0..1}"
  1095   shows "path (shiftpath a g)"
  1096 proof -
  1097   have *: "{0 .. 1} = {0 .. 1-a} \<union> {1-a .. 1}"
  1098     using assms(3) by auto
  1099   have **: "\<And>x. x + a = 1 \<Longrightarrow> g (x + a - 1) = g (x + a)"
  1100     using assms(2)[unfolded pathfinish_def pathstart_def]
  1101     by auto
  1102   show ?thesis
  1103     unfolding path_def shiftpath_def *
  1104   proof (rule continuous_on_closed_Un)
  1105     have contg: "continuous_on {0..1} g"
  1106       using \<open>path g\<close> path_def by blast
  1107     show "continuous_on {0..1-a} (\<lambda>x. if a + x \<le> 1 then g (a + x) else g (a + x - 1))"
  1108     proof (rule continuous_on_eq)
  1109       show "continuous_on {0..1-a} (g \<circ> (+) a)"
  1110         by (intro continuous_intros continuous_on_subset [OF contg]) (use \<open>a \<in> {0..1}\<close> in auto)
  1111     qed auto
  1112     show "continuous_on {1-a..1} (\<lambda>x. if a + x \<le> 1 then g (a + x) else g (a + x - 1))"
  1113     proof (rule continuous_on_eq)
  1114       show "continuous_on {1-a..1} (g \<circ> (+) (a - 1))"
  1115         by (intro continuous_intros continuous_on_subset [OF contg]) (use \<open>a \<in> {0..1}\<close> in auto)
  1116     qed (auto simp:  "**" add.commute add_diff_eq)
  1117   qed auto
  1118 qed
  1119 
  1120 lemma shiftpath_shiftpath:
  1121   assumes "pathfinish g = pathstart g"
  1122     and "a \<in> {0..1}"
  1123     and "x \<in> {0..1}"
  1124   shows "shiftpath (1 - a) (shiftpath a g) x = g x"
  1125   using assms
  1126   unfolding pathfinish_def pathstart_def shiftpath_def
  1127   by auto
  1128 
  1129 lemma path_image_shiftpath:
  1130   assumes a: "a \<in> {0..1}"
  1131     and "pathfinish g = pathstart g"
  1132   shows "path_image (shiftpath a g) = path_image g"
  1133 proof -
  1134   { fix x
  1135     assume g: "g 1 = g 0" "x \<in> {0..1::real}" and gne: "\<And>y. y\<in>{0..1} \<inter> {x. \<not> a + x \<le> 1} \<Longrightarrow> g x \<noteq> g (a + y - 1)"
  1136     then have "\<exists>y\<in>{0..1} \<inter> {x. a + x \<le> 1}. g x = g (a + y)"
  1137     proof (cases "a \<le> x")
  1138       case False
  1139       then show ?thesis
  1140         apply (rule_tac x="1 + x - a" in bexI)
  1141         using g gne[of "1 + x - a"] a
  1142         apply (force simp: field_simps)+
  1143         done
  1144     next
  1145       case True
  1146       then show ?thesis
  1147         using g a  by (rule_tac x="x - a" in bexI) (auto simp: field_simps)
  1148     qed
  1149   }
  1150   then show ?thesis
  1151     using assms
  1152     unfolding shiftpath_def path_image_def pathfinish_def pathstart_def
  1153     by (auto simp: image_iff)
  1154 qed
  1155 
  1156 lemma simple_path_shiftpath:
  1157   assumes "simple_path g" "pathfinish g = pathstart g" and a: "0 \<le> a" "a \<le> 1"
  1158     shows "simple_path (shiftpath a g)"
  1159   unfolding simple_path_def
  1160 proof (intro conjI impI ballI)
  1161   show "path (shiftpath a g)"
  1162     by (simp add: assms path_shiftpath simple_path_imp_path)
  1163   have *: "\<And>x y. \<lbrakk>g x = g y; x \<in> {0..1}; y \<in> {0..1}\<rbrakk> \<Longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0"
  1164     using assms by (simp add:  simple_path_def)
  1165   show "x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0"
  1166     if "x \<in> {0..1}" "y \<in> {0..1}" "shiftpath a g x = shiftpath a g y" for x y
  1167     using that a unfolding shiftpath_def
  1168     by (force split: if_split_asm dest!: *)
  1169 qed
  1170 
  1171 
  1172 subsection \<open>Straight-Line Paths\<close>
  1173 
  1174 definition%important linepath :: "'a::real_normed_vector \<Rightarrow> 'a \<Rightarrow> real \<Rightarrow> 'a"
  1175   where "linepath a b = (\<lambda>x. (1 - x) *\<^sub>R a + x *\<^sub>R b)"
  1176 
  1177 lemma pathstart_linepath[simp]: "pathstart (linepath a b) = a"
  1178   unfolding pathstart_def linepath_def
  1179   by auto
  1180 
  1181 lemma pathfinish_linepath[simp]: "pathfinish (linepath a b) = b"
  1182   unfolding pathfinish_def linepath_def
  1183   by auto
  1184 
  1185 lemma linepath_inner: "linepath a b x \<bullet> v = linepath (a \<bullet> v) (b \<bullet> v) x"
  1186   by (simp add: linepath_def algebra_simps)
  1187 
  1188 lemma Re_linepath': "Re (linepath a b x) = linepath (Re a) (Re b) x"
  1189   by (simp add: linepath_def)
  1190 
  1191 lemma Im_linepath': "Im (linepath a b x) = linepath (Im a) (Im b) x"
  1192   by (simp add: linepath_def)
  1193 
  1194 lemma linepath_0': "linepath a b 0 = a"
  1195   by (simp add: linepath_def)
  1196 
  1197 lemma linepath_1': "linepath a b 1 = b"
  1198   by (simp add: linepath_def)
  1199 
  1200 lemma continuous_linepath_at[intro]: "continuous (at x) (linepath a b)"
  1201   unfolding linepath_def
  1202   by (intro continuous_intros)
  1203 
  1204 lemma continuous_on_linepath [intro,continuous_intros]: "continuous_on s (linepath a b)"
  1205   using continuous_linepath_at
  1206   by (auto intro!: continuous_at_imp_continuous_on)
  1207 
  1208 lemma path_linepath[iff]: "path (linepath a b)"
  1209   unfolding path_def
  1210   by (rule continuous_on_linepath)
  1211 
  1212 lemma path_image_linepath[simp]: "path_image (linepath a b) = closed_segment a b"
  1213   unfolding path_image_def segment linepath_def
  1214   by auto
  1215 
  1216 lemma reversepath_linepath[simp]: "reversepath (linepath a b) = linepath b a"
  1217   unfolding reversepath_def linepath_def
  1218   by auto
  1219 
  1220 lemma linepath_0 [simp]: "linepath 0 b x = x *\<^sub>R b"
  1221   by (simp add: linepath_def)
  1222 
  1223 lemma linepath_cnj: "cnj (linepath a b x) = linepath (cnj a) (cnj b) x"
  1224   by (simp add: linepath_def)
  1225 
  1226 lemma arc_linepath:
  1227   assumes "a \<noteq> b" shows [simp]: "arc (linepath a b)"
  1228 proof -
  1229   {
  1230     fix x y :: "real"
  1231     assume "x *\<^sub>R b + y *\<^sub>R a = x *\<^sub>R a + y *\<^sub>R b"
  1232     then have "(x - y) *\<^sub>R a = (x - y) *\<^sub>R b"
  1233       by (simp add: algebra_simps)
  1234     with assms have "x = y"
  1235       by simp
  1236   }
  1237   then show ?thesis
  1238     unfolding arc_def inj_on_def
  1239     by (fastforce simp: algebra_simps linepath_def)
  1240 qed
  1241 
  1242 lemma simple_path_linepath[intro]: "a \<noteq> b \<Longrightarrow> simple_path (linepath a b)"
  1243   by (simp add: arc_imp_simple_path)
  1244 
  1245 lemma linepath_trivial [simp]: "linepath a a x = a"
  1246   by (simp add: linepath_def real_vector.scale_left_diff_distrib)
  1247 
  1248 lemma linepath_refl: "linepath a a = (\<lambda>x. a)"
  1249   by auto
  1250 
  1251 lemma subpath_refl: "subpath a a g = linepath (g a) (g a)"
  1252   by (simp add: subpath_def linepath_def algebra_simps)
  1253 
  1254 lemma linepath_of_real: "(linepath (of_real a) (of_real b) x) = of_real ((1 - x)*a + x*b)"
  1255   by (simp add: scaleR_conv_of_real linepath_def)
  1256 
  1257 lemma of_real_linepath: "of_real (linepath a b x) = linepath (of_real a) (of_real b) x"
  1258   by (metis linepath_of_real mult.right_neutral of_real_def real_scaleR_def)
  1259 
  1260 lemma inj_on_linepath:
  1261   assumes "a \<noteq> b" shows "inj_on (linepath a b) {0..1}"
  1262 proof (clarsimp simp: inj_on_def linepath_def)
  1263   fix x y
  1264   assume "(1 - x) *\<^sub>R a + x *\<^sub>R b = (1 - y) *\<^sub>R a + y *\<^sub>R b" "0 \<le> x" "x \<le> 1" "0 \<le> y" "y \<le> 1"
  1265   then have "x *\<^sub>R (a - b) = y *\<^sub>R (a - b)"
  1266     by (auto simp: algebra_simps)
  1267   then show "x=y"
  1268     using assms by auto
  1269 qed
  1270 
  1271 lemma linepath_le_1:
  1272   fixes a::"'a::linordered_idom" shows "\<lbrakk>a \<le> 1; b \<le> 1; 0 \<le> u; u \<le> 1\<rbrakk> \<Longrightarrow> (1 - u) * a + u * b \<le> 1"
  1273   using mult_left_le [of a "1-u"] mult_left_le [of b u] by auto
  1274 
  1275 
  1276 subsection%unimportant\<open>Segments via convex hulls\<close>
  1277 
  1278 lemma segments_subset_convex_hull:
  1279     "closed_segment a b \<subseteq> (convex hull {a,b,c})"
  1280     "closed_segment a c \<subseteq> (convex hull {a,b,c})"
  1281     "closed_segment b c \<subseteq> (convex hull {a,b,c})"
  1282     "closed_segment b a \<subseteq> (convex hull {a,b,c})"
  1283     "closed_segment c a \<subseteq> (convex hull {a,b,c})"
  1284     "closed_segment c b \<subseteq> (convex hull {a,b,c})"
  1285 by (auto simp: segment_convex_hull linepath_of_real  elim!: rev_subsetD [OF _ hull_mono])
  1286 
  1287 lemma midpoints_in_convex_hull:
  1288   assumes "x \<in> convex hull s" "y \<in> convex hull s"
  1289     shows "midpoint x y \<in> convex hull s"
  1290 proof -
  1291   have "(1 - inverse(2)) *\<^sub>R x + inverse(2) *\<^sub>R y \<in> convex hull s"
  1292     by (rule convexD_alt) (use assms in auto)
  1293   then show ?thesis
  1294     by (simp add: midpoint_def algebra_simps)
  1295 qed
  1296 
  1297 lemma not_in_interior_convex_hull_3:
  1298   fixes a :: "complex"
  1299   shows "a \<notin> interior(convex hull {a,b,c})"
  1300         "b \<notin> interior(convex hull {a,b,c})"
  1301         "c \<notin> interior(convex hull {a,b,c})"
  1302   by (auto simp: card_insert_le_m1 not_in_interior_convex_hull)
  1303 
  1304 lemma midpoint_in_closed_segment [simp]: "midpoint a b \<in> closed_segment a b"
  1305   using midpoints_in_convex_hull segment_convex_hull by blast
  1306 
  1307 lemma midpoint_in_open_segment [simp]: "midpoint a b \<in> open_segment a b \<longleftrightarrow> a \<noteq> b"
  1308   by (simp add: open_segment_def)
  1309 
  1310 lemma continuous_IVT_local_extremum:
  1311   fixes f :: "'a::euclidean_space \<Rightarrow> real"
  1312   assumes contf: "continuous_on (closed_segment a b) f"
  1313       and "a \<noteq> b" "f a = f b"
  1314   obtains z where "z \<in> open_segment a b"
  1315                   "(\<forall>w \<in> closed_segment a b. (f w) \<le> (f z)) \<or>
  1316                    (\<forall>w \<in> closed_segment a b. (f z) \<le> (f w))"
  1317 proof -
  1318   obtain c where "c \<in> closed_segment a b" and c: "\<And>y. y \<in> closed_segment a b \<Longrightarrow> f y \<le> f c"
  1319     using continuous_attains_sup [of "closed_segment a b" f] contf by auto
  1320   obtain d where "d \<in> closed_segment a b" and d: "\<And>y. y \<in> closed_segment a b \<Longrightarrow> f d \<le> f y"
  1321     using continuous_attains_inf [of "closed_segment a b" f] contf by auto
  1322   show ?thesis
  1323   proof (cases "c \<in> open_segment a b \<or> d \<in> open_segment a b")
  1324     case True
  1325     then show ?thesis
  1326       using c d that by blast
  1327   next
  1328     case False
  1329     then have "(c = a \<or> c = b) \<and> (d = a \<or> d = b)"
  1330       by (simp add: \<open>c \<in> closed_segment a b\<close> \<open>d \<in> closed_segment a b\<close> open_segment_def)
  1331     with \<open>a \<noteq> b\<close> \<open>f a = f b\<close> c d show ?thesis
  1332       by (rule_tac z = "midpoint a b" in that) (fastforce+)
  1333   qed
  1334 qed
  1335 
  1336 text\<open>An injective map into R is also an open map w.r.T. the universe, and conversely. \<close>
  1337 proposition injective_eq_1d_open_map_UNIV:
  1338   fixes f :: "real \<Rightarrow> real"
  1339   assumes contf: "continuous_on S f" and S: "is_interval S"
  1340     shows "inj_on f S \<longleftrightarrow> (\<forall>T. open T \<and> T \<subseteq> S \<longrightarrow> open(f ` T))"
  1341           (is "?lhs = ?rhs")
  1342 proof safe
  1343   fix T
  1344   assume injf: ?lhs and "open T" and "T \<subseteq> S"
  1345   have "\<exists>U. open U \<and> f x \<in> U \<and> U \<subseteq> f ` T" if "x \<in> T" for x
  1346   proof -
  1347     obtain \<delta> where "\<delta> > 0" and \<delta>: "cball x \<delta> \<subseteq> T"
  1348       using \<open>open T\<close> \<open>x \<in> T\<close> open_contains_cball_eq by blast
  1349     show ?thesis
  1350     proof (intro exI conjI)
  1351       have "closed_segment (x-\<delta>) (x+\<delta>) = {x-\<delta>..x+\<delta>}"
  1352         using \<open>0 < \<delta>\<close> by (auto simp: closed_segment_eq_real_ivl)
  1353       also have "\<dots> \<subseteq> S"
  1354         using \<delta> \<open>T \<subseteq> S\<close> by (auto simp: dist_norm subset_eq)
  1355       finally have "f ` (open_segment (x-\<delta>) (x+\<delta>)) = open_segment (f (x-\<delta>)) (f (x+\<delta>))"
  1356         using continuous_injective_image_open_segment_1
  1357         by (metis continuous_on_subset [OF contf] inj_on_subset [OF injf])
  1358       then show "open (f ` {x-\<delta><..<x+\<delta>})"
  1359         using \<open>0 < \<delta>\<close> by (simp add: open_segment_eq_real_ivl)
  1360       show "f x \<in> f ` {x - \<delta><..<x + \<delta>}"
  1361         by (auto simp: \<open>\<delta> > 0\<close>)
  1362       show "f ` {x - \<delta><..<x + \<delta>} \<subseteq> f ` T"
  1363         using \<delta> by (auto simp: dist_norm subset_iff)
  1364     qed
  1365   qed
  1366   with open_subopen show "open (f ` T)"
  1367     by blast
  1368 next
  1369   assume R: ?rhs
  1370   have False if xy: "x \<in> S" "y \<in> S" and "f x = f y" "x \<noteq> y" for x y
  1371   proof -
  1372     have "open (f ` open_segment x y)"
  1373       using R
  1374       by (metis S convex_contains_open_segment is_interval_convex open_greaterThanLessThan open_segment_eq_real_ivl xy)
  1375     moreover
  1376     have "continuous_on (closed_segment x y) f"
  1377       by (meson S closed_segment_subset contf continuous_on_subset is_interval_convex that)
  1378     then obtain \<xi> where "\<xi> \<in> open_segment x y"
  1379                     and \<xi>: "(\<forall>w \<in> closed_segment x y. (f w) \<le> (f \<xi>)) \<or>
  1380                             (\<forall>w \<in> closed_segment x y. (f \<xi>) \<le> (f w))"
  1381       using continuous_IVT_local_extremum [of x y f] \<open>f x = f y\<close> \<open>x \<noteq> y\<close> by blast
  1382     ultimately obtain e where "e>0" and e: "\<And>u. dist u (f \<xi>) < e \<Longrightarrow> u \<in> f ` open_segment x y"
  1383       using open_dist by (metis image_eqI)
  1384     have fin: "f \<xi> + (e/2) \<in> f ` open_segment x y" "f \<xi> - (e/2) \<in> f ` open_segment x y"
  1385       using e [of "f \<xi> + (e/2)"] e [of "f \<xi> - (e/2)"] \<open>e > 0\<close> by (auto simp: dist_norm)
  1386     show ?thesis
  1387       using \<xi> \<open>0 < e\<close> fin open_closed_segment by fastforce
  1388   qed
  1389   then show ?lhs
  1390     by (force simp: inj_on_def)
  1391 qed
  1392 
  1393 
  1394 subsection%unimportant \<open>Bounding a point away from a path\<close>
  1395 
  1396 lemma not_on_path_ball:
  1397   fixes g :: "real \<Rightarrow> 'a::heine_borel"
  1398   assumes "path g"
  1399     and z: "z \<notin> path_image g"
  1400   shows "\<exists>e > 0. ball z e \<inter> path_image g = {}"
  1401 proof -
  1402   have "closed (path_image g)"
  1403     by (simp add: \<open>path g\<close> closed_path_image)
  1404   then obtain a where "a \<in> path_image g" "\<forall>y \<in> path_image g. dist z a \<le> dist z y"
  1405     by (auto intro: distance_attains_inf[OF _ path_image_nonempty, of g z])
  1406   then show ?thesis
  1407     by (rule_tac x="dist z a" in exI) (use dist_commute z in auto)
  1408 qed
  1409 
  1410 lemma not_on_path_cball:
  1411   fixes g :: "real \<Rightarrow> 'a::heine_borel"
  1412   assumes "path g"
  1413     and "z \<notin> path_image g"
  1414   shows "\<exists>e>0. cball z e \<inter> (path_image g) = {}"
  1415 proof -
  1416   obtain e where "ball z e \<inter> path_image g = {}" "e > 0"
  1417     using not_on_path_ball[OF assms] by auto
  1418   moreover have "cball z (e/2) \<subseteq> ball z e"
  1419     using \<open>e > 0\<close> by auto
  1420   ultimately show ?thesis
  1421     by (rule_tac x="e/2" in exI) auto
  1422 qed
  1423 
  1424 subsection \<open>Path component\<close>
  1425 
  1426 text \<open>Original formalization by Tom Hales\<close>
  1427 
  1428 definition%important "path_component s x y \<longleftrightarrow>
  1429   (\<exists>g. path g \<and> path_image g \<subseteq> s \<and> pathstart g = x \<and> pathfinish g = y)"
  1430 
  1431 abbreviation%important
  1432   "path_component_set s x \<equiv> Collect (path_component s x)"
  1433 
  1434 lemmas path_defs = path_def pathstart_def pathfinish_def path_image_def path_component_def
  1435 
  1436 lemma path_component_mem:
  1437   assumes "path_component s x y"
  1438   shows "x \<in> s" and "y \<in> s"
  1439   using assms
  1440   unfolding path_defs
  1441   by auto
  1442 
  1443 lemma path_component_refl:
  1444   assumes "x \<in> s"
  1445   shows "path_component s x x"
  1446   unfolding path_defs
  1447   apply (rule_tac x="\<lambda>u. x" in exI)
  1448   using assms
  1449   apply (auto intro!: continuous_intros)
  1450   done
  1451 
  1452 lemma path_component_refl_eq: "path_component s x x \<longleftrightarrow> x \<in> s"
  1453   by (auto intro!: path_component_mem path_component_refl)
  1454 
  1455 lemma path_component_sym: "path_component s x y \<Longrightarrow> path_component s y x"
  1456   unfolding path_component_def
  1457   apply (erule exE)
  1458   apply (rule_tac x="reversepath g" in exI, auto)
  1459   done
  1460 
  1461 lemma path_component_trans:
  1462   assumes "path_component s x y" and "path_component s y z"
  1463   shows "path_component s x z"
  1464   using assms
  1465   unfolding path_component_def
  1466   apply (elim exE)
  1467   apply (rule_tac x="g +++ ga" in exI)
  1468   apply (auto simp: path_image_join)
  1469   done
  1470 
  1471 lemma path_component_of_subset: "s \<subseteq> t \<Longrightarrow> path_component s x y \<Longrightarrow> path_component t x y"
  1472   unfolding path_component_def by auto
  1473 
  1474 lemma path_component_linepath:
  1475     fixes s :: "'a::real_normed_vector set"
  1476     shows "closed_segment a b \<subseteq> s \<Longrightarrow> path_component s a b"
  1477   unfolding path_component_def
  1478   by (rule_tac x="linepath a b" in exI, auto)
  1479 
  1480 subsubsection%unimportant \<open>Path components as sets\<close>
  1481 
  1482 lemma path_component_set:
  1483   "path_component_set s x =
  1484     {y. (\<exists>g. path g \<and> path_image g \<subseteq> s \<and> pathstart g = x \<and> pathfinish g = y)}"
  1485   by (auto simp: path_component_def)
  1486 
  1487 lemma path_component_subset: "path_component_set s x \<subseteq> s"
  1488   by (auto simp: path_component_mem(2))
  1489 
  1490 lemma path_component_eq_empty: "path_component_set s x = {} \<longleftrightarrow> x \<notin> s"
  1491   using path_component_mem path_component_refl_eq
  1492     by fastforce
  1493 
  1494 lemma path_component_mono:
  1495      "s \<subseteq> t \<Longrightarrow> (path_component_set s x) \<subseteq> (path_component_set t x)"
  1496   by (simp add: Collect_mono path_component_of_subset)
  1497 
  1498 lemma path_component_eq:
  1499    "y \<in> path_component_set s x \<Longrightarrow> path_component_set s y = path_component_set s x"
  1500 by (metis (no_types, lifting) Collect_cong mem_Collect_eq path_component_sym path_component_trans)
  1501 
  1502 
  1503 subsection \<open>Path connectedness of a space\<close>
  1504 
  1505 definition%important "path_connected s \<longleftrightarrow>
  1506   (\<forall>x\<in>s. \<forall>y\<in>s. \<exists>g. path g \<and> path_image g \<subseteq> s \<and> pathstart g = x \<and> pathfinish g = y)"
  1507 
  1508 lemma path_connectedin_iff_path_connected_real [simp]:
  1509      "path_connectedin euclideanreal S \<longleftrightarrow> path_connected S"
  1510   by (simp add: path_connectedin path_connected_def path_defs)
  1511 
  1512 lemma path_connected_component: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. path_component s x y)"
  1513   unfolding path_connected_def path_component_def by auto
  1514 
  1515 lemma path_connected_component_set: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. path_component_set s x = s)"
  1516   unfolding path_connected_component path_component_subset
  1517   using path_component_mem by blast
  1518 
  1519 lemma path_component_maximal:
  1520      "\<lbrakk>x \<in> t; path_connected t; t \<subseteq> s\<rbrakk> \<Longrightarrow> t \<subseteq> (path_component_set s x)"
  1521   by (metis path_component_mono path_connected_component_set)
  1522 
  1523 lemma convex_imp_path_connected:
  1524   fixes s :: "'a::real_normed_vector set"
  1525   assumes "convex s"
  1526   shows "path_connected s"
  1527   unfolding path_connected_def
  1528   using assms convex_contains_segment by fastforce
  1529 
  1530 lemma path_connected_UNIV [iff]: "path_connected (UNIV :: 'a::real_normed_vector set)"
  1531   by (simp add: convex_imp_path_connected)
  1532 
  1533 lemma path_component_UNIV: "path_component_set UNIV x = (UNIV :: 'a::real_normed_vector set)"
  1534   using path_connected_component_set by auto
  1535 
  1536 lemma path_connected_imp_connected:
  1537   assumes "path_connected S"
  1538   shows "connected S"
  1539 proof (rule connectedI)
  1540   fix e1 e2
  1541   assume as: "open e1" "open e2" "S \<subseteq> e1 \<union> e2" "e1 \<inter> e2 \<inter> S = {}" "e1 \<inter> S \<noteq> {}" "e2 \<inter> S \<noteq> {}"
  1542   then obtain x1 x2 where obt:"x1 \<in> e1 \<inter> S" "x2 \<in> e2 \<inter> S"
  1543     by auto
  1544   then obtain g where g: "path g" "path_image g \<subseteq> S" "pathstart g = x1" "pathfinish g = x2"
  1545     using assms[unfolded path_connected_def,rule_format,of x1 x2] by auto
  1546   have *: "connected {0..1::real}"
  1547     by (auto intro!: convex_connected convex_real_interval)
  1548   have "{0..1} \<subseteq> {x \<in> {0..1}. g x \<in> e1} \<union> {x \<in> {0..1}. g x \<in> e2}"
  1549     using as(3) g(2)[unfolded path_defs] by blast
  1550   moreover have "{x \<in> {0..1}. g x \<in> e1} \<inter> {x \<in> {0..1}. g x \<in> e2} = {}"
  1551     using as(4) g(2)[unfolded path_defs]
  1552     unfolding subset_eq
  1553     by auto
  1554   moreover have "{x \<in> {0..1}. g x \<in> e1} \<noteq> {} \<and> {x \<in> {0..1}. g x \<in> e2} \<noteq> {}"
  1555     using g(3,4)[unfolded path_defs]
  1556     using obt
  1557     by (simp add: ex_in_conv [symmetric], metis zero_le_one order_refl)
  1558   ultimately show False
  1559     using *[unfolded connected_local not_ex, rule_format,
  1560       of "{0..1} \<inter> g -` e1" "{0..1} \<inter> g -` e2"]
  1561     using continuous_openin_preimage_gen[OF g(1)[unfolded path_def] as(1)]
  1562     using continuous_openin_preimage_gen[OF g(1)[unfolded path_def] as(2)]
  1563     by auto
  1564 qed
  1565 
  1566 lemma open_path_component:
  1567   fixes S :: "'a::real_normed_vector set"
  1568   assumes "open S"
  1569   shows "open (path_component_set S x)"
  1570   unfolding open_contains_ball
  1571 proof
  1572   fix y
  1573   assume as: "y \<in> path_component_set S x"
  1574   then have "y \<in> S"
  1575     by (simp add: path_component_mem(2))
  1576   then obtain e where e: "e > 0" "ball y e \<subseteq> S"
  1577     using assms[unfolded open_contains_ball]
  1578     by auto
  1579 have "\<And>u. dist y u < e \<Longrightarrow> path_component S x u"
  1580       by (metis (full_types) as centre_in_ball convex_ball convex_imp_path_connected e mem_Collect_eq mem_ball path_component_eq path_component_of_subset path_connected_component)
  1581   then show "\<exists>e > 0. ball y e \<subseteq> path_component_set S x"
  1582     using \<open>e>0\<close> by auto
  1583 qed
  1584 
  1585 lemma open_non_path_component:
  1586   fixes S :: "'a::real_normed_vector set"
  1587   assumes "open S"
  1588   shows "open (S - path_component_set S x)"
  1589   unfolding open_contains_ball
  1590 proof
  1591   fix y
  1592   assume y: "y \<in> S - path_component_set S x"
  1593   then obtain e where e: "e > 0" "ball y e \<subseteq> S"
  1594     using assms openE by auto
  1595   show "\<exists>e>0. ball y e \<subseteq> S - path_component_set S x"
  1596   proof (intro exI conjI subsetI DiffI notI)
  1597     show "\<And>x. x \<in> ball y e \<Longrightarrow> x \<in> S"
  1598       using e by blast
  1599     show False if "z \<in> ball y e" "z \<in> path_component_set S x" for z
  1600     proof -
  1601       have "y \<in> path_component_set S z"
  1602         by (meson assms convex_ball convex_imp_path_connected e open_contains_ball_eq open_path_component path_component_maximal that(1))
  1603       then have "y \<in> path_component_set S x"
  1604         using path_component_eq that(2) by blast
  1605       then show False
  1606         using y by blast
  1607     qed
  1608   qed (use e in auto)
  1609 qed
  1610 
  1611 lemma connected_open_path_connected:
  1612   fixes S :: "'a::real_normed_vector set"
  1613   assumes "open S"
  1614     and "connected S"
  1615   shows "path_connected S"
  1616   unfolding path_connected_component_set
  1617 proof (rule, rule, rule path_component_subset, rule)
  1618   fix x y
  1619   assume "x \<in> S" and "y \<in> S"
  1620   show "y \<in> path_component_set S x"
  1621   proof (rule ccontr)
  1622     assume "\<not> ?thesis"
  1623     moreover have "path_component_set S x \<inter> S \<noteq> {}"
  1624       using \<open>x \<in> S\<close> path_component_eq_empty path_component_subset[of S x]
  1625       by auto
  1626     ultimately
  1627     show False
  1628       using \<open>y \<in> S\<close> open_non_path_component[OF assms(1)] open_path_component[OF assms(1)]
  1629       using assms(2)[unfolded connected_def not_ex, rule_format,
  1630         of "path_component_set S x" "S - path_component_set S x"]
  1631       by auto
  1632   qed
  1633 qed
  1634 
  1635 lemma path_connected_continuous_image:
  1636   assumes "continuous_on S f"
  1637     and "path_connected S"
  1638   shows "path_connected (f ` S)"
  1639   unfolding path_connected_def
  1640 proof (rule, rule)
  1641   fix x' y'
  1642   assume "x' \<in> f ` S" "y' \<in> f ` S"
  1643   then obtain x y where x: "x \<in> S" and y: "y \<in> S" and x': "x' = f x" and y': "y' = f y"
  1644     by auto
  1645   from x y obtain g where "path g \<and> path_image g \<subseteq> S \<and> pathstart g = x \<and> pathfinish g = y"
  1646     using assms(2)[unfolded path_connected_def] by fast
  1647   then show "\<exists>g. path g \<and> path_image g \<subseteq> f ` S \<and> pathstart g = x' \<and> pathfinish g = y'"
  1648     unfolding x' y'
  1649     apply (rule_tac x="f \<circ> g" in exI)
  1650     unfolding path_defs
  1651     apply (intro conjI continuous_on_compose continuous_on_subset[OF assms(1)])
  1652     apply auto
  1653     done
  1654 qed
  1655 
  1656 lemma path_connected_translationI:
  1657   fixes a :: "'a :: topological_group_add"
  1658   assumes "path_connected S" shows "path_connected ((\<lambda>x. a + x) ` S)"
  1659   by (intro path_connected_continuous_image assms continuous_intros)
  1660 
  1661 lemma path_connected_translation:
  1662   fixes a :: "'a :: topological_group_add"
  1663   shows "path_connected ((\<lambda>x. a + x) ` S) = path_connected S"
  1664 proof -
  1665   have "\<forall>x y. (+) (x::'a) ` (+) (0 - x) ` y = y"
  1666     by (simp add: image_image)
  1667   then show ?thesis
  1668     by (metis (no_types) path_connected_translationI)
  1669 qed
  1670 
  1671 lemma path_connected_segment [simp]:
  1672     fixes a :: "'a::real_normed_vector"
  1673     shows "path_connected (closed_segment a b)"
  1674   by (simp add: convex_imp_path_connected)
  1675 
  1676 lemma path_connected_open_segment [simp]:
  1677     fixes a :: "'a::real_normed_vector"
  1678     shows "path_connected (open_segment a b)"
  1679   by (simp add: convex_imp_path_connected)
  1680 
  1681 lemma homeomorphic_path_connectedness:
  1682   "S homeomorphic T \<Longrightarrow> path_connected S \<longleftrightarrow> path_connected T"
  1683   unfolding homeomorphic_def homeomorphism_def by (metis path_connected_continuous_image)
  1684 
  1685 lemma path_connected_empty [simp]: "path_connected {}"
  1686   unfolding path_connected_def by auto
  1687 
  1688 lemma path_connected_singleton [simp]: "path_connected {a}"
  1689   unfolding path_connected_def pathstart_def pathfinish_def path_image_def
  1690   apply clarify
  1691   apply (rule_tac x="\<lambda>x. a" in exI)
  1692   apply (simp add: image_constant_conv)
  1693   apply (simp add: path_def continuous_on_const)
  1694   done
  1695 
  1696 lemma path_connected_Un:
  1697   assumes "path_connected S"
  1698     and "path_connected T"
  1699     and "S \<inter> T \<noteq> {}"
  1700   shows "path_connected (S \<union> T)"
  1701   unfolding path_connected_component
  1702 proof (intro ballI)
  1703   fix x y
  1704   assume x: "x \<in> S \<union> T" and y: "y \<in> S \<union> T"
  1705   from assms obtain z where z: "z \<in> S" "z \<in> T"
  1706     by auto
  1707   show "path_component (S \<union> T) x y"
  1708     using x y
  1709   proof safe
  1710     assume "x \<in> S" "y \<in> S"
  1711     then show "path_component (S \<union> T) x y"
  1712       by (meson Un_upper1 \<open>path_connected S\<close> path_component_of_subset path_connected_component)
  1713   next
  1714     assume "x \<in> S" "y \<in> T"
  1715     then show "path_component (S \<union> T) x y"
  1716       by (metis z assms(1-2) le_sup_iff order_refl path_component_of_subset path_component_trans path_connected_component)
  1717   next
  1718   assume "x \<in> T" "y \<in> S"
  1719     then show "path_component (S \<union> T) x y"
  1720       by (metis z assms(1-2) le_sup_iff order_refl path_component_of_subset path_component_trans path_connected_component)
  1721   next
  1722     assume "x \<in> T" "y \<in> T"
  1723     then show "path_component (S \<union> T) x y"
  1724       by (metis Un_upper1 assms(2) path_component_of_subset path_connected_component sup_commute)
  1725   qed
  1726 qed
  1727 
  1728 lemma path_connected_UNION:
  1729   assumes "\<And>i. i \<in> A \<Longrightarrow> path_connected (S i)"
  1730     and "\<And>i. i \<in> A \<Longrightarrow> z \<in> S i"
  1731   shows "path_connected (\<Union>i\<in>A. S i)"
  1732   unfolding path_connected_component
  1733 proof clarify
  1734   fix x i y j
  1735   assume *: "i \<in> A" "x \<in> S i" "j \<in> A" "y \<in> S j"
  1736   then have "path_component (S i) x z" and "path_component (S j) z y"
  1737     using assms by (simp_all add: path_connected_component)
  1738   then have "path_component (\<Union>i\<in>A. S i) x z" and "path_component (\<Union>i\<in>A. S i) z y"
  1739     using *(1,3) by (auto elim!: path_component_of_subset [rotated])
  1740   then show "path_component (\<Union>i\<in>A. S i) x y"
  1741     by (rule path_component_trans)
  1742 qed
  1743 
  1744 lemma path_component_path_image_pathstart:
  1745   assumes p: "path p" and x: "x \<in> path_image p"
  1746   shows "path_component (path_image p) (pathstart p) x"
  1747 proof -
  1748   obtain y where x: "x = p y" and y: "0 \<le> y" "y \<le> 1"
  1749     using x by (auto simp: path_image_def)
  1750   show ?thesis
  1751     unfolding path_component_def 
  1752   proof (intro exI conjI)
  1753     have "continuous_on {0..1} (p \<circ> ((*) y))"
  1754       apply (rule continuous_intros)+
  1755       using p [unfolded path_def] y
  1756       apply (auto simp: mult_le_one intro: continuous_on_subset [of _ p])
  1757       done
  1758     then show "path (\<lambda>u. p (y * u))"
  1759       by (simp add: path_def)
  1760     show "path_image (\<lambda>u. p (y * u)) \<subseteq> path_image p"
  1761       using y mult_le_one by (fastforce simp: path_image_def image_iff)
  1762   qed (auto simp: pathstart_def pathfinish_def x)
  1763 qed
  1764 
  1765 lemma path_connected_path_image: "path p \<Longrightarrow> path_connected(path_image p)"
  1766   unfolding path_connected_component
  1767   by (meson path_component_path_image_pathstart path_component_sym path_component_trans)
  1768 
  1769 lemma path_connected_path_component [simp]:
  1770    "path_connected (path_component_set s x)"
  1771 proof -
  1772   { fix y z
  1773     assume pa: "path_component s x y" "path_component s x z"
  1774     then have pae: "path_component_set s x = path_component_set s y"
  1775       using path_component_eq by auto
  1776     have yz: "path_component s y z"
  1777       using pa path_component_sym path_component_trans by blast
  1778     then have "\<exists>g. path g \<and> path_image g \<subseteq> path_component_set s x \<and> pathstart g = y \<and> pathfinish g = z"
  1779       apply (simp add: path_component_def, clarify)
  1780       apply (rule_tac x=g in exI)
  1781       by (simp add: pae path_component_maximal path_connected_path_image pathstart_in_path_image)
  1782   }
  1783   then show ?thesis
  1784     by (simp add: path_connected_def)
  1785 qed
  1786 
  1787 lemma path_component: "path_component S x y \<longleftrightarrow> (\<exists>t. path_connected t \<and> t \<subseteq> S \<and> x \<in> t \<and> y \<in> t)"
  1788   apply (intro iffI)
  1789   apply (metis path_connected_path_image path_defs(5) pathfinish_in_path_image pathstart_in_path_image)
  1790   using path_component_of_subset path_connected_component by blast
  1791 
  1792 lemma path_component_path_component [simp]:
  1793    "path_component_set (path_component_set S x) x = path_component_set S x"
  1794 proof (cases "x \<in> S")
  1795   case True show ?thesis
  1796     apply (rule subset_antisym)
  1797     apply (simp add: path_component_subset)
  1798     by (simp add: True path_component_maximal path_component_refl path_connected_path_component)
  1799 next
  1800   case False then show ?thesis
  1801     by (metis False empty_iff path_component_eq_empty)
  1802 qed
  1803 
  1804 lemma path_component_subset_connected_component:
  1805    "(path_component_set S x) \<subseteq> (connected_component_set S x)"
  1806 proof (cases "x \<in> S")
  1807   case True show ?thesis
  1808     apply (rule connected_component_maximal)
  1809     apply (auto simp: True path_component_subset path_component_refl path_connected_imp_connected)
  1810     done
  1811 next
  1812   case False then show ?thesis
  1813     using path_component_eq_empty by auto
  1814 qed
  1815 
  1816 
  1817 subsection%unimportant\<open>Lemmas about path-connectedness\<close>
  1818 
  1819 lemma path_connected_linear_image:
  1820   fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
  1821   assumes "path_connected S" "bounded_linear f"
  1822     shows "path_connected(f ` S)"
  1823 by (auto simp: linear_continuous_on assms path_connected_continuous_image)
  1824 
  1825 lemma is_interval_path_connected: "is_interval S \<Longrightarrow> path_connected S"
  1826   by (simp add: convex_imp_path_connected is_interval_convex)
  1827 
  1828 lemma path_connectedin_path_image:
  1829   assumes "pathin X g" shows "path_connectedin X (g ` ({0..1}))"
  1830   unfolding pathin_def
  1831 proof (rule path_connectedin_continuous_map_image)
  1832   show "continuous_map (subtopology euclideanreal {0..1}) X g"
  1833     using assms pathin_def by blast
  1834 qed (auto simp: is_interval_1 is_interval_path_connected)
  1835 
  1836 lemma path_connected_space_subconnected:
  1837      "path_connected_space X \<longleftrightarrow>
  1838       (\<forall>x \<in> topspace X. \<forall>y \<in> topspace X. \<exists>S. path_connectedin X S \<and> x \<in> S \<and> y \<in> S)"
  1839   unfolding path_connected_space_def Ball_def
  1840   apply (intro all_cong1 imp_cong refl, safe)
  1841   using path_connectedin_path_image apply fastforce
  1842   by (meson path_connectedin)
  1843 
  1844 lemma connectedin_path_image: "pathin X g \<Longrightarrow> connectedin X (g ` ({0..1}))"
  1845   by (simp add: path_connectedin_imp_connectedin path_connectedin_path_image)
  1846 
  1847 lemma compactin_path_image: "pathin X g \<Longrightarrow> compactin X (g ` ({0..1}))"
  1848   unfolding pathin_def
  1849   by (rule image_compactin [of "top_of_set {0..1}"]) auto
  1850 
  1851 lemma linear_homeomorphism_image:
  1852   fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  1853   assumes "linear f" "inj f"
  1854     obtains g where "homeomorphism (f ` S) S g f"
  1855 using linear_injective_left_inverse [OF assms]
  1856 apply clarify
  1857 apply (rule_tac g=g in that)
  1858 using assms
  1859 apply (auto simp: homeomorphism_def eq_id_iff [symmetric] image_comp comp_def linear_conv_bounded_linear linear_continuous_on)
  1860 done
  1861 
  1862 lemma linear_homeomorphic_image:
  1863   fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  1864   assumes "linear f" "inj f"
  1865     shows "S homeomorphic f ` S"
  1866 by (meson homeomorphic_def homeomorphic_sym linear_homeomorphism_image [OF assms])
  1867 
  1868 lemma path_connected_Times:
  1869   assumes "path_connected s" "path_connected t"
  1870     shows "path_connected (s \<times> t)"
  1871 proof (simp add: path_connected_def Sigma_def, clarify)
  1872   fix x1 y1 x2 y2
  1873   assume "x1 \<in> s" "y1 \<in> t" "x2 \<in> s" "y2 \<in> t"
  1874   obtain g where "path g" and g: "path_image g \<subseteq> s" and gs: "pathstart g = x1" and gf: "pathfinish g = x2"
  1875     using \<open>x1 \<in> s\<close> \<open>x2 \<in> s\<close> assms by (force simp: path_connected_def)
  1876   obtain h where "path h" and h: "path_image h \<subseteq> t" and hs: "pathstart h = y1" and hf: "pathfinish h = y2"
  1877     using \<open>y1 \<in> t\<close> \<open>y2 \<in> t\<close> assms by (force simp: path_connected_def)
  1878   have "path (\<lambda>z. (x1, h z))"
  1879     using \<open>path h\<close>
  1880     apply (simp add: path_def)
  1881     apply (rule continuous_on_compose2 [where f = h])
  1882     apply (rule continuous_intros | force)+
  1883     done
  1884   moreover have "path (\<lambda>z. (g z, y2))"
  1885     using \<open>path g\<close>
  1886     apply (simp add: path_def)
  1887     apply (rule continuous_on_compose2 [where f = g])
  1888     apply (rule continuous_intros | force)+
  1889     done
  1890   ultimately have 1: "path ((\<lambda>z. (x1, h z)) +++ (\<lambda>z. (g z, y2)))"
  1891     by (metis hf gs path_join_imp pathstart_def pathfinish_def)
  1892   have "path_image ((\<lambda>z. (x1, h z)) +++ (\<lambda>z. (g z, y2))) \<subseteq> path_image (\<lambda>z. (x1, h z)) \<union> path_image (\<lambda>z. (g z, y2))"
  1893     by (rule Path_Connected.path_image_join_subset)
  1894   also have "\<dots> \<subseteq> (\<Union>x\<in>s. \<Union>x1\<in>t. {(x, x1)})"
  1895     using g h \<open>x1 \<in> s\<close> \<open>y2 \<in> t\<close> by (force simp: path_image_def)
  1896   finally have 2: "path_image ((\<lambda>z. (x1, h z)) +++ (\<lambda>z. (g z, y2))) \<subseteq> (\<Union>x\<in>s. \<Union>x1\<in>t. {(x, x1)})" .
  1897   show "\<exists>g. path g \<and> path_image g \<subseteq> (\<Union>x\<in>s. \<Union>x1\<in>t. {(x, x1)}) \<and>
  1898             pathstart g = (x1, y1) \<and> pathfinish g = (x2, y2)"
  1899     apply (intro exI conjI)
  1900        apply (rule 1)
  1901       apply (rule 2)
  1902      apply (metis hs pathstart_def pathstart_join)
  1903     by (metis gf pathfinish_def pathfinish_join)
  1904 qed
  1905 
  1906 lemma is_interval_path_connected_1:
  1907   fixes s :: "real set"
  1908   shows "is_interval s \<longleftrightarrow> path_connected s"
  1909 using is_interval_connected_1 is_interval_path_connected path_connected_imp_connected by blast
  1910 
  1911 
  1912 subsection%unimportant\<open>Path components\<close>
  1913 
  1914 lemma Union_path_component [simp]:
  1915    "Union {path_component_set S x |x. x \<in> S} = S"
  1916 apply (rule subset_antisym)
  1917 using path_component_subset apply force
  1918 using path_component_refl by auto
  1919 
  1920 lemma path_component_disjoint:
  1921    "disjnt (path_component_set S a) (path_component_set S b) \<longleftrightarrow>
  1922     (a \<notin> path_component_set S b)"
  1923 apply (auto simp: disjnt_def)
  1924 using path_component_eq apply fastforce
  1925 using path_component_sym path_component_trans by blast
  1926 
  1927 lemma path_component_eq_eq:
  1928    "path_component S x = path_component S y \<longleftrightarrow>
  1929         (x \<notin> S) \<and> (y \<notin> S) \<or> x \<in> S \<and> y \<in> S \<and> path_component S x y"
  1930 apply (rule iffI, metis (no_types) path_component_mem(1) path_component_refl)
  1931 apply (erule disjE, metis Collect_empty_eq_bot path_component_eq_empty)
  1932 apply (rule ext)
  1933 apply (metis path_component_trans path_component_sym)
  1934 done
  1935 
  1936 lemma path_component_unique:
  1937   assumes "x \<in> c" "c \<subseteq> S" "path_connected c"
  1938           "\<And>c'. \<lbrakk>x \<in> c'; c' \<subseteq> S; path_connected c'\<rbrakk> \<Longrightarrow> c' \<subseteq> c"
  1939    shows "path_component_set S x = c"
  1940 apply (rule subset_antisym)
  1941 using assms
  1942 apply (metis mem_Collect_eq subsetCE path_component_eq_eq path_component_subset path_connected_path_component)
  1943 by (simp add: assms path_component_maximal)
  1944 
  1945 lemma path_component_intermediate_subset:
  1946    "path_component_set u a \<subseteq> t \<and> t \<subseteq> u
  1947         \<Longrightarrow> path_component_set t a = path_component_set u a"
  1948 by (metis (no_types) path_component_mono path_component_path_component subset_antisym)
  1949 
  1950 lemma complement_path_component_Union:
  1951   fixes x :: "'a :: topological_space"
  1952   shows "S - path_component_set S x =
  1953          \<Union>({path_component_set S y| y. y \<in> S} - {path_component_set S x})"
  1954 proof -
  1955   have *: "(\<And>x. x \<in> S - {a} \<Longrightarrow> disjnt a x) \<Longrightarrow> \<Union>S - a = \<Union>(S - {a})"
  1956     for a::"'a set" and S
  1957     by (auto simp: disjnt_def)
  1958   have "\<And>y. y \<in> {path_component_set S x |x. x \<in> S} - {path_component_set S x}
  1959             \<Longrightarrow> disjnt (path_component_set S x) y"
  1960     using path_component_disjoint path_component_eq by fastforce
  1961   then have "\<Union>{path_component_set S x |x. x \<in> S} - path_component_set S x =
  1962              \<Union>({path_component_set S y |y. y \<in> S} - {path_component_set S x})"
  1963     by (meson *)
  1964   then show ?thesis by simp
  1965 qed
  1966 
  1967 
  1968 subsection\<open>Path components\<close>
  1969 
  1970 definition path_component_of
  1971   where "path_component_of X x y \<equiv> \<exists>g. pathin X g \<and> g 0 = x \<and> g 1 = y"
  1972 
  1973 abbreviation path_component_of_set
  1974   where "path_component_of_set X x \<equiv> Collect (path_component_of X x)"
  1975 
  1976 definition path_components_of :: "'a topology \<Rightarrow> 'a set set"
  1977   where "path_components_of X \<equiv> path_component_of_set X ` topspace X"
  1978 
  1979 lemma path_component_in_topspace:
  1980    "path_component_of X x y \<Longrightarrow> x \<in> topspace X \<and> y \<in> topspace X"
  1981   by (auto simp: path_component_of_def pathin_def continuous_map_def)
  1982 
  1983 lemma path_component_of_refl:
  1984    "path_component_of X x x \<longleftrightarrow> x \<in> topspace X"
  1985   apply (auto simp: path_component_in_topspace)
  1986   apply (force simp: path_component_of_def pathin_const)
  1987   done
  1988 
  1989 lemma path_component_of_sym:
  1990   assumes "path_component_of X x y"
  1991   shows "path_component_of X y x"
  1992   using assms
  1993   apply (clarsimp simp: path_component_of_def pathin_def)
  1994   apply (rule_tac x="g \<circ> (\<lambda>t. 1 - t)" in exI)
  1995   apply (auto intro!: continuous_map_compose)
  1996   apply (force simp: continuous_map_in_subtopology continuous_on_op_minus)
  1997   done
  1998 
  1999 lemma path_component_of_sym_iff:
  2000    "path_component_of X x y \<longleftrightarrow> path_component_of X y x"
  2001   by (metis path_component_of_sym)
  2002 
  2003 lemma path_component_of_trans:
  2004   assumes "path_component_of X x y" and "path_component_of X y z"
  2005   shows "path_component_of X x z"
  2006   unfolding path_component_of_def pathin_def
  2007 proof -
  2008   let ?T01 = "top_of_set {0..1::real}"
  2009   obtain g1 g2 where g1: "continuous_map ?T01 X g1" "x = g1 0" "y = g1 1"
  2010     and g2: "continuous_map ?T01 X g2" "g2 0 = g1 1" "z = g2 1"
  2011     using assms unfolding path_component_of_def pathin_def by blast
  2012   let ?g = "\<lambda>x. if x \<le> 1/2 then (g1 \<circ> (\<lambda>t. 2 * t)) x else (g2 \<circ> (\<lambda>t. 2 * t -1)) x"
  2013   show "\<exists>g. continuous_map ?T01 X g \<and> g 0 = x \<and> g 1 = z"
  2014   proof (intro exI conjI)
  2015     show "continuous_map (subtopology euclideanreal {0..1}) X ?g"
  2016     proof (intro continuous_map_cases_le continuous_map_compose, force, force)
  2017       show "continuous_map (subtopology ?T01 {x \<in> topspace ?T01. x \<le> 1/2}) ?T01 ((*) 2)"
  2018         by (auto simp: continuous_map_in_subtopology continuous_map_from_subtopology)
  2019       have "continuous_map
  2020              (subtopology (top_of_set {0..1}) {x. 0 \<le> x \<and> x \<le> 1 \<and> 1 \<le> x * 2})
  2021              euclideanreal (\<lambda>t. 2 * t - 1)"
  2022         by (intro continuous_intros) (force intro: continuous_map_from_subtopology)
  2023       then show "continuous_map (subtopology ?T01 {x \<in> topspace ?T01. 1/2 \<le> x}) ?T01 (\<lambda>t. 2 * t - 1)"
  2024         by (force simp: continuous_map_in_subtopology)
  2025       show "(g1 \<circ> (*) 2) x = (g2 \<circ> (\<lambda>t. 2 * t - 1)) x" if "x \<in> topspace ?T01" "x = 1/2" for x
  2026         using that by (simp add: g2(2) mult.commute continuous_map_from_subtopology)
  2027     qed (auto simp: g1 g2)
  2028   qed (auto simp: g1 g2)
  2029 qed
  2030 
  2031 
  2032 lemma path_component_of_mono:
  2033    "\<lbrakk>path_component_of (subtopology X S) x y; S \<subseteq> T\<rbrakk> \<Longrightarrow> path_component_of (subtopology X T) x y"
  2034   unfolding path_component_of_def
  2035   by (metis subsetD pathin_subtopology)
  2036 
  2037 
  2038 lemma path_component_of:
  2039   "path_component_of X x y \<longleftrightarrow> (\<exists>T. path_connectedin X T \<and> x \<in> T \<and> y \<in> T)"
  2040   apply (auto simp: path_component_of_def)
  2041   using path_connectedin_path_image apply fastforce
  2042   apply (metis path_connectedin)
  2043   done
  2044 
  2045 lemma path_component_of_set:
  2046    "path_component_of X x y \<longleftrightarrow> (\<exists>g. pathin X g \<and> g 0 = x \<and> g 1 = y)"
  2047   by (auto simp: path_component_of_def)
  2048 
  2049 lemma path_component_of_subset_topspace:
  2050    "Collect(path_component_of X x) \<subseteq> topspace X"
  2051   using path_component_in_topspace by fastforce
  2052 
  2053 lemma path_component_of_eq_empty:
  2054    "Collect(path_component_of X x) = {} \<longleftrightarrow> (x \<notin> topspace X)"
  2055   using path_component_in_topspace path_component_of_refl by fastforce
  2056 
  2057 lemma path_connected_space_iff_path_component:
  2058    "path_connected_space X \<longleftrightarrow> (\<forall>x \<in> topspace X. \<forall>y \<in> topspace X. path_component_of X x y)"
  2059   by (simp add: path_component_of path_connected_space_subconnected)
  2060 
  2061 lemma path_connected_space_imp_path_component_of:
  2062    "\<lbrakk>path_connected_space X; a \<in> topspace X; b \<in> topspace X\<rbrakk>
  2063         \<Longrightarrow> path_component_of X a b"
  2064   by (simp add: path_connected_space_iff_path_component)
  2065 
  2066 lemma path_connected_space_path_component_set:
  2067    "path_connected_space X \<longleftrightarrow> (\<forall>x \<in> topspace X. Collect(path_component_of X x) = topspace X)"
  2068   using path_component_of_subset_topspace path_connected_space_iff_path_component by fastforce
  2069 
  2070 lemma path_component_of_maximal:
  2071    "\<lbrakk>path_connectedin X s; x \<in> s\<rbrakk> \<Longrightarrow> s \<subseteq> Collect(path_component_of X x)"
  2072   using path_component_of by fastforce
  2073 
  2074 lemma path_component_of_equiv:
  2075    "path_component_of X x y \<longleftrightarrow> x \<in> topspace X \<and> y \<in> topspace X \<and> path_component_of X x = path_component_of X y"
  2076     (is "?lhs = ?rhs")
  2077 proof
  2078   assume ?lhs
  2079   then show ?rhs
  2080     apply (simp add: fun_eq_iff path_component_in_topspace)
  2081     apply (meson path_component_of_sym path_component_of_trans)
  2082     done
  2083 qed (simp add: path_component_of_refl)
  2084 
  2085 lemma path_component_of_disjoint:
  2086      "disjnt (Collect (path_component_of X x)) (Collect (path_component_of X y)) \<longleftrightarrow>
  2087       ~(path_component_of X x y)"
  2088   by (force simp: disjnt_def path_component_of_eq_empty path_component_of_equiv)
  2089 
  2090 lemma path_component_of_eq:
  2091    "path_component_of X x = path_component_of X y \<longleftrightarrow>
  2092         (x \<notin> topspace X) \<and> (y \<notin> topspace X) \<or>
  2093         x \<in> topspace X \<and> y \<in> topspace X \<and> path_component_of X x y"
  2094   by (metis Collect_empty_eq_bot path_component_of_eq_empty path_component_of_equiv)
  2095 
  2096 lemma path_connectedin_path_component_of:
  2097   "path_connectedin X (Collect (path_component_of X x))"
  2098 proof -
  2099   have "\<And>y. path_component_of X x y
  2100         \<Longrightarrow> path_component_of (subtopology X (Collect (path_component_of X x))) x y"
  2101     by (meson path_component_of path_component_of_maximal path_connectedin_subtopology)
  2102   then show ?thesis
  2103     apply (simp add: path_connectedin_def path_component_of_subset_topspace path_connected_space_iff_path_component)
  2104     by (metis Int_absorb1 mem_Collect_eq path_component_of_equiv path_component_of_subset_topspace topspace_subtopology)
  2105 qed
  2106 
  2107 lemma Union_path_components_of:
  2108      "\<Union>(path_components_of X) = topspace X"
  2109   by (auto simp: path_components_of_def path_component_of_equiv)
  2110 
  2111 lemma path_components_of_maximal:
  2112    "\<lbrakk>C \<in> path_components_of X; path_connectedin X S; ~disjnt C S\<rbrakk> \<Longrightarrow> S \<subseteq> C"
  2113   apply (auto simp: path_components_of_def path_component_of_equiv)
  2114   using path_component_of_maximal path_connectedin_def apply fastforce
  2115   by (meson disjnt_subset2 path_component_of_disjoint path_component_of_equiv path_component_of_maximal)
  2116 
  2117 lemma pairwise_disjoint_path_components_of:
  2118      "pairwise disjnt (path_components_of X)"
  2119   by (auto simp: path_components_of_def pairwise_def path_component_of_disjoint path_component_of_equiv)
  2120 
  2121 lemma complement_path_components_of_Union:
  2122    "C \<in> path_components_of X
  2123         \<Longrightarrow> topspace X - C = \<Union>(path_components_of X - {C})"
  2124   by (metis Diff_cancel Diff_subset Union_path_components_of cSup_singleton diff_Union_pairwise_disjoint insert_subset pairwise_disjoint_path_components_of)
  2125 
  2126 lemma nonempty_path_components_of:
  2127   "C \<in> path_components_of X \<Longrightarrow> (C \<noteq> {})"
  2128   apply (clarsimp simp: path_components_of_def path_component_of_eq_empty)
  2129   by (meson path_component_of_refl)
  2130 
  2131 lemma path_components_of_subset: "C \<in> path_components_of X \<Longrightarrow> C \<subseteq> topspace X"
  2132   by (auto simp: path_components_of_def path_component_of_equiv)
  2133 
  2134 lemma path_connectedin_path_components_of:
  2135    "C \<in> path_components_of X \<Longrightarrow> path_connectedin X C"
  2136   by (auto simp: path_components_of_def path_connectedin_path_component_of)
  2137 
  2138 lemma path_component_in_path_components_of:
  2139   "Collect (path_component_of X a) \<in> path_components_of X \<longleftrightarrow> a \<in> topspace X"
  2140   apply (rule iffI)
  2141   using nonempty_path_components_of path_component_of_eq_empty apply fastforce
  2142   by (simp add: path_components_of_def)
  2143 
  2144 lemma path_connectedin_Union:
  2145   assumes \<A>: "\<And>S. S \<in> \<A> \<Longrightarrow> path_connectedin X S" "\<Inter>\<A> \<noteq> {}"
  2146   shows "path_connectedin X (\<Union>\<A>)"
  2147 proof -
  2148   obtain a where "\<And>S. S \<in> \<A> \<Longrightarrow> a \<in> S"
  2149     using assms by blast
  2150   then have "\<And>x. x \<in> topspace (subtopology X (\<Union>\<A>)) \<Longrightarrow> path_component_of (subtopology X (\<Union>\<A>)) a x"
  2151     apply (simp add: topspace_subtopology)
  2152     by (meson Union_upper \<A> path_component_of path_connectedin_subtopology)
  2153   then show ?thesis
  2154     using \<A> unfolding path_connectedin_def
  2155     by (metis Sup_le_iff path_component_of_equiv path_connected_space_iff_path_component)
  2156 qed
  2157 
  2158 lemma path_connectedin_Un:
  2159    "\<lbrakk>path_connectedin X S; path_connectedin X T; S \<inter> T \<noteq> {}\<rbrakk>
  2160     \<Longrightarrow> path_connectedin X (S \<union> T)"
  2161   by (blast intro: path_connectedin_Union [of "{S,T}", simplified])
  2162 
  2163 lemma path_connected_space_iff_components_eq:
  2164   "path_connected_space X \<longleftrightarrow>
  2165     (\<forall>C \<in> path_components_of X. \<forall>C' \<in> path_components_of X. C = C')"
  2166   unfolding path_components_of_def
  2167 proof (intro iffI ballI)
  2168   assume "\<forall>C \<in> path_component_of_set X ` topspace X.
  2169              \<forall>C' \<in> path_component_of_set X ` topspace X. C = C'"
  2170   then show "path_connected_space X"
  2171     using path_component_of_refl path_connected_space_iff_path_component by fastforce
  2172 qed (auto simp: path_connected_space_path_component_set)
  2173 
  2174 lemma path_components_of_eq_empty:
  2175    "path_components_of X = {} \<longleftrightarrow> topspace X = {}"
  2176   using Union_path_components_of nonempty_path_components_of by fastforce
  2177 
  2178 lemma path_components_of_empty_space:
  2179    "topspace X = {} \<Longrightarrow> path_components_of X = {}"
  2180   by (simp add: path_components_of_eq_empty)
  2181 
  2182 lemma path_components_of_subset_singleton:
  2183   "path_components_of X \<subseteq> {S} \<longleftrightarrow>
  2184         path_connected_space X \<and> (topspace X = {} \<or> topspace X = S)"
  2185 proof (cases "topspace X = {}")
  2186   case True
  2187   then show ?thesis
  2188     by (auto simp: path_components_of_empty_space path_connected_space_topspace_empty)
  2189 next
  2190   case False
  2191   have "(path_components_of X = {S}) \<longleftrightarrow> (path_connected_space X \<and> topspace X = S)"
  2192   proof (intro iffI conjI)
  2193     assume L: "path_components_of X = {S}"
  2194     then show "path_connected_space X"
  2195       by (simp add: path_connected_space_iff_components_eq)
  2196     show "topspace X = S"
  2197       by (metis L ccpo_Sup_singleton [of S] Union_path_components_of)
  2198   next
  2199     assume R: "path_connected_space X \<and> topspace X = S"
  2200     then show "path_components_of X = {S}"
  2201       using ccpo_Sup_singleton [of S]
  2202       by (metis False all_not_in_conv insert_iff mk_disjoint_insert path_component_in_path_components_of path_connected_space_iff_components_eq path_connected_space_path_component_set)
  2203   qed
  2204   with False show ?thesis
  2205     by (simp add: path_components_of_eq_empty subset_singleton_iff)
  2206 qed
  2207 
  2208 lemma path_connected_space_iff_components_subset_singleton:
  2209    "path_connected_space X \<longleftrightarrow> (\<exists>a. path_components_of X \<subseteq> {a})"
  2210   by (simp add: path_components_of_subset_singleton)
  2211 
  2212 lemma path_components_of_eq_singleton:
  2213    "path_components_of X = {S} \<longleftrightarrow> path_connected_space X \<and> topspace X \<noteq> {} \<and> S = topspace X"
  2214   by (metis cSup_singleton insert_not_empty path_components_of_subset_singleton subset_singleton_iff)
  2215 
  2216 lemma path_components_of_path_connected_space:
  2217    "path_connected_space X \<Longrightarrow> path_components_of X = (if topspace X = {} then {} else {topspace X})"
  2218   by (simp add: path_components_of_eq_empty path_components_of_eq_singleton)
  2219 
  2220 lemma path_component_subset_connected_component_of:
  2221    "path_component_of_set X x \<subseteq> connected_component_of_set X x"
  2222 proof (cases "x \<in> topspace X")
  2223   case True
  2224   then show ?thesis
  2225     by (simp add: connected_component_of_maximal path_component_of_refl path_connectedin_imp_connectedin path_connectedin_path_component_of)
  2226 next
  2227   case False
  2228   then show ?thesis
  2229     using path_component_of_eq_empty by fastforce
  2230 qed
  2231 
  2232 lemma exists_path_component_of_superset:
  2233   assumes S: "path_connectedin X S" and ne: "topspace X \<noteq> {}"
  2234   obtains C where "C \<in> path_components_of X" "S \<subseteq> C"
  2235 proof (cases "S = {}")
  2236   case True
  2237   then show ?thesis
  2238     using ne path_components_of_eq_empty that by fastforce
  2239 next
  2240   case False
  2241   then obtain a where "a \<in> S"
  2242     by blast
  2243   show ?thesis
  2244   proof
  2245     show "Collect (path_component_of X a) \<in> path_components_of X"
  2246       by (meson \<open>a \<in> S\<close> S subsetD path_component_in_path_components_of path_connectedin_subset_topspace)
  2247     show "S \<subseteq> Collect (path_component_of X a)"
  2248       by (simp add: S \<open>a \<in> S\<close> path_component_of_maximal)
  2249   qed
  2250 qed
  2251 
  2252 lemma path_component_of_eq_overlap:
  2253    "path_component_of X x = path_component_of X y \<longleftrightarrow>
  2254       (x \<notin> topspace X) \<and> (y \<notin> topspace X) \<or>
  2255       Collect (path_component_of X x) \<inter> Collect (path_component_of X y) \<noteq> {}"
  2256   by (metis disjnt_def empty_iff inf_bot_right mem_Collect_eq path_component_of_disjoint path_component_of_eq path_component_of_eq_empty)
  2257 
  2258 lemma path_component_of_nonoverlap:
  2259    "Collect (path_component_of X x) \<inter> Collect (path_component_of X y) = {} \<longleftrightarrow>
  2260     (x \<notin> topspace X) \<or> (y \<notin> topspace X) \<or>
  2261     path_component_of X x \<noteq> path_component_of X y"
  2262   by (metis inf.idem path_component_of_eq_empty path_component_of_eq_overlap)
  2263 
  2264 lemma path_component_of_overlap:
  2265    "Collect (path_component_of X x) \<inter> Collect (path_component_of X y) \<noteq> {} \<longleftrightarrow>
  2266     x \<in> topspace X \<and> y \<in> topspace X \<and> path_component_of X x = path_component_of X y"
  2267   by (meson path_component_of_nonoverlap)
  2268 
  2269 lemma path_components_of_disjoint:
  2270      "\<lbrakk>C \<in> path_components_of X; C' \<in> path_components_of X\<rbrakk> \<Longrightarrow> disjnt C C' \<longleftrightarrow> C \<noteq> C'"
  2271   by (auto simp: path_components_of_def path_component_of_disjoint path_component_of_equiv)
  2272 
  2273 lemma path_components_of_overlap:
  2274     "\<lbrakk>C \<in> path_components_of X; C' \<in> path_components_of X\<rbrakk> \<Longrightarrow> C \<inter> C' \<noteq> {} \<longleftrightarrow> C = C'"
  2275   by (auto simp: path_components_of_def path_component_of_equiv)
  2276 
  2277 lemma path_component_of_unique:
  2278    "\<lbrakk>x \<in> C; path_connectedin X C; \<And>C'. \<lbrakk>x \<in> C'; path_connectedin X C'\<rbrakk> \<Longrightarrow> C' \<subseteq> C\<rbrakk>
  2279         \<Longrightarrow> Collect (path_component_of X x) = C"
  2280   by (meson subsetD eq_iff path_component_of_maximal path_connectedin_path_component_of)
  2281 
  2282 lemma path_component_of_discrete_topology [simp]:
  2283   "Collect (path_component_of (discrete_topology U) x) = (if x \<in> U then {x} else {})"
  2284 proof -
  2285   have "\<And>C'. \<lbrakk>x \<in> C'; path_connectedin (discrete_topology U) C'\<rbrakk> \<Longrightarrow> C' \<subseteq> {x}"
  2286     by (metis path_connectedin_discrete_topology subsetD singletonD)
  2287   then have "x \<in> U \<Longrightarrow> Collect (path_component_of (discrete_topology U) x) = {x}"
  2288     by (simp add: path_component_of_unique)
  2289   then show ?thesis
  2290     using path_component_in_topspace by fastforce
  2291 qed
  2292 
  2293 lemma path_component_of_discrete_topology_iff [simp]:
  2294   "path_component_of (discrete_topology U) x y \<longleftrightarrow> x \<in> U \<and> y=x"
  2295   by (metis empty_iff insertI1 mem_Collect_eq path_component_of_discrete_topology singletonD)
  2296 
  2297 lemma path_components_of_discrete_topology [simp]:
  2298    "path_components_of (discrete_topology U) = (\<lambda>x. {x}) ` U"
  2299   by (auto simp: path_components_of_def image_def fun_eq_iff)
  2300 
  2301 lemma homeomorphic_map_path_component_of:
  2302   assumes f: "homeomorphic_map X Y f" and x: "x \<in> topspace X"
  2303   shows "Collect (path_component_of Y (f x)) = f ` Collect(path_component_of X x)"
  2304 proof -
  2305   obtain g where g: "homeomorphic_maps X Y f g"
  2306     using f homeomorphic_map_maps by blast
  2307   show ?thesis
  2308   proof
  2309     have "Collect (path_component_of Y (f x)) \<subseteq> topspace Y"
  2310       by (simp add: path_component_of_subset_topspace)
  2311     moreover have "g ` Collect(path_component_of Y (f x)) \<subseteq> Collect (path_component_of X (g (f x)))"
  2312       using g x unfolding homeomorphic_maps_def
  2313       by (metis f homeomorphic_imp_surjective_map imageI mem_Collect_eq path_component_of_maximal path_component_of_refl path_connectedin_continuous_map_image path_connectedin_path_component_of)
  2314     ultimately show "Collect (path_component_of Y (f x)) \<subseteq> f ` Collect (path_component_of X x)"
  2315       using g x unfolding homeomorphic_maps_def continuous_map_def image_iff subset_iff
  2316       by metis
  2317     show "f ` Collect (path_component_of X x) \<subseteq> Collect (path_component_of Y (f x))"
  2318     proof (rule path_component_of_maximal)
  2319       show "path_connectedin Y (f ` Collect (path_component_of X x))"
  2320         by (meson f homeomorphic_map_path_connectedness_eq path_connectedin_path_component_of)
  2321     qed (simp add: path_component_of_refl x)
  2322   qed
  2323 qed
  2324 
  2325 lemma homeomorphic_map_path_components_of:
  2326   assumes "homeomorphic_map X Y f"
  2327   shows "path_components_of Y = (image f) ` (path_components_of X)"
  2328   unfolding path_components_of_def homeomorphic_imp_surjective_map [OF assms, symmetric]
  2329   apply safe
  2330   using assms homeomorphic_map_path_component_of apply fastforce
  2331   by (metis assms homeomorphic_map_path_component_of imageI)
  2332 
  2333 
  2334 subsection \<open>Sphere is path-connected\<close>
  2335 
  2336 lemma path_connected_punctured_universe:
  2337   assumes "2 \<le> DIM('a::euclidean_space)"
  2338   shows "path_connected (- {a::'a})"
  2339 proof -
  2340   let ?A = "{x::'a. \<exists>i\<in>Basis. x \<bullet> i < a \<bullet> i}"
  2341   let ?B = "{x::'a. \<exists>i\<in>Basis. a \<bullet> i < x \<bullet> i}"
  2342 
  2343   have A: "path_connected ?A"
  2344     unfolding Collect_bex_eq
  2345   proof (rule path_connected_UNION)
  2346     fix i :: 'a
  2347     assume "i \<in> Basis"
  2348     then show "(\<Sum>i\<in>Basis. (a \<bullet> i - 1)*\<^sub>R i) \<in> {x::'a. x \<bullet> i < a \<bullet> i}"
  2349       by simp
  2350     show "path_connected {x. x \<bullet> i < a \<bullet> i}"
  2351       using convex_imp_path_connected [OF convex_halfspace_lt, of i "a \<bullet> i"]
  2352       by (simp add: inner_commute)
  2353   qed
  2354   have B: "path_connected ?B"
  2355     unfolding Collect_bex_eq
  2356   proof (rule path_connected_UNION)
  2357     fix i :: 'a
  2358     assume "i \<in> Basis"
  2359     then show "(\<Sum>i\<in>Basis. (a \<bullet> i + 1) *\<^sub>R i) \<in> {x::'a. a \<bullet> i < x \<bullet> i}"
  2360       by simp
  2361     show "path_connected {x. a \<bullet> i < x \<bullet> i}"
  2362       using convex_imp_path_connected [OF convex_halfspace_gt, of "a \<bullet> i" i]
  2363       by (simp add: inner_commute)
  2364   qed
  2365   obtain S :: "'a set" where "S \<subseteq> Basis" and "card S = Suc (Suc 0)"
  2366     using ex_card[OF assms]
  2367     by auto
  2368   then obtain b0 b1 :: 'a where "b0 \<in> Basis" and "b1 \<in> Basis" and "b0 \<noteq> b1"
  2369     unfolding card_Suc_eq by auto
  2370   then have "a + b0 - b1 \<in> ?A \<inter> ?B"
  2371     by (auto simp: inner_simps inner_Basis)
  2372   then have "?A \<inter> ?B \<noteq> {}"
  2373     by fast
  2374   with A B have "path_connected (?A \<union> ?B)"
  2375     by (rule path_connected_Un)
  2376   also have "?A \<union> ?B = {x. \<exists>i\<in>Basis. x \<bullet> i \<noteq> a \<bullet> i}"
  2377     unfolding neq_iff bex_disj_distrib Collect_disj_eq ..
  2378   also have "\<dots> = {x. x \<noteq> a}"
  2379     unfolding euclidean_eq_iff [where 'a='a]
  2380     by (simp add: Bex_def)
  2381   also have "\<dots> = - {a}"
  2382     by auto
  2383   finally show ?thesis .
  2384 qed
  2385 
  2386 corollary connected_punctured_universe:
  2387   "2 \<le> DIM('N::euclidean_space) \<Longrightarrow> connected(- {a::'N})"
  2388   by (simp add: path_connected_punctured_universe path_connected_imp_connected)
  2389 
  2390 proposition path_connected_sphere:
  2391   fixes a :: "'a :: euclidean_space"
  2392   assumes "2 \<le> DIM('a)"
  2393   shows "path_connected(sphere a r)"
  2394 proof (cases r "0::real" rule: linorder_cases)
  2395   case less
  2396   then show ?thesis
  2397     by (simp add: path_connected_empty)
  2398 next
  2399   case equal
  2400   then show ?thesis
  2401     by (simp add: path_connected_singleton)
  2402 next
  2403   case greater
  2404   then have eq: "(sphere (0::'a) r) = (\<lambda>x. (r / norm x) *\<^sub>R x) ` (- {0::'a})"
  2405     by (force simp: image_iff split: if_split_asm)
  2406   have "continuous_on (- {0::'a}) (\<lambda>x. (r / norm x) *\<^sub>R x)"
  2407     by (intro continuous_intros) auto
  2408   then have "path_connected ((\<lambda>x. (r / norm x) *\<^sub>R x) ` (- {0::'a}))"
  2409     by (intro path_connected_continuous_image path_connected_punctured_universe assms)
  2410   with eq have "path_connected (sphere (0::'a) r)"
  2411     by auto
  2412   then have "path_connected((+) a ` (sphere (0::'a) r))"
  2413     by (simp add: path_connected_translation)
  2414   then show ?thesis
  2415     by (metis add.right_neutral sphere_translation)
  2416 qed
  2417 
  2418 lemma connected_sphere:
  2419     fixes a :: "'a :: euclidean_space"
  2420     assumes "2 \<le> DIM('a)"
  2421       shows "connected(sphere a r)"
  2422   using path_connected_sphere [OF assms]
  2423   by (simp add: path_connected_imp_connected)
  2424 
  2425 
  2426 corollary path_connected_complement_bounded_convex:
  2427     fixes s :: "'a :: euclidean_space set"
  2428     assumes "bounded s" "convex s" and 2: "2 \<le> DIM('a)"
  2429     shows "path_connected (- s)"
  2430 proof (cases "s = {}")
  2431   case True then show ?thesis
  2432     using convex_imp_path_connected by auto
  2433 next
  2434   case False
  2435   then obtain a where "a \<in> s" by auto
  2436   { fix x y assume "x \<notin> s" "y \<notin> s"
  2437     then have "x \<noteq> a" "y \<noteq> a" using \<open>a \<in> s\<close> by auto
  2438     then have bxy: "bounded(insert x (insert y s))"
  2439       by (simp add: \<open>bounded s\<close>)
  2440     then obtain B::real where B: "0 < B" and Bx: "norm (a - x) < B" and By: "norm (a - y) < B"
  2441                           and "s \<subseteq> ball a B"
  2442       using bounded_subset_ballD [OF bxy, of a] by (auto simp: dist_norm)
  2443     define C where "C = B / norm(x - a)"
  2444     { fix u
  2445       assume u: "(1 - u) *\<^sub>R x + u *\<^sub>R (a + C *\<^sub>R (x - a)) \<in> s" and "0 \<le> u" "u \<le> 1"
  2446       have CC: "1 \<le> 1 + (C - 1) * u"
  2447         using \<open>x \<noteq> a\<close> \<open>0 \<le> u\<close>
  2448         apply (simp add: C_def divide_simps norm_minus_commute)
  2449         using Bx by auto
  2450       have *: "\<And>v. (1 - u) *\<^sub>R x + u *\<^sub>R (a + v *\<^sub>R (x - a)) = a + (1 + (v - 1) * u) *\<^sub>R (x - a)"
  2451         by (simp add: algebra_simps)
  2452       have "a + ((1 / (1 + C * u - u)) *\<^sub>R x + ((u / (1 + C * u - u)) *\<^sub>R a + (C * u / (1 + C * u - u)) *\<^sub>R x)) =
  2453             (1 + (u / (1 + C * u - u))) *\<^sub>R a + ((1 / (1 + C * u - u)) + (C * u / (1 + C * u - u))) *\<^sub>R x"
  2454         by (simp add: algebra_simps)
  2455       also have "\<dots> = (1 + (u / (1 + C * u - u))) *\<^sub>R a + (1 + (u / (1 + C * u - u))) *\<^sub>R x"
  2456         using CC by (simp add: field_simps)
  2457       also have "\<dots> = x + (1 + (u / (1 + C * u - u))) *\<^sub>R a + (u / (1 + C * u - u)) *\<^sub>R x"
  2458         by (simp add: algebra_simps)
  2459       also have "\<dots> = x + ((1 / (1 + C * u - u)) *\<^sub>R a +
  2460               ((u / (1 + C * u - u)) *\<^sub>R x + (C * u / (1 + C * u - u)) *\<^sub>R a))"
  2461         using CC by (simp add: field_simps) (simp add: add_divide_distrib scaleR_add_left)
  2462       finally have xeq: "(1 - 1 / (1 + (C - 1) * u)) *\<^sub>R a + (1 / (1 + (C - 1) * u)) *\<^sub>R (a + (1 + (C - 1) * u) *\<^sub>R (x - a)) = x"
  2463         by (simp add: algebra_simps)
  2464       have False
  2465         using \<open>convex s\<close>
  2466         apply (simp add: convex_alt)
  2467         apply (drule_tac x=a in bspec)
  2468          apply (rule  \<open>a \<in> s\<close>)
  2469         apply (drule_tac x="a + (1 + (C - 1) * u) *\<^sub>R (x - a)" in bspec)
  2470          using u apply (simp add: *)
  2471         apply (drule_tac x="1 / (1 + (C - 1) * u)" in spec)
  2472         using \<open>x \<noteq> a\<close> \<open>x \<notin> s\<close> \<open>0 \<le> u\<close> CC
  2473         apply (auto simp: xeq)
  2474         done
  2475     }
  2476     then have pcx: "path_component (- s) x (a + C *\<^sub>R (x - a))"
  2477       by (force simp: closed_segment_def intro!: path_component_linepath)
  2478     define D where "D = B / norm(y - a)"  \<comment> \<open>massive duplication with the proof above\<close>
  2479     { fix u
  2480       assume u: "(1 - u) *\<^sub>R y + u *\<^sub>R (a + D *\<^sub>R (y - a)) \<in> s" and "0 \<le> u" "u \<le> 1"
  2481       have DD: "1 \<le> 1 + (D - 1) * u"
  2482         using \<open>y \<noteq> a\<close> \<open>0 \<le> u\<close>
  2483         apply (simp add: D_def divide_simps norm_minus_commute)
  2484         using By by auto
  2485       have *: "\<And>v. (1 - u) *\<^sub>R y + u *\<^sub>R (a + v *\<^sub>R (y - a)) = a + (1 + (v - 1) * u) *\<^sub>R (y - a)"
  2486         by (simp add: algebra_simps)
  2487       have "a + ((1 / (1 + D * u - u)) *\<^sub>R y + ((u / (1 + D * u - u)) *\<^sub>R a + (D * u / (1 + D * u - u)) *\<^sub>R y)) =
  2488             (1 + (u / (1 + D * u - u))) *\<^sub>R a + ((1 / (1 + D * u - u)) + (D * u / (1 + D * u - u))) *\<^sub>R y"
  2489         by (simp add: algebra_simps)
  2490       also have "\<dots> = (1 + (u / (1 + D * u - u))) *\<^sub>R a + (1 + (u / (1 + D * u - u))) *\<^sub>R y"
  2491         using DD by (simp add: field_simps)
  2492       also have "\<dots> = y + (1 + (u / (1 + D * u - u))) *\<^sub>R a + (u / (1 + D * u - u)) *\<^sub>R y"
  2493         by (simp add: algebra_simps)
  2494       also have "\<dots> = y + ((1 / (1 + D * u - u)) *\<^sub>R a +
  2495               ((u / (1 + D * u - u)) *\<^sub>R y + (D * u / (1 + D * u - u)) *\<^sub>R a))"
  2496         using DD by (simp add: field_simps) (simp add: add_divide_distrib scaleR_add_left)
  2497       finally have xeq: "(1 - 1 / (1 + (D - 1) * u)) *\<^sub>R a + (1 / (1 + (D - 1) * u)) *\<^sub>R (a + (1 + (D - 1) * u) *\<^sub>R (y - a)) = y"
  2498         by (simp add: algebra_simps)
  2499       have False
  2500         using \<open>convex s\<close>
  2501         apply (simp add: convex_alt)
  2502         apply (drule_tac x=a in bspec)
  2503          apply (rule  \<open>a \<in> s\<close>)
  2504         apply (drule_tac x="a + (1 + (D - 1) * u) *\<^sub>R (y - a)" in bspec)
  2505          using u apply (simp add: *)
  2506         apply (drule_tac x="1 / (1 + (D - 1) * u)" in spec)
  2507         using \<open>y \<noteq> a\<close> \<open>y \<notin> s\<close> \<open>0 \<le> u\<close> DD
  2508         apply (auto simp: xeq)
  2509         done
  2510     }
  2511     then have pdy: "path_component (- s) y (a + D *\<^sub>R (y - a))"
  2512       by (force simp: closed_segment_def intro!: path_component_linepath)
  2513     have pyx: "path_component (- s) (a + D *\<^sub>R (y - a)) (a + C *\<^sub>R (x - a))"
  2514       apply (rule path_component_of_subset [of "sphere a B"])
  2515        using \<open>s \<subseteq> ball a B\<close>
  2516        apply (force simp: ball_def dist_norm norm_minus_commute)
  2517       apply (rule path_connected_sphere [OF 2, of a B, simplified path_connected_component, rule_format])
  2518        using \<open>x \<noteq> a\<close>  using \<open>y \<noteq> a\<close>  B apply (auto simp: dist_norm C_def D_def)
  2519       done
  2520     have "path_component (- s) x y"
  2521       by (metis path_component_trans path_component_sym pcx pdy pyx)
  2522   }
  2523   then show ?thesis
  2524     by (auto simp: path_connected_component)
  2525 qed
  2526 
  2527 lemma connected_complement_bounded_convex:
  2528     fixes s :: "'a :: euclidean_space set"
  2529     assumes "bounded s" "convex s" "2 \<le> DIM('a)"
  2530       shows  "connected (- s)"
  2531   using path_connected_complement_bounded_convex [OF assms] path_connected_imp_connected by blast
  2532 
  2533 lemma connected_diff_ball:
  2534     fixes s :: "'a :: euclidean_space set"
  2535     assumes "connected s" "cball a r \<subseteq> s" "2 \<le> DIM('a)"
  2536       shows "connected (s - ball a r)"
  2537   apply (rule connected_diff_open_from_closed [OF ball_subset_cball])
  2538   using assms connected_sphere
  2539   apply (auto simp: cball_diff_eq_sphere dist_norm)
  2540   done
  2541 
  2542 proposition connected_open_delete:
  2543   assumes "open S" "connected S" and 2: "2 \<le> DIM('N::euclidean_space)"
  2544     shows "connected(S - {a::'N})"
  2545 proof (cases "a \<in> S")
  2546   case True
  2547   with \<open>open S\<close> obtain \<epsilon> where "\<epsilon> > 0" and \<epsilon>: "cball a \<epsilon> \<subseteq> S"
  2548     using open_contains_cball_eq by blast
  2549   have "dist a (a + \<epsilon> *\<^sub>R (SOME i. i \<in> Basis)) = \<epsilon>"
  2550     by (simp add: dist_norm SOME_Basis \<open>0 < \<epsilon>\<close> less_imp_le)
  2551   with \<epsilon> have "\<Inter>{S - ball a r |r. 0 < r \<and> r < \<epsilon>} \<subseteq> {} \<Longrightarrow> False"
  2552     apply (drule_tac c="a + scaleR (\<epsilon>) ((SOME i. i \<in> Basis))" in subsetD)
  2553     by auto
  2554   then have nonemp: "(\<Inter>{S - ball a r |r. 0 < r \<and> r < \<epsilon>}) = {} \<Longrightarrow> False"
  2555     by auto
  2556   have con: "\<And>r. r < \<epsilon> \<Longrightarrow> connected (S - ball a r)"
  2557     using \<epsilon> by (force intro: connected_diff_ball [OF \<open>connected S\<close> _ 2])
  2558   have "x \<in> \<Union>{S - ball a r |r. 0 < r \<and> r < \<epsilon>}" if "x \<in> S - {a}" for x
  2559     apply (rule UnionI [of "S - ball a (min \<epsilon> (dist a x) / 2)"])
  2560      using that \<open>0 < \<epsilon>\<close> apply simp_all
  2561     apply (rule_tac x="min \<epsilon> (dist a x) / 2" in exI)
  2562     apply auto
  2563     done
  2564   then have "S - {a} = \<Union>{S - ball a r | r. 0 < r \<and> r < \<epsilon>}"
  2565     by auto
  2566   then show ?thesis
  2567     by (auto intro: connected_Union con dest!: nonemp)
  2568 next
  2569   case False then show ?thesis
  2570     by (simp add: \<open>connected S\<close>)
  2571 qed
  2572 
  2573 corollary path_connected_open_delete:
  2574   assumes "open S" "connected S" and 2: "2 \<le> DIM('N::euclidean_space)"
  2575     shows "path_connected(S - {a::'N})"
  2576 by (simp add: assms connected_open_delete connected_open_path_connected open_delete)
  2577 
  2578 corollary path_connected_punctured_ball:
  2579    "2 \<le> DIM('N::euclidean_space) \<Longrightarrow> path_connected(ball a r - {a::'N})"
  2580 by (simp add: path_connected_open_delete)
  2581 
  2582 corollary connected_punctured_ball:
  2583    "2 \<le> DIM('N::euclidean_space) \<Longrightarrow> connected(ball a r - {a::'N})"
  2584 by (simp add: connected_open_delete)
  2585 
  2586 corollary connected_open_delete_finite:
  2587   fixes S T::"'a::euclidean_space set"
  2588   assumes S: "open S" "connected S" and 2: "2 \<le> DIM('a)" and "finite T"
  2589   shows "connected(S - T)"
  2590   using \<open>finite T\<close> S
  2591 proof (induct T)
  2592   case empty
  2593   show ?case using \<open>connected S\<close> by simp
  2594 next
  2595   case (insert x F)
  2596   then have "connected (S-F)" by auto
  2597   moreover have "open (S - F)" using finite_imp_closed[OF \<open>finite F\<close>] \<open>open S\<close> by auto
  2598   ultimately have "connected (S - F - {x})" using connected_open_delete[OF _ _ 2] by auto
  2599   thus ?case by (metis Diff_insert)
  2600 qed
  2601 
  2602 lemma sphere_1D_doubleton_zero:
  2603   assumes 1: "DIM('a) = 1" and "r > 0"
  2604   obtains x y::"'a::euclidean_space"
  2605     where "sphere 0 r = {x,y} \<and> dist x y = 2*r"
  2606 proof -
  2607   obtain b::'a where b: "Basis = {b}"
  2608     using 1 card_1_singletonE by blast
  2609   show ?thesis
  2610   proof (intro that conjI)
  2611     have "x = norm x *\<^sub>R b \<or> x = - norm x *\<^sub>R b" if "r = norm x" for x
  2612     proof -
  2613       have xb: "(x \<bullet> b) *\<^sub>R b = x"
  2614         using euclidean_representation [of x, unfolded b] by force
  2615       then have "norm ((x \<bullet> b) *\<^sub>R b) = norm x"
  2616         by simp
  2617       with b have "\<bar>x \<bullet> b\<bar> = norm x"
  2618         using norm_Basis by (simp add: b)
  2619       with xb show ?thesis
  2620         apply (simp add: abs_if split: if_split_asm)
  2621         apply (metis add.inverse_inverse real_vector.scale_minus_left xb)
  2622         done
  2623     qed
  2624     with \<open>r > 0\<close> b show "sphere 0 r = {r *\<^sub>R b, - r *\<^sub>R b}"
  2625       by (force simp: sphere_def dist_norm)
  2626     have "dist (r *\<^sub>R b) (- r *\<^sub>R b) = norm (r *\<^sub>R b + r *\<^sub>R b)"
  2627       by (simp add: dist_norm)
  2628     also have "\<dots> = norm ((2*r) *\<^sub>R b)"
  2629       by (metis mult_2 scaleR_add_left)
  2630     also have "\<dots> = 2*r"
  2631       using \<open>r > 0\<close> b norm_Basis by fastforce
  2632     finally show "dist (r *\<^sub>R b) (- r *\<^sub>R b) = 2*r" .
  2633   qed
  2634 qed
  2635 
  2636 lemma sphere_1D_doubleton:
  2637   fixes a :: "'a :: euclidean_space"
  2638   assumes "DIM('a) = 1" and "r > 0"
  2639   obtains x y where "sphere a r = {x,y} \<and> dist x y = 2*r"
  2640 proof -
  2641   have "sphere a r = (+) a ` sphere 0 r"
  2642     by (metis add.right_neutral sphere_translation)
  2643   then show ?thesis
  2644     using sphere_1D_doubleton_zero [OF assms]
  2645     by (metis (mono_tags, lifting) dist_add_cancel image_empty image_insert that)
  2646 qed
  2647 
  2648 lemma psubset_sphere_Compl_connected:
  2649   fixes S :: "'a::euclidean_space set"
  2650   assumes S: "S \<subset> sphere a r" and "0 < r" and 2: "2 \<le> DIM('a)"
  2651   shows "connected(- S)"
  2652 proof -
  2653   have "S \<subseteq> sphere a r"
  2654     using S by blast
  2655   obtain b where "dist a b = r" and "b \<notin> S"
  2656     using S mem_sphere by blast
  2657   have CS: "- S = {x. dist a x \<le> r \<and> (x \<notin> S)} \<union> {x. r \<le> dist a x \<and> (x \<notin> S)}"
  2658     by auto
  2659   have "{x. dist a x \<le> r \<and> x \<notin> S} \<inter> {x. r \<le> dist a x \<and> x \<notin> S} \<noteq> {}"
  2660     using \<open>b \<notin> S\<close> \<open>dist a b = r\<close> by blast
  2661   moreover have "connected {x. dist a x \<le> r \<and> x \<notin> S}"
  2662     apply (rule connected_intermediate_closure [of "ball a r"])
  2663     using assms by auto
  2664   moreover
  2665   have "connected {x. r \<le> dist a x \<and> x \<notin> S}"
  2666     apply (rule connected_intermediate_closure [of "- cball a r"])
  2667     using assms apply (auto intro: connected_complement_bounded_convex)
  2668     apply (metis ComplI interior_cball interior_closure mem_ball not_less)
  2669     done
  2670   ultimately show ?thesis
  2671     by (simp add: CS connected_Un)
  2672 qed
  2673 
  2674 
  2675 subsection\<open>Every annulus is a connected set\<close>
  2676 
  2677 lemma path_connected_2DIM_I:
  2678   fixes a :: "'N::euclidean_space"
  2679   assumes 2: "2 \<le> DIM('N)" and pc: "path_connected {r. 0 \<le> r \<and> P r}"
  2680   shows "path_connected {x. P(norm(x - a))}"
  2681 proof -
  2682   have "{x. P(norm(x - a))} = (+) a ` {x. P(norm x)}"
  2683     by force
  2684   moreover have "path_connected {x::'N. P(norm x)}"
  2685   proof -
  2686     let ?D = "{x. 0 \<le> x \<and> P x} \<times> sphere (0::'N) 1"
  2687     have "x \<in> (\<lambda>z. fst z *\<^sub>R snd z) ` ?D"
  2688       if "P (norm x)" for x::'N
  2689     proof (cases "x=0")
  2690       case True
  2691       with that show ?thesis
  2692         apply (simp add: image_iff)
  2693         apply (rule_tac x=0 in exI, simp)
  2694         using vector_choose_size zero_le_one by blast
  2695     next
  2696       case False
  2697       with that show ?thesis
  2698         by (rule_tac x="(norm x, x /\<^sub>R norm x)" in image_eqI) auto
  2699     qed
  2700     then have *: "{x::'N. P(norm x)} =  (\<lambda>z. fst z *\<^sub>R snd z) ` ?D"
  2701       by auto
  2702     have "continuous_on ?D (\<lambda>z:: real\<times>'N. fst z *\<^sub>R snd z)"
  2703       by (intro continuous_intros)
  2704     moreover have "path_connected ?D"
  2705       by (metis path_connected_Times [OF pc] path_connected_sphere 2)
  2706     ultimately show ?thesis
  2707       apply (subst *)
  2708       apply (rule path_connected_continuous_image, auto)
  2709       done
  2710   qed
  2711   ultimately show ?thesis
  2712     using path_connected_translation by metis
  2713 qed
  2714 
  2715 proposition path_connected_annulus:
  2716   fixes a :: "'N::euclidean_space"
  2717   assumes "2 \<le> DIM('N)"
  2718   shows "path_connected {x. r1 < norm(x - a) \<and> norm(x - a) < r2}"
  2719         "path_connected {x. r1 < norm(x - a) \<and> norm(x - a) \<le> r2}"
  2720         "path_connected {x. r1 \<le> norm(x - a) \<and> norm(x - a) < r2}"
  2721         "path_connected {x. r1 \<le> norm(x - a) \<and> norm(x - a) \<le> r2}"
  2722   by (auto simp: is_interval_def intro!: is_interval_convex convex_imp_path_connected path_connected_2DIM_I [OF assms])
  2723 
  2724 proposition connected_annulus:
  2725   fixes a :: "'N::euclidean_space"
  2726   assumes "2 \<le> DIM('N::euclidean_space)"
  2727   shows "connected {x. r1 < norm(x - a) \<and> norm(x - a) < r2}"
  2728         "connected {x. r1 < norm(x - a) \<and> norm(x - a) \<le> r2}"
  2729         "connected {x. r1 \<le> norm(x - a) \<and> norm(x - a) < r2}"
  2730         "connected {x. r1 \<le> norm(x - a) \<and> norm(x - a) \<le> r2}"
  2731   by (auto simp: path_connected_annulus [OF assms] path_connected_imp_connected)
  2732 
  2733 
  2734 subsection%unimportant\<open>Relations between components and path components\<close>
  2735 
  2736 lemma open_connected_component:
  2737   fixes s :: "'a::real_normed_vector set"
  2738   shows "open s \<Longrightarrow> open (connected_component_set s x)"
  2739     apply (simp add: open_contains_ball, clarify)
  2740     apply (rename_tac y)
  2741     apply (drule_tac x=y in bspec)
  2742      apply (simp add: connected_component_in, clarify)
  2743     apply (rule_tac x=e in exI)
  2744     by (metis mem_Collect_eq connected_component_eq connected_component_maximal centre_in_ball connected_ball)
  2745 
  2746 corollary open_components:
  2747     fixes s :: "'a::real_normed_vector set"
  2748     shows "\<lbrakk>open u; s \<in> components u\<rbrakk> \<Longrightarrow> open s"
  2749   by (simp add: components_iff) (metis open_connected_component)
  2750 
  2751 lemma in_closure_connected_component:
  2752   fixes s :: "'a::real_normed_vector set"
  2753   assumes x: "x \<in> s" and s: "open s"
  2754   shows "x \<in> closure (connected_component_set s y) \<longleftrightarrow>  x \<in> connected_component_set s y"
  2755 proof -
  2756   { assume "x \<in> closure (connected_component_set s y)"
  2757     moreover have "x \<in> connected_component_set s x"
  2758       using x by simp
  2759     ultimately have "x \<in> connected_component_set s y"
  2760       using s by (meson Compl_disjoint closure_iff_nhds_not_empty connected_component_disjoint disjoint_eq_subset_Compl open_connected_component)
  2761   }
  2762   then show ?thesis
  2763     by (auto simp: closure_def)
  2764 qed
  2765 
  2766 lemma connected_disjoint_Union_open_pick:
  2767   assumes "pairwise disjnt B"
  2768           "\<And>S. S \<in> A \<Longrightarrow> connected S \<and> S \<noteq> {}"
  2769           "\<And>S. S \<in> B \<Longrightarrow> open S"
  2770           "\<Union>A \<subseteq> \<Union>B"
  2771           "S \<in> A"
  2772   obtains T where "T \<in> B" "S \<subseteq> T" "S \<inter> \<Union>(B - {T}) = {}"
  2773 proof -
  2774   have "S \<subseteq> \<Union>B" "connected S" "S \<noteq> {}"
  2775     using assms \<open>S \<in> A\<close> by blast+
  2776   then obtain T where "T \<in> B" "S \<inter> T \<noteq> {}"
  2777     by (metis Sup_inf_eq_bot_iff inf.absorb_iff2 inf_commute)
  2778   have 1: "open T" by (simp add: \<open>T \<in> B\<close> assms)
  2779   have 2: "open (\<Union>(B-{T}))" using assms by blast
  2780   have 3: "S \<subseteq> T \<union> \<Union>(B - {T})" using \<open>S \<subseteq> \<Union>B\<close> by blast
  2781   have "T \<inter> \<Union>(B - {T}) = {}" using \<open>T \<in> B\<close> \<open>pairwise disjnt B\<close>
  2782     by (auto simp: pairwise_def disjnt_def)
  2783   then have 4: "T \<inter> \<Union>(B - {T}) \<inter> S = {}" by auto
  2784   from connectedD [OF \<open>connected S\<close> 1 2 3 4]
  2785   have "S \<inter> \<Union>(B-{T}) = {}"
  2786     by (auto simp: Int_commute \<open>S \<inter> T \<noteq> {}\<close>)
  2787   with \<open>T \<in> B\<close> have "S \<subseteq> T"
  2788     using "3" by auto
  2789   show ?thesis
  2790     using \<open>S \<inter> \<Union>(B - {T}) = {}\<close> \<open>S \<subseteq> T\<close> \<open>T \<in> B\<close> that by auto
  2791 qed
  2792 
  2793 lemma connected_disjoint_Union_open_subset:
  2794   assumes A: "pairwise disjnt A" and B: "pairwise disjnt B"
  2795       and SA: "\<And>S. S \<in> A \<Longrightarrow> open S \<and> connected S \<and> S \<noteq> {}"
  2796       and SB: "\<And>S. S \<in> B \<Longrightarrow> open S \<and> connected S \<and> S \<noteq> {}"
  2797       and eq [simp]: "\<Union>A = \<Union>B"
  2798     shows "A \<subseteq> B"
  2799 proof
  2800   fix S
  2801   assume "S \<in> A"
  2802   obtain T where "T \<in> B" "S \<subseteq> T" "S \<inter> \<Union>(B - {T}) = {}"
  2803       apply (rule connected_disjoint_Union_open_pick [OF B, of A])
  2804       using SA SB \<open>S \<in> A\<close> by auto
  2805   moreover obtain S' where "S' \<in> A" "T \<subseteq> S'" "T \<inter> \<Union>(A - {S'}) = {}"
  2806       apply (rule connected_disjoint_Union_open_pick [OF A, of B])
  2807       using SA SB \<open>T \<in> B\<close> by auto
  2808   ultimately have "S' = S"
  2809     by (metis A Int_subset_iff SA \<open>S \<in> A\<close> disjnt_def inf.orderE pairwise_def)
  2810   with \<open>T \<subseteq> S'\<close> have "T \<subseteq> S" by simp
  2811   with \<open>S \<subseteq> T\<close> have "S = T" by blast
  2812   with \<open>T \<in> B\<close> show "S \<in> B" by simp
  2813 qed
  2814 
  2815 lemma connected_disjoint_Union_open_unique:
  2816   assumes A: "pairwise disjnt A" and B: "pairwise disjnt B"
  2817       and SA: "\<And>S. S \<in> A \<Longrightarrow> open S \<and> connected S \<and> S \<noteq> {}"
  2818       and SB: "\<And>S. S \<in> B \<Longrightarrow> open S \<and> connected S \<and> S \<noteq> {}"
  2819       and eq [simp]: "\<Union>A = \<Union>B"
  2820     shows "A = B"
  2821 by (rule subset_antisym; metis connected_disjoint_Union_open_subset assms)
  2822 
  2823 proposition components_open_unique:
  2824  fixes S :: "'a::real_normed_vector set"
  2825   assumes "pairwise disjnt A" "\<Union>A = S"
  2826           "\<And>X. X \<in> A \<Longrightarrow> open X \<and> connected X \<and> X \<noteq> {}"
  2827     shows "components S = A"
  2828 proof -
  2829   have "open S" using assms by blast
  2830   show ?thesis
  2831     apply (rule connected_disjoint_Union_open_unique)
  2832     apply (simp add: components_eq disjnt_def pairwise_def)
  2833     using \<open>open S\<close>
  2834     apply (simp_all add: assms open_components in_components_connected in_components_nonempty)
  2835     done
  2836 qed
  2837 
  2838 
  2839 subsection%unimportant\<open>Existence of unbounded components\<close>
  2840 
  2841 lemma cobounded_unbounded_component:
  2842     fixes s :: "'a :: euclidean_space set"
  2843     assumes "bounded (-s)"
  2844       shows "\<exists>x. x \<in> s \<and> \<not> bounded (connected_component_set s x)"
  2845 proof -
  2846   obtain i::'a where i: "i \<in> Basis"
  2847     using nonempty_Basis by blast
  2848   obtain B where B: "B>0" "-s \<subseteq> ball 0 B"
  2849     using bounded_subset_ballD [OF assms, of 0] by auto
  2850   then have *: "\<And>x. B \<le> norm x \<Longrightarrow> x \<in> s"
  2851     by (force simp: ball_def dist_norm)
  2852   have unbounded_inner: "\<not> bounded {x. inner i x \<ge> B}"
  2853     apply (auto simp: bounded_def dist_norm)
  2854     apply (rule_tac x="x + (max B e + 1 + \<bar>i \<bullet> x\<bar>) *\<^sub>R i" in exI)
  2855     apply simp
  2856     using i
  2857     apply (auto simp: algebra_simps)
  2858     done
  2859   have **: "{x. B \<le> i \<bullet> x} \<subseteq> connected_component_set s (B *\<^sub>R i)"
  2860     apply (rule connected_component_maximal)
  2861     apply (auto simp: i intro: convex_connected convex_halfspace_ge [of B])
  2862     apply (rule *)
  2863     apply (rule order_trans [OF _ Basis_le_norm [OF i]])
  2864     by (simp add: inner_commute)
  2865   have "B *\<^sub>R i \<in> s"
  2866     by (rule *) (simp add: norm_Basis [OF i])
  2867   then show ?thesis
  2868     apply (rule_tac x="B *\<^sub>R i" in exI, clarify)
  2869     apply (frule bounded_subset [of _ "{x. B \<le> i \<bullet> x}", OF _ **])
  2870     using unbounded_inner apply blast
  2871     done
  2872 qed
  2873 
  2874 lemma cobounded_unique_unbounded_component:
  2875     fixes s :: "'a :: euclidean_space set"
  2876     assumes bs: "bounded (-s)" and "2 \<le> DIM('a)"
  2877         and bo: "\<not> bounded(connected_component_set s x)"
  2878                 "\<not> bounded(connected_component_set s y)"
  2879       shows "connected_component_set s x = connected_component_set s y"
  2880 proof -
  2881   obtain i::'a where i: "i \<in> Basis"
  2882     using nonempty_Basis by blast
  2883   obtain B where B: "B>0" "-s \<subseteq> ball 0 B"
  2884     using bounded_subset_ballD [OF bs, of 0] by auto
  2885   then have *: "\<And>x. B \<le> norm x \<Longrightarrow> x \<in> s"
  2886     by (force simp: ball_def dist_norm)
  2887   have ccb: "connected (- ball 0 B :: 'a set)"
  2888     using assms by (auto intro: connected_complement_bounded_convex)
  2889   obtain x' where x': "connected_component s x x'" "norm x' > B"
  2890     using bo [unfolded bounded_def dist_norm, simplified, rule_format]
  2891     by (metis diff_zero norm_minus_commute not_less)
  2892   obtain y' where y': "connected_component s y y'" "norm y' > B"
  2893     using bo [unfolded bounded_def dist_norm, simplified, rule_format]
  2894     by (metis diff_zero norm_minus_commute not_less)
  2895   have x'y': "connected_component s x' y'"
  2896     apply (simp add: connected_component_def)
  2897     apply (rule_tac x="- ball 0 B" in exI)
  2898     using x' y'
  2899     apply (auto simp: ccb dist_norm *)
  2900     done
  2901   show ?thesis
  2902     apply (rule connected_component_eq)
  2903     using x' y' x'y'
  2904     by (metis (no_types, lifting) connected_component_eq_empty connected_component_eq_eq connected_component_idemp connected_component_in)
  2905 qed
  2906 
  2907 lemma cobounded_unbounded_components:
  2908     fixes s :: "'a :: euclidean_space set"
  2909     shows "bounded (-s) \<Longrightarrow> \<exists>c. c \<in> components s \<and> \<not>bounded c"
  2910   by (metis cobounded_unbounded_component components_def imageI)
  2911 
  2912 lemma cobounded_unique_unbounded_components:
  2913     fixes s :: "'a :: euclidean_space set"
  2914     shows  "\<lbrakk>bounded (- s); c \<in> components s; \<not> bounded c; c' \<in> components s; \<not> bounded c'; 2 \<le> DIM('a)\<rbrakk> \<Longrightarrow> c' = c"
  2915   unfolding components_iff
  2916   by (metis cobounded_unique_unbounded_component)
  2917 
  2918 lemma cobounded_has_bounded_component:
  2919   fixes S :: "'a :: euclidean_space set"
  2920   assumes "bounded (- S)" "\<not> connected S" "2 \<le> DIM('a)"
  2921   obtains C where "C \<in> components S" "bounded C"
  2922   by (meson cobounded_unique_unbounded_components connected_eq_connected_components_eq assms)
  2923 
  2924 
  2925 subsection\<open>The \<open>inside\<close> and \<open>outside\<close> of a Set\<close>
  2926 
  2927 text%important\<open>The inside comprises the points in a bounded connected component of the set's complement.
  2928   The outside comprises the points in unbounded connected component of the complement.\<close>
  2929 
  2930 definition%important inside where
  2931   "inside S \<equiv> {x. (x \<notin> S) \<and> bounded(connected_component_set ( - S) x)}"
  2932 
  2933 definition%important outside where
  2934   "outside S \<equiv> -S \<inter> {x. \<not> bounded(connected_component_set (- S) x)}"
  2935 
  2936 lemma outside: "outside S = {x. \<not> bounded(connected_component_set (- S) x)}"
  2937   by (auto simp: outside_def) (metis Compl_iff bounded_empty connected_component_eq_empty)
  2938 
  2939 lemma inside_no_overlap [simp]: "inside S \<inter> S = {}"
  2940   by (auto simp: inside_def)
  2941 
  2942 lemma outside_no_overlap [simp]:
  2943    "outside S \<inter> S = {}"
  2944   by (auto simp: outside_def)
  2945 
  2946 lemma inside_Int_outside [simp]: "inside S \<inter> outside S = {}"
  2947   by (auto simp: inside_def outside_def)
  2948 
  2949 lemma inside_Un_outside [simp]: "inside S \<union> outside S = (- S)"
  2950   by (auto simp: inside_def outside_def)
  2951 
  2952 lemma inside_eq_outside:
  2953    "inside S = outside S \<longleftrightarrow> S = UNIV"
  2954   by (auto simp: inside_def outside_def)
  2955 
  2956 lemma inside_outside: "inside S = (- (S \<union> outside S))"
  2957   by (force simp: inside_def outside)
  2958 
  2959 lemma outside_inside: "outside S = (- (S \<union> inside S))"
  2960   by (auto simp: inside_outside) (metis IntI equals0D outside_no_overlap)
  2961 
  2962 lemma union_with_inside: "S \<union> inside S = - outside S"
  2963   by (auto simp: inside_outside) (simp add: outside_inside)
  2964 
  2965 lemma union_with_outside: "S \<union> outside S = - inside S"
  2966   by (simp add: inside_outside)
  2967 
  2968 lemma outside_mono: "S \<subseteq> T \<Longrightarrow> outside T \<subseteq> outside S"
  2969   by (auto simp: outside bounded_subset connected_component_mono)
  2970 
  2971 lemma inside_mono: "S \<subseteq> T \<Longrightarrow> inside S - T \<subseteq> inside T"
  2972   by (auto simp: inside_def bounded_subset connected_component_mono)
  2973 
  2974 lemma segment_bound_lemma:
  2975   fixes u::real
  2976   assumes "x \<ge> B" "y \<ge> B" "0 \<le> u" "u \<le> 1"
  2977   shows "(1 - u) * x + u * y \<ge> B"
  2978 proof -
  2979   obtain dx dy where "dx \<ge> 0" "dy \<ge> 0" "x = B + dx" "y = B + dy"
  2980     using assms by auto (metis add.commute diff_add_cancel)
  2981   with \<open>0 \<le> u\<close> \<open>u \<le> 1\<close> show ?thesis
  2982     by (simp add: add_increasing2 mult_left_le field_simps)
  2983 qed
  2984 
  2985 lemma cobounded_outside:
  2986   fixes S :: "'a :: real_normed_vector set"
  2987   assumes "bounded S" shows "bounded (- outside S)"
  2988 proof -
  2989   obtain B where B: "B>0" "S \<subseteq> ball 0 B"
  2990     using bounded_subset_ballD [OF assms, of 0] by auto
  2991   { fix x::'a and C::real
  2992     assume Bno: "B \<le> norm x" and C: "0 < C"
  2993     have "\<exists>y. connected_component (- S) x y \<and> norm y > C"
  2994     proof (cases "x = 0")
  2995       case True with B Bno show ?thesis by force
  2996     next
  2997       case False 
  2998       with B C
  2999       have "closed_segment x (((B + C) / norm x) *\<^sub>R x) \<subseteq> - ball 0 B"
  3000         apply (clarsimp simp add: closed_segment_def ball_def dist_norm real_vector_class.scaleR_add_left [symmetric] divide_simps)
  3001         using segment_bound_lemma [of B "norm x" "B+C" ] Bno
  3002         by (meson le_add_same_cancel1 less_eq_real_def not_le)
  3003       also have "... \<subseteq> -S"
  3004         by (simp add: B)
  3005       finally have "\<exists>T. connected T \<and> T \<subseteq> - S \<and> x \<in> T \<and> ((B + C) / norm x) *\<^sub>R x \<in> T"
  3006         by (rule_tac x="closed_segment x (((B+C)/norm x) *\<^sub>R x)" in exI) simp
  3007       with False B
  3008       show ?thesis
  3009         by (rule_tac x="((B+C)/norm x) *\<^sub>R x" in exI) (simp add: connected_component_def)
  3010     qed
  3011   }
  3012   then show ?thesis
  3013     apply (simp add: outside_def assms)
  3014     apply (rule bounded_subset [OF bounded_ball [of 0 B]])
  3015     apply (force simp: dist_norm not_less bounded_pos)
  3016     done
  3017 qed
  3018 
  3019 lemma unbounded_outside:
  3020     fixes S :: "'a::{real_normed_vector, perfect_space} set"
  3021     shows "bounded S \<Longrightarrow> \<not> bounded(outside S)"
  3022   using cobounded_imp_unbounded cobounded_outside by blast
  3023 
  3024 lemma bounded_inside:
  3025     fixes S :: "'a::{real_normed_vector, perfect_space} set"
  3026     shows "bounded S \<Longrightarrow> bounded(inside S)"
  3027   by (simp add: bounded_Int cobounded_outside inside_outside)
  3028 
  3029 lemma connected_outside:
  3030     fixes S :: "'a::euclidean_space set"
  3031     assumes "bounded S" "2 \<le> DIM('a)"
  3032       shows "connected(outside S)"
  3033   apply (clarsimp simp add: connected_iff_connected_component outside)
  3034   apply (rule_tac s="connected_component_set (- S) x" in connected_component_of_subset)
  3035   apply (metis (no_types) assms cobounded_unbounded_component cobounded_unique_unbounded_component connected_component_eq_eq connected_component_idemp double_complement mem_Collect_eq)
  3036   apply clarify
  3037   apply (metis connected_component_eq_eq connected_component_in)
  3038   done
  3039 
  3040 lemma outside_connected_component_lt:
  3041     "outside S = {x. \<forall>B. \<exists>y. B < norm(y) \<and> connected_component (- S) x y}"
  3042 apply (auto simp: outside bounded_def dist_norm)
  3043 apply (metis diff_0 norm_minus_cancel not_less)
  3044 by (metis less_diff_eq norm_minus_commute norm_triangle_ineq2 order.trans pinf(6))
  3045 
  3046 lemma outside_connected_component_le:
  3047    "outside S =
  3048             {x. \<forall>B. \<exists>y. B \<le> norm(y) \<and>
  3049                          connected_component (- S) x y}"
  3050 apply (simp add: outside_connected_component_lt)
  3051 apply (simp add: Set.set_eq_iff)
  3052 by (meson gt_ex leD le_less_linear less_imp_le order.trans)
  3053 
  3054 lemma not_outside_connected_component_lt:
  3055     fixes S :: "'a::euclidean_space set"
  3056     assumes S: "bounded S" and "2 \<le> DIM('a)"
  3057       shows "- (outside S) = {x. \<forall>B. \<exists>y. B < norm(y) \<and> \<not> connected_component (- S) x y}"
  3058 proof -
  3059   obtain B::real where B: "0 < B" and Bno: "\<And>x. x \<in> S \<Longrightarrow> norm x \<le> B"
  3060     using S [simplified bounded_pos] by auto
  3061   { fix y::'a and z::'a
  3062     assume yz: "B < norm z" "B < norm y"
  3063     have "connected_component (- cball 0 B) y z"
  3064       apply (rule connected_componentI [OF _ subset_refl])
  3065       apply (rule connected_complement_bounded_convex)
  3066       using assms yz
  3067       by (auto simp: dist_norm)
  3068     then have "connected_component (- S) y z"
  3069       apply (rule connected_component_of_subset)
  3070       apply (metis Bno Compl_anti_mono mem_cball_0 subset_iff)
  3071       done
  3072   } note cyz = this
  3073   show ?thesis
  3074     apply (auto simp: outside)
  3075     apply (metis Compl_iff bounded_iff cobounded_imp_unbounded mem_Collect_eq not_le)
  3076     apply (simp add: bounded_pos)
  3077     by (metis B connected_component_trans cyz not_le)
  3078 qed
  3079 
  3080 lemma not_outside_connected_component_le:
  3081     fixes S :: "'a::euclidean_space set"
  3082     assumes S: "bounded S"  "2 \<le> DIM('a)"
  3083       shows "- (outside S) = {x. \<forall>B. \<exists>y. B \<le> norm(y) \<and> \<not> connected_component (- S) x y}"
  3084 apply (auto intro: less_imp_le simp: not_outside_connected_component_lt [OF assms])
  3085 by (meson gt_ex less_le_trans)
  3086 
  3087 lemma inside_connected_component_lt:
  3088     fixes S :: "'a::euclidean_space set"
  3089     assumes S: "bounded S"  "2 \<le> DIM('a)"
  3090       shows "inside S = {x. (x \<notin> S) \<and> (\<forall>B. \<exists>y. B < norm(y) \<and> \<not> connected_component (- S) x y)}"
  3091   by (auto simp: inside_outside not_outside_connected_component_lt [OF assms])
  3092 
  3093 lemma inside_connected_component_le:
  3094     fixes S :: "'a::euclidean_space set"
  3095     assumes S: "bounded S"  "2 \<le> DIM('a)"
  3096       shows "inside S = {x. (x \<notin> S) \<and> (\<forall>B. \<exists>y. B \<le> norm(y) \<and> \<not> connected_component (- S) x y)}"
  3097   by (auto simp: inside_outside not_outside_connected_component_le [OF assms])
  3098 
  3099 lemma inside_subset:
  3100   assumes "connected U" and "\<not> bounded U" and "T \<union> U = - S"
  3101   shows "inside S \<subseteq> T"
  3102 apply (auto simp: inside_def)
  3103 by (metis bounded_subset [of "connected_component_set (- S) _"] connected_component_maximal
  3104        Compl_iff Un_iff assms subsetI)
  3105 
  3106 lemma frontier_not_empty:
  3107   fixes S :: "'a :: real_normed_vector set"
  3108   shows "\<lbrakk>S \<noteq> {}; S \<noteq> UNIV\<rbrakk> \<Longrightarrow> frontier S \<noteq> {}"
  3109     using connected_Int_frontier [of UNIV S] by auto
  3110 
  3111 lemma frontier_eq_empty:
  3112   fixes S :: "'a :: real_normed_vector set"
  3113   shows "frontier S = {} \<longleftrightarrow> S = {} \<or> S = UNIV"
  3114 using frontier_UNIV frontier_empty frontier_not_empty by blast
  3115 
  3116 lemma frontier_of_connected_component_subset:
  3117   fixes S :: "'a::real_normed_vector set"
  3118   shows "frontier(connected_component_set S x) \<subseteq> frontier S"
  3119 proof -
  3120   { fix y
  3121     assume y1: "y \<in> closure (connected_component_set S x)"
  3122        and y2: "y \<notin> interior (connected_component_set S x)"
  3123     have "y \<in> closure S"
  3124       using y1 closure_mono connected_component_subset by blast
  3125     moreover have "z \<in> interior (connected_component_set S x)"
  3126           if "0 < e" "ball y e \<subseteq> interior S" "dist y z < e" for e z
  3127     proof -
  3128       have "ball y e \<subseteq> connected_component_set S y"
  3129         apply (rule connected_component_maximal)
  3130         using that interior_subset mem_ball apply auto
  3131         done
  3132       then show ?thesis
  3133         using y1 apply (simp add: closure_approachable open_contains_ball_eq [OF open_interior])
  3134         by (metis connected_component_eq dist_commute mem_Collect_eq mem_ball mem_interior subsetD \<open>0 < e\<close> y2)
  3135     qed
  3136     then have "y \<notin> interior S"
  3137       using y2 by (force simp: open_contains_ball_eq [OF open_interior])
  3138     ultimately have "y \<in> frontier S"
  3139       by (auto simp: frontier_def)
  3140   }
  3141   then show ?thesis by (auto simp: frontier_def)
  3142 qed
  3143 
  3144 lemma frontier_Union_subset_closure:
  3145   fixes F :: "'a::real_normed_vector set set"
  3146   shows "frontier(\<Union>F) \<subseteq> closure(\<Union>t \<in> F. frontier t)"
  3147 proof -
  3148   have "\<exists>y\<in>F. \<exists>y\<in>frontier y. dist y x < e"
  3149        if "T \<in> F" "y \<in> T" "dist y x < e"
  3150           "x \<notin> interior (\<Union>F)" "0 < e" for x y e T
  3151   proof (cases "x \<in> T")
  3152     case True with that show ?thesis
  3153       by (metis Diff_iff Sup_upper closure_subset contra_subsetD dist_self frontier_def interior_mono)
  3154   next
  3155     case False
  3156     have 1: "closed_segment x y \<inter> T \<noteq> {}" using \<open>y \<in> T\<close> by blast
  3157     have 2: "closed_segment x y - T \<noteq> {}"
  3158       using False by blast
  3159     obtain c where "c \<in> closed_segment x y" "c \<in> frontier T"
  3160        using False connected_Int_frontier [OF connected_segment 1 2] by auto
  3161     then show ?thesis
  3162     proof -
  3163       have "norm (y - x) < e"
  3164         by (metis dist_norm \<open>dist y x < e\<close>)
  3165       moreover have "norm (c - x) \<le> norm (y - x)"
  3166         by (simp add: \<open>c \<in> closed_segment x y\<close> segment_bound(1))
  3167       ultimately have "norm (c - x) < e"
  3168         by linarith
  3169       then show ?thesis
  3170         by (metis (no_types) \<open>c \<in> frontier T\<close> dist_norm that(1))
  3171     qed
  3172   qed
  3173   then show ?thesis
  3174     by (fastforce simp add: frontier_def closure_approachable)
  3175 qed
  3176 
  3177 lemma frontier_Union_subset:
  3178   fixes F :: "'a::real_normed_vector set set"
  3179   shows "finite F \<Longrightarrow> frontier(\<Union>F) \<subseteq> (\<Union>t \<in> F. frontier t)"
  3180 by (rule order_trans [OF frontier_Union_subset_closure])
  3181    (auto simp: closure_subset_eq)
  3182 
  3183 lemma frontier_of_components_subset:
  3184   fixes S :: "'a::real_normed_vector set"
  3185   shows "C \<in> components S \<Longrightarrow> frontier C \<subseteq> frontier S"
  3186   by (metis Path_Connected.frontier_of_connected_component_subset components_iff)
  3187 
  3188 lemma frontier_of_components_closed_complement:
  3189   fixes S :: "'a::real_normed_vector set"
  3190   shows "\<lbrakk>closed S; C \<in> components (- S)\<rbrakk> \<Longrightarrow> frontier C \<subseteq> S"
  3191   using frontier_complement frontier_of_components_subset frontier_subset_eq by blast
  3192 
  3193 lemma frontier_minimal_separating_closed:
  3194   fixes S :: "'a::real_normed_vector set"
  3195   assumes "closed S"
  3196       and nconn: "\<not> connected(- S)"
  3197       and C: "C \<in> components (- S)"
  3198       and conn: "\<And>T. \<lbrakk>closed T; T \<subset> S\<rbrakk> \<Longrightarrow> connected(- T)"
  3199     shows "frontier C = S"
  3200 proof (rule ccontr)
  3201   assume "frontier C \<noteq> S"
  3202   then have "frontier C \<subset> S"
  3203     using frontier_of_components_closed_complement [OF \<open>closed S\<close> C] by blast
  3204   then have "connected(- (frontier C))"
  3205     by (simp add: conn)
  3206   have "\<not> connected(- (frontier C))"
  3207     unfolding connected_def not_not
  3208   proof (intro exI conjI)
  3209     show "open C"
  3210       using C \<open>closed S\<close> open_components by blast
  3211     show "open (- closure C)"
  3212       by blast
  3213     show "C \<inter> - closure C \<inter> - frontier C = {}"
  3214       using closure_subset by blast
  3215     show "C \<inter> - frontier C \<noteq> {}"
  3216       using C \<open>open C\<close> components_eq frontier_disjoint_eq by fastforce
  3217     show "- frontier C \<subseteq> C \<union> - closure C"
  3218       by (simp add: \<open>open C\<close> closed_Compl frontier_closures)
  3219     then show "- closure C \<inter> - frontier C \<noteq> {}"
  3220       by (metis (no_types, lifting) C Compl_subset_Compl_iff \<open>frontier C \<subset> S\<close> compl_sup frontier_closures in_components_subset psubsetE sup.absorb_iff2 sup.boundedE sup_bot.right_neutral sup_inf_absorb)
  3221   qed
  3222   then show False
  3223     using \<open>connected (- frontier C)\<close> by blast
  3224 qed
  3225 
  3226 lemma connected_component_UNIV [simp]:
  3227     fixes x :: "'a::real_normed_vector"
  3228     shows "connected_component_set UNIV x = UNIV"
  3229 using connected_iff_eq_connected_component_set [of "UNIV::'a set"] connected_UNIV
  3230 by auto
  3231 
  3232 lemma connected_component_eq_UNIV:
  3233     fixes x :: "'a::real_normed_vector"
  3234     shows "connected_component_set s x = UNIV \<longleftrightarrow> s = UNIV"
  3235   using connected_component_in connected_component_UNIV by blast
  3236 
  3237 lemma components_UNIV [simp]: "components UNIV = {UNIV :: 'a::real_normed_vector set}"
  3238   by (auto simp: components_eq_sing_iff)
  3239 
  3240 lemma interior_inside_frontier:
  3241     fixes s :: "'a::real_normed_vector set"
  3242     assumes "bounded s"
  3243       shows "interior s \<subseteq> inside (frontier s)"
  3244 proof -
  3245   { fix x y
  3246     assume x: "x \<in> interior s" and y: "y \<notin> s"
  3247        and cc: "connected_component (- frontier s) x y"
  3248     have "connected_component_set (- frontier s) x \<inter> frontier s \<noteq> {}"
  3249       apply (rule connected_Int_frontier, simp)
  3250       apply (metis IntI cc connected_component_in connected_component_refl empty_iff interiorE mem_Collect_eq rev_subsetD x)
  3251       using  y cc
  3252       by blast
  3253     then have "bounded (connected_component_set (- frontier s) x)"
  3254       using connected_component_in by auto
  3255   }
  3256   then show ?thesis
  3257     apply (auto simp: inside_def frontier_def)
  3258     apply (rule classical)
  3259     apply (rule bounded_subset [OF assms], blast)
  3260     done
  3261 qed
  3262 
  3263 lemma inside_empty [simp]: "inside {} = ({} :: 'a :: {real_normed_vector, perfect_space} set)"
  3264   by (simp add: inside_def connected_component_UNIV)
  3265 
  3266 lemma outside_empty [simp]: "outside {} = (UNIV :: 'a :: {real_normed_vector, perfect_space} set)"
  3267 using inside_empty inside_Un_outside by blast
  3268 
  3269 lemma inside_same_component:
  3270    "\<lbrakk>connected_component (- s) x y; x \<in> inside s\<rbrakk> \<Longrightarrow> y \<in> inside s"
  3271   using connected_component_eq connected_component_in
  3272   by (fastforce simp add: inside_def)
  3273 
  3274 lemma outside_same_component:
  3275    "\<lbrakk>connected_component (- s) x y; x \<in> outside s\<rbrakk> \<Longrightarrow> y \<in> outside s"
  3276   using connected_component_eq connected_component_in
  3277   by (fastforce simp add: outside_def)
  3278 
  3279 lemma convex_in_outside:
  3280   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3281   assumes s: "convex s" and z: "z \<notin> s"
  3282     shows "z \<in> outside s"
  3283 proof (cases "s={}")
  3284   case True then show ?thesis by simp
  3285 next
  3286   case False then obtain a where "a \<in> s" by blast
  3287   with z have zna: "z \<noteq> a" by auto
  3288   { assume "bounded (connected_component_set (- s) z)"
  3289     with bounded_pos_less obtain B where "B>0" and B: "\<And>x. connected_component (- s) z x \<Longrightarrow> norm x < B"
  3290       by (metis mem_Collect_eq)
  3291     define C where "C = (B + 1 + norm z) / norm (z-a)"
  3292     have "C > 0"
  3293       using \<open>0 < B\<close> zna by (simp add: C_def divide_simps add_strict_increasing)
  3294     have "\<bar>norm (z + C *\<^sub>R (z-a)) - norm (C *\<^sub>R (z-a))\<bar> \<le> norm z"
  3295       by (metis add_diff_cancel norm_triangle_ineq3)
  3296     moreover have "norm (C *\<^sub>R (z-a)) > norm z + B"
  3297       using zna \<open>B>0\<close> by (simp add: C_def le_max_iff_disj field_simps)
  3298     ultimately have C: "norm (z + C *\<^sub>R (z-a)) > B" by linarith
  3299     { fix u::real
  3300       assume u: "0\<le>u" "u\<le>1" and ins: "(1 - u) *\<^sub>R z + u *\<^sub>R (z + C *\<^sub>R (z - a)) \<in> s"
  3301       then have Cpos: "1 + u * C > 0"
  3302         by (meson \<open>0 < C\<close> add_pos_nonneg less_eq_real_def zero_le_mult_iff zero_less_one)
  3303       then have *: "(1 / (1 + u * C)) *\<^sub>R z + (u * C / (1 + u * C)) *\<^sub>R z = z"
  3304         by (simp add: scaleR_add_left [symmetric] divide_simps)
  3305       then have False
  3306         using convexD_alt [OF s \<open>a \<in> s\<close> ins, of "1/(u*C + 1)"] \<open>C>0\<close> \<open>z \<notin> s\<close> Cpos u
  3307         by (simp add: * divide_simps algebra_simps)
  3308     } note contra = this
  3309     have "connected_component (- s) z (z + C *\<^sub>R (z-a))"
  3310       apply (rule connected_componentI [OF connected_segment [of z "z + C *\<^sub>R (z-a)"]])
  3311       apply (simp add: closed_segment_def)
  3312       using contra
  3313       apply auto
  3314       done
  3315     then have False
  3316       using zna B [of "z + C *\<^sub>R (z-a)"] C
  3317       by (auto simp: divide_simps max_mult_distrib_right)
  3318   }
  3319   then show ?thesis
  3320     by (auto simp: outside_def z)
  3321 qed
  3322 
  3323 lemma outside_convex:
  3324   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3325   assumes "convex s"
  3326     shows "outside s = - s"
  3327   by (metis ComplD assms convex_in_outside equalityI inside_Un_outside subsetI sup.cobounded2)
  3328 
  3329 lemma outside_singleton [simp]:
  3330   fixes x :: "'a :: {real_normed_vector, perfect_space}"
  3331   shows "outside {x} = -{x}"
  3332   by (auto simp: outside_convex)
  3333 
  3334 lemma inside_convex:
  3335   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3336   shows "convex s \<Longrightarrow> inside s = {}"
  3337   by (simp add: inside_outside outside_convex)
  3338 
  3339 lemma inside_singleton [simp]:
  3340   fixes x :: "'a :: {real_normed_vector, perfect_space}"
  3341   shows "inside {x} = {}"
  3342   by (auto simp: inside_convex)
  3343 
  3344 lemma outside_subset_convex:
  3345   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3346   shows "\<lbrakk>convex t; s \<subseteq> t\<rbrakk> \<Longrightarrow> - t \<subseteq> outside s"
  3347   using outside_convex outside_mono by blast
  3348 
  3349 lemma outside_Un_outside_Un:
  3350   fixes S :: "'a::real_normed_vector set"
  3351   assumes "S \<inter> outside(T \<union> U) = {}"
  3352   shows "outside(T \<union> U) \<subseteq> outside(T \<union> S)"
  3353 proof
  3354   fix x
  3355   assume x: "x \<in> outside (T \<union> U)"
  3356   have "Y \<subseteq> - S" if "connected Y" "Y \<subseteq> - T" "Y \<subseteq> - U" "x \<in> Y" "u \<in> Y" for u Y
  3357   proof -
  3358     have "Y \<subseteq> connected_component_set (- (T \<union> U)) x"
  3359       by (simp add: connected_component_maximal that)
  3360     also have "\<dots> \<subseteq> outside(T \<union> U)"
  3361       by (metis (mono_tags, lifting) Collect_mono mem_Collect_eq outside outside_same_component x)
  3362     finally have "Y \<subseteq> outside(T \<union> U)" .
  3363     with assms show ?thesis by auto
  3364   qed
  3365   with x show "x \<in> outside (T \<union> S)"
  3366     by (simp add: outside_connected_component_lt connected_component_def) meson
  3367 qed
  3368 
  3369 lemma outside_frontier_misses_closure:
  3370     fixes s :: "'a::real_normed_vector set"
  3371     assumes "bounded s"
  3372     shows  "outside(frontier s) \<subseteq> - closure s"
  3373   unfolding outside_inside Lattices.boolean_algebra_class.compl_le_compl_iff
  3374 proof -
  3375   { assume "interior s \<subseteq> inside (frontier s)"
  3376     hence "interior s \<union> inside (frontier s) = inside (frontier s)"
  3377       by (simp add: subset_Un_eq)
  3378     then have "closure s \<subseteq> frontier s \<union> inside (frontier s)"
  3379       using frontier_def by auto
  3380   }
  3381   then show "closure s \<subseteq> frontier s \<union> inside (frontier s)"
  3382     using interior_inside_frontier [OF assms] by blast
  3383 qed
  3384 
  3385 lemma outside_frontier_eq_complement_closure:
  3386   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3387     assumes "bounded s" "convex s"
  3388       shows "outside(frontier s) = - closure s"
  3389 by (metis Diff_subset assms convex_closure frontier_def outside_frontier_misses_closure
  3390           outside_subset_convex subset_antisym)
  3391 
  3392 lemma inside_frontier_eq_interior:
  3393      fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3394      shows "\<lbrakk>bounded s; convex s\<rbrakk> \<Longrightarrow> inside(frontier s) = interior s"
  3395   apply (simp add: inside_outside outside_frontier_eq_complement_closure)
  3396   using closure_subset interior_subset
  3397   apply (auto simp: frontier_def)
  3398   done
  3399 
  3400 lemma open_inside:
  3401     fixes s :: "'a::real_normed_vector set"
  3402     assumes "closed s"
  3403       shows "open (inside s)"
  3404 proof -
  3405   { fix x assume x: "x \<in> inside s"
  3406     have "open (connected_component_set (- s) x)"
  3407       using assms open_connected_component by blast
  3408     then obtain e where e: "e>0" and e: "\<And>y. dist y x < e \<longrightarrow> connected_component (- s) x y"
  3409       using dist_not_less_zero
  3410       apply (simp add: open_dist)
  3411       by (metis (no_types, lifting) Compl_iff connected_component_refl_eq inside_def mem_Collect_eq x)
  3412     then have "\<exists>e>0. ball x e \<subseteq> inside s"
  3413       by (metis e dist_commute inside_same_component mem_ball subsetI x)
  3414   }
  3415   then show ?thesis
  3416     by (simp add: open_contains_ball)
  3417 qed
  3418 
  3419 lemma open_outside:
  3420     fixes s :: "'a::real_normed_vector set"
  3421     assumes "closed s"
  3422       shows "open (outside s)"
  3423 proof -
  3424   { fix x assume x: "x \<in> outside s"
  3425     have "open (connected_component_set (- s) x)"
  3426       using assms open_connected_component by blast
  3427     then obtain e where e: "e>0" and e: "\<And>y. dist y x < e \<longrightarrow> connected_component (- s) x y"
  3428       using dist_not_less_zero
  3429       apply (simp add: open_dist)
  3430       by (metis Int_iff outside_def connected_component_refl_eq  x)
  3431     then have "\<exists>e>0. ball x e \<subseteq> outside s"
  3432       by (metis e dist_commute outside_same_component mem_ball subsetI x)
  3433   }
  3434   then show ?thesis
  3435     by (simp add: open_contains_ball)
  3436 qed
  3437 
  3438 lemma closure_inside_subset:
  3439     fixes s :: "'a::real_normed_vector set"
  3440     assumes "closed s"
  3441       shows "closure(inside s) \<subseteq> s \<union> inside s"
  3442 by (metis assms closure_minimal open_closed open_outside sup.cobounded2 union_with_inside)
  3443 
  3444 lemma frontier_inside_subset:
  3445     fixes s :: "'a::real_normed_vector set"
  3446     assumes "closed s"
  3447       shows "frontier(inside s) \<subseteq> s"
  3448 proof -
  3449   have "closure (inside s) \<inter> - inside s = closure (inside s) - interior (inside s)"
  3450     by (metis (no_types) Diff_Compl assms closure_closed interior_closure open_closed open_inside)
  3451   moreover have "- inside s \<inter> - outside s = s"
  3452     by (metis (no_types) compl_sup double_compl inside_Un_outside)
  3453   moreover have "closure (inside s) \<subseteq> - outside s"
  3454     by (metis (no_types) assms closure_inside_subset union_with_inside)
  3455   ultimately have "closure (inside s) - interior (inside s) \<subseteq> s"
  3456     by blast
  3457   then show ?thesis
  3458     by (simp add: frontier_def open_inside interior_open)
  3459 qed
  3460 
  3461 lemma closure_outside_subset:
  3462     fixes s :: "'a::real_normed_vector set"
  3463     assumes "closed s"
  3464       shows "closure(outside s) \<subseteq> s \<union> outside s"
  3465   apply (rule closure_minimal, simp)
  3466   by (metis assms closed_open inside_outside open_inside)
  3467 
  3468 lemma frontier_outside_subset:
  3469     fixes s :: "'a::real_normed_vector set"
  3470     assumes "closed s"
  3471       shows "frontier(outside s) \<subseteq> s"
  3472   apply (simp add: frontier_def open_outside interior_open)
  3473   by (metis Diff_subset_conv assms closure_outside_subset interior_eq open_outside sup.commute)
  3474 
  3475 lemma inside_complement_unbounded_connected_empty:
  3476      "\<lbrakk>connected (- s); \<not> bounded (- s)\<rbrakk> \<Longrightarrow> inside s = {}"
  3477   apply (simp add: inside_def)
  3478   by (meson Compl_iff bounded_subset connected_component_maximal order_refl)
  3479 
  3480 lemma inside_bounded_complement_connected_empty:
  3481     fixes s :: "'a::{real_normed_vector, perfect_space} set"
  3482     shows "\<lbrakk>connected (- s); bounded s\<rbrakk> \<Longrightarrow> inside s = {}"
  3483   by (metis inside_complement_unbounded_connected_empty cobounded_imp_unbounded)
  3484 
  3485 lemma inside_inside:
  3486     assumes "s \<subseteq> inside t"
  3487     shows "inside s - t \<subseteq> inside t"
  3488 unfolding inside_def
  3489 proof clarify
  3490   fix x
  3491   assume x: "x \<notin> t" "x \<notin> s" and bo: "bounded (connected_component_set (- s) x)"
  3492   show "bounded (connected_component_set (- t) x)"
  3493   proof (cases "s \<inter> connected_component_set (- t) x = {}")
  3494     case True show ?thesis
  3495       apply (rule bounded_subset [OF bo])
  3496       apply (rule connected_component_maximal)
  3497       using x True apply auto
  3498       done
  3499   next
  3500     case False then show ?thesis
  3501       using assms [unfolded inside_def] x
  3502       apply (simp add: disjoint_iff_not_equal, clarify)
  3503       apply (drule subsetD, assumption, auto)
  3504       by (metis (no_types, hide_lams) ComplI connected_component_eq_eq)
  3505   qed
  3506 qed
  3507 
  3508 lemma inside_inside_subset: "inside(inside s) \<subseteq> s"
  3509   using inside_inside union_with_outside by fastforce
  3510 
  3511 lemma inside_outside_intersect_connected:
  3512       "\<lbrakk>connected t; inside s \<inter> t \<noteq> {}; outside s \<inter> t \<noteq> {}\<rbrakk> \<Longrightarrow> s \<inter> t \<noteq> {}"
  3513   apply (simp add: inside_def outside_def ex_in_conv [symmetric] disjoint_eq_subset_Compl, clarify)
  3514   by (metis (no_types, hide_lams) Compl_anti_mono connected_component_eq connected_component_maximal contra_subsetD double_compl)
  3515 
  3516 lemma outside_bounded_nonempty:
  3517   fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3518     assumes "bounded s" shows "outside s \<noteq> {}"
  3519   by (metis (no_types, lifting) Collect_empty_eq Collect_mem_eq Compl_eq_Diff_UNIV Diff_cancel
  3520                    Diff_disjoint UNIV_I assms ball_eq_empty bounded_diff cobounded_outside convex_ball
  3521                    double_complement order_refl outside_convex outside_def)
  3522 
  3523 lemma outside_compact_in_open:
  3524     fixes s :: "'a :: {real_normed_vector,perfect_space} set"
  3525     assumes s: "compact s" and t: "open t" and "s \<subseteq> t" "t \<noteq> {}"
  3526       shows "outside s \<inter> t \<noteq> {}"
  3527 proof -
  3528   have "outside s \<noteq> {}"
  3529     by (simp add: compact_imp_bounded outside_bounded_nonempty s)
  3530   with assms obtain a b where a: "a \<in> outside s" and b: "b \<in> t" by auto
  3531   show ?thesis
  3532   proof (cases "a \<in> t")
  3533     case True with a show ?thesis by blast
  3534   next
  3535     case False
  3536       have front: "frontier t \<subseteq> - s"
  3537         using \<open>s \<subseteq> t\<close> frontier_disjoint_eq t by auto
  3538       { fix \<gamma>
  3539         assume "path \<gamma>" and pimg_sbs: "path_image \<gamma> - {pathfinish \<gamma>} \<subseteq> interior (- t)"
  3540            and pf: "pathfinish \<gamma> \<in> frontier t" and ps: "pathstart \<gamma> = a"
  3541         define c where "c = pathfinish \<gamma>"
  3542         have "c \<in> -s" unfolding c_def using front pf by blast
  3543         moreover have "open (-s)" using s compact_imp_closed by blast
  3544         ultimately obtain \<epsilon>::real where "\<epsilon> > 0" and \<epsilon>: "cball c \<epsilon> \<subseteq> -s"
  3545           using open_contains_cball[of "-s"] s by blast
  3546         then obtain d where "d \<in> t" and d: "dist d c < \<epsilon>"
  3547           using closure_approachable [of c t] pf unfolding c_def
  3548           by (metis Diff_iff frontier_def)
  3549         then have "d \<in> -s" using \<epsilon>
  3550           using dist_commute by (metis contra_subsetD mem_cball not_le not_less_iff_gr_or_eq)
  3551         have pimg_sbs_cos: "path_image \<gamma> \<subseteq> -s"
  3552           using pimg_sbs apply (auto simp: path_image_def)
  3553           apply (drule subsetD)
  3554           using \<open>c \<in> - s\<close> \<open>s \<subseteq> t\<close> interior_subset apply (auto simp: c_def)
  3555           done
  3556         have "closed_segment c d \<le> cball c \<epsilon>"
  3557           apply (simp add: segment_convex_hull)
  3558           apply (rule hull_minimal)
  3559           using  \<open>\<epsilon> > 0\<close> d apply (auto simp: dist_commute)
  3560           done
  3561         with \<epsilon> have "closed_segment c d \<subseteq> -s" by blast
  3562         moreover have con_gcd: "connected (path_image \<gamma> \<union> closed_segment c d)"
  3563           by (rule connected_Un) (auto simp: c_def \<open>path \<gamma>\<close> connected_path_image)
  3564         ultimately have "connected_component (- s) a d"
  3565           unfolding connected_component_def using pimg_sbs_cos ps by blast
  3566         then have "outside s \<inter> t \<noteq> {}"
  3567           using outside_same_component [OF _ a]  by (metis IntI \<open>d \<in> t\<close> empty_iff)
  3568       } note * = this
  3569       have pal: "pathstart (linepath a b) \<in> closure (- t)"
  3570         by (auto simp: False closure_def)
  3571       show ?thesis
  3572         by (rule exists_path_subpath_to_frontier [OF path_linepath pal _ *]) (auto simp: b)
  3573   qed
  3574 qed
  3575 
  3576 lemma inside_inside_compact_connected:
  3577     fixes s :: "'a :: euclidean_space set"
  3578     assumes s: "closed s" and t: "compact t" and "connected t" "s \<subseteq> inside t"
  3579       shows "inside s \<subseteq> inside t"
  3580 proof (cases "inside t = {}")
  3581   case True with assms show ?thesis by auto
  3582 next
  3583   case False
  3584   consider "DIM('a) = 1" | "DIM('a) \<ge> 2"
  3585     using antisym not_less_eq_eq by fastforce
  3586   then show ?thesis
  3587   proof cases
  3588     case 1 then show ?thesis
  3589              using connected_convex_1_gen assms False inside_convex by blast
  3590   next
  3591     case 2
  3592     have coms: "compact s"
  3593       using assms apply (simp add: s compact_eq_bounded_closed)
  3594        by (meson bounded_inside bounded_subset compact_imp_bounded)
  3595     then have bst: "bounded (s \<union> t)"
  3596       by (simp add: compact_imp_bounded t)
  3597     then obtain r where "0 < r" and r: "s \<union> t \<subseteq> ball 0 r"
  3598       using bounded_subset_ballD by blast
  3599     have outst: "outside s \<inter> outside t \<noteq> {}"
  3600     proof -
  3601       have "- ball 0 r \<subseteq> outside s"
  3602         apply (rule outside_subset_convex)
  3603         using r by auto
  3604       moreover have "- ball 0 r \<subseteq> outside t"
  3605         apply (rule outside_subset_convex)
  3606         using r by auto
  3607       ultimately show ?thesis
  3608         by (metis Compl_subset_Compl_iff Int_subset_iff bounded_ball inf.orderE outside_bounded_nonempty outside_no_overlap)
  3609     qed
  3610     have "s \<inter> t = {}" using assms
  3611       by (metis disjoint_iff_not_equal inside_no_overlap subsetCE)
  3612     moreover have "outside s \<inter> inside t \<noteq> {}"
  3613       by (meson False assms(4) compact_eq_bounded_closed coms open_inside outside_compact_in_open t)
  3614     ultimately have "inside s \<inter> t = {}"
  3615       using inside_outside_intersect_connected [OF \<open>connected t\<close>, of s]
  3616       by (metis "2" compact_eq_bounded_closed coms connected_outside inf.commute inside_outside_intersect_connected outst)
  3617     then show ?thesis
  3618       using inside_inside [OF \<open>s \<subseteq> inside t\<close>] by blast
  3619   qed
  3620 qed
  3621 
  3622 lemma connected_with_inside:
  3623     fixes s :: "'a :: real_normed_vector set"
  3624     assumes s: "closed s" and cons: "connected s"
  3625       shows "connected(s \<union> inside s)"
  3626 proof (cases "s \<union> inside s = UNIV")
  3627   case True with assms show ?thesis by auto
  3628 next
  3629   case False
  3630   then obtain b where b: "b \<notin> s" "b \<notin> inside s" by blast
  3631   have *: "\<exists>y t. y \<in> s \<and> connected t \<and> a \<in> t \<and> y \<in> t \<and> t \<subseteq> (s \<union> inside s)" if "a \<in> (s \<union> inside s)" for a
  3632   using that proof
  3633     assume "a \<in> s" then show ?thesis
  3634       apply (rule_tac x=a in exI)
  3635       apply (rule_tac x="{a}" in exI, simp)
  3636       done
  3637   next
  3638     assume a: "a \<in> inside s"
  3639     show ?thesis
  3640       apply (rule exists_path_subpath_to_frontier [OF path_linepath [of a b], of "inside s"])
  3641       using a apply (simp add: closure_def)
  3642       apply (simp add: b)
  3643       apply (rule_tac x="pathfinish h" in exI)
  3644       apply (rule_tac x="path_image h" in exI)
  3645       apply (simp add: pathfinish_in_path_image connected_path_image, auto)
  3646       using frontier_inside_subset s apply fastforce
  3647       by (metis (no_types, lifting) frontier_inside_subset insertE insert_Diff interior_eq open_inside pathfinish_in_path_image s subsetCE)
  3648   qed
  3649   show ?thesis
  3650     apply (simp add: connected_iff_connected_component)
  3651     apply (simp add: connected_component_def)
  3652     apply (clarify dest!: *)
  3653     apply (rename_tac u u' t t')
  3654     apply (rule_tac x="(s \<union> t \<union> t')" in exI)
  3655     apply (auto simp: intro!: connected_Un cons)
  3656     done
  3657 qed
  3658 
  3659 text\<open>The proof is virtually the same as that above.\<close>
  3660 lemma connected_with_outside:
  3661     fixes s :: "'a :: real_normed_vector set"
  3662     assumes s: "closed s" and cons: "connected s"
  3663       shows "connected(s \<union> outside s)"
  3664 proof (cases "s \<union> outside s = UNIV")
  3665   case True with assms show ?thesis by auto
  3666 next
  3667   case False
  3668   then obtain b where b: "b \<notin> s" "b \<notin> outside s" by blast
  3669   have *: "\<exists>y t. y \<in> s \<and> connected t \<and> a \<in> t \<and> y \<in> t \<and> t \<subseteq> (s \<union> outside s)" if "a \<in> (s \<union> outside s)" for a
  3670   using that proof
  3671     assume "a \<in> s" then show ?thesis
  3672       apply (rule_tac x=a in exI)
  3673       apply (rule_tac x="{a}" in exI, simp)
  3674       done
  3675   next
  3676     assume a: "a \<in> outside s"
  3677     show ?thesis
  3678       apply (rule exists_path_subpath_to_frontier [OF path_linepath [of a b], of "outside s"])
  3679       using a apply (simp add: closure_def)
  3680       apply (simp add: b)
  3681       apply (rule_tac x="pathfinish h" in exI)
  3682       apply (rule_tac x="path_image h" in exI)
  3683       apply (simp add: pathfinish_in_path_image connected_path_image, auto)
  3684       using frontier_outside_subset s apply fastforce
  3685       by (metis (no_types, lifting) frontier_outside_subset insertE insert_Diff interior_eq open_outside pathfinish_in_path_image s subsetCE)
  3686   qed
  3687   show ?thesis
  3688     apply (simp add: connected_iff_connected_component)
  3689     apply (simp add: connected_component_def)
  3690     apply (clarify dest!: *)
  3691     apply (rename_tac u u' t t')
  3692     apply (rule_tac x="(s \<union> t \<union> t')" in exI)
  3693     apply (auto simp: intro!: connected_Un cons)
  3694     done
  3695 qed
  3696 
  3697 lemma inside_inside_eq_empty [simp]:
  3698     fixes s :: "'a :: {real_normed_vector, perfect_space} set"
  3699     assumes s: "closed s" and cons: "connected s"
  3700       shows "inside (inside s) = {}"
  3701   by (metis (no_types) unbounded_outside connected_with_outside [OF assms] bounded_Un
  3702            inside_complement_unbounded_connected_empty unbounded_outside union_with_outside)
  3703 
  3704 lemma inside_in_components:
  3705      "inside s \<in> components (- s) \<longleftrightarrow> connected(inside s) \<and> inside s \<noteq> {}"
  3706   apply (simp add: in_components_maximal)
  3707   apply (auto intro: inside_same_component connected_componentI)
  3708   apply (metis IntI empty_iff inside_no_overlap)
  3709   done
  3710 
  3711 text\<open>The proof is virtually the same as that above.\<close>
  3712 lemma outside_in_components:
  3713      "outside s \<in> components (- s) \<longleftrightarrow> connected(outside s) \<and> outside s \<noteq> {}"
  3714   apply (simp add: in_components_maximal)
  3715   apply (auto intro: outside_same_component connected_componentI)
  3716   apply (metis IntI empty_iff outside_no_overlap)
  3717   done
  3718 
  3719 lemma bounded_unique_outside:
  3720     fixes s :: "'a :: euclidean_space set"
  3721     shows "\<lbrakk>bounded s; DIM('a) \<ge> 2\<rbrakk> \<Longrightarrow> (c \<in> components (- s) \<and> \<not> bounded c \<longleftrightarrow> c = outside s)"
  3722   apply (rule iffI)
  3723   apply (metis cobounded_unique_unbounded_components connected_outside double_compl outside_bounded_nonempty outside_in_components unbounded_outside)
  3724   by (simp add: connected_outside outside_bounded_nonempty outside_in_components unbounded_outside)
  3725 
  3726 
  3727 subsection\<open>Condition for an open map's image to contain a ball\<close>
  3728 
  3729 proposition ball_subset_open_map_image:
  3730   fixes f :: "'a::heine_borel \<Rightarrow> 'b :: {real_normed_vector,heine_borel}"
  3731   assumes contf: "continuous_on (closure S) f"
  3732       and oint: "open (f ` interior S)"
  3733       and le_no: "\<And>z. z \<in> frontier S \<Longrightarrow> r \<le> norm(f z - f a)"
  3734       and "bounded S" "a \<in> S" "0 < r"
  3735     shows "ball (f a) r \<subseteq> f ` S"
  3736 proof (cases "f ` S = UNIV")
  3737   case True then show ?thesis by simp
  3738 next
  3739   case False
  3740     obtain w where w: "w \<in> frontier (f ` S)"
  3741                and dw_le: "\<And>y. y \<in> frontier (f ` S) \<Longrightarrow> norm (f a - w) \<le> norm (f a - y)"
  3742       apply (rule distance_attains_inf [of "frontier(f ` S)" "f a"])
  3743       using \<open>a \<in> S\<close> by (auto simp: frontier_eq_empty dist_norm False)
  3744     then obtain \<xi> where \<xi>: "\<And>n. \<xi> n \<in> f ` S" and tendsw: "\<xi> \<longlonglongrightarrow> w"
  3745       by (metis Diff_iff frontier_def closure_sequential)
  3746     then have "\<And>n. \<exists>x \<in> S. \<xi> n = f x" by force
  3747     then obtain z where zs: "\<And>n. z n \<in> S" and fz: "\<And>n. \<xi> n = f (z n)"
  3748       by metis
  3749     then obtain y K where y: "y \<in> closure S" and "strict_mono (K :: nat \<Rightarrow> nat)" 
  3750                       and Klim: "(z \<circ> K) \<longlonglongrightarrow> y"
  3751       using \<open>bounded S\<close>
  3752       apply (simp add: compact_closure [symmetric] compact_def)
  3753       apply (drule_tac x=z in spec)
  3754       using closure_subset apply force
  3755       done
  3756     then have ftendsw: "((\<lambda>n. f (z n)) \<circ> K) \<longlonglongrightarrow> w"
  3757       by (metis LIMSEQ_subseq_LIMSEQ fun.map_cong0 fz tendsw)
  3758     have zKs: "\<And>n. (z \<circ> K) n \<in> S" by (simp add: zs)
  3759     have fz: "f \<circ> z = \<xi>"  "(\<lambda>n. f (z n)) = \<xi>"
  3760       using fz by auto
  3761     then have "(\<xi> \<circ> K) \<longlonglongrightarrow> f y"
  3762       by (metis (no_types) Klim zKs y contf comp_assoc continuous_on_closure_sequentially)
  3763     with fz have wy: "w = f y" using fz LIMSEQ_unique ftendsw by auto
  3764     have rle: "r \<le> norm (f y - f a)"
  3765       apply (rule le_no)
  3766       using w wy oint
  3767       by (force simp: imageI image_mono interiorI interior_subset frontier_def y)
  3768     have **: "(b \<inter> (- S) \<noteq> {} \<and> b - (- S) \<noteq> {} \<Longrightarrow> b \<inter> f \<noteq> {})
  3769               \<Longrightarrow> (b \<inter> S \<noteq> {}) \<Longrightarrow> b \<inter> f = {} \<Longrightarrow>
  3770               b \<subseteq> S" for b f and S :: "'b set"
  3771       by blast
  3772     show ?thesis
  3773       apply (rule **)   (*such a horrible mess*)
  3774       apply (rule connected_Int_frontier [where t = "f`S", OF connected_ball])
  3775       using \<open>a \<in> S\<close> \<open>0 < r\<close>
  3776       apply (auto simp: disjoint_iff_not_equal  dist_norm)
  3777       by (metis dw_le norm_minus_commute not_less order_trans rle wy)
  3778 qed
  3779 
  3780 end