section \<open>Faces, Extreme Points, Polytopes, Polyhedra etc\<close>
text\<open>Ported from HOL Light by L C Paulson\<close>
theory Polytope
imports Cartesian_Euclidean_Space Path_Connected
begin
subsection \<open>Faces of a (usually convex) set\<close>
definition\<^marker>\<open>tag important\<close> face_of :: "['a::real_vector set, 'a set] \<Rightarrow> bool" (infixr "(face'_of)" 50)
where
"T face_of S \
T \<subseteq> S \<and> convex T \<and>
(\<forall>a \<in> S. \<forall>b \<in> S. \<forall>x \<in> T. x \<in> open_segment a b \<longrightarrow> a \<in> T \<and> b \<in> T)"
lemma face_ofD: "\T face_of S; x \ open_segment a b; a \ S; b \ S; x \ T\ \ a \ T \ b \ T"
unfolding face_of_def by blast
lemma face_of_translation_eq [simp]:
"((+) a ` T face_of (+) a ` S) \ T face_of S"
proof -
have *: "\a T S. T face_of S \ ((+) a ` T face_of (+) a ` S)"
by (simp add: face_of_def)
show ?thesis
by (force simp: image_comp o_def dest: * [where a = "-a"] intro: *)
qed
lemma face_of_linear_image:
assumes "linear f" "inj f"
shows "(f ` c face_of f ` S) \ c face_of S"
by (simp add: face_of_def inj_image_subset_iff inj_image_mem_iff open_segment_linear_image assms)
lemma face_of_refl: "convex S \ S face_of S"
by (auto simp: face_of_def)
lemma face_of_refl_eq: "S face_of S \ convex S"
by (auto simp: face_of_def)
lemma empty_face_of [iff]: "{} face_of S"
by (simp add: face_of_def)
lemma face_of_empty [simp]: "S face_of {} \ S = {}"
by (meson empty_face_of face_of_def subset_empty)
lemma face_of_trans [trans]: "\S face_of T; T face_of u\ \ S face_of u"
unfolding face_of_def by (safe; blast)
lemma face_of_face: "T face_of S \ (f face_of T \ f face_of S \ f \ T)"
unfolding face_of_def by (safe; blast)
lemma face_of_subset: "\F face_of S; F \ T; T \ S\ \ F face_of T"
unfolding face_of_def by (safe; blast)
lemma face_of_slice: "\F face_of S; convex T\ \ (F \ T) face_of (S \ T)"
unfolding face_of_def by (blast intro: convex_Int)
lemma face_of_Int: "\t1 face_of S; t2 face_of S\ \ (t1 \ t2) face_of S"
unfolding face_of_def by (blast intro: convex_Int)
lemma face_of_Inter: "\A \ {}; \T. T \ A \ T face_of S\ \ (\ A) face_of S"
unfolding face_of_def by (blast intro: convex_Inter)
lemma face_of_Int_Int: "\F face_of T; F' face_of t'\ \ (F \ F') face_of (T \ t')"
unfolding face_of_def by (blast intro: convex_Int)
lemma face_of_imp_subset: "T face_of S \ T \ S"
unfolding face_of_def by blast
proposition face_of_imp_eq_affine_Int:
fixes S :: "'a::euclidean_space set"
assumes S: "convex S" and T: "T face_of S"
shows "T = (affine hull T) \ S"
proof -
have "convex T" using T by (simp add: face_of_def)
have *: False if x: "x \ affine hull T" and "x \ S" "x \ T" and y: "y \ rel_interior T" for x y
proof -
obtain e where "e>0" and e: "cball y e \ affine hull T \ T"
using y by (auto simp: rel_interior_cball)
have "y \ x" "y \ S" "y \ T"
using face_of_imp_subset rel_interior_subset T that by blast+
then have zne: "\u. \u \ {0<..<1}; (1 - u) *\<^sub>R y + u *\<^sub>R x \ T\ \ False"
using \<open>x \<in> S\<close> \<open>x \<notin> T\<close> \<open>T face_of S\<close> unfolding face_of_def
by (meson greaterThanLessThan_iff in_segment(2))
have in01: "min (1/2) (e / norm (x - y)) \ {0<..<1}"
using \<open>y \<noteq> x\<close> \<open>e > 0\<close> by simp
have \<section>: "norm (min (1/2) (e / norm (x - y)) *\<^sub>R y - min (1/2) (e / norm (x - y)) *\<^sub>R x) \<le> e"
using \<open>e > 0\<close>
by (simp add: scaleR_diff_right [symmetric] norm_minus_commute min_mult_distrib_right)
show False
apply (rule zne [OF in01 e [THEN subsetD]])
using \<open>y \<in> T\<close>
apply (simp add: hull_inc mem_affine x)
by (simp add: dist_norm algebra_simps \<section>)
qed
show ?thesis
proof (rule subset_antisym)
show "T \ affine hull T \ S"
using assms by (simp add: hull_subset face_of_imp_subset)
show "affine hull T \ S \ T"
using "*" \<open>convex T\<close> rel_interior_eq_empty by fastforce
qed
qed
lemma face_of_imp_closed:
fixes S :: "'a::euclidean_space set"
assumes "convex S" "closed S" "T face_of S" shows "closed T"
by (metis affine_affine_hull affine_closed closed_Int face_of_imp_eq_affine_Int assms)
lemma face_of_Int_supporting_hyperplane_le_strong:
assumes "convex(S \ {x. a \ x = b})" and aleb: "\x. x \ S \ a \ x \ b"
shows "(S \ {x. a \ x = b}) face_of S"
proof -
have *: "a \ u = a \ x" if "x \ open_segment u v" "u \ S" "v \ S" and b: "b = a \ x"
for u v x
proof (rule antisym)
show "a \ u \ a \ x"
using aleb \<open>u \<in> S\<close> \<open>b = a \<bullet> x\<close> by blast
next
obtain \<xi> where "b = a \<bullet> ((1 - \<xi>) *\<^sub>R u + \<xi> *\<^sub>R v)" "0 < \<xi>" "\<xi> < 1"
using \<open>b = a \<bullet> x\<close> \<open>x \<in> open_segment u v\<close> in_segment
by (auto simp: open_segment_image_interval split: if_split_asm)
then have "b + \ * (a \ u) \ a \ u + \ * b"
using aleb [OF \<open>v \<in> S\<close>] by (simp add: algebra_simps)
then have "(1 - \) * b \ (1 - \) * (a \ u)"
by (simp add: algebra_simps)
then have "b \ a \ u"
using \<open>\<xi> < 1\<close> by auto
with b show "a \ x \ a \ u" by simp
qed
show ?thesis
using "*" open_segment_commute by (fastforce simp add: face_of_def assms)
qed
lemma face_of_Int_supporting_hyperplane_ge_strong:
"\convex(S \ {x. a \ x = b}); \x. x \ S \ a \ x \ b\
\<Longrightarrow> (S \<inter> {x. a \<bullet> x = b}) face_of S"
using face_of_Int_supporting_hyperplane_le_strong [of S "-a" "-b"] by simp
lemma face_of_Int_supporting_hyperplane_le:
"\convex S; \x. x \ S \ a \ x \ b\ \ (S \ {x. a \ x = b}) face_of S"
by (simp add: convex_Int convex_hyperplane face_of_Int_supporting_hyperplane_le_strong)
lemma face_of_Int_supporting_hyperplane_ge:
"\convex S; \x. x \ S \ a \ x \ b\ \ (S \ {x. a \ x = b}) face_of S"
by (simp add: convex_Int convex_hyperplane face_of_Int_supporting_hyperplane_ge_strong)
lemma face_of_imp_convex: "T face_of S \ convex T"
using face_of_def by blast
lemma face_of_imp_compact:
fixes S :: "'a::euclidean_space set"
shows "\convex S; compact S; T face_of S\ \ compact T"
by (meson bounded_subset compact_eq_bounded_closed face_of_imp_closed face_of_imp_subset)
lemma face_of_Int_subface:
"\A \ B face_of A; A \ B face_of B; C face_of A; D face_of B\
\<Longrightarrow> (C \<inter> D) face_of C \<and> (C \<inter> D) face_of D"
by (meson face_of_Int_Int face_of_face inf_le1 inf_le2)
lemma subset_of_face_of:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "u \ S" "T \ (rel_interior u) \ {}"
shows "u \ T"
proof
fix c
assume "c \ u"
obtain b where "b \ T" "b \ rel_interior u" using assms by auto
then obtain e where "e>0" "b \ u" and e: "cball b e \ affine hull u \ u"
by (auto simp: rel_interior_cball)
show "c \ T"
proof (cases "b=c")
case True with \<open>b \<in> T\<close> show ?thesis by blast
next
case False
define d where "d = b + (e / norm(b - c)) *\<^sub>R (b - c)"
have "d \ cball b e \ affine hull u"
using \<open>e > 0\<close> \<open>b \<in> u\<close> \<open>c \<in> u\<close>
by (simp add: d_def dist_norm hull_inc mem_affine_3_minus False)
with e have "d \ u" by blast
have nbc: "norm (b - c) + e > 0" using \<open>e > 0\<close>
by (metis add.commute le_less_trans less_add_same_cancel2 norm_ge_zero)
then have [simp]: "d \ c" using False scaleR_cancel_left [of "1 + (e / norm (b - c))" b c]
by (simp add: algebra_simps d_def) (simp add: field_split_simps)
have [simp]: "((e - e * e / (e + norm (b - c))) / norm (b - c)) = (e / (e + norm (b - c)))"
using False nbc
by (simp add: divide_simps) (simp add: algebra_simps)
have "b \ open_segment d c"
apply (simp add: open_segment_image_interval)
apply (simp add: d_def algebra_simps image_def)
apply (rule_tac x="e / (e + norm (b - c))" in bexI)
using False nbc \<open>0 < e\<close> by (auto simp: algebra_simps)
then have "d \ T \ c \ T"
by (meson \<open>b \<in> T\<close> \<open>c \<in> u\<close> \<open>d \<in> u\<close> assms face_ofD subset_iff)
then show ?thesis ..
qed
qed
lemma face_of_eq:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "U face_of S" "(rel_interior T) \ (rel_interior U) \ {}"
shows "T = U"
using assms
unfolding disjoint_iff_not_equal
by (metis IntI empty_iff face_of_imp_subset mem_rel_interior_ball subset_antisym subset_of_face_of)
lemma face_of_disjoint_rel_interior:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "T \ S"
shows "T \ rel_interior S = {}"
by (meson assms subset_of_face_of face_of_imp_subset order_refl subset_antisym)
lemma face_of_disjoint_interior:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "T \ S"
shows "T \ interior S = {}"
proof -
have "T \ interior S \ rel_interior S"
by (meson inf_sup_ord(2) interior_subset_rel_interior order.trans)
thus ?thesis
by (metis (no_types) Int_greatest assms face_of_disjoint_rel_interior inf_sup_ord(1) subset_empty)
qed
lemma face_of_subset_rel_boundary:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "T \ S"
shows "T \ (S - rel_interior S)"
by (meson DiffI assms disjoint_iff_not_equal face_of_disjoint_rel_interior face_of_imp_subset rev_subsetD subsetI)
lemma face_of_subset_rel_frontier:
fixes S :: "'a::real_normed_vector set"
assumes "T face_of S" "T \ S"
shows "T \ rel_frontier S"
using assms closure_subset face_of_disjoint_rel_interior face_of_imp_subset rel_frontier_def by fastforce
lemma face_of_aff_dim_lt:
fixes S :: "'a::euclidean_space set"
assumes "convex S" "T face_of S" "T \ S"
shows "aff_dim T < aff_dim S"
proof -
have "aff_dim T \ aff_dim S"
by (simp add: face_of_imp_subset aff_dim_subset assms)
moreover have "aff_dim T \ aff_dim S"
proof (cases "T = {}")
case True then show ?thesis
by (metis aff_dim_empty \<open>T \<noteq> S\<close>)
next case False then show ?thesis
by (metis Set.set_insert assms convex_rel_frontier_aff_dim dual_order.irrefl face_of_imp_convex face_of_subset_rel_frontier insert_not_empty subsetI)
qed
ultimately show ?thesis
by simp
qed
lemma subset_of_face_of_affine_hull:
fixes S :: "'a::euclidean_space set"
assumes T: "T face_of S" and "convex S" "U \ S" and dis: "\ disjnt (affine hull T) (rel_interior U)"
shows "U \ T"
proof (rule subset_of_face_of [OF T \<open>U \<subseteq> S\<close>])
show "T \ rel_interior U \ {}"
using face_of_imp_eq_affine_Int [OF \<open>convex S\<close> T] rel_interior_subset [of U] dis \<open>U \<subseteq> S\<close> disjnt_def
by fastforce
qed
lemma affine_hull_face_of_disjoint_rel_interior:
fixes S :: "'a::euclidean_space set"
assumes "convex S" "F face_of S" "F \ S"
shows "affine hull F \ rel_interior S = {}"
by (metis assms disjnt_def face_of_imp_subset order_refl subset_antisym subset_of_face_of_affine_hull)
lemma affine_diff_divide:
assumes "affine S" "k \ 0" "k \ 1" and xy: "x \ S" "y /\<^sub>R (1 - k) \ S"
shows "(x - y) /\<^sub>R k \ S"
proof -
have "inverse(k) *\<^sub>R (x - y) = (1 - inverse k) *\<^sub>R inverse(1 - k) *\<^sub>R y + inverse(k) *\<^sub>R x"
using assms
by (simp add: algebra_simps) (simp add: scaleR_left_distrib [symmetric] field_split_simps)
then show ?thesis
using \<open>affine S\<close> xy by (auto simp: affine_alt)
qed
proposition face_of_convex_hulls:
assumes S: "finite S" "T \ S" and disj: "affine hull T \ convex hull (S - T) = {}"
shows "(convex hull T) face_of (convex hull S)"
proof -
have fin: "finite T" "finite (S - T)" using assms
by (auto simp: finite_subset)
have *: "x \ convex hull T"
if x: "x \ convex hull S" and y: "y \ convex hull S" and w: "w \ convex hull T" "w \ open_segment x y"
for x y w
proof -
have waff: "w \ affine hull T"
using convex_hull_subset_affine_hull w by blast
obtain a b where a: "\i. i \ S \ 0 \ a i" and asum: "sum a S = 1" and aeqx: "(\i\S. a i *\<^sub>R i) = x"
and b: "\i. i \ S \ 0 \ b i" and bsum: "sum b S = 1" and beqy: "(\i\S. b i *\<^sub>R i) = y"
using x y by (auto simp: assms convex_hull_finite)
obtain u where "(1 - u) *\<^sub>R x + u *\<^sub>R y \ convex hull T" "x \ y" and weq: "w = (1 - u) *\<^sub>R x + u *\<^sub>R y"
and u01: "0 < u" "u < 1"
using w by (auto simp: open_segment_image_interval split: if_split_asm)
define c where "c i = (1 - u) * a i + u * b i" for i
have cge0: "\i. i \ S \ 0 \ c i"
using a b u01 by (simp add: c_def)
have sumc1: "sum c S = 1"
by (simp add: c_def sum.distrib sum_distrib_left [symmetric] asum bsum)
have sumci_xy: "(\i\S. c i *\<^sub>R i) = (1 - u) *\<^sub>R x + u *\<^sub>R y"
apply (simp add: c_def sum.distrib scaleR_left_distrib)
by (simp only: scaleR_scaleR [symmetric] Real_Vector_Spaces.scaleR_right.sum [symmetric] aeqx beqy)
show ?thesis
proof (cases "sum c (S - T) = 0")
case True
have ci0: "\i. i \ (S - T) \ c i = 0"
using True cge0 fin(2) sum_nonneg_eq_0_iff by auto
have a0: "a i = 0" if "i \ (S - T)" for i
using ci0 [OF that] u01 a [of i] b [of i] that
by (simp add: c_def Groups.ordered_comm_monoid_add_class.add_nonneg_eq_0_iff)
have [simp]: "sum a T = 1"
using assms by (metis sum.mono_neutral_cong_right a0 asum)
show ?thesis
apply (simp add: convex_hull_finite \<open>finite T\<close>)
apply (rule_tac x=a in exI)
using a0 assms
apply (auto simp: cge0 a aeqx [symmetric] sum.mono_neutral_right)
done
next
case False
define k where "k = sum c (S - T)"
have "k > 0" using False
unfolding k_def by (metis DiffD1 antisym_conv cge0 sum_nonneg not_less)
have weq_sumsum: "w = sum (\x. c x *\<^sub>R x) T + sum (\x. c x *\<^sub>R x) (S - T)"
by (metis (no_types) add.commute S(1) S(2) sum.subset_diff sumci_xy weq)
show ?thesis
proof (cases "k = 1")
case True
then have "sum c T = 0"
by (simp add: S k_def sum_diff sumc1)
then have [simp]: "sum c (S - T) = 1"
by (simp add: S sum_diff sumc1)
have ci0: "\i. i \ T \ c i = 0"
by (meson \<open>finite T\<close> \<open>sum c T = 0\<close> \<open>T \<subseteq> S\<close> cge0 sum_nonneg_eq_0_iff subsetCE)
then have [simp]: "(\i\S-T. c i *\<^sub>R i) = w"
by (simp add: weq_sumsum)
have "w \ convex hull (S - T)"
apply (simp add: convex_hull_finite fin)
apply (rule_tac x=c in exI)
apply (auto simp: cge0 weq True k_def)
done
then show ?thesis
using disj waff by blast
next
case False
then have sumcf: "sum c T = 1 - k"
by (simp add: S k_def sum_diff sumc1)
have ge0: "\x. x \ T \ 0 \ inverse (1 - k) * c x"
by (metis \<open>T \<subseteq> S\<close> cge0 inverse_nonnegative_iff_nonnegative mult_nonneg_nonneg subsetD sum_nonneg sumcf)
have eq1: "(\x\T. inverse (1 - k) * c x) = 1"
by (metis False eq_iff_diff_eq_0 mult.commute right_inverse sum_distrib_left sumcf)
have "(\i\T. c i *\<^sub>R i) /\<^sub>R (1 - k) \ convex hull T"
apply (simp add: convex_hull_finite fin)
apply (rule_tac x="\i. inverse (1-k) * c i" in exI)
by (metis (mono_tags, lifting) eq1 ge0 scaleR_scaleR scale_sum_right sum.cong)
with \<open>0 < k\<close> have "inverse(k) *\<^sub>R (w - sum (\<lambda>i. c i *\<^sub>R i) T) \<in> affine hull T"
by (simp add: affine_diff_divide [OF affine_affine_hull] False waff convex_hull_subset_affine_hull [THEN subsetD])
moreover have "inverse(k) *\<^sub>R (w - sum (\x. c x *\<^sub>R x) T) \ convex hull (S - T)"
apply (simp add: weq_sumsum convex_hull_finite fin)
apply (rule_tac x="\i. inverse k * c i" in exI)
using \<open>k > 0\<close> cge0
apply (auto simp: scaleR_right.sum sum_distrib_left [symmetric] k_def [symmetric])
done
ultimately show ?thesis
using disj by blast
qed
qed
qed
have [simp]: "convex hull T \ convex hull S"
by (simp add: \<open>T \<subseteq> S\<close> hull_mono)
show ?thesis
using open_segment_commute by (auto simp: face_of_def intro: *)
qed
proposition face_of_convex_hull_insert:
assumes "finite S" "a \ affine hull S" and T: "T face_of convex hull S"
shows "T face_of convex hull insert a S"
proof -
have "convex hull S face_of convex hull insert a S"
by (simp add: assms face_of_convex_hulls insert_Diff_if subset_insertI)
then show ?thesis
using T face_of_trans by blast
qed
proposition face_of_affine_trivial:
assumes "affine S" "T face_of S"
shows "T = {} \ T = S"
proof (rule ccontr, clarsimp)
assume "T \ {}" "T \ S"
then obtain a where "a \ T" by auto
then have "a \ S"
using \<open>T face_of S\<close> face_of_imp_subset by blast
have "S \ T"
proof
fix b assume "b \ S"
show "b \ T"
proof (cases "a = b")
case True with \<open>a \<in> T\<close> show ?thesis by auto
next
case False
then have "a \ 2 *\<^sub>R a - b"
by (simp add: scaleR_2)
with False have "a \ open_segment (2 *\<^sub>R a - b) b"
apply (clarsimp simp: open_segment_def closed_segment_def)
apply (rule_tac x="1/2" in exI)
by (simp add: algebra_simps)
moreover have "2 *\<^sub>R a - b \ S"
by (rule mem_affine [OF \<open>affine S\<close> \<open>a \<in> S\<close> \<open>b \<in> S\<close>, of 2 "-1", simplified])
moreover note \<open>b \<in> S\<close> \<open>a \<in> T\<close>
ultimately show ?thesis
by (rule face_ofD [OF \<open>T face_of S\<close>, THEN conjunct2])
qed
qed
then show False
using \<open>T \<noteq> S\<close> \<open>T face_of S\<close> face_of_imp_subset by blast
qed
lemma face_of_affine_eq:
"affine S \ (T face_of S \ T = {} \ T = S)"
using affine_imp_convex face_of_affine_trivial face_of_refl by auto
proposition Inter_faces_finite_altbound:
fixes T :: "'a::euclidean_space set set"
assumes cfaI: "\c. c \ T \ c face_of S"
shows "\F'. finite F' \ F' \ T \ card F' \ DIM('a) + 2 \ \F' = \T"
proof (cases "\F'. finite F' \ F' \ T \ card F' \ DIM('a) + 2 \ (\c. c \ T \ c \ (\F') \ (\F'))")
case True
then obtain c where c:
"\F'. \finite F'; F' \ T; card F' \ DIM('a) + 2\ \ c F' \ T \ c F' \ (\F') \ (\F')"
by metis
define d where "d = rec_nat {c{}} (\n r. insert (c r) r)"
have [simp]: "d 0 = {c {}}"
by (simp add: d_def)
have dSuc [simp]: "\n. d (Suc n) = insert (c (d n)) (d n)"
by (simp add: d_def)
have dn_notempty: "d n \ {}" for n
by (induction n) auto
have dn_le_Suc: "d n \ T \ finite(d n) \ card(d n) \ Suc n" if "n \ DIM('a) + 2" for n
using that
proof (induction n)
case 0
then show ?case by (simp add: c)
next
case (Suc n)
then show ?case by (auto simp: c card_insert_if)
qed
have aff_dim_le: "aff_dim(\(d n)) \ DIM('a) - int n" if "n \ DIM('a) + 2" for n
using that
proof (induction n)
case 0
then show ?case
by (simp add: aff_dim_le_DIM)
next
case (Suc n)
have fs: "\(d (Suc n)) face_of S"
by (meson Suc.prems cfaI dn_le_Suc dn_notempty face_of_Inter subsetCE)
have condn: "convex (\(d n))"
using Suc.prems nat_le_linear not_less_eq_eq
by (blast intro: face_of_imp_convex cfaI convex_Inter dest: dn_le_Suc)
have fdn: "\(d (Suc n)) face_of \(d n)"
by (metis (no_types, lifting) Inter_anti_mono Suc.prems dSuc cfaI dn_le_Suc dn_notempty face_of_Inter face_of_imp_subset face_of_subset subset_iff subset_insertI)
have ne: "\(d (Suc n)) \ \(d n)"
by (metis (no_types, lifting) Suc.prems Suc_leD c complete_lattice_class.Inf_insert dSuc dn_le_Suc less_irrefl order.trans)
have *: "\m::int. \d. \d'::int. d < d' \ d' \ m - n \ d \ m - of_nat(n+1)"
by arith
have "aff_dim (\(d (Suc n))) < aff_dim (\(d n))"
by (rule face_of_aff_dim_lt [OF condn fdn ne])
moreover have "aff_dim (\(d n)) \ int (DIM('a)) - int n"
using Suc by auto
ultimately
have "aff_dim (\(d (Suc n))) \ int (DIM('a)) - (n+1)" by arith
then show ?case by linarith
qed
have "aff_dim (\(d (DIM('a) + 2))) \ -2"
using aff_dim_le [OF order_refl] by simp
with aff_dim_geq [of "\(d (DIM('a) + 2))"] show ?thesis
using order.trans by fastforce
next
case False
then show ?thesis
apply simp
apply (erule ex_forward)
by blast
qed
lemma faces_of_translation:
"{F. F face_of image (\x. a + x) S} = image (image (\x. a + x)) {F. F face_of S}"
proof -
have "\F. F face_of (+) a ` S \ \G. G face_of S \ F = (+) a ` G"
by (metis face_of_imp_subset face_of_translation_eq subset_imageE)
then show ?thesis
by (auto simp: image_iff)
qed
proposition face_of_Times:
assumes "F face_of S" and "F' face_of S'"
shows "(F \ F') face_of (S \ S')"
proof -
have "F \ F' \ S \ S'"
using assms [unfolded face_of_def] by blast
moreover
have "convex (F \ F')"
using assms [unfolded face_of_def] by (blast intro: convex_Times)
moreover
have "a \ F \ a' \ F' \ b \ F \ b' \ F'"
if "a \ S" "b \ S" "a' \ S'" "b' \ S'" "x \ F \ F'" "x \ open_segment (a,a') (b,b')"
for a b a' b' x
proof (cases "b=a \ b'=a'")
case True with that show ?thesis
using assms
by (force simp: in_segment dest: face_ofD)
next
case False with assms [unfolded face_of_def] that show ?thesis
by (blast dest!: open_segment_PairD)
qed
ultimately show ?thesis
unfolding face_of_def by blast
qed
corollary face_of_Times_decomp:
fixes S :: "'a::euclidean_space set" and S' :: "'b::euclidean_space set"
shows "C face_of (S \ S') \ (\F F'. F face_of S \ F' face_of S' \ C = F \ F')"
(is "?lhs = ?rhs")
proof
assume C: ?lhs
show ?rhs
proof (cases "C = {}")
case True then show ?thesis by auto
next
case False
have 1: "fst ` C \ S" "snd ` C \ S'"
using C face_of_imp_subset by fastforce+
have "convex C"
using C by (metis face_of_imp_convex)
have conv: "convex (fst ` C)" "convex (snd ` C)"
by (simp_all add: \<open>convex C\<close> convex_linear_image linear_fst linear_snd)
have fstab: "a \ fst ` C \ b \ fst ` C"
if "a \ S" "b \ S" "x \ open_segment a b" "(x,x') \ C" for a b x x'
proof -
have *: "(x,x') \ open_segment (a,x') (b,x')"
using that by (auto simp: in_segment)
show ?thesis
using face_ofD [OF C *] that face_of_imp_subset [OF C] by force
qed
have fst: "fst ` C face_of S"
by (force simp: face_of_def 1 conv fstab)
have sndab: "a' \ snd ` C \ b' \ snd ` C"
if "a' \ S'" "b' \ S'" "x' \ open_segment a' b'" "(x,x') \ C" for a' b' x x'
proof -
have *: "(x,x') \ open_segment (x,a') (x,b')"
using that by (auto simp: in_segment)
show ?thesis
using face_ofD [OF C *] that face_of_imp_subset [OF C] by force
qed
have snd: "snd ` C face_of S'"
by (force simp: face_of_def 1 conv sndab)
have cc: "rel_interior C \ rel_interior (fst ` C) \ rel_interior (snd ` C)"
by (force simp: face_of_Times rel_interior_Times conv fst snd \<open>convex C\<close> linear_fst linear_snd rel_interior_convex_linear_image [symmetric])
have "C = fst ` C \ snd ` C"
proof (rule face_of_eq [OF C])
show "fst ` C \ snd ` C face_of S \ S'"
by (simp add: face_of_Times rel_interior_Times conv fst snd)
show "rel_interior C \ rel_interior (fst ` C \ snd ` C) \ {}"
using False rel_interior_eq_empty \<open>convex C\<close> cc
by (auto simp: face_of_Times rel_interior_Times conv fst)
qed
with fst snd show ?thesis by metis
qed
next
assume ?rhs with face_of_Times show ?lhs by auto
qed
lemma face_of_Times_eq:
fixes S :: "'a::euclidean_space set" and S' :: "'b::euclidean_space set"
shows "(F \ F') face_of (S \ S') \
F = {} \<or> F' = {} \<or> F face_of S \<and> F' face_of S'"
by (auto simp: face_of_Times_decomp times_eq_iff)
lemma hyperplane_face_of_halfspace_le: "{x. a \ x = b} face_of {x. a \ x \ b}"
proof -
have "{x. a \ x \ b} \ {x. a \ x = b} = {x. a \ x = b}"
by auto
with face_of_Int_supporting_hyperplane_le [OF convex_halfspace_le [of a b], of a b]
show ?thesis by auto
qed
lemma hyperplane_face_of_halfspace_ge: "{x. a \ x = b} face_of {x. a \ x \ b}"
proof -
have "{x. a \ x \ b} \ {x. a \ x = b} = {x. a \ x = b}"
by auto
with face_of_Int_supporting_hyperplane_ge [OF convex_halfspace_ge [of b a], of b a]
show ?thesis by auto
qed
lemma face_of_halfspace_le:
fixes a :: "'n::euclidean_space"
shows "F face_of {x. a \ x \ b} \
F = {} \<or> F = {x. a \<bullet> x = b} \<or> F = {x. a \<bullet> x \<le> b}"
(is "?lhs = ?rhs")
proof (cases "a = 0")
case True then show ?thesis
using face_of_affine_eq affine_UNIV by auto
next
case False
then have ine: "interior {x. a \ x \ b} \ {}"
using halfspace_eq_empty_lt interior_halfspace_le by blast
show ?thesis
proof
assume L: ?lhs
have "F face_of {x. a \ x = b}" if "F \ {x. a \ x \ b}"
proof -
have "F face_of rel_frontier {x. a \ x \ b}"
proof (rule face_of_subset [OF L])
show "F \ rel_frontier {x. a \ x \ b}"
by (simp add: L face_of_subset_rel_frontier that)
qed (force simp: rel_frontier_def closed_halfspace_le)
then show ?thesis
using False
by (simp add: frontier_halfspace_le rel_frontier_nonempty_interior [OF ine])
qed
with L show ?rhs
using affine_hyperplane face_of_affine_eq by blast
next
assume ?rhs
then show ?lhs
by (metis convex_halfspace_le empty_face_of face_of_refl hyperplane_face_of_halfspace_le)
qed
qed
lemma face_of_halfspace_ge:
fixes a :: "'n::euclidean_space"
shows "F face_of {x. a \ x \ b} \
F = {} \<or> F = {x. a \<bullet> x = b} \<or> F = {x. a \<bullet> x \<ge> b}"
using face_of_halfspace_le [of F "-a" "-b"] by simp
subsection\<open>Exposed faces\<close>
text\<open>That is, faces that are intersection with supporting hyperplane\<close>
definition\<^marker>\<open>tag important\<close> exposed_face_of :: "['a::euclidean_space set, 'a set] \<Rightarrow> bool"
(infixr "(exposed'_face'_of)" 50)
where "T exposed_face_of S \
T face_of S \<and> (\<exists>a b. S \<subseteq> {x. a \<bullet> x \<le> b} \<and> T = S \<inter> {x. a \<bullet> x = b})"
lemma empty_exposed_face_of [iff]: "{} exposed_face_of S"
apply (simp add: exposed_face_of_def)
apply (rule_tac x=0 in exI)
apply (rule_tac x=1 in exI, force)
done
lemma exposed_face_of_refl_eq [simp]: "S exposed_face_of S \ convex S"
proof
assume S: "convex S"
have "S \ {x. 0 \ x \ 0} \ S = S \ {x. 0 \ x = 0}"
by auto
with S show "S exposed_face_of S"
using exposed_face_of_def face_of_refl_eq by blast
qed (simp add: exposed_face_of_def face_of_refl_eq)
lemma exposed_face_of_refl: "convex S \ S exposed_face_of S"
by simp
lemma exposed_face_of:
"T exposed_face_of S \
T face_of S \<and>
(T = {} \<or> T = S \<or>
(\<exists>a b. a \<noteq> 0 \<and> S \<subseteq> {x. a \<bullet> x \<le> b} \<and> T = S \<inter> {x. a \<bullet> x = b}))"
proof (cases "T = {}")
case True then show ?thesis
by simp
next
case False
show ?thesis
proof (cases "T = S")
case True then show ?thesis
by (simp add: face_of_refl_eq)
next
case False
with \<open>T \<noteq> {}\<close> show ?thesis
apply (auto simp: exposed_face_of_def)
apply (metis inner_zero_left)
done
qed
qed
lemma exposed_face_of_Int_supporting_hyperplane_le:
"\convex S; \x. x \ S \ a \ x \ b\ \ (S \ {x. a \ x = b}) exposed_face_of S"
by (force simp: exposed_face_of_def face_of_Int_supporting_hyperplane_le)
lemma exposed_face_of_Int_supporting_hyperplane_ge:
"\convex S; \x. x \ S \ a \ x \ b\ \ (S \ {x. a \ x = b}) exposed_face_of S"
using exposed_face_of_Int_supporting_hyperplane_le [of S "-a" "-b"] by simp
proposition exposed_face_of_Int:
assumes "T exposed_face_of S"
and "u exposed_face_of S"
shows "(T \ u) exposed_face_of S"
proof -
obtain a b where T: "S \ {x. a \ x = b} face_of S"
and S: "S \ {x. a \ x \ b}"
and teq: "T = S \ {x. a \ x = b}"
using assms by (auto simp: exposed_face_of_def)
obtain a' b' where u: "S \ {x. a' \ x = b'} face_of S"
and s': "S \ {x. a' \ x \ b'}"
and ueq: "u = S \ {x. a' \ x = b'}"
using assms by (auto simp: exposed_face_of_def)
have tu: "T \ u face_of S"
using T teq u ueq by (simp add: face_of_Int)
have ss: "S \ {x. (a + a') \ x \ b + b'}"
using S s' by (force simp: inner_left_distrib)
show ?thesis
apply (simp add: exposed_face_of_def tu)
apply (rule_tac x="a+a'" in exI)
apply (rule_tac x="b+b'" in exI)
using S s'
apply (fastforce simp: ss inner_left_distrib teq ueq)
done
qed
proposition exposed_face_of_Inter:
fixes P :: "'a::euclidean_space set set"
assumes "P \ {}"
and "\T. T \ P \ T exposed_face_of S"
shows "\P exposed_face_of S"
proof -
obtain Q where "finite Q" and QsubP: "Q \ P" "card Q \ DIM('a) + 2" and IntQ: "\Q = \P"
using Inter_faces_finite_altbound [of P S] assms [unfolded exposed_face_of]
by force
show ?thesis
proof (cases "Q = {}")
case True then show ?thesis
by (metis IntQ Inter_UNIV_conv(2) assms(1) assms(2) ex_in_conv)
next
case False
have "Q \ {T. T exposed_face_of S}"
using QsubP assms by blast
moreover have "Q \ {T. T exposed_face_of S} \ \Q exposed_face_of S"
using \<open>finite Q\<close> False
by (induction Q rule: finite_induct; use exposed_face_of_Int in fastforce)
ultimately show ?thesis
by (simp add: IntQ)
qed
qed
proposition exposed_face_of_sums:
assumes "convex S" and "convex T"
and "F exposed_face_of {x + y | x y. x \ S \ y \ T}"
(is "F exposed_face_of ?ST")
obtains k l
where "k exposed_face_of S" "l exposed_face_of T"
"F = {x + y | x y. x \ k \ y \ l}"
proof (cases "F = {}")
case True then show ?thesis
using that by blast
next
case False
show ?thesis
proof (cases "F = ?ST")
case True then show ?thesis
using assms exposed_face_of_refl_eq that by blast
next
case False
obtain p where "p \ F" using \F \ {}\ by blast
moreover
obtain u z where T: "?ST \ {x. u \ x = z} face_of ?ST"
and S: "?ST \ {x. u \ x \ z}"
and feq: "F = ?ST \ {x. u \ x = z}"
using assms by (auto simp: exposed_face_of_def)
ultimately obtain a0 b0
where p: "p = a0 + b0" and "a0 \ S" "b0 \ T" and z: "u \ p = z"
by auto
have lez: "u \ (x + y) \ z" if "x \ S" "y \ T" for x y
using S that by auto
have sef: "S \ {x. u \ x = u \ a0} exposed_face_of S"
proof (rule exposed_face_of_Int_supporting_hyperplane_le [OF \<open>convex S\<close>])
show "\x. x \ S \ u \ x \ u \ a0"
by (metis p z add_le_cancel_right inner_right_distrib lez [OF _ \<open>b0 \<in> T\<close>])
qed
have tef: "T \ {x. u \ x = u \ b0} exposed_face_of T"
proof (rule exposed_face_of_Int_supporting_hyperplane_le [OF \<open>convex T\<close>])
show "\x. x \ T \ u \ x \ u \ b0"
by (metis p z add.commute add_le_cancel_right inner_right_distrib lez [OF \<open>a0 \<in> S\<close>])
qed
have "{x + y |x y. x \ S \ u \ x = u \ a0 \ y \ T \ u \ y = u \ b0} \ F"
by (auto simp: feq) (metis inner_right_distrib p z)
moreover have "F \ {x + y |x y. x \ S \ u \ x = u \ a0 \ y \ T \ u \ y = u \ b0}"
proof -
have "\x y. \z = u \ (x + y); x \ S; y \ T\
\<Longrightarrow> u \<bullet> x = u \<bullet> a0 \<and> u \<bullet> y = u \<bullet> b0"
using z p \<open>a0 \<in> S\<close> \<open>b0 \<in> T\<close>
apply (simp add: inner_right_distrib)
apply (metis add_le_cancel_right antisym lez [unfolded inner_right_distrib] add.commute)
done
then show ?thesis
using feq by blast
qed
ultimately have "F = {x + y |x y. x \ S \ {x. u \ x = u \ a0} \ y \ T \ {x. u \ x = u \ b0}}"
by blast
then show ?thesis
by (rule that [OF sef tef])
qed
qed
proposition exposed_face_of_parallel:
"T exposed_face_of S \
T face_of S \<and>
(\<exists>a b. S \<subseteq> {x. a \<bullet> x \<le> b} \<and> T = S \<inter> {x. a \<bullet> x = b} \<and>
(T \<noteq> {} \<longrightarrow> T \<noteq> S \<longrightarrow> a \<noteq> 0) \<and>
(T \<noteq> S \<longrightarrow> (\<forall>w \<in> affine hull S. (w + a) \<in> affine hull S)))"
(is "?lhs = ?rhs")
proof
assume ?lhs then show ?rhs
proof (clarsimp simp: exposed_face_of_def)
fix a b
assume faceS: "S \ {x. a \ x = b} face_of S" and Ssub: "S \ {x. a \ x \ b}"
show "\c d. S \ {x. c \ x \ d} \
S \<inter> {x. a \<bullet> x = b} = S \<inter> {x. c \<bullet> x = d} \<and>
(S \<inter> {x. a \<bullet> x = b} \<noteq> {} \<longrightarrow> S \<inter> {x. a \<bullet> x = b} \<noteq> S \<longrightarrow> c \<noteq> 0) \<and>
(S \<inter> {x. a \<bullet> x = b} \<noteq> S \<longrightarrow> (\<forall>w \<in> affine hull S. w + c \<in> affine hull S))"
proof (cases "affine hull S \ {x. -a \ x \ -b} = {} \ affine hull S \ {x. - a \ x \ - b}")
case True
then show ?thesis
proof
assume "affine hull S \ {x. - a \ x \ - b} = {}"
then show ?thesis
apply (rule_tac x="0" in exI)
apply (rule_tac x="1" in exI)
using hull_subset by fastforce
next
assume "affine hull S \ {x. - a \ x \ - b}"
then show ?thesis
apply (rule_tac x="0" in exI)
apply (rule_tac x="0" in exI)
using Ssub hull_subset by fastforce
qed
next
case False
then obtain a' b' where "a' \ 0"
and le: "affine hull S \ {x. a' \ x \ b'} = affine hull S \ {x. - a \ x \ - b}"
and eq: "affine hull S \ {x. a' \ x = b'} = affine hull S \ {x. - a \ x = - b}"
and mem: "\w. w \ affine hull S \ w + a' \ affine hull S"
using affine_parallel_slice affine_affine_hull by metis
show ?thesis
proof (intro conjI impI allI ballI exI)
have *: "S \ - (affine hull S \ {x. P x}) \ affine hull S \ {x. Q x} \ S \ {x. \ P x \ Q x}"
for P Q
using hull_subset by fastforce
have "S \ {x. \ (a' \ x \ b') \ a' \ x = b'}"
by (rule *) (use le eq Ssub in auto)
then show "S \ {x. - a' \ x \ - b'}"
by auto
show "S \ {x. a \ x = b} = S \ {x. - a' \ x = - b'}"
using eq hull_subset [of S affine] by force
show "\S \ {x. a \ x = b} \ {}; S \ {x. a \ x = b} \ S\ \ - a' \ 0"
using \<open>a' \<noteq> 0\<close> by auto
show "w + - a' \ affine hull S"
if "S \ {x. a \ x = b} \ S" "w \ affine hull S" for w
proof -
have "w + 1 *\<^sub>R (w - (w + a')) \ affine hull S"
using affine_affine_hull mem mem_affine_3_minus that(2) by blast
then show ?thesis by simp
qed
qed
qed
qed
next
assume ?rhs then show ?lhs
unfolding exposed_face_of_def by blast
qed
subsection\<open>Extreme points of a set: its singleton faces\<close>
definition\<^marker>\<open>tag important\<close> extreme_point_of :: "['a::real_vector, 'a set] \<Rightarrow> bool"
(infixr "(extreme'_point'_of)" 50)
where "x extreme_point_of S \
x \<in> S \<and> (\<forall>a \<in> S. \<forall>b \<in> S. x \<notin> open_segment a b)"
lemma extreme_point_of_stillconvex:
"convex S \ (x extreme_point_of S \ x \ S \ convex(S - {x}))"
by (fastforce simp add: convex_contains_segment extreme_point_of_def open_segment_def)
lemma face_of_singleton:
"{x} face_of S \ x extreme_point_of S"
by (fastforce simp add: extreme_point_of_def face_of_def)
lemma extreme_point_not_in_REL_INTERIOR:
fixes S :: "'a::real_normed_vector set"
shows "\x extreme_point_of S; S \ {x}\ \ x \ rel_interior S"
by (metis disjoint_iff face_of_disjoint_rel_interior face_of_singleton insertI1)
lemma extreme_point_not_in_interior:
fixes S :: "'a::{real_normed_vector, perfect_space} set"
assumes "x extreme_point_of S" shows "x \ interior S"
proof (cases "S = {x}")
case False
then show ?thesis
by (meson assms subsetD extreme_point_not_in_REL_INTERIOR interior_subset_rel_interior)
qed (simp add: empty_interior_finite)
lemma extreme_point_of_face:
"F face_of S \ v extreme_point_of F \ v extreme_point_of S \ v \ F"
by (meson empty_subsetI face_of_face face_of_singleton insert_subset)
lemma extreme_point_of_convex_hull:
"x extreme_point_of (convex hull S) \ x \ S"
using hull_minimal [of S "(convex hull S) - {x}" convex]
using hull_subset [of S convex]
by (force simp add: extreme_point_of_stillconvex)
proposition extreme_points_of_convex_hull:
"{x. x extreme_point_of (convex hull S)} \ S"
using extreme_point_of_convex_hull by auto
lemma extreme_point_of_empty [simp]: "\ (x extreme_point_of {})"
by (simp add: extreme_point_of_def)
lemma extreme_point_of_singleton [iff]: "x extreme_point_of {a} \ x = a"
using extreme_point_of_stillconvex by auto
lemma extreme_point_of_translation_eq:
"(a + x) extreme_point_of (image (\x. a + x) S) \ x extreme_point_of S"
by (auto simp: extreme_point_of_def)
lemma extreme_points_of_translation:
"{x. x extreme_point_of (image (\x. a + x) S)} =
(\<lambda>x. a + x) ` {x. x extreme_point_of S}"
using extreme_point_of_translation_eq
by auto (metis (no_types, lifting) image_iff mem_Collect_eq minus_add_cancel)
lemma extreme_points_of_translation_subtract:
"{x. x extreme_point_of (image (\x. x - a) S)} =
(\<lambda>x. x - a) ` {x. x extreme_point_of S}"
using extreme_points_of_translation [of "- a" S]
by simp
lemma extreme_point_of_Int:
"\x extreme_point_of S; x extreme_point_of T\ \ x extreme_point_of (S \ T)"
by (simp add: extreme_point_of_def)
lemma extreme_point_of_Int_supporting_hyperplane_le:
"\S \ {x. a \ x = b} = {c}; \x. x \ S \ a \ x \ b\ \ c extreme_point_of S"
by (metis convex_singleton face_of_Int_supporting_hyperplane_le_strong face_of_singleton)
lemma extreme_point_of_Int_supporting_hyperplane_ge:
"\S \ {x. a \ x = b} = {c}; \x. x \ S \ a \ x \ b\ \ c extreme_point_of S"
using extreme_point_of_Int_supporting_hyperplane_le [of S "-a" "-b" c]
by simp
lemma exposed_point_of_Int_supporting_hyperplane_le:
"\S \ {x. a \ x = b} = {c}; \x. x \ S \ a \ x \ b\ \ {c} exposed_face_of S"
unfolding exposed_face_of_def
by (force simp: face_of_singleton extreme_point_of_Int_supporting_hyperplane_le)
lemma exposed_point_of_Int_supporting_hyperplane_ge:
"\S \ {x. a \ x = b} = {c}; \x. x \ S \ a \ x \ b\ \ {c} exposed_face_of S"
using exposed_point_of_Int_supporting_hyperplane_le [of S "-a" "-b" c]
by simp
lemma extreme_point_of_convex_hull_insert:
assumes "finite S" "a \ convex hull S"
shows "a extreme_point_of (convex hull (insert a S))"
proof (cases "a \ S")
case False
then show ?thesis
using face_of_convex_hulls [of "insert a S" "{a}"] assms
by (auto simp: face_of_singleton hull_same)
qed (use assms in \<open>simp add: hull_inc\<close>)
subsection\<open>Facets\<close>
definition\<^marker>\<open>tag important\<close> facet_of :: "['a::euclidean_space set, 'a set] \<Rightarrow> bool"
(infixr "(facet'_of)" 50)
where "F facet_of S \ F face_of S \ F \ {} \ aff_dim F = aff_dim S - 1"
lemma facet_of_empty [simp]: "\ S facet_of {}"
by (simp add: facet_of_def)
lemma facet_of_irrefl [simp]: "\ S facet_of S "
by (simp add: facet_of_def)
lemma facet_of_imp_face_of: "F facet_of S \ F face_of S"
by (simp add: facet_of_def)
lemma facet_of_imp_subset: "F facet_of S \ F \ S"
by (simp add: face_of_imp_subset facet_of_def)
lemma hyperplane_facet_of_halfspace_le:
"a \ 0 \ {x. a \ x = b} facet_of {x. a \ x \ b}"
unfolding facet_of_def hyperplane_eq_empty
by (auto simp: hyperplane_face_of_halfspace_ge hyperplane_face_of_halfspace_le
Suc_leI of_nat_diff aff_dim_halfspace_le)
lemma hyperplane_facet_of_halfspace_ge:
"a \ 0 \ {x. a \ x = b} facet_of {x. a \ x \ b}"
unfolding facet_of_def hyperplane_eq_empty
by (auto simp: hyperplane_face_of_halfspace_le hyperplane_face_of_halfspace_ge
Suc_leI of_nat_diff aff_dim_halfspace_ge)
lemma facet_of_halfspace_le:
"F facet_of {x. a \ x \ b} \ a \ 0 \ F = {x. a \ x = b}"
(is "?lhs = ?rhs")
proof
assume c: ?lhs
with c facet_of_irrefl show ?rhs
by (force simp: aff_dim_halfspace_le facet_of_def face_of_halfspace_le cong: conj_cong split: if_split_asm)
next
assume ?rhs then show ?lhs
by (simp add: hyperplane_facet_of_halfspace_le)
qed
lemma facet_of_halfspace_ge:
"F facet_of {x. a \ x \ b} \ a \ 0 \ F = {x. a \ x = b}"
using facet_of_halfspace_le [of F "-a" "-b"] by simp
subsection \<open>Edges: faces of affine dimension 1\<close> (*FIXME too small subsection, rearrange? *)
definition\<^marker>\<open>tag important\<close> edge_of :: "['a::euclidean_space set, 'a set] \<Rightarrow> bool" (infixr "(edge'_of)" 50)
where "e edge_of S \ e face_of S \ aff_dim e = 1"
lemma edge_of_imp_subset:
"S edge_of T \ S \ T"
by (simp add: edge_of_def face_of_imp_subset)
subsection\<open>Existence of extreme points\<close>
proposition different_norm_3_collinear_points:
fixes a :: "'a::euclidean_space"
assumes "x \ open_segment a b" "norm(a) = norm(b)" "norm(x) = norm(b)"
shows False
proof -
obtain u where "norm ((1 - u) *\<^sub>R a + u *\<^sub>R b) = norm b"
and "a \ b"
and u01: "0 < u" "u < 1"
using assms by (auto simp: open_segment_image_interval if_splits)
then have "(1 - u) *\<^sub>R a \ (1 - u) *\<^sub>R a + ((1 - u) * 2) *\<^sub>R a \ u *\<^sub>R b =
(1 - u * u) *\<^sub>R (a \<bullet> a)"
using assms by (simp add: norm_eq algebra_simps inner_commute)
then have "(1 - u) *\<^sub>R ((1 - u) *\<^sub>R a \ a + (2 * u) *\<^sub>R a \ b) =
(1 - u) *\<^sub>R ((1 + u) *\<^sub>R (a \<bullet> a))"
by (simp add: algebra_simps)
then have "(1 - u) *\<^sub>R (a \ a) + (2 * u) *\<^sub>R (a \ b) = (1 + u) *\<^sub>R (a \ a)"
using u01 by auto
then have "a \ b = a \ a"
using u01 by (simp add: algebra_simps)
then have "a = b"
using \<open>norm(a) = norm(b)\<close> norm_eq vector_eq by fastforce
then show ?thesis
using \<open>a \<noteq> b\<close> by force
qed
proposition extreme_point_exists_convex:
fixes S :: "'a::euclidean_space set"
assumes "compact S" "convex S" "S \ {}"
obtains x where "x extreme_point_of S"
proof -
obtain x where "x \ S" and xsup: "\y. y \ S \ norm y \ norm x"
using distance_attains_sup [of S 0] assms by auto
have False if "a \ S" "b \ S" and x: "x \ open_segment a b" for a b
proof -
have noax: "norm a \ norm x" and nobx: "norm b \ norm x" using xsup that by auto
have "a \ b"
using empty_iff open_segment_idem x by auto
show False
by (metis dist_0_norm dist_decreases_open_segment noax nobx not_le x)
qed
then show ?thesis
by (meson \<open>x \<in> S\<close> extreme_point_of_def that)
qed
subsection\<open>Krein-Milman, the weaker form\<close>
proposition Krein_Milman:
fixes S :: "'a::euclidean_space set"
assumes "compact S" "convex S"
shows "S = closure(convex hull {x. x extreme_point_of S})"
proof (cases "S = {}")
case True then show ?thesis by simp
next
case False
have "closed S"
by (simp add: \<open>compact S\<close> compact_imp_closed)
have "closure (convex hull {x. x extreme_point_of S}) \ S"
by (simp add: \<open>closed S\<close> assms closure_minimal extreme_point_of_def hull_minimal)
moreover have "u \ closure (convex hull {x. x extreme_point_of S})"
if "u \ S" for u
proof (rule ccontr)
assume unot: "u \ closure(convex hull {x. x extreme_point_of S})"
then obtain a b where "a \ u < b"
and ab: "\x. x \ closure(convex hull {x. x extreme_point_of S}) \ b < a \ x"
using separating_hyperplane_closed_point [of "closure(convex hull {x. x extreme_point_of S})"]
by blast
have "continuous_on S ((\) a)"
by (rule continuous_intros)+
then obtain m where "m \ S" and m: "\y. y \ S \ a \ m \ a \ y"
using continuous_attains_inf [of S "\x. a \ x"] \compact S\ \u \ S\
by auto
define T where "T = S \ {x. a \ x = a \ m}"
have "m \ T"
by (simp add: T_def \<open>m \<in> S\<close>)
moreover have "compact T"
by (simp add: T_def compact_Int_closed [OF \<open>compact S\<close> closed_hyperplane])
moreover have "convex T"
by (simp add: T_def convex_Int [OF \<open>convex S\<close> convex_hyperplane])
ultimately obtain v where v: "v extreme_point_of T"
using extreme_point_exists_convex [of T] by auto
then have "{v} face_of T"
by (simp add: face_of_singleton)
also have "T face_of S"
by (simp add: T_def m face_of_Int_supporting_hyperplane_ge [OF \<open>convex S\<close>])
finally have "v extreme_point_of S"
by (simp add: face_of_singleton)
then have "b < a \ v"
using closure_subset by (simp add: closure_hull hull_inc ab)
then show False
using \<open>a \<bullet> u < b\<close> \<open>{v} face_of T\<close> face_of_imp_subset m T_def that by fastforce
qed
ultimately show ?thesis
by blast
qed
text\<open>Now the sharper form.\<close>
lemma Krein_Milman_Minkowski_aux:
fixes S :: "'a::euclidean_space set"
assumes n: "dim S = n" and S: "compact S" "convex S" "0 \ S"
shows "0 \ convex hull {x. x extreme_point_of S}"
using n S
proof (induction n arbitrary: S rule: less_induct)
case (less n S) show ?case
proof (cases "0 \ rel_interior S")
case True with Krein_Milman less.prems
show ?thesis
by (metis subsetD convex_convex_hull convex_rel_interior_closure rel_interior_subset)
next
case False
have "rel_interior S \ {}"
by (simp add: rel_interior_convex_nonempty_aux less)
then obtain c where c: "c \ rel_interior S" by blast
obtain a where "a \ 0"
and le_ay: "\y. y \ S \ a \ 0 \ a \ y"
and less_ay: "\y. y \ rel_interior S \ a \ 0 < a \ y"
by (blast intro: supporting_hyperplane_rel_boundary intro!: less False)
have face: "S \ {x. a \ x = 0} face_of S"
using face_of_Int_supporting_hyperplane_ge le_ay \<open>convex S\<close> by auto
then have co: "compact (S \ {x. a \ x = 0})" "convex (S \ {x. a \ x = 0})"
using less.prems by (blast intro: face_of_imp_compact face_of_imp_convex)+
have "a \ y = 0" if "y \ span (S \ {x. a \ x = 0})" for y
proof -
have "y \ span {x. a \ x = 0}"
by (metis inf.cobounded2 span_mono subsetCE that)
then show ?thesis
by (blast intro: span_induct [OF _ subspace_hyperplane])
qed
then have "dim (S \ {x. a \ x = 0}) < n"
by (metis (no_types) less_ay c subsetD dim_eq_span inf.strict_order_iff
inf_le1 \<open>dim S = n\<close> not_le rel_interior_subset span_0 span_base)
then have "0 \ convex hull {x. x extreme_point_of (S \ {x. a \ x = 0})}"
by (rule less.IH) (auto simp: co less.prems)
then show ?thesis
by (metis (mono_tags, lifting) Collect_mono_iff face extreme_point_of_face hull_mono subset_iff)
qed
qed
theorem Krein_Milman_Minkowski:
fixes S :: "'a::euclidean_space set"
assumes "compact S" "convex S"
shows "S = convex hull {x. x extreme_point_of S}"
proof
show "S \ convex hull {x. x extreme_point_of S}"
proof
fix a assume [simp]: "a \ S"
have 1: "compact ((+) (- a) ` S)"
by (simp add: \<open>compact S\<close> compact_translation_subtract cong: image_cong_simp)
have 2: "convex ((+) (- a) ` S)"
by (simp add: \<open>convex S\<close> compact_translation_subtract)
show a_invex: "a \ convex hull {x. x extreme_point_of S}"
using Krein_Milman_Minkowski_aux [OF refl 1 2]
convex_hull_translation [of "-a"]
by (auto simp: extreme_points_of_translation_subtract translation_assoc cong: image_cong_simp)
qed
next
show "convex hull {x. x extreme_point_of S} \ S"
proof -
have "{a. a extreme_point_of S} \ S"
using extreme_point_of_def by blast
then show ?thesis
by (simp add: \<open>convex S\<close> hull_minimal)
qed
qed
subsection\<open>Applying it to convex hulls of explicitly indicated finite sets\<close>
corollary Krein_Milman_polytope:
fixes S :: "'a::euclidean_space set"
shows
"finite S
\<Longrightarrow> convex hull S =
convex hull {x. x extreme_point_of (convex hull S)}"
by (simp add: Krein_Milman_Minkowski finite_imp_compact_convex_hull)
lemma extreme_points_of_convex_hull_eq:
fixes S :: "'a::euclidean_space set"
shows
"\compact S; \T. T \ S \ convex hull T \ convex hull S\
\<Longrightarrow> {x. x extreme_point_of (convex hull S)} = S"
by (metis (full_types) Krein_Milman_Minkowski compact_convex_hull convex_convex_hull extreme_points_of_convex_hull psubsetI)
lemma extreme_point_of_convex_hull_eq:
fixes S :: "'a::euclidean_space set"
shows
"\compact S; \T. T \ S \ convex hull T \ convex hull S\
\<Longrightarrow> (x extreme_point_of (convex hull S) \<longleftrightarrow> x \<in> S)"
using extreme_points_of_convex_hull_eq by auto
lemma extreme_point_of_convex_hull_convex_independent:
fixes S :: "'a::euclidean_space set"
assumes "compact S" and S: "\a. a \ S \ a \ convex hull (S - {a})"
shows "(x extreme_point_of (convex hull S) \ x \ S)"
proof -
have "convex hull T \ convex hull S" if "T \ S" for T
proof -
obtain a where "T \ S" "a \ S" "a \ T" using \T \ S\ by blast
then show ?thesis
by (metis (full_types) Diff_eq_empty_iff Diff_insert0 S hull_mono hull_subset insert_Diff_single subsetCE)
qed
then show ?thesis
by (rule extreme_point_of_convex_hull_eq [OF \<open>compact S\<close>])
qed
lemma extreme_point_of_convex_hull_affine_independent:
fixes S :: "'a::euclidean_space set"
shows
"\ affine_dependent S
\<Longrightarrow> (x extreme_point_of (convex hull S) \<longleftrightarrow> x \<in> S)"
by (metis aff_independent_finite affine_dependent_def affine_hull_convex_hull extreme_point_of_convex_hull_convex_independent finite_imp_compact hull_inc)
text\<open>Elementary proofs exist, not requiring Euclidean spaces and all this development\<close>
lemma extreme_point_of_convex_hull_2:
fixes x :: "'a::euclidean_space"
shows "x extreme_point_of (convex hull {a,b}) \ x = a \ x = b"
proof -
have "x extreme_point_of (convex hull {a,b}) \ x \ {a,b}"
by (intro extreme_point_of_convex_hull_affine_independent affine_independent_2)
then show ?thesis
by simp
qed
lemma extreme_point_of_segment:
fixes x :: "'a::euclidean_space"
shows
"x extreme_point_of closed_segment a b \ x = a \ x = b"
by (simp add: extreme_point_of_convex_hull_2 segment_convex_hull)
lemma face_of_convex_hull_subset:
fixes S :: "'a::euclidean_space set"
assumes "compact S" and T: "T face_of (convex hull S)"
obtains s' where "s' \<subseteq> S" "T = convex hull s'"
proof
show "{x. x extreme_point_of T} \ S"
using T extreme_point_of_convex_hull extreme_point_of_face by blast
show "T = convex hull {x. x extreme_point_of T}"
proof (rule Krein_Milman_Minkowski)
show "compact T"
using T assms compact_convex_hull face_of_imp_compact by auto
show "convex T"
using T face_of_imp_convex by blast
qed
qed
lemma face_of_convex_hull_aux:
assumes eq: "x *\<^sub>R p = u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c"
and x: "u + v + w = x" "x \ 0" and S: "affine S" "a \ S" "b \ S" "c \ S"
shows "p \ S"
proof -
have "p = (u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c) /\<^sub>R x"
by (metis \<open>x \<noteq> 0\<close> eq mult.commute right_inverse scaleR_one scaleR_scaleR)
moreover have "affine hull {a,b,c} \ S"
by (simp add: S hull_minimal)
moreover have "(u *\<^sub>R a + v *\<^sub>R b + w *\<^sub>R c) /\<^sub>R x \ affine hull {a,b,c}"
apply (simp add: affine_hull_3)
apply (rule_tac x="u/x" in exI)
apply (rule_tac x="v/x" in exI)
apply (rule_tac x="w/x" in exI)
using x apply (auto simp: field_split_simps)
done
ultimately show ?thesis by force
qed
proposition face_of_convex_hull_insert_eq:
fixes a :: "'a :: euclidean_space"
assumes "finite S" and a: "a \ affine hull S"
shows "(F face_of (convex hull (insert a S)) \
F face_of (convex hull S) \<or>
(\<exists>F'. F' face_of (convex hull S) \<and> F = convex hull (insert a F')))"
(is "F face_of ?CAS \ _")
proof safe
assume F: "F face_of ?CAS"
and *: "\F'. F' face_of convex hull S \ F = convex hull insert a F'"
obtain T where T: "T \ insert a S" and FeqT: "F = convex hull T"
by (metis F \<open>finite S\<close> compact_insert finite_imp_compact face_of_convex_hull_subset)
show "F face_of convex hull S"
proof (cases "a \ T")
case True
have "F = convex hull insert a (convex hull T \ convex hull S)"
proof
have "T \ insert a (convex hull T \ convex hull S)"
using T hull_subset by fastforce
then show "F \ convex hull insert a (convex hull T \ convex hull S)"
by (simp add: FeqT hull_mono)
show "convex hull insert a (convex hull T \ convex hull S) \ F"
by (simp add: FeqT True hull_inc hull_minimal)
qed
moreover have "convex hull T \ convex hull S face_of convex hull S"
by (metis F FeqT convex_convex_hull face_of_slice hull_mono inf.absorb_iff2 subset_insertI)
ultimately show ?thesis
using * by force
next
case False
then show ?thesis
by (metis FeqT F T face_of_subset hull_mono subset_insert subset_insertI)
qed
next
assume "F face_of convex hull S"
show "F face_of ?CAS"
by (simp add: \<open>F face_of convex hull S\<close> a face_of_convex_hull_insert \<open>finite S\<close>)
next
fix F
assume F: "F face_of convex hull S"
show "convex hull insert a F face_of ?CAS"
proof (cases "S = {}")
case True
then show ?thesis
using F face_of_affine_eq by auto
next
case False
have anotc: "a \ convex hull S"
by (metis (no_types) a affine_hull_convex_hull hull_inc)
show ?thesis
proof (cases "F = {}")
case True show ?thesis
using anotc by (simp add: \<open>F = {}\<close> \<open>finite S\<close> extreme_point_of_convex_hull_insert face_of_singleton)
next
case False
have "convex hull insert a F \ ?CAS"
by (simp add: F a \<open>finite S\<close> convex_hull_subset face_of_convex_hull_insert face_of_imp_subset hull_inc)
moreover
have "(\y v. (1 - ub) *\<^sub>R a + ub *\<^sub>R b = (1 - v) *\<^sub>R a + v *\<^sub>R y \
0 \<le> v \<and> v \<le> 1 \<and> y \<in> F) \<and>
(\<exists>x u. (1 - uc) *\<^sub>R a + uc *\<^sub>R c = (1 - u) *\<^sub>R a + u *\<^sub>R x \<and>
0 \<le> u \<and> u \<le> 1 \<and> x \<in> F)"
if *: "(1 - ux) *\<^sub>R a + ux *\<^sub>R x
\<in> open_segment ((1 - ub) *\<^sub>R a + ub *\<^sub>R b) ((1 - uc) *\<^sub>R a + uc *\<^sub>R c)"
and "0 \ ub" "ub \ 1" "0 \ uc" "uc \ 1" "0 \ ux" "ux \ 1"
and b: "b \ convex hull S" and c: "c \ convex hull S" and "x \ F"
for b c ub uc ux x
proof -
have xah: "x \ affine hull S"
using F convex_hull_subset_affine_hull face_of_imp_subset \<open>x \<in> F\<close> by blast
have ah: "b \ affine hull S" "c \ affine hull S"
using b c convex_hull_subset_affine_hull by blast+
obtain v where ne: "(1 - ub) *\<^sub>R a + ub *\<^sub>R b \ (1 - uc) *\<^sub>R a + uc *\<^sub>R c"
and eq: "(1 - ux) *\<^sub>R a + ux *\<^sub>R x =
(1 - v) *\<^sub>R ((1 - ub) *\<^sub>R a + ub *\<^sub>R b) + v *\<^sub>R ((1 - uc) *\<^sub>R a + uc *\<^sub>R c)"
and "0 < v" "v < 1"
using * by (auto simp: in_segment)
then have 0: "((1 - ux) - ((1 - v) * (1 - ub) + v * (1 - uc))) *\<^sub>R a +
(ux *\<^sub>R x - (((1 - v) * ub) *\<^sub>R b + (v * uc) *\<^sub>R c)) = 0"
by (auto simp: algebra_simps)
then have "((1 - ux) - ((1 - v) * (1 - ub) + v * (1 - uc))) *\<^sub>R a =
((1 - v) * ub) *\<^sub>R b + (v * uc) *\<^sub>R c + (-ux) *\<^sub>R x"
by (auto simp: algebra_simps)
then have "a \ affine hull S" if "1 - ux - ((1 - v) * (1 - ub) + v * (1 - uc)) \ 0"
by (rule face_of_convex_hull_aux) (use b c xah ah that in \<open>auto simp: algebra_simps\<close>)
then have "1 - ux - ((1 - v) * (1 - ub) + v * (1 - uc)) = 0"
using a by blast
with 0 have equx: "(1 - v) * ub + v * uc = ux"
and uxx: "ux *\<^sub>R x = (((1 - v) * ub) *\<^sub>R b + (v * uc) *\<^sub>R c)"
by auto (auto simp: algebra_simps)
show ?thesis
proof (cases "uc = 0")
case True
then show ?thesis
using equx \<open>0 \<le> ub\<close> \<open>ub \<le> 1\<close> \<open>v < 1\<close> uxx \<open>x \<in> F\<close> by force
next
case False
show ?thesis
proof (cases "ub = 0")
case True
then show ?thesis
using equx \<open>0 \<le> uc\<close> \<open>uc \<le> 1\<close> \<open>0 < v\<close> uxx \<open>x \<in> F\<close> by force
next
case False
then have "0 < ub" "0 < uc"
using \<open>uc \<noteq> 0\<close> \<open>0 \<le> ub\<close> \<open>0 \<le> uc\<close> by auto
then have "(1 - v) * ub > 0" "v * uc > 0"
by (simp_all add: \<open>0 < uc\<close> \<open>0 < v\<close> \<open>v < 1\<close>)
then have "ux \ 0"
using equx \<open>0 < v\<close> by auto
have "b \ F \ c \ F"
proof (cases "b = c")
case True
--> --------------------
--> maximum size reached
--> --------------------
¤ Dauer der Verarbeitung: 0.58 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|