diff --git a/thys/Euler_Polyhedron_Formula/Euler_Formula.thy b/thys/Euler_Polyhedron_Formula/Euler_Formula.thy --- a/thys/Euler_Polyhedron_Formula/Euler_Formula.thy +++ b/thys/Euler_Polyhedron_Formula/Euler_Formula.thy @@ -1,1643 +1,1641 @@ section \Euler's Polyhedron Formula\ text \One of the Famous 100 Theorems, ported from HOL Light\ text\Cited source: Lawrence, J. (1997). A Short Proof of Euler's Relation for Convex Polytopes. \emph{Canadian Mathematical Bulletin}, \textbf{40}(4), 471--474.\ theory Euler_Formula imports "HOL-Analysis.Analysis" - Library_Extras - Inclusion_Exclusion begin text\ Interpret which "side" of a hyperplane a point is on. \ definition hyperplane_side where "hyperplane_side \ \(a,b). \x. sgn (a \ x - b)" text\ Equivalence relation imposed by a hyperplane arrangement. \ definition hyperplane_equiv where "hyperplane_equiv \ \A x y. \h \ A. hyperplane_side h x = hyperplane_side h y" lemma hyperplane_equiv_refl [iff]: "hyperplane_equiv A x x" by (simp add: hyperplane_equiv_def) lemma hyperplane_equiv_sym: "hyperplane_equiv A x y \ hyperplane_equiv A y x" by (auto simp: hyperplane_equiv_def) lemma hyperplane_equiv_trans: "\hyperplane_equiv A x y; hyperplane_equiv A y z\ \ hyperplane_equiv A x z" by (auto simp: hyperplane_equiv_def) lemma hyperplane_equiv_Un: "hyperplane_equiv (A \ B) x y \ hyperplane_equiv A x y \ hyperplane_equiv B x y" by (meson Un_iff hyperplane_equiv_def) subsection\ Cells of a hyperplane arrangement\ definition hyperplane_cell :: "('a::real_inner \ real) set \ 'a set \ bool" where "hyperplane_cell \ \A C. \x. C = Collect (hyperplane_equiv A x)" lemma hyperplane_cell: "hyperplane_cell A C \ (\x. C = {y. hyperplane_equiv A x y})" by (simp add: hyperplane_cell_def) lemma not_hyperplane_cell_empty [simp]: "\ hyperplane_cell A {}" using hyperplane_cell by auto lemma nonempty_hyperplane_cell: "hyperplane_cell A C \ (C \ {})" by auto lemma Union_hyperplane_cells: "\ {C. hyperplane_cell A C} = UNIV" using hyperplane_cell by blast lemma disjoint_hyperplane_cells: "\hyperplane_cell A C1; hyperplane_cell A C2; C1 \ C2\ \ disjnt C1 C2" by (force simp: hyperplane_cell_def disjnt_iff hyperplane_equiv_def) lemma disjoint_hyperplane_cells_eq: "\hyperplane_cell A C1; hyperplane_cell A C2\ \ (disjnt C1 C2 \ (C1 \ C2))" using disjoint_hyperplane_cells by auto lemma hyperplane_cell_empty [iff]: "hyperplane_cell {} C \ C = UNIV" by (simp add: hyperplane_cell hyperplane_equiv_def) lemma hyperplane_cell_singleton_cases: assumes "hyperplane_cell {(a,b)} C" shows "C = {x. a \ x = b} \ C = {x. a \ x < b} \ C = {x. a \ x > b}" proof - obtain x where x: "C = {y. hyperplane_side (a, b) x = hyperplane_side (a, b) y}" using assms by (auto simp: hyperplane_equiv_def hyperplane_cell) then show ?thesis by (auto simp: hyperplane_side_def sgn_if split: if_split_asm) qed lemma hyperplane_cell_singleton: "hyperplane_cell {(a,b)} C \ (if a = 0 then C = UNIV else C = {x. a \ x = b} \ C = {x. a \ x < b} \ C = {x. a \ x > b})" apply (simp add: hyperplane_cell_def hyperplane_equiv_def hyperplane_side_def sgn_if split: if_split_asm) by (smt (verit) Collect_cong gt_ex hyperplane_eq_Ex lt_ex) lemma hyperplane_cell_Un: "hyperplane_cell (A \ B) C \ C \ {} \ (\C1 C2. hyperplane_cell A C1 \ hyperplane_cell B C2 \ C = C1 \ C2)" by (auto simp: hyperplane_cell hyperplane_equiv_def) lemma finite_hyperplane_cells: "finite A \ finite {C. hyperplane_cell A C}" proof (induction rule: finite_induct) case (insert p A) obtain a b where peq: "p = (a,b)" by fastforce have "Collect (hyperplane_cell {p}) \ {{x. a \ x = b},{x. a \ x < b},{x. a \ x > b}}" using hyperplane_cell_singleton_cases by (auto simp: peq) then have *: "finite (Collect (hyperplane_cell {p}))" by (simp add: finite_subset) define \ where "\ \ (\C1 \ {C. hyperplane_cell A C}. \C2 \ {C. hyperplane_cell {p} C}. {C1 \ C2})" have "{a. hyperplane_cell (insert p A) a} \ \" using hyperplane_cell_Un [of "{p}" A] by (auto simp: \_def) moreover have "finite \" using * \_def insert.IH by blast ultimately show ?case using finite_subset by blast qed auto lemma finite_restrict_hyperplane_cells: "finite A \ finite {C. hyperplane_cell A C \ P C}" by (simp add: finite_hyperplane_cells) lemma finite_set_of_hyperplane_cells: "\finite A; \C. C \ \ \ hyperplane_cell A C\ \ finite \" by (metis finite_hyperplane_cells finite_subset mem_Collect_eq subsetI) lemma pairwise_disjoint_hyperplane_cells: "(\C. C \ \ \ hyperplane_cell A C) \ pairwise disjnt \" by (metis disjoint_hyperplane_cells pairwiseI) lemma hyperplane_cell_Int_open_affine: assumes "finite A" "hyperplane_cell A C" obtains S T where "open S" "affine T" "C = S \ T" using assms proof (induction arbitrary: thesis C rule: finite_induct) case empty then show ?case by auto next case (insert p A thesis C') obtain a b where peq: "p = (a,b)" by fastforce obtain C C1 where C1: "hyperplane_cell {(a,b)} C1" and C: "hyperplane_cell A C" and "C' \ {}" and C': "C' = C1 \ C" by (metis hyperplane_cell_Un insert.prems(2) insert_is_Un peq) then obtain S T where ST: "open S" "affine T" "C = S \ T" by (meson insert.IH) show ?case proof (cases "a=0") case True with insert.prems show ?thesis by (metis C1 Int_commute ST \C' = C1 \ C\ hyperplane_cell_singleton inf_top.right_neutral) next case False then consider "C1 = {x. a \ x = b}" | "C1 = {x. a \ x < b}" | "C1 = {x. b < a \ x}" by (metis C1 hyperplane_cell_singleton) then show ?thesis proof cases case 1 then show thesis by (metis C' ST affine_Int affine_hyperplane inf_left_commute insert.prems(1)) next case 2 with ST show thesis by (metis Int_assoc C' insert.prems(1) open_Int open_halfspace_lt) next case 3 with ST show thesis by (metis Int_assoc C' insert.prems(1) open_Int open_halfspace_gt) qed qed qed lemma hyperplane_cell_relatively_open: assumes "finite A" "hyperplane_cell A C" shows "openin (subtopology euclidean (affine hull C)) C" proof - obtain S T where "open S" "affine T" "C = S \ T" by (meson assms hyperplane_cell_Int_open_affine) show ?thesis proof (cases "S \ T = {}") case True then show ?thesis by (simp add: \C = S \ T\) next case False then have "affine hull (S \ T) = T" by (metis \affine T\ \open S\ affine_hull_affine_Int_open hull_same inf_commute) then show ?thesis using \C = S \ T\ \open S\ openin_subtopology by fastforce qed qed lemma hyperplane_cell_relative_interior: "\finite A; hyperplane_cell A C\ \ rel_interior C = C" by (simp add: hyperplane_cell_relatively_open rel_interior_openin) lemma hyperplane_cell_convex: assumes "hyperplane_cell A C" shows "convex C" proof - obtain c where c: "C = {y. hyperplane_equiv A c y}" by (meson assms hyperplane_cell) have "convex (\h\A. {y. hyperplane_side h c = hyperplane_side h y})" proof (rule convex_INT) fix h :: "'a \ real" assume "h \ A" obtain a b where heq: "h = (a,b)" by fastforce have [simp]: "{y. \ a \ c < a \ y \ a \ y = a \ c} = {y. a \ y = a \ c}" "{y. \ b < a \ y \ a \ y \ b} = {y. b > a \ y}" by auto then show "convex {y. hyperplane_side h c = hyperplane_side h y}" by (fastforce simp: heq hyperplane_side_def sgn_if convex_halfspace_gt convex_halfspace_lt convex_hyperplane cong: conj_cong) qed with c show ?thesis by (simp add: hyperplane_equiv_def INTER_eq) qed lemma hyperplane_cell_Inter: assumes "\C. C \ \ \ hyperplane_cell A C" and "\ \ {}" and INT: "\\ \ {}" shows "hyperplane_cell A (\\)" proof - have "\\ = {y. hyperplane_equiv A z y}" if "z \ \\" for z using assms that by (force simp: hyperplane_cell hyperplane_equiv_def) with INT hyperplane_cell show ?thesis by fastforce qed lemma hyperplane_cell_Int: "\hyperplane_cell A S; hyperplane_cell A T; S \ T \ {}\ \ hyperplane_cell A (S \ T)" by (metis hyperplane_cell_Un sup.idem) subsection\ A cell complex is considered to be a union of such cells\ definition hyperplane_cellcomplex where "hyperplane_cellcomplex A S \ \\. (\C \ \. hyperplane_cell A C) \ S = \\" lemma hyperplane_cellcomplex_empty [simp]: "hyperplane_cellcomplex A {}" using hyperplane_cellcomplex_def by auto lemma hyperplane_cell_cellcomplex: "hyperplane_cell A C \ hyperplane_cellcomplex A C" by (auto simp: hyperplane_cellcomplex_def) lemma hyperplane_cellcomplex_Union: assumes "\S. S \ \ \ hyperplane_cellcomplex A S" shows "hyperplane_cellcomplex A (\ \)" proof - obtain \ where \: "\S. S \ \ \ (\C \ \ S. hyperplane_cell A C) \ S = \(\ S)" by (metis assms hyperplane_cellcomplex_def) show ?thesis unfolding hyperplane_cellcomplex_def using \ by (fastforce intro: exI [where x="\ (\ ` \)"]) qed lemma hyperplane_cellcomplex_Un: "\hyperplane_cellcomplex A S; hyperplane_cellcomplex A T\ \ hyperplane_cellcomplex A (S \ T)" by (smt (verit) Un_iff Union_Un_distrib hyperplane_cellcomplex_def) lemma hyperplane_cellcomplex_UNIV [simp]: "hyperplane_cellcomplex A UNIV" by (metis Union_hyperplane_cells hyperplane_cellcomplex_def mem_Collect_eq) lemma hyperplane_cellcomplex_Inter: assumes "\S. S \ \ \ hyperplane_cellcomplex A S" shows "hyperplane_cellcomplex A (\\)" proof (cases "\ = {}") case True then show ?thesis by simp next case False obtain \ where \: "\S. S \ \ \ (\C \ \ S. hyperplane_cell A C) \ S = \(\ S)" by (metis assms hyperplane_cellcomplex_def) have *: "\ = (\S. \(\ S)) ` \" using \ by force define U where "U \ \ {T \ {\(g ` \) |g. \S\\. g S \ \ S}. T \ {}}" have "\\ = \{\(g ` \) |g. \S\\. g S \ \ S}" using False \ unfolding Inter_over_Union [symmetric] by blast also have "\ = U" unfolding U_def by blast finally have "\\ = U" . have "hyperplane_cellcomplex A U" using False \ unfolding U_def apply (intro hyperplane_cellcomplex_Union hyperplane_cell_cellcomplex) by (auto intro!: hyperplane_cell_Inter) then show ?thesis by (simp add: \\\ = U\) qed lemma hyperplane_cellcomplex_Int: "\hyperplane_cellcomplex A S; hyperplane_cellcomplex A T\ \ hyperplane_cellcomplex A (S \ T)" using hyperplane_cellcomplex_Inter [of "{S,T}"] by force lemma hyperplane_cellcomplex_Compl: assumes "hyperplane_cellcomplex A S" shows "hyperplane_cellcomplex A (- S)" proof - obtain \ where \: "\C. C \ \ \ hyperplane_cell A C" and "S = \\" by (meson assms hyperplane_cellcomplex_def) have "hyperplane_cellcomplex A (\T \ \. -T)" proof (intro hyperplane_cellcomplex_Inter) fix C0 assume "C0 \ uminus ` \" then obtain C where C: "C0 = -C" "C \ \" by auto have *: "-C = \ {D. hyperplane_cell A D \ D \ C}" (is "_ = ?rhs") proof show "- C \ ?rhs" using hyperplane_cell by blast show "?rhs \ - C" by clarify (meson \C \ \\ \ disjnt_iff disjoint_hyperplane_cells) qed then show "hyperplane_cellcomplex A C0" by (metis (no_types, lifting) C(1) hyperplane_cell_cellcomplex hyperplane_cellcomplex_Union mem_Collect_eq) qed then show ?thesis by (simp add: \S = \ \\ uminus_Sup) qed lemma hyperplane_cellcomplex_diff: "\hyperplane_cellcomplex A S; hyperplane_cellcomplex A T\ \ hyperplane_cellcomplex A (S - T)" using hyperplane_cellcomplex_Inter [of "{S,-T}"] by (force simp: Diff_eq hyperplane_cellcomplex_Compl) lemma hyperplane_cellcomplex_mono: assumes "hyperplane_cellcomplex A S" "A \ B" shows "hyperplane_cellcomplex B S" proof - obtain \ where \: "\C. C \ \ \ hyperplane_cell A C" and eq: "S = \\" by (meson assms hyperplane_cellcomplex_def) show ?thesis unfolding eq proof (intro hyperplane_cellcomplex_Union) fix C assume "C \ \" have "\x. x \ C \ \D'. (\D. D' = D \ C \ hyperplane_cell (B - A) D \ D \ C \ {}) \ x \ D'" unfolding hyperplane_cell_def by blast then have "hyperplane_cellcomplex (A \ (B - A)) C" unfolding hyperplane_cellcomplex_def hyperplane_cell_Un using \ \C \ \\ by (fastforce intro!: exI [where x=" {D \ C |D. hyperplane_cell (B - A) D \ D \ C \ {}}"]) moreover have "B = A \ (B - A)" using \A \ B\ by auto ultimately show "hyperplane_cellcomplex B C" by simp qed qed lemma finite_hyperplane_cellcomplexes: assumes "finite A" shows "finite {C. hyperplane_cellcomplex A C}" proof - have "{C. hyperplane_cellcomplex A C} \ image \ {T. T \ {C. hyperplane_cell A C}}" by (force simp: hyperplane_cellcomplex_def subset_eq) with finite_hyperplane_cells show ?thesis by (metis assms finite_Collect_subsets finite_surj) qed lemma finite_restrict_hyperplane_cellcomplexes: "finite A \ finite {C. hyperplane_cellcomplex A C \ P C}" by (simp add: finite_hyperplane_cellcomplexes) lemma finite_set_of_hyperplane_cellcomplex: assumes "finite A" "\C. C \ \ \ hyperplane_cellcomplex A C" shows "finite \" by (metis assms finite_hyperplane_cellcomplexes mem_Collect_eq rev_finite_subset subsetI) lemma cell_subset_cellcomplex: "\hyperplane_cell A C; hyperplane_cellcomplex A S\ \ C \ S \ ~ disjnt C S" by (smt (verit) Union_iff disjnt_iff disjnt_subset1 disjoint_hyperplane_cells_eq hyperplane_cellcomplex_def subsetI) subsection \Euler characteristic\ definition Euler_characteristic :: "('a::euclidean_space \ real) set \ 'a set \ int" where "Euler_characteristic A S \ (\C | hyperplane_cell A C \ C \ S. (-1) ^ nat (aff_dim C))" lemma Euler_characteristic_empty [simp]: "Euler_characteristic A {} = 0" by (simp add: sum.neutral Euler_characteristic_def) lemma Euler_characteristic_cell_Union: assumes "\C. C \ \ \ hyperplane_cell A C" shows "Euler_characteristic A (\ \) = (\C\\. (- 1) ^ nat (aff_dim C))" proof - have "\x. \hyperplane_cell A x; x \ \ \\ \ x \ \" by (metis assms disjnt_Union1 disjnt_subset1 disjoint_hyperplane_cells_eq) then have "{C. hyperplane_cell A C \ C \ \ \} = \" by (auto simp: assms) then show ?thesis by (auto simp: Euler_characteristic_def) qed lemma Euler_characteristic_cell: "hyperplane_cell A C \ Euler_characteristic A C = (-1) ^ (nat(aff_dim C))" using Euler_characteristic_cell_Union [of "{C}"] by force lemma Euler_characteristic_cellcomplex_Un: assumes "finite A" "hyperplane_cellcomplex A S" and AT: "hyperplane_cellcomplex A T" and "disjnt S T" shows "Euler_characteristic A (S \ T) = Euler_characteristic A S + Euler_characteristic A T" proof - have *: "{C. hyperplane_cell A C \ C \ S \ T} = {C. hyperplane_cell A C \ C \ S} \ {C. hyperplane_cell A C \ C \ T}" using cell_subset_cellcomplex [OF _ AT] by (auto simp: disjnt_iff) have **: "{C. hyperplane_cell A C \ C \ S} \ {C. hyperplane_cell A C \ C \ T} = {}" using assms cell_subset_cellcomplex disjnt_subset1 by fastforce show ?thesis unfolding Euler_characteristic_def by (simp add: finite_restrict_hyperplane_cells assms * ** flip: sum.union_disjoint) qed lemma Euler_characteristic_cellcomplex_Union: assumes "finite A" and \: "\C. C \ \ \ hyperplane_cellcomplex A C" "pairwise disjnt \" shows "Euler_characteristic A (\ \) = sum (Euler_characteristic A) \" proof - have "finite \" using assms finite_set_of_hyperplane_cellcomplex by blast then show ?thesis using \ proof (induction rule: finite_induct) case empty then show ?case by auto next case (insert C \) then obtain "disjoint \" "disjnt C (\ \)" by (metis disjnt_Union2 pairwise_insert) with insert show ?case by (simp add: Euler_characteristic_cellcomplex_Un hyperplane_cellcomplex_Union \finite A\) qed qed lemma Euler_characteristic: fixes A :: "('n::euclidean_space * real) set" assumes "finite A" shows "Euler_characteristic A S = (\d = 0..DIM('n). (-1) ^ d * int (card {C. hyperplane_cell A C \ C \ S \ aff_dim C = int d}))" (is "_ = ?rhs") proof - have "\T. \hyperplane_cell A T; T \ S\ \ aff_dim T \ {0..DIM('n)}" by (metis atLeastAtMost_iff nle_le order.strict_iff_not aff_dim_negative_iff nonempty_hyperplane_cell aff_dim_le_DIM) then have *: "aff_dim ` {C. hyperplane_cell A C \ C \ S} \ int ` {0..DIM('n)}" by (auto simp: image_int_atLeastAtMost) have "Euler_characteristic A S = (\y\int ` {0..DIM('n)}. \C\{x. hyperplane_cell A x \ x \ S \ aff_dim x = y}. (- 1) ^ nat y) " using sum.group [of "{C. hyperplane_cell A C \ C \ S}" "int ` {0..DIM('n)}" aff_dim "\C. (-1::int) ^ nat(aff_dim C)", symmetric] by (simp add: assms Euler_characteristic_def finite_restrict_hyperplane_cells *) also have "\ = ?rhs" by (simp add: sum.reindex mult_of_nat_commute) finally show ?thesis . qed subsection \Show that the characteristic is invariant w.r.t. hyperplane arrangement.\ lemma hyperplane_cells_distinct_lemma: "{x. a \ x = b} \ {x. a \ x < b} = {} \ {x. a \ x = b} \ {x. a \ x > b} = {} \ {x. a \ x < b} \ {x. a \ x = b} = {} \ {x. a \ x < b} \ {x. a \ x > b} = {} \ {x. a \ x > b} \ {x. a \ x = b} = {} \ {x. a \ x > b} \ {x. a \ x < b} = {}" by auto proposition Euler_characterstic_lemma: assumes "finite A" and "hyperplane_cellcomplex A S" shows "Euler_characteristic (insert h A) S = Euler_characteristic A S" proof - obtain \ where \: "\C. C \ \ \ hyperplane_cell A C" and "S = \\" and "pairwise disjnt \" by (meson assms hyperplane_cellcomplex_def pairwise_disjoint_hyperplane_cells) obtain a b where "h = (a,b)" by fastforce have "\C. C \ \ \ hyperplane_cellcomplex A C \ hyperplane_cellcomplex (insert (a,b) A) C" by (meson \ hyperplane_cell_cellcomplex hyperplane_cellcomplex_mono subset_insertI) moreover have "sum (Euler_characteristic (insert (a,b) A)) \ = sum (Euler_characteristic A) \" proof (rule sum.cong [OF refl]) fix C assume "C \ \" have "Euler_characteristic (insert (a, b) A) C = (-1) ^ nat(aff_dim C)" proof (cases "hyperplane_cell (insert (a,b) A) C") case True then show ?thesis using Euler_characteristic_cell by blast next case False with \[OF \C \ \\] have "a \ 0" by (smt (verit, ccfv_threshold) hyperplane_cell_Un hyperplane_cell_empty hyperplane_cell_singleton insert_is_Un sup_bot_left) have "convex C" using \hyperplane_cell A C\ hyperplane_cell_convex by blast define r where "r \ (\D\{C' \ C |C'. hyperplane_cell {(a, b)} C' \ C' \ C \ {}}. (-1::int) ^ nat (aff_dim D))" have "Euler_characteristic (insert (a, b) A) C = (\D | (D \ {} \ (\C1 C2. hyperplane_cell {(a, b)} C1 \ hyperplane_cell A C2 \ D = C1 \ C2)) \ D \ C. (- 1) ^ nat (aff_dim D))" unfolding r_def Euler_characteristic_def insert_is_Un [of _ A] hyperplane_cell_Un .. also have "\ = r" unfolding r_def apply (rule sum.cong [OF _ refl]) using \hyperplane_cell A C\ disjoint_hyperplane_cells disjnt_iff by (smt (verit, ccfv_SIG) Collect_cong Int_iff disjoint_iff subsetD subsetI) also have "\ = (-1) ^ nat(aff_dim C)" proof - have "C \ {}" using \hyperplane_cell A C\ by auto show ?thesis proof (cases "C \ {x. a \ x < b} \ C \ {x. a \ x > b} \ C \ {x. a \ x = b}") case Csub: True with \C \ {}\ have "r = sum (\c. (-1) ^ nat (aff_dim c)) {C}" unfolding r_def apply (intro sum.cong [OF _ refl]) by (auto simp: \a \ 0\ hyperplane_cell_singleton) also have "\ = (-1) ^ nat(aff_dim C)" by simp finally show ?thesis . next case False then obtain u v where uv: "u \ C" "\ a \ u < b" "v \ C" "\ a \ v > b" by blast have CInt_ne: "C \ {x. a \ x = b} \ {}" proof (cases "a \ u = b \ a \ v = b") case True with uv show ?thesis by blast next case False have "a \ v < a \ u" using False uv by auto define w where "w \ v + ((b - a \ v) / (a \ u - a \ v)) *\<^sub>R (u - v)" have **: "v + a *\<^sub>R (u - v) = (1 - a) *\<^sub>R v + a *\<^sub>R u" for a by (simp add: algebra_simps) have "w \ C" unfolding w_def ** proof (intro convexD_alt) qed (use \a \ v < a \ u\ \convex C\ uv in auto) moreover have "w \ {x. a \ x = b}" using \a \ v < a \ u\ by (simp add: w_def inner_add_right inner_diff_right) ultimately show ?thesis by blast qed have Cab: "C \ {x. a \ x < b} \ {} \ C \ {x. b < a \ x} \ {}" proof - obtain u v where "u \ C" "a \ u = b" "v \ C" "a \ v \ b" "u\v" using False \C \ {x. a \ x = b} \ {}\ by blast have "openin (subtopology euclidean (affine hull C)) C" using \hyperplane_cell A C\ \finite A\ hyperplane_cell_relatively_open by blast then obtain \ where "0 < \" and \: "\x'. \x' \ affine hull C; dist x' u < \\ \ x' \ C" by (meson \u \ C\ openin_euclidean_subtopology_iff) define \ where "\ \ u - (\ / 2 / norm (v - u)) *\<^sub>R (v - u)" have "\ \ C" proof (rule \) show "\ \ affine hull C" by (simp add: \_def \u \ C\ \v \ C\ hull_inc mem_affine_3_minus2) qed (use \_def \0 < \\ in force) consider "a \ v < b" | "a \ v > b" using \a \ v \ b\ by linarith then show ?thesis proof cases case 1 moreover have "\ \ {x. b < a \ x}" using "1" \0 < \\ \a \ u = b\ divide_less_cancel by (fastforce simp: \_def algebra_simps) ultimately show ?thesis using \v \ C\ \\ \ C\ by blast next case 2 moreover have "\ \ {x. b > a \ x}" using "2" \0 < \\ \a \ u = b\ divide_less_cancel by (fastforce simp: \_def algebra_simps) ultimately show ?thesis using \v \ C\ \\ \ C\ by blast qed qed have "r = (\C\{{x. a \ x = b} \ C, {x. b < a \ x} \ C, {x. a \ x < b} \ C}. (- 1) ^ nat (aff_dim C))" unfolding r_def proof (intro sum.cong [OF _ refl] equalityI) show "{{x. a \ x = b} \ C, {x. b < a \ x} \ C, {x. a \ x < b} \ C} \ {C' \ C |C'. hyperplane_cell {(a, b)} C' \ C' \ C \ {}}" apply clarsimp using Cab Int_commute \C \ {x. a \ x = b} \ {}\ hyperplane_cell_singleton \a \ 0\ by metis qed (auto simp: \a \ 0\ hyperplane_cell_singleton) also have "\ = (-1) ^ nat (aff_dim (C \ {x. a \ x = b})) + (-1) ^ nat (aff_dim (C \ {x. b < a \ x})) + (-1) ^ nat (aff_dim (C \ {x. a \ x < b}))" using hyperplane_cells_distinct_lemma [of a b] Cab by (auto simp: sum.insert_if Int_commute Int_left_commute) also have "\ = (- 1) ^ nat (aff_dim C)" proof - have *: "aff_dim (C \ {x. a \ x < b}) = aff_dim C \ aff_dim (C \ {x. a \ x > b}) = aff_dim C" by (metis Cab open_halfspace_lt open_halfspace_gt aff_dim_affine_hull affine_hull_convex_Int_open[OF \convex C\]) obtain S T where "open S" "affine T" and Ceq: "C = S \ T" by (meson \hyperplane_cell A C\ \finite A\ hyperplane_cell_Int_open_affine) have "affine hull C = affine hull T" by (metis Ceq \C \ {}\ \affine T\ \open S\ affine_hull_affine_Int_open inf_commute) moreover have "T \ ({x. a \ x = b} \ S) \ {}" using Ceq \C \ {x. a \ x = b} \ {}\ by blast then have "affine hull (C \ {x. a \ x = b}) = affine hull (T \ {x. a \ x = b})" using affine_hull_affine_Int_open[of "T \ {x. a \ x = b}" S] by (simp add: Ceq Int_ac \affine T\ \open S\ affine_Int affine_hyperplane) ultimately have "aff_dim (affine hull C) = aff_dim(affine hull (C \ {x. a \ x = b})) + 1" using CInt_ne False Ceq by (auto simp: aff_dim_affine_Int_hyperplane \affine T\) moreover have "0 \ aff_dim (C \ {x. a \ x = b})" by (metis CInt_ne aff_dim_negative_iff linorder_not_le) ultimately show ?thesis by (simp add: * nat_add_distrib) qed finally show ?thesis . qed qed finally show "Euler_characteristic (insert (a, b) A) C = (-1) ^ nat(aff_dim C)" . qed then show "Euler_characteristic (insert (a, b) A) C = (Euler_characteristic A C)" by (simp add: Euler_characteristic_cell \ \C \ \\) qed ultimately show ?thesis by (simp add: Euler_characteristic_cellcomplex_Union \S = \ \\ \disjoint \\ \h = (a, b)\ assms(1)) qed lemma Euler_characterstic_invariant_aux: assumes "finite B" "finite A" "hyperplane_cellcomplex A S" shows "Euler_characteristic (A \ B) S = Euler_characteristic A S" using assms by (induction rule: finite_induct) (auto simp: Euler_characterstic_lemma hyperplane_cellcomplex_mono) lemma Euler_characterstic_invariant: assumes "finite A" "finite B" "hyperplane_cellcomplex A S" "hyperplane_cellcomplex B S" shows "Euler_characteristic A S = Euler_characteristic B S" by (metis Euler_characterstic_invariant_aux assms sup_commute) lemma Euler_characteristic_inclusion_exclusion: assumes "finite A" "finite \" "\K. K \ \ \ hyperplane_cellcomplex A K" shows "Euler_characteristic A (\ \) = (\\ | \ \ \ \ \ \ {}. (- 1) ^ (card \ + 1) * Euler_characteristic A (\\))" proof - interpret Incl_Excl "hyperplane_cellcomplex A" "Euler_characteristic A" proof show "Euler_characteristic A (S \ T) = Euler_characteristic A S + Euler_characteristic A T" if "hyperplane_cellcomplex A S" and "hyperplane_cellcomplex A T" and "disjnt S T" for S T using that Euler_characteristic_cellcomplex_Un assms(1) by blast qed (use hyperplane_cellcomplex_Int hyperplane_cellcomplex_Un hyperplane_cellcomplex_diff in auto) show ?thesis using restricted assms by blast qed subsection \Euler-type relation for full-dimensional proper polyhedral cones\ lemma Euler_polyhedral_cone: fixes S :: "'n::euclidean_space set" assumes "polyhedron S" "conic S" and intS: "interior S \ {}" and "S \ UNIV" shows "(\d = 0..DIM('n). (- 1) ^ d * int (card {f. f face_of S \ aff_dim f = int d})) = 0" (is "?lhs = 0") proof - have [simp]: "affine hull S = UNIV" by (simp add: affine_hull_nonempty_interior intS) with \polyhedron S\ obtain H where "finite H" and Seq: "S = \H" and Hex: "\h. h\H \ \a b. a\0 \ h = {x. a \ x \ b}" and Hsub: "\\. \ \ H \ S \ \\" by (fastforce simp: polyhedron_Int_affine_minimal) have "0 \ S" using assms(2) conic_contains_0 intS interior_empty by blast have *: "\a. a\0 \ h = {x. a \ x \ 0}" if "h \ H" for h proof - obtain a b where "a\0" and ab: "h = {x. a \ x \ b}" using Hex [OF \h \ H\] by blast have "0 \ \H" using Seq \0 \ S\ by force then have "0 \ h" using that by blast consider "b=0" | "b < 0" | "b > 0" by linarith then show ?thesis proof cases case 1 then show ?thesis using \a \ 0\ ab by blast next case 2 then show ?thesis using \0 \ h\ ab by auto next case 3 have "S \ \(H - {h})" using Hsub [of "H - {h}"] that by auto then obtain x where x: "x \ \(H - {h})" and "x \ S" by auto define \ where "\ \ min (1/2) (b / (a \ x))" have "b < a \ x" using \x \ S\ ab x by (fastforce simp: \S = \H\) with 3 have "0 < a \ x" by auto with 3 have "0 < \" by (simp add: \_def) have "\ < 1" using \_def by linarith have "\ * (a \ x) \ b" unfolding \_def using \0 < a \ x\ pos_le_divide_eq by fastforce have "x = inverse \ *\<^sub>R \ *\<^sub>R x" using \0 < \\ by force moreover have "\ *\<^sub>R x \ S" proof - have "\ *\<^sub>R x \ h" by (simp add: \\ * (a \ x) \ b\ ab) moreover have "\ *\<^sub>R x \ \(H - {h})" proof - have "\ *\<^sub>R x \ k" if "x \ k" "k \ H" "k \ h" for k proof - obtain a' b' where "a'\0" "k = {x. a' \ x \ b'}" using Hex \k \ H\ by blast have "(0 \ a' \ x \ a' \ \ *\<^sub>R x \ a' \ x)" by (metis \\ < 1\ inner_scaleR_right order_less_le pth_1 real_scaleR_def scaleR_right_mono) moreover have "(0 \ -(a' \ x) \ 0 \ -(a' \ \ *\<^sub>R x)) " using \0 < \\ mult_le_0_iff order_less_imp_le by auto ultimately have "a' \ x \ b' \ a' \ \ *\<^sub>R x \ b'" by (smt (verit) InterD \0 \ \H\ \k = {x. a' \ x \ b'}\ inner_zero_right mem_Collect_eq that(2)) then show ?thesis using \k = {x. a' \ x \ b'}\ \x \ k\ by fastforce qed with x show ?thesis by blast qed ultimately show ?thesis using Seq by blast qed with \conic S\ have "inverse \ *\<^sub>R \ *\<^sub>R x \ S" by (meson \0 < \\ conic_def inverse_nonnegative_iff_nonnegative order_less_le) ultimately show ?thesis using \x \ S\ by presburger qed qed then obtain fa where fa: "\h. h \ H \ fa h \ 0 \ h = {x. fa h \ x \ 0}" by metis define fa_le_0 where "fa_le_0 \ \h. {x. fa h \ x \ 0}" have fa': "\h. h \ H \ fa_le_0 h = h" using fa fa_le_0_def by blast define A where "A \ (\h. (fa h,0::real)) ` H" have "finite A" using \finite H\ by (simp add: A_def) then have "?lhs = Euler_characteristic A S" proof - have [simp]: "card {f. f face_of S \ aff_dim f = int d} = card {C. hyperplane_cell A C \ C \ S \ aff_dim C = int d}" if "finite A" and "d \ card (Basis::'n set)" for d :: nat proof (rule bij_betw_same_card) have hyper1: "hyperplane_cell A (rel_interior f) \ rel_interior f \ S \ aff_dim (rel_interior f) = d \ closure (rel_interior f) = f" if "f face_of S" "aff_dim f = d" for f proof - have 1: "closure(rel_interior f) = f" proof - have "closure(rel_interior f) = closure f" by (meson convex_closure_rel_interior face_of_imp_convex that(1)) also have "\ = f" by (meson assms(1) closure_closed face_of_polyhedron_polyhedron polyhedron_imp_closed that(1)) finally show ?thesis . qed then have 2: "aff_dim (rel_interior f) = d" by (metis closure_aff_dim that(2)) have "f \ {}" using aff_dim_negative_iff [of f] by (simp add: that(2)) obtain J0 where "J0 \ H" and J0: "f = \ (fa_le_0 ` H) \ (\h \ J0. {x. fa h \ x = 0})" proof (cases "f = S") case True have "S = \ (fa_le_0 ` H)" using Seq fa by (auto simp: fa_le_0_def) then show ?thesis using True that by blast next case False have fexp: "f = \{S \ {x. fa h \ x = 0} | h. h \ H \ f \ S \ {x. fa h \ x = 0}}" proof (rule face_of_polyhedron_explicit) show "S = affine hull S \ \ H" by (simp add: Seq hull_subset inf.absorb2) qed (auto simp: False \f \ {}\ \f face_of S\ \finite H\ Hsub fa) show ?thesis proof have *: "\x h. \x \ f; h \ H\ \ fa h \ x \ 0" using Seq fa face_of_imp_subset \f face_of S\ by fastforce show "f = \ (fa_le_0 ` H) \ (\h \ {h \ H. f \ S \ {x. fa h \ x = 0}}. {x. fa h \ x = 0})" (is "f = ?I") proof show "f \ ?I" using \f face_of S\ fa face_of_imp_subset by (force simp: * fa_le_0_def) show "?I \ f" apply (subst (2) fexp) apply (clarsimp simp: * fa_le_0_def) by (metis Inter_iff Seq fa mem_Collect_eq) qed qed blast qed define H' where "H' = (\h. {x. -(fa h) \ x \ 0}) ` H" have "\J. finite J \ J \ H \ H' \ f = affine hull f \ \J" proof (intro exI conjI) let ?J = "H \ image (\h. {x. -(fa h) \ x \ 0}) J0" show "finite (?J::'n set set)" using \J0 \ H\ \finite H\ finite_subset by fastforce show "?J \ H \ H'" using \J0 \ H\ by (auto simp: H'_def) have "f = \?J" proof show "f \ \?J" unfolding J0 by (auto simp: fa') have "\x j. \j \ J0; \h\H. x \ h; \j\J0. 0 \ fa j \ x\ \ fa j \ x = 0" by (metis \J0 \ H\ fa in_mono inf.absorb2 inf.orderE mem_Collect_eq) then show "\?J \ f" unfolding J0 by (auto simp: fa') qed then show "f = affine hull f \ \?J" by (simp add: Int_absorb1 hull_subset) qed then have **: "\n J. finite J \ card J = n \ J \ H \ H' \ f = affine hull f \ \J" by blast obtain J nJ where J: "finite J" "card J = nJ" "J \ H \ H'" and feq: "f = affine hull f \ \J" and minJ: "\m J'. \finite J'; m < nJ; card J' = m; J' \ H \ H'\ \ f \ affine hull f \ \J'" using exists_least_iff [THEN iffD1, OF **] by metis have FF: "f \ (affine hull f \ \J')" if "J' \ J" for J' proof - have "f \ affine hull f \ \J'" using minJ by (metis J finite_subset psubset_card_mono psubset_imp_subset psubset_subset_trans that) then show ?thesis by (metis Int_subset_iff Inter_Un_distrib feq hull_subset inf_sup_ord(2) psubsetI sup.absorb4 that) qed have "\a. {x. a \ x \ 0} = h \ (h \ H \ a = fa h \ (\h'. h' \ H \ a = -(fa h')))" if "h \ J" for h proof - have "h \ H \ H'" using \J \ H \ H'\ that by blast then show ?thesis proof show ?thesis if "h \ H" using that fa by blast next assume "h \ H'" then obtain h' where "h' \ H" "h = {x. 0 \ fa h' \ x}" by (auto simp: H'_def) then show ?thesis by (force simp: intro!: exI[where x="- (fa h')"]) qed qed then obtain ga where ga_h: "\h. h \ J \ h = {x. ga h \ x \ 0}" and ga_fa: "\h. h \ J \ h \ H \ ga h = fa h \ (\h'. h' \ H \ ga h = -(fa h'))" by metis have 3: "hyperplane_cell A (rel_interior f)" proof - have D: "rel_interior f = {x \ f. \h\J. ga h \ x < 0}" proof (rule rel_interior_polyhedron_explicit [OF \finite J\ feq]) show "ga h \ 0 \ h = {x. ga h \ x \ 0}" if "h \ J" for h using that fa ga_fa ga_h by force qed (auto simp: FF) have H: "h \ H \ ga h = fa h" if "h \ J" for h proof - obtain z where z: "z \ rel_interior f" using "1" \f \ {}\ by force then have "z \ f \ z \ S" using D \f face_of S\ face_of_imp_subset by blast then show ?thesis using ga_fa [OF that] by (smt (verit, del_insts) D InterE Seq fa inner_minus_left mem_Collect_eq that z) qed then obtain K where "K \ H" and K: "f = \ (fa_le_0 ` H) \ (\h \ K. {x. fa h \ x = 0})" using J0 \J0 \ H\ by blast have E: "rel_interior f = {x. (\h \ H. fa h \ x \ 0) \ (\h \ K. fa h \ x = 0) \ (\h \ J. ga h \ x < 0)}" unfolding D by (simp add: K fa_le_0_def) have relif: "rel_interior f \ {}" using "1" \f \ {}\ by force with E have "disjnt J K" using H disjnt_iff by fastforce define IFJK where "IFJK \ \h. if h \ J then {x. fa h \ x < 0} else if h \ K then {x. fa h \ x = 0} else if rel_interior f \ {x. fa h \ x = 0} then {x. fa h \ x = 0} else {x. fa h \ x < 0}" have relint_f: "rel_interior f = \(IFJK ` H)" proof have A: False if x: "x \ rel_interior f" and y: "y \ rel_interior f" and less0: "fa h \ y < 0" and fa0: "fa h \ x = 0" and "h \ H" "h \ J" "h \ K" for x h y proof - obtain \ where "x \ f" "\>0" and \: "\t. \dist x t \ \; t \ affine hull f\ \ t \ f" using x by (force simp: mem_rel_interior_cball) then have "y \ x" using fa0 less0 by force define x' where "x' \ x + (\ / norm(y - x)) *\<^sub>R (x - y)" have "x \ affine hull f \ y \ affine hull f" by (metis \x \ f\ hull_inc mem_rel_interior_cball y) moreover have "dist x x' \ \" using \0 < \\ \y \ x\ by (simp add: x'_def divide_simps dist_norm norm_minus_commute) ultimately have "x' \ f" by (simp add: \ mem_affine_3_minus x'_def) have "x' \ S" using \f face_of S\ \x' \ f\ face_of_imp_subset by auto then have "x' \ h" using Seq that(5) by blast then have "x' \ {x. fa h \ x \ 0}" using fa that(5) by blast moreover have "\ / norm (y - x) * -(fa h \ y) > 0" using \0 < \\ \y \ x\ less0 by (simp add: field_split_simps) ultimately show ?thesis by (simp add: x'_def fa0 inner_diff_right inner_right_distrib) qed show "rel_interior f \ \(IFJK ` H)" unfolding IFJK_def by (smt (verit, ccfv_SIG) A E H INT_I in_mono mem_Collect_eq subsetI) show "\(IFJK ` H) \ rel_interior f" using \K \ H\ \disjnt J K\ apply (clarsimp simp add: ball_Un E H disjnt_iff IFJK_def) apply (smt (verit, del_insts) IntI Int_Collect subsetD) done qed obtain z where zrelf: "z \ rel_interior f" using relif by blast moreover have H: "z \ IFJK h \ (x \ IFJK h) = (hyperplane_side (fa h, 0) z = hyperplane_side (fa h, 0) x)" for h x using zrelf by (auto simp: IFJK_def hyperplane_side_def sgn_if split: if_split_asm) then have "z \ \(IFJK ` H) \ (x \ \(IFJK ` H)) = hyperplane_equiv A z x" for x unfolding A_def Inter_iff hyperplane_equiv_def ball_simps using H by blast then have "x \ rel_interior f \ hyperplane_equiv A z x" for x using relint_f zrelf by presburger ultimately show ?thesis by (metis equalityI hyperplane_cell mem_Collect_eq subset_iff) qed have 4: "rel_interior f \ S" by (meson face_of_imp_subset order_trans rel_interior_subset that(1)) show ?thesis using "1" "2" "3" "4" by blast qed have hyper2: "(closure c face_of S \ aff_dim (closure c) = d) \ rel_interior (closure c) = c" if c: "hyperplane_cell A c" and "c \ S" "aff_dim c = d" for c proof (intro conjI) obtain J where "J \ H" and J: "c = (\h \ J. {x. (fa h) \ x < 0}) \ (\h \ (H - J). {x. (fa h) \ x = 0})" proof - obtain z where z: "c = {y. \x \ H. sgn (fa x \ y) = sgn (fa x \ z)}" using c by (force simp: hyperplane_cell A_def hyperplane_equiv_def hyperplane_side_def) show thesis proof let ?J = "{h \ H. sgn(fa h \ z) = -1}" have 1: "fa h \ x < 0" if "\h\H. sgn (fa h \ x) = sgn (fa h \ z)" and "h \ H" and "sgn (fa h \ z) = - 1" for x h using that by (metis sgn_1_neg) have 2: "sgn (fa h \ z) = - 1" if "\h\H. sgn (fa h \ x) = sgn (fa h \ z)" and "h \ H" and "fa h \ x \ 0" for x h proof - have "\0 < fa h \ x; 0 < fa h \ z\ \ False" using that fa by (smt (verit, del_insts) Inter_iff Seq \c \ S\ mem_Collect_eq subset_iff z) then show ?thesis by (metis that sgn_if sgn_zero_iff) qed have 3: "sgn (fa h \ x) = sgn (fa h \ z)" if "h \ H" and "\h. h \ H \ sgn (fa h \ z) = - 1 \ fa h \ x < 0" and "\h\H - {h \ H. sgn (fa h \ z) = - 1}. fa h \ x = 0" for x h using that 2 by (metis (mono_tags, lifting) Diff_iff mem_Collect_eq sgn_neg) show "c = (\h \?J. {x. fa h \ x < 0}) \ (\h\H - ?J. {x. fa h \ x = 0})" unfolding z by (auto intro: 1 2 3) qed auto qed have "finite J" using \J \ H\ \finite H\ finite_subset by blast show "closure c face_of S" proof - have cc: "closure c = closure (\h\J. {x. fa h \ x < 0}) \ closure (\h\H - J. {x. fa h \ x = 0})" unfolding J proof (rule closure_Int_convex) show "convex (\h\J. {x. fa h \ x < 0})" by (simp add: convex_INT convex_halfspace_lt) show "convex (\h\H - J. {x. fa h \ x = 0})" by (simp add: convex_INT convex_hyperplane) have o1: "open (\h\J. {x. fa h \ x < 0})" by (metis open_INT[OF \finite J\] open_halfspace_lt) have o2: "openin (top_of_set (affine hull (\h\H - J. {x. fa h \ x = 0}))) (\h\H - J. {x. fa h \ x = 0})" proof - have "affine (\h\H - J. {n. fa h \ n = 0})" using affine_hyperplane by auto then show ?thesis by (metis (no_types) affine_hull_eq openin_subtopology_self) qed show "rel_interior (\h\J. {x. fa h \ x < 0}) \ rel_interior (\h\H - J. {x. fa h \ x = 0}) \ {}" by (metis nonempty_hyperplane_cell c rel_interior_open o1 rel_interior_openin o2 J) qed have clo_im_J: "closure ` ((\h. {x. fa h \ x < 0}) ` J) = (\h. {x. fa h \ x \ 0}) ` J" using \J \ H\ by (force simp: image_comp fa) have cleq: "closure (\h\H - J. {x. fa h \ x = 0}) = (\h\H - J. {x. fa h \ x = 0})" by (intro closure_closed) (blast intro: closed_hyperplane) have **: "(\h\J. {x. fa h \ x \ 0}) \ (\h\H - J. {x. fa h \ x = 0}) face_of S" if "(\h\J. {x. fa h \ x < 0}) \ {}" proof (cases "J=H") case True have [simp]: "(\x\H. {xa. fa x \ xa \ 0}) = \H" using fa by auto show ?thesis using \polyhedron S\ by (simp add: Seq True polyhedron_imp_convex face_of_refl) next case False have **: "(\h\J. {n. fa h \ n \ 0}) \ (\h\H - J. {x. fa h \ x = 0}) = (\h\H - J. S \ {x. fa h \ x = 0})" (is "?L = ?R") proof show "?L \ ?R" by clarsimp (smt (verit) DiffI InterI Seq fa mem_Collect_eq) show "?R \ ?L" using False Seq \J \ H\ fa by blast qed show ?thesis unfolding ** proof (rule face_of_Inter) show "(\h. S \ {x. fa h \ x = 0}) ` (H - J) \ {}" using False \J \ H\ by blast show "T face_of S" if T: "T \ (\h. S \ {x. fa h \ x = 0}) ` (H - J)" for T proof - obtain h where h: "T = S \ {x. fa h \ x = 0}" and "h \ H" "h \ J" using T by auto have "S \ {x. fa h \ x = 0} face_of S" proof (rule face_of_Int_supporting_hyperplane_le) show "convex S" by (simp add: assms(1) polyhedron_imp_convex) show "fa h \ x \ 0" if "x \ S" for x using that Seq fa \h \ H\ by auto qed then show ?thesis using h by blast qed qed qed have *: "\S. S \ (\h. {x. fa h \ x < 0}) ` J \ convex S \ open S" using convex_halfspace_lt open_halfspace_lt by fastforce show ?thesis unfolding cc apply (simp add: * closure_Inter_convex_open) by (metis "**" cleq clo_im_J image_image) qed show "aff_dim (closure c) = int d" by (simp add: that) show "rel_interior (closure c) = c" by (metis \finite A\ c convex_rel_interior_closure hyperplane_cell_convex hyperplane_cell_relative_interior) qed have "rel_interior ` {f. f face_of S \ aff_dim f = int d} = {C. hyperplane_cell A C \ C \ S \ aff_dim C = int d}" using hyper1 hyper2 by fastforce then show "bij_betw (rel_interior) {f. f face_of S \ aff_dim f = int d} {C. hyperplane_cell A C \ C \ S \ aff_dim C = int d}" unfolding bij_betw_def inj_on_def by (metis (mono_tags) hyper1 mem_Collect_eq) qed show ?thesis by (simp add: Euler_characteristic \finite A\) qed also have "\ = 0" proof - have A: "hyperplane_cellcomplex A (- h)" if "h \ H" for h proof (rule hyperplane_cellcomplex_mono [OF hyperplane_cell_cellcomplex]) have "- h = {x. fa h \ x = 0} \ - h = {x. fa h \ x < 0} \ - h = {x. 0 < fa h \ x}" by (smt (verit, ccfv_SIG) Collect_cong Collect_neg_eq fa that) then show "hyperplane_cell {(fa h,0)} (- h)" by (simp add: hyperplane_cell_singleton fa that) show "{(fa h,0)} \ A" by (simp add: A_def that) qed then have "\h. h \ H \ hyperplane_cellcomplex A h" using hyperplane_cellcomplex_Compl by fastforce then have "hyperplane_cellcomplex A S" by (simp add: Seq hyperplane_cellcomplex_Inter) then have D: "Euler_characteristic A (UNIV::'n set) = Euler_characteristic A (\H) + Euler_characteristic A (- \H)" using Euler_characteristic_cellcomplex_Un by (metis Compl_partition Diff_cancel Diff_eq Seq \finite A\ disjnt_def hyperplane_cellcomplex_Compl) have "Euler_characteristic A UNIV = Euler_characteristic {} (UNIV::'n set)" by (simp add: Euler_characterstic_invariant \finite A\) then have E: "Euler_characteristic A UNIV = (-1) ^ (DIM('n))" by (simp add: Euler_characteristic_cell) have DD: "Euler_characteristic A (\ (uminus ` J)) = (- 1) ^ DIM('n)" if "J \ {}" "J \ H" for J proof - define B where "B \ (\h. (fa h,0::real)) ` J" then have "B \ A" by (simp add: A_def image_mono that) have "\x. y = -x" if "y \ \ (uminus ` H)" for y::'n \ \Weirdly, the assumption is not used\ by (metis add.inverse_inverse) moreover have "-x \ \ (uminus ` H) \ x \ interior S" for x proof - have 1: "interior S = {x \ S. \h\H. fa h \ x < 0}" using rel_interior_polyhedron_explicit [OF \finite H\ _ fa] by (metis (no_types, lifting) inf_top_left Hsub Seq \affine hull S = UNIV\ rel_interior_interior) have 2: "\x y. \y \ H; \h\H. fa h \ x < 0; - x \ y\ \ False" by (smt (verit, best) fa inner_minus_right mem_Collect_eq) show ?thesis apply (simp add: 1) by (smt (verit) 2 * fa Inter_iff Seq inner_minus_right mem_Collect_eq) qed ultimately have INT_Compl_H: "\ (uminus ` H) = uminus ` interior S" by blast obtain z where z: "z \ \ (uminus ` J)" using \J \ H\ \\ (uminus ` H) = uminus ` interior S\ intS by fastforce have "\ (uminus ` J) = Collect (hyperplane_equiv B z)" (is "?L = ?R") proof show "?L \ ?R" using fa \J \ H\ z by (fastforce simp: hyperplane_equiv_def hyperplane_side_def B_def set_eq_iff ) show "?R \ ?L" using z \J \ H\ apply (clarsimp simp add: hyperplane_equiv_def hyperplane_side_def B_def) by (metis fa in_mono mem_Collect_eq sgn_le_0_iff) qed then have hyper_B: "hyperplane_cell B (\ (uminus ` J))" by (metis hyperplane_cell) have "Euler_characteristic A (\ (uminus ` J)) = Euler_characteristic B (\ (uminus ` J))" proof (rule Euler_characterstic_invariant [OF \finite A\]) show "finite B" using \B \ A\ \finite A\ finite_subset by blast show "hyperplane_cellcomplex A (\ (uminus ` J))" by (meson \B \ A\ hyper_B hyperplane_cell_cellcomplex hyperplane_cellcomplex_mono) show "hyperplane_cellcomplex B (\ (uminus ` J))" by (simp add: hyper_B hyperplane_cell_cellcomplex) qed also have "\ = (- 1) ^ nat (aff_dim (\ (uminus ` J)))" using Euler_characteristic_cell hyper_B by blast also have "\ = (- 1) ^ DIM('n)" proof - have "affine hull \ (uminus ` H) = UNIV" by (simp add: INT_Compl_H affine_hull_nonempty_interior intS interior_negations) then have "affine hull \ (uminus ` J) = UNIV" by (metis Inf_superset_mono hull_mono subset_UNIV subset_antisym subset_image_iff that(2)) with aff_dim_eq_full show ?thesis by (metis nat_int) qed finally show ?thesis . qed have EE: "(\\ | \ \ uminus ` H \ \\{}. (-1) ^ (card \ + 1) * Euler_characteristic A (\\)) = (\\ | \ \ uminus ` H \ \ \ {}. (-1) ^ (card \ + 1) * (- 1) ^ DIM('n))" by (intro sum.cong [OF refl]) (fastforce simp: subset_image_iff intro!: DD) also have "\ = (-1) ^ DIM('n)" proof - have A: "(\y = 1..card H. \t\{x \ {\. \ \ uminus ` H \ \ \ {}}. card x = y}. (- 1) ^ (card t + 1)) = (\\\{\. \ \ uminus ` H \ \ \ {}}. (- 1) ^ (card \ + 1))" proof (rule sum.group) have "\C. \C \ uminus ` H; C \ {}\ \ Suc 0 \ card C \ card C \ card H" by (meson \finite H\ card_eq_0_iff finite_surj le_zero_eq not_less_eq_eq surj_card_le) then show "card ` {\. \ \ uminus ` H \ \ \ {}} \ {1..card H}" by force qed (auto simp: \finite H\) have "(\n = Suc 0..card H. - (int (card {x. x \ uminus ` H \ x \ {} \ card x = n}) * (- 1) ^ n)) = (\n = Suc 0..card H. (-1) ^ (Suc n) * (card H choose n))" proof (rule sum.cong [OF refl]) fix n assume "n \ {Suc 0..card H}" then have "{\. \ \ uminus ` H \ \ \ {} \ card \ = n} = {\. \ \ uminus ` H \ card \ = n}" by auto then have "card{\. \ \ uminus ` H \ \ \ {} \ card \ = n} = card (uminus ` H) choose n" by (simp add: \finite H\ n_subsets) also have "\ = card H choose n" by (metis card_image double_complement inj_on_inverseI) finally show "- (int (card {\. \ \ uminus ` H \ \ \ {} \ card \ = n}) * (- 1) ^ n) = (- 1) ^ Suc n * int (card H choose n)" by simp qed also have "\ = - (\k = Suc 0..card H. (-1) ^ k * (card H choose k))" by (simp add: sum_negf) also have "\ = 1 - (\k=0..card H. (-1) ^ k * (card H choose k))" using atLeastSucAtMost_greaterThanAtMost by (simp add: sum.head [of 0]) also have "\ = 1 - 0 ^ card H" using binomial_ring [of "-1" "1::int" "card H"] by (simp add: mult.commute atLeast0AtMost) also have "\ = 1" using Seq \finite H\ \S \ UNIV\ card_0_eq by auto finally have C: "(\n = Suc 0..card H. - (int (card {x. x \ uminus ` H \ x \ {} \ card x = n}) * (- 1) ^ n)) = (1::int)" . have "(\\ | \ \ uminus ` H \ \ \ {}. (- 1) ^ (card \ + 1)) = (1::int)" unfolding A [symmetric] by (simp add: C) then show ?thesis by (simp flip: sum_distrib_right power_Suc) qed finally have "(\\ | \ \ uminus ` H \ \\{}. (-1) ^ (card \ + 1) * Euler_characteristic A (\\)) = (-1) ^ DIM('n)" . then have "Euler_characteristic A (\ (uminus ` H)) = (-1) ^ (DIM('n))" using Euler_characteristic_inclusion_exclusion [OF \finite A\] by (smt (verit) A Collect_cong \finite H\ finite_imageI image_iff sum.cong) then show ?thesis using D E by (simp add: uminus_Inf Seq) qed finally show ?thesis . qed subsection \Euler-Poincare relation for special $(n-1)$-dimensional polytope\ lemma Euler_Poincare_lemma: fixes p :: "'n::euclidean_space set" assumes "DIM('n) \ 2" "polytope p" "i \ Basis" and affp: "affine hull p = {x. x \ i = 1}" shows "(\d = 0..DIM('n) - 1. (-1) ^ d * int (card {f. f face_of p \ aff_dim f = int d})) = 1" proof - have "aff_dim p = aff_dim {x. i \ x = 1}" by (metis (no_types, lifting) Collect_cong aff_dim_affine_hull affp inner_commute) also have "... = int (DIM('n) - 1)" using aff_dim_hyperplane [of i 1] \i \ Basis\ by fastforce finally have AP: "aff_dim p = int (DIM('n) - 1)" . show ?thesis proof (cases "p = {}") case True with AP show ?thesis by simp next case False define S where "S \ conic hull p" have 1: "(conic hull f) \ {x. x \ i = 1} = f" if "f \ {x. x \ i = 1}" for f using that by (smt (verit, ccfv_threshold) affp conic_hull_Int_affine_hull hull_hull inner_zero_left mem_Collect_eq) obtain K where "finite K" and K: "p = convex hull K" by (meson assms(2) polytope_def) then have "convex_cone hull K = conic hull (convex hull K)" using False convex_cone_hull_separate_nonempty by auto then have "polyhedron S" using polyhedron_convex_cone_hull by (simp add: S_def \polytope p\ polyhedron_conic_hull_polytope) then have "convex S" by (simp add: polyhedron_imp_convex) then have "conic S" by (simp add: S_def conic_conic_hull) then have "0 \ S" by (simp add: False S_def) have "S \ UNIV" proof assume "S = UNIV" then have "conic hull p \ {x. x\i = 1} = p" by (metis "1" affp hull_subset) then have "bounded {x. x \ i = 1}" using S_def \S = UNIV\ assms(2) polytope_imp_bounded by auto then obtain B where "B>0" and B: "\x. x \ {x. x \ i = 1} \ norm x \ B" using bounded_normE by blast define x where "x \ (\b\Basis. (if b=i then 1 else B+1) *\<^sub>R b)" obtain j where j: "j \ Basis" "j\i" using \DIM('n) \ 2\ by (metis DIM_complex DIM_ge_Suc0 card_2_iff' card_le_Suc0_iff_eq euclidean_space_class.finite_Basis le_antisym) have "B+1 \ \x \ j\" using j by (simp add: x_def) also have "\ \ norm x" using Basis_le_norm j by blast finally have "norm x > B" by simp moreover have "x \ i = 1" by (simp add: x_def \i \ Basis\) ultimately show False using B by force qed have "S \ {}" by (metis False S_def empty_subsetI equalityI hull_subset) have "\c x. \0 < c; x \ p; x \ 0\ \ 0 < (c *\<^sub>R x) \ i" by (metis (mono_tags) Int_Collect Int_iff affp hull_inc inner_commute inner_scaleR_right mult.right_neutral) then have doti_gt0: "0 < x \ i" if S: "x \ S" and "x \ 0" for x using that by (auto simp: S_def conic_hull_explicit) have "\a. {a} face_of S \ a = 0" using \conic S\ conic_contains_0 face_of_conic by blast moreover have "{0} face_of S" proof - have "\a b u. \a \ S; b \ S; a \ b; u < 1; 0 < u; (1 - u) *\<^sub>R a + u *\<^sub>R b = 0\ \ False" using conic_def euclidean_all_zero_iff inner_left_distrib scaleR_eq_0_iff by (smt (verit, del_insts) doti_gt0 \conic S\ \i \ Basis\) then show ?thesis by (auto simp: in_segment face_of_singleton extreme_point_of_def \0 \ S\) qed ultimately have face_0: "{f. f face_of S \ (\a. f = {a})} = {{0}}" by auto have "interior S \ {}" proof assume "interior S = {}" then obtain a b where "a \ 0" and ab: "S \ {x. a \ x = b}" by (metis \convex S\ empty_interior_subset_hyperplane) have "{x. x \ i = 1} \ {x. a \ x = b}" by (metis S_def ab affine_hyperplane affp hull_inc subset_eq subset_hull) moreover have "\ {x. x \ i = 1} \ {x. a \ x = b}" using aff_dim_hyperplane [of a b] by (metis AP \a \ 0\ aff_dim_eq_full_gen affine_hyperplane affp hull_subset less_le_not_le subset_hull) ultimately have "S \ {x. x \ i = 1}" using ab by auto with \S \ {}\ show False using \conic S\ conic_contains_0 by fastforce qed then have "(\d = 0..DIM('n). (-1) ^ d * int (card {f. f face_of S \ aff_dim f = int d})) = 0" using Euler_polyhedral_cone \S \ UNIV\ \conic S\ \polyhedron S\ by blast then have "1 + (\d = 1..DIM('n). (-1) ^ d * (card {f. f face_of S \ aff_dim f = d})) = 0" by (simp add: sum.atLeast_Suc_atMost aff_dim_eq_0 face_0) moreover have "(\d = 1..DIM('n). (-1) ^ d * (card {f. f face_of S \ aff_dim f = d})) = - (\d = 0..DIM('n) - 1. (-1) ^ d * int (card {f. f face_of p \ aff_dim f = int d}))" proof - have "(\d = 1..DIM('n). (-1) ^ d * (card {f. f face_of S \ aff_dim f = d})) = (\d = Suc 0..Suc (DIM('n)-1). (-1) ^ d * (card {f. f face_of S \ aff_dim f = d}))" by auto also have "... = - (\d = 0..DIM('n) - 1. (-1) ^ d * card {f. f face_of S \ aff_dim f = 1 + int d})" unfolding sum.atLeast_Suc_atMost_Suc_shift by (simp add: sum_negf) also have "... = - (\d = 0..DIM('n) - 1. (-1) ^ d * card {f. f face_of p \ aff_dim f = int d})" proof - { fix d assume "d \ DIM('n) - Suc 0" have conic_face_p: "(conic hull f) face_of S" if "f face_of p" for f proof (cases "f={}") case False have "{c *\<^sub>R x |c x. 0 \ c \ x \ f} \ {c *\<^sub>R x |c x. 0 \ c \ x \ p}" using face_of_imp_subset that by blast moreover have "convex {c *\<^sub>R x |c x. 0 \ c \ x \ f}" by (metis (no_types) cone_hull_expl convex_cone_hull face_of_imp_convex that) moreover have "(\c x. ca *\<^sub>R a = c *\<^sub>R x \ 0 \ c \ x \ f) \ (\c x. cb *\<^sub>R b = c *\<^sub>R x \ 0 \ c \ x \ f)" if "\a\p. \b\p. (\x\f. x \ open_segment a b) \ a \ f \ b \ f" and "0 \ ca" "a \ p" "0 \ cb" "b \ p" and "0 \ cx" "x \ f" and oseg: "cx *\<^sub>R x \ open_segment (ca *\<^sub>R a) (cb *\<^sub>R b)" for ca a cb b cx x proof - have ai: "a \ i = 1" and bi: "b \ i = 1" using affp hull_inc that(3,5) by fastforce+ have xi: "x \ i = 1" using affp that \f face_of p\ face_of_imp_subset hull_subset by fastforce show ?thesis proof (cases "cx *\<^sub>R x = 0") case True then show ?thesis using \{0} face_of S\ face_ofD \conic S\ that by (smt (verit, best) S_def conic_def hull_subset insertCI singletonD subsetD) next case False then have "cx \ 0" "x \ 0" by auto obtain u where "0 < u" "u < 1" and u: "cx *\<^sub>R x = (1 - u) *\<^sub>R (ca *\<^sub>R a) + u *\<^sub>R (cb *\<^sub>R b)" using oseg in_segment(2) by metis show ?thesis proof (cases "x = a") case True then have ua: "(cx - (1 - u) * ca) *\<^sub>R a = (u * cb) *\<^sub>R b" using u by (simp add: algebra_simps) then have "(cx - (1 - u) * ca) * 1 = u * cb * 1" by (metis ai bi inner_scaleR_left) then have "a=b \ cb = 0" using ua \0 < u\ by force then show ?thesis by (metis True scaleR_zero_left that(2) that(4) that(7)) next case False show ?thesis proof (cases "x = b") case True then have ub: "(cx - (u * cb)) *\<^sub>R b = ((1 - u) * ca) *\<^sub>R a" using u by (simp add: algebra_simps) then have "(cx - (u * cb)) * 1 = ((1 - u) * ca) * 1" by (metis ai bi inner_scaleR_left) then have "a=b \ ca = 0" using \u < 1\ ub by auto then show ?thesis using False True that(4) that(7) by auto next case False have "cx > 0" using \cx \ 0\ \0 \ cx\ by linarith have False if "ca = 0" proof - have "cx = u * cb" by (metis add_0 bi inner_real_def inner_scaleR_left real_inner_1_right scale_eq_0_iff that u xi) then show False using \x \ b\ \cx \ 0\ that u by force qed with \0 \ ca\ have "ca > 0" by force have aff: "x \ affine hull p \ a \ affine hull p \ b \ affine hull p" using affp xi ai bi by blast show ?thesis proof (cases "cb=0") case True have u': "cx *\<^sub>R x = ((1 - u) * ca) *\<^sub>R a" using u by (simp add: True) then have "cx = ((1 - u) * ca)" by (metis ai inner_scaleR_left mult.right_neutral xi) then show ?thesis using True u' \cx \ 0\ \ca \ 0\ \x \ f\ by auto next case False with \cb \ 0\ have "cb > 0" by linarith { have False if "a=b" proof - have *: "cx *\<^sub>R x = ((1 - u) * ca + u * cb) *\<^sub>R b" using u that by (simp add: algebra_simps) then have "cx = ((1 - u) * ca + u * cb)" by (metis xi bi inner_scaleR_left mult.right_neutral) with \x \ b\ \cx \ 0\ * show False by force qed } moreover have "cx *\<^sub>R x /\<^sub>R cx = (((1 - u) * ca) *\<^sub>R a + (cb * u) *\<^sub>R b) /\<^sub>R cx" using u by simp then have xeq: "x = ((1-u) * ca / cx) *\<^sub>R a + (cb * u / cx) *\<^sub>R b" by (simp add: \cx \ 0\ divide_inverse_commute scaleR_right_distrib) then have proj: "1 = ((1-u) * ca / cx) + (cb * u / cx)" using ai bi xi by (simp add: inner_left_distrib) then have eq: "cx + ca * u = ca + cb * u" using \cx > 0\ by (simp add: field_simps) have "\u>0. u < 1 \ x = (1 - u) *\<^sub>R a + u *\<^sub>R b" proof (intro exI conjI) show "0 < inverse cx * u * cb" by (simp add: \0 < cb\ \0 < cx\ \0 < u\) show "inverse cx * u * cb < 1" using proj \0 < ca\ \0 < cx\ \u < 1\ by (simp add: divide_simps) show "x = (1 - inverse cx * u * cb) *\<^sub>R a + (inverse cx * u * cb) *\<^sub>R b" using eq \cx \ 0\ by (simp add: xeq field_simps) qed ultimately show ?thesis using that by (metis in_segment(2)) qed qed qed qed qed ultimately show ?thesis using that by (auto simp: S_def conic_hull_explicit face_of_def) qed auto moreover have conic_hyperplane_eq: "conic hull (f \ {x. x \ i = 1}) = f" if "f face_of S" "0 < aff_dim f" for f proof show "conic hull (f \ {x. x \ i = 1}) \ f" by (metis \conic S\ face_of_conic inf_le1 subset_hull that(1)) have "\c x'. x = c *\<^sub>R x' \ 0 \ c \ x' \ f \ x' \ i = 1" if "x \ f" for x proof (cases "x=0") case True obtain y where "y \ f" "y \ 0" by (metis \0 < aff_dim f\ aff_dim_sing aff_dim_subset insertCI linorder_not_le subset_iff) then have "y \ i > 0" using \f face_of S\ doti_gt0 face_of_imp_subset by blast then have "y /\<^sub>R (y \ i) \ f \ (y /\<^sub>R (y \ i)) \ i = 1" using \conic S\ \f face_of S\ \y \ f\ conic_def face_of_conic by fastforce then show ?thesis using True by fastforce next case False then have "x \ i > 0" using \f face_of S\ doti_gt0 face_of_imp_subset that by blast then have "x /\<^sub>R (x \ i) \ f \ (x /\<^sub>R (x \ i)) \ i = 1" using \conic S\ \f face_of S\ \x \ f\ conic_def face_of_conic by fastforce then show ?thesis by (metis \0 < x \ i\ divideR_right eucl_less_le_not_le) qed then show "f \ conic hull (f \ {x. x \ i = 1})" by (auto simp: conic_hull_explicit) qed have conic_face_S: "conic hull f face_of S" if "f face_of S" for f by (metis \conic S\ face_of_conic hull_same that) have aff_1d: "aff_dim (conic hull f) = aff_dim f + 1" (is "?lhs = ?rhs") if "f face_of p" and "f \ {}" for f proof (rule order_antisym) have "?lhs \ aff_dim(affine hull (insert 0 (affine hull f)))" proof (intro aff_dim_subset hull_minimal) show "f \ affine hull insert 0 (affine hull f)" by (metis hull_insert hull_subset insert_subset) show "conic (affine hull insert 0 (affine hull f))" by (metis affine_hull_span_0 conic_span hull_inc insertI1) qed also have "\ \ ?rhs" by (simp add: aff_dim_insert) finally show "?lhs \ ?rhs" . have "aff_dim f < aff_dim (conic hull f)" proof (intro aff_dim_psubset psubsetI) show "affine hull f \ affine hull (conic hull f)" by (simp add: hull_mono hull_subset) have "0 \ affine hull f" using affp face_of_imp_subset hull_mono that(1) by fastforce moreover have "0 \ affine hull (conic hull f)" by (simp add: \f \ {}\ hull_inc) ultimately show "affine hull f \ affine hull (conic hull f)" by auto qed then show "?rhs \ ?lhs" by simp qed have face_S_imp_face_p: "\f. f face_of S \ f \ {x. x \ i = 1} face_of p" by (metis "1" S_def affp convex_affine_hull face_of_slice hull_subset) have conic_eq_f: "conic hull f \ {x. x \ i = 1} = f" if "f face_of p" for f by (metis "1" affp face_of_imp_subset hull_subset le_inf_iff that) have dim_f_hyperplane: "aff_dim (f \ {x. x \ i = 1}) = int d" if "f face_of S" "aff_dim f = 1 + int d" for f proof - have "conic f" using \conic S\ face_of_conic that(1) by blast then have "0 \ f" using conic_contains_0 that by force moreover have "\ f \ {0}" using subset_singletonD that(2) by fastforce ultimately obtain y where y: "y \ f" "y \ 0" by blast then have "y \ i > 0" using doti_gt0 face_of_imp_subset that(1) by blast have "aff_dim (conic hull (f \ {x. x \ i = 1})) = aff_dim (f \ {x. x \ i = 1}) + 1" proof (rule aff_1d) show "f \ {x. x \ i = 1} face_of p" by (simp add: face_S_imp_face_p that(1)) have "inverse(y \ i) *\<^sub>R y \ f" using \0 < y \ i\ \conic S\ conic_mul face_of_conic that(1) y(1) by fastforce moreover have "inverse(y \ i) *\<^sub>R y \ {x. x \ i = 1}" using \y \ i > 0\ by (simp add: field_simps) ultimately show "f \ {x. x \ i = 1} \ {}" by blast qed then show ?thesis by (simp add: conic_hyperplane_eq that) qed have "card {f. f face_of S \ aff_dim f = 1 + int d} = card {f. f face_of p \ aff_dim f = int d}" proof (intro bij_betw_same_card bij_betw_imageI) show "inj_on (\f. f \ {x. x \ i = 1}) {f. f face_of S \ aff_dim f = 1 + int d}" by (smt (verit) conic_hyperplane_eq inj_on_def mem_Collect_eq of_nat_less_0_iff) show "(\f. f \ {x. x \ i = 1}) ` {f. f face_of S \ aff_dim f = 1 + int d} = {f. f face_of p \ aff_dim f = int d}" using aff_1d conic_eq_f conic_face_p by (fastforce simp: image_iff face_S_imp_face_p dim_f_hyperplane) qed } then show ?thesis by force qed finally show ?thesis . qed ultimately show ?thesis by auto qed qed corollary Euler_poincare_special: fixes p :: "'n::euclidean_space set" assumes "2 \ DIM('n)" "polytope p" "i \ Basis" and affp: "affine hull p = {x. x \ i = 0}" shows "(\d = 0..DIM('n) - 1. (-1) ^ d * card {f. f face_of p \ aff_dim f = d}) = 1" proof - { fix d have eq: "image((+) i) ` {f. f face_of p} \ image((+) i) ` {f. aff_dim f = int d} = image((+) i) ` {f. f face_of p} \ {f. aff_dim f = int d}" by (auto simp: aff_dim_translation_eq) have "card {f. f face_of p \ aff_dim f = int d} = card (image((+) i) ` {f. f face_of p \ aff_dim f = int d})" by (simp add: inj_on_image card_image) also have "\ = card (image((+) i) ` {f. f face_of p} \ {f. aff_dim f = int d})" by (simp add: Collect_conj_eq image_Int inj_on_image eq) also have "\ = card {f. f face_of (+) i ` p \ aff_dim f = int d}" by (simp add: Collect_conj_eq faces_of_translation) finally have "card {f. f face_of p \ aff_dim f = int d} = card {f. f face_of (+) i ` p \ aff_dim f = int d}" . } then have "(\d = 0..DIM('n) - 1. (-1) ^ d * card {f. f face_of p \ aff_dim f = d}) = (\d = 0..DIM('n) - 1. (-1) ^ d * card {f. f face_of (+) i ` p \ aff_dim f = int d})" by simp also have "\ = 1" proof (rule Euler_Poincare_lemma) have "\x. \i \ Basis; x \ i = 1\ \ \y. y \ i = 0 \ x = y + i" by (metis add_cancel_left_left eq_diff_eq inner_diff_left inner_same_Basis) then show "affine hull (+) i ` p = {x. x \ i = 1}" using \i \ Basis\ unfolding affine_hull_translation affp by (auto simp: algebra_simps) qed (use assms polytope_translation_eq in auto) finally show ?thesis . qed subsection \Now Euler-Poincare for a general full-dimensional polytope\ theorem Euler_Poincare_full: fixes p :: "'n::euclidean_space set" assumes "polytope p" "aff_dim p = DIM('n)" shows "(\d = 0..DIM('n). (-1) ^ d * (card {f. f face_of p \ aff_dim f = d})) = 1" proof - define augm:: "'n \ 'n \ real" where "augm \ \x. (x,0)" define S where "S \ augm ` p" obtain i::'n where i: "i \ Basis" by (meson SOME_Basis) have "bounded_linear augm" by (auto simp: augm_def bounded_linearI') then have "polytope S" unfolding S_def using polytope_linear_image \polytope p\ bounded_linear.linear by blast have face_pS: "\F. F face_of p \ augm ` F face_of S" using S_def \bounded_linear augm\ augm_def bounded_linear.linear face_of_linear_image inj_on_def by blast have aff_dim_eq[simp]: "aff_dim (augm ` F) = aff_dim F" for F using \bounded_linear augm\ aff_dim_injective_linear_image bounded_linear.linear unfolding augm_def inj_on_def by blast have *: "{F. F face_of S \ aff_dim F = int d} = (image augm) ` {F. F face_of p \ aff_dim F = int d}" (is "?lhs = ?rhs") for d proof have "\G. \G face_of S; aff_dim G = int d\ \ \F. F face_of p \ aff_dim F = int d \ G = augm ` F" by (metis face_pS S_def aff_dim_eq face_of_imp_subset subset_imageE) then show "?lhs \ ?rhs" by (auto simp: image_iff) qed (auto simp: image_iff face_pS) have ceqc: "card {f. f face_of S \ aff_dim f = int d} = card {f. f face_of p \ aff_dim f = int d}" for d unfolding * by (rule card_image) (auto simp: inj_on_def augm_def) have "(\d = 0..DIM('n \ real) - 1. (- 1) ^ d * int (card {f. f face_of S \ aff_dim f = int d})) = 1" proof (rule Euler_poincare_special) show "2 \ DIM('n \ real)" by auto have snd0: "(a, b) \ affine hull S \ b = 0" for a b using S_def \bounded_linear augm\ affine_hull_linear_image augm_def by blast moreover have "\a. (a, 0) \ affine hull S" using S_def \bounded_linear augm\ aff_dim_eq_full affine_hull_linear_image assms(2) augm_def by blast ultimately show "affine hull S = {x. x \ (0::'n, 1::real) = 0}" by auto qed (auto simp: \polytope S\ Basis_prod_def) then show ?thesis by (simp add: ceqc) qed text \In particular, the Euler relation in 3 dimensions\ corollary Euler_relation: fixes p :: "'n::euclidean_space set" assumes "polytope p" "aff_dim p = 3" "DIM('n) = 3" shows "(card {v. v face_of p \ aff_dim v = 0} + card {f. f face_of p \ aff_dim f = 2}) - card {e. e face_of p \ aff_dim e = 1} = 2" proof - have "\x. \x face_of p; aff_dim x = 3\ \ x = p" using assms by (metis face_of_aff_dim_lt less_irrefl polytope_imp_convex) then have 3: "{f. f face_of p \ aff_dim f = 3} = {p}" using assms by (auto simp: face_of_refl polytope_imp_convex) have "(\d = 0..3. (-1) ^ d * int (card {f. f face_of p \ aff_dim f = int d})) = 1" using Euler_Poincare_full [of p] assms by simp then show ?thesis by (simp add: sum.atLeast0_atMost_Suc_shift numeral_3_eq_3 3) qed end \ No newline at end of file diff --git a/thys/Euler_Polyhedron_Formula/Inclusion_Exclusion.thy b/thys/Euler_Polyhedron_Formula/Inclusion_Exclusion.thy deleted file mode 100644 --- a/thys/Euler_Polyhedron_Formula/Inclusion_Exclusion.thy +++ /dev/null @@ -1,296 +0,0 @@ -section \Inclusion-exclusion principle\ - -text \Inclusion-exclusion principle, the usual and generalized forms.\ - -theory Inclusion_Exclusion - imports Main -begin - -lemma subset_insert_lemma: - "{T. T \ (insert a S) \ P T} = {T. T \ S \ P T} \ {insert a T |T. T \ S \ P(insert a T)}" (is "?L=?R") -proof - show "?L \ ?R" - by (smt (verit) UnI1 UnI2 insert_Diff mem_Collect_eq subsetI subset_insert_iff) -qed blast - -locale Incl_Excl = - fixes P :: "'a set \ bool" and f :: "'a set \ 'b::ring_1" - assumes disj_add: "\P S; P T; disjnt S T\ \ f(S \ T) = f S + f T" - and empty: "P{}" - and Int: "\P S; P T\ \ P(S \ T)" - and Un: "\P S; P T\ \ P(S \ T)" - and Diff: "\P S; P T\ \ P(S - T)" - -begin - -lemma f_empty [simp]: "f{} = 0" - using disj_add empty by fastforce - -lemma f_Un_Int: "\P S; P T\ \ f(S \ T) + f(S \ T) = f S + f T" - by (smt (verit, ccfv_threshold) Diff Int Groups.add_ac Incl_Excl.Diff Incl_Excl.Int Incl_Excl_axioms Int_Diff_Un Int_Diff_disjoint Int_absorb Un_Diff Un_Int_eq disj_add disjnt_def group_cancel.add2 sup_bot.right_neutral) - - -lemma restricted_indexed: - assumes "finite A" and X: "\a. a \ A \ P(X a)" - shows "f(\(X ` A)) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\ (X ` B)))" -proof - - have "\finite A; card A = n; \a \ A. P (X a)\ - \ f(\(X ` A)) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\ (X ` B)))" for n X and A :: "'c set" - proof (induction n arbitrary: A X rule: less_induct) - case (less n0 A0 X) - show ?case - proof (cases "n0=0") - case True - with less show ?thesis - by fastforce - next - case False - with less.prems obtain A n a where *: "n0 = Suc n" "A0 = insert a A" "a \ A" "card A = n" "finite A" - by (metis card_Suc_eq_finite not0_implies_Suc) - with less have "P (X a)" by blast - have APX: "\a \ A. P (X a)" - by (simp add: "*" less.prems) - have PUXA: "P (\ (X ` A))" - using \finite A\ APX - by (induction) (auto simp: empty Un) - have "f (\ (X ` A0)) = f (X a \ \ (X ` A))" - by (simp add: *) - also have "... = f (X a) + f (\ (X ` A)) - f (X a \ \ (X ` A))" - using f_Un_Int add_diff_cancel PUXA \P (X a)\ by metis - also have "... = f (X a) - (\B | B \ A \ B \ {}. (- 1) ^ card B * f (\ (X ` B))) + - (\B | B \ A \ B \ {}. (- 1) ^ card B * f (X a \ \ (X ` B)))" - proof - - have 1: "f (\i\A. X a \ X i) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\b\B. X a \ X b))" - using less.IH [of n A "\i. X a \ X i"] APX Int \P (X a)\ by (simp add: *) - have 2: "X a \ \ (X ` A) = (\i\A. X a \ X i)" - by auto - have 3: "f (\ (X ` A)) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\ (X ` B)))" - using less.IH [of n A X] APX Int \P (X a)\ by (simp add: *) - show ?thesis - unfolding 3 2 1 - by (simp add: sum_negf) - qed - also have "... = (\B | B \ A0 \ B \ {}. (- 1) ^ (card B + 1) * f (\ (X ` B)))" - proof - - have F: "{insert a B |B. B \ A} = insert a ` Pow A \ {B. B \ A \ B \ {}} = Pow A - {{}}" - by auto - have G: "(\B\Pow A. (- 1) ^ card (insert a B) * f (X a \ \ (X ` B))) = (\B\Pow A. - ((- 1) ^ card B * f (X a \ \ (X ` B))))" - proof (rule sum.cong [OF refl]) - fix B - assume B: "B \ Pow A" - then have "finite B" - using \finite A\ finite_subset by auto - show "(- 1) ^ card (insert a B) * f (X a \ \ (X ` B)) = - ((- 1) ^ card B * f (X a \ \ (X ` B)))" - using B * by (auto simp add: card_insert_if \finite B\) - qed - have disj: "{B. B \ A \ B \ {}} \ {insert a B |B. B \ A} = {}" - using * by blast - have inj: "inj_on (insert a) (Pow A)" - using "*" inj_on_def by fastforce - show ?thesis - apply (simp add: * subset_insert_lemma sum.union_disjoint disj sum_negf) - apply (simp add: F G sum_negf sum.reindex [OF inj] o_def sum_diff *) - done - qed - finally show ?thesis . - qed - qed - then show ?thesis - by (meson assms) -qed - -lemma restricted: - assumes "finite A" "\a. a \ A \ P a" - shows "f(\ A) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\ B))" - using restricted_indexed [of A "\x. x"] assms by auto - -end - -subsection\Versions for unrestrictedly additive functions\ - -lemma Incl_Excl_UN: - fixes f :: "'a set \ 'b::ring_1" - assumes "\S T. disjnt S T \ f(S \ T) = f S + f T" "finite A" - shows "f(\(G ` A)) = (\B | B \ A \ B \ {}. (-1) ^ (card B + 1) * f (\ (G ` B)))" -proof - - interpret Incl_Excl "\x. True" f - by (simp add: Incl_Excl.intro assms(1)) - show ?thesis - using restricted_indexed assms by blast -qed - -lemma Incl_Excl_Union: - fixes f :: "'a set \ 'b::ring_1" - assumes "\S T. disjnt S T \ f(S \ T) = f S + f T" "finite A" - shows "f(\ A) = (\B | B \ A \ B \ {}. (- 1) ^ (card B + 1) * f (\ B))" - using Incl_Excl_UN[of f A "\X. X"] assms by simp - -text \The famous inclusion-exclusion formula for the cardinality of a union\ -lemma int_card_UNION: - assumes "finite A" "\K. K \ A \ finite K" - shows "int (card (\A)) = (\I | I \ A \ I \ {}. (- 1) ^ (card I + 1) * int (card (\I)))" -proof - - interpret Incl_Excl finite "int o card" - proof qed (auto simp add: card_Un_disjnt) - show ?thesis - using restricted assms by auto -qed - -text\A more conventional form\ -lemma inclusion_exclusion: - assumes "finite A" "\K. K \ A \ finite K" - shows "int(card(\ A)) = - (\n=1..card A. (-1) ^ (Suc n) * (\B | B \ A \ card B = n. int (card (\ B))))" (is "_=?R") -proof - - have fin: "finite {I. I \ A \ I \ {}}" - by (simp add: assms) - have "\k. \Suc 0 \ k; k \ card A\ \ \B\A. B \ {} \ k = card B" - by (metis (mono_tags, lifting) Suc_le_D Zero_neq_Suc card_eq_0_iff obtain_subset_with_card_n) - with \finite A\ finite_subset - have card_eq: "card ` {I. I \ A \ I \ {}} = {1..card A}" - using not_less_eq_eq card_mono by (fastforce simp: image_iff) - have "int(card(\ A)) - = (\y = 1..card A. \I\{x. x \ A \ x \ {} \ card x = y}. - ((- 1) ^ y * int (card (\ I))))" - by (simp add: int_card_UNION assms sum.image_gen [OF fin, where g=card] card_eq) - also have "... = ?R" - proof - - have "{B. B \ A \ B \ {} \ card B = k} = {B. B \ A \ card B = k}" - if "Suc 0 \ k" and "k \ card A" for k - using that by auto - then show ?thesis - by (clarsimp simp add: sum_negf simp flip: sum_distrib_left) - qed - finally show ?thesis . -qed - -lemma card_UNION: - assumes "finite A" and "\K. K \ A \ finite K" - shows "card (\A) = nat (\I | I \ A \ I \ {}. (- 1) ^ (card I + 1) * int (card (\I)))" - by (simp only: flip: int_card_UNION [OF assms]) - -lemma card_UNION_nonneg: - assumes "finite A" and "\K. K \ A \ finite K" - shows "(\I | I \ A \ I \ {}. (- 1) ^ (card I + 1) * int (card (\I))) \ 0" - using int_card_UNION [OF assms] by presburger - -subsection \a general "Moebius inversion" inclusion-exclusion principle. -This "symmetric" form is from Ira Gessel: "Symmetric Inclusion-Exclusion" \ - -lemma sum_Un_eq: - "\S \ T = {}; S \ T = U; finite U\ - \ (sum f S + sum f T = sum f U)" - by (metis finite_Un sum.union_disjoint) - -lemma card_adjust_lemma: "\inj_on f S; x = y + card (f ` S)\ \ x = y + card S" - by (simp add: card_image) - -lemma card_subsets_step: - assumes "finite S" "x \ S" "U \ S" - shows "card {T. T \ (insert x S) \ U \ T \ odd(card T)} - = card {T. T \ S \ U \ T \ odd(card T)} + card {T. T \ S \ U \ T \ even(card T)} \ - card {T. T \ (insert x S) \ U \ T \ even(card T)} - = card {T. T \ S \ U \ T \ even(card T)} + card {T. T \ S \ U \ T \ odd(card T)}" -proof - - have inj: "inj_on (insert x) {T. T \ S \ P T}" for P - using assms by (auto simp: inj_on_def) - have [simp]: "finite {T. T \ S \ P T}" "finite (insert x ` {T. T \ S \ P T})" for P - using \finite S\ by auto - have [simp]: "disjnt {T. T \ S \ P T} (insert x ` {T. T \ S \ Q T})" for P Q - using assms by (auto simp: disjnt_iff) - have eq: "{T. T \ S \ U \ T \ P T} \ insert x ` {T. T \ S \ U \ T \ Q T} - = {T. T \ insert x S \ U \ T \ P T}" (is "?L = ?R") - if "\A. A \ S \ Q (insert x A) \ P A" "\A. \ Q A \ P A" for P Q - proof - show "?L \ ?R" - by (clarsimp simp: image_iff subset_iff) (meson subsetI that) - show "?R \ ?L" - using \U \ S\ - by (clarsimp simp: image_iff) (smt (verit) insert_iff mk_disjoint_insert subset_iff that) - qed - have [simp]: "\A. A \ S \ even (card (insert x A)) \ odd (card A)" - by (metis \finite S\ \x \ S\ card_insert_disjoint even_Suc finite_subset subsetD) - show ?thesis - by (intro conjI card_adjust_lemma [OF inj]; simp add: eq flip: card_Un_disjnt) -qed - -lemma card_subsupersets_even_odd: - assumes "finite S" "U \ S" - shows "card {T. T \ S \ U \ T \ even(card T)} - = card {T. T \ S \ U \ T \ odd(card T)}" - using assms -proof (induction "card S" arbitrary: S rule: less_induct) - case (less S) - then obtain x where "x \ U" "x \ S" - by blast - then have U: "U \ S - {x}" - using less.prems(2) by blast - let ?V = "S - {x}" - show ?case - using card_subsets_step [of ?V x U] less.prems U - by (simp add: insert_absorb \x \ S\) -qed - -lemma sum_alternating_cancels: - assumes "finite S" "card {x. x \ S \ even(f x)} = card {x. x \ S \ odd(f x)}" - shows "(\x\S. (-1) ^ f x) = (0::'b::ring_1)" -proof - - have "(\x\S. (-1) ^ f x) - = (\x | x \ S \ even (f x). (-1) ^ f x) + (\x | x \ S \ odd (f x). (-1) ^ f x)" - by (rule sum_Un_eq [symmetric]; force simp: \finite S\) - also have "... = (0::'b::ring_1)" - by (simp add: minus_one_power_iff assms cong: conj_cong) - finally show ?thesis . -qed - -lemma inclusion_exclusion_symmetric: - fixes f :: "'a set \ 'b::ring_1" - assumes \
: "\S. finite S \ g S = (\T \ Pow S. (-1) ^ card T * f T)" - and "finite S" - shows "f S = (\T \ Pow S. (-1) ^ card T * g T)" -proof - - have "(-1) ^ card T * g T = (-1) ^ card T * (\U | U \ S \ U \ T. (-1) ^ card U * f U)" - if "T \ S" for T - proof - - have [simp]: "{U. U \ S \ U \ T} = Pow T" - using that by auto - show ?thesis - using that by (simp add: \finite S\ finite_subset \
) - qed - then have "(\T \ Pow S. (-1) ^ card T * g T) - = (\T\Pow S. (-1) ^ card T * (\U | U \ {U. U \ S} \ U \ T. (-1) ^ card U * f U))" - by simp - also have "... = (\U\Pow S. (\T | T \ S \ U \ T. (-1) ^ card T) * (-1) ^ card U * f U)" - unfolding sum_distrib_left - by (subst sum.swap_restrict; simp add: \finite S\ algebra_simps sum_distrib_right Pow_def) - also have "... = (\U\Pow S. if U=S then f S else 0)" - proof - - have [simp]: "{T. T \ S \ S \ T} = {S}" - by auto - show ?thesis - apply (rule sum.cong [OF refl]) - by (simp add: sum_alternating_cancels card_subsupersets_even_odd \finite S\ flip: power_add) - qed - also have "... = f S" - by (simp add: \finite S\) - finally show ?thesis - by presburger -qed - -text\ The more typical non-symmetric version. \ -lemma inclusion_exclusion_mobius: - fixes f :: "'a set \ 'b::ring_1" - assumes \
: "\S. finite S \ g S = sum f (Pow S)" and "finite S" - shows "f S = (\T \ Pow S. (-1) ^ (card S - card T) * g T)" (is "_ = ?rhs") -proof - - have "(- 1) ^ card S * f S = (\T\Pow S. (- 1) ^ card T * g T)" - by (rule inclusion_exclusion_symmetric; simp add: assms flip: power_add mult.assoc) - then have "((- 1) ^ card S * (- 1) ^ card S) * f S = ((- 1) ^ card S) * (\T\Pow S. (- 1) ^ card T * g T)" - by (simp add: mult_ac) - then have "f S = (\T\Pow S. (- 1) ^ (card S + card T) * g T)" - by (simp add: sum_distrib_left flip: power_add mult.assoc) - also have "... = ?rhs" - by (simp add: \finite S\ card_mono neg_one_power_add_eq_neg_one_power_diff) - finally show ?thesis . -qed - -end \ No newline at end of file diff --git a/thys/Euler_Polyhedron_Formula/Library_Extras.thy b/thys/Euler_Polyhedron_Formula/Library_Extras.thy deleted file mode 100644 --- a/thys/Euler_Polyhedron_Formula/Library_Extras.thy +++ /dev/null @@ -1,747 +0,0 @@ -section \Library Extras\ -text \For adding to the repository\ - -theory Library_Extras imports - "HOL-Analysis.Polytope" - -begin - -section \Conic sets and conic hull\ - -definition conic :: "'a::real_vector set \ bool" - where "conic S \ \x c. x \ S \ 0 \ c \ (c *\<^sub>R x) \ S" - -lemma conicD: "\conic S; x \ S; 0 \ c\ \ (c *\<^sub>R x) \ S" - by (meson conic_def) - -lemma subspace_imp_conic: "subspace S \ conic S" - by (simp add: conic_def subspace_def) - -lemma conic_empty [simp]: "conic {}" - using conic_def by blast - -lemma conic_UNIV: "conic UNIV" - by (simp add: conic_def) - -lemma conic_Inter: "(\S. S \ \ \ conic S) \ conic(\\)" - by (simp add: conic_def) - -lemma conic_linear_image: - "\conic S; linear f\ \ conic(f ` S)" - by (smt (verit) conic_def image_iff linear.scaleR) - -lemma conic_linear_image_eq: - "\linear f; inj f\ \ conic (f ` S) \ conic S" - by (smt (verit) conic_def conic_linear_image inj_image_mem_iff linear_cmul) - -lemma conic_mul: "\conic S; x \ S; 0 \ c\ \ (c *\<^sub>R x) \ S" - using conic_def by blast - -lemma conic_conic_hull: "conic(conic hull S)" - by (metis (no_types, lifting) conic_Inter hull_def mem_Collect_eq) - -lemma conic_hull_eq: "(conic hull S = S) \ conic S" - by (metis conic_conic_hull hull_same) - -lemma conic_hull_UNIV [simp]: "conic hull UNIV = UNIV" - by simp - -lemma conic_negations: "conic S \ conic (image uminus S)" - by (auto simp: conic_def image_iff) - -lemma conic_span [iff]: "conic(span S)" - by (simp add: subspace_imp_conic) - -lemma conic_hull_explicit: - "conic hull S = {c *\<^sub>R x| c x. 0 \ c \ x \ S}" -proof (rule hull_unique) - show "S \ {c *\<^sub>R x |c x. 0 \ c \ x \ S}" - by (metis (no_types) cone_hull_expl hull_subset) - show "conic {c *\<^sub>R x |c x. 0 \ c \ x \ S}" - using mult_nonneg_nonneg by (force simp: conic_def) -qed (auto simp: conic_def) - -lemma conic_hull_as_image: - "conic hull S = (\z. fst z *\<^sub>R snd z) ` ({0..} \ S)" - by (force simp: conic_hull_explicit) - -lemma conic_hull_linear_image: - "linear f \ conic hull f ` S = f ` (conic hull S)" - by (force simp: conic_hull_explicit image_iff set_eq_iff linear_scale) - -lemma conic_hull_image_scale: - assumes "\x. x \ S \ 0 < c x" - shows "conic hull (\x. c x *\<^sub>R x) ` S = conic hull S" -proof - show "conic hull (\x. c x *\<^sub>R x) ` S \ conic hull S" - proof (rule hull_minimal) - show "(\x. c x *\<^sub>R x) ` S \ conic hull S" - using assms conic_hull_explicit by fastforce - qed (simp add: conic_conic_hull) - show "conic hull S \ conic hull (\x. c x *\<^sub>R x) ` S" - proof (rule hull_minimal) - { fix x - assume "x \ S" - then have "x = inverse(c x) *\<^sub>R c x *\<^sub>R x" - using assms by fastforce - then have "x \ conic hull (\x. c x *\<^sub>R x) ` S" - by (smt (verit, best) \x \ S\ assms conic_conic_hull conic_mul hull_inc image_eqI inverse_nonpositive_iff_nonpositive) - } - then show "S \ conic hull (\x. c x *\<^sub>R x) ` S" by auto - qed (simp add: conic_conic_hull) -qed - -lemma convex_conic_hull: - assumes "convex S" - shows "convex (conic hull S)" -proof - - { fix c x d y and u :: real - assume \
: "(0::real) \ c" "x \ S" "(0::real) \ d" "y \ S" "0 \ u" "u \ 1" - have "\c'' x''. ((1 - u) * c) *\<^sub>R x + (u * d) *\<^sub>R y = c'' *\<^sub>R x'' \ 0 \ c'' \ x'' \ S" - proof (cases "(1 - u) * c = 0") - case True - with \0 \ d\ \y \ S\\0 \ u\ - show ?thesis by force - next - case False - define \ where "\ \ (1 - u) * c + u * d" - have *: "c * u \ c" - by (simp add: "\
" mult_left_le) - have "\ > 0" - using False \
by (smt (verit, best) \_def split_mult_pos_le) - then have **: "c + d * u = \ + c * u" - by (simp add: \_def mult.commute right_diff_distrib') - show ?thesis - proof (intro exI conjI) - show "0 \ \" - using \0 < \\ by auto - show "((1 - u) * c) *\<^sub>R x + (u * d) *\<^sub>R y = \ *\<^sub>R (((1 - u) * c / \) *\<^sub>R x + (u * d / \) *\<^sub>R y)" - using \\ > 0\ by (simp add: algebra_simps diff_divide_distrib) - show "((1 - u) * c / \) *\<^sub>R x + (u * d / \) *\<^sub>R y \ S" - using \0 < \\ - by (intro convexD [OF assms]) (auto simp: \
field_split_simps * **) - qed - qed - } - then show ?thesis - by (auto simp add: conic_hull_explicit convex_alt) -qed - -lemma conic_halfspace_le: "conic {x. a \ x \ 0}" - by (auto simp: conic_def mult_le_0_iff) - -lemma conic_halfspace_ge: "conic {x. a \ x \ 0}" - by (auto simp: conic_def mult_le_0_iff) - -lemma conic_hull_empty [simp]: "conic hull {} = {}" - by (simp add: conic_hull_eq) - -lemma conic_contains_0: "conic S \ (0 \ S \ S \ {})" - by (simp add: Convex.cone_def cone_contains_0 conic_def) - -lemma conic_hull_eq_empty: "conic hull S = {} \ (S = {})" - using conic_hull_explicit by fastforce - -lemma conic_sums: "\conic S; conic T\ \ conic (\x\ S. \y \ T. {x + y})" - by (simp add: conic_def) (metis scaleR_right_distrib) - -lemma conic_Times: "\conic S; conic T\ \ conic(S \ T)" - by (auto simp: conic_def) - -lemma conic_Times_eq: - "conic(S \ T) \ S = {} \ T = {} \ conic S \ conic T" (is "?lhs = ?rhs") -proof - show "?lhs \ ?rhs" - by (force simp: conic_def) - show "?rhs \ ?lhs" - by (force simp: conic_Times) -qed - -lemma conic_hull_0 [simp]: "conic hull {0} = {0}" - by (simp add: conic_hull_eq subspace_imp_conic) - -lemma conic_hull_contains_0 [simp]: "0 \ conic hull S \ (S \ {})" - by (simp add: conic_conic_hull conic_contains_0 conic_hull_eq_empty) - -lemma conic_hull_eq_sing: - "conic hull S = {x} \ S = {0} \ x = 0" -proof - show "conic hull S = {x} \ S = {0} \ x = 0" - by (metis conic_conic_hull conic_contains_0 conic_def conic_hull_eq hull_inc insert_not_empty singleton_iff) -qed simp - -lemma conic_hull_Int_affine_hull: - assumes "T \ S" "0 \ affine hull S" - shows "(conic hull T) \ (affine hull S) = T" -proof - - have TaffS: "T \ affine hull S" - using \T \ S\ hull_subset by fastforce - moreover - { fix c x - assume "c *\<^sub>R x \ affine hull S" - and "0 \ c" - and "x \ T" - have "c *\<^sub>R x \ T" - proof (cases "c=1") - case True - then show ?thesis - by (simp add: \x \ T\) - next - case False - then have "x /\<^sub>R (1 - c) = x + (c * inverse (1 - c)) *\<^sub>R x" - by (smt (verit, ccfv_SIG) diff_add_cancel mult.commute real_vector_affinity_eq scaleR_collapse scaleR_scaleR) - then have "0 = inverse(1 - c) *\<^sub>R c *\<^sub>R x + (1 - inverse(1 - c)) *\<^sub>R x" - by (simp add: algebra_simps) - then have "0 \ affine hull S" - by (smt (verit) \c *\<^sub>R x \ affine hull S\ \x \ T\ affine_affine_hull TaffS in_mono mem_affine) - then show ?thesis - using assms by auto - qed } - then have "conic hull T \ affine hull S \ T" - by (auto simp: conic_hull_explicit) - ultimately show ?thesis - by (auto simp: hull_inc) -qed - - -lemma open_in_subset_relative_interior: - fixes S :: "'a::euclidean_space set" - shows "openin (top_of_set (affine hull T)) S \ (S \ rel_interior T) = (S \ T)" - by (meson order.trans rel_interior_maximal rel_interior_subset) - - -lemma conic_hull_eq_span_affine_hull: - fixes S :: "'a::euclidean_space set" - assumes "0 \ rel_interior S" - shows "conic hull S = span S \ conic hull S = affine hull S" -proof - - obtain \ where "\>0" and \: "cball 0 \ \ affine hull S \ S" - using assms mem_rel_interior_cball by blast - have *: "affine hull S = span S" - by (meson affine_hull_span_0 assms hull_inc mem_rel_interior_cball) - moreover - have "conic hull S \ span S" - by (simp add: hull_minimal span_superset) - moreover - { fix x - assume "x \ affine hull S" - have "x \ conic hull S" - proof (cases "x=0") - case True - then show ?thesis - using \x \ affine hull S\ by auto - next - case False - then have "(\ / norm x) *\<^sub>R x \ cball 0 \ \ affine hull S" - using \0 < \\ \x \ affine hull S\ * span_mul by fastforce - then have "(\ / norm x) *\<^sub>R x \ S" - by (meson \ subsetD) - then have "\c xa. x = c *\<^sub>R xa \ 0 \ c \ xa \ S" - by (smt (verit, del_insts) \0 < \\ divide_nonneg_nonneg eq_vector_fraction_iff norm_eq_zero norm_ge_zero) - then show ?thesis - by (simp add: conic_hull_explicit) - qed - } - then have "affine hull S \ conic hull S" - by auto - ultimately show ?thesis - by blast -qed - -lemma conic_hull_eq_span: - fixes S :: "'a::euclidean_space set" - assumes "0 \ rel_interior S" - shows "conic hull S = span S" - by (simp add: assms conic_hull_eq_span_affine_hull) - -lemma conic_hull_eq_affine_hull: - fixes S :: "'a::euclidean_space set" - assumes "0 \ rel_interior S" - shows "conic hull S = affine hull S" - using assms conic_hull_eq_span_affine_hull by blast - -lemma conic_hull_eq_span_eq: - fixes S :: "'a::euclidean_space set" - shows "0 \ rel_interior(conic hull S) \ conic hull S = span S" (is "?lhs = ?rhs") -proof - show "?lhs \ ?rhs" - by (metis conic_hull_eq_span conic_span hull_hull hull_minimal hull_subset span_eq) - show "?rhs \ ?lhs" - by (metis rel_interior_affine subspace_affine subspace_span) -qed - -section\Closure of conic hulls\ - -proposition closedin_conic_hull: - fixes S :: "'a::euclidean_space set" - assumes "compact T" "0 \ T" "T \ S" - shows "closedin (top_of_set (conic hull S)) (conic hull T)" -proof - - have **: "compact ({0..} \ T \ (\z. fst z *\<^sub>R snd z) -` K)" (is "compact ?L") - if "K \ (\z. (fst z) *\<^sub>R snd z) ` ({0..} \ S)" "compact K" for K - proof - - obtain r where "r > 0" and r: "\x. x \ K \ norm x \ r" - by (metis \compact K\ bounded_normE compact_imp_bounded) - show ?thesis - unfolding compact_eq_bounded_closed - proof - have "bounded ({0..r / setdist{0}T} \ T)" - by (simp add: assms(1) bounded_Times compact_imp_bounded) - moreover - { fix a b - assume "a *\<^sub>R b \ K" and "b \ T" and "0 \ a" - have "setdist {0} T \ 0" - using \b \ T\ assms compact_imp_closed setdist_eq_0_closed by auto - then have T0: "setdist {0} T > 0" - using less_eq_real_def by fastforce - then have "a * setdist {0} T \ r" - by (smt (verit, ccfv_SIG) \0 \ a\ \a *\<^sub>R b \ K\ \b \ T\ dist_0_norm mult_mono' norm_scaleR r setdist_le_dist singletonI) - with T0 \r>0\ have "a \ r / setdist {0} T" - by (simp add: divide_simps) - } - then have "?L \ ({0..r / setdist{0}T} \ T)" by auto - ultimately show "bounded ?L" - by (meson bounded_subset) - show "closed ?L" - proof (rule continuous_closed_preimage) - show "continuous_on ({0..} \ T) (\z. fst z *\<^sub>R snd z)" - by (intro continuous_intros) - show "closed ({0::real..} \ T)" - by (simp add: assms(1) closed_Times compact_imp_closed) - show "closed K" - by (simp add: compact_imp_closed that(2)) - qed - qed - qed - show ?thesis - unfolding conic_hull_as_image - proof (rule proper_map) - show "compact ({0..} \ T \ (\z. fst z *\<^sub>R snd z) -` K)" (is "compact ?L") - if "K \ (\z. (fst z) *\<^sub>R snd z) ` ({0..} \ S)" "compact K" for K - proof - - obtain r where "r > 0" and r: "\x. x \ K \ norm x \ r" - by (metis \compact K\ bounded_normE compact_imp_bounded) - show ?thesis - unfolding compact_eq_bounded_closed - proof - have "bounded ({0..r / setdist{0}T} \ T)" - by (simp add: assms(1) bounded_Times compact_imp_bounded) - moreover - { fix a b - assume "a *\<^sub>R b \ K" and "b \ T" and "0 \ a" - have "setdist {0} T \ 0" - using \b \ T\ assms compact_imp_closed setdist_eq_0_closed by auto - then have T0: "setdist {0} T > 0" - using less_eq_real_def by fastforce - then have "a * setdist {0} T \ r" - by (smt (verit, ccfv_SIG) \0 \ a\ \a *\<^sub>R b \ K\ \b \ T\ dist_0_norm mult_mono' norm_scaleR r setdist_le_dist singletonI) - with T0 \r>0\ have "a \ r / setdist {0} T" - by (simp add: divide_simps) - } - then have "?L \ ({0..r / setdist{0}T} \ T)" by auto - ultimately show "bounded ?L" - by (meson bounded_subset) - show "closed ?L" - proof (rule continuous_closed_preimage) - show "continuous_on ({0..} \ T) (\z. fst z *\<^sub>R snd z)" - by (intro continuous_intros) - show "closed ({0::real..} \ T)" - by (simp add: assms(1) closed_Times compact_imp_closed) - show "closed K" - by (simp add: compact_imp_closed that(2)) - qed - qed - qed - show "(\z. fst z *\<^sub>R snd z) ` ({0::real..} \ T) \ (\z. fst z *\<^sub>R snd z) ` ({0..} \ S)" - using \T \ S\ by force - qed auto -qed - -lemma closed_conic_hull: - fixes S :: "'a::euclidean_space set" - assumes "0 \ rel_interior S \ compact S \ 0 \ S" - shows "closed(conic hull S)" - using assms -proof - assume "0 \ rel_interior S" - then show "closed (conic hull S)" - by (simp add: conic_hull_eq_span) -next - assume "compact S \ 0 \ S" - then have "closedin (top_of_set UNIV) (conic hull S)" - using closedin_conic_hull by force - then show "closed (conic hull S)" - by simp -qed - -lemma conic_closure: - fixes S :: "'a::euclidean_space set" - shows "conic S \ conic(closure S)" - by (meson Convex.cone_def cone_closure conic_def) - -lemma closure_conic_hull: - fixes S :: "'a::euclidean_space set" - assumes "0 \ rel_interior S \ bounded S \ ~(0 \ closure S)" - shows "closure(conic hull S) = conic hull (closure S)" - using assms -proof - assume "0 \ rel_interior S" - then show "closure (conic hull S) = conic hull closure S" - by (metis closed_affine_hull closure_closed closure_same_affine_hull closure_subset conic_hull_eq_affine_hull subsetD subset_rel_interior) -next - have "\x. x \ conic hull closure S \ x \ closure (conic hull S)" - by (metis (no_types, opaque_lifting) closure_mono conic_closure conic_conic_hull subset_eq subset_hull) - moreover - assume "bounded S \ 0 \ closure S" - then have "\x. x \ closure (conic hull S) \ x \ conic hull closure S" - by (metis closed_conic_hull closure_Un_frontier closure_closed closure_mono compact_closure hull_Un_subset le_sup_iff subsetD) - ultimately show "closure (conic hull S) = conic hull closure S" - by blast -qed - - -lemma faces_of_linear_image: - "\linear f; inj f\ \ {T. T face_of (f ` S)} = (image f) ` {T. T face_of S}" - by (smt (verit) Collect_cong face_of_def face_of_linear_image setcompr_eq_image subset_imageE) - -lemma face_of_conic: - assumes "conic S" "f face_of S" - shows "conic f" - unfolding conic_def -proof (intro strip) - fix x and c::real - assume "x \ f" and "0 \ c" - have f: "\a b x. \a \ S; b \ S; x \ f; x \ open_segment a b\ \ a \ f \ b \ f" - using \f face_of S\ face_ofD by blast - show "c *\<^sub>R x \ f" - proof (cases "x=0 \ c=1") - case True - then show ?thesis - using \x \ f\ by auto - next - case False - with \0 \ c\ obtain d e where de: "0 \ d" "0 \ e" "d < 1" "1 < e" "d < e" "(d = c \ e = c)" - apply (simp add: neq_iff) - by (metis gt_ex less_eq_real_def order_less_le_trans zero_less_one) - then obtain [simp]: "c *\<^sub>R x \ S" "e *\<^sub>R x \ S" \x \ S\ - using \x \ f\ assms conic_mul face_of_imp_subset by blast - have "x \ open_segment (d *\<^sub>R x) (e *\<^sub>R x)" if "c *\<^sub>R x \ f" - using de False that - apply (simp add: in_segment) - apply (rule exI [where x="(1 - d) / (e - d)"]) - apply (simp add: field_simps) - by (smt (verit, del_insts) add_divide_distrib divide_self scaleR_collapse) - then show ?thesis - using \conic S\ f [of "d *\<^sub>R x" "e *\<^sub>R x" x] de \x \ f\ - by (force simp: conic_def in_segment) - qed -qed - -lemma extreme_point_of_conic: - assumes "conic S" and x: "x extreme_point_of S" - shows "x = 0" -proof - - have "{x} face_of S" - by (simp add: face_of_singleton x) - then have "conic{x}" - using assms(1) face_of_conic by blast - then show ?thesis - by (force simp: conic_def) -qed - -section \Convex cones and corresponding hulls\ - -definition convex_cone :: "'a::real_vector set \ bool" - where "convex_cone \ \S. S \ {} \ convex S \ conic S" - -lemma convex_cone_iff: - "convex_cone S \ - 0 \ S \ (\x \ S. \y \ S. x + y \ S) \ (\x \ S. \c\0. c *\<^sub>R x \ S)" - by (metis cone_def conic_contains_0 conic_def convex_cone convex_cone_def) - -lemma convex_cone_add: "\convex_cone S; x \ S; y \ S\ \ x+y \ S" - by (simp add: convex_cone_iff) - -lemma convex_cone_scaleR: "\convex_cone S; 0 \ c; x \ S\ \ c *\<^sub>R x \ S" - by (simp add: convex_cone_iff) - -lemma convex_cone_nonempty: "convex_cone S \ S \ {}" - by (simp add: convex_cone_def) - -lemma convex_cone_linear_image: - "convex_cone S \ linear f \ convex_cone(f ` S)" - by (simp add: conic_linear_image convex_cone_def convex_linear_image) - -lemma convex_cone_linear_image_eq: - "\linear f; inj f\ \ (convex_cone(f ` S) \ convex_cone S)" - by (simp add: conic_linear_image_eq convex_cone_def) - -lemma convex_cone_halfspace_ge: "convex_cone {x. a \ x \ 0}" - by (simp add: convex_cone_iff inner_simps(2)) - -lemma convex_cone_halfspace_le: "convex_cone {x. a \ x \ 0}" - by (simp add: convex_cone_iff inner_right_distrib mult_nonneg_nonpos) - -lemma convex_cone_contains_0: "convex_cone S \ 0 \ S" - using convex_cone_iff by blast - -lemma convex_cone_Inter: - "(\S. S \ f \ convex_cone S) \ convex_cone(\ f)" - by (simp add: convex_cone_iff) - -lemma convex_cone_convex_cone_hull: "convex_cone(convex_cone hull S)" - by (metis (no_types, lifting) convex_cone_Inter hull_def mem_Collect_eq) - -lemma convex_convex_cone_hull: "convex(convex_cone hull S)" - by (meson convex_cone_convex_cone_hull convex_cone_def) - -lemma conic_convex_cone_hull: "conic(convex_cone hull S)" - by (metis convex_cone_convex_cone_hull convex_cone_def) - -lemma convex_cone_hull_nonempty: "convex_cone hull S \ {}" - by (simp add: convex_cone_convex_cone_hull convex_cone_nonempty) - -lemma convex_cone_hull_contains_0: "0 \ convex_cone hull S" - by (simp add: convex_cone_contains_0 convex_cone_convex_cone_hull) - -lemma convex_cone_hull_add: - "\x \ convex_cone hull S; y \ convex_cone hull S\ \ x + y \ convex_cone hull S" - by (simp add: convex_cone_add convex_cone_convex_cone_hull) - -lemma convex_cone_hull_mul: - "\x \ convex_cone hull S; 0 \ c\ \ (c *\<^sub>R x) \ convex_cone hull S" - by (simp add: conic_convex_cone_hull conic_mul) - -lemma convex_cone_sums: - "\convex_cone S; convex_cone T\ \ convex_cone (\x\ S. \y \ T. {x + y})" - by (simp add: convex_cone_def conic_sums convex_sums) - -lemma convex_cone_Times: - "\convex_cone S; convex_cone T\ \ convex_cone(S \ T)" - by (simp add: conic_Times convex_Times convex_cone_def) - -lemma convex_cone_Times_D1: "convex_cone (S \ T) \ convex_cone S" - by (metis Times_empty conic_Times_eq convex_cone_def convex_convex_hull convex_hull_Times hull_same times_eq_iff) - -lemma convex_cone_Times_eq: - "convex_cone(S \ T) \ convex_cone S \ convex_cone T" -proof (cases "S={} \ T={}") - case True - then show ?thesis - by (auto dest: convex_cone_nonempty) -next - case False - then have "convex_cone (S \ T) \ convex_cone T" - by (metis conic_Times_eq convex_cone_def convex_convex_hull convex_hull_Times hull_same times_eq_iff) - then show ?thesis - using convex_cone_Times convex_cone_Times_D1 by blast -qed - - -lemma convex_cone_hull_Un: - "convex_cone hull(S \ T) = (\x \ convex_cone hull S. \y \ convex_cone hull T. {x + y})" - (is "?lhs = ?rhs") -proof - show "?lhs \ ?rhs" - proof (rule hull_minimal) - show "S \ T \ (\x\convex_cone hull S. \y\convex_cone hull T. {x + y})" - apply (clarsimp simp: subset_iff) - by (metis add_0 convex_cone_hull_contains_0 group_cancel.rule0 hull_inc) - show "convex_cone (\x\convex_cone hull S. \y\convex_cone hull T. {x + y})" - by (simp add: convex_cone_convex_cone_hull convex_cone_sums) - qed -next - show "?rhs \ ?lhs" - by clarify (metis convex_cone_hull_add hull_mono le_sup_iff subsetD subsetI) -qed - -lemma convex_cone_singleton [iff]: "convex_cone {0}" - by (simp add: convex_cone_iff) - -lemma convex_hull_subset_convex_cone_hull: - "convex hull S \ convex_cone hull S" - by (simp add: convex_convex_cone_hull hull_minimal hull_subset) - - -lemma conic_hull_subset_convex_cone_hull: - "conic hull S \ convex_cone hull S" - by (simp add: conic_convex_cone_hull hull_minimal hull_subset) - -lemma subspace_imp_convex_cone: "subspace S \ convex_cone S" - by (simp add: convex_cone_iff subspace_def) - -lemma convex_cone_span: "convex_cone(span S)" - by (simp add: subspace_imp_convex_cone) - -lemma convex_cone_negations: - "convex_cone S \ convex_cone (image uminus S)" - by (simp add: convex_cone_linear_image module_hom_uminus) - -lemma subspace_convex_cone_symmetric: - "subspace S \ convex_cone S \ (\x \ S. -x \ S)" - by (smt (verit) convex_cone_iff scaleR_left.minus subspace_def subspace_neg) - - - -lemma convex_cone_hull_separate_nonempty: - assumes "S \ {}" - shows "convex_cone hull S = conic hull (convex hull S)" (is "?lhs = ?rhs") -proof - show "?lhs \ ?rhs" - by (simp add: assms conic_conic_hull conic_hull_eq_empty convex_cone_def convex_conic_hull hull_inc hull_minimal subsetI) - show "?rhs \ ?lhs" - by (simp add: conic_convex_cone_hull convex_hull_subset_convex_cone_hull subset_hull) -qed - -lemma convex_cone_hull_empty [simp]: "convex_cone hull {} = {0}" - by (metis convex_cone_hull_contains_0 convex_cone_singleton hull_redundant hull_same) - -lemma convex_cone_hull_separate: - "convex_cone hull S = insert 0 (conic hull (convex hull S))" - by (cases "S={}") (simp_all add: convex_cone_hull_separate_nonempty insert_absorb) - -lemma convex_cone_hull_convex_hull_nonempty: - "S \ {} \ convex_cone hull S = (\x \ convex hull S. \c\{0..}. {c *\<^sub>R x})" - by (force simp: convex_cone_hull_separate_nonempty conic_hull_as_image) - - -lemma convex_cone_hull_convex_hull: - "convex_cone hull S = insert 0 (\x \ convex hull S. \c\{0..}. {c *\<^sub>R x})" - by (force simp: convex_cone_hull_separate conic_hull_as_image) - -lemma convex_cone_hull_linear_image: - "linear f \ convex_cone hull (f ` S) = image f (convex_cone hull S)" - by (metis (no_types, lifting) conic_hull_linear_image convex_cone_hull_separate convex_hull_linear_image image_insert linear_0) - -subsection \Finitely generated cone is polyhedral, and hence closed\ - -proposition polyhedron_convex_cone_hull: - fixes S :: "'a::euclidean_space set" - assumes "finite S" - shows "polyhedron(convex_cone hull S)" -proof (cases "S = {}") - case True - then show ?thesis - by (simp add: affine_imp_polyhedron) -next - case False - then have "polyhedron(convex hull (insert 0 S))" - by (simp add: assms polyhedron_convex_hull) - then obtain F a b where "finite F" - and F: "convex hull (insert 0 S) = \ F" - and ab: "\h. h \ F \ a h \ 0 \ h = {x. a h \ x \ b h}" - unfolding polyhedron_def by metis - then have "F \ {}" - by (metis bounded_convex_hull finite_imp_bounded Inf_empty assms finite_insert not_bounded_UNIV) - show ?thesis - unfolding polyhedron_def - proof (intro exI conjI) - show "convex_cone hull S = \ {h \ F. b h = 0}" (is "?lhs = ?rhs") - proof - show "?lhs \ ?rhs" - proof (rule hull_minimal) - show "S \ \ {h \ F. b h = 0}" - by (smt (verit, best) F InterE InterI hull_subset insert_subset mem_Collect_eq subset_eq) - have "\S. \S \ F; b S = 0\ \ convex_cone S" - by (metis ab convex_cone_halfspace_le) - then show "convex_cone (\ {h \ F. b h = 0})" - by (force intro: convex_cone_Inter) - qed - have "x \ convex_cone hull S" - if x: "\h. \h \ F; b h = 0\ \ x \ h" for x - proof - - have "\t. 0 < t \ (t *\<^sub>R x) \ h" if "h \ F" for h - proof (cases "b h = 0") - case True - then show ?thesis - by (metis x linordered_field_no_ub mult_1 scaleR_one that zero_less_mult_iff) - next - case False - then have "b h > 0" - by (smt (verit, del_insts) F InterE ab hull_subset inner_zero_right insert_subset mem_Collect_eq that) - then have "0 \ interior {x. a h \ x \ b h}" - by (simp add: ab that) - then have "0 \ interior h" - using ab that by auto - then obtain \ where "0 < \" and \: "ball 0 \ \ h" - using mem_interior by blast - show ?thesis - proof (cases "x=0") - case True - then show ?thesis - using \ \0 < \\ by auto - next - case False - with \ \0 < \\ show ?thesis - by (intro exI [where x="\ / (2 * norm x)"]) (auto simp: divide_simps) - qed - qed - then obtain t where t: "\h. h \ F \ 0 < t h \ (t h *\<^sub>R x) \ h" - by metis - then have "Inf (t ` F) *\<^sub>R x /\<^sub>R Inf (t ` F) = x" - by (smt (verit) \F \ {}\ \finite F\ field_simps(58) finite_imageI finite_less_Inf_iff image_iff image_is_empty) - moreover have "Inf (t ` F) *\<^sub>R x /\<^sub>R Inf (t ` F) \ convex_cone hull S" - proof (rule conicD [OF conic_convex_cone_hull]) - have "Inf (t ` F) *\<^sub>R x \ \ F" - proof clarify - fix h - assume "h \ F" - have eq: "Inf (t ` F) *\<^sub>R x = (1 - Inf(t ` F) / t h) *\<^sub>R 0 + (Inf(t ` F) / t h) *\<^sub>R t h *\<^sub>R x" - using \h \ F\ t by force - show "Inf (t ` F) *\<^sub>R x \ h" - unfolding eq - proof (rule convexD_alt) - have "h = {x. a h \ x \ b h}" - by (simp add: \h \ F\ ab) - then show "convex h" - by (metis convex_halfspace_le) - show "0 \ h" - by (metis F InterE \h \ F\ hull_subset insertCI subsetD) - show "t h *\<^sub>R x \ h" - by (simp add: \h \ F\ t) - show "0 \ Inf (t ` F) / t h" - by (metis \F \ {}\ \h \ F\ cINF_greatest divide_nonneg_pos less_eq_real_def t) - show "Inf (t ` F) / t h \ 1" - by (simp add: \finite F\ \h \ F\ cInf_le_finite t) - qed - qed - moreover have "convex hull (insert 0 S) \ convex_cone hull S" - by (simp add: convex_cone_hull_contains_0 convex_convex_cone_hull hull_minimal hull_subset) - ultimately show "Inf (t ` F) *\<^sub>R x \ convex_cone hull S" - using F by blast - show "0 \ inverse (Inf (t ` F))" - using t by (simp add: \F \ {}\ \finite F\ finite_less_Inf_iff less_eq_real_def) - qed - ultimately show ?thesis - by auto - qed - then show "?rhs \ ?lhs" - by auto - qed - show "\h\{h \ F. b h = 0}. \a b. a \ 0 \ h = {x. a \ x \ b}" - using ab by blast - qed (auto simp: \finite F\) -qed - - -lemma closed_convex_cone_hull: - fixes S :: "'a::euclidean_space set" - shows "finite S \ closed(convex_cone hull S)" - by (simp add: polyhedron_convex_cone_hull polyhedron_imp_closed) - -lemma polyhedron_convex_cone_hull_polytope: - fixes S :: "'a::euclidean_space set" - shows "polytope S \ polyhedron(convex_cone hull S)" - by (metis convex_cone_hull_separate hull_hull polyhedron_convex_cone_hull polytope_def) - -lemma polyhedron_conic_hull_polytope: - fixes S :: "'a::euclidean_space set" - shows "polytope S \ polyhedron(conic hull S)" - by (metis conic_hull_eq_empty convex_cone_hull_separate_nonempty hull_hull polyhedron_convex_cone_hull_polytope polyhedron_empty polytope_def) - -lemma closed_conic_hull_strong: - fixes S :: "'a::euclidean_space set" - shows "0 \ rel_interior S \ polytope S \ compact S \ ~(0 \ S) \ closed(conic hull S)" - using closed_conic_hull polyhedron_conic_hull_polytope polyhedron_imp_closed by blast - -end \ No newline at end of file