src/HOL/Analysis/Convex.thy
author wenzelm
Mon Mar 25 17:21:26 2019 +0100 (3 weeks ago)
changeset 69981 3dced198b9ec
parent 69802 6ec272e153f0
child 70086 72c52a897de2
permissions -rw-r--r--
more strict AFP properties;
     1 (* Title:      HOL/Analysis/Convex_Euclidean_Space.thy
     2    Author:     L C Paulson, University of Cambridge
     3    Author:     Robert Himmelmann, TU Muenchen
     4    Author:     Bogdan Grechuk, University of Edinburgh
     5    Author:     Armin Heller, TU Muenchen
     6    Author:     Johannes Hoelzl, TU Muenchen
     7 *)
     8 
     9 section \<open>Convex Sets and Functions\<close>
    10 
    11 theory Convex
    12 imports
    13   Linear_Algebra
    14   "HOL-Library.Set_Algebras"
    15 begin
    16 
    17 subsection \<open>Convexity\<close>
    18 
    19 definition%important convex :: "'a::real_vector set \<Rightarrow> bool"
    20   where "convex s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u\<ge>0. \<forall>v\<ge>0. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s)"
    21 
    22 lemma convexI:
    23   assumes "\<And>x y u v. x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> 0 \<le> u \<Longrightarrow> 0 \<le> v \<Longrightarrow> u + v = 1 \<Longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s"
    24   shows "convex s"
    25   using assms unfolding convex_def by fast
    26 
    27 lemma convexD:
    28   assumes "convex s" and "x \<in> s" and "y \<in> s" and "0 \<le> u" and "0 \<le> v" and "u + v = 1"
    29   shows "u *\<^sub>R x + v *\<^sub>R y \<in> s"
    30   using assms unfolding convex_def by fast
    31 
    32 lemma convex_alt: "convex s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u. 0 \<le> u \<and> u \<le> 1 \<longrightarrow> ((1 - u) *\<^sub>R x + u *\<^sub>R y) \<in> s)"
    33   (is "_ \<longleftrightarrow> ?alt")
    34 proof
    35   show "convex s" if alt: ?alt
    36   proof -
    37     {
    38       fix x y and u v :: real
    39       assume mem: "x \<in> s" "y \<in> s"
    40       assume "0 \<le> u" "0 \<le> v"
    41       moreover
    42       assume "u + v = 1"
    43       then have "u = 1 - v" by auto
    44       ultimately have "u *\<^sub>R x + v *\<^sub>R y \<in> s"
    45         using alt [rule_format, OF mem] by auto
    46     }
    47     then show ?thesis
    48       unfolding convex_def by auto
    49   qed
    50   show ?alt if "convex s"
    51     using that by (auto simp: convex_def)
    52 qed
    53 
    54 lemma convexD_alt:
    55   assumes "convex s" "a \<in> s" "b \<in> s" "0 \<le> u" "u \<le> 1"
    56   shows "((1 - u) *\<^sub>R a + u *\<^sub>R b) \<in> s"
    57   using assms unfolding convex_alt by auto
    58 
    59 lemma mem_convex_alt:
    60   assumes "convex S" "x \<in> S" "y \<in> S" "u \<ge> 0" "v \<ge> 0" "u + v > 0"
    61   shows "((u/(u+v)) *\<^sub>R x + (v/(u+v)) *\<^sub>R y) \<in> S"
    62   apply (rule convexD)
    63   using assms
    64        apply (simp_all add: zero_le_divide_iff add_divide_distrib [symmetric])
    65   done
    66 
    67 lemma convex_empty[intro,simp]: "convex {}"
    68   unfolding convex_def by simp
    69 
    70 lemma convex_singleton[intro,simp]: "convex {a}"
    71   unfolding convex_def by (auto simp: scaleR_left_distrib[symmetric])
    72 
    73 lemma convex_UNIV[intro,simp]: "convex UNIV"
    74   unfolding convex_def by auto
    75 
    76 lemma convex_Inter: "(\<And>s. s\<in>f \<Longrightarrow> convex s) \<Longrightarrow> convex(\<Inter>f)"
    77   unfolding convex_def by auto
    78 
    79 lemma convex_Int: "convex s \<Longrightarrow> convex t \<Longrightarrow> convex (s \<inter> t)"
    80   unfolding convex_def by auto
    81 
    82 lemma convex_INT: "(\<And>i. i \<in> A \<Longrightarrow> convex (B i)) \<Longrightarrow> convex (\<Inter>i\<in>A. B i)"
    83   unfolding convex_def by auto
    84 
    85 lemma convex_Times: "convex s \<Longrightarrow> convex t \<Longrightarrow> convex (s \<times> t)"
    86   unfolding convex_def by auto
    87 
    88 lemma convex_halfspace_le: "convex {x. inner a x \<le> b}"
    89   unfolding convex_def
    90   by (auto simp: inner_add intro!: convex_bound_le)
    91 
    92 lemma convex_halfspace_ge: "convex {x. inner a x \<ge> b}"
    93 proof -
    94   have *: "{x. inner a x \<ge> b} = {x. inner (-a) x \<le> -b}"
    95     by auto
    96   show ?thesis
    97     unfolding * using convex_halfspace_le[of "-a" "-b"] by auto
    98 qed
    99 
   100 lemma convex_halfspace_abs_le: "convex {x. \<bar>inner a x\<bar> \<le> b}"
   101 proof -
   102   have *: "{x. \<bar>inner a x\<bar> \<le> b} = {x. inner a x \<le> b} \<inter> {x. -b \<le> inner a x}"
   103     by auto
   104   show ?thesis
   105     unfolding * by (simp add: convex_Int convex_halfspace_ge convex_halfspace_le)
   106 qed
   107 
   108 lemma convex_hyperplane: "convex {x. inner a x = b}"
   109 proof -
   110   have *: "{x. inner a x = b} = {x. inner a x \<le> b} \<inter> {x. inner a x \<ge> b}"
   111     by auto
   112   show ?thesis using convex_halfspace_le convex_halfspace_ge
   113     by (auto intro!: convex_Int simp: *)
   114 qed
   115 
   116 lemma convex_halfspace_lt: "convex {x. inner a x < b}"
   117   unfolding convex_def
   118   by (auto simp: convex_bound_lt inner_add)
   119 
   120 lemma convex_halfspace_gt: "convex {x. inner a x > b}"
   121   using convex_halfspace_lt[of "-a" "-b"] by auto
   122 
   123 lemma convex_halfspace_Re_ge: "convex {x. Re x \<ge> b}"
   124   using convex_halfspace_ge[of b "1::complex"] by simp
   125 
   126 lemma convex_halfspace_Re_le: "convex {x. Re x \<le> b}"
   127   using convex_halfspace_le[of "1::complex" b] by simp
   128 
   129 lemma convex_halfspace_Im_ge: "convex {x. Im x \<ge> b}"
   130   using convex_halfspace_ge[of b \<i>] by simp
   131 
   132 lemma convex_halfspace_Im_le: "convex {x. Im x \<le> b}"
   133   using convex_halfspace_le[of \<i> b] by simp
   134 
   135 lemma convex_halfspace_Re_gt: "convex {x. Re x > b}"
   136   using convex_halfspace_gt[of b "1::complex"] by simp
   137 
   138 lemma convex_halfspace_Re_lt: "convex {x. Re x < b}"
   139   using convex_halfspace_lt[of "1::complex" b] by simp
   140 
   141 lemma convex_halfspace_Im_gt: "convex {x. Im x > b}"
   142   using convex_halfspace_gt[of b \<i>] by simp
   143 
   144 lemma convex_halfspace_Im_lt: "convex {x. Im x < b}"
   145   using convex_halfspace_lt[of \<i> b] by simp
   146 
   147 lemma convex_real_interval [iff]:
   148   fixes a b :: "real"
   149   shows "convex {a..}" and "convex {..b}"
   150     and "convex {a<..}" and "convex {..<b}"
   151     and "convex {a..b}" and "convex {a<..b}"
   152     and "convex {a..<b}" and "convex {a<..<b}"
   153 proof -
   154   have "{a..} = {x. a \<le> inner 1 x}"
   155     by auto
   156   then show 1: "convex {a..}"
   157     by (simp only: convex_halfspace_ge)
   158   have "{..b} = {x. inner 1 x \<le> b}"
   159     by auto
   160   then show 2: "convex {..b}"
   161     by (simp only: convex_halfspace_le)
   162   have "{a<..} = {x. a < inner 1 x}"
   163     by auto
   164   then show 3: "convex {a<..}"
   165     by (simp only: convex_halfspace_gt)
   166   have "{..<b} = {x. inner 1 x < b}"
   167     by auto
   168   then show 4: "convex {..<b}"
   169     by (simp only: convex_halfspace_lt)
   170   have "{a..b} = {a..} \<inter> {..b}"
   171     by auto
   172   then show "convex {a..b}"
   173     by (simp only: convex_Int 1 2)
   174   have "{a<..b} = {a<..} \<inter> {..b}"
   175     by auto
   176   then show "convex {a<..b}"
   177     by (simp only: convex_Int 3 2)
   178   have "{a..<b} = {a..} \<inter> {..<b}"
   179     by auto
   180   then show "convex {a..<b}"
   181     by (simp only: convex_Int 1 4)
   182   have "{a<..<b} = {a<..} \<inter> {..<b}"
   183     by auto
   184   then show "convex {a<..<b}"
   185     by (simp only: convex_Int 3 4)
   186 qed
   187 
   188 lemma convex_Reals: "convex \<real>"
   189   by (simp add: convex_def scaleR_conv_of_real)
   190 
   191 
   192 subsection%unimportant \<open>Explicit expressions for convexity in terms of arbitrary sums\<close>
   193 
   194 lemma convex_sum:
   195   fixes C :: "'a::real_vector set"
   196   assumes "finite s"
   197     and "convex C"
   198     and "(\<Sum> i \<in> s. a i) = 1"
   199   assumes "\<And>i. i \<in> s \<Longrightarrow> a i \<ge> 0"
   200     and "\<And>i. i \<in> s \<Longrightarrow> y i \<in> C"
   201   shows "(\<Sum> j \<in> s. a j *\<^sub>R y j) \<in> C"
   202   using assms(1,3,4,5)
   203 proof (induct arbitrary: a set: finite)
   204   case empty
   205   then show ?case by simp
   206 next
   207   case (insert i s) note IH = this(3)
   208   have "a i + sum a s = 1"
   209     and "0 \<le> a i"
   210     and "\<forall>j\<in>s. 0 \<le> a j"
   211     and "y i \<in> C"
   212     and "\<forall>j\<in>s. y j \<in> C"
   213     using insert.hyps(1,2) insert.prems by simp_all
   214   then have "0 \<le> sum a s"
   215     by (simp add: sum_nonneg)
   216   have "a i *\<^sub>R y i + (\<Sum>j\<in>s. a j *\<^sub>R y j) \<in> C"
   217   proof (cases "sum a s = 0")
   218     case True
   219     with \<open>a i + sum a s = 1\<close> have "a i = 1"
   220       by simp
   221     from sum_nonneg_0 [OF \<open>finite s\<close> _ True] \<open>\<forall>j\<in>s. 0 \<le> a j\<close> have "\<forall>j\<in>s. a j = 0"
   222       by simp
   223     show ?thesis using \<open>a i = 1\<close> and \<open>\<forall>j\<in>s. a j = 0\<close> and \<open>y i \<in> C\<close>
   224       by simp
   225   next
   226     case False
   227     with \<open>0 \<le> sum a s\<close> have "0 < sum a s"
   228       by simp
   229     then have "(\<Sum>j\<in>s. (a j / sum a s) *\<^sub>R y j) \<in> C"
   230       using \<open>\<forall>j\<in>s. 0 \<le> a j\<close> and \<open>\<forall>j\<in>s. y j \<in> C\<close>
   231       by (simp add: IH sum_divide_distrib [symmetric])
   232     from \<open>convex C\<close> and \<open>y i \<in> C\<close> and this and \<open>0 \<le> a i\<close>
   233       and \<open>0 \<le> sum a s\<close> and \<open>a i + sum a s = 1\<close>
   234     have "a i *\<^sub>R y i + sum a s *\<^sub>R (\<Sum>j\<in>s. (a j / sum a s) *\<^sub>R y j) \<in> C"
   235       by (rule convexD)
   236     then show ?thesis
   237       by (simp add: scaleR_sum_right False)
   238   qed
   239   then show ?case using \<open>finite s\<close> and \<open>i \<notin> s\<close>
   240     by simp
   241 qed
   242 
   243 lemma convex:
   244   "convex s \<longleftrightarrow> (\<forall>(k::nat) u x. (\<forall>i. 1\<le>i \<and> i\<le>k \<longrightarrow> 0 \<le> u i \<and> x i \<in>s) \<and> (sum u {1..k} = 1)
   245       \<longrightarrow> sum (\<lambda>i. u i *\<^sub>R x i) {1..k} \<in> s)"
   246 proof safe
   247   fix k :: nat
   248   fix u :: "nat \<Rightarrow> real"
   249   fix x
   250   assume "convex s"
   251     "\<forall>i. 1 \<le> i \<and> i \<le> k \<longrightarrow> 0 \<le> u i \<and> x i \<in> s"
   252     "sum u {1..k} = 1"
   253   with convex_sum[of "{1 .. k}" s] show "(\<Sum>j\<in>{1 .. k}. u j *\<^sub>R x j) \<in> s"
   254     by auto
   255 next
   256   assume *: "\<forall>k u x. (\<forall> i :: nat. 1 \<le> i \<and> i \<le> k \<longrightarrow> 0 \<le> u i \<and> x i \<in> s) \<and> sum u {1..k} = 1
   257     \<longrightarrow> (\<Sum>i = 1..k. u i *\<^sub>R (x i :: 'a)) \<in> s"
   258   {
   259     fix \<mu> :: real
   260     fix x y :: 'a
   261     assume xy: "x \<in> s" "y \<in> s"
   262     assume mu: "\<mu> \<ge> 0" "\<mu> \<le> 1"
   263     let ?u = "\<lambda>i. if (i :: nat) = 1 then \<mu> else 1 - \<mu>"
   264     let ?x = "\<lambda>i. if (i :: nat) = 1 then x else y"
   265     have "{1 :: nat .. 2} \<inter> - {x. x = 1} = {2}"
   266       by auto
   267     then have card: "card ({1 :: nat .. 2} \<inter> - {x. x = 1}) = 1"
   268       by simp
   269     then have "sum ?u {1 .. 2} = 1"
   270       using sum.If_cases[of "{(1 :: nat) .. 2}" "\<lambda> x. x = 1" "\<lambda> x. \<mu>" "\<lambda> x. 1 - \<mu>"]
   271       by auto
   272     with *[rule_format, of "2" ?u ?x] have s: "(\<Sum>j \<in> {1..2}. ?u j *\<^sub>R ?x j) \<in> s"
   273       using mu xy by auto
   274     have grarr: "(\<Sum>j \<in> {Suc (Suc 0)..2}. ?u j *\<^sub>R ?x j) = (1 - \<mu>) *\<^sub>R y"
   275       using sum_head_Suc[of "Suc (Suc 0)" 2 "\<lambda> j. (1 - \<mu>) *\<^sub>R y"] by auto
   276     from sum_head_Suc[of "Suc 0" 2 "\<lambda> j. ?u j *\<^sub>R ?x j", simplified this]
   277     have "(\<Sum>j \<in> {1..2}. ?u j *\<^sub>R ?x j) = \<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y"
   278       by auto
   279     then have "(1 - \<mu>) *\<^sub>R y + \<mu> *\<^sub>R x \<in> s"
   280       using s by (auto simp: add.commute)
   281   }
   282   then show "convex s"
   283     unfolding convex_alt by auto
   284 qed
   285 
   286 
   287 lemma convex_explicit:
   288   fixes s :: "'a::real_vector set"
   289   shows "convex s \<longleftrightarrow>
   290     (\<forall>t u. finite t \<and> t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and> sum u t = 1 \<longrightarrow> sum (\<lambda>x. u x *\<^sub>R x) t \<in> s)"
   291 proof safe
   292   fix t
   293   fix u :: "'a \<Rightarrow> real"
   294   assume "convex s"
   295     and "finite t"
   296     and "t \<subseteq> s" "\<forall>x\<in>t. 0 \<le> u x" "sum u t = 1"
   297   then show "(\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s"
   298     using convex_sum[of t s u "\<lambda> x. x"] by auto
   299 next
   300   assume *: "\<forall>t. \<forall> u. finite t \<and> t \<subseteq> s \<and> (\<forall>x\<in>t. 0 \<le> u x) \<and>
   301     sum u t = 1 \<longrightarrow> (\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s"
   302   show "convex s"
   303     unfolding convex_alt
   304   proof safe
   305     fix x y
   306     fix \<mu> :: real
   307     assume **: "x \<in> s" "y \<in> s" "0 \<le> \<mu>" "\<mu> \<le> 1"
   308     show "(1 - \<mu>) *\<^sub>R x + \<mu> *\<^sub>R y \<in> s"
   309     proof (cases "x = y")
   310       case False
   311       then show ?thesis
   312         using *[rule_format, of "{x, y}" "\<lambda> z. if z = x then 1 - \<mu> else \<mu>"] **
   313         by auto
   314     next
   315       case True
   316       then show ?thesis
   317         using *[rule_format, of "{x, y}" "\<lambda> z. 1"] **
   318         by (auto simp: field_simps real_vector.scale_left_diff_distrib)
   319     qed
   320   qed
   321 qed
   322 
   323 lemma convex_finite:
   324   assumes "finite s"
   325   shows "convex s \<longleftrightarrow> (\<forall>u. (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<longrightarrow> sum (\<lambda>x. u x *\<^sub>R x) s \<in> s)"
   326   unfolding convex_explicit
   327   apply safe
   328   subgoal for u by (erule allE [where x=s], erule allE [where x=u]) auto
   329   subgoal for t u
   330   proof -
   331     have if_distrib_arg: "\<And>P f g x. (if P then f else g) x = (if P then f x else g x)"
   332       by simp
   333     assume sum: "\<forall>u. (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<longrightarrow> (\<Sum>x\<in>s. u x *\<^sub>R x) \<in> s"
   334     assume *: "\<forall>x\<in>t. 0 \<le> u x" "sum u t = 1"
   335     assume "t \<subseteq> s"
   336     then have "s \<inter> t = t" by auto
   337     with sum[THEN spec[where x="\<lambda>x. if x\<in>t then u x else 0"]] * show "(\<Sum>x\<in>t. u x *\<^sub>R x) \<in> s"
   338       by (auto simp: assms sum.If_cases if_distrib if_distrib_arg)
   339   qed
   340   done
   341 
   342 
   343 subsection \<open>Functions that are convex on a set\<close>
   344 
   345 definition%important convex_on :: "'a::real_vector set \<Rightarrow> ('a \<Rightarrow> real) \<Rightarrow> bool"
   346   where "convex_on s f \<longleftrightarrow>
   347     (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u\<ge>0. \<forall>v\<ge>0. u + v = 1 \<longrightarrow> f (u *\<^sub>R x + v *\<^sub>R y) \<le> u * f x + v * f y)"
   348 
   349 lemma convex_onI [intro?]:
   350   assumes "\<And>t x y. t > 0 \<Longrightarrow> t < 1 \<Longrightarrow> x \<in> A \<Longrightarrow> y \<in> A \<Longrightarrow>
   351     f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \<le> (1 - t) * f x + t * f y"
   352   shows "convex_on A f"
   353   unfolding convex_on_def
   354 proof clarify
   355   fix x y
   356   fix u v :: real
   357   assume A: "x \<in> A" "y \<in> A" "u \<ge> 0" "v \<ge> 0" "u + v = 1"
   358   from A(5) have [simp]: "v = 1 - u"
   359     by (simp add: algebra_simps)
   360   from A(1-4) show "f (u *\<^sub>R x + v *\<^sub>R y) \<le> u * f x + v * f y"
   361     using assms[of u y x]
   362     by (cases "u = 0 \<or> u = 1") (auto simp: algebra_simps)
   363 qed
   364 
   365 lemma convex_on_linorderI [intro?]:
   366   fixes A :: "('a::{linorder,real_vector}) set"
   367   assumes "\<And>t x y. t > 0 \<Longrightarrow> t < 1 \<Longrightarrow> x \<in> A \<Longrightarrow> y \<in> A \<Longrightarrow> x < y \<Longrightarrow>
   368     f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \<le> (1 - t) * f x + t * f y"
   369   shows "convex_on A f"
   370 proof
   371   fix x y
   372   fix t :: real
   373   assume A: "x \<in> A" "y \<in> A" "t > 0" "t < 1"
   374   with assms [of t x y] assms [of "1 - t" y x]
   375   show "f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \<le> (1 - t) * f x + t * f y"
   376     by (cases x y rule: linorder_cases) (auto simp: algebra_simps)
   377 qed
   378 
   379 lemma convex_onD:
   380   assumes "convex_on A f"
   381   shows "\<And>t x y. t \<ge> 0 \<Longrightarrow> t \<le> 1 \<Longrightarrow> x \<in> A \<Longrightarrow> y \<in> A \<Longrightarrow>
   382     f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \<le> (1 - t) * f x + t * f y"
   383   using assms by (auto simp: convex_on_def)
   384 
   385 lemma convex_onD_Icc:
   386   assumes "convex_on {x..y} f" "x \<le> (y :: _ :: {real_vector,preorder})"
   387   shows "\<And>t. t \<ge> 0 \<Longrightarrow> t \<le> 1 \<Longrightarrow>
   388     f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \<le> (1 - t) * f x + t * f y"
   389   using assms(2) by (intro convex_onD [OF assms(1)]) simp_all
   390 
   391 lemma convex_on_subset: "convex_on t f \<Longrightarrow> s \<subseteq> t \<Longrightarrow> convex_on s f"
   392   unfolding convex_on_def by auto
   393 
   394 lemma convex_on_add [intro]:
   395   assumes "convex_on s f"
   396     and "convex_on s g"
   397   shows "convex_on s (\<lambda>x. f x + g x)"
   398 proof -
   399   {
   400     fix x y
   401     assume "x \<in> s" "y \<in> s"
   402     moreover
   403     fix u v :: real
   404     assume "0 \<le> u" "0 \<le> v" "u + v = 1"
   405     ultimately
   406     have "f (u *\<^sub>R x + v *\<^sub>R y) + g (u *\<^sub>R x + v *\<^sub>R y) \<le> (u * f x + v * f y) + (u * g x + v * g y)"
   407       using assms unfolding convex_on_def by (auto simp: add_mono)
   408     then have "f (u *\<^sub>R x + v *\<^sub>R y) + g (u *\<^sub>R x + v *\<^sub>R y) \<le> u * (f x + g x) + v * (f y + g y)"
   409       by (simp add: field_simps)
   410   }
   411   then show ?thesis
   412     unfolding convex_on_def by auto
   413 qed
   414 
   415 lemma convex_on_cmul [intro]:
   416   fixes c :: real
   417   assumes "0 \<le> c"
   418     and "convex_on s f"
   419   shows "convex_on s (\<lambda>x. c * f x)"
   420 proof -
   421   have *: "u * (c * fx) + v * (c * fy) = c * (u * fx + v * fy)"
   422     for u c fx v fy :: real
   423     by (simp add: field_simps)
   424   show ?thesis using assms(2) and mult_left_mono [OF _ assms(1)]
   425     unfolding convex_on_def and * by auto
   426 qed
   427 
   428 lemma convex_lower:
   429   assumes "convex_on s f"
   430     and "x \<in> s"
   431     and "y \<in> s"
   432     and "0 \<le> u"
   433     and "0 \<le> v"
   434     and "u + v = 1"
   435   shows "f (u *\<^sub>R x + v *\<^sub>R y) \<le> max (f x) (f y)"
   436 proof -
   437   let ?m = "max (f x) (f y)"
   438   have "u * f x + v * f y \<le> u * max (f x) (f y) + v * max (f x) (f y)"
   439     using assms(4,5) by (auto simp: mult_left_mono add_mono)
   440   also have "\<dots> = max (f x) (f y)"
   441     using assms(6) by (simp add: distrib_right [symmetric])
   442   finally show ?thesis
   443     using assms unfolding convex_on_def by fastforce
   444 qed
   445 
   446 lemma convex_on_dist [intro]:
   447   fixes s :: "'a::real_normed_vector set"
   448   shows "convex_on s (\<lambda>x. dist a x)"
   449 proof (auto simp: convex_on_def dist_norm)
   450   fix x y
   451   assume "x \<in> s" "y \<in> s"
   452   fix u v :: real
   453   assume "0 \<le> u"
   454   assume "0 \<le> v"
   455   assume "u + v = 1"
   456   have "a = u *\<^sub>R a + v *\<^sub>R a"
   457     unfolding scaleR_left_distrib[symmetric] and \<open>u + v = 1\<close> by simp
   458   then have *: "a - (u *\<^sub>R x + v *\<^sub>R y) = (u *\<^sub>R (a - x)) + (v *\<^sub>R (a - y))"
   459     by (auto simp: algebra_simps)
   460   show "norm (a - (u *\<^sub>R x + v *\<^sub>R y)) \<le> u * norm (a - x) + v * norm (a - y)"
   461     unfolding * using norm_triangle_ineq[of "u *\<^sub>R (a - x)" "v *\<^sub>R (a - y)"]
   462     using \<open>0 \<le> u\<close> \<open>0 \<le> v\<close> by auto
   463 qed
   464 
   465 
   466 subsection%unimportant \<open>Arithmetic operations on sets preserve convexity\<close>
   467 
   468 lemma convex_linear_image:
   469   assumes "linear f"
   470     and "convex s"
   471   shows "convex (f ` s)"
   472 proof -
   473   interpret f: linear f by fact
   474   from \<open>convex s\<close> show "convex (f ` s)"
   475     by (simp add: convex_def f.scaleR [symmetric] f.add [symmetric])
   476 qed
   477 
   478 lemma convex_linear_vimage:
   479   assumes "linear f"
   480     and "convex s"
   481   shows "convex (f -` s)"
   482 proof -
   483   interpret f: linear f by fact
   484   from \<open>convex s\<close> show "convex (f -` s)"
   485     by (simp add: convex_def f.add f.scaleR)
   486 qed
   487 
   488 lemma convex_scaling:
   489   assumes "convex s"
   490   shows "convex ((\<lambda>x. c *\<^sub>R x) ` s)"
   491 proof -
   492   have "linear (\<lambda>x. c *\<^sub>R x)"
   493     by (simp add: linearI scaleR_add_right)
   494   then show ?thesis
   495     using \<open>convex s\<close> by (rule convex_linear_image)
   496 qed
   497 
   498 lemma convex_scaled:
   499   assumes "convex S"
   500   shows "convex ((\<lambda>x. x *\<^sub>R c) ` S)"
   501 proof -
   502   have "linear (\<lambda>x. x *\<^sub>R c)"
   503     by (simp add: linearI scaleR_add_left)
   504   then show ?thesis
   505     using \<open>convex S\<close> by (rule convex_linear_image)
   506 qed
   507 
   508 lemma convex_negations:
   509   assumes "convex S"
   510   shows "convex ((\<lambda>x. - x) ` S)"
   511 proof -
   512   have "linear (\<lambda>x. - x)"
   513     by (simp add: linearI)
   514   then show ?thesis
   515     using \<open>convex S\<close> by (rule convex_linear_image)
   516 qed
   517 
   518 lemma convex_sums:
   519   assumes "convex S"
   520     and "convex T"
   521   shows "convex (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
   522 proof -
   523   have "linear (\<lambda>(x, y). x + y)"
   524     by (auto intro: linearI simp: scaleR_add_right)
   525   with assms have "convex ((\<lambda>(x, y). x + y) ` (S \<times> T))"
   526     by (intro convex_linear_image convex_Times)
   527   also have "((\<lambda>(x, y). x + y) ` (S \<times> T)) = (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
   528     by auto
   529   finally show ?thesis .
   530 qed
   531 
   532 lemma convex_differences:
   533   assumes "convex S" "convex T"
   534   shows "convex (\<Union>x\<in> S. \<Union>y \<in> T. {x - y})"
   535 proof -
   536   have "{x - y| x y. x \<in> S \<and> y \<in> T} = {x + y |x y. x \<in> S \<and> y \<in> uminus ` T}"
   537     by (auto simp: diff_conv_add_uminus simp del: add_uminus_conv_diff)
   538   then show ?thesis
   539     using convex_sums[OF assms(1) convex_negations[OF assms(2)]] by auto
   540 qed
   541 
   542 lemma convex_translation:
   543   "convex ((+) a ` S)" if "convex S"
   544 proof -
   545   have "(\<Union> x\<in> {a}. \<Union>y \<in> S. {x + y}) = (+) a ` S"
   546     by auto
   547   then show ?thesis
   548     using convex_sums [OF convex_singleton [of a] that] by auto
   549 qed
   550 
   551 lemma convex_translation_subtract:
   552   "convex ((\<lambda>b. b - a) ` S)" if "convex S"
   553   using convex_translation [of S "- a"] that by (simp cong: image_cong_simp)
   554 
   555 lemma convex_affinity:
   556   assumes "convex S"
   557   shows "convex ((\<lambda>x. a + c *\<^sub>R x) ` S)"
   558 proof -
   559   have "(\<lambda>x. a + c *\<^sub>R x) ` S = (+) a ` (*\<^sub>R) c ` S"
   560     by auto
   561   then show ?thesis
   562     using convex_translation[OF convex_scaling[OF assms], of a c] by auto
   563 qed
   564 
   565 lemma pos_is_convex: "convex {0 :: real <..}"
   566   unfolding convex_alt
   567 proof safe
   568   fix y x \<mu> :: real
   569   assume *: "y > 0" "x > 0" "\<mu> \<ge> 0" "\<mu> \<le> 1"
   570   {
   571     assume "\<mu> = 0"
   572     then have "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y = y"
   573       by simp
   574     then have "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y > 0"
   575       using * by simp
   576   }
   577   moreover
   578   {
   579     assume "\<mu> = 1"
   580     then have "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y > 0"
   581       using * by simp
   582   }
   583   moreover
   584   {
   585     assume "\<mu> \<noteq> 1" "\<mu> \<noteq> 0"
   586     then have "\<mu> > 0" "(1 - \<mu>) > 0"
   587       using * by auto
   588     then have "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y > 0"
   589       using * by (auto simp: add_pos_pos)
   590   }
   591   ultimately show "(1 - \<mu>) *\<^sub>R y + \<mu> *\<^sub>R x > 0"
   592     by fastforce
   593 qed
   594 
   595 lemma convex_on_sum:
   596   fixes a :: "'a \<Rightarrow> real"
   597     and y :: "'a \<Rightarrow> 'b::real_vector"
   598     and f :: "'b \<Rightarrow> real"
   599   assumes "finite s" "s \<noteq> {}"
   600     and "convex_on C f"
   601     and "convex C"
   602     and "(\<Sum> i \<in> s. a i) = 1"
   603     and "\<And>i. i \<in> s \<Longrightarrow> a i \<ge> 0"
   604     and "\<And>i. i \<in> s \<Longrightarrow> y i \<in> C"
   605   shows "f (\<Sum> i \<in> s. a i *\<^sub>R y i) \<le> (\<Sum> i \<in> s. a i * f (y i))"
   606   using assms
   607 proof (induct s arbitrary: a rule: finite_ne_induct)
   608   case (singleton i)
   609   then have ai: "a i = 1"
   610     by auto
   611   then show ?case
   612     by auto
   613 next
   614   case (insert i s)
   615   then have "convex_on C f"
   616     by simp
   617   from this[unfolded convex_on_def, rule_format]
   618   have conv: "\<And>x y \<mu>. x \<in> C \<Longrightarrow> y \<in> C \<Longrightarrow> 0 \<le> \<mu> \<Longrightarrow> \<mu> \<le> 1 \<Longrightarrow>
   619       f (\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y) \<le> \<mu> * f x + (1 - \<mu>) * f y"
   620     by simp
   621   show ?case
   622   proof (cases "a i = 1")
   623     case True
   624     then have "(\<Sum> j \<in> s. a j) = 0"
   625       using insert by auto
   626     then have "\<And>j. j \<in> s \<Longrightarrow> a j = 0"
   627       using insert by (fastforce simp: sum_nonneg_eq_0_iff)
   628     then show ?thesis
   629       using insert by auto
   630   next
   631     case False
   632     from insert have yai: "y i \<in> C" "a i \<ge> 0"
   633       by auto
   634     have fis: "finite (insert i s)"
   635       using insert by auto
   636     then have ai1: "a i \<le> 1"
   637       using sum_nonneg_leq_bound[of "insert i s" a] insert by simp
   638     then have "a i < 1"
   639       using False by auto
   640     then have i0: "1 - a i > 0"
   641       by auto
   642     let ?a = "\<lambda>j. a j / (1 - a i)"
   643     have a_nonneg: "?a j \<ge> 0" if "j \<in> s" for j
   644       using i0 insert that by fastforce
   645     have "(\<Sum> j \<in> insert i s. a j) = 1"
   646       using insert by auto
   647     then have "(\<Sum> j \<in> s. a j) = 1 - a i"
   648       using sum.insert insert by fastforce
   649     then have "(\<Sum> j \<in> s. a j) / (1 - a i) = 1"
   650       using i0 by auto
   651     then have a1: "(\<Sum> j \<in> s. ?a j) = 1"
   652       unfolding sum_divide_distrib by simp
   653     have "convex C" using insert by auto
   654     then have asum: "(\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<in> C"
   655       using insert convex_sum [OF \<open>finite s\<close> \<open>convex C\<close> a1 a_nonneg] by auto
   656     have asum_le: "f (\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<le> (\<Sum> j \<in> s. ?a j * f (y j))"
   657       using a_nonneg a1 insert by blast
   658     have "f (\<Sum> j \<in> insert i s. a j *\<^sub>R y j) = f ((\<Sum> j \<in> s. a j *\<^sub>R y j) + a i *\<^sub>R y i)"
   659       using sum.insert[of s i "\<lambda> j. a j *\<^sub>R y j", OF \<open>finite s\<close> \<open>i \<notin> s\<close>] insert
   660       by (auto simp only: add.commute)
   661     also have "\<dots> = f (((1 - a i) * inverse (1 - a i)) *\<^sub>R (\<Sum> j \<in> s. a j *\<^sub>R y j) + a i *\<^sub>R y i)"
   662       using i0 by auto
   663     also have "\<dots> = f ((1 - a i) *\<^sub>R (\<Sum> j \<in> s. (a j * inverse (1 - a i)) *\<^sub>R y j) + a i *\<^sub>R y i)"
   664       using scaleR_right.sum[of "inverse (1 - a i)" "\<lambda> j. a j *\<^sub>R y j" s, symmetric]
   665       by (auto simp: algebra_simps)
   666     also have "\<dots> = f ((1 - a i) *\<^sub>R (\<Sum> j \<in> s. ?a j *\<^sub>R y j) + a i *\<^sub>R y i)"
   667       by (auto simp: divide_inverse)
   668     also have "\<dots> \<le> (1 - a i) *\<^sub>R f ((\<Sum> j \<in> s. ?a j *\<^sub>R y j)) + a i * f (y i)"
   669       using conv[of "y i" "(\<Sum> j \<in> s. ?a j *\<^sub>R y j)" "a i", OF yai(1) asum yai(2) ai1]
   670       by (auto simp: add.commute)
   671     also have "\<dots> \<le> (1 - a i) * (\<Sum> j \<in> s. ?a j * f (y j)) + a i * f (y i)"
   672       using add_right_mono [OF mult_left_mono [of _ _ "1 - a i",
   673             OF asum_le less_imp_le[OF i0]], of "a i * f (y i)"]
   674       by simp
   675     also have "\<dots> = (\<Sum> j \<in> s. (1 - a i) * ?a j * f (y j)) + a i * f (y i)"
   676       unfolding sum_distrib_left[of "1 - a i" "\<lambda> j. ?a j * f (y j)"]
   677       using i0 by auto
   678     also have "\<dots> = (\<Sum> j \<in> s. a j * f (y j)) + a i * f (y i)"
   679       using i0 by auto
   680     also have "\<dots> = (\<Sum> j \<in> insert i s. a j * f (y j))"
   681       using insert by auto
   682     finally show ?thesis
   683       by simp
   684   qed
   685 qed
   686 
   687 lemma convex_on_alt:
   688   fixes C :: "'a::real_vector set"
   689   assumes "convex C"
   690   shows "convex_on C f \<longleftrightarrow>
   691     (\<forall>x \<in> C. \<forall> y \<in> C. \<forall> \<mu> :: real. \<mu> \<ge> 0 \<and> \<mu> \<le> 1 \<longrightarrow>
   692       f (\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y) \<le> \<mu> * f x + (1 - \<mu>) * f y)"
   693 proof safe
   694   fix x y
   695   fix \<mu> :: real
   696   assume *: "convex_on C f" "x \<in> C" "y \<in> C" "0 \<le> \<mu>" "\<mu> \<le> 1"
   697   from this[unfolded convex_on_def, rule_format]
   698   have "0 \<le> u \<Longrightarrow> 0 \<le> v \<Longrightarrow> u + v = 1 \<Longrightarrow> f (u *\<^sub>R x + v *\<^sub>R y) \<le> u * f x + v * f y" for u v
   699     by auto
   700   from this [of "\<mu>" "1 - \<mu>", simplified] *
   701   show "f (\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y) \<le> \<mu> * f x + (1 - \<mu>) * f y"
   702     by auto
   703 next
   704   assume *: "\<forall>x\<in>C. \<forall>y\<in>C. \<forall>\<mu>. 0 \<le> \<mu> \<and> \<mu> \<le> 1 \<longrightarrow>
   705     f (\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y) \<le> \<mu> * f x + (1 - \<mu>) * f y"
   706   {
   707     fix x y
   708     fix u v :: real
   709     assume **: "x \<in> C" "y \<in> C" "u \<ge> 0" "v \<ge> 0" "u + v = 1"
   710     then have[simp]: "1 - u = v" by auto
   711     from *[rule_format, of x y u]
   712     have "f (u *\<^sub>R x + v *\<^sub>R y) \<le> u * f x + v * f y"
   713       using ** by auto
   714   }
   715   then show "convex_on C f"
   716     unfolding convex_on_def by auto
   717 qed
   718 
   719 lemma convex_on_diff:
   720   fixes f :: "real \<Rightarrow> real"
   721   assumes f: "convex_on I f"
   722     and I: "x \<in> I" "y \<in> I"
   723     and t: "x < t" "t < y"
   724   shows "(f x - f t) / (x - t) \<le> (f x - f y) / (x - y)"
   725     and "(f x - f y) / (x - y) \<le> (f t - f y) / (t - y)"
   726 proof -
   727   define a where "a \<equiv> (t - y) / (x - y)"
   728   with t have "0 \<le> a" "0 \<le> 1 - a"
   729     by (auto simp: field_simps)
   730   with f \<open>x \<in> I\<close> \<open>y \<in> I\<close> have cvx: "f (a * x + (1 - a) * y) \<le> a * f x + (1 - a) * f y"
   731     by (auto simp: convex_on_def)
   732   have "a * x + (1 - a) * y = a * (x - y) + y"
   733     by (simp add: field_simps)
   734   also have "\<dots> = t"
   735     unfolding a_def using \<open>x < t\<close> \<open>t < y\<close> by simp
   736   finally have "f t \<le> a * f x + (1 - a) * f y"
   737     using cvx by simp
   738   also have "\<dots> = a * (f x - f y) + f y"
   739     by (simp add: field_simps)
   740   finally have "f t - f y \<le> a * (f x - f y)"
   741     by simp
   742   with t show "(f x - f t) / (x - t) \<le> (f x - f y) / (x - y)"
   743     by (simp add: le_divide_eq divide_le_eq field_simps a_def)
   744   with t show "(f x - f y) / (x - y) \<le> (f t - f y) / (t - y)"
   745     by (simp add: le_divide_eq divide_le_eq field_simps)
   746 qed
   747 
   748 lemma pos_convex_function:
   749   fixes f :: "real \<Rightarrow> real"
   750   assumes "convex C"
   751     and leq: "\<And>x y. x \<in> C \<Longrightarrow> y \<in> C \<Longrightarrow> f' x * (y - x) \<le> f y - f x"
   752   shows "convex_on C f"
   753   unfolding convex_on_alt[OF assms(1)]
   754   using assms
   755 proof safe
   756   fix x y \<mu> :: real
   757   let ?x = "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y"
   758   assume *: "convex C" "x \<in> C" "y \<in> C" "\<mu> \<ge> 0" "\<mu> \<le> 1"
   759   then have "1 - \<mu> \<ge> 0" by auto
   760   then have xpos: "?x \<in> C"
   761     using * unfolding convex_alt by fastforce
   762   have geq: "\<mu> * (f x - f ?x) + (1 - \<mu>) * (f y - f ?x) \<ge>
   763       \<mu> * f' ?x * (x - ?x) + (1 - \<mu>) * f' ?x * (y - ?x)"
   764     using add_mono [OF mult_left_mono [OF leq [OF xpos *(2)] \<open>\<mu> \<ge> 0\<close>]
   765         mult_left_mono [OF leq [OF xpos *(3)] \<open>1 - \<mu> \<ge> 0\<close>]]
   766     by auto
   767   then have "\<mu> * f x + (1 - \<mu>) * f y - f ?x \<ge> 0"
   768     by (auto simp: field_simps)
   769   then show "f (\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y) \<le> \<mu> * f x + (1 - \<mu>) * f y"
   770     using convex_on_alt by auto
   771 qed
   772 
   773 lemma atMostAtLeast_subset_convex:
   774   fixes C :: "real set"
   775   assumes "convex C"
   776     and "x \<in> C" "y \<in> C" "x < y"
   777   shows "{x .. y} \<subseteq> C"
   778 proof safe
   779   fix z assume z: "z \<in> {x .. y}"
   780   have less: "z \<in> C" if *: "x < z" "z < y"
   781   proof -
   782     let ?\<mu> = "(y - z) / (y - x)"
   783     have "0 \<le> ?\<mu>" "?\<mu> \<le> 1"
   784       using assms * by (auto simp: field_simps)
   785     then have comb: "?\<mu> * x + (1 - ?\<mu>) * y \<in> C"
   786       using assms iffD1[OF convex_alt, rule_format, of C y x ?\<mu>]
   787       by (simp add: algebra_simps)
   788     have "?\<mu> * x + (1 - ?\<mu>) * y = (y - z) * x / (y - x) + (1 - (y - z) / (y - x)) * y"
   789       by (auto simp: field_simps)
   790     also have "\<dots> = ((y - z) * x + (y - x - (y - z)) * y) / (y - x)"
   791       using assms by (simp only: add_divide_distrib) (auto simp: field_simps)
   792     also have "\<dots> = z"
   793       using assms by (auto simp: field_simps)
   794     finally show ?thesis
   795       using comb by auto
   796   qed
   797   show "z \<in> C"
   798     using z less assms by (auto simp: le_less)
   799 qed
   800 
   801 lemma f''_imp_f':
   802   fixes f :: "real \<Rightarrow> real"
   803   assumes "convex C"
   804     and f': "\<And>x. x \<in> C \<Longrightarrow> DERIV f x :> (f' x)"
   805     and f'': "\<And>x. x \<in> C \<Longrightarrow> DERIV f' x :> (f'' x)"
   806     and pos: "\<And>x. x \<in> C \<Longrightarrow> f'' x \<ge> 0"
   807     and x: "x \<in> C"
   808     and y: "y \<in> C"
   809   shows "f' x * (y - x) \<le> f y - f x"
   810   using assms
   811 proof -
   812   have less_imp: "f y - f x \<ge> f' x * (y - x)" "f' y * (x - y) \<le> f x - f y"
   813     if *: "x \<in> C" "y \<in> C" "y > x" for x y :: real
   814   proof -
   815     from * have ge: "y - x > 0" "y - x \<ge> 0"
   816       by auto
   817     from * have le: "x - y < 0" "x - y \<le> 0"
   818       by auto
   819     then obtain z1 where z1: "z1 > x" "z1 < y" "f y - f x = (y - x) * f' z1"
   820       using subsetD[OF atMostAtLeast_subset_convex[OF \<open>convex C\<close> \<open>x \<in> C\<close> \<open>y \<in> C\<close> \<open>x < y\<close>],
   821           THEN f', THEN MVT2[OF \<open>x < y\<close>, rule_format, unfolded atLeastAtMost_iff[symmetric]]]
   822       by auto
   823     then have "z1 \<in> C"
   824       using atMostAtLeast_subset_convex \<open>convex C\<close> \<open>x \<in> C\<close> \<open>y \<in> C\<close> \<open>x < y\<close>
   825       by fastforce
   826     from z1 have z1': "f x - f y = (x - y) * f' z1"
   827       by (simp add: field_simps)
   828     obtain z2 where z2: "z2 > x" "z2 < z1" "f' z1 - f' x = (z1 - x) * f'' z2"
   829       using subsetD[OF atMostAtLeast_subset_convex[OF \<open>convex C\<close> \<open>x \<in> C\<close> \<open>z1 \<in> C\<close> \<open>x < z1\<close>],
   830           THEN f'', THEN MVT2[OF \<open>x < z1\<close>, rule_format, unfolded atLeastAtMost_iff[symmetric]]] z1
   831       by auto
   832     obtain z3 where z3: "z3 > z1" "z3 < y" "f' y - f' z1 = (y - z1) * f'' z3"
   833       using subsetD[OF atMostAtLeast_subset_convex[OF \<open>convex C\<close> \<open>z1 \<in> C\<close> \<open>y \<in> C\<close> \<open>z1 < y\<close>],
   834           THEN f'', THEN MVT2[OF \<open>z1 < y\<close>, rule_format, unfolded atLeastAtMost_iff[symmetric]]] z1
   835       by auto
   836     have "f' y - (f x - f y) / (x - y) = f' y - f' z1"
   837       using * z1' by auto
   838     also have "\<dots> = (y - z1) * f'' z3"
   839       using z3 by auto
   840     finally have cool': "f' y - (f x - f y) / (x - y) = (y - z1) * f'' z3"
   841       by simp
   842     have A': "y - z1 \<ge> 0"
   843       using z1 by auto
   844     have "z3 \<in> C"
   845       using z3 * atMostAtLeast_subset_convex \<open>convex C\<close> \<open>x \<in> C\<close> \<open>z1 \<in> C\<close> \<open>x < z1\<close>
   846       by fastforce
   847     then have B': "f'' z3 \<ge> 0"
   848       using assms by auto
   849     from A' B' have "(y - z1) * f'' z3 \<ge> 0"
   850       by auto
   851     from cool' this have "f' y - (f x - f y) / (x - y) \<ge> 0"
   852       by auto
   853     from mult_right_mono_neg[OF this le(2)]
   854     have "f' y * (x - y) - (f x - f y) / (x - y) * (x - y) \<le> 0 * (x - y)"
   855       by (simp add: algebra_simps)
   856     then have "f' y * (x - y) - (f x - f y) \<le> 0"
   857       using le by auto
   858     then have res: "f' y * (x - y) \<le> f x - f y"
   859       by auto
   860     have "(f y - f x) / (y - x) - f' x = f' z1 - f' x"
   861       using * z1 by auto
   862     also have "\<dots> = (z1 - x) * f'' z2"
   863       using z2 by auto
   864     finally have cool: "(f y - f x) / (y - x) - f' x = (z1 - x) * f'' z2"
   865       by simp
   866     have A: "z1 - x \<ge> 0"
   867       using z1 by auto
   868     have "z2 \<in> C"
   869       using z2 z1 * atMostAtLeast_subset_convex \<open>convex C\<close> \<open>z1 \<in> C\<close> \<open>y \<in> C\<close> \<open>z1 < y\<close>
   870       by fastforce
   871     then have B: "f'' z2 \<ge> 0"
   872       using assms by auto
   873     from A B have "(z1 - x) * f'' z2 \<ge> 0"
   874       by auto
   875     with cool have "(f y - f x) / (y - x) - f' x \<ge> 0"
   876       by auto
   877     from mult_right_mono[OF this ge(2)]
   878     have "(f y - f x) / (y - x) * (y - x) - f' x * (y - x) \<ge> 0 * (y - x)"
   879       by (simp add: algebra_simps)
   880     then have "f y - f x - f' x * (y - x) \<ge> 0"
   881       using ge by auto
   882     then show "f y - f x \<ge> f' x * (y - x)" "f' y * (x - y) \<le> f x - f y"
   883       using res by auto
   884   qed
   885   show ?thesis
   886   proof (cases "x = y")
   887     case True
   888     with x y show ?thesis by auto
   889   next
   890     case False
   891     with less_imp x y show ?thesis
   892       by (auto simp: neq_iff)
   893   qed
   894 qed
   895 
   896 lemma f''_ge0_imp_convex:
   897   fixes f :: "real \<Rightarrow> real"
   898   assumes conv: "convex C"
   899     and f': "\<And>x. x \<in> C \<Longrightarrow> DERIV f x :> (f' x)"
   900     and f'': "\<And>x. x \<in> C \<Longrightarrow> DERIV f' x :> (f'' x)"
   901     and pos: "\<And>x. x \<in> C \<Longrightarrow> f'' x \<ge> 0"
   902   shows "convex_on C f"
   903   using f''_imp_f'[OF conv f' f'' pos] assms pos_convex_function
   904   by fastforce
   905 
   906 lemma minus_log_convex:
   907   fixes b :: real
   908   assumes "b > 1"
   909   shows "convex_on {0 <..} (\<lambda> x. - log b x)"
   910 proof -
   911   have "\<And>z. z > 0 \<Longrightarrow> DERIV (log b) z :> 1 / (ln b * z)"
   912     using DERIV_log by auto
   913   then have f': "\<And>z. z > 0 \<Longrightarrow> DERIV (\<lambda> z. - log b z) z :> - 1 / (ln b * z)"
   914     by (auto simp: DERIV_minus)
   915   have "\<And>z::real. z > 0 \<Longrightarrow> DERIV inverse z :> - (inverse z ^ Suc (Suc 0))"
   916     using less_imp_neq[THEN not_sym, THEN DERIV_inverse] by auto
   917   from this[THEN DERIV_cmult, of _ "- 1 / ln b"]
   918   have "\<And>z::real. z > 0 \<Longrightarrow>
   919     DERIV (\<lambda> z. (- 1 / ln b) * inverse z) z :> (- 1 / ln b) * (- (inverse z ^ Suc (Suc 0)))"
   920     by auto
   921   then have f''0: "\<And>z::real. z > 0 \<Longrightarrow>
   922     DERIV (\<lambda> z. - 1 / (ln b * z)) z :> 1 / (ln b * z * z)"
   923     unfolding inverse_eq_divide by (auto simp: mult.assoc)
   924   have f''_ge0: "\<And>z::real. z > 0 \<Longrightarrow> 1 / (ln b * z * z) \<ge> 0"
   925     using \<open>b > 1\<close> by (auto intro!: less_imp_le)
   926   from f''_ge0_imp_convex[OF pos_is_convex, unfolded greaterThan_iff, OF f' f''0 f''_ge0]
   927   show ?thesis
   928     by auto
   929 qed
   930 
   931 
   932 subsection%unimportant \<open>Convexity of real functions\<close>
   933 
   934 lemma convex_on_realI:
   935   assumes "connected A"
   936     and "\<And>x. x \<in> A \<Longrightarrow> (f has_real_derivative f' x) (at x)"
   937     and "\<And>x y. x \<in> A \<Longrightarrow> y \<in> A \<Longrightarrow> x \<le> y \<Longrightarrow> f' x \<le> f' y"
   938   shows "convex_on A f"
   939 proof (rule convex_on_linorderI)
   940   fix t x y :: real
   941   assume t: "t > 0" "t < 1"
   942   assume xy: "x \<in> A" "y \<in> A" "x < y"
   943   define z where "z = (1 - t) * x + t * y"
   944   with \<open>connected A\<close> and xy have ivl: "{x..y} \<subseteq> A"
   945     using connected_contains_Icc by blast
   946 
   947   from xy t have xz: "z > x"
   948     by (simp add: z_def algebra_simps)
   949   have "y - z = (1 - t) * (y - x)"
   950     by (simp add: z_def algebra_simps)
   951   also from xy t have "\<dots> > 0"
   952     by (intro mult_pos_pos) simp_all
   953   finally have yz: "z < y"
   954     by simp
   955 
   956   from assms xz yz ivl t have "\<exists>\<xi>. \<xi> > x \<and> \<xi> < z \<and> f z - f x = (z - x) * f' \<xi>"
   957     by (intro MVT2) (auto intro!: assms(2))
   958   then obtain \<xi> where \<xi>: "\<xi> > x" "\<xi> < z" "f' \<xi> = (f z - f x) / (z - x)"
   959     by auto
   960   from assms xz yz ivl t have "\<exists>\<eta>. \<eta> > z \<and> \<eta> < y \<and> f y - f z = (y - z) * f' \<eta>"
   961     by (intro MVT2) (auto intro!: assms(2))
   962   then obtain \<eta> where \<eta>: "\<eta> > z" "\<eta> < y" "f' \<eta> = (f y - f z) / (y - z)"
   963     by auto
   964 
   965   from \<eta>(3) have "(f y - f z) / (y - z) = f' \<eta>" ..
   966   also from \<xi> \<eta> ivl have "\<xi> \<in> A" "\<eta> \<in> A"
   967     by auto
   968   with \<xi> \<eta> have "f' \<eta> \<ge> f' \<xi>"
   969     by (intro assms(3)) auto
   970   also from \<xi>(3) have "f' \<xi> = (f z - f x) / (z - x)" .
   971   finally have "(f y - f z) * (z - x) \<ge> (f z - f x) * (y - z)"
   972     using xz yz by (simp add: field_simps)
   973   also have "z - x = t * (y - x)"
   974     by (simp add: z_def algebra_simps)
   975   also have "y - z = (1 - t) * (y - x)"
   976     by (simp add: z_def algebra_simps)
   977   finally have "(f y - f z) * t \<ge> (f z - f x) * (1 - t)"
   978     using xy by simp
   979   then show "(1 - t) * f x + t * f y \<ge> f ((1 - t) *\<^sub>R x + t *\<^sub>R y)"
   980     by (simp add: z_def algebra_simps)
   981 qed
   982 
   983 lemma convex_on_inverse:
   984   assumes "A \<subseteq> {0<..}"
   985   shows "convex_on A (inverse :: real \<Rightarrow> real)"
   986 proof (rule convex_on_subset[OF _ assms], intro convex_on_realI[of _ _ "\<lambda>x. -inverse (x^2)"])
   987   fix u v :: real
   988   assume "u \<in> {0<..}" "v \<in> {0<..}" "u \<le> v"
   989   with assms show "-inverse (u^2) \<le> -inverse (v^2)"
   990     by (intro le_imp_neg_le le_imp_inverse_le power_mono) (simp_all)
   991 qed (insert assms, auto intro!: derivative_eq_intros simp: divide_simps power2_eq_square)
   992 
   993 lemma convex_onD_Icc':
   994   assumes "convex_on {x..y} f" "c \<in> {x..y}"
   995   defines "d \<equiv> y - x"
   996   shows "f c \<le> (f y - f x) / d * (c - x) + f x"
   997 proof (cases x y rule: linorder_cases)
   998   case less
   999   then have d: "d > 0"
  1000     by (simp add: d_def)
  1001   from assms(2) less have A: "0 \<le> (c - x) / d" "(c - x) / d \<le> 1"
  1002     by (simp_all add: d_def divide_simps)
  1003   have "f c = f (x + (c - x) * 1)"
  1004     by simp
  1005   also from less have "1 = ((y - x) / d)"
  1006     by (simp add: d_def)
  1007   also from d have "x + (c - x) * \<dots> = (1 - (c - x) / d) *\<^sub>R x + ((c - x) / d) *\<^sub>R y"
  1008     by (simp add: field_simps)
  1009   also have "f \<dots> \<le> (1 - (c - x) / d) * f x + (c - x) / d * f y"
  1010     using assms less by (intro convex_onD_Icc) simp_all
  1011   also from d have "\<dots> = (f y - f x) / d * (c - x) + f x"
  1012     by (simp add: field_simps)
  1013   finally show ?thesis .
  1014 qed (insert assms(2), simp_all)
  1015 
  1016 lemma convex_onD_Icc'':
  1017   assumes "convex_on {x..y} f" "c \<in> {x..y}"
  1018   defines "d \<equiv> y - x"
  1019   shows "f c \<le> (f x - f y) / d * (y - c) + f y"
  1020 proof (cases x y rule: linorder_cases)
  1021   case less
  1022   then have d: "d > 0"
  1023     by (simp add: d_def)
  1024   from assms(2) less have A: "0 \<le> (y - c) / d" "(y - c) / d \<le> 1"
  1025     by (simp_all add: d_def divide_simps)
  1026   have "f c = f (y - (y - c) * 1)"
  1027     by simp
  1028   also from less have "1 = ((y - x) / d)"
  1029     by (simp add: d_def)
  1030   also from d have "y - (y - c) * \<dots> = (1 - (1 - (y - c) / d)) *\<^sub>R x + (1 - (y - c) / d) *\<^sub>R y"
  1031     by (simp add: field_simps)
  1032   also have "f \<dots> \<le> (1 - (1 - (y - c) / d)) * f x + (1 - (y - c) / d) * f y"
  1033     using assms less by (intro convex_onD_Icc) (simp_all add: field_simps)
  1034   also from d have "\<dots> = (f x - f y) / d * (y - c) + f y"
  1035     by (simp add: field_simps)
  1036   finally show ?thesis .
  1037 qed (insert assms(2), simp_all)
  1038 
  1039 lemma convex_translation_eq [simp]:
  1040   "convex ((+) a ` s) \<longleftrightarrow> convex s"
  1041   by (metis convex_translation translation_galois)
  1042 
  1043 lemma convex_translation_subtract_eq [simp]:
  1044   "convex ((\<lambda>b. b - a) ` s) \<longleftrightarrow> convex s"
  1045   using convex_translation_eq [of "- a"] by (simp cong: image_cong_simp)
  1046 
  1047 lemma convex_linear_image_eq [simp]:
  1048     fixes f :: "'a::real_vector \<Rightarrow> 'b::real_vector"
  1049     shows "\<lbrakk>linear f; inj f\<rbrakk> \<Longrightarrow> convex (f ` s) \<longleftrightarrow> convex s"
  1050     by (metis (no_types) convex_linear_image convex_linear_vimage inj_vimage_image_eq)
  1051 
  1052 lemma fst_linear: "linear fst"
  1053   unfolding linear_iff by (simp add: algebra_simps)
  1054 
  1055 lemma snd_linear: "linear snd"
  1056   unfolding linear_iff by (simp add: algebra_simps)
  1057 
  1058 lemma fst_snd_linear: "linear (\<lambda>(x,y). x + y)"
  1059   unfolding linear_iff by (simp add: algebra_simps)
  1060 
  1061 lemma vector_choose_size:
  1062   assumes "0 \<le> c"
  1063   obtains x :: "'a::{real_normed_vector, perfect_space}" where "norm x = c"
  1064 proof -
  1065   obtain a::'a where "a \<noteq> 0"
  1066     using UNIV_not_singleton UNIV_eq_I set_zero singletonI by fastforce
  1067   then show ?thesis
  1068     by (rule_tac x="scaleR (c / norm a) a" in that) (simp add: assms)
  1069 qed
  1070 
  1071 lemma vector_choose_dist:
  1072   assumes "0 \<le> c"
  1073   obtains y :: "'a::{real_normed_vector, perfect_space}" where "dist x y = c"
  1074 by (metis add_diff_cancel_left' assms dist_commute dist_norm vector_choose_size)
  1075 
  1076 lemma sum_delta_notmem:
  1077   assumes "x \<notin> s"
  1078   shows "sum (\<lambda>y. if (y = x) then P x else Q y) s = sum Q s"
  1079     and "sum (\<lambda>y. if (x = y) then P x else Q y) s = sum Q s"
  1080     and "sum (\<lambda>y. if (y = x) then P y else Q y) s = sum Q s"
  1081     and "sum (\<lambda>y. if (x = y) then P y else Q y) s = sum Q s"
  1082   apply (rule_tac [!] sum.cong)
  1083   using assms
  1084   apply auto
  1085   done
  1086 
  1087 lemma sum_delta'':
  1088   fixes s::"'a::real_vector set"
  1089   assumes "finite s"
  1090   shows "(\<Sum>x\<in>s. (if y = x then f x else 0) *\<^sub>R x) = (if y\<in>s then (f y) *\<^sub>R y else 0)"
  1091 proof -
  1092   have *: "\<And>x y. (if y = x then f x else (0::real)) *\<^sub>R x = (if x=y then (f x) *\<^sub>R x else 0)"
  1093     by auto
  1094   show ?thesis
  1095     unfolding * using sum.delta[OF assms, of y "\<lambda>x. f x *\<^sub>R x"] by auto
  1096 qed
  1097 
  1098 lemma if_smult: "(if P then x else (y::real)) *\<^sub>R v = (if P then x *\<^sub>R v else y *\<^sub>R v)"
  1099   by (fact if_distrib)
  1100 
  1101 lemma dist_triangle_eq:
  1102   fixes x y z :: "'a::real_inner"
  1103   shows "dist x z = dist x y + dist y z \<longleftrightarrow>
  1104     norm (x - y) *\<^sub>R (y - z) = norm (y - z) *\<^sub>R (x - y)"
  1105 proof -
  1106   have *: "x - y + (y - z) = x - z" by auto
  1107   show ?thesis unfolding dist_norm norm_triangle_eq[of "x - y" "y - z", unfolded *]
  1108     by (auto simp:norm_minus_commute)
  1109 qed
  1110 
  1111 
  1112 subsection \<open>Affine set and affine hull\<close>
  1113 
  1114 definition%important affine :: "'a::real_vector set \<Rightarrow> bool"
  1115   where "affine s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u v. u + v = 1 \<longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> s)"
  1116 
  1117 lemma affine_alt: "affine s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. \<forall>u::real. (1 - u) *\<^sub>R x + u *\<^sub>R y \<in> s)"
  1118   unfolding affine_def by (metis eq_diff_eq')
  1119 
  1120 lemma affine_empty [iff]: "affine {}"
  1121   unfolding affine_def by auto
  1122 
  1123 lemma affine_sing [iff]: "affine {x}"
  1124   unfolding affine_alt by (auto simp: scaleR_left_distrib [symmetric])
  1125 
  1126 lemma affine_UNIV [iff]: "affine UNIV"
  1127   unfolding affine_def by auto
  1128 
  1129 lemma affine_Inter [intro]: "(\<And>s. s\<in>f \<Longrightarrow> affine s) \<Longrightarrow> affine (\<Inter>f)"
  1130   unfolding affine_def by auto
  1131 
  1132 lemma affine_Int[intro]: "affine s \<Longrightarrow> affine t \<Longrightarrow> affine (s \<inter> t)"
  1133   unfolding affine_def by auto
  1134 
  1135 lemma affine_scaling: "affine s \<Longrightarrow> affine (image (\<lambda>x. c *\<^sub>R x) s)"
  1136   apply (clarsimp simp add: affine_def)
  1137   apply (rule_tac x="u *\<^sub>R x + v *\<^sub>R y" in image_eqI)
  1138   apply (auto simp: algebra_simps)
  1139   done
  1140 
  1141 lemma affine_affine_hull [simp]: "affine(affine hull s)"
  1142   unfolding hull_def
  1143   using affine_Inter[of "{t. affine t \<and> s \<subseteq> t}"] by auto
  1144 
  1145 lemma affine_hull_eq[simp]: "(affine hull s = s) \<longleftrightarrow> affine s"
  1146   by (metis affine_affine_hull hull_same)
  1147 
  1148 lemma affine_hyperplane: "affine {x. a \<bullet> x = b}"
  1149   by (simp add: affine_def algebra_simps) (metis distrib_right mult.left_neutral)
  1150 
  1151 
  1152 subsubsection%unimportant \<open>Some explicit formulations\<close>
  1153 
  1154 text "Formalized by Lars Schewe."
  1155 
  1156 lemma affine:
  1157   fixes V::"'a::real_vector set"
  1158   shows "affine V \<longleftrightarrow>
  1159          (\<forall>S u. finite S \<and> S \<noteq> {} \<and> S \<subseteq> V \<and> sum u S = 1 \<longrightarrow> (\<Sum>x\<in>S. u x *\<^sub>R x) \<in> V)"
  1160 proof -
  1161   have "u *\<^sub>R x + v *\<^sub>R y \<in> V" if "x \<in> V" "y \<in> V" "u + v = (1::real)"
  1162     and *: "\<And>S u. \<lbrakk>finite S; S \<noteq> {}; S \<subseteq> V; sum u S = 1\<rbrakk> \<Longrightarrow> (\<Sum>x\<in>S. u x *\<^sub>R x) \<in> V" for x y u v
  1163   proof (cases "x = y")
  1164     case True
  1165     then show ?thesis
  1166       using that by (metis scaleR_add_left scaleR_one)
  1167   next
  1168     case False
  1169     then show ?thesis
  1170       using that *[of "{x,y}" "\<lambda>w. if w = x then u else v"] by auto
  1171   qed
  1172   moreover have "(\<Sum>x\<in>S. u x *\<^sub>R x) \<in> V"
  1173                 if *: "\<And>x y u v. \<lbrakk>x\<in>V; y\<in>V; u + v = 1\<rbrakk> \<Longrightarrow> u *\<^sub>R x + v *\<^sub>R y \<in> V"
  1174                   and "finite S" "S \<noteq> {}" "S \<subseteq> V" "sum u S = 1" for S u
  1175   proof -
  1176     define n where "n = card S"
  1177     consider "card S = 0" | "card S = 1" | "card S = 2" | "card S > 2" by linarith
  1178     then show "(\<Sum>x\<in>S. u x *\<^sub>R x) \<in> V"
  1179     proof cases
  1180       assume "card S = 1"
  1181       then obtain a where "S={a}"
  1182         by (auto simp: card_Suc_eq)
  1183       then show ?thesis
  1184         using that by simp
  1185     next
  1186       assume "card S = 2"
  1187       then obtain a b where "S = {a, b}"
  1188         by (metis Suc_1 card_1_singletonE card_Suc_eq)
  1189       then show ?thesis
  1190         using *[of a b] that
  1191         by (auto simp: sum_clauses(2))
  1192     next
  1193       assume "card S > 2"
  1194       then show ?thesis using that n_def
  1195       proof (induct n arbitrary: u S)
  1196         case 0
  1197         then show ?case by auto
  1198       next
  1199         case (Suc n u S)
  1200         have "sum u S = card S" if "\<not> (\<exists>x\<in>S. u x \<noteq> 1)"
  1201           using that unfolding card_eq_sum by auto
  1202         with Suc.prems obtain x where "x \<in> S" and x: "u x \<noteq> 1" by force
  1203         have c: "card (S - {x}) = card S - 1"
  1204           by (simp add: Suc.prems(3) \<open>x \<in> S\<close>)
  1205         have "sum u (S - {x}) = 1 - u x"
  1206           by (simp add: Suc.prems sum_diff1 \<open>x \<in> S\<close>)
  1207         with x have eq1: "inverse (1 - u x) * sum u (S - {x}) = 1"
  1208           by auto
  1209         have inV: "(\<Sum>y\<in>S - {x}. (inverse (1 - u x) * u y) *\<^sub>R y) \<in> V"
  1210         proof (cases "card (S - {x}) > 2")
  1211           case True
  1212           then have S: "S - {x} \<noteq> {}" "card (S - {x}) = n"
  1213             using Suc.prems c by force+
  1214           show ?thesis
  1215           proof (rule Suc.hyps)
  1216             show "(\<Sum>a\<in>S - {x}. inverse (1 - u x) * u a) = 1"
  1217               by (auto simp: eq1 sum_distrib_left[symmetric])
  1218           qed (use S Suc.prems True in auto)
  1219         next
  1220           case False
  1221           then have "card (S - {x}) = Suc (Suc 0)"
  1222             using Suc.prems c by auto
  1223           then obtain a b where ab: "(S - {x}) = {a, b}" "a\<noteq>b"
  1224             unfolding card_Suc_eq by auto
  1225           then show ?thesis
  1226             using eq1 \<open>S \<subseteq> V\<close>
  1227             by (auto simp: sum_distrib_left distrib_left intro!: Suc.prems(2)[of a b])
  1228         qed
  1229         have "u x + (1 - u x) = 1 \<Longrightarrow>
  1230           u x *\<^sub>R x + (1 - u x) *\<^sub>R ((\<Sum>y\<in>S - {x}. u y *\<^sub>R y) /\<^sub>R (1 - u x)) \<in> V"
  1231           by (rule Suc.prems) (use \<open>x \<in> S\<close> Suc.prems inV in \<open>auto simp: scaleR_right.sum\<close>)
  1232         moreover have "(\<Sum>a\<in>S. u a *\<^sub>R a) = u x *\<^sub>R x + (\<Sum>a\<in>S - {x}. u a *\<^sub>R a)"
  1233           by (meson Suc.prems(3) sum.remove \<open>x \<in> S\<close>)
  1234         ultimately show "(\<Sum>x\<in>S. u x *\<^sub>R x) \<in> V"
  1235           by (simp add: x)
  1236       qed
  1237     qed (use \<open>S\<noteq>{}\<close> \<open>finite S\<close> in auto)
  1238   qed
  1239   ultimately show ?thesis
  1240     unfolding affine_def by meson
  1241 qed
  1242 
  1243 
  1244 lemma affine_hull_explicit:
  1245   "affine hull p = {y. \<exists>S u. finite S \<and> S \<noteq> {} \<and> S \<subseteq> p \<and> sum u S = 1 \<and> sum (\<lambda>v. u v *\<^sub>R v) S = y}"
  1246   (is "_ = ?rhs")
  1247 proof (rule hull_unique)
  1248   show "p \<subseteq> ?rhs"
  1249   proof (intro subsetI CollectI exI conjI)
  1250     show "\<And>x. sum (\<lambda>z. 1) {x} = 1"
  1251       by auto
  1252   qed auto
  1253   show "?rhs \<subseteq> T" if "p \<subseteq> T" "affine T" for T
  1254     using that unfolding affine by blast
  1255   show "affine ?rhs"
  1256     unfolding affine_def
  1257   proof clarify
  1258     fix u v :: real and sx ux sy uy
  1259     assume uv: "u + v = 1"
  1260       and x: "finite sx" "sx \<noteq> {}" "sx \<subseteq> p" "sum ux sx = (1::real)"
  1261       and y: "finite sy" "sy \<noteq> {}" "sy \<subseteq> p" "sum uy sy = (1::real)" 
  1262     have **: "(sx \<union> sy) \<inter> sx = sx" "(sx \<union> sy) \<inter> sy = sy"
  1263       by auto
  1264     show "\<exists>S w. finite S \<and> S \<noteq> {} \<and> S \<subseteq> p \<and>
  1265         sum w S = 1 \<and> (\<Sum>v\<in>S. w v *\<^sub>R v) = u *\<^sub>R (\<Sum>v\<in>sx. ux v *\<^sub>R v) + v *\<^sub>R (\<Sum>v\<in>sy. uy v *\<^sub>R v)"
  1266     proof (intro exI conjI)
  1267       show "finite (sx \<union> sy)"
  1268         using x y by auto
  1269       show "sum (\<lambda>i. (if i\<in>sx then u * ux i else 0) + (if i\<in>sy then v * uy i else 0)) (sx \<union> sy) = 1"
  1270         using x y uv
  1271         by (simp add: sum_Un sum.distrib sum.inter_restrict[symmetric] sum_distrib_left [symmetric] **)
  1272       have "(\<Sum>i\<in>sx \<union> sy. ((if i \<in> sx then u * ux i else 0) + (if i \<in> sy then v * uy i else 0)) *\<^sub>R i)
  1273           = (\<Sum>i\<in>sx. (u * ux i) *\<^sub>R i) + (\<Sum>i\<in>sy. (v * uy i) *\<^sub>R i)"
  1274         using x y
  1275         unfolding scaleR_left_distrib scaleR_zero_left if_smult
  1276         by (simp add: sum_Un sum.distrib sum.inter_restrict[symmetric]  **)
  1277       also have "\<dots> = u *\<^sub>R (\<Sum>v\<in>sx. ux v *\<^sub>R v) + v *\<^sub>R (\<Sum>v\<in>sy. uy v *\<^sub>R v)"
  1278         unfolding scaleR_scaleR[symmetric] scaleR_right.sum [symmetric] by blast
  1279       finally show "(\<Sum>i\<in>sx \<union> sy. ((if i \<in> sx then u * ux i else 0) + (if i \<in> sy then v * uy i else 0)) *\<^sub>R i) 
  1280                   = u *\<^sub>R (\<Sum>v\<in>sx. ux v *\<^sub>R v) + v *\<^sub>R (\<Sum>v\<in>sy. uy v *\<^sub>R v)" .
  1281     qed (use x y in auto)
  1282   qed
  1283 qed
  1284 
  1285 lemma affine_hull_finite:
  1286   assumes "finite S"
  1287   shows "affine hull S = {y. \<exists>u. sum u S = 1 \<and> sum (\<lambda>v. u v *\<^sub>R v) S = y}"
  1288 proof -
  1289   have *: "\<exists>h. sum h S = 1 \<and> (\<Sum>v\<in>S. h v *\<^sub>R v) = x" 
  1290     if "F \<subseteq> S" "finite F" "F \<noteq> {}" and sum: "sum u F = 1" and x: "(\<Sum>v\<in>F. u v *\<^sub>R v) = x" for x F u
  1291   proof -
  1292     have "S \<inter> F = F"
  1293       using that by auto
  1294     show ?thesis
  1295     proof (intro exI conjI)
  1296       show "(\<Sum>x\<in>S. if x \<in> F then u x else 0) = 1"
  1297         by (metis (mono_tags, lifting) \<open>S \<inter> F = F\<close> assms sum.inter_restrict sum)
  1298       show "(\<Sum>v\<in>S. (if v \<in> F then u v else 0) *\<^sub>R v) = x"
  1299         by (simp add: if_smult cong: if_cong) (metis (no_types) \<open>S \<inter> F = F\<close> assms sum.inter_restrict x)
  1300     qed
  1301   qed
  1302   show ?thesis
  1303     unfolding affine_hull_explicit using assms
  1304     by (fastforce dest: *)
  1305 qed
  1306 
  1307 
  1308 subsubsection%unimportant \<open>Stepping theorems and hence small special cases\<close>
  1309 
  1310 lemma affine_hull_empty[simp]: "affine hull {} = {}"
  1311   by simp
  1312 
  1313 lemma affine_hull_finite_step:
  1314   fixes y :: "'a::real_vector"
  1315   shows "finite S \<Longrightarrow>
  1316       (\<exists>u. sum u (insert a S) = w \<and> sum (\<lambda>x. u x *\<^sub>R x) (insert a S) = y) \<longleftrightarrow>
  1317       (\<exists>v u. sum u S = w - v \<and> sum (\<lambda>x. u x *\<^sub>R x) S = y - v *\<^sub>R a)" (is "_ \<Longrightarrow> ?lhs = ?rhs")
  1318 proof -
  1319   assume fin: "finite S"
  1320   show "?lhs = ?rhs"
  1321   proof
  1322     assume ?lhs
  1323     then obtain u where u: "sum u (insert a S) = w \<and> (\<Sum>x\<in>insert a S. u x *\<^sub>R x) = y"
  1324       by auto
  1325     show ?rhs
  1326     proof (cases "a \<in> S")
  1327       case True
  1328       then show ?thesis
  1329         using u by (simp add: insert_absorb) (metis diff_zero real_vector.scale_zero_left)
  1330     next
  1331       case False
  1332       show ?thesis
  1333         by (rule exI [where x="u a"]) (use u fin False in auto)
  1334     qed
  1335   next
  1336     assume ?rhs
  1337     then obtain v u where vu: "sum u S = w - v"  "(\<Sum>x\<in>S. u x *\<^sub>R x) = y - v *\<^sub>R a"
  1338       by auto
  1339     have *: "\<And>x M. (if x = a then v else M) *\<^sub>R x = (if x = a then v *\<^sub>R x else M *\<^sub>R x)"
  1340       by auto
  1341     show ?lhs
  1342     proof (cases "a \<in> S")
  1343       case True
  1344       show ?thesis
  1345         by (rule exI [where x="\<lambda>x. (if x=a then v else 0) + u x"])
  1346            (simp add: True scaleR_left_distrib sum.distrib sum_clauses fin vu * cong: if_cong)
  1347     next
  1348       case False
  1349       then show ?thesis
  1350         apply (rule_tac x="\<lambda>x. if x=a then v else u x" in exI) 
  1351         apply (simp add: vu sum_clauses(2)[OF fin] *)
  1352         by (simp add: sum_delta_notmem(3) vu)
  1353     qed
  1354   qed
  1355 qed
  1356 
  1357 lemma affine_hull_2:
  1358   fixes a b :: "'a::real_vector"
  1359   shows "affine hull {a,b} = {u *\<^sub>R a + v *\<^sub>R b| u v. (u + v = 1)}"
  1360   (is "?lhs = ?rhs")
  1361 proof -
  1362   have *:
  1363     "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::real)"
  1364     "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::'a)" by auto
  1365   have "?lhs = {y. \<exists>u. sum u {a, b} = 1 \<and> (\<Sum>v\<in>{a, b}. u v *\<^sub>R v) = y}"
  1366     using affine_hull_finite[of "{a,b}"] by auto
  1367   also have "\<dots> = {y. \<exists>v u. u b = 1 - v \<and> u b *\<^sub>R b = y - v *\<^sub>R a}"
  1368     by (simp add: affine_hull_finite_step[of "{b}" a])
  1369   also have "\<dots> = ?rhs" unfolding * by auto
  1370   finally show ?thesis by auto
  1371 qed
  1372 
  1373 lemma affine_hull_3:
  1374   fixes a b c :: "'a::real_vector"
  1375   shows "affine hull {a,b,c} = { u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c| u v w. u + v + w = 1}"
  1376 proof -
  1377   have *:
  1378     "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::real)"
  1379     "\<And>x y z. z = x - y \<longleftrightarrow> y + z = (x::'a)" by auto
  1380   show ?thesis
  1381     apply (simp add: affine_hull_finite affine_hull_finite_step)
  1382     unfolding *
  1383     apply safe
  1384      apply (metis add.assoc)
  1385     apply (rule_tac x=u in exI, force)
  1386     done
  1387 qed
  1388 
  1389 lemma mem_affine:
  1390   assumes "affine S" "x \<in> S" "y \<in> S" "u + v = 1"
  1391   shows "u *\<^sub>R x + v *\<^sub>R y \<in> S"
  1392   using assms affine_def[of S] by auto
  1393 
  1394 lemma mem_affine_3:
  1395   assumes "affine S" "x \<in> S" "y \<in> S" "z \<in> S" "u + v + w = 1"
  1396   shows "u *\<^sub>R x + v *\<^sub>R y + w *\<^sub>R z \<in> S"
  1397 proof -
  1398   have "u *\<^sub>R x + v *\<^sub>R y + w *\<^sub>R z \<in> affine hull {x, y, z}"
  1399     using affine_hull_3[of x y z] assms by auto
  1400   moreover
  1401   have "affine hull {x, y, z} \<subseteq> affine hull S"
  1402     using hull_mono[of "{x, y, z}" "S"] assms by auto
  1403   moreover
  1404   have "affine hull S = S"
  1405     using assms affine_hull_eq[of S] by auto
  1406   ultimately show ?thesis by auto
  1407 qed
  1408 
  1409 lemma mem_affine_3_minus:
  1410   assumes "affine S" "x \<in> S" "y \<in> S" "z \<in> S"
  1411   shows "x + v *\<^sub>R (y-z) \<in> S"
  1412   using mem_affine_3[of S x y z 1 v "-v"] assms
  1413   by (simp add: algebra_simps)
  1414 
  1415 corollary mem_affine_3_minus2:
  1416     "\<lbrakk>affine S; x \<in> S; y \<in> S; z \<in> S\<rbrakk> \<Longrightarrow> x - v *\<^sub>R (y-z) \<in> S"
  1417   by (metis add_uminus_conv_diff mem_affine_3_minus real_vector.scale_minus_left)
  1418 
  1419 
  1420 subsubsection%unimportant \<open>Some relations between affine hull and subspaces\<close>
  1421 
  1422 lemma affine_hull_insert_subset_span:
  1423   "affine hull (insert a S) \<subseteq> {a + v| v . v \<in> span {x - a | x . x \<in> S}}"
  1424 proof -
  1425   have "\<exists>v T u. x = a + v \<and> (finite T \<and> T \<subseteq> {x - a |x. x \<in> S} \<and> (\<Sum>v\<in>T. u v *\<^sub>R v) = v)"
  1426     if "finite F" "F \<noteq> {}" "F \<subseteq> insert a S" "sum u F = 1" "(\<Sum>v\<in>F. u v *\<^sub>R v) = x"
  1427     for x F u
  1428   proof -
  1429     have *: "(\<lambda>x. x - a) ` (F - {a}) \<subseteq> {x - a |x. x \<in> S}"
  1430       using that by auto
  1431     show ?thesis
  1432     proof (intro exI conjI)
  1433       show "finite ((\<lambda>x. x - a) ` (F - {a}))"
  1434         by (simp add: that(1))
  1435       show "(\<Sum>v\<in>(\<lambda>x. x - a) ` (F - {a}). u(v+a) *\<^sub>R v) = x-a"
  1436         by (simp add: sum.reindex[unfolded inj_on_def] algebra_simps
  1437             sum_subtractf scaleR_left.sum[symmetric] sum_diff1 that)
  1438     qed (use \<open>F \<subseteq> insert a S\<close> in auto)
  1439   qed
  1440   then show ?thesis
  1441     unfolding affine_hull_explicit span_explicit by blast
  1442 qed
  1443 
  1444 lemma affine_hull_insert_span:
  1445   assumes "a \<notin> S"
  1446   shows "affine hull (insert a S) = {a + v | v . v \<in> span {x - a | x.  x \<in> S}}"
  1447 proof -
  1448   have *: "\<exists>G u. finite G \<and> G \<noteq> {} \<and> G \<subseteq> insert a S \<and> sum u G = 1 \<and> (\<Sum>v\<in>G. u v *\<^sub>R v) = y"
  1449     if "v \<in> span {x - a |x. x \<in> S}" "y = a + v" for y v
  1450   proof -
  1451     from that
  1452     obtain T u where u: "finite T" "T \<subseteq> {x - a |x. x \<in> S}" "a + (\<Sum>v\<in>T. u v *\<^sub>R v) = y"
  1453       unfolding span_explicit by auto
  1454     define F where "F = (\<lambda>x. x + a) ` T"
  1455     have F: "finite F" "F \<subseteq> S" "(\<Sum>v\<in>F. u (v - a) *\<^sub>R (v - a)) = y - a"
  1456       unfolding F_def using u by (auto simp: sum.reindex[unfolded inj_on_def])
  1457     have *: "F \<inter> {a} = {}" "F \<inter> - {a} = F"
  1458       using F assms by auto
  1459     show "\<exists>G u. finite G \<and> G \<noteq> {} \<and> G \<subseteq> insert a S \<and> sum u G = 1 \<and> (\<Sum>v\<in>G. u v *\<^sub>R v) = y"
  1460       apply (rule_tac x = "insert a F" in exI)
  1461       apply (rule_tac x = "\<lambda>x. if x=a then 1 - sum (\<lambda>x. u (x - a)) F else u (x - a)" in exI)
  1462       using assms F
  1463       apply (auto simp:  sum_clauses sum.If_cases if_smult sum_subtractf scaleR_left.sum algebra_simps *)
  1464       done
  1465   qed
  1466   show ?thesis
  1467     by (intro subset_antisym affine_hull_insert_subset_span) (auto simp: affine_hull_explicit dest!: *)
  1468 qed
  1469 
  1470 lemma affine_hull_span:
  1471   assumes "a \<in> S"
  1472   shows "affine hull S = {a + v | v. v \<in> span {x - a | x. x \<in> S - {a}}}"
  1473   using affine_hull_insert_span[of a "S - {a}", unfolded insert_Diff[OF assms]] by auto
  1474 
  1475 
  1476 subsubsection%unimportant \<open>Parallel affine sets\<close>
  1477 
  1478 definition affine_parallel :: "'a::real_vector set \<Rightarrow> 'a::real_vector set \<Rightarrow> bool"
  1479   where "affine_parallel S T \<longleftrightarrow> (\<exists>a. T = (\<lambda>x. a + x) ` S)"
  1480 
  1481 lemma affine_parallel_expl_aux:
  1482   fixes S T :: "'a::real_vector set"
  1483   assumes "\<And>x. x \<in> S \<longleftrightarrow> a + x \<in> T"
  1484   shows "T = (\<lambda>x. a + x) ` S"
  1485 proof -
  1486   have "x \<in> ((\<lambda>x. a + x) ` S)" if "x \<in> T" for x
  1487     using that
  1488     by (simp add: image_iff) (metis add.commute diff_add_cancel assms)
  1489   moreover have "T \<ge> (\<lambda>x. a + x) ` S"
  1490     using assms by auto
  1491   ultimately show ?thesis by auto
  1492 qed
  1493 
  1494 lemma affine_parallel_expl: "affine_parallel S T \<longleftrightarrow> (\<exists>a. \<forall>x. x \<in> S \<longleftrightarrow> a + x \<in> T)"
  1495   by (auto simp add: affine_parallel_def)
  1496     (use affine_parallel_expl_aux [of S _ T] in blast)
  1497 
  1498 lemma affine_parallel_reflex: "affine_parallel S S"
  1499   unfolding affine_parallel_def
  1500   using image_add_0 by blast
  1501 
  1502 lemma affine_parallel_commut:
  1503   assumes "affine_parallel A B"
  1504   shows "affine_parallel B A"
  1505 proof -
  1506   from assms obtain a where B: "B = (\<lambda>x. a + x) ` A"
  1507     unfolding affine_parallel_def by auto
  1508   have [simp]: "(\<lambda>x. x - a) = plus (- a)" by (simp add: fun_eq_iff)
  1509   from B show ?thesis
  1510     using translation_galois [of B a A]
  1511     unfolding affine_parallel_def by blast
  1512 qed
  1513 
  1514 lemma affine_parallel_assoc:
  1515   assumes "affine_parallel A B"
  1516     and "affine_parallel B C"
  1517   shows "affine_parallel A C"
  1518 proof -
  1519   from assms obtain ab where "B = (\<lambda>x. ab + x) ` A"
  1520     unfolding affine_parallel_def by auto
  1521   moreover
  1522   from assms obtain bc where "C = (\<lambda>x. bc + x) ` B"
  1523     unfolding affine_parallel_def by auto
  1524   ultimately show ?thesis
  1525     using translation_assoc[of bc ab A] unfolding affine_parallel_def by auto
  1526 qed
  1527 
  1528 lemma affine_translation_aux:
  1529   fixes a :: "'a::real_vector"
  1530   assumes "affine ((\<lambda>x. a + x) ` S)"
  1531   shows "affine S"
  1532 proof -
  1533   {
  1534     fix x y u v
  1535     assume xy: "x \<in> S" "y \<in> S" "(u :: real) + v = 1"
  1536     then have "(a + x) \<in> ((\<lambda>x. a + x) ` S)" "(a + y) \<in> ((\<lambda>x. a + x) ` S)"
  1537       by auto
  1538     then have h1: "u *\<^sub>R  (a + x) + v *\<^sub>R (a + y) \<in> (\<lambda>x. a + x) ` S"
  1539       using xy assms unfolding affine_def by auto
  1540     have "u *\<^sub>R (a + x) + v *\<^sub>R (a + y) = (u + v) *\<^sub>R a + (u *\<^sub>R x + v *\<^sub>R y)"
  1541       by (simp add: algebra_simps)
  1542     also have "\<dots> = a + (u *\<^sub>R x + v *\<^sub>R y)"
  1543       using \<open>u + v = 1\<close> by auto
  1544     ultimately have "a + (u *\<^sub>R x + v *\<^sub>R y) \<in> (\<lambda>x. a + x) ` S"
  1545       using h1 by auto
  1546     then have "u *\<^sub>R x + v *\<^sub>R y \<in> S" by auto
  1547   }
  1548   then show ?thesis unfolding affine_def by auto
  1549 qed
  1550 
  1551 lemma affine_translation:
  1552   "affine S \<longleftrightarrow> affine ((+) a ` S)" for a :: "'a::real_vector"
  1553 proof
  1554   show "affine ((+) a ` S)" if "affine S"
  1555     using that translation_assoc [of "- a" a S]
  1556     by (auto intro: affine_translation_aux [of "- a" "((+) a ` S)"])
  1557   show "affine S" if "affine ((+) a ` S)"
  1558     using that by (rule affine_translation_aux)
  1559 qed
  1560 
  1561 lemma parallel_is_affine:
  1562   fixes S T :: "'a::real_vector set"
  1563   assumes "affine S" "affine_parallel S T"
  1564   shows "affine T"
  1565 proof -
  1566   from assms obtain a where "T = (\<lambda>x. a + x) ` S"
  1567     unfolding affine_parallel_def by auto
  1568   then show ?thesis
  1569     using affine_translation assms by auto
  1570 qed
  1571 
  1572 lemma subspace_imp_affine: "subspace s \<Longrightarrow> affine s"
  1573   unfolding subspace_def affine_def by auto
  1574 
  1575 
  1576 subsubsection%unimportant \<open>Subspace parallel to an affine set\<close>
  1577 
  1578 lemma subspace_affine: "subspace S \<longleftrightarrow> affine S \<and> 0 \<in> S"
  1579 proof -
  1580   have h0: "subspace S \<Longrightarrow> affine S \<and> 0 \<in> S"
  1581     using subspace_imp_affine[of S] subspace_0 by auto
  1582   {
  1583     assume assm: "affine S \<and> 0 \<in> S"
  1584     {
  1585       fix c :: real
  1586       fix x
  1587       assume x: "x \<in> S"
  1588       have "c *\<^sub>R x = (1-c) *\<^sub>R 0 + c *\<^sub>R x" by auto
  1589       moreover
  1590       have "(1 - c) *\<^sub>R 0 + c *\<^sub>R x \<in> S"
  1591         using affine_alt[of S] assm x by auto
  1592       ultimately have "c *\<^sub>R x \<in> S" by auto
  1593     }
  1594     then have h1: "\<forall>c. \<forall>x \<in> S. c *\<^sub>R x \<in> S" by auto
  1595 
  1596     {
  1597       fix x y
  1598       assume xy: "x \<in> S" "y \<in> S"
  1599       define u where "u = (1 :: real)/2"
  1600       have "(1/2) *\<^sub>R (x+y) = (1/2) *\<^sub>R (x+y)"
  1601         by auto
  1602       moreover
  1603       have "(1/2) *\<^sub>R (x+y)=(1/2) *\<^sub>R x + (1-(1/2)) *\<^sub>R y"
  1604         by (simp add: algebra_simps)
  1605       moreover
  1606       have "(1 - u) *\<^sub>R x + u *\<^sub>R y \<in> S"
  1607         using affine_alt[of S] assm xy by auto
  1608       ultimately
  1609       have "(1/2) *\<^sub>R (x+y) \<in> S"
  1610         using u_def by auto
  1611       moreover
  1612       have "x + y = 2 *\<^sub>R ((1/2) *\<^sub>R (x+y))"
  1613         by auto
  1614       ultimately
  1615       have "x + y \<in> S"
  1616         using h1[rule_format, of "(1/2) *\<^sub>R (x+y)" "2"] by auto
  1617     }
  1618     then have "\<forall>x \<in> S. \<forall>y \<in> S. x + y \<in> S"
  1619       by auto
  1620     then have "subspace S"
  1621       using h1 assm unfolding subspace_def by auto
  1622   }
  1623   then show ?thesis using h0 by metis
  1624 qed
  1625 
  1626 lemma affine_diffs_subspace:
  1627   assumes "affine S" "a \<in> S"
  1628   shows "subspace ((\<lambda>x. (-a)+x) ` S)"
  1629 proof -
  1630   have [simp]: "(\<lambda>x. x - a) = plus (- a)" by (simp add: fun_eq_iff)
  1631   have "affine ((\<lambda>x. (-a)+x) ` S)"
  1632     using affine_translation assms by blast
  1633   moreover have "0 \<in> ((\<lambda>x. (-a)+x) ` S)"
  1634     using assms exI[of "(\<lambda>x. x\<in>S \<and> -a+x = 0)" a] by auto
  1635   ultimately show ?thesis using subspace_affine by auto
  1636 qed
  1637 
  1638 lemma affine_diffs_subspace_subtract:
  1639   "subspace ((\<lambda>x. x - a) ` S)" if "affine S" "a \<in> S"
  1640   using that affine_diffs_subspace [of _ a] by simp
  1641 
  1642 lemma parallel_subspace_explicit:
  1643   assumes "affine S"
  1644     and "a \<in> S"
  1645   assumes "L \<equiv> {y. \<exists>x \<in> S. (-a) + x = y}"
  1646   shows "subspace L \<and> affine_parallel S L"
  1647 proof -
  1648   from assms have "L = plus (- a) ` S" by auto
  1649   then have par: "affine_parallel S L"
  1650     unfolding affine_parallel_def ..
  1651   then have "affine L" using assms parallel_is_affine by auto
  1652   moreover have "0 \<in> L"
  1653     using assms by auto
  1654   ultimately show ?thesis
  1655     using subspace_affine par by auto
  1656 qed
  1657 
  1658 lemma parallel_subspace_aux:
  1659   assumes "subspace A"
  1660     and "subspace B"
  1661     and "affine_parallel A B"
  1662   shows "A \<supseteq> B"
  1663 proof -
  1664   from assms obtain a where a: "\<forall>x. x \<in> A \<longleftrightarrow> a + x \<in> B"
  1665     using affine_parallel_expl[of A B] by auto
  1666   then have "-a \<in> A"
  1667     using assms subspace_0[of B] by auto
  1668   then have "a \<in> A"
  1669     using assms subspace_neg[of A "-a"] by auto
  1670   then show ?thesis
  1671     using assms a unfolding subspace_def by auto
  1672 qed
  1673 
  1674 lemma parallel_subspace:
  1675   assumes "subspace A"
  1676     and "subspace B"
  1677     and "affine_parallel A B"
  1678   shows "A = B"
  1679 proof
  1680   show "A \<supseteq> B"
  1681     using assms parallel_subspace_aux by auto
  1682   show "A \<subseteq> B"
  1683     using assms parallel_subspace_aux[of B A] affine_parallel_commut by auto
  1684 qed
  1685 
  1686 lemma affine_parallel_subspace:
  1687   assumes "affine S" "S \<noteq> {}"
  1688   shows "\<exists>!L. subspace L \<and> affine_parallel S L"
  1689 proof -
  1690   have ex: "\<exists>L. subspace L \<and> affine_parallel S L"
  1691     using assms parallel_subspace_explicit by auto
  1692   {
  1693     fix L1 L2
  1694     assume ass: "subspace L1 \<and> affine_parallel S L1" "subspace L2 \<and> affine_parallel S L2"
  1695     then have "affine_parallel L1 L2"
  1696       using affine_parallel_commut[of S L1] affine_parallel_assoc[of L1 S L2] by auto
  1697     then have "L1 = L2"
  1698       using ass parallel_subspace by auto
  1699   }
  1700   then show ?thesis using ex by auto
  1701 qed
  1702 
  1703 
  1704 subsection \<open>Cones\<close>
  1705 
  1706 definition%important cone :: "'a::real_vector set \<Rightarrow> bool"
  1707   where "cone s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>c\<ge>0. c *\<^sub>R x \<in> s)"
  1708 
  1709 lemma cone_empty[intro, simp]: "cone {}"
  1710   unfolding cone_def by auto
  1711 
  1712 lemma cone_univ[intro, simp]: "cone UNIV"
  1713   unfolding cone_def by auto
  1714 
  1715 lemma cone_Inter[intro]: "\<forall>s\<in>f. cone s \<Longrightarrow> cone (\<Inter>f)"
  1716   unfolding cone_def by auto
  1717 
  1718 lemma subspace_imp_cone: "subspace S \<Longrightarrow> cone S"
  1719   by (simp add: cone_def subspace_scale)
  1720 
  1721 
  1722 subsubsection \<open>Conic hull\<close>
  1723 
  1724 lemma cone_cone_hull: "cone (cone hull s)"
  1725   unfolding hull_def by auto
  1726 
  1727 lemma cone_hull_eq: "cone hull s = s \<longleftrightarrow> cone s"
  1728   apply (rule hull_eq)
  1729   using cone_Inter
  1730   unfolding subset_eq
  1731   apply auto
  1732   done
  1733 
  1734 lemma mem_cone:
  1735   assumes "cone S" "x \<in> S" "c \<ge> 0"
  1736   shows "c *\<^sub>R x \<in> S"
  1737   using assms cone_def[of S] by auto
  1738 
  1739 lemma cone_contains_0:
  1740   assumes "cone S"
  1741   shows "S \<noteq> {} \<longleftrightarrow> 0 \<in> S"
  1742 proof -
  1743   {
  1744     assume "S \<noteq> {}"
  1745     then obtain a where "a \<in> S" by auto
  1746     then have "0 \<in> S"
  1747       using assms mem_cone[of S a 0] by auto
  1748   }
  1749   then show ?thesis by auto
  1750 qed
  1751 
  1752 lemma cone_0: "cone {0}"
  1753   unfolding cone_def by auto
  1754 
  1755 lemma cone_Union[intro]: "(\<forall>s\<in>f. cone s) \<longrightarrow> cone (\<Union>f)"
  1756   unfolding cone_def by blast
  1757 
  1758 lemma cone_iff:
  1759   assumes "S \<noteq> {}"
  1760   shows "cone S \<longleftrightarrow> 0 \<in> S \<and> (\<forall>c. c > 0 \<longrightarrow> ((*\<^sub>R) c) ` S = S)"
  1761 proof -
  1762   {
  1763     assume "cone S"
  1764     {
  1765       fix c :: real
  1766       assume "c > 0"
  1767       {
  1768         fix x
  1769         assume "x \<in> S"
  1770         then have "x \<in> ((*\<^sub>R) c) ` S"
  1771           unfolding image_def
  1772           using \<open>cone S\<close> \<open>c>0\<close> mem_cone[of S x "1/c"]
  1773             exI[of "(\<lambda>t. t \<in> S \<and> x = c *\<^sub>R t)" "(1 / c) *\<^sub>R x"]
  1774           by auto
  1775       }
  1776       moreover
  1777       {
  1778         fix x
  1779         assume "x \<in> ((*\<^sub>R) c) ` S"
  1780         then have "x \<in> S"
  1781           using \<open>cone S\<close> \<open>c > 0\<close>
  1782           unfolding cone_def image_def \<open>c > 0\<close> by auto
  1783       }
  1784       ultimately have "((*\<^sub>R) c) ` S = S" by blast
  1785     }
  1786     then have "0 \<in> S \<and> (\<forall>c. c > 0 \<longrightarrow> ((*\<^sub>R) c) ` S = S)"
  1787       using \<open>cone S\<close> cone_contains_0[of S] assms by auto
  1788   }
  1789   moreover
  1790   {
  1791     assume a: "0 \<in> S \<and> (\<forall>c. c > 0 \<longrightarrow> ((*\<^sub>R) c) ` S = S)"
  1792     {
  1793       fix x
  1794       assume "x \<in> S"
  1795       fix c1 :: real
  1796       assume "c1 \<ge> 0"
  1797       then have "c1 = 0 \<or> c1 > 0" by auto
  1798       then have "c1 *\<^sub>R x \<in> S" using a \<open>x \<in> S\<close> by auto
  1799     }
  1800     then have "cone S" unfolding cone_def by auto
  1801   }
  1802   ultimately show ?thesis by blast
  1803 qed
  1804 
  1805 lemma cone_hull_empty: "cone hull {} = {}"
  1806   by (metis cone_empty cone_hull_eq)
  1807 
  1808 lemma cone_hull_empty_iff: "S = {} \<longleftrightarrow> cone hull S = {}"
  1809   by (metis bot_least cone_hull_empty hull_subset xtrans(5))
  1810 
  1811 lemma cone_hull_contains_0: "S \<noteq> {} \<longleftrightarrow> 0 \<in> cone hull S"
  1812   using cone_cone_hull[of S] cone_contains_0[of "cone hull S"] cone_hull_empty_iff[of S]
  1813   by auto
  1814 
  1815 lemma mem_cone_hull:
  1816   assumes "x \<in> S" "c \<ge> 0"
  1817   shows "c *\<^sub>R x \<in> cone hull S"
  1818   by (metis assms cone_cone_hull hull_inc mem_cone)
  1819 
  1820 proposition cone_hull_expl: "cone hull S = {c *\<^sub>R x | c x. c \<ge> 0 \<and> x \<in> S}"
  1821   (is "?lhs = ?rhs")
  1822 proof -
  1823   {
  1824     fix x
  1825     assume "x \<in> ?rhs"
  1826     then obtain cx :: real and xx where x: "x = cx *\<^sub>R xx" "cx \<ge> 0" "xx \<in> S"
  1827       by auto
  1828     fix c :: real
  1829     assume c: "c \<ge> 0"
  1830     then have "c *\<^sub>R x = (c * cx) *\<^sub>R xx"
  1831       using x by (simp add: algebra_simps)
  1832     moreover
  1833     have "c * cx \<ge> 0" using c x by auto
  1834     ultimately
  1835     have "c *\<^sub>R x \<in> ?rhs" using x by auto
  1836   }
  1837   then have "cone ?rhs"
  1838     unfolding cone_def by auto
  1839   then have "?rhs \<in> Collect cone"
  1840     unfolding mem_Collect_eq by auto
  1841   {
  1842     fix x
  1843     assume "x \<in> S"
  1844     then have "1 *\<^sub>R x \<in> ?rhs"
  1845       apply auto
  1846       apply (rule_tac x = 1 in exI, auto)
  1847       done
  1848     then have "x \<in> ?rhs" by auto
  1849   }
  1850   then have "S \<subseteq> ?rhs" by auto
  1851   then have "?lhs \<subseteq> ?rhs"
  1852     using \<open>?rhs \<in> Collect cone\<close> hull_minimal[of S "?rhs" "cone"] by auto
  1853   moreover
  1854   {
  1855     fix x
  1856     assume "x \<in> ?rhs"
  1857     then obtain cx :: real and xx where x: "x = cx *\<^sub>R xx" "cx \<ge> 0" "xx \<in> S"
  1858       by auto
  1859     then have "xx \<in> cone hull S"
  1860       using hull_subset[of S] by auto
  1861     then have "x \<in> ?lhs"
  1862       using x cone_cone_hull[of S] cone_def[of "cone hull S"] by auto
  1863   }
  1864   ultimately show ?thesis by auto
  1865 qed
  1866 
  1867 
  1868 subsection \<open>Affine dependence and consequential theorems\<close>
  1869 
  1870 text "Formalized by Lars Schewe."
  1871 
  1872 definition%important affine_dependent :: "'a::real_vector set \<Rightarrow> bool"
  1873   where "affine_dependent s \<longleftrightarrow> (\<exists>x\<in>s. x \<in> affine hull (s - {x}))"
  1874 
  1875 lemma affine_dependent_subset:
  1876    "\<lbrakk>affine_dependent s; s \<subseteq> t\<rbrakk> \<Longrightarrow> affine_dependent t"
  1877 apply (simp add: affine_dependent_def Bex_def)
  1878 apply (blast dest: hull_mono [OF Diff_mono [OF _ subset_refl]])
  1879 done
  1880 
  1881 lemma affine_independent_subset:
  1882   shows "\<lbrakk>\<not> affine_dependent t; s \<subseteq> t\<rbrakk> \<Longrightarrow> \<not> affine_dependent s"
  1883 by (metis affine_dependent_subset)
  1884 
  1885 lemma affine_independent_Diff:
  1886    "\<not> affine_dependent s \<Longrightarrow> \<not> affine_dependent(s - t)"
  1887 by (meson Diff_subset affine_dependent_subset)
  1888 
  1889 proposition affine_dependent_explicit:
  1890   "affine_dependent p \<longleftrightarrow>
  1891     (\<exists>S u. finite S \<and> S \<subseteq> p \<and> sum u S = 0 \<and> (\<exists>v\<in>S. u v \<noteq> 0) \<and> sum (\<lambda>v. u v *\<^sub>R v) S = 0)"
  1892 proof -
  1893   have "\<exists>S u. finite S \<and> S \<subseteq> p \<and> sum u S = 0 \<and> (\<exists>v\<in>S. u v \<noteq> 0) \<and> (\<Sum>w\<in>S. u w *\<^sub>R w) = 0"
  1894     if "(\<Sum>w\<in>S. u w *\<^sub>R w) = x" "x \<in> p" "finite S" "S \<noteq> {}" "S \<subseteq> p - {x}" "sum u S = 1" for x S u
  1895   proof (intro exI conjI)
  1896     have "x \<notin> S" 
  1897       using that by auto
  1898     then show "(\<Sum>v \<in> insert x S. if v = x then - 1 else u v) = 0"
  1899       using that by (simp add: sum_delta_notmem)
  1900     show "(\<Sum>w \<in> insert x S. (if w = x then - 1 else u w) *\<^sub>R w) = 0"
  1901       using that \<open>x \<notin> S\<close> by (simp add: if_smult sum_delta_notmem cong: if_cong)
  1902   qed (use that in auto)
  1903   moreover have "\<exists>x\<in>p. \<exists>S u. finite S \<and> S \<noteq> {} \<and> S \<subseteq> p - {x} \<and> sum u S = 1 \<and> (\<Sum>v\<in>S. u v *\<^sub>R v) = x"
  1904     if "(\<Sum>v\<in>S. u v *\<^sub>R v) = 0" "finite S" "S \<subseteq> p" "sum u S = 0" "v \<in> S" "u v \<noteq> 0" for S u v
  1905   proof (intro bexI exI conjI)
  1906     have "S \<noteq> {v}"
  1907       using that by auto
  1908     then show "S - {v} \<noteq> {}"
  1909       using that by auto
  1910     show "(\<Sum>x \<in> S - {v}. - (1 / u v) * u x) = 1"
  1911       unfolding sum_distrib_left[symmetric] sum_diff1[OF \<open>finite S\<close>] by (simp add: that)
  1912     show "(\<Sum>x\<in>S - {v}. (- (1 / u v) * u x) *\<^sub>R x) = v"
  1913       unfolding sum_distrib_left [symmetric] scaleR_scaleR[symmetric]
  1914                 scaleR_right.sum [symmetric] sum_diff1[OF \<open>finite S\<close>] 
  1915       using that by auto
  1916     show "S - {v} \<subseteq> p - {v}"
  1917       using that by auto
  1918   qed (use that in auto)
  1919   ultimately show ?thesis
  1920     unfolding affine_dependent_def affine_hull_explicit by auto
  1921 qed
  1922 
  1923 lemma affine_dependent_explicit_finite:
  1924   fixes S :: "'a::real_vector set"
  1925   assumes "finite S"
  1926   shows "affine_dependent S \<longleftrightarrow>
  1927     (\<exists>u. sum u S = 0 \<and> (\<exists>v\<in>S. u v \<noteq> 0) \<and> sum (\<lambda>v. u v *\<^sub>R v) S = 0)"
  1928   (is "?lhs = ?rhs")
  1929 proof
  1930   have *: "\<And>vt u v. (if vt then u v else 0) *\<^sub>R v = (if vt then (u v) *\<^sub>R v else 0::'a)"
  1931     by auto
  1932   assume ?lhs
  1933   then obtain t u v where
  1934     "finite t" "t \<subseteq> S" "sum u t = 0" "v\<in>t" "u v \<noteq> 0"  "(\<Sum>v\<in>t. u v *\<^sub>R v) = 0"
  1935     unfolding affine_dependent_explicit by auto
  1936   then show ?rhs
  1937     apply (rule_tac x="\<lambda>x. if x\<in>t then u x else 0" in exI)
  1938     apply (auto simp: * sum.inter_restrict[OF assms, symmetric] Int_absorb1[OF \<open>t\<subseteq>S\<close>])
  1939     done
  1940 next
  1941   assume ?rhs
  1942   then obtain u v where "sum u S = 0"  "v\<in>S" "u v \<noteq> 0" "(\<Sum>v\<in>S. u v *\<^sub>R v) = 0"
  1943     by auto
  1944   then show ?lhs unfolding affine_dependent_explicit
  1945     using assms by auto
  1946 qed
  1947 
  1948 
  1949 subsection%unimportant \<open>Connectedness of convex sets\<close>
  1950 
  1951 lemma connectedD:
  1952   "connected S \<Longrightarrow> open A \<Longrightarrow> open B \<Longrightarrow> S \<subseteq> A \<union> B \<Longrightarrow> A \<inter> B \<inter> S = {} \<Longrightarrow> A \<inter> S = {} \<or> B \<inter> S = {}"
  1953   by (rule Topological_Spaces.topological_space_class.connectedD)
  1954 
  1955 lemma convex_connected:
  1956   fixes S :: "'a::real_normed_vector set"
  1957   assumes "convex S"
  1958   shows "connected S"
  1959 proof (rule connectedI)
  1960   fix A B
  1961   assume "open A" "open B" "A \<inter> B \<inter> S = {}" "S \<subseteq> A \<union> B"
  1962   moreover
  1963   assume "A \<inter> S \<noteq> {}" "B \<inter> S \<noteq> {}"
  1964   then obtain a b where a: "a \<in> A" "a \<in> S" and b: "b \<in> B" "b \<in> S" by auto
  1965   define f where [abs_def]: "f u = u *\<^sub>R a + (1 - u) *\<^sub>R b" for u
  1966   then have "continuous_on {0 .. 1} f"
  1967     by (auto intro!: continuous_intros)
  1968   then have "connected (f ` {0 .. 1})"
  1969     by (auto intro!: connected_continuous_image)
  1970   note connectedD[OF this, of A B]
  1971   moreover have "a \<in> A \<inter> f ` {0 .. 1}"
  1972     using a by (auto intro!: image_eqI[of _ _ 1] simp: f_def)
  1973   moreover have "b \<in> B \<inter> f ` {0 .. 1}"
  1974     using b by (auto intro!: image_eqI[of _ _ 0] simp: f_def)
  1975   moreover have "f ` {0 .. 1} \<subseteq> S"
  1976     using \<open>convex S\<close> a b unfolding convex_def f_def by auto
  1977   ultimately show False by auto
  1978 qed
  1979 
  1980 corollary connected_UNIV[intro]: "connected (UNIV :: 'a::real_normed_vector set)"
  1981   by (simp add: convex_connected)
  1982 
  1983 lemma convex_prod:
  1984   assumes "\<And>i. i \<in> Basis \<Longrightarrow> convex {x. P i x}"
  1985   shows "convex {x. \<forall>i\<in>Basis. P i (x\<bullet>i)}"
  1986   using assms unfolding convex_def
  1987   by (auto simp: inner_add_left)
  1988 
  1989 lemma convex_positive_orthant: "convex {x::'a::euclidean_space. (\<forall>i\<in>Basis. 0 \<le> x\<bullet>i)}"
  1990   by (rule convex_prod) (simp add: atLeast_def[symmetric] convex_real_interval)
  1991 
  1992 subsection \<open>Convex hull\<close>
  1993 
  1994 lemma convex_convex_hull [iff]: "convex (convex hull s)"
  1995   unfolding hull_def
  1996   using convex_Inter[of "{t. convex t \<and> s \<subseteq> t}"]
  1997   by auto
  1998 
  1999 lemma convex_hull_subset:
  2000     "s \<subseteq> convex hull t \<Longrightarrow> convex hull s \<subseteq> convex hull t"
  2001   by (simp add: convex_convex_hull subset_hull)
  2002 
  2003 lemma convex_hull_eq: "convex hull s = s \<longleftrightarrow> convex s"
  2004   by (metis convex_convex_hull hull_same)
  2005 
  2006 subsubsection%unimportant \<open>Convex hull is "preserved" by a linear function\<close>
  2007 
  2008 lemma convex_hull_linear_image:
  2009   assumes f: "linear f"
  2010   shows "f ` (convex hull s) = convex hull (f ` s)"
  2011 proof
  2012   show "convex hull (f ` s) \<subseteq> f ` (convex hull s)"
  2013     by (intro hull_minimal image_mono hull_subset convex_linear_image assms convex_convex_hull)
  2014   show "f ` (convex hull s) \<subseteq> convex hull (f ` s)"
  2015   proof (unfold image_subset_iff_subset_vimage, rule hull_minimal)
  2016     show "s \<subseteq> f -` (convex hull (f ` s))"
  2017       by (fast intro: hull_inc)
  2018     show "convex (f -` (convex hull (f ` s)))"
  2019       by (intro convex_linear_vimage [OF f] convex_convex_hull)
  2020   qed
  2021 qed
  2022 
  2023 lemma in_convex_hull_linear_image:
  2024   assumes "linear f"
  2025     and "x \<in> convex hull s"
  2026   shows "f x \<in> convex hull (f ` s)"
  2027   using convex_hull_linear_image[OF assms(1)] assms(2) by auto
  2028 
  2029 lemma convex_hull_Times:
  2030   "convex hull (s \<times> t) = (convex hull s) \<times> (convex hull t)"
  2031 proof
  2032   show "convex hull (s \<times> t) \<subseteq> (convex hull s) \<times> (convex hull t)"
  2033     by (intro hull_minimal Sigma_mono hull_subset convex_Times convex_convex_hull)
  2034   have "(x, y) \<in> convex hull (s \<times> t)" if x: "x \<in> convex hull s" and y: "y \<in> convex hull t" for x y
  2035   proof (rule hull_induct [OF x], rule hull_induct [OF y])
  2036     fix x y assume "x \<in> s" and "y \<in> t"
  2037     then show "(x, y) \<in> convex hull (s \<times> t)"
  2038       by (simp add: hull_inc)
  2039   next
  2040     fix x let ?S = "((\<lambda>y. (0, y)) -` (\<lambda>p. (- x, 0) + p) ` (convex hull s \<times> t))"
  2041     have "convex ?S"
  2042       by (intro convex_linear_vimage convex_translation convex_convex_hull,
  2043         simp add: linear_iff)
  2044     also have "?S = {y. (x, y) \<in> convex hull (s \<times> t)}"
  2045       by (auto simp: image_def Bex_def)
  2046     finally show "convex {y. (x, y) \<in> convex hull (s \<times> t)}" .
  2047   next
  2048     show "convex {x. (x, y) \<in> convex hull s \<times> t}"
  2049     proof -
  2050       fix y let ?S = "((\<lambda>x. (x, 0)) -` (\<lambda>p. (0, - y) + p) ` (convex hull s \<times> t))"
  2051       have "convex ?S"
  2052       by (intro convex_linear_vimage convex_translation convex_convex_hull,
  2053         simp add: linear_iff)
  2054       also have "?S = {x. (x, y) \<in> convex hull (s \<times> t)}"
  2055         by (auto simp: image_def Bex_def)
  2056       finally show "convex {x. (x, y) \<in> convex hull (s \<times> t)}" .
  2057     qed
  2058   qed
  2059   then show "(convex hull s) \<times> (convex hull t) \<subseteq> convex hull (s \<times> t)"
  2060     unfolding subset_eq split_paired_Ball_Sigma by blast
  2061 qed
  2062 
  2063 
  2064 subsubsection%unimportant \<open>Stepping theorems for convex hulls of finite sets\<close>
  2065 
  2066 lemma convex_hull_empty[simp]: "convex hull {} = {}"
  2067   by (rule hull_unique) auto
  2068 
  2069 lemma convex_hull_singleton[simp]: "convex hull {a} = {a}"
  2070   by (rule hull_unique) auto
  2071 
  2072 lemma convex_hull_insert:
  2073   fixes S :: "'a::real_vector set"
  2074   assumes "S \<noteq> {}"
  2075   shows "convex hull (insert a S) =
  2076          {x. \<exists>u\<ge>0. \<exists>v\<ge>0. \<exists>b. (u + v = 1) \<and> b \<in> (convex hull S) \<and> (x = u *\<^sub>R a + v *\<^sub>R b)}"
  2077   (is "_ = ?hull")
  2078 proof (intro equalityI hull_minimal subsetI)
  2079   fix x
  2080   assume "x \<in> insert a S"
  2081   then have "\<exists>u\<ge>0. \<exists>v\<ge>0. u + v = 1 \<and> (\<exists>b. b \<in> convex hull S \<and> x = u *\<^sub>R a + v *\<^sub>R b)"
  2082   unfolding insert_iff
  2083   proof
  2084     assume "x = a"
  2085     then show ?thesis
  2086       by (rule_tac x=1 in exI) (use assms hull_subset in fastforce)
  2087   next
  2088     assume "x \<in> S"
  2089     with hull_subset[of S convex] show ?thesis
  2090       by force
  2091   qed
  2092   then show "x \<in> ?hull"
  2093     by simp
  2094 next
  2095   fix x
  2096   assume "x \<in> ?hull"
  2097   then obtain u v b where obt: "u\<ge>0" "v\<ge>0" "u + v = 1" "b \<in> convex hull S" "x = u *\<^sub>R a + v *\<^sub>R b"
  2098     by auto
  2099   have "a \<in> convex hull insert a S" "b \<in> convex hull insert a S"
  2100     using hull_mono[of S "insert a S" convex] hull_mono[of "{a}" "insert a S" convex] and obt(4)
  2101     by auto
  2102   then show "x \<in> convex hull insert a S"
  2103     unfolding obt(5) using obt(1-3)
  2104     by (rule convexD [OF convex_convex_hull])
  2105 next
  2106   show "convex ?hull"
  2107   proof (rule convexI)
  2108     fix x y u v
  2109     assume as: "(0::real) \<le> u" "0 \<le> v" "u + v = 1" and x: "x \<in> ?hull" and y: "y \<in> ?hull"
  2110     from x obtain u1 v1 b1 where
  2111       obt1: "u1\<ge>0" "v1\<ge>0" "u1 + v1 = 1" "b1 \<in> convex hull S" and xeq: "x = u1 *\<^sub>R a + v1 *\<^sub>R b1"
  2112       by auto
  2113     from y obtain u2 v2 b2 where
  2114       obt2: "u2\<ge>0" "v2\<ge>0" "u2 + v2 = 1" "b2 \<in> convex hull S" and yeq: "y = u2 *\<^sub>R a + v2 *\<^sub>R b2"
  2115       by auto
  2116     have *: "\<And>(x::'a) s1 s2. x - s1 *\<^sub>R x - s2 *\<^sub>R x = ((1::real) - (s1 + s2)) *\<^sub>R x"
  2117       by (auto simp: algebra_simps)
  2118     have "\<exists>b \<in> convex hull S. u *\<^sub>R x + v *\<^sub>R y =
  2119       (u * u1) *\<^sub>R a + (v * u2) *\<^sub>R a + (b - (u * u1) *\<^sub>R b - (v * u2) *\<^sub>R b)"
  2120     proof (cases "u * v1 + v * v2 = 0")
  2121       case True
  2122       have *: "\<And>(x::'a) s1 s2. x - s1 *\<^sub>R x - s2 *\<^sub>R x = ((1::real) - (s1 + s2)) *\<^sub>R x"
  2123         by (auto simp: algebra_simps)
  2124       have eq0: "u * v1 = 0" "v * v2 = 0"
  2125         using True mult_nonneg_nonneg[OF \<open>u\<ge>0\<close> \<open>v1\<ge>0\<close>] mult_nonneg_nonneg[OF \<open>v\<ge>0\<close> \<open>v2\<ge>0\<close>]
  2126         by arith+
  2127       then have "u * u1 + v * u2 = 1"
  2128         using as(3) obt1(3) obt2(3) by auto
  2129       then show ?thesis
  2130         using "*" eq0 as obt1(4) xeq yeq by auto
  2131     next
  2132       case False
  2133       have "1 - (u * u1 + v * u2) = (u + v) - (u * u1 + v * u2)"
  2134         using as(3) obt1(3) obt2(3) by (auto simp: field_simps)
  2135       also have "\<dots> = u * (v1 + u1 - u1) + v * (v2 + u2 - u2)"
  2136         using as(3) obt1(3) obt2(3) by (auto simp: field_simps)
  2137       also have "\<dots> = u * v1 + v * v2"
  2138         by simp
  2139       finally have **:"1 - (u * u1 + v * u2) = u * v1 + v * v2" by auto
  2140       let ?b = "((u * v1) / (u * v1 + v * v2)) *\<^sub>R b1 + ((v * v2) / (u * v1 + v * v2)) *\<^sub>R b2"
  2141       have zeroes: "0 \<le> u * v1 + v * v2" "0 \<le> u * v1" "0 \<le> u * v1 + v * v2" "0 \<le> v * v2"
  2142         using as(1,2) obt1(1,2) obt2(1,2) by auto
  2143       show ?thesis
  2144       proof
  2145         show "u *\<^sub>R x + v *\<^sub>R y = (u * u1) *\<^sub>R a + (v * u2) *\<^sub>R a + (?b - (u * u1) *\<^sub>R ?b - (v * u2) *\<^sub>R ?b)"
  2146           unfolding xeq yeq * **
  2147           using False by (auto simp: scaleR_left_distrib scaleR_right_distrib)
  2148         show "?b \<in> convex hull S"
  2149           using False zeroes obt1(4) obt2(4)
  2150           by (auto simp: convexD [OF convex_convex_hull] scaleR_left_distrib scaleR_right_distrib  add_divide_distrib[symmetric]  zero_le_divide_iff)
  2151       qed
  2152     qed
  2153     then obtain b where b: "b \<in> convex hull S" 
  2154        "u *\<^sub>R x + v *\<^sub>R y = (u * u1) *\<^sub>R a + (v * u2) *\<^sub>R a + (b - (u * u1) *\<^sub>R b - (v * u2) *\<^sub>R b)" ..
  2155 
  2156     have u1: "u1 \<le> 1"
  2157       unfolding obt1(3)[symmetric] and not_le using obt1(2) by auto
  2158     have u2: "u2 \<le> 1"
  2159       unfolding obt2(3)[symmetric] and not_le using obt2(2) by auto
  2160     have "u1 * u + u2 * v \<le> max u1 u2 * u + max u1 u2 * v"
  2161     proof (rule add_mono)
  2162       show "u1 * u \<le> max u1 u2 * u" "u2 * v \<le> max u1 u2 * v"
  2163         by (simp_all add: as mult_right_mono)
  2164     qed
  2165     also have "\<dots> \<le> 1"
  2166       unfolding distrib_left[symmetric] and as(3) using u1 u2 by auto
  2167     finally have le1: "u1 * u + u2 * v \<le> 1" .    
  2168     show "u *\<^sub>R x + v *\<^sub>R y \<in> ?hull"
  2169     proof (intro CollectI exI conjI)
  2170       show "0 \<le> u * u1 + v * u2"
  2171         by (simp add: as(1) as(2) obt1(1) obt2(1))
  2172       show "0 \<le> 1 - u * u1 - v * u2"
  2173         by (simp add: le1 diff_diff_add mult.commute)
  2174     qed (use b in \<open>auto simp: algebra_simps\<close>)
  2175   qed
  2176 qed
  2177 
  2178 lemma convex_hull_insert_alt:
  2179    "convex hull (insert a S) =
  2180      (if S = {} then {a}
  2181       else {(1 - u) *\<^sub>R a + u *\<^sub>R x |x u. 0 \<le> u \<and> u \<le> 1 \<and> x \<in> convex hull S})"
  2182   apply (auto simp: convex_hull_insert)
  2183   using diff_eq_eq apply fastforce
  2184   by (metis add.group_left_neutral add_le_imp_le_diff diff_add_cancel)
  2185 
  2186 subsubsection%unimportant \<open>Explicit expression for convex hull\<close>
  2187 
  2188 proposition convex_hull_indexed:
  2189   fixes S :: "'a::real_vector set"
  2190   shows "convex hull S =
  2191     {y. \<exists>k u x. (\<forall>i\<in>{1::nat .. k}. 0 \<le> u i \<and> x i \<in> S) \<and>
  2192                 (sum u {1..k} = 1) \<and> (\<Sum>i = 1..k. u i *\<^sub>R x i) = y}"
  2193     (is "?xyz = ?hull")
  2194 proof (rule hull_unique [OF _ convexI])
  2195   show "S \<subseteq> ?hull" 
  2196     by (clarsimp, rule_tac x=1 in exI, rule_tac x="\<lambda>x. 1" in exI, auto)
  2197 next
  2198   fix T
  2199   assume "S \<subseteq> T" "convex T"
  2200   then show "?hull \<subseteq> T"
  2201     by (blast intro: convex_sum)
  2202 next
  2203   fix x y u v
  2204   assume uv: "0 \<le> u" "0 \<le> v" "u + v = (1::real)"
  2205   assume xy: "x \<in> ?hull" "y \<in> ?hull"
  2206   from xy obtain k1 u1 x1 where
  2207     x [rule_format]: "\<forall>i\<in>{1::nat..k1}. 0\<le>u1 i \<and> x1 i \<in> S" 
  2208                       "sum u1 {Suc 0..k1} = 1" "(\<Sum>i = Suc 0..k1. u1 i *\<^sub>R x1 i) = x"
  2209     by auto
  2210   from xy obtain k2 u2 x2 where
  2211     y [rule_format]: "\<forall>i\<in>{1::nat..k2}. 0\<le>u2 i \<and> x2 i \<in> S" 
  2212                      "sum u2 {Suc 0..k2} = 1" "(\<Sum>i = Suc 0..k2. u2 i *\<^sub>R x2 i) = y"
  2213     by auto
  2214   have *: "\<And>P (x::'a) y s t i. (if P i then s else t) *\<^sub>R (if P i then x else y) = (if P i then s *\<^sub>R x else t *\<^sub>R y)"
  2215           "{1..k1 + k2} \<inter> {1..k1} = {1..k1}" "{1..k1 + k2} \<inter> - {1..k1} = (\<lambda>i. i + k1) ` {1..k2}"
  2216     by auto
  2217   have inj: "inj_on (\<lambda>i. i + k1) {1..k2}"
  2218     unfolding inj_on_def by auto
  2219   let ?uu = "\<lambda>i. if i \<in> {1..k1} then u * u1 i else v * u2 (i - k1)"
  2220   let ?xx = "\<lambda>i. if i \<in> {1..k1} then x1 i else x2 (i - k1)"
  2221   show "u *\<^sub>R x + v *\<^sub>R y \<in> ?hull"
  2222   proof (intro CollectI exI conjI ballI)
  2223     show "0 \<le> ?uu i" "?xx i \<in> S" if "i \<in> {1..k1+k2}" for i
  2224       using that by (auto simp add: le_diff_conv uv(1) x(1) uv(2) y(1))
  2225     show "(\<Sum>i = 1..k1 + k2. ?uu i) = 1"  "(\<Sum>i = 1..k1 + k2. ?uu i *\<^sub>R ?xx i) = u *\<^sub>R x + v *\<^sub>R y"
  2226       unfolding * sum.If_cases[OF finite_atLeastAtMost[of 1 "k1 + k2"]]
  2227         sum.reindex[OF inj] Collect_mem_eq o_def
  2228       unfolding scaleR_scaleR[symmetric] scaleR_right.sum [symmetric] sum_distrib_left[symmetric]
  2229       by (simp_all add: sum_distrib_left[symmetric]  x(2,3) y(2,3) uv(3))
  2230   qed 
  2231 qed
  2232 
  2233 lemma convex_hull_finite:
  2234   fixes S :: "'a::real_vector set"
  2235   assumes "finite S"
  2236   shows "convex hull S = {y. \<exists>u. (\<forall>x\<in>S. 0 \<le> u x) \<and> sum u S = 1 \<and> sum (\<lambda>x. u x *\<^sub>R x) S = y}"
  2237   (is "?HULL = _")
  2238 proof (rule hull_unique [OF _ convexI]; clarify)
  2239   fix x
  2240   assume "x \<in> S"
  2241   then show "\<exists>u. (\<forall>x\<in>S. 0 \<le> u x) \<and> sum u S = 1 \<and> (\<Sum>x\<in>S. u x *\<^sub>R x) = x"
  2242     by (rule_tac x="\<lambda>y. if x=y then 1 else 0" in exI) (auto simp: sum.delta'[OF assms] sum_delta''[OF assms])
  2243 next
  2244   fix u v :: real
  2245   assume uv: "0 \<le> u" "0 \<le> v" "u + v = 1"
  2246   fix ux assume ux [rule_format]: "\<forall>x\<in>S. 0 \<le> ux x" "sum ux S = (1::real)"
  2247   fix uy assume uy [rule_format]: "\<forall>x\<in>S. 0 \<le> uy x" "sum uy S = (1::real)"
  2248   have "0 \<le> u * ux x + v * uy x" if "x\<in>S" for x
  2249     by (simp add: that uv ux(1) uy(1))
  2250   moreover
  2251   have "(\<Sum>x\<in>S. u * ux x + v * uy x) = 1"
  2252     unfolding sum.distrib and sum_distrib_left[symmetric] ux(2) uy(2)
  2253     using uv(3) by auto
  2254   moreover
  2255   have "(\<Sum>x\<in>S. (u * ux x + v * uy x) *\<^sub>R x) = u *\<^sub>R (\<Sum>x\<in>S. ux x *\<^sub>R x) + v *\<^sub>R (\<Sum>x\<in>S. uy x *\<^sub>R x)"
  2256     unfolding scaleR_left_distrib sum.distrib scaleR_scaleR[symmetric] scaleR_right.sum [symmetric]
  2257     by auto
  2258   ultimately
  2259   show "\<exists>uc. (\<forall>x\<in>S. 0 \<le> uc x) \<and> sum uc S = 1 \<and>
  2260              (\<Sum>x\<in>S. uc x *\<^sub>R x) = u *\<^sub>R (\<Sum>x\<in>S. ux x *\<^sub>R x) + v *\<^sub>R (\<Sum>x\<in>S. uy x *\<^sub>R x)"
  2261     by (rule_tac x="\<lambda>x. u * ux x + v * uy x" in exI, auto)
  2262 qed (use assms in \<open>auto simp: convex_explicit\<close>)
  2263 
  2264 
  2265 subsubsection%unimportant \<open>Another formulation\<close>
  2266 
  2267 text "Formalized by Lars Schewe."
  2268 
  2269 lemma convex_hull_explicit:
  2270   fixes p :: "'a::real_vector set"
  2271   shows "convex hull p =
  2272     {y. \<exists>S u. finite S \<and> S \<subseteq> p \<and> (\<forall>x\<in>S. 0 \<le> u x) \<and> sum u S = 1 \<and> sum (\<lambda>v. u v *\<^sub>R v) S = y}"
  2273   (is "?lhs = ?rhs")
  2274 proof -
  2275   {
  2276     fix x
  2277     assume "x\<in>?lhs"
  2278     then obtain k u y where
  2279         obt: "\<forall>i\<in>{1::nat..k}. 0 \<le> u i \<and> y i \<in> p" "sum u {1..k} = 1" "(\<Sum>i = 1..k. u i *\<^sub>R y i) = x"
  2280       unfolding convex_hull_indexed by auto
  2281 
  2282     have fin: "finite {1..k}" by auto
  2283     have fin': "\<And>v. finite {i \<in> {1..k}. y i = v}" by auto
  2284     {
  2285       fix j
  2286       assume "j\<in>{1..k}"
  2287       then have "y j \<in> p" "0 \<le> sum u {i. Suc 0 \<le> i \<and> i \<le> k \<and> y i = y j}"
  2288         using obt(1)[THEN bspec[where x=j]] and obt(2)
  2289         apply simp
  2290         apply (rule sum_nonneg)
  2291         using obt(1)
  2292         apply auto
  2293         done
  2294     }
  2295     moreover
  2296     have "(\<Sum>v\<in>y ` {1..k}. sum u {i \<in> {1..k}. y i = v}) = 1"
  2297       unfolding sum.image_gen[OF fin, symmetric] using obt(2) by auto
  2298     moreover have "(\<Sum>v\<in>y ` {1..k}. sum u {i \<in> {1..k}. y i = v} *\<^sub>R v) = x"
  2299       using sum.image_gen[OF fin, of "\<lambda>i. u i *\<^sub>R y i" y, symmetric]
  2300       unfolding scaleR_left.sum using obt(3) by auto
  2301     ultimately
  2302     have "\<exists>S u. finite S \<and> S \<subseteq> p \<and> (\<forall>x\<in>S. 0 \<le> u x) \<and> sum u S = 1 \<and> (\<Sum>v\<in>S. u v *\<^sub>R v) = x"
  2303       apply (rule_tac x="y ` {1..k}" in exI)
  2304       apply (rule_tac x="\<lambda>v. sum u {i\<in>{1..k}. y i = v}" in exI, auto)
  2305       done
  2306     then have "x\<in>?rhs" by auto
  2307   }
  2308   moreover
  2309   {
  2310     fix y
  2311     assume "y\<in>?rhs"
  2312     then obtain S u where
  2313       obt: "finite S" "S \<subseteq> p" "\<forall>x\<in>S. 0 \<le> u x" "sum u S = 1" "(\<Sum>v\<in>S. u v *\<^sub>R v) = y"
  2314       by auto
  2315 
  2316     obtain f where f: "inj_on f {1..card S}" "f ` {1..card S} = S"
  2317       using ex_bij_betw_nat_finite_1[OF obt(1)] unfolding bij_betw_def by auto
  2318 
  2319     {
  2320       fix i :: nat
  2321       assume "i\<in>{1..card S}"
  2322       then have "f i \<in> S"
  2323         using f(2) by blast
  2324       then have "0 \<le> u (f i)" "f i \<in> p" using obt(2,3) by auto
  2325     }
  2326     moreover have *: "finite {1..card S}" by auto
  2327     {
  2328       fix y
  2329       assume "y\<in>S"
  2330       then obtain i where "i\<in>{1..card S}" "f i = y"
  2331         using f using image_iff[of y f "{1..card S}"]
  2332         by auto
  2333       then have "{x. Suc 0 \<le> x \<and> x \<le> card S \<and> f x = y} = {i}"
  2334         apply auto
  2335         using f(1)[unfolded inj_on_def]
  2336         by (metis One_nat_def atLeastAtMost_iff)
  2337       then have "card {x. Suc 0 \<le> x \<and> x \<le> card S \<and> f x = y} = 1" by auto
  2338       then have "(\<Sum>x\<in>{x \<in> {1..card S}. f x = y}. u (f x)) = u y"
  2339           "(\<Sum>x\<in>{x \<in> {1..card S}. f x = y}. u (f x) *\<^sub>R f x) = u y *\<^sub>R y"
  2340         by (auto simp: sum_constant_scaleR)
  2341     }
  2342     then have "(\<Sum>x = 1..card S. u (f x)) = 1" "(\<Sum>i = 1..card S. u (f i) *\<^sub>R f i) = y"
  2343       unfolding sum.image_gen[OF *(1), of "\<lambda>x. u (f x) *\<^sub>R f x" f]
  2344         and sum.image_gen[OF *(1), of "\<lambda>x. u (f x)" f]
  2345       unfolding f
  2346       using sum.cong [of S S "\<lambda>y. (\<Sum>x\<in>{x \<in> {1..card S}. f x = y}. u (f x) *\<^sub>R f x)" "\<lambda>v. u v *\<^sub>R v"]
  2347       using sum.cong [of S S "\<lambda>y. (\<Sum>x\<in>{x \<in> {1..card S}. f x = y}. u (f x))" u]
  2348       unfolding obt(4,5)
  2349       by auto
  2350     ultimately
  2351     have "\<exists>k u x. (\<forall>i\<in>{1..k}. 0 \<le> u i \<and> x i \<in> p) \<and> sum u {1..k} = 1 \<and>
  2352         (\<Sum>i::nat = 1..k. u i *\<^sub>R x i) = y"
  2353       apply (rule_tac x="card S" in exI)
  2354       apply (rule_tac x="u \<circ> f" in exI)
  2355       apply (rule_tac x=f in exI, fastforce)
  2356       done
  2357     then have "y \<in> ?lhs"
  2358       unfolding convex_hull_indexed by auto
  2359   }
  2360   ultimately show ?thesis
  2361     unfolding set_eq_iff by blast
  2362 qed
  2363 
  2364 
  2365 subsubsection%unimportant \<open>A stepping theorem for that expansion\<close>
  2366 
  2367 lemma convex_hull_finite_step:
  2368   fixes S :: "'a::real_vector set"
  2369   assumes "finite S"
  2370   shows
  2371     "(\<exists>u. (\<forall>x\<in>insert a S. 0 \<le> u x) \<and> sum u (insert a S) = w \<and> sum (\<lambda>x. u x *\<^sub>R x) (insert a S) = y)
  2372       \<longleftrightarrow> (\<exists>v\<ge>0. \<exists>u. (\<forall>x\<in>S. 0 \<le> u x) \<and> sum u S = w - v \<and> sum (\<lambda>x. u x *\<^sub>R x) S = y - v *\<^sub>R a)"
  2373   (is "?lhs = ?rhs")
  2374 proof (rule, case_tac[!] "a\<in>S")
  2375   assume "a \<in> S"
  2376   then have *: "insert a S = S" by auto
  2377   assume ?lhs
  2378   then show ?rhs
  2379     unfolding *  by (rule_tac x=0 in exI, auto)
  2380 next
  2381   assume ?lhs
  2382   then obtain u where
  2383       u: "\<forall>x\<in>insert a S. 0 \<le> u x" "sum u (insert a S) = w" "(\<Sum>x\<in>insert a S. u x *\<^sub>R x) = y"
  2384     by auto
  2385   assume "a \<notin> S"
  2386   then show ?rhs
  2387     apply (rule_tac x="u a" in exI)
  2388     using u(1)[THEN bspec[where x=a]]
  2389     apply simp
  2390     apply (rule_tac x=u in exI)
  2391     using u[unfolded sum_clauses(2)[OF assms]] and \<open>a\<notin>S\<close>
  2392     apply auto
  2393     done
  2394 next
  2395   assume "a \<in> S"
  2396   then have *: "insert a S = S" by auto
  2397   have fin: "finite (insert a S)" using assms by auto
  2398   assume ?rhs
  2399   then obtain v u where uv: "v\<ge>0" "\<forall>x\<in>S. 0 \<le> u x" "sum u S = w - v" "(\<Sum>x\<in>S. u x *\<^sub>R x) = y - v *\<^sub>R a"
  2400     by auto
  2401   show ?lhs
  2402     apply (rule_tac x = "\<lambda>x. (if a = x then v else 0) + u x" in exI)
  2403     unfolding scaleR_left_distrib and sum.distrib and sum_delta''[OF fin] and sum.delta'[OF fin]
  2404     unfolding sum_clauses(2)[OF assms]
  2405     using uv and uv(2)[THEN bspec[where x=a]] and \<open>a\<in>S\<close>
  2406     apply auto
  2407     done
  2408 next
  2409   assume ?rhs
  2410   then obtain v u where uv: "v\<ge>0" "\<forall>x\<in>S. 0 \<le> u x" "sum u S = w - v" "(\<Sum>x\<in>S. u x *\<^sub>R x) = y - v *\<^sub>R a"
  2411     by auto
  2412   moreover assume "a \<notin> S"
  2413   moreover
  2414   have "(\<Sum>x\<in>S. if a = x then v else u x) = sum u S"  "(\<Sum>x\<in>S. (if a = x then v else u x) *\<^sub>R x) = (\<Sum>x\<in>S. u x *\<^sub>R x)"
  2415     using \<open>a \<notin> S\<close>
  2416     by (auto simp: intro!: sum.cong)
  2417   ultimately show ?lhs
  2418     by (rule_tac x="\<lambda>x. if a = x then v else u x" in exI) (auto simp: sum_clauses(2)[OF assms])
  2419 qed
  2420 
  2421 
  2422 subsubsection%unimportant \<open>Hence some special cases\<close>
  2423 
  2424 lemma convex_hull_2:
  2425   "convex hull {a,b} = {u *\<^sub>R a + v *\<^sub>R b | u v. 0 \<le> u \<and> 0 \<le> v \<and> u + v = 1}"
  2426 proof -
  2427   have *: "\<And>u. (\<forall>x\<in>{a, b}. 0 \<le> u x) \<longleftrightarrow> 0 \<le> u a \<and> 0 \<le> u b"
  2428     by auto
  2429   have **: "finite {b}" by auto
  2430   show ?thesis
  2431     apply (simp add: convex_hull_finite)
  2432     unfolding convex_hull_finite_step[OF **, of a 1, unfolded * conj_assoc]
  2433     apply auto
  2434     apply (rule_tac x=v in exI)
  2435     apply (rule_tac x="1 - v" in exI, simp)
  2436     apply (rule_tac x=u in exI, simp)
  2437     apply (rule_tac x="\<lambda>x. v" in exI, simp)
  2438     done
  2439 qed
  2440 
  2441 lemma convex_hull_2_alt: "convex hull {a,b} = {a + u *\<^sub>R (b - a) | u.  0 \<le> u \<and> u \<le> 1}"
  2442   unfolding convex_hull_2
  2443 proof (rule Collect_cong)
  2444   have *: "\<And>x y ::real. x + y = 1 \<longleftrightarrow> x = 1 - y"
  2445     by auto
  2446   fix x
  2447   show "(\<exists>v u. x = v *\<^sub>R a + u *\<^sub>R b \<and> 0 \<le> v \<and> 0 \<le> u \<and> v + u = 1) \<longleftrightarrow>
  2448     (\<exists>u. x = a + u *\<^sub>R (b - a) \<and> 0 \<le> u \<and> u \<le> 1)"
  2449     unfolding *
  2450     apply auto
  2451     apply (rule_tac[!] x=u in exI)
  2452     apply (auto simp: algebra_simps)
  2453     done
  2454 qed
  2455 
  2456 lemma convex_hull_3:
  2457   "convex hull {a,b,c} = { u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c | u v w. 0 \<le> u \<and> 0 \<le> v \<and> 0 \<le> w \<and> u + v + w = 1}"
  2458 proof -
  2459   have fin: "finite {a,b,c}" "finite {b,c}" "finite {c}"
  2460     by auto
  2461   have *: "\<And>x y z ::real. x + y + z = 1 \<longleftrightarrow> x = 1 - y - z"
  2462     by (auto simp: field_simps)
  2463   show ?thesis
  2464     unfolding convex_hull_finite[OF fin(1)] and convex_hull_finite_step[OF fin(2)] and *
  2465     unfolding convex_hull_finite_step[OF fin(3)]
  2466     apply (rule Collect_cong, simp)
  2467     apply auto
  2468     apply (rule_tac x=va in exI)
  2469     apply (rule_tac x="u c" in exI, simp)
  2470     apply (rule_tac x="1 - v - w" in exI, simp)
  2471     apply (rule_tac x=v in exI, simp)
  2472     apply (rule_tac x="\<lambda>x. w" in exI, simp)
  2473     done
  2474 qed
  2475 
  2476 lemma convex_hull_3_alt:
  2477   "convex hull {a,b,c} = {a + u *\<^sub>R (b - a) + v *\<^sub>R (c - a) | u v.  0 \<le> u \<and> 0 \<le> v \<and> u + v \<le> 1}"
  2478 proof -
  2479   have *: "\<And>x y z ::real. x + y + z = 1 \<longleftrightarrow> x = 1 - y - z"
  2480     by auto
  2481   show ?thesis
  2482     unfolding convex_hull_3
  2483     apply (auto simp: *)
  2484     apply (rule_tac x=v in exI)
  2485     apply (rule_tac x=w in exI)
  2486     apply (simp add: algebra_simps)
  2487     apply (rule_tac x=u in exI)
  2488     apply (rule_tac x=v in exI)
  2489     apply (simp add: algebra_simps)
  2490     done
  2491 qed
  2492 
  2493 
  2494 subsection%unimportant \<open>Relations among closure notions and corresponding hulls\<close>
  2495 
  2496 lemma affine_imp_convex: "affine s \<Longrightarrow> convex s"
  2497   unfolding affine_def convex_def by auto
  2498 
  2499 lemma convex_affine_hull [simp]: "convex (affine hull S)"
  2500   by (simp add: affine_imp_convex)
  2501 
  2502 lemma subspace_imp_convex: "subspace s \<Longrightarrow> convex s"
  2503   using subspace_imp_affine affine_imp_convex by auto
  2504 
  2505 lemma affine_hull_subset_span: "(affine hull s) \<subseteq> (span s)"
  2506   by (metis hull_minimal span_superset subspace_imp_affine subspace_span)
  2507 
  2508 lemma convex_hull_subset_span: "(convex hull s) \<subseteq> (span s)"
  2509   by (metis hull_minimal span_superset subspace_imp_convex subspace_span)
  2510 
  2511 lemma convex_hull_subset_affine_hull: "(convex hull s) \<subseteq> (affine hull s)"
  2512   by (metis affine_affine_hull affine_imp_convex hull_minimal hull_subset)
  2513 
  2514 lemma affine_dependent_imp_dependent: "affine_dependent s \<Longrightarrow> dependent s"
  2515   unfolding affine_dependent_def dependent_def
  2516   using affine_hull_subset_span by auto
  2517 
  2518 lemma dependent_imp_affine_dependent:
  2519   assumes "dependent {x - a| x . x \<in> s}"
  2520     and "a \<notin> s"
  2521   shows "affine_dependent (insert a s)"
  2522 proof -
  2523   from assms(1)[unfolded dependent_explicit] obtain S u v
  2524     where obt: "finite S" "S \<subseteq> {x - a |x. x \<in> s}" "v\<in>S" "u v  \<noteq> 0" "(\<Sum>v\<in>S. u v *\<^sub>R v) = 0"
  2525     by auto
  2526   define t where "t = (\<lambda>x. x + a) ` S"
  2527 
  2528   have inj: "inj_on (\<lambda>x. x + a) S"
  2529     unfolding inj_on_def by auto
  2530   have "0 \<notin> S"
  2531     using obt(2) assms(2) unfolding subset_eq by auto
  2532   have fin: "finite t" and "t \<subseteq> s"
  2533     unfolding t_def using obt(1,2) by auto
  2534   then have "finite (insert a t)" and "insert a t \<subseteq> insert a s"
  2535     by auto
  2536   moreover have *: "\<And>P Q. (\<Sum>x\<in>t. (if x = a then P x else Q x)) = (\<Sum>x\<in>t. Q x)"
  2537     apply (rule sum.cong)
  2538     using \<open>a\<notin>s\<close> \<open>t\<subseteq>s\<close>
  2539     apply auto
  2540     done
  2541   have "(\<Sum>x\<in>insert a t. if x = a then - (\<Sum>x\<in>t. u (x - a)) else u (x - a)) = 0"
  2542     unfolding sum_clauses(2)[OF fin] * using \<open>a\<notin>s\<close> \<open>t\<subseteq>s\<close> by auto
  2543   moreover have "\<exists>v\<in>insert a t. (if v = a then - (\<Sum>x\<in>t. u (x - a)) else u (v - a)) \<noteq> 0"
  2544     using obt(3,4) \<open>0\<notin>S\<close>
  2545     by (rule_tac x="v + a" in bexI) (auto simp: t_def)
  2546   moreover have *: "\<And>P Q. (\<Sum>x\<in>t. (if x = a then P x else Q x) *\<^sub>R x) = (\<Sum>x\<in>t. Q x *\<^sub>R x)"
  2547     using \<open>a\<notin>s\<close> \<open>t\<subseteq>s\<close> by (auto intro!: sum.cong)
  2548   have "(\<Sum>x\<in>t. u (x - a)) *\<^sub>R a = (\<Sum>v\<in>t. u (v - a) *\<^sub>R v)"
  2549     unfolding scaleR_left.sum
  2550     unfolding t_def and sum.reindex[OF inj] and o_def
  2551     using obt(5)
  2552     by (auto simp: sum.distrib scaleR_right_distrib)
  2553   then have "(\<Sum>v\<in>insert a t. (if v = a then - (\<Sum>x\<in>t. u (x - a)) else u (v - a)) *\<^sub>R v) = 0"
  2554     unfolding sum_clauses(2)[OF fin]
  2555     using \<open>a\<notin>s\<close> \<open>t\<subseteq>s\<close>
  2556     by (auto simp: *)
  2557   ultimately show ?thesis
  2558     unfolding affine_dependent_explicit
  2559     apply (rule_tac x="insert a t" in exI, auto)
  2560     done
  2561 qed
  2562 
  2563 lemma convex_cone:
  2564   "convex s \<and> cone s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. (x + y) \<in> s) \<and> (\<forall>x\<in>s. \<forall>c\<ge>0. (c *\<^sub>R x) \<in> s)"
  2565   (is "?lhs = ?rhs")
  2566 proof -
  2567   {
  2568     fix x y
  2569     assume "x\<in>s" "y\<in>s" and ?lhs
  2570     then have "2 *\<^sub>R x \<in>s" "2 *\<^sub>R y \<in> s"
  2571       unfolding cone_def by auto
  2572     then have "x + y \<in> s"
  2573       using \<open>?lhs\<close>[unfolded convex_def, THEN conjunct1]
  2574       apply (erule_tac x="2*\<^sub>R x" in ballE)
  2575       apply (erule_tac x="2*\<^sub>R y" in ballE)
  2576       apply (erule_tac x="1/2" in allE, simp)
  2577       apply (erule_tac x="1/2" in allE, auto)
  2578       done
  2579   }
  2580   then show ?thesis
  2581     unfolding convex_def cone_def by blast
  2582 qed
  2583 
  2584 lemma affine_dependent_biggerset:
  2585   fixes s :: "'a::euclidean_space set"
  2586   assumes "finite s" "card s \<ge> DIM('a) + 2"
  2587   shows "affine_dependent s"
  2588 proof -
  2589   have "s \<noteq> {}" using assms by auto
  2590   then obtain a where "a\<in>s" by auto
  2591   have *: "{x - a |x. x \<in> s - {a}} = (\<lambda>x. x - a) ` (s - {a})"
  2592     by auto
  2593   have "card {x - a |x. x \<in> s - {a}} = card (s - {a})"
  2594     unfolding * by (simp add: card_image inj_on_def)
  2595   also have "\<dots> > DIM('a)" using assms(2)
  2596     unfolding card_Diff_singleton[OF assms(1) \<open>a\<in>s\<close>] by auto
  2597   finally show ?thesis
  2598     apply (subst insert_Diff[OF \<open>a\<in>s\<close>, symmetric])
  2599     apply (rule dependent_imp_affine_dependent)
  2600     apply (rule dependent_biggerset, auto)
  2601     done
  2602 qed
  2603 
  2604 lemma affine_dependent_biggerset_general:
  2605   assumes "finite (S :: 'a::euclidean_space set)"
  2606     and "card S \<ge> dim S + 2"
  2607   shows "affine_dependent S"
  2608 proof -
  2609   from assms(2) have "S \<noteq> {}" by auto
  2610   then obtain a where "a\<in>S" by auto
  2611   have *: "{x - a |x. x \<in> S - {a}} = (\<lambda>x. x - a) ` (S - {a})"
  2612     by auto
  2613   have **: "card {x - a |x. x \<in> S - {a}} = card (S - {a})"
  2614     by (metis (no_types, lifting) "*" card_image diff_add_cancel inj_on_def)
  2615   have "dim {x - a |x. x \<in> S - {a}} \<le> dim S"
  2616     using \<open>a\<in>S\<close> by (auto simp: span_base span_diff intro: subset_le_dim)
  2617   also have "\<dots> < dim S + 1" by auto
  2618   also have "\<dots> \<le> card (S - {a})"
  2619     using assms
  2620     using card_Diff_singleton[OF assms(1) \<open>a\<in>S\<close>]
  2621     by auto
  2622   finally show ?thesis
  2623     apply (subst insert_Diff[OF \<open>a\<in>S\<close>, symmetric])
  2624     apply (rule dependent_imp_affine_dependent)
  2625     apply (rule dependent_biggerset_general)
  2626     unfolding **
  2627     apply auto
  2628     done
  2629 qed
  2630 
  2631 
  2632 subsection%unimportant \<open>Some Properties of Affine Dependent Sets\<close>
  2633 
  2634 lemma affine_independent_0 [simp]: "\<not> affine_dependent {}"
  2635   by (simp add: affine_dependent_def)
  2636 
  2637 lemma affine_independent_1 [simp]: "\<not> affine_dependent {a}"
  2638   by (simp add: affine_dependent_def)
  2639 
  2640 lemma affine_independent_2 [simp]: "\<not> affine_dependent {a,b}"
  2641   by (simp add: affine_dependent_def insert_Diff_if hull_same)
  2642 
  2643 lemma affine_hull_translation: "affine hull ((\<lambda>x. a + x) `  S) = (\<lambda>x. a + x) ` (affine hull S)"
  2644 proof -
  2645   have "affine ((\<lambda>x. a + x) ` (affine hull S))"
  2646     using affine_translation affine_affine_hull by blast
  2647   moreover have "(\<lambda>x. a + x) `  S \<subseteq> (\<lambda>x. a + x) ` (affine hull S)"
  2648     using hull_subset[of S] by auto
  2649   ultimately have h1: "affine hull ((\<lambda>x. a + x) `  S) \<subseteq> (\<lambda>x. a + x) ` (affine hull S)"
  2650     by (metis hull_minimal)
  2651   have "affine((\<lambda>x. -a + x) ` (affine hull ((\<lambda>x. a + x) `  S)))"
  2652     using affine_translation affine_affine_hull by blast
  2653   moreover have "(\<lambda>x. -a + x) ` (\<lambda>x. a + x) `  S \<subseteq> (\<lambda>x. -a + x) ` (affine hull ((\<lambda>x. a + x) `  S))"
  2654     using hull_subset[of "(\<lambda>x. a + x) `  S"] by auto
  2655   moreover have "S = (\<lambda>x. -a + x) ` (\<lambda>x. a + x) `  S"
  2656     using translation_assoc[of "-a" a] by auto
  2657   ultimately have "(\<lambda>x. -a + x) ` (affine hull ((\<lambda>x. a + x) `  S)) >= (affine hull S)"
  2658     by (metis hull_minimal)
  2659   then have "affine hull ((\<lambda>x. a + x) ` S) >= (\<lambda>x. a + x) ` (affine hull S)"
  2660     by auto
  2661   then show ?thesis using h1 by auto
  2662 qed
  2663 
  2664 lemma affine_dependent_translation:
  2665   assumes "affine_dependent S"
  2666   shows "affine_dependent ((\<lambda>x. a + x) ` S)"
  2667 proof -
  2668   obtain x where x: "x \<in> S \<and> x \<in> affine hull (S - {x})"
  2669     using assms affine_dependent_def by auto
  2670   have "(+) a ` (S - {x}) = (+) a ` S - {a + x}"
  2671     by auto
  2672   then have "a + x \<in> affine hull ((\<lambda>x. a + x) ` S - {a + x})"
  2673     using affine_hull_translation[of a "S - {x}"] x by auto
  2674   moreover have "a + x \<in> (\<lambda>x. a + x) ` S"
  2675     using x by auto
  2676   ultimately show ?thesis
  2677     unfolding affine_dependent_def by auto
  2678 qed
  2679 
  2680 lemma affine_dependent_translation_eq:
  2681   "affine_dependent S \<longleftrightarrow> affine_dependent ((\<lambda>x. a + x) ` S)"
  2682 proof -
  2683   {
  2684     assume "affine_dependent ((\<lambda>x. a + x) ` S)"
  2685     then have "affine_dependent S"
  2686       using affine_dependent_translation[of "((\<lambda>x. a + x) ` S)" "-a"] translation_assoc[of "-a" a]
  2687       by auto
  2688   }
  2689   then show ?thesis
  2690     using affine_dependent_translation by auto
  2691 qed
  2692 
  2693 lemma affine_hull_0_dependent:
  2694   assumes "0 \<in> affine hull S"
  2695   shows "dependent S"
  2696 proof -
  2697   obtain s u where s_u: "finite s \<and> s \<noteq> {} \<and> s \<subseteq> S \<and> sum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = 0"
  2698     using assms affine_hull_explicit[of S] by auto
  2699   then have "\<exists>v\<in>s. u v \<noteq> 0"
  2700     using sum_not_0[of "u" "s"] by auto
  2701   then have "finite s \<and> s \<subseteq> S \<and> (\<exists>v\<in>s. u v \<noteq> 0 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = 0)"
  2702     using s_u by auto
  2703   then show ?thesis
  2704     unfolding dependent_explicit[of S] by auto
  2705 qed
  2706 
  2707 lemma affine_dependent_imp_dependent2:
  2708   assumes "affine_dependent (insert 0 S)"
  2709   shows "dependent S"
  2710 proof -
  2711   obtain x where x: "x \<in> insert 0 S \<and> x \<in> affine hull (insert 0 S - {x})"
  2712     using affine_dependent_def[of "(insert 0 S)"] assms by blast
  2713   then have "x \<in> span (insert 0 S - {x})"
  2714     using affine_hull_subset_span by auto
  2715   moreover have "span (insert 0 S - {x}) = span (S - {x})"
  2716     using insert_Diff_if[of "0" S "{x}"] span_insert_0[of "S-{x}"] by auto
  2717   ultimately have "x \<in> span (S - {x})" by auto
  2718   then have "x \<noteq> 0 \<Longrightarrow> dependent S"
  2719     using x dependent_def by auto
  2720   moreover
  2721   {
  2722     assume "x = 0"
  2723     then have "0 \<in> affine hull S"
  2724       using x hull_mono[of "S - {0}" S] by auto
  2725     then have "dependent S"
  2726       using affine_hull_0_dependent by auto
  2727   }
  2728   ultimately show ?thesis by auto
  2729 qed
  2730 
  2731 lemma affine_dependent_iff_dependent:
  2732   assumes "a \<notin> S"
  2733   shows "affine_dependent (insert a S) \<longleftrightarrow> dependent ((\<lambda>x. -a + x) ` S)"
  2734 proof -
  2735   have "((+) (- a) ` S) = {x - a| x . x \<in> S}" by auto
  2736   then show ?thesis
  2737     using affine_dependent_translation_eq[of "(insert a S)" "-a"]
  2738       affine_dependent_imp_dependent2 assms
  2739       dependent_imp_affine_dependent[of a S]
  2740     by (auto simp del: uminus_add_conv_diff)
  2741 qed
  2742 
  2743 lemma affine_dependent_iff_dependent2:
  2744   assumes "a \<in> S"
  2745   shows "affine_dependent S \<longleftrightarrow> dependent ((\<lambda>x. -a + x) ` (S-{a}))"
  2746 proof -
  2747   have "insert a (S - {a}) = S"
  2748     using assms by auto
  2749   then show ?thesis
  2750     using assms affine_dependent_iff_dependent[of a "S-{a}"] by auto
  2751 qed
  2752 
  2753 lemma affine_hull_insert_span_gen:
  2754   "affine hull (insert a s) = (\<lambda>x. a + x) ` span ((\<lambda>x. - a + x) ` s)"
  2755 proof -
  2756   have h1: "{x - a |x. x \<in> s} = ((\<lambda>x. -a+x) ` s)"
  2757     by auto
  2758   {
  2759     assume "a \<notin> s"
  2760     then have ?thesis
  2761       using affine_hull_insert_span[of a s] h1 by auto
  2762   }
  2763   moreover
  2764   {
  2765     assume a1: "a \<in> s"
  2766     have "\<exists>x. x \<in> s \<and> -a+x=0"
  2767       apply (rule exI[of _ a])
  2768       using a1
  2769       apply auto
  2770       done
  2771     then have "insert 0 ((\<lambda>x. -a+x) ` (s - {a})) = (\<lambda>x. -a+x) ` s"
  2772       by auto
  2773     then have "span ((\<lambda>x. -a+x) ` (s - {a}))=span ((\<lambda>x. -a+x) ` s)"
  2774       using span_insert_0[of "(+) (- a) ` (s - {a})"] by (auto simp del: uminus_add_conv_diff)
  2775     moreover have "{x - a |x. x \<in> (s - {a})} = ((\<lambda>x. -a+x) ` (s - {a}))"
  2776       by auto
  2777     moreover have "insert a (s - {a}) = insert a s"
  2778       by auto
  2779     ultimately have ?thesis
  2780       using affine_hull_insert_span[of "a" "s-{a}"] by auto
  2781   }
  2782   ultimately show ?thesis by auto
  2783 qed
  2784 
  2785 lemma affine_hull_span2:
  2786   assumes "a \<in> s"
  2787   shows "affine hull s = (\<lambda>x. a+x) ` span ((\<lambda>x. -a+x) ` (s-{a}))"
  2788   using affine_hull_insert_span_gen[of a "s - {a}", unfolded insert_Diff[OF assms]]
  2789   by auto
  2790 
  2791 lemma affine_hull_span_gen:
  2792   assumes "a \<in> affine hull s"
  2793   shows "affine hull s = (\<lambda>x. a+x) ` span ((\<lambda>x. -a+x) ` s)"
  2794 proof -
  2795   have "affine hull (insert a s) = affine hull s"
  2796     using hull_redundant[of a affine s] assms by auto
  2797   then show ?thesis
  2798     using affine_hull_insert_span_gen[of a "s"] by auto
  2799 qed
  2800 
  2801 lemma affine_hull_span_0:
  2802   assumes "0 \<in> affine hull S"
  2803   shows "affine hull S = span S"
  2804   using affine_hull_span_gen[of "0" S] assms by auto
  2805 
  2806 lemma extend_to_affine_basis_nonempty:
  2807   fixes S V :: "'n::euclidean_space set"
  2808   assumes "\<not> affine_dependent S" "S \<subseteq> V" "S \<noteq> {}"
  2809   shows "\<exists>T. \<not> affine_dependent T \<and> S \<subseteq> T \<and> T \<subseteq> V \<and> affine hull T = affine hull V"
  2810 proof -
  2811   obtain a where a: "a \<in> S"
  2812     using assms by auto
  2813   then have h0: "independent  ((\<lambda>x. -a + x) ` (S-{a}))"
  2814     using affine_dependent_iff_dependent2 assms by auto
  2815   obtain B where B:
  2816     "(\<lambda>x. -a+x) ` (S - {a}) \<subseteq> B \<and> B \<subseteq> (\<lambda>x. -a+x) ` V \<and> independent B \<and> (\<lambda>x. -a+x) ` V \<subseteq> span B"
  2817     using assms
  2818     by (blast intro: maximal_independent_subset_extend[OF _ h0, of "(\<lambda>x. -a + x) ` V"])
  2819   define T where "T = (\<lambda>x. a+x) ` insert 0 B"
  2820   then have "T = insert a ((\<lambda>x. a+x) ` B)"
  2821     by auto
  2822   then have "affine hull T = (\<lambda>x. a+x) ` span B"
  2823     using affine_hull_insert_span_gen[of a "((\<lambda>x. a+x) ` B)"] translation_assoc[of "-a" a B]
  2824     by auto
  2825   then have "V \<subseteq> affine hull T"
  2826     using B assms translation_inverse_subset[of a V "span B"]
  2827     by auto
  2828   moreover have "T \<subseteq> V"
  2829     using T_def B a assms by auto
  2830   ultimately have "affine hull T = affine hull V"
  2831     by (metis Int_absorb1 Int_absorb2 hull_hull hull_mono)
  2832   moreover have "S \<subseteq> T"
  2833     using T_def B translation_inverse_subset[of a "S-{a}" B]
  2834     by auto
  2835   moreover have "\<not> affine_dependent T"
  2836     using T_def affine_dependent_translation_eq[of "insert 0 B"]
  2837       affine_dependent_imp_dependent2 B
  2838     by auto
  2839   ultimately show ?thesis using \<open>T \<subseteq> V\<close> by auto
  2840 qed
  2841 
  2842 lemma affine_basis_exists:
  2843   fixes V :: "'n::euclidean_space set"
  2844   shows "\<exists>B. B \<subseteq> V \<and> \<not> affine_dependent B \<and> affine hull V = affine hull B"
  2845 proof (cases "V = {}")
  2846   case True
  2847   then show ?thesis
  2848     using affine_independent_0 by auto
  2849 next
  2850   case False
  2851   then obtain x where "x \<in> V" by auto
  2852   then show ?thesis
  2853     using affine_dependent_def[of "{x}"] extend_to_affine_basis_nonempty[of "{x}" V]
  2854     by auto
  2855 qed
  2856 
  2857 proposition extend_to_affine_basis:
  2858   fixes S V :: "'n::euclidean_space set"
  2859   assumes "\<not> affine_dependent S" "S \<subseteq> V"
  2860   obtains T where "\<not> affine_dependent T" "S \<subseteq> T" "T \<subseteq> V" "affine hull T = affine hull V"
  2861 proof (cases "S = {}")
  2862   case True then show ?thesis
  2863     using affine_basis_exists by (metis empty_subsetI that)
  2864 next
  2865   case False
  2866   then show ?thesis by (metis assms extend_to_affine_basis_nonempty that)
  2867 qed
  2868 
  2869 subsection \<open>Affine Dimension of a Set\<close>
  2870 
  2871 definition%important aff_dim :: "('a::euclidean_space) set \<Rightarrow> int"
  2872   where "aff_dim V =
  2873   (SOME d :: int.
  2874     \<exists>B. affine hull B = affine hull V \<and> \<not> affine_dependent B \<and> of_nat (card B) = d + 1)"
  2875 
  2876 lemma aff_dim_basis_exists:
  2877   fixes V :: "('n::euclidean_space) set"
  2878   shows "\<exists>B. affine hull B = affine hull V \<and> \<not> affine_dependent B \<and> of_nat (card B) = aff_dim V + 1"
  2879 proof -
  2880   obtain B where "\<not> affine_dependent B \<and> affine hull B = affine hull V"
  2881     using affine_basis_exists[of V] by auto
  2882   then show ?thesis
  2883     unfolding aff_dim_def
  2884       some_eq_ex[of "\<lambda>d. \<exists>B. affine hull B = affine hull V \<and> \<not> affine_dependent B \<and> of_nat (card B) = d + 1"]
  2885     apply auto
  2886     apply (rule exI[of _ "int (card B) - (1 :: int)"])
  2887     apply (rule exI[of _ "B"], auto)
  2888     done
  2889 qed
  2890 
  2891 lemma affine_hull_nonempty: "S \<noteq> {} \<longleftrightarrow> affine hull S \<noteq> {}"
  2892 proof -
  2893   have "S = {} \<Longrightarrow> affine hull S = {}"
  2894     using affine_hull_empty by auto
  2895   moreover have "affine hull S = {} \<Longrightarrow> S = {}"
  2896     unfolding hull_def by auto
  2897   ultimately show ?thesis by blast
  2898 qed
  2899 
  2900 lemma aff_dim_parallel_subspace_aux:
  2901   fixes B :: "'n::euclidean_space set"
  2902   assumes "\<not> affine_dependent B" "a \<in> B"
  2903   shows "finite B \<and> ((card B) - 1 = dim (span ((\<lambda>x. -a+x) ` (B-{a}))))"
  2904 proof -
  2905   have "independent ((\<lambda>x. -a + x) ` (B-{a}))"
  2906     using affine_dependent_iff_dependent2 assms by auto
  2907   then have fin: "dim (span ((\<lambda>x. -a+x) ` (B-{a}))) = card ((\<lambda>x. -a + x) ` (B-{a}))"
  2908     "finite ((\<lambda>x. -a + x) ` (B - {a}))"
  2909     using indep_card_eq_dim_span[of "(\<lambda>x. -a+x) ` (B-{a})"] by auto
  2910   show ?thesis
  2911   proof (cases "(\<lambda>x. -a + x) ` (B - {a}) = {}")
  2912     case True
  2913     have "B = insert a ((\<lambda>x. a + x) ` (\<lambda>x. -a + x) ` (B - {a}))"
  2914       using translation_assoc[of "a" "-a" "(B - {a})"] assms by auto
  2915     then have "B = {a}" using True by auto
  2916     then show ?thesis using assms fin by auto
  2917   next
  2918     case False
  2919     then have "card ((\<lambda>x. -a + x) ` (B - {a})) > 0"
  2920       using fin by auto
  2921     moreover have h1: "card ((\<lambda>x. -a + x) ` (B-{a})) = card (B-{a})"
  2922       by (rule card_image) (use translate_inj_on in blast)
  2923     ultimately have "card (B-{a}) > 0" by auto
  2924     then have *: "finite (B - {a})"
  2925       using card_gt_0_iff[of "(B - {a})"] by auto
  2926     then have "card (B - {a}) = card B - 1"
  2927       using card_Diff_singleton assms by auto
  2928     with * show ?thesis using fin h1 by auto
  2929   qed
  2930 qed
  2931 
  2932 lemma aff_dim_parallel_subspace:
  2933   fixes V L :: "'n::euclidean_space set"
  2934   assumes "V \<noteq> {}"
  2935     and "subspace L"
  2936     and "affine_parallel (affine hull V) L"
  2937   shows "aff_dim V = int (dim L)"
  2938 proof -
  2939   obtain B where
  2940     B: "affine hull B = affine hull V \<and> \<not> affine_dependent B \<and> int (card B) = aff_dim V + 1"
  2941     using aff_dim_basis_exists by auto
  2942   then have "B \<noteq> {}"
  2943     using assms B affine_hull_nonempty[of V] affine_hull_nonempty[of B]
  2944     by auto
  2945   then obtain a where a: "a \<in> B" by auto
  2946   define Lb where "Lb = span ((\<lambda>x. -a+x) ` (B-{a}))"
  2947   moreover have "affine_parallel (affine hull B) Lb"
  2948     using Lb_def B assms affine_hull_span2[of a B] a
  2949       affine_parallel_commut[of "Lb" "(affine hull B)"]
  2950     unfolding affine_parallel_def
  2951     by auto
  2952   moreover have "subspace Lb"
  2953     using Lb_def subspace_span by auto
  2954   moreover have "affine hull B \<noteq> {}"
  2955     using assms B affine_hull_nonempty[of V] by auto
  2956   ultimately have "L = Lb"
  2957     using assms affine_parallel_subspace[of "affine hull B"] affine_affine_hull[of B] B
  2958     by auto
  2959   then have "dim L = dim Lb"
  2960     by auto
  2961   moreover have "card B - 1 = dim Lb" and "finite B"
  2962     using Lb_def aff_dim_parallel_subspace_aux a B by auto
  2963   ultimately show ?thesis
  2964     using B \<open>B \<noteq> {}\<close> card_gt_0_iff[of B] by auto
  2965 qed
  2966 
  2967 lemma aff_independent_finite:
  2968   fixes B :: "'n::euclidean_space set"
  2969   assumes "\<not> affine_dependent B"
  2970   shows "finite B"
  2971 proof -
  2972   {
  2973     assume "B \<noteq> {}"
  2974     then obtain a where "a \<in> B" by auto
  2975     then have ?thesis
  2976       using aff_dim_parallel_subspace_aux assms by auto
  2977   }
  2978   then show ?thesis by auto
  2979 qed
  2980 
  2981 lemmas independent_finite = independent_imp_finite
  2982 
  2983 lemma span_substd_basis:
  2984   assumes d: "d \<subseteq> Basis"
  2985   shows "span d = {x. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x\<bullet>i = 0}"
  2986   (is "_ = ?B")
  2987 proof -
  2988   have "d \<subseteq> ?B"
  2989     using d by (auto simp: inner_Basis)
  2990   moreover have s: "subspace ?B"
  2991     using subspace_substandard[of "\<lambda>i. i \<notin> d"] .
  2992   ultimately have "span d \<subseteq> ?B"
  2993     using span_mono[of d "?B"] span_eq_iff[of "?B"] by blast
  2994   moreover have *: "card d \<le> dim (span d)"
  2995     using independent_card_le_dim[of d "span d"] independent_substdbasis[OF assms]
  2996       span_superset[of d]
  2997     by auto
  2998   moreover from * have "dim ?B \<le> dim (span d)"
  2999     using dim_substandard[OF assms] by auto
  3000   ultimately show ?thesis
  3001     using s subspace_dim_equal[of "span d" "?B"] subspace_span[of d] by auto
  3002 qed
  3003 
  3004 lemma basis_to_substdbasis_subspace_isomorphism:
  3005   fixes B :: "'a::euclidean_space set"
  3006   assumes "independent B"
  3007   shows "\<exists>f d::'a set. card d = card B \<and> linear f \<and> f ` B = d \<and>
  3008     f ` span B = {x. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0} \<and> inj_on f (span B) \<and> d \<subseteq> Basis"
  3009 proof -
  3010   have B: "card B = dim B"
  3011     using dim_unique[of B B "card B"] assms span_superset[of B] by auto
  3012   have "dim B \<le> card (Basis :: 'a set)"
  3013     using dim_subset_UNIV[of B] by simp
  3014   from ex_card[OF this] obtain d :: "'a set" where d: "d \<subseteq> Basis" and t: "card d = dim B"
  3015     by auto
  3016   let ?t = "{x::'a::euclidean_space. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x\<bullet>i = 0}"
  3017   have "\<exists>f. linear f \<and> f ` B = d \<and> f ` span B = ?t \<and> inj_on f (span B)"
  3018   proof (intro basis_to_basis_subspace_isomorphism subspace_span subspace_substandard span_superset)
  3019     show "d \<subseteq> {x. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x \<bullet> i = 0}"
  3020       using d inner_not_same_Basis by blast
  3021   qed (auto simp: span_substd_basis independent_substdbasis dim_substandard d t B assms)
  3022   with t \<open>card B = dim B\<close> d show ?thesis by auto
  3023 qed
  3024 
  3025 lemma aff_dim_empty:
  3026   fixes S :: "'n::euclidean_space set"
  3027   shows "S = {} \<longleftrightarrow> aff_dim S = -1"
  3028 proof -
  3029   obtain B where *: "affine hull B = affine hull S"
  3030     and "\<not> affine_dependent B"
  3031     and "int (card B) = aff_dim S + 1"
  3032     using aff_dim_basis_exists by auto
  3033   moreover
  3034   from * have "S = {} \<longleftrightarrow> B = {}"
  3035     using affine_hull_nonempty[of B] affine_hull_nonempty[of S] by auto
  3036   ultimately show ?thesis
  3037     using aff_independent_finite[of B] card_gt_0_iff[of B] by auto
  3038 qed
  3039 
  3040 lemma aff_dim_empty_eq [simp]: "aff_dim ({}::'a::euclidean_space set) = -1"
  3041   by (simp add: aff_dim_empty [symmetric])
  3042 
  3043 lemma aff_dim_affine_hull [simp]: "aff_dim (affine hull S) = aff_dim S"
  3044   unfolding aff_dim_def using hull_hull[of _ S] by auto
  3045 
  3046 lemma aff_dim_affine_hull2:
  3047   assumes "affine hull S = affine hull T"
  3048   shows "aff_dim S = aff_dim T"
  3049   unfolding aff_dim_def using assms by auto
  3050 
  3051 lemma aff_dim_unique:
  3052   fixes B V :: "'n::euclidean_space set"
  3053   assumes "affine hull B = affine hull V \<and> \<not> affine_dependent B"
  3054   shows "of_nat (card B) = aff_dim V + 1"
  3055 proof (cases "B = {}")
  3056   case True
  3057   then have "V = {}"
  3058     using affine_hull_nonempty[of V] affine_hull_nonempty[of B] assms
  3059     by auto
  3060   then have "aff_dim V = (-1::int)"
  3061     using aff_dim_empty by auto
  3062   then show ?thesis
  3063     using \<open>B = {}\<close> by auto
  3064 next
  3065   case False
  3066   then obtain a where a: "a \<in> B" by auto
  3067   define Lb where "Lb = span ((\<lambda>x. -a+x) ` (B-{a}))"
  3068   have "affine_parallel (affine hull B) Lb"
  3069     using Lb_def affine_hull_span2[of a B] a
  3070       affine_parallel_commut[of "Lb" "(affine hull B)"]
  3071     unfolding affine_parallel_def by auto
  3072   moreover have "subspace Lb"
  3073     using Lb_def subspace_span by auto
  3074   ultimately have "aff_dim B = int(dim Lb)"
  3075     using aff_dim_parallel_subspace[of B Lb] \<open>B \<noteq> {}\<close> by auto
  3076   moreover have "(card B) - 1 = dim Lb" "finite B"
  3077     using Lb_def aff_dim_parallel_subspace_aux a assms by auto
  3078   ultimately have "of_nat (card B) = aff_dim B + 1"
  3079     using \<open>B \<noteq> {}\<close> card_gt_0_iff[of B] by auto
  3080   then show ?thesis
  3081     using aff_dim_affine_hull2 assms by auto
  3082 qed
  3083 
  3084 lemma aff_dim_affine_independent:
  3085   fixes B :: "'n::euclidean_space set"
  3086   assumes "\<not> affine_dependent B"
  3087   shows "of_nat (card B) = aff_dim B + 1"
  3088   using aff_dim_unique[of B B] assms by auto
  3089 
  3090 lemma affine_independent_iff_card:
  3091     fixes s :: "'a::euclidean_space set"
  3092     shows "\<not> affine_dependent s \<longleftrightarrow> finite s \<and> aff_dim s = int(card s) - 1"
  3093   apply (rule iffI)
  3094   apply (simp add: aff_dim_affine_independent aff_independent_finite)
  3095   by (metis affine_basis_exists [of s] aff_dim_unique card_subset_eq diff_add_cancel of_nat_eq_iff)
  3096 
  3097 lemma aff_dim_sing [simp]:
  3098   fixes a :: "'n::euclidean_space"
  3099   shows "aff_dim {a} = 0"
  3100   using aff_dim_affine_independent[of "{a}"] affine_independent_1 by auto
  3101 
  3102 lemma aff_dim_2 [simp]: "aff_dim {a,b} = (if a = b then 0 else 1)"
  3103 proof (clarsimp)
  3104   assume "a \<noteq> b"
  3105   then have "aff_dim{a,b} = card{a,b} - 1"
  3106     using affine_independent_2 [of a b] aff_dim_affine_independent by fastforce
  3107   also have "\<dots> = 1"
  3108     using \<open>a \<noteq> b\<close> by simp
  3109   finally show "aff_dim {a, b} = 1" .
  3110 qed
  3111 
  3112 lemma aff_dim_inner_basis_exists:
  3113   fixes V :: "('n::euclidean_space) set"
  3114   shows "\<exists>B. B \<subseteq> V \<and> affine hull B = affine hull V \<and>
  3115     \<not> affine_dependent B \<and> of_nat (card B) = aff_dim V + 1"
  3116 proof -
  3117   obtain B where B: "\<not> affine_dependent B" "B \<subseteq> V" "affine hull B = affine hull V"
  3118     using affine_basis_exists[of V] by auto
  3119   then have "of_nat(card B) = aff_dim V+1" using aff_dim_unique by auto
  3120   with B show ?thesis by auto
  3121 qed
  3122 
  3123 lemma aff_dim_le_card:
  3124   fixes V :: "'n::euclidean_space set"
  3125   assumes "finite V"
  3126   shows "aff_dim V \<le> of_nat (card V) - 1"
  3127 proof -
  3128   obtain B where B: "B \<subseteq> V" "of_nat (card B) = aff_dim V + 1"
  3129     using aff_dim_inner_basis_exists[of V] by auto
  3130   then have "card B \<le> card V"
  3131     using assms card_mono by auto
  3132   with B show ?thesis by auto
  3133 qed
  3134 
  3135 lemma aff_dim_parallel_eq:
  3136   fixes S T :: "'n::euclidean_space set"
  3137   assumes "affine_parallel (affine hull S) (affine hull T)"
  3138   shows "aff_dim S = aff_dim T"
  3139 proof -
  3140   {
  3141     assume "T \<noteq> {}" "S \<noteq> {}"
  3142     then obtain L where L: "subspace L \<and> affine_parallel (affine hull T) L"
  3143       using affine_parallel_subspace[of "affine hull T"]
  3144         affine_affine_hull[of T] affine_hull_nonempty
  3145       by auto
  3146     then have "aff_dim T = int (dim L)"
  3147       using aff_dim_parallel_subspace \<open>T \<noteq> {}\<close> by auto
  3148     moreover have *: "subspace L \<and> affine_parallel (affine hull S) L"
  3149        using L affine_parallel_assoc[of "affine hull S" "affine hull T" L] assms by auto
  3150     moreover from * have "aff_dim S = int (dim L)"
  3151       using aff_dim_parallel_subspace \<open>S \<noteq> {}\<close> by auto
  3152     ultimately have ?thesis by auto
  3153   }
  3154   moreover
  3155   {
  3156     assume "S = {}"
  3157     then have "S = {}" and "T = {}"
  3158       using assms affine_hull_nonempty
  3159       unfolding affine_parallel_def
  3160       by auto
  3161     then have ?thesis using aff_dim_empty by auto
  3162   }
  3163   moreover
  3164   {
  3165     assume "T = {}"
  3166     then have "S = {}" and "T = {}"
  3167       using assms affine_hull_nonempty
  3168       unfolding affine_parallel_def
  3169       by auto
  3170     then have ?thesis
  3171       using aff_dim_empty by auto
  3172   }
  3173   ultimately show ?thesis by blast
  3174 qed
  3175 
  3176 lemma aff_dim_translation_eq:
  3177   "aff_dim ((+) a ` S) = aff_dim S" for a :: "'n::euclidean_space"
  3178 proof -
  3179   have "affine_parallel (affine hull S) (affine hull ((\<lambda>x. a + x) ` S))"
  3180     unfolding affine_parallel_def
  3181     apply (rule exI[of _ "a"])
  3182     using affine_hull_translation[of a S]
  3183     apply auto
  3184     done
  3185   then show ?thesis
  3186     using aff_dim_parallel_eq[of S "(\<lambda>x. a + x) ` S"] by auto
  3187 qed
  3188 
  3189 lemma aff_dim_translation_eq_subtract:
  3190   "aff_dim ((\<lambda>x. x - a) ` S) = aff_dim S" for a :: "'n::euclidean_space"
  3191   using aff_dim_translation_eq [of "- a"] by (simp cong: image_cong_simp)
  3192 
  3193 lemma aff_dim_affine:
  3194   fixes S L :: "'n::euclidean_space set"
  3195   assumes "S \<noteq> {}"
  3196     and "affine S"
  3197     and "subspace L"
  3198     and "affine_parallel S L"
  3199   shows "aff_dim S = int (dim L)"
  3200 proof -
  3201   have *: "affine hull S = S"
  3202     using assms affine_hull_eq[of S] by auto
  3203   then have "affine_parallel (affine hull S) L"
  3204     using assms by (simp add: *)
  3205   then show ?thesis
  3206     using assms aff_dim_parallel_subspace[of S L] by blast
  3207 qed
  3208 
  3209 lemma dim_affine_hull:
  3210   fixes S :: "'n::euclidean_space set"
  3211   shows "dim (affine hull S) = dim S"
  3212 proof -
  3213   have "dim (affine hull S) \<ge> dim S"
  3214     using dim_subset by auto
  3215   moreover have "dim (span S) \<ge> dim (affine hull S)"
  3216     using dim_subset affine_hull_subset_span by blast
  3217   moreover have "dim (span S) = dim S"
  3218     using dim_span by auto
  3219   ultimately show ?thesis by auto
  3220 qed
  3221 
  3222 lemma aff_dim_subspace:
  3223   fixes S :: "'n::euclidean_space set"
  3224   assumes "subspace S"
  3225   shows "aff_dim S = int (dim S)"
  3226 proof (cases "S={}")
  3227   case True with assms show ?thesis
  3228     by (simp add: subspace_affine)
  3229 next
  3230   case False
  3231   with aff_dim_affine[of S S] assms subspace_imp_affine[of S] affine_parallel_reflex[of S] subspace_affine
  3232   show ?thesis by auto
  3233 qed
  3234 
  3235 lemma aff_dim_zero:
  3236   fixes S :: "'n::euclidean_space set"
  3237   assumes "0 \<in> affine hull S"
  3238   shows "aff_dim S = int (dim S)"
  3239 proof -
  3240   have "subspace (affine hull S)"
  3241     using subspace_affine[of "affine hull S"] affine_affine_hull assms
  3242     by auto
  3243   then have "aff_dim (affine hull S) = int (dim (affine hull S))"
  3244     using assms aff_dim_subspace[of "affine hull S"] by auto
  3245   then show ?thesis
  3246     using aff_dim_affine_hull[of S] dim_affine_hull[of S]
  3247     by auto
  3248 qed
  3249 
  3250 lemma aff_dim_eq_dim:
  3251   "aff_dim S = int (dim ((+) (- a) ` S))" if "a \<in> affine hull S"
  3252     for S :: "'n::euclidean_space set"
  3253 proof -
  3254   have "0 \<in> affine hull (+) (- a) ` S"
  3255     unfolding affine_hull_translation
  3256     using that by (simp add: ac_simps)
  3257   with aff_dim_zero show ?thesis
  3258     by (metis aff_dim_translation_eq)
  3259 qed
  3260 
  3261 lemma aff_dim_eq_dim_subtract:
  3262   "aff_dim S = int (dim ((\<lambda>x. x - a) ` S))" if "a \<in> affine hull S"
  3263     for S :: "'n::euclidean_space set"
  3264   using aff_dim_eq_dim [of a] that by (simp cong: image_cong_simp)
  3265 
  3266 lemma aff_dim_UNIV [simp]: "aff_dim (UNIV :: 'n::euclidean_space set) = int(DIM('n))"
  3267   using aff_dim_subspace[of "(UNIV :: 'n::euclidean_space set)"]
  3268     dim_UNIV[where 'a="'n::euclidean_space"]
  3269   by auto
  3270 
  3271 lemma aff_dim_geq:
  3272   fixes V :: "'n::euclidean_space set"
  3273   shows "aff_dim V \<ge> -1"
  3274 proof -
  3275   obtain B where "affine hull B = affine hull V"
  3276     and "\<not> affine_dependent B"
  3277     and "int (card B) = aff_dim V + 1"
  3278     using aff_dim_basis_exists by auto
  3279   then show ?thesis by auto
  3280 qed
  3281 
  3282 lemma aff_dim_negative_iff [simp]:
  3283   fixes S :: "'n::euclidean_space set"
  3284   shows "aff_dim S < 0 \<longleftrightarrow>S = {}"
  3285 by (metis aff_dim_empty aff_dim_geq diff_0 eq_iff zle_diff1_eq)
  3286 
  3287 lemma aff_lowdim_subset_hyperplane:
  3288   fixes S :: "'a::euclidean_space set"
  3289   assumes "aff_dim S < DIM('a)"
  3290   obtains a b where "a \<noteq> 0" "S \<subseteq> {x. a \<bullet> x = b}"
  3291 proof (cases "S={}")
  3292   case True
  3293   moreover
  3294   have "(SOME b. b \<in> Basis) \<noteq> 0"
  3295     by (metis norm_some_Basis norm_zero zero_neq_one)
  3296   ultimately show ?thesis
  3297     using that by blast
  3298 next
  3299   case False
  3300   then obtain c S' where "c \<notin> S'" "S = insert c S'"
  3301     by (meson equals0I mk_disjoint_insert)
  3302   have "dim ((+) (-c) ` S) < DIM('a)"
  3303     by (metis \<open>S = insert c S'\<close> aff_dim_eq_dim assms hull_inc insertI1 of_nat_less_imp_less)
  3304   then obtain a where "a \<noteq> 0" "span ((+) (-c) ` S) \<subseteq> {x. a \<bullet> x = 0}"
  3305     using lowdim_subset_hyperplane by blast
  3306   moreover
  3307   have "a \<bullet> w = a \<bullet> c" if "span ((+) (- c) ` S) \<subseteq> {x. a \<bullet> x = 0}" "w \<in> S" for w
  3308   proof -
  3309     have "w-c \<in> span ((+) (- c) ` S)"
  3310       by (simp add: span_base \<open>w \<in> S\<close>)
  3311     with that have "w-c \<in> {x. a \<bullet> x = 0}"
  3312       by blast
  3313     then show ?thesis
  3314       by (auto simp: algebra_simps)
  3315   qed
  3316   ultimately have "S \<subseteq> {x. a \<bullet> x = a \<bullet> c}"
  3317     by blast
  3318   then show ?thesis
  3319     by (rule that[OF \<open>a \<noteq> 0\<close>])
  3320 qed
  3321 
  3322 lemma affine_independent_card_dim_diffs:
  3323   fixes S :: "'a :: euclidean_space set"
  3324   assumes "\<not> affine_dependent S" "a \<in> S"
  3325     shows "card S = dim {x - a|x. x \<in> S} + 1"
  3326 proof -
  3327   have 1: "{b - a|b. b \<in> (S - {a})} \<subseteq> {x - a|x. x \<in> S}" by auto
  3328   have 2: "x - a \<in> span {b - a |b. b \<in> S - {a}}" if "x \<in> S" for x
  3329   proof (cases "x = a")
  3330     case True then show ?thesis by (simp add: span_clauses)
  3331   next
  3332     case False then show ?thesis
  3333       using assms by (blast intro: span_base that)
  3334   qed
  3335   have "\<not> affine_dependent (insert a S)"
  3336     by (simp add: assms insert_absorb)
  3337   then have 3: "independent {b - a |b. b \<in> S - {a}}"
  3338       using dependent_imp_affine_dependent by fastforce
  3339   have "{b - a |b. b \<in> S - {a}} = (\<lambda>b. b-a) ` (S - {a})"
  3340     by blast
  3341   then have "card {b - a |b. b \<in> S - {a}} = card ((\<lambda>b. b-a) ` (S - {a}))"
  3342     by simp
  3343   also have "\<dots> = card (S - {a})"
  3344     by (metis (no_types, lifting) card_image diff_add_cancel inj_onI)
  3345   also have "\<dots> = card S - 1"
  3346     by (simp add: aff_independent_finite assms)
  3347   finally have 4: "card {b - a |b. b \<in> S - {a}} = card S - 1" .
  3348   have "finite S"
  3349     by (meson assms aff_independent_finite)
  3350   with \<open>a \<in> S\<close> have "card S \<noteq> 0" by auto
  3351   moreover have "dim {x - a |x. x \<in> S} = card S - 1"
  3352     using 2 by (blast intro: dim_unique [OF 1 _ 3 4])
  3353   ultimately show ?thesis
  3354     by auto
  3355 qed
  3356 
  3357 lemma independent_card_le_aff_dim:
  3358   fixes B :: "'n::euclidean_space set"
  3359   assumes "B \<subseteq> V"
  3360   assumes "\<not> affine_dependent B"
  3361   shows "int (card B) \<le> aff_dim V + 1"
  3362 proof -
  3363   obtain T where T: "\<not> affine_dependent T \<and> B \<subseteq> T \<and> T \<subseteq> V \<and> affine hull T = affine hull V"
  3364     by (metis assms extend_to_affine_basis[of B V])
  3365   then have "of_nat (card T) = aff_dim V + 1"
  3366     using aff_dim_unique by auto
  3367   then show ?thesis
  3368     using T card_mono[of T B] aff_independent_finite[of T] by auto
  3369 qed
  3370 
  3371 lemma aff_dim_subset:
  3372   fixes S T :: "'n::euclidean_space set"
  3373   assumes "S \<subseteq> T"
  3374   shows "aff_dim S \<le> aff_dim T"
  3375 proof -
  3376   obtain B where B: "\<not> affine_dependent B" "B \<subseteq> S" "affine hull B = affine hull S"
  3377     "of_nat (card B) = aff_dim S + 1"
  3378     using aff_dim_inner_basis_exists[of S] by auto
  3379   then have "int (card B) \<le> aff_dim T + 1"
  3380     using assms independent_card_le_aff_dim[of B T] by auto
  3381   with B show ?thesis by auto
  3382 qed
  3383 
  3384 lemma aff_dim_le_DIM:
  3385   fixes S :: "'n::euclidean_space set"
  3386   shows "aff_dim S \<le> int (DIM('n))"
  3387 proof -
  3388   have "aff_dim (UNIV :: 'n::euclidean_space set) = int(DIM('n))"
  3389     using aff_dim_UNIV by auto
  3390   then show "aff_dim (S:: 'n::euclidean_space set) \<le> int(DIM('n))"
  3391     using aff_dim_subset[of S "(UNIV :: ('n::euclidean_space) set)"] subset_UNIV by auto
  3392 qed
  3393 
  3394 lemma affine_dim_equal:
  3395   fixes S :: "'n::euclidean_space set"
  3396   assumes "affine S" "affine T" "S \<noteq> {}" "S \<subseteq> T" "aff_dim S = aff_dim T"
  3397   shows "S = T"
  3398 proof -
  3399   obtain a where "a \<in> S" using assms by auto
  3400   then have "a \<in> T" using assms by auto
  3401   define LS where "LS = {y. \<exists>x \<in> S. (-a) + x = y}"
  3402   then have ls: "subspace LS" "affine_parallel S LS"
  3403     using assms parallel_subspace_explicit[of S a LS] \<open>a \<in> S\<close> by auto
  3404   then have h1: "int(dim LS) = aff_dim S"
  3405     using assms aff_dim_affine[of S LS] by auto
  3406   have "T \<noteq> {}" using assms by auto
  3407   define LT where "LT = {y. \<exists>x \<in> T. (-a) + x = y}"
  3408   then have lt: "subspace LT \<and> affine_parallel T LT"
  3409     using assms parallel_subspace_explicit[of T a LT] \<open>a \<in> T\<close> by auto
  3410   then have "int(dim LT) = aff_dim T"
  3411     using assms aff_dim_affine[of T LT] \<open>T \<noteq> {}\<close> by auto
  3412   then have "dim LS = dim LT"
  3413     using h1 assms by auto
  3414   moreover have "LS \<le> LT"
  3415     using LS_def LT_def assms by auto
  3416   ultimately have "LS = LT"
  3417     using subspace_dim_equal[of LS LT] ls lt by auto
  3418   moreover have "S = {x. \<exists>y \<in> LS. a+y=x}"
  3419     using LS_def by auto
  3420   moreover have "T = {x. \<exists>y \<in> LT. a+y=x}"
  3421     using LT_def by auto
  3422   ultimately show ?thesis by auto
  3423 qed
  3424 
  3425 lemma aff_dim_eq_0:
  3426   fixes S :: "'a::euclidean_space set"
  3427   shows "aff_dim S = 0 \<longleftrightarrow> (\<exists>a. S = {a})"
  3428 proof (cases "S = {}")
  3429   case True
  3430   then show ?thesis
  3431     by auto
  3432 next
  3433   case False
  3434   then obtain a where "a \<in> S" by auto
  3435   show ?thesis
  3436   proof safe
  3437     assume 0: "aff_dim S = 0"
  3438     have "\<not> {a,b} \<subseteq> S" if "b \<noteq> a" for b
  3439       by (metis "0" aff_dim_2 aff_dim_subset not_one_le_zero that)
  3440     then show "\<exists>a. S = {a}"
  3441       using \<open>a \<in> S\<close> by blast
  3442   qed auto
  3443 qed
  3444 
  3445 lemma affine_hull_UNIV:
  3446   fixes S :: "'n::euclidean_space set"
  3447   assumes "aff_dim S = int(DIM('n))"
  3448   shows "affine hull S = (UNIV :: ('n::euclidean_space) set)"
  3449 proof -
  3450   have "S \<noteq> {}"
  3451     using assms aff_dim_empty[of S] by auto
  3452   have h0: "S \<subseteq> affine hull S"
  3453     using hull_subset[of S _] by auto
  3454   have h1: "aff_dim (UNIV :: ('n::euclidean_space) set) = aff_dim S"
  3455     using aff_dim_UNIV assms by auto
  3456   then have h2: "aff_dim (affine hull S) \<le> aff_dim (UNIV :: ('n::euclidean_space) set)"
  3457     using aff_dim_le_DIM[of "affine hull S"] assms h0 by auto
  3458   have h3: "aff_dim S \<le> aff_dim (affine hull S)"
  3459     using h0 aff_dim_subset[of S "affine hull S"] assms by auto
  3460   then have h4: "aff_dim (affine hull S) = aff_dim (UNIV :: ('n::euclidean_space) set)"
  3461     using h0 h1 h2 by auto
  3462   then show ?thesis
  3463     using affine_dim_equal[of "affine hull S" "(UNIV :: ('n::euclidean_space) set)"]
  3464       affine_affine_hull[of S] affine_UNIV assms h4 h0 \<open>S \<noteq> {}\<close>
  3465     by auto
  3466 qed
  3467 
  3468 lemma disjoint_affine_hull:
  3469   fixes s :: "'n::euclidean_space set"
  3470   assumes "\<not> affine_dependent s" "t \<subseteq> s" "u \<subseteq> s" "t \<inter> u = {}"
  3471     shows "(affine hull t) \<inter> (affine hull u) = {}"
  3472 proof -
  3473   have "finite s" using assms by (simp add: aff_independent_finite)
  3474   then have "finite t" "finite u" using assms finite_subset by blast+
  3475   { fix y
  3476     assume yt: "y \<in> affine hull t" and yu: "y \<in> affine hull u"
  3477     then obtain a b
  3478            where a1 [simp]: "sum a t = 1" and [simp]: "sum (\<lambda>v. a v *\<^sub>R v) t = y"
  3479              and [simp]: "sum b u = 1" "sum (\<lambda>v. b v *\<^sub>R v) u = y"
  3480       by (auto simp: affine_hull_finite \<open>finite t\<close> \<open>finite u\<close>)
  3481     define c where "c x = (if x \<in> t then a x else if x \<in> u then -(b x) else 0)" for x
  3482     have [simp]: "s \<inter> t = t" "s \<inter> - t \<inter> u = u" using assms by auto
  3483     have "sum c s = 0"
  3484       by (simp add: c_def comm_monoid_add_class.sum.If_cases \<open>finite s\<close> sum_negf)
  3485     moreover have "\<not> (\<forall>v\<in>s. c v = 0)"
  3486       by (metis (no_types) IntD1 \<open>s \<inter> t = t\<close> a1 c_def sum_not_0 zero_neq_one)
  3487     moreover have "(\<Sum>v\<in>s. c v *\<^sub>R v) = 0"
  3488       by (simp add: c_def if_smult sum_negf
  3489              comm_monoid_add_class.sum.If_cases \<open>finite s\<close>)
  3490     ultimately have False
  3491       using assms \<open>finite s\<close> by (auto simp: affine_dependent_explicit)
  3492   }
  3493   then show ?thesis by blast
  3494 qed
  3495 
  3496 lemma aff_dim_convex_hull:
  3497   fixes S :: "'n::euclidean_space set"
  3498   shows "aff_dim (convex hull S) = aff_dim S"
  3499   using aff_dim_affine_hull[of S] convex_hull_subset_affine_hull[of S]
  3500     hull_subset[of S "convex"] aff_dim_subset[of S "convex hull S"]
  3501     aff_dim_subset[of "convex hull S" "affine hull S"]
  3502   by auto
  3503 
  3504 subsection \<open>Caratheodory's theorem\<close>
  3505 
  3506 lemma convex_hull_caratheodory_aff_dim:
  3507   fixes p :: "('a::euclidean_space) set"
  3508   shows "convex hull p =
  3509     {y. \<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> aff_dim p + 1 \<and>
  3510       (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<and> sum (\<lambda>v. u v *\<^sub>R v) s = y}"
  3511   unfolding convex_hull_explicit set_eq_iff mem_Collect_eq
  3512 proof (intro allI iffI)
  3513   fix y
  3514   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>
  3515     sum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
  3516   assume "\<exists>s u. finite s \<and> s \<subseteq> p \<and> (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
  3517   then obtain N where "?P N" by auto
  3518   then have "\<exists>n\<le>N. (\<forall>k<n. \<not> ?P k) \<and> ?P n"
  3519     apply (rule_tac ex_least_nat_le, auto)
  3520     done
  3521   then obtain n where "?P n" and smallest: "\<forall>k<n. \<not> ?P k"
  3522     by blast
  3523   then obtain s u where obt: "finite s" "card s = n" "s\<subseteq>p" "\<forall>x\<in>s. 0 \<le> u x"
  3524     "sum u s = 1"  "(\<Sum>v\<in>s. u v *\<^sub>R v) = y" by auto
  3525 
  3526   have "card s \<le> aff_dim p + 1"
  3527   proof (rule ccontr, simp only: not_le)
  3528     assume "aff_dim p + 1 < card s"
  3529     then have "affine_dependent s"
  3530       using affine_dependent_biggerset[OF obt(1)] independent_card_le_aff_dim not_less obt(3)
  3531       by blast
  3532     then obtain w v where wv: "sum w s = 0" "v\<in>s" "w v \<noteq> 0" "(\<Sum>v\<in>s. w v *\<^sub>R v) = 0"
  3533       using affine_dependent_explicit_finite[OF obt(1)] by auto
  3534     define i where "i = (\<lambda>v. (u v) / (- w v)) ` {v\<in>s. w v < 0}"
  3535     define t where "t = Min i"
  3536     have "\<exists>x\<in>s. w x < 0"
  3537     proof (rule ccontr, simp add: not_less)
  3538       assume as:"\<forall>x\<in>s. 0 \<le> w x"
  3539       then have "sum w (s - {v}) \<ge> 0"
  3540         apply (rule_tac sum_nonneg, auto)
  3541         done
  3542       then have "sum w s > 0"
  3543         unfolding sum.remove[OF obt(1) \<open>v\<in>s\<close>]
  3544         using as[THEN bspec[where x=v]]  \<open>v\<in>s\<close>  \<open>w v \<noteq> 0\<close> by auto
  3545       then show False using wv(1) by auto
  3546     qed
  3547     then have "i \<noteq> {}" unfolding i_def by auto
  3548     then have "t \<ge> 0"
  3549       using Min_ge_iff[of i 0 ] and obt(1)
  3550       unfolding t_def i_def
  3551       using obt(4)[unfolded le_less]
  3552       by (auto simp: divide_le_0_iff)
  3553     have t: "\<forall>v\<in>s. u v + t * w v \<ge> 0"
  3554     proof
  3555       fix v
  3556       assume "v \<in> s"
  3557       then have v: "0 \<le> u v"
  3558         using obt(4)[THEN bspec[where x=v]] by auto
  3559       show "0 \<le> u v + t * w v"
  3560       proof (cases "w v < 0")
  3561         case False
  3562         thus ?thesis using v \<open>t\<ge>0\<close> by auto
  3563       next
  3564         case True
  3565         then have "t \<le> u v / (- w v)"
  3566           using \<open>v\<in>s\<close> unfolding t_def i_def
  3567           apply (rule_tac Min_le)
  3568           using obt(1) apply auto
  3569           done
  3570         then show ?thesis
  3571           unfolding real_0_le_add_iff
  3572           using pos_le_divide_eq[OF True[unfolded neg_0_less_iff_less[symmetric]]]
  3573           by auto
  3574       qed
  3575     qed
  3576     obtain a where "a \<in> s" and "t = (\<lambda>v. (u v) / (- w v)) a" and "w a < 0"
  3577       using Min_in[OF _ \<open>i\<noteq>{}\<close>] and obt(1) unfolding i_def t_def by auto
  3578     then have a: "a \<in> s" "u a + t * w a = 0" by auto
  3579     have *: "\<And>f. sum f (s - {a}) = sum f s - ((f a)::'b::ab_group_add)"
  3580       unfolding sum.remove[OF obt(1) \<open>a\<in>s\<close>] by auto
  3581     have "(\<Sum>v\<in>s. u v + t * w v) = 1"
  3582       unfolding sum.distrib wv(1) sum_distrib_left[symmetric] obt(5) by auto
  3583     moreover have "(\<Sum>v\<in>s. u v *\<^sub>R v + (t * w v) *\<^sub>R v) - (u a *\<^sub>R a + (t * w a) *\<^sub>R a) = y"
  3584       unfolding sum.distrib obt(6) scaleR_scaleR[symmetric] scaleR_right.sum [symmetric] wv(4)
  3585       using a(2) [THEN eq_neg_iff_add_eq_0 [THEN iffD2]] by simp
  3586     ultimately have "?P (n - 1)"
  3587       apply (rule_tac x="(s - {a})" in exI)
  3588       apply (rule_tac x="\<lambda>v. u v + t * w v" in exI)
  3589       using obt(1-3) and t and a
  3590       apply (auto simp: * scaleR_left_distrib)
  3591       done
  3592     then show False
  3593       using smallest[THEN spec[where x="n - 1"]] by auto
  3594   qed
  3595   then show "\<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> aff_dim p + 1 \<and>
  3596       (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<and> (\<Sum>v\<in>s. u v *\<^sub>R v) = y"
  3597     using obt by auto
  3598 qed auto
  3599 
  3600 lemma caratheodory_aff_dim:
  3601   fixes p :: "('a::euclidean_space) set"
  3602   shows "convex hull p = {x. \<exists>s. finite s \<and> s \<subseteq> p \<and> card s \<le> aff_dim p + 1 \<and> x \<in> convex hull s}"
  3603         (is "?lhs = ?rhs")
  3604 proof
  3605   show "?lhs \<subseteq> ?rhs"
  3606     apply (subst convex_hull_caratheodory_aff_dim, clarify)
  3607     apply (rule_tac x=s in exI)
  3608     apply (simp add: hull_subset convex_explicit [THEN iffD1, OF convex_convex_hull])
  3609     done
  3610 next
  3611   show "?rhs \<subseteq> ?lhs"
  3612     using hull_mono by blast
  3613 qed
  3614 
  3615 lemma convex_hull_caratheodory:
  3616   fixes p :: "('a::euclidean_space) set"
  3617   shows "convex hull p =
  3618             {y. \<exists>s u. finite s \<and> s \<subseteq> p \<and> card s \<le> DIM('a) + 1 \<and>
  3619               (\<forall>x\<in>s. 0 \<le> u x) \<and> sum u s = 1 \<and> sum (\<lambda>v. u v *\<^sub>R v) s = y}"
  3620         (is "?lhs = ?rhs")
  3621 proof (intro set_eqI iffI)
  3622   fix x
  3623   assume "x \<in> ?lhs" then show "x \<in> ?rhs"
  3624     apply (simp only: convex_hull_caratheodory_aff_dim Set.mem_Collect_eq)
  3625     apply (erule ex_forward)+
  3626     using aff_dim_le_DIM [of p]
  3627     apply simp
  3628     done
  3629 next
  3630   fix x
  3631   assume "x \<in> ?rhs" then show "x \<in> ?lhs"
  3632     by (auto simp: convex_hull_explicit)
  3633 qed
  3634 
  3635 theorem caratheodory:
  3636   "convex hull p =
  3637     {x::'a::euclidean_space. \<exists>s. finite s \<and> s \<subseteq> p \<and>
  3638       card s \<le> DIM('a) + 1 \<and> x \<in> convex hull s}"
  3639 proof safe
  3640   fix x
  3641   assume "x \<in> convex hull p"
  3642   then obtain s u where "finite s" "s \<subseteq> p" "card s \<le> DIM('a) + 1"
  3643     "\<forall>x\<in>s. 0 \<le> u x" "sum u s = 1" "(\<Sum>v\<in>s. u v *\<^sub>R v) = x"
  3644     unfolding convex_hull_caratheodory by auto
  3645   then show "\<exists>s. finite s \<and> s \<subseteq> p \<and> card s \<le> DIM('a) + 1 \<and> x \<in> convex hull s"
  3646     apply (rule_tac x=s in exI)
  3647     using hull_subset[of s convex]
  3648     using convex_convex_hull[simplified convex_explicit, of s,
  3649       THEN spec[where x=s], THEN spec[where x=u]]
  3650     apply auto
  3651     done
  3652 next
  3653   fix x s
  3654   assume  "finite s" "s \<subseteq> p" "card s \<le> DIM('a) + 1" "x \<in> convex hull s"
  3655   then show "x \<in> convex hull p"
  3656     using hull_mono[OF \<open>s\<subseteq>p\<close>] by auto
  3657 qed
  3658 
  3659 subsection%unimportant\<open>Some Properties of subset of standard basis\<close>
  3660 
  3661 lemma affine_hull_substd_basis:
  3662   assumes "d \<subseteq> Basis"
  3663   shows "affine hull (insert 0 d) = {x::'a::euclidean_space. \<forall>i\<in>Basis. i \<notin> d \<longrightarrow> x\<bullet>i = 0}"
  3664   (is "affine hull (insert 0 ?A) = ?B")
  3665 proof -
  3666   have *: "\<And>A. (+) (0::'a) ` A = A" "\<And>A. (+) (- (0::'a)) ` A = A"
  3667     by auto
  3668   show ?thesis
  3669     unfolding affine_hull_insert_span_gen span_substd_basis[OF assms,symmetric] * ..
  3670 qed
  3671 
  3672 lemma affine_hull_convex_hull [simp]: "affine hull (convex hull S) = affine hull S"
  3673   by (metis Int_absorb1 Int_absorb2 convex_hull_subset_affine_hull hull_hull hull_mono hull_subset)
  3674 
  3675 
  3676 subsection%unimportant \<open>Moving and scaling convex hulls\<close>
  3677 
  3678 lemma convex_hull_set_plus:
  3679   "convex hull (S + T) = convex hull S + convex hull T"
  3680   unfolding set_plus_image
  3681   apply (subst convex_hull_linear_image [symmetric])
  3682   apply (simp add: linear_iff scaleR_right_distrib)
  3683   apply (simp add: convex_hull_Times)
  3684   done
  3685 
  3686 lemma translation_eq_singleton_plus: "(\<lambda>x. a + x) ` T = {a} + T"
  3687   unfolding set_plus_def by auto
  3688 
  3689 lemma convex_hull_translation:
  3690   "convex hull ((\<lambda>x. a + x) ` S) = (\<lambda>x. a + x) ` (convex hull S)"
  3691   unfolding translation_eq_singleton_plus
  3692   by (simp only: convex_hull_set_plus convex_hull_singleton)
  3693 
  3694 lemma convex_hull_scaling:
  3695   "convex hull ((\<lambda>x. c *\<^sub>R x) ` S) = (\<lambda>x. c *\<^sub>R x) ` (convex hull S)"
  3696   using linear_scaleR by (rule convex_hull_linear_image [symmetric])
  3697 
  3698 lemma convex_hull_affinity:
  3699   "convex hull ((\<lambda>x. a + c *\<^sub>R x) ` S) = (\<lambda>x. a + c *\<^sub>R x) ` (convex hull S)"
  3700   by(simp only: image_image[symmetric] convex_hull_scaling convex_hull_translation)
  3701 
  3702 
  3703 subsection%unimportant \<open>Convexity of cone hulls\<close>
  3704 
  3705 lemma convex_cone_hull:
  3706   assumes "convex S"
  3707   shows "convex (cone hull S)"
  3708 proof (rule convexI)
  3709   fix x y
  3710   assume xy: "x \<in> cone hull S" "y \<in> cone hull S"
  3711   then have "S \<noteq> {}"
  3712     using cone_hull_empty_iff[of S] by auto
  3713   fix u v :: real
  3714   assume uv: "u \<ge> 0" "v \<ge> 0" "u + v = 1"
  3715   then have *: "u *\<^sub>R x \<in> cone hull S" "v *\<^sub>R y \<in> cone hull S"
  3716     using cone_cone_hull[of S] xy cone_def[of "cone hull S"] by auto
  3717   from * obtain cx :: real and xx where x: "u *\<^sub>R x = cx *\<^sub>R xx" "cx \<ge> 0" "xx \<in> S"
  3718     using cone_hull_expl[of S] by auto
  3719   from * obtain cy :: real and yy where y: "v *\<^sub>R y = cy *\<^sub>R yy" "cy \<ge> 0" "yy \<in> S"
  3720     using cone_hull_expl[of S] by auto
  3721   {
  3722     assume "cx + cy \<le> 0"
  3723     then have "u *\<^sub>R x = 0" and "v *\<^sub>R y = 0"
  3724       using x y by auto
  3725     then have "u *\<^sub>R x + v *\<^sub>R y = 0"
  3726       by auto
  3727     then have "u *\<^sub>R x + v *\<^sub>R y \<in> cone hull S"
  3728       using cone_hull_contains_0[of S] \<open>S \<noteq> {}\<close> by auto
  3729   }
  3730   moreover
  3731   {
  3732     assume "cx + cy > 0"
  3733     then have "(cx / (cx + cy)) *\<^sub>R xx + (cy / (cx + cy)) *\<^sub>R yy \<in> S"
  3734       using assms mem_convex_alt[of S xx yy cx cy] x y by auto
  3735     then have "cx *\<^sub>R xx + cy *\<^sub>R yy \<in> cone hull S"
  3736       using mem_cone_hull[of "(cx/(cx+cy)) *\<^sub>R xx + (cy/(cx+cy)) *\<^sub>R yy" S "cx+cy"] \<open>cx+cy>0\<close>
  3737       by (auto simp: scaleR_right_distrib)
  3738     then have "u *\<^sub>R x + v *\<^sub>R y \<in> cone hull S"
  3739       using x y by auto
  3740   }
  3741   moreover have "cx + cy \<le> 0 \<or> cx + cy > 0" by auto
  3742   ultimately show "u *\<^sub>R x + v *\<^sub>R y \<in> cone hull S" by blast
  3743 qed
  3744 
  3745 lemma cone_convex_hull:
  3746   assumes "cone S"
  3747   shows "cone (convex hull S)"
  3748 proof (cases "S = {}")
  3749   case True
  3750   then show ?thesis by auto
  3751 next
  3752   case False
  3753   then have *: "0 \<in> S \<and> (\<forall>c. c > 0 \<longrightarrow> (*\<^sub>R) c ` S = S)"
  3754     using cone_iff[of S] assms by auto
  3755   {
  3756     fix c :: real
  3757     assume "c > 0"
  3758     then have "(*\<^sub>R) c ` (convex hull S) = convex hull ((*\<^sub>R) c ` S)"
  3759       using convex_hull_scaling[of _ S] by auto
  3760     also have "\<dots> = convex hull S"
  3761       using * \<open>c > 0\<close> by auto
  3762     finally have "(*\<^sub>R) c ` (convex hull S) = convex hull S"
  3763       by auto
  3764   }
  3765   then have "0 \<in> convex hull S" "\<And>c. c > 0 \<Longrightarrow> ((*\<^sub>R) c ` (convex hull S)) = (convex hull S)"
  3766     using * hull_subset[of S convex] by auto
  3767   then show ?thesis
  3768     using \<open>S \<noteq> {}\<close> cone_iff[of "convex hull S"] by auto
  3769 qed
  3770 
  3771 subsection \<open>Radon's theorem\<close>
  3772 
  3773 text "Formalized by Lars Schewe."
  3774 
  3775 lemma Radon_ex_lemma:
  3776   assumes "finite c" "affine_dependent c"
  3777   shows "\<exists>u. sum u c = 0 \<and> (\<exists>v\<in>c. u v \<noteq> 0) \<and> sum (\<lambda>v. u v *\<^sub>R v) c = 0"
  3778 proof -
  3779   from assms(2)[unfolded affine_dependent_explicit]
  3780   obtain s u where
  3781       "finite s" "s \<subseteq> c" "sum u s = 0" "\<exists>v\<in>s. u v \<noteq> 0" "(\<Sum>v\<in>s. u v *\<^sub>R v) = 0"
  3782     by blast
  3783   then show ?thesis
  3784     apply (rule_tac x="\<lambda>v. if v\<in>s then u v else 0" in exI)
  3785     unfolding if_smult scaleR_zero_left and sum.inter_restrict[OF assms(1), symmetric]
  3786     apply (auto simp: Int_absorb1)
  3787     done
  3788 qed
  3789 
  3790 lemma Radon_s_lemma:
  3791   assumes "finite s"
  3792     and "sum f s = (0::real)"
  3793   shows "sum f {x\<in>s. 0 < f x} = - sum f {x\<in>s. f x < 0}"
  3794 proof -
  3795   have *: "\<And>x. (if f x < 0 then f x else 0) + (if 0 < f x then f x else 0) = f x"
  3796     by auto
  3797   show ?thesis
  3798     unfolding add_eq_0_iff[symmetric] and sum.inter_filter[OF assms(1)]
  3799       and sum.distrib[symmetric] and *
  3800     using assms(2)
  3801     by assumption
  3802 qed
  3803 
  3804 lemma Radon_v_lemma:
  3805   assumes "finite s"
  3806     and "sum f s = 0"
  3807     and "\<forall>x. g x = (0::real) \<longrightarrow> f x = (0::'a::euclidean_space)"
  3808   shows "(sum f {x\<in>s. 0 < g x}) = - sum f {x\<in>s. g x < 0}"
  3809 proof -
  3810   have *: "\<And>x. (if 0 < g x then f x else 0) + (if g x < 0 then f x else 0) = f x"
  3811     using assms(3) by auto
  3812   show ?thesis
  3813     unfolding eq_neg_iff_add_eq_0 and sum.inter_filter[OF assms(1)]
  3814       and sum.distrib[symmetric] and *
  3815     using assms(2)
  3816     apply assumption
  3817     done
  3818 qed
  3819 
  3820 lemma Radon_partition:
  3821   assumes "finite c" "affine_dependent c"
  3822   shows "\<exists>m p. m \<inter> p = {} \<and> m \<union> p = c \<and> (convex hull m) \<inter> (convex hull p) \<noteq> {}"
  3823 proof -
  3824   obtain u v where uv: "sum u c = 0" "v\<in>c" "u v \<noteq> 0"  "(\<Sum>v\<in>c. u v *\<^sub>R v) = 0"
  3825     using Radon_ex_lemma[OF assms] by auto
  3826   have fin: "finite {x \<in> c. 0 < u x}" "finite {x \<in> c. 0 > u x}"
  3827     using assms(1) by auto
  3828   define z  where "z = inverse (sum u {x\<in>c. u x > 0}) *\<^sub>R sum (\<lambda>x. u x *\<^sub>R x) {x\<in>c. u x > 0}"
  3829   have "sum u {x \<in> c. 0 < u x} \<noteq> 0"
  3830   proof (cases "u v \<ge> 0")
  3831     case False
  3832     then have "u v < 0" by auto
  3833     then show ?thesis
  3834     proof (cases "\<exists>w\<in>{x \<in> c. 0 < u x}. u w > 0")
  3835       case True
  3836       then show ?thesis
  3837         using sum_nonneg_eq_0_iff[of _ u, OF fin(1)] by auto
  3838     next
  3839       case False
  3840       then have "sum u c \<le> sum (\<lambda>x. if x=v then u v else 0) c"
  3841         apply (rule_tac sum_mono, auto)
  3842         done
  3843       then show ?thesis
  3844         unfolding sum.delta[OF assms(1)] using uv(2) and \<open>u v < 0\<close> and uv(1) by auto
  3845     qed
  3846   qed (insert sum_nonneg_eq_0_iff[of _ u, OF fin(1)] uv(2-3), auto)
  3847 
  3848   then have *: "sum u {x\<in>c. u x > 0} > 0"
  3849     unfolding less_le
  3850     apply (rule_tac conjI)
  3851     apply (rule_tac sum_nonneg, auto)
  3852     done
  3853   moreover have "sum u ({x \<in> c. 0 < u x} \<union> {x \<in> c. u x < 0}) = sum u c"
  3854     "(\<Sum>x\<in>{x \<in> c. 0 < u x} \<union> {x \<in> c. u x < 0}. u x *\<^sub>R x) = (\<Sum>x\<in>c. u x *\<^sub>R x)"
  3855     using assms(1)
  3856     apply (rule_tac[!] sum.mono_neutral_left, auto)
  3857     done
  3858   then have "sum u {x \<in> c. 0 < u x} = - sum u {x \<in> c. 0 > u x}"
  3859     "(\<Sum>x\<in>{x \<in> c. 0 < u x}. u x *\<^sub>R x) = - (\<Sum>x\<in>{x \<in> c. 0 > u x}. u x *\<^sub>R x)"
  3860     unfolding eq_neg_iff_add_eq_0
  3861     using uv(1,4)
  3862     by (auto simp: sum.union_inter_neutral[OF fin, symmetric])
  3863   moreover have "\<forall>x\<in>{v \<in> c. u v < 0}. 0 \<le> inverse (sum u {x \<in> c. 0 < u x}) * - u x"
  3864     apply rule
  3865     apply (rule mult_nonneg_nonneg)
  3866     using *
  3867     apply auto
  3868     done
  3869   ultimately have "z \<in> convex hull {v \<in> c. u v \<le> 0}"
  3870     unfolding convex_hull_explicit mem_Collect_eq
  3871     apply (rule_tac x="{v \<in> c. u v < 0}" in exI)
  3872     apply (rule_tac x="\<lambda>y. inverse (sum u {x\<in>c. u x > 0}) * - u y" in exI)
  3873     using assms(1) unfolding scaleR_scaleR[symmetric] scaleR_right.sum [symmetric] and z_def
  3874     apply (auto simp: sum_negf sum_distrib_left[symmetric])
  3875     done
  3876   moreover have "\<forall>x\<in>{v \<in> c. 0 < u v}. 0 \<le> inverse (sum u {x \<in> c. 0 < u x}) * u x"
  3877     apply rule
  3878     apply (rule mult_nonneg_nonneg)
  3879     using *
  3880     apply auto
  3881     done
  3882   then have "z \<in> convex hull {v \<in> c. u v > 0}"
  3883     unfolding convex_hull_explicit mem_Collect_eq
  3884     apply (rule_tac x="{v \<in> c. 0 < u v}" in exI)
  3885     apply (rule_tac x="\<lambda>y. inverse (sum u {x\<in>c. u x > 0}) * u y" in exI)
  3886     using assms(1)
  3887     unfolding scaleR_scaleR[symmetric] scaleR_right.sum [symmetric] and z_def
  3888     using *
  3889     apply (auto simp: sum_negf sum_distrib_left[symmetric])
  3890     done
  3891   ultimately show ?thesis
  3892     apply (rule_tac x="{v\<in>c. u v \<le> 0}" in exI)
  3893     apply (rule_tac x="{v\<in>c. u v > 0}" in exI, auto)
  3894     done
  3895 qed
  3896 
  3897 theorem Radon:
  3898   assumes "affine_dependent c"
  3899   obtains m p where "m \<subseteq> c" "p \<subseteq> c" "m \<inter> p = {}" "(convex hull m) \<inter> (convex hull p) \<noteq> {}"
  3900 proof -
  3901   from assms[unfolded affine_dependent_explicit]
  3902   obtain s u where
  3903       "finite s" "s \<subseteq> c" "sum u s = 0" "\<exists>v\<in>s. u v \<noteq> 0" "(\<Sum>v\<in>s. u v *\<^sub>R v) = 0"
  3904     by blast
  3905   then have *: "finite s" "affine_dependent s" and s: "s \<subseteq> c"
  3906     unfolding affine_dependent_explicit by auto
  3907   from Radon_partition[OF *]
  3908   obtain m p where "m \<inter> p = {}" "m \<union> p = s" "convex hull m \<inter> convex hull p \<noteq> {}"
  3909     by blast
  3910   then show ?thesis
  3911     apply (rule_tac that[of p m])
  3912     using s
  3913     apply auto
  3914     done
  3915 qed
  3916 
  3917 
  3918 subsection \<open>Helly's theorem\<close>
  3919 
  3920 lemma Helly_induct:
  3921   fixes f :: "'a::euclidean_space set set"
  3922   assumes "card f = n"
  3923     and "n \<ge> DIM('a) + 1"
  3924     and "\<forall>s\<in>f. convex s" "\<forall>t\<subseteq>f. card t = DIM('a) + 1 \<longrightarrow> \<Inter>t \<noteq> {}"
  3925   shows "\<Inter>f \<noteq> {}"
  3926   using assms
  3927 proof (induction n arbitrary: f)
  3928   case 0
  3929   then show ?case by auto
  3930 next
  3931   case (Suc n)
  3932   have "finite f"
  3933     using \<open>card f = Suc n\<close> by (auto intro: card_ge_0_finite)
  3934   show "\<Inter>f \<noteq> {}"
  3935   proof (cases "n = DIM('a)")
  3936     case True
  3937     then show ?thesis
  3938       by (simp add: Suc.prems(1) Suc.prems(4))
  3939   next
  3940     case False
  3941     have "\<Inter>(f - {s}) \<noteq> {}" if "s \<in> f" for s
  3942     proof (rule Suc.IH[rule_format])
  3943       show "card (f - {s}) = n"
  3944         by (simp add: Suc.prems(1) \<open>finite f\<close> that)
  3945       show "DIM('a) + 1 \<le> n"
  3946         using False Suc.prems(2) by linarith
  3947       show "\<And>t. \<lbrakk>t \<subseteq> f - {s}; card t = DIM('a) + 1\<rbrakk> \<Longrightarrow> \<Inter>t \<noteq> {}"
  3948         by (simp add: Suc.prems(4) subset_Diff_insert)
  3949     qed (use Suc in auto)
  3950     then have "\<forall>s\<in>f. \<exists>x. x \<in> \<Inter>(f - {s})"
  3951       by blast
  3952     then obtain X where X: "\<And>s. s\<in>f \<Longrightarrow> X s \<in> \<Inter>(f - {s})"
  3953       by metis
  3954     show ?thesis
  3955     proof (cases "inj_on X f")
  3956       case False
  3957       then obtain s t where "s\<noteq>t" and st: "s\<in>f" "t\<in>f" "X s = X t"
  3958         unfolding inj_on_def by auto
  3959       then have *: "\<Inter>f = \<Inter>(f - {s}) \<inter> \<Inter>(f - {t})" by auto
  3960       show ?thesis
  3961         by (metis "*" X disjoint_iff_not_equal st)
  3962     next
  3963       case True
  3964       then obtain m p where mp: "m \<inter> p = {}" "m \<union> p = X ` f" "convex hull m \<inter> convex hull p \<noteq> {}"
  3965         using Radon_partition[of "X ` f"] and affine_dependent_biggerset[of "X ` f"]
  3966         unfolding card_image[OF True] and \<open>card f = Suc n\<close>
  3967         using Suc(3) \<open>finite f\<close> and False
  3968         by auto
  3969       have "m \<subseteq> X ` f" "p \<subseteq> X ` f"
  3970         using mp(2) by auto
  3971       then obtain g h where gh:"m = X ` g" "p = X ` h" "g \<subseteq> f" "h \<subseteq> f"
  3972         unfolding subset_image_iff by auto
  3973       then have "f \<union> (g \<union> h) = f" by auto
  3974       then have f: "f = g \<union> h"
  3975         using inj_on_Un_image_eq_iff[of X f "g \<union> h"] and True
  3976         unfolding mp(2)[unfolded image_Un[symmetric] gh]
  3977         by auto
  3978       have *: "g \<inter> h = {}"
  3979         using mp(1)
  3980         unfolding gh
  3981         using inj_on_image_Int[OF True gh(3,4)]
  3982         by auto
  3983       have "convex hull (X ` h) \<subseteq> \<Inter>g" "convex hull (X ` g) \<subseteq> \<Inter>h"
  3984         by (rule hull_minimal; use X * f in \<open>auto simp: Suc.prems(3) convex_Inter\<close>)+
  3985       then show ?thesis
  3986         unfolding f using mp(3)[unfolded gh] by blast
  3987     qed
  3988   qed 
  3989 qed
  3990 
  3991 theorem Helly:
  3992   fixes f :: "'a::euclidean_space set set"
  3993   assumes "card f \<ge> DIM('a) + 1" "\<forall>s\<in>f. convex s"
  3994     and "\<And>t. \<lbrakk>t\<subseteq>f; card t = DIM('a) + 1\<rbrakk> \<Longrightarrow> \<Inter>t \<noteq> {}"
  3995   shows "\<Inter>f \<noteq> {}"
  3996   apply (rule Helly_induct)
  3997   using assms
  3998   apply auto
  3999   done
  4000 
  4001 subsection \<open>Epigraphs of convex functions\<close>
  4002 
  4003 definition%important "epigraph S (f :: _ \<Rightarrow> real) = {xy. fst xy \<in> S \<and> f (fst xy) \<le> snd xy}"
  4004 
  4005 lemma mem_epigraph: "(x, y) \<in> epigraph S f \<longleftrightarrow> x \<in> S \<and> f x \<le> y"
  4006   unfolding epigraph_def by auto
  4007 
  4008 lemma convex_epigraph: "convex (epigraph S f) \<longleftrightarrow> convex_on S f \<and> convex S"
  4009 proof safe
  4010   assume L: "convex (epigraph S f)"
  4011   then show "convex_on S f"
  4012     by (auto simp: convex_def convex_on_def epigraph_def)
  4013   show "convex S"
  4014     using L
  4015     apply (clarsimp simp: convex_def convex_on_def epigraph_def)
  4016     apply (erule_tac x=x in allE)
  4017     apply (erule_tac x="f x" in allE, safe)
  4018     apply (erule_tac x=y in allE)
  4019     apply (erule_tac x="f y" in allE)
  4020     apply (auto simp: )
  4021     done
  4022 next
  4023   assume "convex_on S f" "convex S"
  4024   then show "convex (epigraph S f)"
  4025     unfolding convex_def convex_on_def epigraph_def
  4026     apply safe
  4027      apply (rule_tac [2] y="u * f a + v * f aa" in order_trans)
  4028       apply (auto intro!:mult_left_mono add_mono)
  4029     done
  4030 qed
  4031 
  4032 lemma convex_epigraphI: "convex_on S f \<Longrightarrow> convex S \<Longrightarrow> convex (epigraph S f)"
  4033   unfolding convex_epigraph by auto
  4034 
  4035 lemma convex_epigraph_convex: "convex S \<Longrightarrow> convex_on S f \<longleftrightarrow> convex(epigraph S f)"
  4036   by (simp add: convex_epigraph)
  4037 
  4038 
  4039 subsubsection%unimportant \<open>Use this to derive general bound property of convex function\<close>
  4040 
  4041 lemma convex_on:
  4042   assumes "convex S"
  4043   shows "convex_on S f \<longleftrightarrow>
  4044     (\<forall>k u x. (\<forall>i\<in>{1..k::nat}. 0 \<le> u i \<and> x i \<in> S) \<and> sum u {1..k} = 1 \<longrightarrow>
  4045       f (sum (\<lambda>i. u i *\<^sub>R x i) {1..k}) \<le> sum (\<lambda>i. u i * f(x i)) {1..k})"
  4046 
  4047   unfolding convex_epigraph_convex[OF assms] convex epigraph_def Ball_def mem_Collect_eq
  4048   unfolding fst_sum snd_sum fst_scaleR snd_scaleR
  4049   apply safe
  4050     apply (drule_tac x=k in spec)
  4051     apply (drule_tac x=u in spec)
  4052     apply (drule_tac x="\<lambda>i. (x i, f (x i))" in spec)
  4053     apply simp
  4054   using assms[unfolded convex] apply simp
  4055   apply (rule_tac y="\<Sum>i = 1..k. u i * f (fst (x i))" in order_trans, force)
  4056    apply (rule sum_mono)
  4057    apply (erule_tac x=i in allE)
  4058   unfolding real_scaleR_def
  4059    apply (rule mult_left_mono)
  4060   using assms[unfolded convex] apply auto
  4061   done
  4062 
  4063 subsection%unimportant \<open>A bound within a convex hull\<close>
  4064 
  4065 lemma convex_on_convex_hull_bound:
  4066   assumes "convex_on (convex hull s) f"
  4067     and "\<forall>x\<in>s. f x \<le> b"
  4068   shows "\<forall>x\<in> convex hull s. f x \<le> b"
  4069 proof
  4070   fix x
  4071   assume "x \<in> convex hull s"
  4072   then obtain k u v where
  4073     obt: "\<forall>i\<in>{1..k::nat}. 0 \<le> u i \<and> v i \<in> s" "sum u {1..k} = 1" "(\<Sum>i = 1..k. u i *\<^sub>R v i) = x"
  4074     unfolding convex_hull_indexed mem_Collect_eq by auto
  4075   have "(\<Sum>i = 1..k. u i * f (v i)) \<le> b"
  4076     using sum_mono[of "{1..k}" "\<lambda>i. u i * f (v i)" "\<lambda>i. u i * b"]
  4077     unfolding sum_distrib_right[symmetric] obt(2) mult_1
  4078     apply (drule_tac meta_mp)
  4079     apply (rule mult_left_mono)
  4080     using assms(2) obt(1)
  4081     apply auto
  4082     done
  4083   then show "f x \<le> b"
  4084     using assms(1)[unfolded convex_on[OF convex_convex_hull], rule_format, of k u v]
  4085     unfolding obt(2-3)
  4086     using obt(1) and hull_subset[unfolded subset_eq, rule_format, of _ s]
  4087     by auto
  4088 qed
  4089 
  4090 lemma inner_sum_Basis[simp]: "i \<in> Basis \<Longrightarrow> (\<Sum>Basis) \<bullet> i = 1"
  4091   by (simp add: inner_sum_left sum.If_cases inner_Basis)
  4092 
  4093 lemma convex_set_plus:
  4094   assumes "convex S" and "convex T" shows "convex (S + T)"
  4095 proof -
  4096   have "convex (\<Union>x\<in> S. \<Union>y \<in> T. {x + y})"
  4097     using assms by (rule convex_sums)
  4098   moreover have "(\<Union>x\<in> S. \<Union>y \<in> T. {x + y}) = S + T"
  4099     unfolding set_plus_def by auto
  4100   finally show "convex (S + T)" .
  4101 qed
  4102 
  4103 lemma convex_set_sum:
  4104   assumes "\<And>i. i \<in> A \<Longrightarrow> convex (B i)"
  4105   shows "convex (\<Sum>i\<in>A. B i)"
  4106 proof (cases "finite A")
  4107   case True then show ?thesis using assms
  4108     by induct (auto simp: convex_set_plus)
  4109 qed auto
  4110 
  4111 lemma finite_set_sum:
  4112   assumes "finite A" and "\<forall>i\<in>A. finite (B i)" shows "finite (\<Sum>i\<in>A. B i)"
  4113   using assms by (induct set: finite, simp, simp add: finite_set_plus)
  4114 
  4115 lemma box_eq_set_sum_Basis:
  4116   shows "{x. \<forall>i\<in>Basis. x\<bullet>i \<in> B i} = (\<Sum>i\<in>Basis. image (\<lambda>x. x *\<^sub>R i) (B i))"
  4117   apply (subst set_sum_alt [OF finite_Basis], safe)
  4118   apply (fast intro: euclidean_representation [symmetric])
  4119   apply (subst inner_sum_left)
  4120 apply (rename_tac f)
  4121   apply (subgoal_tac "(\<Sum>x\<in>Basis. f x \<bullet> i) = f i \<bullet> i")
  4122   apply (drule (1) bspec)
  4123   apply clarsimp
  4124   apply (frule sum.remove [OF finite_Basis])
  4125   apply (erule trans, simp)
  4126   apply (rule sum.neutral, clarsimp)
  4127   apply (frule_tac x=i in bspec, assumption)
  4128   apply (drule_tac x=x in bspec, assumption, clarsimp)
  4129   apply (cut_tac u=x and v=i in inner_Basis, assumption+)
  4130   apply (rule ccontr, simp)
  4131   done
  4132 
  4133 lemma convex_hull_set_sum:
  4134   "convex hull (\<Sum>i\<in>A. B i) = (\<Sum>i\<in>A. convex hull (B i))"
  4135 proof (cases "finite A")
  4136   assume "finite A" then show ?thesis
  4137     by (induct set: finite, simp, simp add: convex_hull_set_plus)
  4138 qed simp
  4139 
  4140 
  4141 end