src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy
changeset 34291 4e896680897e
parent 34289 c9c14c72d035
child 34915 7894c7dab132
equal deleted inserted replaced
34290:1edf0f223c6e 34291:4e896680897e
    33   "a \<le> b \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 b" "dest_vec1 (1::real^1) = 1"
    33   "a \<le> b \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 b" "dest_vec1 (1::real^1) = 1"
    34   by(auto simp add:vector_component_simps all_1 Cart_eq)
    34   by(auto simp add:vector_component_simps all_1 Cart_eq)
    35 
    35 
    36 lemma nequals0I:"x\<in>A \<Longrightarrow> A \<noteq> {}" by auto
    36 lemma nequals0I:"x\<in>A \<Longrightarrow> A \<noteq> {}" by auto
    37 
    37 
    38 lemma norm_not_0:"(x::real^'n::finite)\<noteq>0 \<Longrightarrow> norm x \<noteq> 0" by auto
    38 lemma norm_not_0:"(x::real^'n)\<noteq>0 \<Longrightarrow> norm x \<noteq> 0" by auto
    39 
    39 
    40 lemma setsum_delta_notmem: assumes "x\<notin>s"
    40 lemma setsum_delta_notmem: assumes "x\<notin>s"
    41   shows "setsum (\<lambda>y. if (y = x) then P x else Q y) s = setsum Q s"
    41   shows "setsum (\<lambda>y. if (y = x) then P x else Q y) s = setsum Q s"
    42         "setsum (\<lambda>y. if (x = y) then P x else Q y) s = setsum Q s"
    42         "setsum (\<lambda>y. if (x = y) then P x else Q y) s = setsum Q s"
    43         "setsum (\<lambda>y. if (y = x) then P y else Q y) s = setsum Q s"
    43         "setsum (\<lambda>y. if (y = x) then P y else Q y) s = setsum Q s"
    59 lemma mem_interval_1: fixes x :: "real^1" shows
    59 lemma mem_interval_1: fixes x :: "real^1" shows
    60  "(x \<in> {a .. b} \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 x \<and> dest_vec1 x \<le> dest_vec1 b)"
    60  "(x \<in> {a .. b} \<longleftrightarrow> dest_vec1 a \<le> dest_vec1 x \<and> dest_vec1 x \<le> dest_vec1 b)"
    61  "(x \<in> {a<..<b} \<longleftrightarrow> dest_vec1 a < dest_vec1 x \<and> dest_vec1 x < dest_vec1 b)"
    61  "(x \<in> {a<..<b} \<longleftrightarrow> dest_vec1 a < dest_vec1 x \<and> dest_vec1 x < dest_vec1 b)"
    62 by(simp_all add: Cart_eq vector_less_def vector_le_def dest_vec1_def all_1)
    62 by(simp_all add: Cart_eq vector_less_def vector_le_def dest_vec1_def all_1)
    63 
    63 
    64 lemma image_smult_interval:"(\<lambda>x. m *\<^sub>R (x::real^'n::finite)) ` {a..b} =
    64 lemma image_smult_interval:"(\<lambda>x. m *\<^sub>R (x::real^'n)) ` {a..b} =
    65   (if {a..b} = {} then {} else if 0 \<le> m then {m *\<^sub>R a..m *\<^sub>R b} else {m *\<^sub>R b..m *\<^sub>R a})"
    65   (if {a..b} = {} then {} else if 0 \<le> m then {m *\<^sub>R a..m *\<^sub>R b} else {m *\<^sub>R b..m *\<^sub>R a})"
    66   using image_affinity_interval[of m 0 a b] by auto
    66   using image_affinity_interval[of m 0 a b] by auto
    67 
    67 
    68 lemma dest_vec1_inverval:
    68 lemma dest_vec1_inverval:
    69   "dest_vec1 ` {a .. b} = {dest_vec1 a .. dest_vec1 b}"
    69   "dest_vec1 ` {a .. b} = {dest_vec1 a .. dest_vec1 b}"
    88 proof- have *:"x - y + (y - z) = x - z" by auto
    88 proof- have *:"x - y + (y - z) = x - z" by auto
    89   show ?thesis unfolding dist_norm norm_triangle_eq[of "x - y" "y - z", unfolded smult_conv_scaleR *]
    89   show ?thesis unfolding dist_norm norm_triangle_eq[of "x - y" "y - z", unfolded smult_conv_scaleR *]
    90     by(auto simp add:norm_minus_commute) qed
    90     by(auto simp add:norm_minus_commute) qed
    91 
    91 
    92 lemma norm_eqI:"x = y \<Longrightarrow> norm x = norm y" by auto 
    92 lemma norm_eqI:"x = y \<Longrightarrow> norm x = norm y" by auto 
    93 lemma norm_minus_eqI:"(x::real^'n::finite) = - y \<Longrightarrow> norm x = norm y" by auto
    93 lemma norm_minus_eqI:"(x::real^'n) = - y \<Longrightarrow> norm x = norm y" by auto
    94 
    94 
    95 lemma Min_grI: assumes "finite A" "A \<noteq> {}" "\<forall>a\<in>A. x < a" shows "x < Min A"
    95 lemma Min_grI: assumes "finite A" "A \<noteq> {}" "\<forall>a\<in>A. x < a" shows "x < Min A"
    96   unfolding Min_gr_iff[OF assms(1,2)] using assms(3) by auto
    96   unfolding Min_gr_iff[OF assms(1,2)] using assms(3) by auto
    97 
    97 
    98 lemma dimindex_ge_1:"CARD(_::finite) \<ge> 1"
    98 lemma dimindex_ge_1:"CARD(_::finite) \<ge> 1"
   416   by(auto simp add: real_convex_bound_lt inner_add)
   416   by(auto simp add: real_convex_bound_lt inner_add)
   417 
   417 
   418 lemma convex_halfspace_gt: "convex {x. inner a x > b}"
   418 lemma convex_halfspace_gt: "convex {x. inner a x > b}"
   419    using convex_halfspace_lt[of "-a" "-b"] by auto
   419    using convex_halfspace_lt[of "-a" "-b"] by auto
   420 
   420 
   421 lemma convex_positive_orthant: "convex {x::real^'n::finite. (\<forall>i. 0 \<le> x$i)}"
   421 lemma convex_positive_orthant: "convex {x::real^'n. (\<forall>i. 0 \<le> x$i)}"
   422   unfolding convex_def apply auto apply(erule_tac x=i in allE)+
   422   unfolding convex_def apply auto apply(erule_tac x=i in allE)+
   423   apply(rule add_nonneg_nonneg) by(auto simp add: mult_nonneg_nonneg)
   423   apply(rule add_nonneg_nonneg) by(auto simp add: mult_nonneg_nonneg)
   424 
   424 
   425 subsection {* Explicit expressions for convexity in terms of arbitrary sums. *}
   425 subsection {* Explicit expressions for convexity in terms of arbitrary sums. *}
   426 
   426 
  1138       apply(erule_tac x="2*\<^sub>R x" in ballE) apply(erule_tac x="2*\<^sub>R y" in ballE)
  1138       apply(erule_tac x="2*\<^sub>R x" in ballE) apply(erule_tac x="2*\<^sub>R y" in ballE)
  1139       apply(erule_tac x="1/2" in allE) apply simp apply(erule_tac x="1/2" in allE) by auto  }
  1139       apply(erule_tac x="1/2" in allE) apply simp apply(erule_tac x="1/2" in allE) by auto  }
  1140   thus ?thesis unfolding convex_def cone_def by auto
  1140   thus ?thesis unfolding convex_def cone_def by auto
  1141 qed
  1141 qed
  1142 
  1142 
  1143 lemma affine_dependent_biggerset: fixes s::"(real^'n::finite) set"
  1143 lemma affine_dependent_biggerset: fixes s::"(real^'n) set"
  1144   assumes "finite s" "card s \<ge> CARD('n) + 2"
  1144   assumes "finite s" "card s \<ge> CARD('n) + 2"
  1145   shows "affine_dependent s"
  1145   shows "affine_dependent s"
  1146 proof-
  1146 proof-
  1147   have "s\<noteq>{}" using assms by auto then obtain a where "a\<in>s" by auto
  1147   have "s\<noteq>{}" using assms by auto then obtain a where "a\<in>s" by auto
  1148   have *:"{x - a |x. x \<in> s - {a}} = (\<lambda>x. x - a) ` (s - {a})" by auto
  1148   have *:"{x - a |x. x \<in> s - {a}} = (\<lambda>x. x - a) ` (s - {a})" by auto
  1153   finally show ?thesis apply(subst insert_Diff[OF `a\<in>s`, THEN sym])
  1153   finally show ?thesis apply(subst insert_Diff[OF `a\<in>s`, THEN sym])
  1154     apply(rule dependent_imp_affine_dependent)
  1154     apply(rule dependent_imp_affine_dependent)
  1155     apply(rule dependent_biggerset) by auto qed
  1155     apply(rule dependent_biggerset) by auto qed
  1156 
  1156 
  1157 lemma affine_dependent_biggerset_general:
  1157 lemma affine_dependent_biggerset_general:
  1158   assumes "finite (s::(real^'n::finite) set)" "card s \<ge> dim s + 2"
  1158   assumes "finite (s::(real^'n) set)" "card s \<ge> dim s + 2"
  1159   shows "affine_dependent s"
  1159   shows "affine_dependent s"
  1160 proof-
  1160 proof-
  1161   from assms(2) have "s \<noteq> {}" by auto
  1161   from assms(2) have "s \<noteq> {}" by auto
  1162   then obtain a where "a\<in>s" by auto
  1162   then obtain a where "a\<in>s" by auto
  1163   have *:"{x - a |x. x \<in> s - {a}} = (\<lambda>x. x - a) ` (s - {a})" by auto
  1163   have *:"{x - a |x. x \<in> s - {a}} = (\<lambda>x. x - a) ` (s - {a})" by auto
  1172   finally show ?thesis apply(subst insert_Diff[OF `a\<in>s`, THEN sym])
  1172   finally show ?thesis apply(subst insert_Diff[OF `a\<in>s`, THEN sym])
  1173     apply(rule dependent_imp_affine_dependent) apply(rule dependent_biggerset_general) unfolding ** by auto qed
  1173     apply(rule dependent_imp_affine_dependent) apply(rule dependent_biggerset_general) unfolding ** by auto qed
  1174 
  1174 
  1175 subsection {* Caratheodory's theorem. *}
  1175 subsection {* Caratheodory's theorem. *}
  1176 
  1176 
  1177 lemma convex_hull_caratheodory: fixes p::"(real^'n::finite) set"
  1177 lemma convex_hull_caratheodory: fixes p::"(real^'n) set"
  1178   shows "convex hull p = {y. \<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> CARD('n) + 1 \<and>
  1178   shows "convex hull p = {y. \<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> CARD('n) + 1 \<and>
  1179   (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> setsum (\<lambda>v. u v *\<^sub>R v) s = y}"
  1179   (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> setsum (\<lambda>v. u v *\<^sub>R v) s = y}"
  1180   unfolding convex_hull_explicit expand_set_eq mem_Collect_eq
  1180   unfolding convex_hull_explicit expand_set_eq mem_Collect_eq
  1181 proof(rule,rule)
  1181 proof(rule,rule)
  1182   fix y let ?P = "\<lambda>n. \<exists>s u. finite s \<and> card s = n \<and> s \<subseteq> p \<and> (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
  1182   fix y let ?P = "\<lambda>n. \<exists>s u. finite s \<and> card s = n \<and> s \<subseteq> p \<and> (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
  1229   thus "\<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> CARD('n) + 1
  1229   thus "\<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> CARD('n) + 1
  1230     \<and> (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y" using obt by auto
  1230     \<and> (\<forall>x\<in>s. 0 \<le> u x) \<and> setsum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y" using obt by auto
  1231 qed auto
  1231 qed auto
  1232 
  1232 
  1233 lemma caratheodory:
  1233 lemma caratheodory:
  1234  "convex hull p = {x::real^'n::finite. \<exists>s. finite s \<and> s \<subseteq> p \<and>
  1234  "convex hull p = {x::real^'n. \<exists>s. finite s \<and> s \<subseteq> p \<and>
  1235       card s \<le> CARD('n) + 1 \<and> x \<in> convex hull s}"
  1235       card s \<le> CARD('n) + 1 \<and> x \<in> convex hull s}"
  1236   unfolding expand_set_eq apply(rule, rule) unfolding mem_Collect_eq proof-
  1236   unfolding expand_set_eq apply(rule, rule) unfolding mem_Collect_eq proof-
  1237   fix x assume "x \<in> convex hull p"
  1237   fix x assume "x \<in> convex hull p"
  1238   then obtain s u where "finite s" "s \<subseteq> p" "card s \<le> CARD('n) + 1"
  1238   then obtain s u where "finite s" "s \<subseteq> p" "card s \<le> CARD('n) + 1"
  1239      "\<forall>x\<in>s. 0 \<le> u x" "setsum u s = 1" "(\<Sum>v\<in>s. u v *\<^sub>R v) = x"unfolding convex_hull_caratheodory by auto
  1239      "\<forall>x\<in>s. 0 \<le> u x" "setsum u s = 1" "(\<Sum>v\<in>s. u v *\<^sub>R v) = x"unfolding convex_hull_caratheodory by auto
  1336     apply (rule compact_continuous_image)
  1336     apply (rule compact_continuous_image)
  1337     apply (intro compact_Times compact_real_interval assms)
  1337     apply (intro compact_Times compact_real_interval assms)
  1338     done
  1338     done
  1339 qed
  1339 qed
  1340 
  1340 
  1341 lemma compact_convex_hull: fixes s::"(real^'n::finite) set"
  1341 lemma compact_convex_hull: fixes s::"(real^'n) set"
  1342   assumes "compact s"  shows "compact(convex hull s)"
  1342   assumes "compact s"  shows "compact(convex hull s)"
  1343 proof(cases "s={}")
  1343 proof(cases "s={}")
  1344   case True thus ?thesis using compact_empty by simp
  1344   case True thus ?thesis using compact_empty by simp
  1345 next
  1345 next
  1346   case False then obtain w where "w\<in>s" by auto
  1346   case False then obtain w where "w\<in>s" by auto
  1544   using convex_hull_empty simplex_extremal_le[of s] by(cases "s={}")auto
  1544   using convex_hull_empty simplex_extremal_le[of s] by(cases "s={}")auto
  1545 
  1545 
  1546 subsection {* Closest point of a convex set is unique, with a continuous projection. *}
  1546 subsection {* Closest point of a convex set is unique, with a continuous projection. *}
  1547 
  1547 
  1548 definition
  1548 definition
  1549   closest_point :: "(real ^ 'n::finite) set \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 'n" where
  1549   closest_point :: "(real ^ 'n) set \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 'n" where
  1550  "closest_point s a = (SOME x. x \<in> s \<and> (\<forall>y\<in>s. dist a x \<le> dist a y))"
  1550  "closest_point s a = (SOME x. x \<in> s \<and> (\<forall>y\<in>s. dist a x \<le> dist a y))"
  1551 
  1551 
  1552 lemma closest_point_exists:
  1552 lemma closest_point_exists:
  1553   assumes "closed s" "s \<noteq> {}"
  1553   assumes "closed s" "s \<noteq> {}"
  1554   shows  "closest_point s a \<in> s" "\<forall>y\<in>s. dist a (closest_point s a) \<le> dist a y"
  1554   shows  "closest_point s a \<in> s" "\<forall>y\<in>s. dist a (closest_point s a) \<le> dist a y"
  1578 
  1578 
  1579 (* TODO: move *)
  1579 (* TODO: move *)
  1580 lemma norm_le: "norm x \<le> norm y \<longleftrightarrow> inner x x \<le> inner y y"
  1580 lemma norm_le: "norm x \<le> norm y \<longleftrightarrow> inner x x \<le> inner y y"
  1581   unfolding norm_eq_sqrt_inner by simp
  1581   unfolding norm_eq_sqrt_inner by simp
  1582 
  1582 
  1583 lemma closer_points_lemma: fixes y::"real^'n::finite"
  1583 lemma closer_points_lemma: fixes y::"real^'n"
  1584   assumes "inner y z > 0"
  1584   assumes "inner y z > 0"
  1585   shows "\<exists>u>0. \<forall>v>0. v \<le> u \<longrightarrow> norm(v *\<^sub>R z - y) < norm y"
  1585   shows "\<exists>u>0. \<forall>v>0. v \<le> u \<longrightarrow> norm(v *\<^sub>R z - y) < norm y"
  1586 proof- have z:"inner z z > 0" unfolding inner_gt_zero_iff using assms by auto
  1586 proof- have z:"inner z z > 0" unfolding inner_gt_zero_iff using assms by auto
  1587   thus ?thesis using assms apply(rule_tac x="inner y z / inner z z" in exI) apply(rule) defer proof(rule+)
  1587   thus ?thesis using assms apply(rule_tac x="inner y z / inner z z" in exI) apply(rule) defer proof(rule+)
  1588     fix v assume "0<v" "v \<le> inner y z / inner z z"
  1588     fix v assume "0<v" "v \<le> inner y z / inner z z"
  1589     thus "norm (v *\<^sub>R z - y) < norm y" unfolding norm_lt using z and assms
  1589     thus "norm (v *\<^sub>R z - y) < norm y" unfolding norm_lt using z and assms
  1590       by (simp add: field_simps inner_diff inner_commute mult_strict_left_mono[OF _ `0<v`])
  1590       by (simp add: field_simps inner_diff inner_commute mult_strict_left_mono[OF _ `0<v`])
  1591   qed(rule divide_pos_pos, auto) qed
  1591   qed(rule divide_pos_pos, auto) qed
  1592 
  1592 
  1593 lemma closer_point_lemma:
  1593 lemma closer_point_lemma:
  1594   fixes x y z :: "real ^ 'n::finite"
  1594   fixes x y z :: "real ^ 'n"
  1595   assumes "inner (y - x) (z - x) > 0"
  1595   assumes "inner (y - x) (z - x) > 0"
  1596   shows "\<exists>u>0. u \<le> 1 \<and> dist (x + u *\<^sub>R (z - x)) y < dist x y"
  1596   shows "\<exists>u>0. u \<le> 1 \<and> dist (x + u *\<^sub>R (z - x)) y < dist x y"
  1597 proof- obtain u where "u>0" and u:"\<forall>v>0. v \<le> u \<longrightarrow> norm (v *\<^sub>R (z - x) - (y - x)) < norm (y - x)"
  1597 proof- obtain u where "u>0" and u:"\<forall>v>0. v \<le> u \<longrightarrow> norm (v *\<^sub>R (z - x) - (y - x)) < norm (y - x)"
  1598     using closer_points_lemma[OF assms] by auto
  1598     using closer_points_lemma[OF assms] by auto
  1599   show ?thesis apply(rule_tac x="min u 1" in exI) using u[THEN spec[where x="min u 1"]] and `u>0`
  1599   show ?thesis apply(rule_tac x="min u 1" in exI) using u[THEN spec[where x="min u 1"]] and `u>0`
  1716       unfolding power2_norm_eq_inner and not_less by (auto simp add: field_simps inner_commute inner_diff)
  1716       unfolding power2_norm_eq_inner and not_less by (auto simp add: field_simps inner_commute inner_diff)
  1717   qed(insert `y\<in>s` `z\<notin>s`, auto)
  1717   qed(insert `y\<in>s` `z\<notin>s`, auto)
  1718 qed
  1718 qed
  1719 
  1719 
  1720 lemma separating_hyperplane_closed_0:
  1720 lemma separating_hyperplane_closed_0:
  1721   assumes "convex (s::(real^'n::finite) set)" "closed s" "0 \<notin> s"
  1721   assumes "convex (s::(real^'n) set)" "closed s" "0 \<notin> s"
  1722   shows "\<exists>a b. a \<noteq> 0 \<and> 0 < b \<and> (\<forall>x\<in>s. inner a x > b)"
  1722   shows "\<exists>a b. a \<noteq> 0 \<and> 0 < b \<and> (\<forall>x\<in>s. inner a x > b)"
  1723   proof(cases "s={}") guess a using UNIV_witness[where 'a='n] ..
  1723   proof(cases "s={}") guess a using UNIV_witness[where 'a='n] ..
  1724   case True have "norm ((basis a)::real^'n::finite) = 1" 
  1724   case True have "norm ((basis a)::real^'n) = 1" 
  1725     using norm_basis and dimindex_ge_1 by auto
  1725     using norm_basis and dimindex_ge_1 by auto
  1726   thus ?thesis apply(rule_tac x="basis a" in exI, rule_tac x=1 in exI) using True by auto
  1726   thus ?thesis apply(rule_tac x="basis a" in exI, rule_tac x=1 in exI) using True by auto
  1727 next case False thus ?thesis using False using separating_hyperplane_closed_point[OF assms]
  1727 next case False thus ?thesis using False using separating_hyperplane_closed_point[OF assms]
  1728     apply - apply(erule exE)+ unfolding dot_rzero apply(rule_tac x=a in exI, rule_tac x=b in exI) by auto qed
  1728     apply - apply(erule exE)+ unfolding dot_rzero apply(rule_tac x=a in exI, rule_tac x=b in exI) by auto qed
  1729 
  1729 
  1730 subsection {* Now set-to-set for closed/compact sets. *}
  1730 subsection {* Now set-to-set for closed/compact sets. *}
  1731 
  1731 
  1732 lemma separating_hyperplane_closed_compact:
  1732 lemma separating_hyperplane_closed_compact:
  1733   assumes "convex (s::(real^'n::finite) set)" "closed s" "convex t" "compact t" "t \<noteq> {}" "s \<inter> t = {}"
  1733   assumes "convex (s::(real^'n) set)" "closed s" "convex t" "compact t" "t \<noteq> {}" "s \<inter> t = {}"
  1734   shows "\<exists>a b. (\<forall>x\<in>s. inner a x < b) \<and> (\<forall>x\<in>t. inner a x > b)"
  1734   shows "\<exists>a b. (\<forall>x\<in>s. inner a x < b) \<and> (\<forall>x\<in>t. inner a x > b)"
  1735 proof(cases "s={}")
  1735 proof(cases "s={}")
  1736   case True
  1736   case True
  1737   obtain b where b:"b>0" "\<forall>x\<in>t. norm x \<le> b" using compact_imp_bounded[OF assms(4)] unfolding bounded_pos by auto
  1737   obtain b where b:"b>0" "\<forall>x\<in>t. norm x \<le> b" using compact_imp_bounded[OF assms(4)] unfolding bounded_pos by auto
  1738   obtain z::"real^'n" where z:"norm z = b + 1" using vector_choose_size[of "b + 1"] and b(1) by auto
  1738   obtain z::"real^'n" where z:"norm z = b + 1" using vector_choose_size[of "b + 1"] and b(1) by auto
  1770   thus ?thesis apply(rule_tac x="-a" in exI, rule_tac x="-b" in exI) by auto qed
  1770   thus ?thesis apply(rule_tac x="-a" in exI, rule_tac x="-b" in exI) by auto qed
  1771 
  1771 
  1772 subsection {* General case without assuming closure and getting non-strict separation. *}
  1772 subsection {* General case without assuming closure and getting non-strict separation. *}
  1773 
  1773 
  1774 lemma separating_hyperplane_set_0:
  1774 lemma separating_hyperplane_set_0:
  1775   assumes "convex s" "(0::real^'n::finite) \<notin> s"
  1775   assumes "convex s" "(0::real^'n) \<notin> s"
  1776   shows "\<exists>a. a \<noteq> 0 \<and> (\<forall>x\<in>s. 0 \<le> inner a x)"
  1776   shows "\<exists>a. a \<noteq> 0 \<and> (\<forall>x\<in>s. 0 \<le> inner a x)"
  1777 proof- let ?k = "\<lambda>c. {x::real^'n. 0 \<le> inner c x}"
  1777 proof- let ?k = "\<lambda>c. {x::real^'n. 0 \<le> inner c x}"
  1778   have "frontier (cball 0 1) \<inter> (\<Inter> (?k ` s)) \<noteq> {}"
  1778   have "frontier (cball 0 1) \<inter> (\<Inter> (?k ` s)) \<noteq> {}"
  1779     apply(rule compact_imp_fip) apply(rule compact_frontier[OF compact_cball])
  1779     apply(rule compact_imp_fip) apply(rule compact_frontier[OF compact_cball])
  1780     defer apply(rule,rule,erule conjE) proof-
  1780     defer apply(rule,rule,erule conjE) proof-
  1792   qed(insert closed_halfspace_ge, auto)
  1792   qed(insert closed_halfspace_ge, auto)
  1793   then obtain x where "norm x = 1" "\<forall>y\<in>s. x\<in>?k y" unfolding frontier_cball dist_norm by auto
  1793   then obtain x where "norm x = 1" "\<forall>y\<in>s. x\<in>?k y" unfolding frontier_cball dist_norm by auto
  1794   thus ?thesis apply(rule_tac x=x in exI) by(auto simp add: inner_commute) qed
  1794   thus ?thesis apply(rule_tac x=x in exI) by(auto simp add: inner_commute) qed
  1795 
  1795 
  1796 lemma separating_hyperplane_sets:
  1796 lemma separating_hyperplane_sets:
  1797   assumes "convex s" "convex (t::(real^'n::finite) set)" "s \<noteq> {}" "t \<noteq> {}" "s \<inter> t = {}"
  1797   assumes "convex s" "convex (t::(real^'n) set)" "s \<noteq> {}" "t \<noteq> {}" "s \<inter> t = {}"
  1798   shows "\<exists>a b. a \<noteq> 0 \<and> (\<forall>x\<in>s. inner a x \<le> b) \<and> (\<forall>x\<in>t. inner a x \<ge> b)"
  1798   shows "\<exists>a b. a \<noteq> 0 \<and> (\<forall>x\<in>s. inner a x \<le> b) \<and> (\<forall>x\<in>t. inner a x \<ge> b)"
  1799 proof- from separating_hyperplane_set_0[OF convex_differences[OF assms(2,1)]]
  1799 proof- from separating_hyperplane_set_0[OF convex_differences[OF assms(2,1)]]
  1800   obtain a where "a\<noteq>0" "\<forall>x\<in>{x - y |x y. x \<in> t \<and> y \<in> s}. 0 \<le> inner a x" 
  1800   obtain a where "a\<noteq>0" "\<forall>x\<in>{x - y |x y. x \<in> t \<and> y \<in> s}. 0 \<le> inner a x" 
  1801     using assms(3-5) by auto 
  1801     using assms(3-5) by auto 
  1802   hence "\<forall>x\<in>t. \<forall>y\<in>s. inner a y \<le> inner a x"
  1802   hence "\<forall>x\<in>t. \<forall>y\<in>s. inner a y \<le> inner a x"
  1953   from radon_partition[OF *] guess m .. then guess p ..
  1953   from radon_partition[OF *] guess m .. then guess p ..
  1954   thus ?thesis apply(rule_tac that[of p m]) using s by auto qed
  1954   thus ?thesis apply(rule_tac that[of p m]) using s by auto qed
  1955 
  1955 
  1956 subsection {* Helly's theorem. *}
  1956 subsection {* Helly's theorem. *}
  1957 
  1957 
  1958 lemma helly_induct: fixes f::"(real^'n::finite) set set"
  1958 lemma helly_induct: fixes f::"(real^'n) set set"
  1959   assumes "card f = n" "n \<ge> CARD('n) + 1"
  1959   assumes "card f = n" "n \<ge> CARD('n) + 1"
  1960   "\<forall>s\<in>f. convex s" "\<forall>t\<subseteq>f. card t = CARD('n) + 1 \<longrightarrow> \<Inter> t \<noteq> {}"
  1960   "\<forall>s\<in>f. convex s" "\<forall>t\<subseteq>f. card t = CARD('n) + 1 \<longrightarrow> \<Inter> t \<noteq> {}"
  1961   shows "\<Inter> f \<noteq> {}"
  1961   shows "\<Inter> f \<noteq> {}"
  1962 using assms proof(induct n arbitrary: f)
  1962 using assms proof(induct n arbitrary: f)
  1963 case (Suc n)
  1963 case (Suc n)
  1991       thus "x\<in>\<Inter>g" using X[THEN bspec[where x=y]] using * f by auto
  1991       thus "x\<in>\<Inter>g" using X[THEN bspec[where x=y]] using * f by auto
  1992     qed(auto)
  1992     qed(auto)
  1993     thus ?thesis unfolding f using mp(3)[unfolded gh] by blast qed
  1993     thus ?thesis unfolding f using mp(3)[unfolded gh] by blast qed
  1994 qed(insert dimindex_ge_1, auto) qed(auto)
  1994 qed(insert dimindex_ge_1, auto) qed(auto)
  1995 
  1995 
  1996 lemma helly: fixes f::"(real^'n::finite) set set"
  1996 lemma helly: fixes f::"(real^'n) set set"
  1997   assumes "card f \<ge> CARD('n) + 1" "\<forall>s\<in>f. convex s"
  1997   assumes "card f \<ge> CARD('n) + 1" "\<forall>s\<in>f. convex s"
  1998           "\<forall>t\<subseteq>f. card t = CARD('n) + 1 \<longrightarrow> \<Inter> t \<noteq> {}"
  1998           "\<forall>t\<subseteq>f. card t = CARD('n) + 1 \<longrightarrow> \<Inter> t \<noteq> {}"
  1999   shows "\<Inter> f \<noteq>{}"
  1999   shows "\<Inter> f \<noteq>{}"
  2000   apply(rule helly_induct) using assms by auto
  2000   apply(rule helly_induct) using assms by auto
  2001 
  2001 
  2060   qed(insert `y\<in>s`, auto simp add: dist_norm scaleR_left_distrib obt(3))
  2060   qed(insert `y\<in>s`, auto simp add: dist_norm scaleR_left_distrib obt(3))
  2061   thus ?thesis apply(rule_tac that[of u]) apply(rule obt(1), assumption)
  2061   thus ?thesis apply(rule_tac that[of u]) apply(rule obt(1), assumption)
  2062     apply(rule,rule,rule ccontr) apply(rule u_max) by auto qed
  2062     apply(rule,rule,rule ccontr) apply(rule u_max) by auto qed
  2063 
  2063 
  2064 lemma starlike_compact_projective:
  2064 lemma starlike_compact_projective:
  2065   assumes "compact s" "cball (0::real^'n::finite) 1 \<subseteq> s "
  2065   assumes "compact s" "cball (0::real^'n) 1 \<subseteq> s "
  2066   "\<forall>x\<in>s. \<forall>u. 0 \<le> u \<and> u < 1 \<longrightarrow> (u *\<^sub>R x) \<in> (s - frontier s )"
  2066   "\<forall>x\<in>s. \<forall>u. 0 \<le> u \<and> u < 1 \<longrightarrow> (u *\<^sub>R x) \<in> (s - frontier s )"
  2067   shows "s homeomorphic (cball (0::real^'n::finite) 1)"
  2067   shows "s homeomorphic (cball (0::real^'n) 1)"
  2068 proof-
  2068 proof-
  2069   have fs:"frontier s \<subseteq> s" apply(rule frontier_subset_closed) using compact_imp_closed[OF assms(1)] by simp
  2069   have fs:"frontier s \<subseteq> s" apply(rule frontier_subset_closed) using compact_imp_closed[OF assms(1)] by simp
  2070   def pi \<equiv> "\<lambda>x::real^'n. inverse (norm x) *\<^sub>R x"
  2070   def pi \<equiv> "\<lambda>x::real^'n. inverse (norm x) *\<^sub>R x"
  2071   have "0 \<notin> frontier s" unfolding frontier_straddle apply(rule ccontr) unfolding not_not apply(erule_tac x=1 in allE)
  2071   have "0 \<notin> frontier s" unfolding frontier_straddle apply(rule ccontr) unfolding not_not apply(erule_tac x=1 in allE)
  2072     using assms(2)[unfolded subset_eq Ball_def mem_cball] by auto
  2072     using assms(2)[unfolded subset_eq Ball_def mem_cball] by auto
  2198         ultimately have *:"pi x = pi y" using surf(4)[THEN bspec[where x="pi x"]] surf(4)[THEN bspec[where x="pi y"]] by auto 
  2198         ultimately have *:"pi x = pi y" using surf(4)[THEN bspec[where x="pi x"]] surf(4)[THEN bspec[where x="pi y"]] by auto 
  2199         moreover have "norm x = norm y" using as(3)[unfolded *] using False by(auto dest:surf_0)
  2199         moreover have "norm x = norm y" using as(3)[unfolded *] using False by(auto dest:surf_0)
  2200         ultimately show ?thesis using injpi by auto qed qed
  2200         ultimately show ?thesis using injpi by auto qed qed
  2201   qed auto qed
  2201   qed auto qed
  2202 
  2202 
  2203 lemma homeomorphic_convex_compact_lemma: fixes s::"(real^'n::finite) set"
  2203 lemma homeomorphic_convex_compact_lemma: fixes s::"(real^'n) set"
  2204   assumes "convex s" "compact s" "cball 0 1 \<subseteq> s"
  2204   assumes "convex s" "compact s" "cball 0 1 \<subseteq> s"
  2205   shows "s homeomorphic (cball (0::real^'n) 1)"
  2205   shows "s homeomorphic (cball (0::real^'n) 1)"
  2206   apply(rule starlike_compact_projective[OF assms(2-3)]) proof(rule,rule,rule,erule conjE)
  2206   apply(rule starlike_compact_projective[OF assms(2-3)]) proof(rule,rule,rule,erule conjE)
  2207   fix x u assume as:"x \<in> s" "0 \<le> u" "u < (1::real)"
  2207   fix x u assume as:"x \<in> s" "0 \<le> u" "u < (1::real)"
  2208   hence "u *\<^sub>R x \<in> interior s" unfolding interior_def mem_Collect_eq
  2208   hence "u *\<^sub>R x \<in> interior s" unfolding interior_def mem_Collect_eq
  2216       unfolding class_semiring.mul_a using `u<1` by auto
  2216       unfolding class_semiring.mul_a using `u<1` by auto
  2217     thus "y \<in> s" using assms(1)[unfolded convex_def, rule_format, of "inverse(1 - u) *\<^sub>R (y - u *\<^sub>R x)" x "1 - u" u]
  2217     thus "y \<in> s" using assms(1)[unfolded convex_def, rule_format, of "inverse(1 - u) *\<^sub>R (y - u *\<^sub>R x)" x "1 - u" u]
  2218       using as unfolding scaleR_scaleR by auto qed auto
  2218       using as unfolding scaleR_scaleR by auto qed auto
  2219   thus "u *\<^sub>R x \<in> s - frontier s" using frontier_def and interior_subset by auto qed
  2219   thus "u *\<^sub>R x \<in> s - frontier s" using frontier_def and interior_subset by auto qed
  2220 
  2220 
  2221 lemma homeomorphic_convex_compact_cball: fixes e::real and s::"(real^'n::finite) set"
  2221 lemma homeomorphic_convex_compact_cball: fixes e::real and s::"(real^'n) set"
  2222   assumes "convex s" "compact s" "interior s \<noteq> {}" "0 < e"
  2222   assumes "convex s" "compact s" "interior s \<noteq> {}" "0 < e"
  2223   shows "s homeomorphic (cball (b::real^'n::finite) e)"
  2223   shows "s homeomorphic (cball (b::real^'n) e)"
  2224 proof- obtain a where "a\<in>interior s" using assms(3) by auto
  2224 proof- obtain a where "a\<in>interior s" using assms(3) by auto
  2225   then obtain d where "d>0" and d:"cball a d \<subseteq> s" unfolding mem_interior_cball by auto
  2225   then obtain d where "d>0" and d:"cball a d \<subseteq> s" unfolding mem_interior_cball by auto
  2226   let ?d = "inverse d" and ?n = "0::real^'n"
  2226   let ?d = "inverse d" and ?n = "0::real^'n"
  2227   have "cball ?n 1 \<subseteq> (\<lambda>x. inverse d *\<^sub>R (x - a)) ` s"
  2227   have "cball ?n 1 \<subseteq> (\<lambda>x. inverse d *\<^sub>R (x - a)) ` s"
  2228     apply(rule, rule_tac x="d *\<^sub>R x + a" in image_eqI) defer
  2228     apply(rule, rule_tac x="d *\<^sub>R x + a" in image_eqI) defer
  2233     using assms(1,2) by(auto simp add: uminus_add_conv_diff scaleR_right_diff_distrib)
  2233     using assms(1,2) by(auto simp add: uminus_add_conv_diff scaleR_right_diff_distrib)
  2234   thus ?thesis apply(rule_tac homeomorphic_trans[OF _ homeomorphic_balls(2)[of 1 _ ?n]])
  2234   thus ?thesis apply(rule_tac homeomorphic_trans[OF _ homeomorphic_balls(2)[of 1 _ ?n]])
  2235     apply(rule homeomorphic_trans[OF homeomorphic_affinity[of "?d" s "?d *\<^sub>R -a"]])
  2235     apply(rule homeomorphic_trans[OF homeomorphic_affinity[of "?d" s "?d *\<^sub>R -a"]])
  2236     using `d>0` `e>0` by(auto simp add: uminus_add_conv_diff scaleR_right_diff_distrib) qed
  2236     using `d>0` `e>0` by(auto simp add: uminus_add_conv_diff scaleR_right_diff_distrib) qed
  2237 
  2237 
  2238 lemma homeomorphic_convex_compact: fixes s::"(real^'n::finite) set" and t::"(real^'n) set"
  2238 lemma homeomorphic_convex_compact: fixes s::"(real^'n) set" and t::"(real^'n) set"
  2239   assumes "convex s" "compact s" "interior s \<noteq> {}"
  2239   assumes "convex s" "compact s" "interior s \<noteq> {}"
  2240           "convex t" "compact t" "interior t \<noteq> {}"
  2240           "convex t" "compact t" "interior t \<noteq> {}"
  2241   shows "s homeomorphic t"
  2241   shows "s homeomorphic t"
  2242   using assms by(meson zero_less_one homeomorphic_trans homeomorphic_convex_compact_cball homeomorphic_sym)
  2242   using assms by(meson zero_less_one homeomorphic_trans homeomorphic_convex_compact_cball homeomorphic_sym)
  2243 
  2243 
  2244 subsection {* Epigraphs of convex functions. *}
  2244 subsection {* Epigraphs of convex functions. *}
  2245 
  2245 
  2246 definition "epigraph s (f::real^'n::finite \<Rightarrow> real) = {xy. fstcart xy \<in> s \<and> f(fstcart xy) \<le> dest_vec1 (sndcart xy)}"
  2246 definition "epigraph s (f::real^'n \<Rightarrow> real) = {xy. fstcart xy \<in> s \<and> f(fstcart xy) \<le> dest_vec1 (sndcart xy)}"
  2247 
  2247 
  2248 lemma mem_epigraph: "(pastecart x (vec1 y)) \<in> epigraph s f \<longleftrightarrow> x \<in> s \<and> f x \<le> y" unfolding epigraph_def by auto
  2248 lemma mem_epigraph: "(pastecart x (vec1 y)) \<in> epigraph s f \<longleftrightarrow> x \<in> s \<and> f x \<le> y" unfolding epigraph_def by auto
  2249 
  2249 
  2250 lemma convex_epigraph: 
  2250 lemma convex_epigraph: 
  2251   "convex(epigraph s f) \<longleftrightarrow> convex_on s f \<and> convex s"
  2251   "convex(epigraph s f) \<longleftrightarrow> convex_on s f \<and> convex s"
  2315 lemma is_interval_connected:
  2315 lemma is_interval_connected:
  2316   fixes s :: "(real ^ _) set"
  2316   fixes s :: "(real ^ _) set"
  2317   shows "is_interval s \<Longrightarrow> connected s"
  2317   shows "is_interval s \<Longrightarrow> connected s"
  2318   using is_interval_convex convex_connected by auto
  2318   using is_interval_convex convex_connected by auto
  2319 
  2319 
  2320 lemma convex_interval: "convex {a .. b}" "convex {a<..<b::real^'n::finite}"
  2320 lemma convex_interval: "convex {a .. b}" "convex {a<..<b::real^'n}"
  2321   apply(rule_tac[!] is_interval_convex) using is_interval_interval by auto
  2321   apply(rule_tac[!] is_interval_convex) using is_interval_interval by auto
  2322 
  2322 
  2323 subsection {* On @{text "real^1"}, @{text "is_interval"}, @{text "convex"} and @{text "connected"} are all equivalent. *}
  2323 subsection {* On @{text "real^1"}, @{text "is_interval"}, @{text "convex"} and @{text "connected"} are all equivalent. *}
  2324 
  2324 
  2325 lemma is_interval_1:
  2325 lemma is_interval_1:
  2349   "connected s \<longleftrightarrow> convex (s::(real^1) set)" 
  2349   "connected s \<longleftrightarrow> convex (s::(real^1) set)" 
  2350   using is_interval_convex convex_connected is_interval_connected_1 by auto
  2350   using is_interval_convex convex_connected is_interval_connected_1 by auto
  2351 
  2351 
  2352 subsection {* Another intermediate value theorem formulation. *}
  2352 subsection {* Another intermediate value theorem formulation. *}
  2353 
  2353 
  2354 lemma ivt_increasing_component_on_1: fixes f::"real^1 \<Rightarrow> real^'n::finite"
  2354 lemma ivt_increasing_component_on_1: fixes f::"real^1 \<Rightarrow> real^'n"
  2355   assumes "dest_vec1 a \<le> dest_vec1 b" "continuous_on {a .. b} f" "(f a)$k \<le> y" "y \<le> (f b)$k"
  2355   assumes "dest_vec1 a \<le> dest_vec1 b" "continuous_on {a .. b} f" "(f a)$k \<le> y" "y \<le> (f b)$k"
  2356   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2356   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2357 proof- have "f a \<in> f ` {a..b}" "f b \<in> f ` {a..b}" apply(rule_tac[!] imageI) 
  2357 proof- have "f a \<in> f ` {a..b}" "f b \<in> f ` {a..b}" apply(rule_tac[!] imageI) 
  2358     using assms(1) by(auto simp add: vector_le_def dest_vec1_def)
  2358     using assms(1) by(auto simp add: vector_le_def dest_vec1_def)
  2359   thus ?thesis using connected_ivt_component[of "f ` {a..b}" "f a" "f b" k y]
  2359   thus ?thesis using connected_ivt_component[of "f ` {a..b}" "f a" "f b" k y]
  2360     using connected_continuous_image[OF assms(2) convex_connected[OF convex_interval(1)]]
  2360     using connected_continuous_image[OF assms(2) convex_connected[OF convex_interval(1)]]
  2361     using assms by(auto intro!: imageI) qed
  2361     using assms by(auto intro!: imageI) qed
  2362 
  2362 
  2363 lemma ivt_increasing_component_1: fixes f::"real^1 \<Rightarrow> real^'n::finite"
  2363 lemma ivt_increasing_component_1: fixes f::"real^1 \<Rightarrow> real^'n"
  2364   assumes "dest_vec1 a \<le> dest_vec1 b"
  2364   assumes "dest_vec1 a \<le> dest_vec1 b"
  2365   "\<forall>x\<in>{a .. b}. continuous (at x) f" "f a$k \<le> y" "y \<le> f b$k"
  2365   "\<forall>x\<in>{a .. b}. continuous (at x) f" "f a$k \<le> y" "y \<le> f b$k"
  2366   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2366   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2367   apply(rule ivt_increasing_component_on_1) using assms using continuous_at_imp_continuous_on by auto
  2367   apply(rule ivt_increasing_component_on_1) using assms using continuous_at_imp_continuous_on by auto
  2368 
  2368 
  2369 lemma ivt_decreasing_component_on_1: fixes f::"real^1 \<Rightarrow> real^'n::finite"
  2369 lemma ivt_decreasing_component_on_1: fixes f::"real^1 \<Rightarrow> real^'n"
  2370   assumes "dest_vec1 a \<le> dest_vec1 b" "continuous_on {a .. b} f" "(f b)$k \<le> y" "y \<le> (f a)$k"
  2370   assumes "dest_vec1 a \<le> dest_vec1 b" "continuous_on {a .. b} f" "(f b)$k \<le> y" "y \<le> (f a)$k"
  2371   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2371   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2372   apply(subst neg_equal_iff_equal[THEN sym]) unfolding vector_uminus_component[THEN sym]
  2372   apply(subst neg_equal_iff_equal[THEN sym]) unfolding vector_uminus_component[THEN sym]
  2373   apply(rule ivt_increasing_component_on_1) using assms using continuous_on_neg
  2373   apply(rule ivt_increasing_component_on_1) using assms using continuous_on_neg
  2374   by(auto simp add:vector_uminus_component)
  2374   by(auto simp add:vector_uminus_component)
  2375 
  2375 
  2376 lemma ivt_decreasing_component_1: fixes f::"real^1 \<Rightarrow> real^'n::finite"
  2376 lemma ivt_decreasing_component_1: fixes f::"real^1 \<Rightarrow> real^'n"
  2377   assumes "dest_vec1 a \<le> dest_vec1 b" "\<forall>x\<in>{a .. b}. continuous (at x) f" "f b$k \<le> y" "y \<le> f a$k"
  2377   assumes "dest_vec1 a \<le> dest_vec1 b" "\<forall>x\<in>{a .. b}. continuous (at x) f" "f b$k \<le> y" "y \<le> f a$k"
  2378   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2378   shows "\<exists>x\<in>{a..b}. (f x)$k = y"
  2379   apply(rule ivt_decreasing_component_on_1) using assms using continuous_at_imp_continuous_on by auto
  2379   apply(rule ivt_decreasing_component_on_1) using assms using continuous_at_imp_continuous_on by auto
  2380 
  2380 
  2381 subsection {* A bound within a convex hull, and so an interval. *}
  2381 subsection {* A bound within a convex hull, and so an interval. *}
  2392     using assms(2) obt(1) by auto
  2392     using assms(2) obt(1) by auto
  2393   thus "f x \<le> b" using assms(1)[unfolded convex_on[OF convex_convex_hull], rule_format, of k u v]
  2393   thus "f x \<le> b" using assms(1)[unfolded convex_on[OF convex_convex_hull], rule_format, of k u v]
  2394     unfolding obt(2-3) using obt(1) and hull_subset[unfolded subset_eq, rule_format, of _ s] by auto qed
  2394     unfolding obt(2-3) using obt(1) and hull_subset[unfolded subset_eq, rule_format, of _ s] by auto qed
  2395 
  2395 
  2396 lemma unit_interval_convex_hull:
  2396 lemma unit_interval_convex_hull:
  2397   "{0::real^'n::finite .. 1} = convex hull {x. \<forall>i. (x$i = 0) \<or> (x$i = 1)}" (is "?int = convex hull ?points")
  2397   "{0::real^'n .. 1} = convex hull {x. \<forall>i. (x$i = 0) \<or> (x$i = 1)}" (is "?int = convex hull ?points")
  2398 proof- have 01:"{0,1} \<subseteq> convex hull ?points" apply rule apply(rule_tac hull_subset[unfolded subset_eq, rule_format]) by auto
  2398 proof- have 01:"{0,1} \<subseteq> convex hull ?points" apply rule apply(rule_tac hull_subset[unfolded subset_eq, rule_format]) by auto
  2399   { fix n x assume "x\<in>{0::real^'n .. 1}" "n \<le> CARD('n)" "card {i. x$i \<noteq> 0} \<le> n" 
  2399   { fix n x assume "x\<in>{0::real^'n .. 1}" "n \<le> CARD('n)" "card {i. x$i \<noteq> 0} \<le> n" 
  2400   hence "x\<in>convex hull ?points" proof(induct n arbitrary: x)
  2400   hence "x\<in>convex hull ?points" proof(induct n arbitrary: x)
  2401     case 0 hence "x = 0" apply(subst Cart_eq) apply rule by auto
  2401     case 0 hence "x = 0" apply(subst Cart_eq) apply rule by auto
  2402     thus "x\<in>convex hull ?points" using 01 by auto
  2402     thus "x\<in>convex hull ?points" using 01 by auto
  2428         { fix j have "x$j \<noteq> 0 \<Longrightarrow> 0 \<le> (x $ j - x $ i) / (1 - x $ i)" "(x $ j - x $ i) / (1 - x $ i) \<le> 1"
  2428         { fix j have "x$j \<noteq> 0 \<Longrightarrow> 0 \<le> (x $ j - x $ i) / (1 - x $ i)" "(x $ j - x $ i) / (1 - x $ i) \<le> 1"
  2429             apply(rule_tac divide_nonneg_pos) using i(1)[of j] using False i01
  2429             apply(rule_tac divide_nonneg_pos) using i(1)[of j] using False i01
  2430             using Suc(2)[unfolded mem_interval, rule_format, of j] by(auto simp add:field_simps Cart_lambda_beta) 
  2430             using Suc(2)[unfolded mem_interval, rule_format, of j] by(auto simp add:field_simps Cart_lambda_beta) 
  2431           hence "0 \<le> ?y j \<and> ?y j \<le> 1" by auto }
  2431           hence "0 \<le> ?y j \<and> ?y j \<le> 1" by auto }
  2432         moreover have "i\<in>{j. x$j \<noteq> 0} - {j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0}" using i01 by(auto simp add: Cart_lambda_beta)
  2432         moreover have "i\<in>{j. x$j \<noteq> 0} - {j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0}" using i01 by(auto simp add: Cart_lambda_beta)
  2433         hence "{j. x$j \<noteq> 0} \<noteq> {j. ((\<chi> j. ?y j)::real^'n::finite) $ j \<noteq> 0}" by auto
  2433         hence "{j. x$j \<noteq> 0} \<noteq> {j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0}" by auto
  2434         hence **:"{j. ((\<chi> j. ?y j)::real^'n::finite) $ j \<noteq> 0} \<subset> {j. x$j \<noteq> 0}" apply - apply rule by(auto simp add: Cart_lambda_beta)  
  2434         hence **:"{j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0} \<subset> {j. x$j \<noteq> 0}" apply - apply rule by(auto simp add: Cart_lambda_beta)  
  2435         have "card {j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0} \<le> n" using less_le_trans[OF psubset_card_mono[OF _ **] Suc(4)] by auto
  2435         have "card {j. ((\<chi> j. ?y j)::real^'n) $ j \<noteq> 0} \<le> n" using less_le_trans[OF psubset_card_mono[OF _ **] Suc(4)] by auto
  2436         ultimately show ?thesis apply(subst *) apply(rule convex_convex_hull[unfolded convex_def, rule_format])
  2436         ultimately show ?thesis apply(subst *) apply(rule convex_convex_hull[unfolded convex_def, rule_format])
  2437           apply(rule_tac hull_subset[unfolded subset_eq, rule_format]) defer apply(rule Suc(1))
  2437           apply(rule_tac hull_subset[unfolded subset_eq, rule_format]) defer apply(rule Suc(1))
  2438           unfolding mem_interval using i01 Suc(3) by (auto simp add: Cart_lambda_beta)
  2438           unfolding mem_interval using i01 Suc(3) by (auto simp add: Cart_lambda_beta)
  2439       qed qed qed } note * = this
  2439       qed qed qed } note * = this
  2442     unfolding mem_interval apply rule unfolding mem_Collect_eq apply(erule_tac x=i in allE)
  2442     unfolding mem_interval apply rule unfolding mem_Collect_eq apply(erule_tac x=i in allE)
  2443     by(auto simp add: vector_le_def mem_def[of _ convex]) qed
  2443     by(auto simp add: vector_le_def mem_def[of _ convex]) qed
  2444 
  2444 
  2445 subsection {* And this is a finite set of vertices. *}
  2445 subsection {* And this is a finite set of vertices. *}
  2446 
  2446 
  2447 lemma unit_cube_convex_hull: obtains s where "finite s" "{0 .. 1::real^'n::finite} = convex hull s"
  2447 lemma unit_cube_convex_hull: obtains s where "finite s" "{0 .. 1::real^'n} = convex hull s"
  2448   apply(rule that[of "{x::real^'n::finite. \<forall>i. x$i=0 \<or> x$i=1}"])
  2448   apply(rule that[of "{x::real^'n. \<forall>i. x$i=0 \<or> x$i=1}"])
  2449   apply(rule finite_subset[of _ "(\<lambda>s. (\<chi> i. if i\<in>s then 1::real else 0)::real^'n::finite) ` UNIV"])
  2449   apply(rule finite_subset[of _ "(\<lambda>s. (\<chi> i. if i\<in>s then 1::real else 0)::real^'n) ` UNIV"])
  2450   prefer 3 apply(rule unit_interval_convex_hull) apply rule unfolding mem_Collect_eq proof-
  2450   prefer 3 apply(rule unit_interval_convex_hull) apply rule unfolding mem_Collect_eq proof-
  2451   fix x::"real^'n" assume as:"\<forall>i. x $ i = 0 \<or> x $ i = 1"
  2451   fix x::"real^'n" assume as:"\<forall>i. x $ i = 0 \<or> x $ i = 1"
  2452   show "x \<in> (\<lambda>s. \<chi> i. if i \<in> s then 1 else 0) ` UNIV" apply(rule image_eqI[where x="{i. x$i = 1}"])
  2452   show "x \<in> (\<lambda>s. \<chi> i. if i \<in> s then 1 else 0) ` UNIV" apply(rule image_eqI[where x="{i. x$i = 1}"])
  2453     unfolding Cart_eq using as by(auto simp add:Cart_lambda_beta) qed auto
  2453     unfolding Cart_eq using as by(auto simp add:Cart_lambda_beta) qed auto
  2454 
  2454 
  2455 subsection {* Hence any cube (could do any nonempty interval). *}
  2455 subsection {* Hence any cube (could do any nonempty interval). *}
  2456 
  2456 
  2457 lemma cube_convex_hull:
  2457 lemma cube_convex_hull:
  2458   assumes "0 < d" obtains s::"(real^'n::finite) set" where "finite s" "{x - (\<chi> i. d) .. x + (\<chi> i. d)} = convex hull s" proof-
  2458   assumes "0 < d" obtains s::"(real^'n) set" where "finite s" "{x - (\<chi> i. d) .. x + (\<chi> i. d)} = convex hull s" proof-
  2459   let ?d = "(\<chi> i. d)::real^'n"
  2459   let ?d = "(\<chi> i. d)::real^'n"
  2460   have *:"{x - ?d .. x + ?d} = (\<lambda>y. x - ?d + (2 * d) *\<^sub>R y) ` {0 .. 1}" apply(rule set_ext, rule)
  2460   have *:"{x - ?d .. x + ?d} = (\<lambda>y. x - ?d + (2 * d) *\<^sub>R y) ` {0 .. 1}" apply(rule set_ext, rule)
  2461     unfolding image_iff defer apply(erule bexE) proof-
  2461     unfolding image_iff defer apply(erule bexE) proof-
  2462     fix y assume as:"y\<in>{x - ?d .. x + ?d}"
  2462     fix y assume as:"y\<in>{x - ?d .. x + ?d}"
  2463     { fix i::'n have "x $ i \<le> d + y $ i" "y $ i \<le> d + x $ i" using as[unfolded mem_interval, THEN spec[where x=i]]
  2463     { fix i::'n have "x $ i \<le> d + y $ i" "y $ i \<le> d + x $ i" using as[unfolded mem_interval, THEN spec[where x=i]]
  2550   thus "\<bar>f y\<bar> \<le> b + 2 * \<bar>f x\<bar>" using zero_le_dist[of x y] by auto qed
  2550   thus "\<bar>f y\<bar> \<le> b + 2 * \<bar>f x\<bar>" using zero_le_dist[of x y] by auto qed
  2551 
  2551 
  2552 subsection {* Hence a convex function on an open set is continuous. *}
  2552 subsection {* Hence a convex function on an open set is continuous. *}
  2553 
  2553 
  2554 lemma convex_on_continuous:
  2554 lemma convex_on_continuous:
  2555   assumes "open (s::(real^'n::finite) set)" "convex_on s f" 
  2555   assumes "open (s::(real^'n) set)" "convex_on s f" 
  2556   shows "continuous_on s f"
  2556   shows "continuous_on s f"
  2557   unfolding continuous_on_eq_continuous_at[OF assms(1)] proof
  2557   unfolding continuous_on_eq_continuous_at[OF assms(1)] proof
  2558   note dimge1 = dimindex_ge_1[where 'a='n]
  2558   note dimge1 = dimindex_ge_1[where 'a='n]
  2559   fix x assume "x\<in>s"
  2559   fix x assume "x\<in>s"
  2560   then obtain e where e:"cball x e \<subseteq> s" "e>0" using assms(1) unfolding open_contains_cball by auto
  2560   then obtain e where e:"cball x e \<subseteq> s" "e>0" using assms(1) unfolding open_contains_cball by auto
  2595 
  2595 
  2596 (* Use the same overloading tricks as for intervals, so that 
  2596 (* Use the same overloading tricks as for intervals, so that 
  2597    segment[a,b] is closed and segment(a,b) is open relative to affine hull. *)
  2597    segment[a,b] is closed and segment(a,b) is open relative to affine hull. *)
  2598 
  2598 
  2599 definition
  2599 definition
  2600   midpoint :: "real ^ 'n::finite \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 'n" where
  2600   midpoint :: "real ^ 'n \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 'n" where
  2601   "midpoint a b = (inverse (2::real)) *\<^sub>R (a + b)"
  2601   "midpoint a b = (inverse (2::real)) *\<^sub>R (a + b)"
  2602 
  2602 
  2603 definition
  2603 definition
  2604   open_segment :: "real ^ 'n::finite \<Rightarrow> real ^ 'n \<Rightarrow> (real ^ 'n) set" where
  2604   open_segment :: "real ^ 'n \<Rightarrow> real ^ 'n \<Rightarrow> (real ^ 'n) set" where
  2605   "open_segment a b = {(1 - u) *\<^sub>R a + u *\<^sub>R b | u::real.  0 < u \<and> u < 1}"
  2605   "open_segment a b = {(1 - u) *\<^sub>R a + u *\<^sub>R b | u::real.  0 < u \<and> u < 1}"
  2606 
  2606 
  2607 definition
  2607 definition
  2608   closed_segment :: "real ^ 'n::finite \<Rightarrow> real ^ 'n \<Rightarrow> (real ^ 'n) set" where
  2608   closed_segment :: "real ^ 'n \<Rightarrow> real ^ 'n \<Rightarrow> (real ^ 'n) set" where
  2609   "closed_segment a b = {(1 - u) *\<^sub>R a + u *\<^sub>R b | u::real. 0 \<le> u \<and> u \<le> 1}"
  2609   "closed_segment a b = {(1 - u) *\<^sub>R a + u *\<^sub>R b | u::real. 0 \<le> u \<and> u \<le> 1}"
  2610 
  2610 
  2611 definition "between = (\<lambda> (a,b). closed_segment a b)"
  2611 definition "between = (\<lambda> (a,b). closed_segment a b)"
  2612 
  2612 
  2613 lemmas segment = open_segment_def closed_segment_def
  2613 lemmas segment = open_segment_def closed_segment_def
  2623   "dist a (midpoint a b) = (dist a b) / 2" (is ?t1)
  2623   "dist a (midpoint a b) = (dist a b) / 2" (is ?t1)
  2624   "dist b (midpoint a b) = (dist a b) / 2" (is ?t2)
  2624   "dist b (midpoint a b) = (dist a b) / 2" (is ?t2)
  2625   "dist (midpoint a b) a = (dist a b) / 2" (is ?t3)
  2625   "dist (midpoint a b) a = (dist a b) / 2" (is ?t3)
  2626   "dist (midpoint a b) b = (dist a b) / 2" (is ?t4)
  2626   "dist (midpoint a b) b = (dist a b) / 2" (is ?t4)
  2627 proof-
  2627 proof-
  2628   have *: "\<And>x y::real^'n::finite. 2 *\<^sub>R x = - y \<Longrightarrow> norm x = (norm y) / 2" unfolding equation_minus_iff by auto
  2628   have *: "\<And>x y::real^'n. 2 *\<^sub>R x = - y \<Longrightarrow> norm x = (norm y) / 2" unfolding equation_minus_iff by auto
  2629   have **:"\<And>x y::real^'n::finite. 2 *\<^sub>R x =   y \<Longrightarrow> norm x = (norm y) / 2" by auto
  2629   have **:"\<And>x y::real^'n. 2 *\<^sub>R x =   y \<Longrightarrow> norm x = (norm y) / 2" by auto
  2630   note scaleR_right_distrib [simp]
  2630   note scaleR_right_distrib [simp]
  2631   show ?t1 unfolding midpoint_def dist_norm apply (rule **) by(auto,vector)
  2631   show ?t1 unfolding midpoint_def dist_norm apply (rule **) by(auto,vector)
  2632   show ?t2 unfolding midpoint_def dist_norm apply (rule *)  by(auto,vector)
  2632   show ?t2 unfolding midpoint_def dist_norm apply (rule *)  by(auto,vector)
  2633   show ?t3 unfolding midpoint_def dist_norm apply (rule *)  by(auto,vector)
  2633   show ?t3 unfolding midpoint_def dist_norm apply (rule *)  by(auto,vector)
  2634   show ?t4 unfolding midpoint_def dist_norm apply (rule **) by(auto,vector) qed
  2634   show ?t4 unfolding midpoint_def dist_norm apply (rule **) by(auto,vector) qed
  2635 
  2635 
  2636 lemma midpoint_eq_endpoint:
  2636 lemma midpoint_eq_endpoint:
  2637   "midpoint a b = a \<longleftrightarrow> a = (b::real^'n::finite)"
  2637   "midpoint a b = a \<longleftrightarrow> a = (b::real^'n)"
  2638   "midpoint a b = b \<longleftrightarrow> a = b"
  2638   "midpoint a b = b \<longleftrightarrow> a = b"
  2639   unfolding dist_eq_0_iff[where 'a="real^'n", THEN sym] dist_midpoint by auto
  2639   unfolding dist_eq_0_iff[where 'a="real^'n", THEN sym] dist_midpoint by auto
  2640 
  2640 
  2641 lemma convex_contains_segment:
  2641 lemma convex_contains_segment:
  2642   "convex s \<longleftrightarrow> (\<forall>a\<in>s. \<forall>b\<in>s. closed_segment a b \<subseteq> s)"
  2642   "convex s \<longleftrightarrow> (\<forall>a\<in>s. \<forall>b\<in>s. closed_segment a b \<subseteq> s)"
  2677 lemma segment_refl:"closed_segment a a = {a}" unfolding segment by (auto simp add: algebra_simps)
  2677 lemma segment_refl:"closed_segment a a = {a}" unfolding segment by (auto simp add: algebra_simps)
  2678 
  2678 
  2679 lemma between_mem_segment: "between (a,b) x \<longleftrightarrow> x \<in> closed_segment a b"
  2679 lemma between_mem_segment: "between (a,b) x \<longleftrightarrow> x \<in> closed_segment a b"
  2680   unfolding between_def mem_def by auto
  2680   unfolding between_def mem_def by auto
  2681 
  2681 
  2682 lemma between:"between (a,b) (x::real^'n::finite) \<longleftrightarrow> dist a b = (dist a x) + (dist x b)"
  2682 lemma between:"between (a,b) (x::real^'n) \<longleftrightarrow> dist a b = (dist a x) + (dist x b)"
  2683 proof(cases "a = b")
  2683 proof(cases "a = b")
  2684   case True thus ?thesis unfolding between_def split_conv mem_def[of x, symmetric]
  2684   case True thus ?thesis unfolding between_def split_conv mem_def[of x, symmetric]
  2685     by(auto simp add:segment_refl dist_commute) next
  2685     by(auto simp add:segment_refl dist_commute) next
  2686   case False hence Fal:"norm (a - b) \<noteq> 0" and Fal2: "norm (a - b) > 0" by auto 
  2686   case False hence Fal:"norm (a - b) \<noteq> 0" and Fal2: "norm (a - b) > 0" by auto 
  2687   have *:"\<And>u. a - ((1 - u) *\<^sub>R a + u *\<^sub>R b) = u *\<^sub>R (a - b)" by (auto simp add: algebra_simps)
  2687   have *:"\<And>u. a - ((1 - u) *\<^sub>R a + u *\<^sub>R b) = u *\<^sub>R (a - b)" by (auto simp add: algebra_simps)
  2704             unfolding as[unfolded dist_norm] using as[unfolded dist_triangle_eq Cart_eq,rule_format, of i]
  2704             unfolding as[unfolded dist_norm] using as[unfolded dist_triangle_eq Cart_eq,rule_format, of i]
  2705             by(auto simp add:field_simps vector_component_simps)
  2705             by(auto simp add:field_simps vector_component_simps)
  2706           finally show "x $ i = ((1 - norm (a - x) / norm (a - b)) *\<^sub>R a + (norm (a - x) / norm (a - b)) *\<^sub>R b) $ i" by auto
  2706           finally show "x $ i = ((1 - norm (a - x) / norm (a - b)) *\<^sub>R a + (norm (a - x) / norm (a - b)) *\<^sub>R b) $ i" by auto
  2707         qed(insert Fal2, auto) qed qed
  2707         qed(insert Fal2, auto) qed qed
  2708 
  2708 
  2709 lemma between_midpoint: fixes a::"real^'n::finite" shows
  2709 lemma between_midpoint: fixes a::"real^'n" shows
  2710   "between (a,b) (midpoint a b)" (is ?t1) 
  2710   "between (a,b) (midpoint a b)" (is ?t1) 
  2711   "between (b,a) (midpoint a b)" (is ?t2)
  2711   "between (b,a) (midpoint a b)" (is ?t2)
  2712 proof- have *:"\<And>x y z. x = (1/2::real) *\<^sub>R z \<Longrightarrow> y = (1/2) *\<^sub>R z \<Longrightarrow> norm z = norm x + norm y" by auto
  2712 proof- have *:"\<And>x y z. x = (1/2::real) *\<^sub>R z \<Longrightarrow> y = (1/2) *\<^sub>R z \<Longrightarrow> norm z = norm x + norm y" by auto
  2713   show ?t1 ?t2 unfolding between midpoint_def dist_norm apply(rule_tac[!] *)
  2713   show ?t1 ?t2 unfolding between midpoint_def dist_norm apply(rule_tac[!] *)
  2714     by(auto simp add:field_simps Cart_eq vector_component_simps) qed
  2714     by(auto simp add:field_simps Cart_eq vector_component_simps) qed
  2774   apply(rule_tac x=u in exI) defer apply(rule_tac x="\<lambda>x. if x = 0 then 1 - setsum u s else u x" in exI) using assms(2)
  2774   apply(rule_tac x=u in exI) defer apply(rule_tac x="\<lambda>x. if x = 0 then 1 - setsum u s else u x" in exI) using assms(2)
  2775   unfolding if_smult and setsum_delta_notmem[OF assms(2)] by auto
  2775   unfolding if_smult and setsum_delta_notmem[OF assms(2)] by auto
  2776 
  2776 
  2777 lemma std_simplex:
  2777 lemma std_simplex:
  2778   "convex hull (insert 0 { basis i | i. i\<in>UNIV}) =
  2778   "convex hull (insert 0 { basis i | i. i\<in>UNIV}) =
  2779         {x::real^'n::finite . (\<forall>i. 0 \<le> x$i) \<and> setsum (\<lambda>i. x$i) UNIV \<le> 1 }" (is "convex hull (insert 0 ?p) = ?s")
  2779         {x::real^'n . (\<forall>i. 0 \<le> x$i) \<and> setsum (\<lambda>i. x$i) UNIV \<le> 1 }" (is "convex hull (insert 0 ?p) = ?s")
  2780 proof- let ?D = "UNIV::'n set"
  2780 proof- let ?D = "UNIV::'n set"
  2781   have "0\<notin>?p" by(auto simp add: basis_nonzero)
  2781   have "0\<notin>?p" by(auto simp add: basis_nonzero)
  2782   have "{(basis i)::real^'n |i. i \<in> ?D} = basis ` ?D" by auto
  2782   have "{(basis i)::real^'n |i. i \<in> ?D} = basis ` ?D" by auto
  2783   note sumbas = this  setsum_reindex[OF basis_inj, unfolded o_def]
  2783   note sumbas = this  setsum_reindex[OF basis_inj, unfolded o_def]
  2784   show ?thesis unfolding simplex[OF finite_stdbasis `0\<notin>?p`] apply(rule set_ext) unfolding mem_Collect_eq apply rule
  2784   show ?thesis unfolding simplex[OF finite_stdbasis `0\<notin>?p`] apply(rule set_ext) unfolding mem_Collect_eq apply rule
  2794       apply(rule_tac x="\<lambda>y. inner y x" in exI) apply(rule,rule) unfolding mem_Collect_eq apply(erule exE) using as(1) apply(erule_tac x=i in allE) 
  2794       apply(rule_tac x="\<lambda>y. inner y x" in exI) apply(rule,rule) unfolding mem_Collect_eq apply(erule exE) using as(1) apply(erule_tac x=i in allE) 
  2795       unfolding sumbas using as(2) and basis_expansion_unique [where 'a=real, unfolded smult_conv_scaleR] by(auto simp add:inner_basis) qed qed 
  2795       unfolding sumbas using as(2) and basis_expansion_unique [where 'a=real, unfolded smult_conv_scaleR] by(auto simp add:inner_basis) qed qed 
  2796 
  2796 
  2797 lemma interior_std_simplex:
  2797 lemma interior_std_simplex:
  2798   "interior (convex hull (insert 0 { basis i| i. i\<in>UNIV})) =
  2798   "interior (convex hull (insert 0 { basis i| i. i\<in>UNIV})) =
  2799   {x::real^'n::finite. (\<forall>i. 0 < x$i) \<and> setsum (\<lambda>i. x$i) UNIV < 1 }"
  2799   {x::real^'n. (\<forall>i. 0 < x$i) \<and> setsum (\<lambda>i. x$i) UNIV < 1 }"
  2800   apply(rule set_ext) unfolding mem_interior std_simplex unfolding subset_eq mem_Collect_eq Ball_def mem_ball
  2800   apply(rule set_ext) unfolding mem_interior std_simplex unfolding subset_eq mem_Collect_eq Ball_def mem_ball
  2801   unfolding Ball_def[symmetric] apply rule apply(erule exE, (erule conjE)+) defer apply(erule conjE) proof-
  2801   unfolding Ball_def[symmetric] apply rule apply(erule exE, (erule conjE)+) defer apply(erule conjE) proof-
  2802   fix x::"real^'n" and e assume "0<e" and as:"\<forall>xa. dist x xa < e \<longrightarrow> (\<forall>x. 0 \<le> xa $ x) \<and> setsum (op $ xa) UNIV \<le> 1"
  2802   fix x::"real^'n" and e assume "0<e" and as:"\<forall>xa. dist x xa < e \<longrightarrow> (\<forall>x. 0 \<le> xa $ x) \<and> setsum (op $ xa) UNIV \<le> 1"
  2803   show "(\<forall>xa. 0 < x $ xa) \<and> setsum (op $ x) UNIV < 1" apply(rule,rule) proof-
  2803   show "(\<forall>xa. 0 < x $ xa) \<and> setsum (op $ x) UNIV < 1" apply(rule,rule) proof-
  2804     fix i::'n show "0 < x $ i" using as[THEN spec[where x="x - (e / 2) *\<^sub>R basis i"]] and `e>0`
  2804     fix i::'n show "0 < x $ i" using as[THEN spec[where x="x - (e / 2) *\<^sub>R basis i"]] and `e>0`
  2811     have "setsum (op $ x) UNIV < setsum (op $ (x + (e / 2) *\<^sub>R basis a)) UNIV" unfolding * setsum_addf
  2811     have "setsum (op $ x) UNIV < setsum (op $ (x + (e / 2) *\<^sub>R basis a)) UNIV" unfolding * setsum_addf
  2812       using `0<e` dimindex_ge_1 by(auto simp add: setsum_delta')
  2812       using `0<e` dimindex_ge_1 by(auto simp add: setsum_delta')
  2813     also have "\<dots> \<le> 1" using ** apply(drule_tac as[rule_format]) by auto
  2813     also have "\<dots> \<le> 1" using ** apply(drule_tac as[rule_format]) by auto
  2814     finally show "setsum (op $ x) UNIV < 1" by auto qed
  2814     finally show "setsum (op $ x) UNIV < 1" by auto qed
  2815 next
  2815 next
  2816   fix x::"real^'n::finite" assume as:"\<forall>i. 0 < x $ i" "setsum (op $ x) UNIV < 1"
  2816   fix x::"real^'n" assume as:"\<forall>i. 0 < x $ i" "setsum (op $ x) UNIV < 1"
  2817   guess a using UNIV_witness[where 'a='b] ..
  2817   guess a using UNIV_witness[where 'a='b] ..
  2818   let ?d = "(1 - setsum (op $ x) UNIV) / real (CARD('n))"
  2818   let ?d = "(1 - setsum (op $ x) UNIV) / real (CARD('n))"
  2819   have "Min ((op $ x) ` UNIV) > 0" apply(rule Min_grI) using as(1) dimindex_ge_1 by auto
  2819   have "Min ((op $ x) ` UNIV) > 0" apply(rule Min_grI) using as(1) dimindex_ge_1 by auto
  2820   moreover have"?d > 0" apply(rule divide_pos_pos) using as(2) using dimindex_ge_1 by(auto simp add: Suc_le_eq)
  2820   moreover have"?d > 0" apply(rule divide_pos_pos) using as(2) using dimindex_ge_1 by(auto simp add: Suc_le_eq)
  2821   ultimately show "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> (\<forall>i. 0 \<le> y $ i) \<and> setsum (op $ y) UNIV \<le> 1"
  2821   ultimately show "\<exists>e>0. \<forall>y. dist x y < e \<longrightarrow> (\<forall>i. 0 \<le> y $ i) \<and> setsum (op $ y) UNIV \<le> 1"
  2830       fix i::'n have "norm (x - y) < x$i" using y[unfolded min_less_iff_conj dist_norm, THEN conjunct1]
  2830       fix i::'n have "norm (x - y) < x$i" using y[unfolded min_less_iff_conj dist_norm, THEN conjunct1]
  2831         using Min_gr_iff[of "op $ x ` dimset x"] dimindex_ge_1 by auto
  2831         using Min_gr_iff[of "op $ x ` dimset x"] dimindex_ge_1 by auto
  2832       thus "0 \<le> y$i" using component_le_norm[of "x - y" i] and as(1)[rule_format, of i] by(auto simp add: vector_component_simps)
  2832       thus "0 \<le> y$i" using component_le_norm[of "x - y" i] and as(1)[rule_format, of i] by(auto simp add: vector_component_simps)
  2833     qed auto qed auto qed
  2833     qed auto qed auto qed
  2834 
  2834 
  2835 lemma interior_std_simplex_nonempty: obtains a::"real^'n::finite" where
  2835 lemma interior_std_simplex_nonempty: obtains a::"real^'n" where
  2836   "a \<in> interior(convex hull (insert 0 {basis i | i . i \<in> UNIV}))" proof-
  2836   "a \<in> interior(convex hull (insert 0 {basis i | i . i \<in> UNIV}))" proof-
  2837   let ?D = "UNIV::'n set" let ?a = "setsum (\<lambda>b::real^'n. inverse (2 * real CARD('n)) *\<^sub>R b) {(basis i) | i. i \<in> ?D}"
  2837   let ?D = "UNIV::'n set" let ?a = "setsum (\<lambda>b::real^'n. inverse (2 * real CARD('n)) *\<^sub>R b) {(basis i) | i. i \<in> ?D}"
  2838   have *:"{basis i :: real ^ 'n | i. i \<in> ?D} = basis ` ?D" by auto
  2838   have *:"{basis i :: real ^ 'n | i. i \<in> ?D} = basis ` ?D" by auto
  2839   { fix i have "?a $ i = inverse (2 * real CARD('n))"
  2839   { fix i have "?a $ i = inverse (2 * real CARD('n))"
  2840     unfolding setsum_component vector_smult_component and * and setsum_reindex[OF basis_inj] and o_def
  2840     unfolding setsum_component vector_smult_component and * and setsum_reindex[OF basis_inj] and o_def
  2847     also have "\<dots> < 1" unfolding setsum_constant card_enum real_eq_of_nat real_divide_def[THEN sym] by (auto simp add:field_simps)
  2847     also have "\<dots> < 1" unfolding setsum_constant card_enum real_eq_of_nat real_divide_def[THEN sym] by (auto simp add:field_simps)
  2848     finally show "setsum (op $ ?a) ?D < 1" by auto qed qed
  2848     finally show "setsum (op $ ?a) ?D < 1" by auto qed qed
  2849 
  2849 
  2850 subsection {* Paths. *}
  2850 subsection {* Paths. *}
  2851 
  2851 
  2852 definition "path (g::real^1 \<Rightarrow> real^'n::finite) \<longleftrightarrow> continuous_on {0 .. 1} g"
  2852 definition "path (g::real^1 \<Rightarrow> real^'n) \<longleftrightarrow> continuous_on {0 .. 1} g"
  2853 
  2853 
  2854 definition "pathstart (g::real^1 \<Rightarrow> real^'n) = g 0"
  2854 definition "pathstart (g::real^1 \<Rightarrow> real^'n) = g 0"
  2855 
  2855 
  2856 definition "pathfinish (g::real^1 \<Rightarrow> real^'n) = g 1"
  2856 definition "pathfinish (g::real^1 \<Rightarrow> real^'n) = g 1"
  2857 
  2857 
  3136     by(auto simp add:vector_component_simps image_iff) qed
  3136     by(auto simp add:vector_component_simps image_iff) qed
  3137 
  3137 
  3138 subsection {* Special case of straight-line paths. *}
  3138 subsection {* Special case of straight-line paths. *}
  3139 
  3139 
  3140 definition
  3140 definition
  3141   linepath :: "real ^ 'n::finite \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 1 \<Rightarrow> real ^ 'n" where
  3141   linepath :: "real ^ 'n \<Rightarrow> real ^ 'n \<Rightarrow> real ^ 1 \<Rightarrow> real ^ 'n" where
  3142   "linepath a b = (\<lambda>x. (1 - dest_vec1 x) *\<^sub>R a + dest_vec1 x *\<^sub>R b)"
  3142   "linepath a b = (\<lambda>x. (1 - dest_vec1 x) *\<^sub>R a + dest_vec1 x *\<^sub>R b)"
  3143 
  3143 
  3144 lemma pathstart_linepath[simp]: "pathstart(linepath a b) = a"
  3144 lemma pathstart_linepath[simp]: "pathstart(linepath a b) = a"
  3145   unfolding pathstart_def linepath_def by auto
  3145   unfolding pathstart_def linepath_def by auto
  3146 
  3146 
  3321     by(auto simp add:path_component_of_subset [OF Un_upper1] path_component_of_subset[OF Un_upper2]) qed
  3321     by(auto simp add:path_component_of_subset [OF Un_upper1] path_component_of_subset[OF Un_upper2]) qed
  3322 
  3322 
  3323 subsection {* sphere is path-connected. *}
  3323 subsection {* sphere is path-connected. *}
  3324 
  3324 
  3325 lemma path_connected_punctured_universe:
  3325 lemma path_connected_punctured_universe:
  3326  assumes "2 \<le> CARD('n::finite)" shows "path_connected((UNIV::(real^'n::finite) set) - {a})" proof-
  3326  assumes "2 \<le> CARD('n::finite)" shows "path_connected((UNIV::(real^'n) set) - {a})" proof-
  3327   obtain \<psi> where \<psi>:"bij_betw \<psi> {1..CARD('n)} (UNIV::'n set)" using ex_bij_betw_nat_finite_1[OF finite_UNIV] by auto
  3327   obtain \<psi> where \<psi>:"bij_betw \<psi> {1..CARD('n)} (UNIV::'n set)" using ex_bij_betw_nat_finite_1[OF finite_UNIV] by auto
  3328   let ?U = "UNIV::(real^'n) set" let ?u = "?U - {0}"
  3328   let ?U = "UNIV::(real^'n) set" let ?u = "?U - {0}"
  3329   let ?basis = "\<lambda>k. basis (\<psi> k)"
  3329   let ?basis = "\<lambda>k. basis (\<psi> k)"
  3330   let ?A = "\<lambda>k. {x::real^'n. \<exists>i\<in>{1..k}. inner (basis (\<psi> i)) x \<noteq> 0}"
  3330   let ?A = "\<lambda>k. {x::real^'n. \<exists>i\<in>{1..k}. inner (basis (\<psi> i)) x \<noteq> 0}"
  3331   have "\<forall>k\<in>{2..CARD('n)}. path_connected (?A k)" proof
  3331   have "\<forall>k\<in>{2..CARD('n)}. path_connected (?A k)" proof
  3364     apply rule apply(rule_tac x="x - a" in bexI) by auto
  3364     apply rule apply(rule_tac x="x - a" in bexI) by auto
  3365   have **:"\<And>x::real^'n. x\<noteq>0 \<longleftrightarrow> (\<exists>i. inner (basis i) x \<noteq> 0)" unfolding Cart_eq by(auto simp add: inner_basis)
  3365   have **:"\<And>x::real^'n. x\<noteq>0 \<longleftrightarrow> (\<exists>i. inner (basis i) x \<noteq> 0)" unfolding Cart_eq by(auto simp add: inner_basis)
  3366   show ?thesis unfolding * apply(rule path_connected_continuous_image) apply(rule continuous_on_intros)+ 
  3366   show ?thesis unfolding * apply(rule path_connected_continuous_image) apply(rule continuous_on_intros)+ 
  3367     unfolding ** apply(rule lem[THEN bspec[where x="CARD('n)"], unfolded ***]) using assms by auto qed
  3367     unfolding ** apply(rule lem[THEN bspec[where x="CARD('n)"], unfolded ***]) using assms by auto qed
  3368 
  3368 
  3369 lemma path_connected_sphere: assumes "2 \<le> CARD('n::finite)" shows "path_connected {x::real^'n::finite. norm(x - a) = r}" proof(cases "r\<le>0")
  3369 lemma path_connected_sphere: assumes "2 \<le> CARD('n::finite)" shows "path_connected {x::real^'n. norm(x - a) = r}" proof(cases "r\<le>0")
  3370   case True thus ?thesis proof(cases "r=0") 
  3370   case True thus ?thesis proof(cases "r=0") 
  3371     case False hence "{x::real^'n. norm(x - a) = r} = {}" using True by auto
  3371     case False hence "{x::real^'n. norm(x - a) = r} = {}" using True by auto
  3372     thus ?thesis using path_connected_empty by auto
  3372     thus ?thesis using path_connected_empty by auto
  3373   qed(auto intro!:path_connected_singleton) next
  3373   qed(auto intro!:path_connected_singleton) next
  3374   case False hence *:"{x::real^'n. norm(x - a) = r} = (\<lambda>x. a + r *\<^sub>R x) ` {x. norm x = 1}" unfolding not_le apply -apply(rule set_ext,rule)
  3374   case False hence *:"{x::real^'n. norm(x - a) = r} = (\<lambda>x. a + r *\<^sub>R x) ` {x. norm x = 1}" unfolding not_le apply -apply(rule set_ext,rule)
  3379     apply(rule, rule continuous_at_within_inv[unfolded o_def inverse_eq_divide]) apply(rule continuous_at_within)
  3379     apply(rule, rule continuous_at_within_inv[unfolded o_def inverse_eq_divide]) apply(rule continuous_at_within)
  3380     apply(rule continuous_at_norm[unfolded o_def]) by auto
  3380     apply(rule continuous_at_norm[unfolded o_def]) by auto
  3381   thus ?thesis unfolding * ** using path_connected_punctured_universe[OF assms]
  3381   thus ?thesis unfolding * ** using path_connected_punctured_universe[OF assms]
  3382     by(auto intro!: path_connected_continuous_image continuous_on_intros continuous_on_mul) qed
  3382     by(auto intro!: path_connected_continuous_image continuous_on_intros continuous_on_mul) qed
  3383 
  3383 
  3384 lemma connected_sphere: "2 \<le> CARD('n) \<Longrightarrow> connected {x::real^'n::finite. norm(x - a) = r}"
  3384 lemma connected_sphere: "2 \<le> CARD('n) \<Longrightarrow> connected {x::real^'n. norm(x - a) = r}"
  3385   using path_connected_sphere path_connected_imp_connected by auto
  3385   using path_connected_sphere path_connected_imp_connected by auto
  3386  
  3386 
  3387 end
  3387 end