diff --git a/thys/Lower_Semicontinuous/Lower_Semicontinuous.thy b/thys/Lower_Semicontinuous/Lower_Semicontinuous.thy --- a/thys/Lower_Semicontinuous/Lower_Semicontinuous.thy +++ b/thys/Lower_Semicontinuous/Lower_Semicontinuous.thy @@ -1,1859 +1,1859 @@ (* Title: thys/Lower_Semicontinuous/Lower_Semicontinuous.thy Author: Bogdan Grechuk, University of Edinburgh *) section \Lower semicontinuous functions\ theory Lower_Semicontinuous imports "HOL-Analysis.Multivariate_Analysis" begin subsection\Relative interior in one dimension\ lemma rel_interior_ereal_semiline: fixes a :: ereal shows "rel_interior {y. a \ ereal y} = {y. a < ereal y}" proof (cases a) case (real r) then show ?thesis using rel_interior_real_semiline[of r] by (simp add: atLeast_def greaterThan_def) next case PInf thus ?thesis using rel_interior_empty by auto next case MInf thus ?thesis using rel_interior_UNIV by auto qed lemma closed_ereal_semiline: fixes a :: ereal shows "closed {y. a \ ereal y}" proof (cases a) case (real r) then show ?thesis using closed_real_atLeast unfolding atLeast_def by simp qed auto lemma ereal_semiline_unique: fixes a b :: ereal shows "{y. a \ ereal y} = {y. b \ ereal y} \ a = b" by (metis mem_Collect_eq ereal_le_real order_antisym) subsection \Lower and upper semicontinuity\ definition lsc_at :: "'a \ ('a::topological_space \ 'b::order_topology) \ bool" where "lsc_at x0 f \ (\X l. X \ x0 \ (f \ X) \ l \ f x0 \ l)" definition usc_at :: "'a \ ('a::topological_space \ 'b::order_topology) \ bool" where "usc_at x0 f \ (\X l. X \ x0 \ (f \ X) \ l \ l \ f x0)" lemma lsc_at_mem: assumes "lsc_at x0 f" assumes "x \ x0" assumes "(f \ x) \ A" shows "f x0 \ A" using assms lsc_at_def[of x0 f] by blast lemma usc_at_mem: assumes "usc_at x0 f" assumes "x \ x0" assumes "(f \ x) \ A" shows "f x0 \ A" using assms usc_at_def[of x0 f] by blast lemma lsc_at_open: fixes f :: "'a::first_countable_topology \ 'b::{complete_linorder, linorder_topology}" shows "lsc_at x0 f \ (\S. open S \ f x0 \ S \ (\T. open T \ x0 \ T \ (\x'\T. f x' \ f x0 \ f x' \ S)))" (is "?lhs \ ?rhs") proof- { assume "~?rhs" from this obtain S where S_def: "open S \ f x0 : S \ (\T. (open T \ x0 \ T) \ (\x'\T. f x' \ f x0 \ f x' \ S))" by metis define X where "X = {x'. f x' \ f x0 \ f x' \ S}" hence "x0 islimpt X" unfolding islimpt_def using S_def by auto from this obtain x where x_def: "(\n. x n \ X) \ x \ x0" using islimpt_sequential[of x0 X] by auto hence not: "~(f \ x) \ (f x0)" unfolding lim_explicit using X_def S_def by auto from compact_complete_linorder[of "f \ x"] obtain l r where r_def: "strict_mono r \ ((f \ x) \ r) \ l" by auto { assume "l : S" hence "\N. \n\N. f(x(r n)) \ S" using r_def lim_explicit[of "f \ x \ r" l] S_def by auto hence False using x_def X_def by auto } hence l_prop: "l \ S \ l\f x0" using r_def x_def X_def Lim_bounded[of "f \ x \ r"] by auto { assume "f x0 \ l" hence "f x0 = l" using l_prop by auto hence False using l_prop S_def by auto } hence "\x l. x \ x0 \ (f \ x) \ l \ ~(f x0 \ l)" apply(rule_tac x="x \ r" in exI) apply(rule_tac x=l in exI) using r_def x_def by (auto simp add: o_assoc LIMSEQ_subseq_LIMSEQ) hence "~?lhs" unfolding lsc_at_def by blast } moreover { assume "?rhs" { fix x A assume x_def: "x \ x0" "(f \ x) \ A" { assume "A \ f x0" from this obtain S V where SV_def: "open S \ open V \ f x0 : S \ A : V \ S Int V = {}" using hausdorff[of "f x0" A] by auto from this obtain T where T_def: "open T \ x0 : T \ (\x'\T. (f x' \ f x0 \ f x' \ S))" using \?rhs\ by metis from this obtain N1 where "\n\N1. x n \ T" using x_def lim_explicit[of x x0] by auto hence *: "\n\N1. (f (x n) \ f x0 \ f(x n) \ S)" using T_def by auto from SV_def obtain N2 where "\n\N2. f(x n) \ V" using lim_explicit[of "f \ x" A] x_def by auto hence "\n\(max N1 N2). \(f(x n) \ f x0)" using SV_def * by auto hence "\n\(max N1 N2). f(x n) \ f x0" by auto hence "f x0 \ A" using Lim_bounded2[of "f \ x" A "max N1 N2" "f x0"] x_def by auto } hence "f x0 \ A" by auto } hence "?lhs" unfolding lsc_at_def by blast } ultimately show ?thesis by blast qed lemma lsc_at_open_mem: fixes f :: "'a::first_countable_topology \ 'b::{complete_linorder, linorder_topology}" assumes "lsc_at x0 f" assumes "open S \ f x0 : S" obtains T where "open T \ x0 \ T \ (\x'\T. (f x' \ f x0 \ f x' \ S))" using assms lsc_at_open[of x0 f] by blast lemma lsc_at_MInfty: fixes f :: "'a::topological_space \ ereal" assumes "f x0 = -\" shows "lsc_at x0 f" unfolding lsc_at_def using assms by auto lemma lsc_at_PInfty: fixes f :: "'a::metric_space \ ereal" assumes "f x0 = \" shows "lsc_at x0 f \ continuous (at x0) f" unfolding lsc_at_open continuous_at_open using assms by auto lemma lsc_at_real: fixes f :: "'a::metric_space \ ereal" assumes "\f x0\ \ \" shows "lsc_at x0 f \ (\e. e>0 \ (\T. open T \ x0 : T \ (\y \ T. f y > f x0 - e)))" (is "?lhs \ ?rhs") proof- obtain m where m_def: "f x0 = ereal m" using assms by (cases "f x0") auto { assume lsc: "lsc_at x0 f" { fix e assume e_def: "(e :: ereal)>0" hence *: "f x0 : {f x0 - e <..< f x0 + e}" using assms ereal_between by auto from this obtain T where T_def: "open T \ x0 : T \ (\x'\T. f x' \ f x0 \ f x' \ {f x0 - e <..< f x0 + e})" apply (subst lsc_at_open_mem[of x0 f "{f x0 - e <..< f x0 + e}"]) using lsc e_def by auto { fix y assume "y:T" { assume "f y \ f x0" hence "f y > f x0 - e" using T_def \y:T\ by auto } moreover { assume "f y > f x0" hence "\>f x0 - e" using * by auto } ultimately have "f y > f x0 - e" using not_le by blast } hence "\T. open T \ x0 \ T \ (\y \ T. f y > f x0 - e)" using T_def by auto } hence "?rhs" by auto } moreover { assume "?rhs" { fix S assume S_def: "open S \ f x0 : S" from this obtain e where e_def: "e>0 \ {f x0 - e<.. S" apply (subst ereal_open_cont_interval[of S "f x0"]) using assms by auto from this obtain T where T_def: "open T \ x0 : T \ (\y \ T. f y > f x0 - e)" using \?rhs\[rule_format, of e] by auto { fix y assume "y:T" "f y \ f x0" hence "f y < f x0 + e" using assms e_def ereal_between[of "f x0" e] by auto hence "f y \ S" using e_def T_def \y\T\ by auto } hence "\T. open T \ x0 : T \ (\y\T. (f y \ f x0 \ f y \ S))" using T_def by auto } hence "lsc_at x0 f" using lsc_at_open by auto } ultimately show ?thesis by auto qed lemma lsc_at_ereal: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (\CT. open T \ x0 \ T \ (\y \ T. f y > C))" (is "?lhs \ ?rhs") proof- { assume "f x0 = -\" hence ?thesis using lsc_at_MInfty by auto } moreover { assume pinf: "f x0 = \" { assume lsc: "lsc_at x0 f" { fix C assume "C f x0 : {C<..}" by auto from this obtain T where T_def: "open T \ x0 \ T \ (\y\T. f y \ {C<..})" using pinf lsc lsc_at_PInfty[of f x0] unfolding continuous_at_open by metis hence "\T. open T \ x0 \ T \ (\y\T. C < f y)" by auto } hence "?rhs" by auto } moreover { assume "?rhs" { fix S assume S_def: "open S \ f x0 : S" then obtain C where C_def: "ereal C < f x0 \ {ereal C<..} \ S" using pinf open_PInfty by auto then obtain T where T_def: "open T \ x0 : T \ (\y \ T. f y \ S)" using \?rhs\[rule_format, of "ereal C"] by auto hence "\T. open T \ x0 \ T \ (\y\T. (f y \ f x0 \ f y \ S))" using T_def by auto } hence "lsc_at x0 f" using lsc_at_open by auto } ultimately have ?thesis by blast } moreover { assume fin: "f x0 \ -\" "f x0 \ \" { assume lsc: "lsc_at x0 f" { fix C assume "C0" using fin ereal_less_minus_iff by auto from this obtain T where T_def: "open T \ x0 \ T \ (\y\T. f x0 - (f x0-C) < f y)" using lsc_at_real[of f x0] lsc fin by auto moreover have "f x0 - (f x0-C) = C" using fin apply (cases "f x0", cases C) by auto ultimately have "\T. open T \ x0 \ T \ (\y\T. C < f y)" by auto } hence "?rhs" by auto } moreover { assume "?rhs" { fix e :: ereal assume "e>0" hence "f x0 - e < f x0" using fin apply (cases "f x0", cases e) by auto hence "\T. open T \ x0 \ T \ (\y\T. f x0 - e < f y)" using fin \?rhs\ by auto } hence "lsc_at x0 f" using lsc_at_real[of f x0] fin by auto } ultimately have ?thesis by blast } ultimately show ?thesis by blast qed lemma lst_at_ball: fixes f :: "'a::metric_space => ereal" shows "lsc_at x0 f \ (\Cd>0. \y \ (ball x0 d). C ?rhs") proof- { assume lsc: "lsc_at x0 f" { fix C :: ereal assume "C x0 : T \ (\y \ T. C < f y)" using lsc lsc_at_ereal[of x0 f] by auto hence "\d. d>0 \ (\y \ (ball x0 d). C < f y)" by (force simp add: open_contains_ball) } } moreover { assume "?rhs" { fix C :: ereal assume "C0 \ (\y \ (ball x0 d). C < f y)" using \?rhs\ by auto hence "\T. open T \ x0 \ T \ (\y \ T. C < f y)" apply (rule_tac x="ball x0 d" in exI) apply (simp add: centre_in_ball) done } hence "lsc_at x0 f" using lsc_at_ereal[of x0 f] by auto } ultimately show ?thesis by auto qed lemma lst_at_delta: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (\Cd>0. \y. dist x0 y < d \ C < f y)" (is "?lhs \ ?rhs") proof- have "?rhs \ (\Cd>0. \y \ (ball x0 d). C < f y)" unfolding ball_def by auto thus ?thesis using lst_at_ball[of x0 f] by auto qed lemma lsc_liminf_at: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ f x0 \ Liminf (at x0) f" unfolding lst_at_ball le_Liminf_iff eventually_at by (intro arg_cong[where f=All] imp_cong refl ext ex_cong) (auto simp: dist_commute zero_less_dist_iff) lemma lsc_liminf_at_eq: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (f x0 = min (f x0) (Liminf (at x0) f))" by (metis inf_ereal_def le_iff_inf lsc_liminf_at) lemma lsc_imp_liminf: fixes f :: "'a::metric_space \ ereal" assumes "lsc_at x0 f" assumes "x \ x0" shows "f x0 \ liminf (f \ x)" proof (cases "f x0") case PInf then show ?thesis using assms lsc_at_PInfty[of f x0] lim_imp_Liminf[of _ "f \ x"] continuous_at_sequentially[of x0 f] by auto next case (real r) { fix e assume e_def: "(e :: ereal)>0" from this obtain T where T_def: "open T \ x0 : T \ (\y \ T. f y > f x0 - e)" using lsc_at_real[of f x0] real assms by auto from this obtain N where N_def: "\n\N. x n \ T" apply (subst tendsto_obtains_N[of x x0 T]) using assms by auto hence "\n\N. f x0 - e < (f \ x) n" using T_def by auto hence "liminf (f \ x) \ f x0 - e" by (intro Liminf_bounded) (auto simp: eventually_sequentially intro!: exI[of _ N]) hence "f x0 \ liminf (f \ x) + e" apply (cases e) unfolding ereal_minus_le_iff by auto } then show ?thesis by (intro ereal_le_epsilon) auto qed auto lemma lsc_liminf: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (\x. x \ x0 \ f x0 \ liminf (f \ x))" (is "?lhs \ ?rhs") proof- { assume "?rhs" { fix x A assume x_def: "x \ x0" "(f \ x) \ A" hence "f x0 \ A" using \?rhs\ lim_imp_Liminf[of sequentially] by auto } hence "?lhs" unfolding lsc_at_def by blast } from this show ?thesis using lsc_imp_liminf by auto qed lemma lsc_sequentially: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (\x c. x \ x0 \ (\n. f(x n)\c) \ f(x0)\c)" (is "?lhs \ ?rhs") proof- { assume "?rhs" { fix x l assume "x \ x0" "(f \ x) \ l" { assume "l = \" hence "f x0 \ l" by auto } moreover { assume "l = -\" { fix B :: real obtain N where N_def: "\n\N. f(x n) \ ereal B" using Lim_MInfty[of "f \ x"] \(f \ x) \ l\ \l = -\\ by auto define g where "g n = (if n\N then x n else x N)" for n hence "g \ x0" by (intro filterlim_cong[THEN iffD1, OF refl refl _ \x \ x0\]) (auto simp: eventually_sequentially) moreover have "\n. f(g n) \ ereal B" using g_def N_def by auto ultimately have "f x0 \ ereal B" using \?rhs\ by auto } hence "f x0 = -\" using ereal_bot by auto hence "f x0 \ l" by auto } moreover { assume fin: "\l\ \ \" { fix e assume e_def: "(e :: ereal)>0" from this obtain N where N_def: "\n\N. f(x n) \ {l - e <..< l + e}" apply (subst tendsto_obtains_N[of "f \ x" l "{l - e <..< l + e}"]) using fin e_def ereal_between \(f \ x) \ l\ by auto define g where "g n = (if n\N then x n else x N)" for n hence "g \ x0" by (intro filterlim_cong[THEN iffD1, OF refl refl _ \x \ x0\]) (auto simp: eventually_sequentially) moreover have "\n. f(g n) \ l + e" using g_def N_def by auto ultimately have "f x0 \ l + e" using \?rhs\ by auto } hence "f x0 \ l" using ereal_le_epsilon by auto } ultimately have "f x0 \ l" by blast } hence "lsc_at x0 f" unfolding lsc_at_def by auto } moreover { assume lsc: "lsc_at x0 f" { fix x c assume xc_def: "x \ x0 \ (\n. f(x n)\c)" hence "liminf (f \ x) \ c" using Limsup_bounded[where F = sequentially and X = "f \ x" and C = c] Liminf_le_Limsup[of sequentially "f \ x"] by auto hence "f x0 \ c" using lsc xc_def lsc_imp_liminf[of x0 f x] by auto } hence "?rhs" by auto } ultimately show ?thesis by blast qed lemma lsc_sequentially_gen: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 f \ (\x c c0. x \ x0 \ c \ c0 \ (\n. f(x n)\c n) \ f(x0)\c0)" (is "?lhs \ ?rhs") proof- { assume "?rhs" { fix x c0 assume a: "x \ x0 \ (\n. f (x n) \ c0)" define c where "c = (\n::nat. c0)" hence "c \ c0" by auto hence "f(x0)\c0" using \?rhs\[rule_format, of x c c0] using a c_def by auto } hence "?lhs" using lsc_sequentially[of x0 f] by auto } moreover { assume lsc: "lsc_at x0 f" { fix x c c0 assume xc_def: "x \ x0 \ c \ c0 \ (\n. f(x n)\c n)" hence "liminf (f \ x) \ c0" using Liminf_mono[of "f \ x" c sequentially] lim_imp_Liminf[of sequentially] by auto hence "f x0 \ c0" using lsc xc_def lsc_imp_liminf[of x0 f x] by auto } hence "?rhs" by auto } ultimately show ?thesis by blast qed lemma lsc_sequentially_mem: fixes f :: "'a::metric_space \ ereal" assumes "lsc_at x0 f" assumes "x \ x0" "c \ c0" assumes "\n. f(x n)\c n" shows "f(x0)\c0" using lsc_sequentially_gen[of x0 f] assms by auto lemma lsc_uminus: fixes f :: "'a::metric_space \ ereal" shows "lsc_at x0 (\x. -f x) \ usc_at x0 f" proof- { assume lsc: "lsc_at x0 (\x. -f x)" { fix x A assume x_def: "x \ x0" "(f \ x) \ A" hence "(\i. - f (x i)) \ -A" using tendsto_uminus_ereal[of "f \ x" A] by auto hence "((\x. - f x) \ x) \ -A" unfolding o_def by auto hence " - f x0 \ - A" apply (subst lsc_at_mem[of x0 "(\x. -f x)" x]) using lsc x_def by auto hence "f x0 \ A" by auto } hence "usc_at x0 f" unfolding usc_at_def by auto } moreover { assume usc: "usc_at x0 f" { fix x A assume x_def: "x \ x0" "((\x. - f x) \ x) \ A" hence "(\i. - f (x i)) \ A" unfolding o_def by auto hence "(\i. f (x i)) \ - A" using tendsto_uminus_ereal[of "(\i. - f (x i))" A] by auto hence "(f \ x) \ -A" unfolding o_def by auto hence "f x0 \ - A" apply (subst usc_at_mem[of x0 "f" x]) using usc x_def by auto hence "-f x0 \ A" by (auto simp: ereal_uminus_le_reorder) } hence "lsc_at x0 (\x. -f x)" unfolding lsc_at_def by auto } ultimately show ?thesis by blast qed lemma usc_limsup: fixes f :: "'a::metric_space \ ereal" shows "usc_at x0 f \ (\x. x \ x0 \ f x0 \ limsup (f \ x))" (is "?lhs \ ?rhs") proof- have "usc_at x0 f \ (\x. x \ x0 \ - f x0 \ liminf ((\x. - f x) \ x))" using lsc_uminus[of x0 f] lsc_liminf[of x0 "(\x. - f x)"] by auto moreover { fix x assume "x \ x0" have "(-f x0 \ -limsup (f \ x)) \ (-f x0 \ liminf ((\x. - f x) \ x))" using ereal_Liminf_uminus[of _ "f \ x"] unfolding o_def by auto hence "(f x0 \ limsup (f \ x)) \ (-f x0 \ liminf ((\x. - f x) \ x))" by auto } ultimately show ?thesis by auto qed lemma usc_imp_limsup: fixes f :: "'a::metric_space \ ereal" assumes "usc_at x0 f" assumes "x \ x0" shows "f x0 \ limsup (f \ x)" using assms usc_limsup[of x0 f] by auto lemma usc_limsup_at: fixes f :: "'a::metric_space \ ereal" shows "usc_at x0 f \ f x0 \ Limsup (at x0) f" proof- have "usc_at x0 f \ lsc_at x0 (\x. -(f x))" by (metis lsc_uminus) also have "\ \ -(f x0) \ Liminf (at x0) (\x. -(f x))" by (metis lsc_liminf_at) also have "\ \ -(f x0) \ -(Limsup (at x0) f)" by (metis ereal_Liminf_uminus) finally show ?thesis by auto qed lemma continuous_iff_lsc_usc: fixes f :: "'a::metric_space \ ereal" shows "continuous (at x0) f \ (lsc_at x0 f) \ (usc_at x0 f)" proof- { assume a: "continuous (at x0) f" { fix x assume "x \ x0" hence "(f \ x) \ f x0" using a continuous_imp_tendsto[of x0 f x] by auto hence "liminf (f \ x) = f x0 \ limsup (f \ x) = f x0" using lim_imp_Liminf[of sequentially] lim_imp_Limsup[of sequentially] by auto } hence "lsc_at x0 f \ usc_at x0 f" unfolding lsc_liminf usc_limsup by auto } moreover { assume a: "(lsc_at x0 f) \ (usc_at x0 f)" { fix x assume "x \ x0" hence "limsup (f \ x) \ f x0" using a unfolding usc_limsup by auto moreover have "\ \ liminf (f \ x)" using a \x \ x0\ unfolding lsc_liminf by auto ultimately have "limsup (f \ x) = f x0 \ liminf (f \ x) = f x0" using Liminf_le_Limsup[of sequentially "f \ x"] by auto hence "(f \ x) \ f x0" using Liminf_eq_Limsup[of sequentially] by auto } hence "continuous (at x0) f" using continuous_at_sequentially[of x0 f] by auto } ultimately show ?thesis by blast qed lemma continuous_lsc_compose: assumes "lsc_at (g x0) f" "continuous (at x0) g" shows "lsc_at x0 (f \ g)" proof- { fix x L assume "x \ x0" "(f \ g \ x) \ L" hence "f(g x0) \ L" apply (subst lsc_at_mem[of "g x0" f "g \ x" L]) using assms continuous_imp_tendsto[of x0 g x] unfolding o_def by auto } from this show ?thesis unfolding lsc_at_def by auto qed lemma continuous_isCont: "continuous (at x0) f \ isCont f x0" by (metis continuous_at isCont_def) lemma isCont_iff_lsc_usc: fixes f :: "'a::metric_space \ ereal" shows "isCont f x0 \ (lsc_at x0 f) \ (usc_at x0 f)" by (metis continuous_iff_lsc_usc continuous_isCont) definition lsc :: "('a::topological_space \ 'b::order_topology) \ bool" where "lsc f \ (\x. lsc_at x f)" definition usc :: "('a::topological_space \ 'b::order_topology) \ bool" where "usc f \ (\x. usc_at x f)" lemma continuous_UNIV_iff_lsc_usc: fixes f :: "'a::metric_space \ ereal" shows "(\x. continuous (at x) f) \ (lsc f) \ (usc f)" by (metis continuous_iff_lsc_usc lsc_def usc_def) subsection \Epigraphs\ definition "Epigraph S (f::_ \ ereal) = {xy. fst xy : S \ f (fst xy) \ ereal(snd xy)}" lemma mem_Epigraph: "(x, y) \ Epigraph S f \ x \ S \ f x \ ereal y" unfolding Epigraph_def by auto lemma ereal_closed_levels: fixes f :: "'a::metric_space \ ereal" shows "(\y. closed {x. f(x)\y}) \ (\r. closed {x. f(x)\ereal r})" (is "?lhs \ ?rhs") proof- { assume "?rhs" { fix y :: ereal { assume "y \ \ \ y \ -\" hence "closed {x. f(x)\y}" using \?rhs\ by (cases y) auto } moreover { assume "y=\" hence "closed {x. f(x)\y}" by auto } moreover { assume "y=-\" hence "{x. f(x)\y} = Inter {{x. f(x)\ereal r} |r. r : UNIV}" using ereal_bot by auto hence "closed {x. f(x)\y}" using closed_Inter \?rhs\ by auto } ultimately have "closed {x. f(x)\y}" by blast } hence "?lhs" by auto } from this show ?thesis by auto qed lemma lsc_iff: fixes f :: "'a::metric_space \ ereal" shows "(lsc f \ (\y. closed {x. f(x)\y})) \ (lsc f \ closed (Epigraph UNIV f))" proof- { assume "lsc f" { fix z z0 assume a: "\n. z n \ (Epigraph UNIV f) \ z \ z0" { fix n have "z n : (Epigraph UNIV f)" using a by auto hence "f (fst (z n)) \ ereal(snd (z n))" using a unfolding Epigraph_def by auto hence "\xn cn. z n = (xn, cn) \ f(xn)\ereal cn" apply (rule_tac x="fst (z n)" in exI) apply (rule_tac x="snd (z n)" in exI) by auto } from this obtain x c where xc_def: "\n. z n = (x n, c n) \ f(x n)\ereal (c n)" by metis from this a have "\x0 c0. z0 = (x0, c0) \ x \ x0 \ c \ c0" apply (rule_tac x="fst z0" in exI) apply (rule_tac x="snd z0" in exI) using tendsto_fst[of z z0] tendsto_snd[of z z0] by auto from this obtain x0 c0 where xc0_def: "z0 = (x0, c0) \ x \ x0 \ c \ c0" by auto hence "f(x0)\ereal c0" apply (subst lsc_sequentially_mem[of x0 f x "ereal \ c" "ereal c0"]) using \lsc f\ xc_def unfolding lsc_def unfolding o_def by auto hence "z0 : (Epigraph UNIV f)" unfolding Epigraph_def using xc0_def by auto } hence "closed (Epigraph UNIV f)" by (simp add: closed_sequential_limits) } moreover { assume "closed (Epigraph UNIV f)" hence *: "\x l. (\n. f (fst (x n)) \ ereal(snd (x n))) \ x \ l \ f (fst l) \ ereal(snd l)" unfolding Epigraph_def closed_sequential_limits by auto { fix r :: real { fix z z0 assume a: "\n. f(z n)\ereal r \ z \ z0" hence "f(z0)\ereal r" using *[rule_format, of "(\n. (z n,r))" "(z0,r)"] tendsto_Pair[of z z0] by auto } hence "closed {x. f(x)\ereal r}" by (simp add: closed_sequential_limits) } hence "\y. closed {x. f(x)\y}" using ereal_closed_levels by auto } moreover { assume a: "\y. closed {x. f(x)\ y}" { fix x0 { fix x l assume "x \ x0" "(f \ x) \ l" { assume "l = \" hence "f x0 \ l" by auto } moreover { assume mi: "l = -\" { fix B :: real obtain N where N_def: "\n\N. f(x n)\ereal B" using mi \(f \ x) \ l\ Lim_MInfty[of "f \ x"] by auto { fix d assume "(d::real)>0" from this obtain N1 where N1_def: "\n\N1. dist (x n) x0 < d" using \x \ x0\ unfolding lim_sequentially by auto hence "\y. dist y x0 < d \ y : {x. f(x)\ereal B}" apply (rule_tac x="x (max N N1)" in exI) using N_def by auto } hence "x0 : closure {x. f(x)\ereal B}" apply (subst closure_approachable) by auto hence "f x0 \ ereal B" using a by auto } hence "f x0 \ l" using ereal_bot[of "f x0"] by auto } moreover { assume fin: "\l\ \ \" { fix e assume e_def: "(e :: ereal)>0" from this obtain N where N_def: "\n\N. f(x n) : {l - e <..< l + e}" apply (subst tendsto_obtains_N[of "f \ x" l "{l - e <..< l + e}"]) using fin e_def ereal_between \(f \ x) \ l\ by auto hence *: "\n\N. x n : {x. f(x)\l+e}" using N_def by auto { fix d assume "(d::real)>0" from this obtain N1 where N1_def: "\n\N1. dist (x n) x0 < d" using \x \ x0\ unfolding lim_sequentially by auto hence "\y. dist y x0 < d \ y : {x. f(x)\l+e}" apply (rule_tac x="x (max N N1)" in exI) using * by auto } hence "x0 : closure {x. f(x)\l+e}" apply (subst closure_approachable) by auto hence "f x0 \ l+e" using a by auto } hence "f x0 \ l" using ereal_le_epsilon by auto } ultimately have "f x0 \ l" by blast } hence "lsc_at x0 f" unfolding lsc_at_def by auto } hence "lsc f" unfolding lsc_def by auto } ultimately show ?thesis by auto qed definition lsc_hull :: "('a::metric_space \ ereal) \ ('a::metric_space \ ereal)" where "lsc_hull f = (SOME g. Epigraph UNIV g = closure(Epigraph UNIV f))" lemma epigraph_mono: fixes f :: "'a::metric_space \ ereal" shows "(x,y):Epigraph UNIV f \ y\z \ (x,z):Epigraph UNIV f" unfolding Epigraph_def apply auto using ereal_less_eq(3)[of y z] order_trans_rules(23) by blast lemma closed_epigraph_lines: fixes S :: "('a::metric_space * 'b::metric_space) set" assumes "closed S" shows "closed {z. (x, z) : S}" proof- { fix z assume z_def: "z : closure {z. (x, z) : S}" { fix e :: real assume "e>0" from this obtain y where y_def: "(x,y) : S \ dist y z < e" using closure_approachable[of z "{z. (x, z) : S}"] z_def by auto moreover have "dist (x,y) (x,z) = dist y z" unfolding dist_prod_def by auto ultimately have "\s. s \ S \ dist s (x,z) < e" apply(rule_tac x="(x,y)" in exI) by auto } hence "(x,z):S" using closed_approachable[of S "(x,z)"] assms by auto } hence "closure {z. (x, z) : S} \ {z. (x, z) : S}" by blast from this show ?thesis using closure_subset_eq by auto qed lemma mono_epigraph: fixes S :: "('a::metric_space * real) set" assumes mono: "\x y z. (x,y):S \ y\z \ (x,z):S" assumes "closed S" shows "\g. ((Epigraph UNIV g) = S)" proof- { fix x have "closed {z. (x, z) : S}" using \closed S\ closed_epigraph_lines by auto hence "\a. {z. (x, z) : S} = {z. a \ ereal z}" apply (subst mono_closed_ereal) using mono by auto } from this obtain g where g_def: "\x. {z. (x, z) : S} = {z. g x \ ereal z}" by metis { fix s have "s:S \ (fst s, snd s) : S" by auto also have "\ \ g(fst s) \ ereal (snd s)" using g_def[rule_format, of "fst s"] by blast finally have "s:S \ g(fst s) \ ereal (snd s)" by auto } hence "(Epigraph UNIV g) = S" unfolding Epigraph_def by auto from this show ?thesis by auto qed lemma lsc_hull_exists: fixes f :: "'a::metric_space \ ereal" shows "\g. Epigraph UNIV g = closure (Epigraph UNIV f)" proof- { fix x y z assume xy: "(x,y):closure (Epigraph UNIV f) \ y\z" { fix e :: real assume "e>0" hence "\ya\Epigraph UNIV f. dist ya (x, y) < e" using xy closure_approachable[of "(x,y)" "Epigraph UNIV f"] by auto from this obtain a b where ab: "(a,b):Epigraph UNIV f \ dist (a,b) (x,y) < e" by auto moreover have "dist (a,b) (x,y) = dist (a,b+(z-y)) (x,z)" unfolding dist_prod_def dist_norm by (simp add: algebra_simps) moreover have "(a,b+(z-y)):Epigraph UNIV f" apply (subst epigraph_mono[of _ b]) using ab xy by auto ultimately have "\w\Epigraph UNIV f. dist w (x, z) < e" by auto } hence "(x,z):closure (Epigraph UNIV f)" using closure_approachable by auto } hence "\x y z. (x,y) \ closure (Epigraph UNIV f) \ y\z \ (x,z) \ closure (Epigraph UNIV f)" by auto from this show ?thesis using mono_epigraph[of "closure (Epigraph UNIV f)"] by auto qed lemma epigraph_invertible: assumes "Epigraph UNIV f = Epigraph UNIV g" shows "f=g" proof- { fix x { fix C have "f x \ ereal C \ (x,C) : Epigraph UNIV f" unfolding Epigraph_def by auto also have "\ \ (x,C) : Epigraph UNIV g" using assms by auto also have "\ \ g x \ ereal C" unfolding Epigraph_def by auto finally have "f x \ ereal C \ g x \ ereal C" by auto } hence "g x = f x" using ereal_le_real[of "g x" "f x"] ereal_le_real[of "f x" "g x"] by auto } from this show ?thesis by (simp add: ext) qed lemma lsc_hull_ex_unique: fixes f :: "'a::metric_space \ ereal" shows "\!g. Epigraph UNIV g = closure (Epigraph UNIV f)" using lsc_hull_exists epigraph_invertible by metis lemma epigraph_lsc_hull: fixes f :: "'a::metric_space \ ereal" shows "Epigraph UNIV (lsc_hull f) = closure(Epigraph UNIV f)" proof- have "\g. Epigraph UNIV g = closure (Epigraph UNIV f)" using lsc_hull_exists by auto thus ?thesis unfolding lsc_hull_def using some_eq_ex[of "(\g. Epigraph UNIV g = closure(Epigraph UNIV f))"] by auto qed lemma lsc_hull_expl: "(g = lsc_hull f) \ (Epigraph UNIV g = closure(Epigraph UNIV f))" proof- { assume "Epigraph UNIV g = closure(Epigraph UNIV f)" hence "lsc_hull f = g" unfolding lsc_hull_def apply (subst some1_equality[of _ g]) using lsc_hull_ex_unique by metis+ } from this show ?thesis using epigraph_lsc_hull by auto qed lemma lsc_lsc_hull: "lsc (lsc_hull f)" using epigraph_lsc_hull[of f] lsc_iff[of "lsc_hull f"] by auto lemma epigraph_subset_iff: fixes f g :: "'a::metric_space \ ereal" shows "Epigraph UNIV f \ Epigraph UNIV g \ (\x. g x \ f x)" proof- { assume epi: "Epigraph UNIV f \ Epigraph UNIV g" { fix x { fix z assume "f x \ ereal z" hence "(x,z)\Epigraph UNIV f" unfolding Epigraph_def by auto hence "(x,z)\Epigraph UNIV g" using epi by auto hence "g x \ ereal z" unfolding Epigraph_def by auto } hence "g x \ f x" apply (subst ereal_le_real) by auto } } moreover { assume le: "\x. g x \ f x" { fix x y assume "(x,y):Epigraph UNIV f" hence "f x \ ereal y" unfolding Epigraph_def by auto moreover have "g x \ f x" using le by auto ultimately have "g x \ ereal y" by auto hence "(x,y):Epigraph UNIV g" unfolding Epigraph_def by auto } } ultimately show ?thesis by auto qed lemma lsc_hull_le: "(lsc_hull f) x \ f x" using epigraph_lsc_hull[of f] closure_subset epigraph_subset_iff[of f "lsc_hull f"] by auto lemma lsc_hull_greatest: fixes f g :: "'a::metric_space \ ereal" assumes "lsc g" "\x. g x \ f x" shows "\x. g x \ (lsc_hull f) x" proof- have "closure(Epigraph UNIV f) \ Epigraph UNIV g" using lsc_iff epigraph_subset_iff assms by (metis closure_minimal) from this show ?thesis using epigraph_subset_iff lsc_hull_expl by metis qed lemma lsc_hull_iff_greatest: fixes f g :: "'a::metric_space \ ereal" shows "(g = lsc_hull f) \ lsc g \ (\x. g x \ f x) \ (\h. lsc h \ (\x. h x \ f x) \ (\x. h x \ g x))" (is "?lhs \ ?rhs") proof- { assume "?lhs" hence "?rhs" using lsc_lsc_hull lsc_hull_le lsc_hull_greatest by metis } moreover { assume "?rhs" { fix x have "(lsc_hull f) x \ g x" using \?rhs\ lsc_lsc_hull lsc_hull_le by metis moreover have "(lsc_hull f) x \ g x" using \?rhs\ lsc_hull_greatest by metis ultimately have "(lsc_hull f) x = g x" by auto } hence "?lhs" by (simp add: ext) } ultimately show ?thesis by blast qed lemma lsc_hull_mono: fixes f g :: "'a::metric_space \ ereal" assumes "\x. g x \ f x" shows "\x. (lsc_hull g) x \ (lsc_hull f) x" proof- { fix x have "(lsc_hull g) x \ g x" using lsc_hull_le[of g x] by auto also have "\ \ f x" using assms by auto finally have "(lsc_hull g) x \ f x" by auto } note * = this show ?thesis apply (subst lsc_hull_greatest) using lsc_lsc_hull[of g] * by auto qed lemma lsc_hull_lsc: "lsc f \ (f = lsc_hull f)" using lsc_hull_iff_greatest[of f f] by auto lemma lsc_hull_liminf_at: fixes f :: "'a::metric_space \ ereal" shows "\x. (lsc_hull f) x = min (f x) (Liminf (at x) f)" proof- { fix x z assume "(x,z):Epigraph UNIV (\x. min (f x) (Liminf (at x) f))" hence xz_def: "ereal z \ (SUP e\{0<..}. INF y\ball x e. f y)" unfolding Epigraph_def min_Liminf_at by auto { fix e::real assume "e>0" hence "e/sqrt 2>0" using \e>0\ by simp from this obtain e1 where e1_def: "e1 e1>0" using dense by auto hence "(SUP e\{0<..}. INF y\ball x e. f y) \ (INF y\ball x e1. f y)" by (auto intro: SUP_upper) hence "ereal z \ (INF y\ball x e1. f y)" using xz_def by auto hence *: "\y>ereal z. \t. t \ ball x e1 \ f t \ y" by (simp add: Bex_def Inf_le_iff_less) obtain t where t_def: "t : ball x e1 \ f t \ ereal(z+e1)" using e1_def *[rule_format, of "ereal(z+e1)"] by auto hence epi: "(t,z+e1):Epigraph UNIV f" unfolding Epigraph_def by auto have "dist x t < e1" using t_def unfolding ball_def dist_norm by auto hence "sqrt (e1 ^ 2 + dist x t ^ 2) < e" using e1_def apply (subst real_sqrt_sum_squares_less) by auto moreover have "dist (x,z) (t,z+e1) = sqrt (e1 ^ 2 + dist x t ^ 2)" unfolding dist_prod_def dist_norm by (simp add: algebra_simps) ultimately have "dist (x,z) (t,z+e1) < e" by auto hence "\y\Epigraph UNIV f. dist y (x, z) < e" apply (rule_tac x="(t,z+e1)" in bexI) apply (simp add: dist_commute) using epi by auto } hence "(x,z) : closure (Epigraph UNIV f)" using closure_approachable[of "(x,z)" "Epigraph UNIV f"] by auto } moreover { fix x z assume xz_def: "(x,z):closure (Epigraph UNIV f)" { fix e::real assume "e>0" from this obtain y where y_def: "y:(Epigraph UNIV f) \ dist y (x,z) < e" using closure_approachable[of "(x,z)" "Epigraph UNIV f"] xz_def by metis have "dist (fst y) x \ sqrt ((dist (fst y) x) ^ 2 + (dist (snd y) z) ^ 2)" by (auto intro: real_sqrt_sum_squares_ge1) also have "\ sqrt ((dist (fst y) x) ^ 2 + (dist (snd y) z) ^ 2)" by (auto intro: real_sqrt_sum_squares_ge2) also have "\ball x e. f y) \ f(fst y)" using h1 by (simp add: INF_lower) also have "\\ereal(snd y)" using y_def unfolding Epigraph_def by auto also have "\ < ereal(z+e)" using h2 unfolding dist_norm by auto finally have "(INF y\ball x e. f y) < ereal(z+e)" by auto } hence *: "\e>0. (INF y\ball x e. f y) < ereal(z+e)" by auto { fix e assume "(e::real)>0" { fix d assume "(d::real)>0" { assume "dball x d. f y) < ereal(z+d)" using * \d>0\ by auto also have "\< ereal(z+e)" using \d by auto finally have "(INF y\ball x d. f y) < ereal(z+e)" by auto } moreover { assume "~(d ball x d" by auto hence "(INF y\ball x d. f y) \ (INF y\ball x e. f y)" apply (subst INF_mono) by auto also have "\< ereal(z+e)" using * \e>0\ by auto finally have "(INF y\ball x d. f y) < ereal(z+e)" by auto } ultimately have "(INF y\ball x d. f y) < ereal(z+e)" by blast hence "(INF y\ball x d. f y) \ ereal(z+e)" by auto } hence "min (f x) (Liminf (at x) f) \ ereal (z+e)" unfolding min_Liminf_at by (auto intro: SUP_least) } hence "min (f x) (Liminf (at x) f) \ ereal z" using ereal_le_epsilon2 by auto hence "(x,z):Epigraph UNIV (\x. min (f x) (Liminf (at x) f))" unfolding Epigraph_def by auto } ultimately have "Epigraph UNIV (\x. min (f x) (Liminf (at x) f))= closure (Epigraph UNIV f)" by auto hence "(\x. min (f x) (Liminf (at x) f)) = lsc_hull f" using epigraph_invertible epigraph_lsc_hull[of f] by blast from this show ?thesis by metis qed lemma lsc_hull_same_inf: fixes f :: "'a::metric_space \ ereal" shows "(INF x. lsc_hull f x) = (INF x. f x)" proof- { fix x have "(INF x. f x) \ (INF y\ball x 1. f y)" apply (subst INF_mono) by auto also have "\ \ min (f x) (Liminf (at x) f)" unfolding min_Liminf_at by (auto intro: SUP_upper) also have "\=(lsc_hull f) x" using lsc_hull_liminf_at[of f] by auto finally have "(INF x. f x) \ (lsc_hull f) x" by auto } hence "(INF x. f x) \ (INF x. lsc_hull f x)" apply (subst INF_greatest) by auto moreover have "(INF x. lsc_hull f x) \ (INF x. f x)" apply (subst INF_mono) using lsc_hull_le by auto ultimately show ?thesis by auto qed subsection \Convex Functions\ definition convex_on :: "'a::real_vector set \ ('a \ ereal) \ bool" where "convex_on s f \ (\x\s. \y\s. \u\0. \v\0. u + v = 1 \ f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * f x + ereal v * f y)" lemma convex_on_ereal_mem: assumes "convex_on s f" assumes "x:s" "y:s" assumes "u\0" "v\0" "u+v=1" shows "f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * f x + ereal v * f y" using assms unfolding convex_on_def by auto lemma convex_on_ereal_subset: "convex_on t f \ s \ t \ convex_on s f" unfolding convex_on_def by auto lemma convex_on_ereal_univ: "convex_on UNIV f \ (\S. convex_on S f)" using convex_on_ereal_subset by auto lemma ereal_pos_sum_distrib_left: fixes f :: "'a \ ereal" assumes "r\0" "r \ \" shows "r * sum f A = sum (\n. r * f n) A" proof (cases "finite A") case True thus ?thesis proof induct case empty thus ?case by simp next case (insert x A) thus ?case using assms by (simp add: ereal_pos_distrib) qed next case False thus ?thesis by simp qed lemma convex_ereal_add: fixes f g :: "'a::real_vector \ ereal" assumes "convex_on s f" "convex_on s g" shows "convex_on s (\x. f x + g x)" proof- { fix x y assume "x:s" "y:s" moreover fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" ultimately have "f (u *\<^sub>R x + v *\<^sub>R y) + g (u *\<^sub>R x + v *\<^sub>R y) \ (ereal u * f x + ereal v * f y) + (ereal u * g x + ereal v * g y)" using assms unfolding convex_on_def by (auto simp add: add_mono) also have "\=(ereal u * f x + ereal u * g x) + (ereal v * f y + ereal v * g y)" by (simp add: algebra_simps) also have "\= ereal u * (f x + g x) + ereal v * (f y + g y)" using uv by (simp add: ereal_pos_distrib) finally have "f (u *\<^sub>R x + v *\<^sub>R y) + g (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * (f x + g x) + ereal v * (f y + g y)" by auto } thus ?thesis unfolding convex_on_def by auto qed lemma convex_ereal_cmul: assumes "0 \ (c::ereal)" "convex_on s f" shows "convex_on s (\x. c * f x)" proof- { fix x y assume "x:s" "y:s" moreover fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" ultimately have "f (u *\<^sub>R x + v *\<^sub>R y) \ (ereal u * f x + ereal v * f y)" using assms unfolding convex_on_def by auto hence "c * f (u *\<^sub>R x + v *\<^sub>R y) \ c * (ereal u * f x + ereal v * f y)" using assms by (intro ereal_mult_left_mono) auto also have "\ \ c * (ereal u * f x) + c * (ereal v * f y)" using assms by (simp add: ereal_le_distrib) also have "\ = ereal u *(c* f x) + ereal v *(c* f y)" by (simp add: algebra_simps) finally have "c * f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * (c * f x) + ereal v * (c * f y)" by auto } thus ?thesis unfolding convex_on_def by auto qed lemma convex_ereal_max: fixes f g :: "'a::real_vector \ ereal" assumes "convex_on s f" "convex_on s g" shows "convex_on s (\x. max (f x) (g x))" proof- { fix x y assume "x:s" "y:s" moreover fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" ultimately have "max (f (u *\<^sub>R x + v *\<^sub>R y)) (g (u *\<^sub>R x + v *\<^sub>R y)) \ max (ereal u * f x + ereal v * f y) (ereal u * g x + ereal v * g y)" apply (subst max.mono) using assms unfolding convex_on_def by auto also have "\\ereal u * max (f x) (g x) + ereal v * max (f y) (g y)" apply (subst max.boundedI) apply (subst add_mono) prefer 4 apply (subst add_mono) by (subst ereal_mult_left_mono, auto simp add: uv)+ finally have "max (f (u *\<^sub>R x + v *\<^sub>R y)) (g (u *\<^sub>R x + v *\<^sub>R y)) \ ereal u * max (f x) (g x) + ereal v * max (f y) (g y)" by auto } thus ?thesis unfolding convex_on_def by auto qed lemma convex_on_ereal_alt: fixes C :: "'a::real_vector set" assumes "convex C" shows "convex_on C f = (\x \ C. \y \ C. \m :: real. m \ 0 \ m \ 1 \ f (m *\<^sub>R x + (1 - m) *\<^sub>R y) \ (ereal m) * f x + (1 - (ereal m)) * f y)" proof safe fix x y fix m :: real have[simp]: "ereal (1 - m) = (1 - ereal m)" using ereal_minus(1)[of 1 m] by (auto simp: one_ereal_def) assume asms: "convex_on C f" "x : C" "y : C" "0 \ m" "m \ 1" from this[unfolded convex_on_def, rule_format] have "\u v. ((0 \ u \ 0 \ v \ u + v = 1) \ f (u *\<^sub>R x + v *\<^sub>R y) \ (ereal u) * f x + (ereal v) * f y)" by auto from this[rule_format, of "m" "1 - m", simplified] asms show "f (m *\<^sub>R x + (1 - m) *\<^sub>R y) \ (ereal m) * f x + (1 - ereal m) * f y" by auto next assume asm: "\x\C. \y\C. \m. 0 \ m \ m \ 1 \ f (m *\<^sub>R x + (1 - m) *\<^sub>R y) \ (ereal m) * f x + (1 - ereal m) * f y" { fix x y fix u v :: real assume lasm: "x \ C" "y \ C" "u \ 0" "v \ 0" "u + v = 1" hence[simp]: "1-u=v" "1 - ereal u = ereal v" using ereal_minus(1)[of 1 m] by (auto simp: one_ereal_def) from asm[rule_format, of x y u] have "f (u *\<^sub>R x + v *\<^sub>R y) \ (ereal u) * f x + (ereal v) * f y" using lasm by auto } thus "convex_on C f" unfolding convex_on_def by auto qed lemma convex_on_ereal_alt_mem: fixes C :: "'a::real_vector set" assumes "convex C" assumes "convex_on C f" assumes "x : C" "y : C" assumes "(m::real) \ 0" "m \ 1" shows "f (m *\<^sub>R x + (1 - m) *\<^sub>R y) \ (ereal m) * f x + (1 - (ereal m)) * f y" by (metis assms convex_on_ereal_alt) lemma ereal_add_right_mono: "(a::ereal) \ b \ a + c \ b + c" by (metis add_mono order_refl) lemma convex_on_ereal_sum_aux: assumes "1-a>0" shows "(1 - ereal a) * (ereal (c / (1 - a)) * b) = (ereal c) * b" by (metis mult.assoc mult.commute eq_divide_eq ereal_minus(1) assms one_ereal_def less_le times_ereal.simps(1)) lemma convex_on_ereal_sum: fixes a :: "'a \ real" fixes y :: "'a \ 'b::real_vector" fixes f :: "'b \ ereal" assumes "finite s" "s \ {}" assumes "convex_on C f" assumes "convex C" assumes "(SUM i : s. a i) = 1" assumes "\i. i \ s \ a i \ 0" assumes "\i. i \ s \ y i \ C" shows "f (SUM i : s. a i *\<^sub>R y i) \ (SUM i : s. ereal (a i) * f (y i))" using assms(1,2,5-) proof (induct s arbitrary:a rule:finite_ne_induct) case (singleton i) hence ai: "a i = 1" by auto thus ?case by (auto simp: one_ereal_def[symmetric]) next case (insert i s) from \convex_on C f\ have conv: "\x y m. ((x \ C \ y \ C \ 0 \ m \ m \ 1) \ f (m *\<^sub>R x + (1 - m) *\<^sub>R y) \ (ereal m) * f x + (1 - ereal m) * f y)" using convex_on_ereal_alt[of C f] \convex C\ by auto { assume "a i = 1" hence "(SUM j : s. a j) = 0" using insert by auto hence "\j. (j \ s \ a j = 0)" using insert by (simp add: sum_nonneg_eq_0_iff) hence ?case using insert.hyps(1-3) \a i = 1\ by (simp add: zero_ereal_def[symmetric] one_ereal_def[symmetric]) } moreover { assume asm: "a i \ 1" from insert have yai: "y i : C" "a i \ 0" by auto have fis: "finite (insert i s)" using insert by auto hence ai1: "a i \ 1" using sum_nonneg_leq_bound[of "insert i s" a] insert by simp hence "a i < 1" using asm by auto hence i0: "1 - a i > 0" by auto hence i1: "1 - ereal (a i) > 0" using ereal_minus(1)[of 1 "a i"] by (simp add: zero_ereal_def[symmetric] one_ereal_def[symmetric]) have i2: "1 - ereal (a i) \ \" using ereal_minus(1)[of 1] by (simp add: zero_ereal_def[symmetric] one_ereal_def[symmetric]) let "?a j" = "a j / (1 - a i)" have a_nonneg: "\j. j \ s \ 0 \ a j / (1 - a i)" using i0 insert by (metis insert_iff divide_nonneg_pos) have "(SUM j : insert i s. a j) = 1" using insert by auto hence "(SUM j : s. a j) = 1 - a i" using sum.insert insert by fastforce hence "(SUM j : s. a j) / (1 - a i) = 1" using i0 by auto hence a1: "(SUM j : s. ?a j) = 1" unfolding sum_divide_distrib by simp have asum: "(SUM j : s. ?a j *\<^sub>R y j) : C" using insert convex_sum[OF \finite s\ \convex C\ a1 a_nonneg] by auto have asum_le: "f (SUM j : s. ?a j *\<^sub>R y j) \ (SUM j : s. ereal (?a j) * f (y j))" using a_nonneg a1 insert by blast have "f (SUM j : insert i s. a j *\<^sub>R y j) = f ((SUM j : s. a j *\<^sub>R y j) + a i *\<^sub>R y i)" using sum.insert[of s i "\j. a j *\<^sub>R y j", OF \finite s\ \i \ s\] by (auto simp only:add.commute) also have "\ = f (((1 - a i) * inverse (1 - a i)) *\<^sub>R (SUM j : s. a j *\<^sub>R y j) + a i *\<^sub>R y i)" using i0 by auto also have "\ = f ((1 - a i) *\<^sub>R (SUM j : s. (a j * inverse (1 - a i)) *\<^sub>R y j) + a i *\<^sub>R y i)" using scaleR_right.sum[of "inverse (1 - a i)" "\j. a j *\<^sub>R y j" s, symmetric] by (auto simp:algebra_simps) also have "\ = f ((1 - a i) *\<^sub>R (SUM j : s. ?a j *\<^sub>R y j) + a i *\<^sub>R y i)" by (auto simp: divide_inverse) also have "\ \ (1 - ereal (a i)) * f ((SUM j : s. ?a j *\<^sub>R y j)) + (ereal (a i)) * f (y i)" using conv[rule_format, of "y i" "(SUM j : s. ?a j *\<^sub>R y j)" "a i"] using yai(1) asum yai(2) ai1 by (auto simp add:add.commute) also have "\ \ (1 - ereal (a i)) * (SUM j : s. ereal (?a j) * f (y j)) + (ereal (a i)) * f (y i)" using ereal_add_right_mono[OF ereal_mult_left_mono[of _ _ "1 - ereal (a i)", OF asum_le less_imp_le[OF i1]], of "(ereal (a i)) * f (y i)"] by simp also have "\ = (SUM j : s. (1 - ereal (a i)) * (ereal (?a j) * f (y j))) + (ereal (a i)) * f (y i)" unfolding ereal_pos_sum_distrib_left[of "1 - ereal (a i)" "\j. (ereal (?a j)) * f (y j)", OF less_imp_le[OF i1] i2] by auto also have "\ = (SUM j : s. (ereal (a j)) * f (y j)) + (ereal (a i)) * f (y i)" using i0 convex_on_ereal_sum_aux by auto also have "\ = (ereal (a i)) * f (y i) + (SUM j : s. (ereal (a j)) * f (y j))" by (simp add: add.commute) also have "\ = (SUM j : insert i s. (ereal (a j)) * f (y j))" using insert by auto finally have "f (SUM j : insert i s. a j *\<^sub>R y j) \ (SUM j : insert i s. (ereal (a j)) * f (y j))" by simp } ultimately show ?case by auto qed lemma sum_2: "sum u {1::nat..2} = (u 1)+(u 2)" proof- have "{1::nat..2} = {1::nat,2}" by auto thus ?thesis by auto qed lemma convex_on_ereal_iff: assumes "convex s" shows "convex_on s f \ (\k u x. (\i\{1..k::nat}. 0 \ u i \ x i : s) \ sum u {1..k} = 1 \ f (sum (\i. u i *\<^sub>R x i) {1..k} ) \ sum (\i. (ereal (u i)) * f(x i)) {1..k} )" (is "?rhs \ ?lhs") proof- { assume "?rhs" { fix k u x have zero: "~(sum u {1..0::nat} = (1::real))" by auto assume "(\i\{1..k::nat}. (0::real) \ u i \ x i \ s)" moreover assume *: "sum u {1..k} = 1" moreover from * have "k \ 0" using zero by metis ultimately have "f (sum (\i. u i *\<^sub>R x i) {1..k} ) \ sum (\i. (ereal (u i)) * f(x i)) {1..k}" using convex_on_ereal_sum[of "{1..k}" s f u x] using assms \?rhs\ by auto } hence "?lhs" by auto } moreover { assume "?lhs" { fix x y u v assume xys: "x:s" "y:s" assume uv1: "u\0" "v\0" "u + v = (1::real)" define xy where "xy = (\i::nat. if i=1 then x else y)" define uv where "uv = (\i::nat. if i=1 then u else v)" have "\i\{1..2::nat}. (0 \ uv i) \ (xy i : s)" unfolding xy_def uv_def using xys uv1 by auto moreover have "sum uv {1..2} = 1" using sum_2[of uv] unfolding uv_def using uv1 by auto moreover have "(SUM i = 1..2. uv i *\<^sub>R xy i) = u *\<^sub>R x + v *\<^sub>R y" using sum_2[of "(\i. uv i *\<^sub>R xy i)"] unfolding xy_def uv_def using xys uv1 by auto moreover have "(SUM i = 1..2. ereal (uv i) * f (xy i)) = ereal u * f x + ereal v * f y" using sum_2[of "(\i. ereal (uv i) * f (xy i))"] unfolding xy_def uv_def using xys uv1 by auto ultimately have "f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * f x + ereal v * f y" using \?lhs\[rule_format, of "2" uv xy] by auto } hence "?rhs" unfolding convex_on_def by auto } ultimately show ?thesis by blast qed lemma convex_Epigraph: assumes "convex S" shows "convex(Epigraph S f) \ convex_on S f" proof- { assume rhs: "convex(Epigraph S f)" { fix x y assume xy: "x:S" "y:S" fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" have "f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * f x + ereal v * f y" proof- { assume "u=0 | v=0" hence ?thesis using uv by (auto simp: zero_ereal_def[symmetric] one_ereal_def[symmetric]) } moreover { assume "f x = \ | f y = \" hence ?thesis using uv by (auto simp: zero_ereal_def[symmetric] one_ereal_def[symmetric]) } moreover { assume a: "f x = -\ \ (f y \ \) \ ~(u=0)" from this obtain z where "f y \ ereal z" apply (cases "f y") by auto hence yz: "(y,z) : Epigraph S f" unfolding Epigraph_def using xy by auto { fix C::real have "(x, (1/u)*(C - v * z)) : Epigraph S f" unfolding Epigraph_def using a xy by auto hence "(u *\<^sub>R x + v *\<^sub>R y, C) : Epigraph S f" using rhs convexD[of "Epigraph S f" "(x, (1/u)*(C - v * z))" "(y,z)" u v] uv yz a by auto hence "(f (u *\<^sub>R x + v *\<^sub>R y) \ ereal C)" unfolding Epigraph_def by auto } hence "f (u *\<^sub>R x + v *\<^sub>R y) = -\" using ereal_bot by auto hence ?thesis by auto } moreover { assume a: "(f x \ \) \ f y = -\ \ ~(v=0)" from this obtain z where "f x \ ereal z" apply (cases "f x") by auto hence xz: "(x,z) : Epigraph S f" unfolding Epigraph_def using xy by auto { fix C::real have "(y, (1/v)*(C - u * z)) : Epigraph S f" unfolding Epigraph_def using a xy by auto hence "(u *\<^sub>R x + v *\<^sub>R y, C) : Epigraph S f" using rhs convexD[of "Epigraph S f" "(x,z)" "(y, (1/v)*(C - u * z))" u v] uv xz a by auto hence "(f (u *\<^sub>R x + v *\<^sub>R y) \ ereal C)" unfolding Epigraph_def by auto } hence "f (u *\<^sub>R x + v *\<^sub>R y) = -\" using ereal_bot by auto hence ?thesis by auto } moreover { assume a: "f x \ \ \ f x \ -\ \ f y \ \ \ f y \ -\" from this obtain fx fy where fxy: "f x = ereal fx \ f y = ereal fy" apply (cases "f x", cases "f y") by auto hence "(x, fx) : Epigraph S f \ (y, fy) : Epigraph S f" unfolding Epigraph_def using xy by auto hence "(u *\<^sub>R x + v *\<^sub>R y, u * fx + v * fy) : Epigraph S f" using rhs convexD[of "Epigraph S f" "(x,fx)" "(y,fy)" u v] uv by auto hence ?thesis unfolding Epigraph_def using fxy by auto } ultimately show ?thesis by blast qed } hence "convex_on S f" unfolding convex_on_def by auto } moreover { assume lhs: "convex_on S f" { fix x y fx fy assume xy: "(x,fx):Epigraph S f" "(y,fy):Epigraph S f" fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" hence le: "f x \ ereal fx \ f y \ ereal fy" using xy unfolding Epigraph_def by auto have "x:S \ y:S" using xy unfolding Epigraph_def by auto moreover hence inS: "u *\<^sub>R x + v *\<^sub>R y : S" using assms uv convexD[of S] by auto ultimately have "f(u *\<^sub>R x + v *\<^sub>R y) \ (ereal u) * f x + (ereal v) * f y" using lhs convex_on_ereal_mem[of S f x y u v] uv by auto also have "\ \ (ereal u) * (ereal fx) + (ereal v) * (ereal fy)" apply (subst add_mono) apply (subst ereal_mult_left_mono) prefer 4 apply (subst ereal_mult_left_mono) using le uv by auto also have "\ = ereal (u * fx + v * fy)" by auto finally have "(u *\<^sub>R x + v *\<^sub>R y, u * fx + v * fy) : Epigraph S f" unfolding Epigraph_def using inS by auto } hence "convex(Epigraph S f)" unfolding convex_def by auto } ultimately show ?thesis by auto qed lemma convex_EpigraphI: "convex_on s f \ convex s \ convex(Epigraph s f)" unfolding convex_Epigraph by auto definition concave_on :: "'a::real_vector set \ ('a \ ereal) \ bool" where "concave_on S f \ convex_on S (\x. - f x)" definition finite_on :: "'a::real_vector set \ ('a \ ereal) \ bool" where "finite_on S f \ (\x\S. (f x \ \ \ f x \ -\))" definition affine_on :: "'a::real_vector set \ ('a \ ereal) \ bool" where "affine_on S f \ (convex_on S f \ concave_on S f \ finite_on S f)" definition "domain (f::_ \ ereal) = {x. f x < \}" lemma domain_Epigraph_aux: assumes "x \ \" shows "\r. x\ereal r" using assms by (cases x) auto lemma domain_Epigraph: "domain f = {x. \y. (x,y) \ Epigraph UNIV f}" unfolding domain_def Epigraph_def using domain_Epigraph_aux by auto lemma domain_Epigraph_fst: "domain f = fst ` (Epigraph UNIV f)" proof- { fix x assume "x:domain f" from this obtain y where "(x,y):Epigraph UNIV f" using domain_Epigraph[of f] by auto moreover have "x = fst (x,y)" by auto ultimately have "x:fst ` (Epigraph UNIV f)" unfolding image_def by blast } from this show ?thesis using domain_Epigraph[of f] by auto qed lemma convex_on_domain: "convex_on (domain f) f \ convex_on UNIV f" proof- { assume lhs: "convex_on (domain f) f" { fix x y fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" have "f (u *\<^sub>R x + v *\<^sub>R y) \ ereal u * f x + ereal v * f y" proof- { assume "f x = \ | f y = \" hence ?thesis using uv by (auto simp: zero_ereal_def[symmetric] one_ereal_def[symmetric]) } moreover { assume "~ (f x = \ | f y = \)" hence "x : domain f \ y : domain f" unfolding domain_def by auto hence ?thesis using lhs unfolding convex_on_def using uv by auto } ultimately show ?thesis by blast qed } hence "convex_on UNIV f" unfolding convex_on_def by auto } from this show ?thesis using convex_on_ereal_subset by auto qed lemma convex_on_domain2: "convex_on (domain f) f \ (\S. convex_on S f)" by (metis convex_on_domain convex_on_ereal_univ) lemma convex_domain: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "convex (domain f)" proof- have "convex (Epigraph UNIV f)" using assms convex_Epigraph by auto thus ?thesis unfolding domain_Epigraph_fst - apply (subst convex_linear_image) using fst_linear linear_conv_bounded_linear by auto + apply (subst convex_linear_image) using linear_fst linear_conv_bounded_linear by auto qed lemma infinite_convex_domain_iff: fixes f :: "'a::euclidean_space \ ereal" assumes "\x. (f x = \ | f x = -\)" shows "convex_on UNIV f \ convex (domain f)" proof- { assume dom: "convex (domain f)" { fix x y assume "x:domain f" "y:domain f" moreover fix u v ::real assume uv: "0 \ u" "0 \ v" "u + v = 1" ultimately have "u *\<^sub>R x + v *\<^sub>R y : domain f" using dom unfolding convex_def by auto hence "f(u *\<^sub>R x + v *\<^sub>R y) = -\" using assms unfolding domain_def by auto } hence "convex_on (domain f) f" unfolding convex_on_def by auto hence "convex_on UNIV f" by (metis convex_on_domain2) } thus ?thesis by (metis convex_domain) qed lemma convex_PInfty_outside: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" "convex S" shows "convex_on UNIV (\x. if x:S then (f x) else \)" proof- define g where "g x = (if x:S then -\ else \::ereal)" for x hence "convex_on UNIV g" apply (subst infinite_convex_domain_iff) using assms unfolding domain_def by auto moreover have "(\x. if x:S then (f x) else \) = (\x. max (f x) (g x))" apply (subst fun_eq_iff) unfolding g_def by auto ultimately show ?thesis using convex_ereal_max assms by auto qed definition proper_on :: "'a::real_vector set \ ('a \ ereal) \ bool" where "proper_on S f \ ((\x\S. f x \ -\) \ (\x\S. f x \ \))" definition proper :: "('a::real_vector \ ereal) \ bool" where "proper f \ proper_on UNIV f" lemma proper_iff: "proper f \ ((\x. f x \ -\) \ (\x. f x \ \))" unfolding proper_def proper_on_def by auto lemma improper_iff: "~(proper f) \ ((\x. f x = -\) | (\x. f x = \))" using proper_iff by auto lemma ereal_MInf_plus[simp]: "-\ + x = (if x = \ then \ else -\::ereal)" by (cases x) auto lemma convex_improper: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "~(proper f)" shows "\x\rel_interior(domain f). f x = -\" proof- { assume "domain f = {}" hence ?thesis using rel_interior_empty by auto } moreover { assume nemp: "domain f \ {}" then obtain u where u_def: "f u = -\" using assms improper_iff[of f] unfolding domain_def by auto hence udom: "u:domain f" unfolding domain_def by auto { fix x assume "x:rel_interior(domain f)" then obtain m where m_def: "m>1 \ (1 - m) *\<^sub>R u + m *\<^sub>R x : domain f" using convex_rel_interior_iff[of "domain f" x] nemp convex_domain[of f] assms udom by auto define v where "v = 1/m" hence v01: "0 v<1" using m_def by auto define y where "y = (1 - m) *\<^sub>R u + m *\<^sub>R x" have "x = (1-v) *\<^sub>R u+v *\<^sub>R y" unfolding v_def y_def using m_def by (simp add: algebra_simps) hence "f x \ (1-ereal v) * f u+ereal v * f y" using convex_on_ereal_alt_mem[of "UNIV" f y u v] assms convex_UNIV v01 by (simp add: add.commute) moreover have "f y < \" using m_def y_def unfolding domain_def by auto moreover have *: "0 < 1 - ereal v" using v01 by (metis diff_gt_0_iff_gt ereal_less(2) ereal_minus(1) one_ereal_def) moreover from * have "(1-ereal v) * f u = -\" using u_def by auto ultimately have "f x = -\" using v01 by simp } hence ?thesis by auto } ultimately show ?thesis by blast qed lemma convex_improper2: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "~(proper f)" shows "f x = \ | f x = -\ | x : rel_frontier (domain f)" proof- { assume a: "~(f x = \ | f x = -\)" hence "x: domain f" unfolding domain_def by auto hence "x : closure (domain f)" using closure_subset by auto moreover have "x \ rel_interior (domain f)" using assms convex_improper a by auto ultimately have "x : rel_frontier (domain f)" unfolding rel_frontier_def by auto } thus ?thesis by auto qed lemma convex_lsc_improper: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "~(proper f)" assumes "lsc f" shows "f x = \ | f x = -\" proof- { fix x assume "f x \ \" hence "lsc_at x f" using assms unfolding lsc_def by auto have "x: domain f" unfolding domain_def using \f x \ \\ by auto hence "x : closure (domain f)" using closure_subset by auto hence x_def: "x : closure (rel_interior (domain f))" by (metis assms(1) convex_closure_rel_interior convex_domain) { fix C assume "C0 \ (\y. dist x y < d \ C < f y)" using lst_at_delta[of x f] \lsc_at x f\ by auto from this obtain y where y_def: "y:rel_interior (domain f) \ dist y x < d" using x_def closure_approachable[of x "rel_interior (domain f)"] by auto hence "f y = -\" by (metis assms(1) assms(2) convex_improper) moreover have "C < f y" using y_def d_def by (simp add: dist_commute) ultimately have False by auto } hence "f x = -\" by auto } from this show ?thesis by auto qed lemma convex_lsc_hull: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "convex_on UNIV (lsc_hull f)" proof- have "convex(Epigraph UNIV f)" by (metis assms convex_EpigraphI convex_UNIV) hence "convex (Epigraph UNIV (lsc_hull f))" by (metis convex_closure epigraph_lsc_hull) thus ?thesis by (metis convex_Epigraph convex_UNIV) qed lemma improper_lsc_hull: fixes f :: "'a::euclidean_space \ ereal" assumes "~(proper f)" shows "~(proper (lsc_hull f))" proof- { assume *: "\x. f x = \" then have "lsc f" by (metis (full_types) UNIV_I lsc_at_open lsc_def open_UNIV) with * have "\x. (lsc_hull f) x = \" by (metis lsc_hull_lsc) } hence "(\x. f x = \) \ (\x. (lsc_hull f) x = \)" by (metis ereal_infty_less_eq(1) lsc_hull_le) moreover have "(\x. f x = -\) \ (\x. (lsc_hull f) x = -\)" by (metis ereal_infty_less_eq2(2) lsc_hull_le) ultimately show ?thesis using assms unfolding improper_iff by auto qed lemma lsc_hull_convex_improper: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "~(proper f)" shows "\x\rel_interior(domain f). (lsc_hull f) x = f x" by (metis assms convex_improper ereal_infty_less_eq(2) lsc_hull_le) lemma convex_with_rel_open_domain: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "rel_open (domain f)" shows "(\x. f x > -\) | (\x. (f x = \ | f x = -\))" proof- { assume "\(\x. f x > -\)" hence "\(proper f)" using proper_iff by auto hence "\x\rel_interior(domain f). f x = -\" by (metis assms(1) convex_improper) hence "\x\domain f. f x = -\" by (metis assms(2) rel_open_def) hence "\x. (f x = \ | f x = -\)" unfolding domain_def by auto } thus ?thesis by auto qed lemma convex_with_UNIV_domain: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "domain f = UNIV" shows "(\x. f x > -\) \ (\x. f x = -\)" by (metis assms convex_improper ereal_MInfty_lessI proper_iff rel_interior_UNIV UNIV_I) lemma rel_interior_Epigraph: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "(x,z) : rel_interior (Epigraph UNIV f) \ (x : rel_interior (domain f) \ f x < ereal z)" apply (subst rel_interior_projection[of _ "(\y. {z. (y, z) : Epigraph UNIV f})"]) apply (metis assms convex_EpigraphI convex_UNIV convex_on_ereal_univ) unfolding domain_Epigraph Epigraph_def using rel_interior_ereal_semiline by auto lemma rel_interior_EpigraphI: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "rel_interior (Epigraph UNIV f) = {(x,z) |x z. x : rel_interior (domain f) \ f x < ereal z}" proof- { fix x z have "(x,z):rel_interior (Epigraph UNIV f) \ (x : rel_interior (domain f) \ f x < ereal z)" using rel_interior_Epigraph[of f x z] assms by auto } thus ?thesis by auto qed lemma convex_less_ri_domain: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "\x. f x < a" shows "\x\rel_interior (domain f). f x < a" proof- define A where "A = {(x::'a::euclidean_space,m)|x m. ereal m ereal z < a" using ereal_dense2 by auto hence "(x,z):A \ (x,z):Epigraph UNIV f" unfolding A_def Epigraph_def by auto hence "A Int (Epigraph UNIV f) \ {}" unfolding A_def Epigraph_def using assms by auto moreover have "open A" proof(cases a) case real hence "A = {y. inner (0::'a, 1) y < real_of_ereal a}" using A_def by auto thus ?thesis using open_halfspace_lt by auto next case PInf thus ?thesis using A_def by auto next case MInf thus ?thesis using A_def by auto qed ultimately have "A Int rel_interior(Epigraph UNIV f) \ {}" by (metis assms(1) convex_Epigraph convex_UNIV open_Int_closure_eq_empty open_inter_closure_rel_interior) then obtain x0 z0 where "(x0,z0):A \ x0 : rel_interior (domain f) \ f x0 < ereal z0" using rel_interior_Epigraph[of f] assms by auto thus ?thesis apply(rule_tac x="x0" in bexI) using A_def by auto qed lemma rel_interior_eq_between: fixes S T :: "('m::euclidean_space) set" assumes "convex S" "convex T" shows "(rel_interior S = rel_interior T) \ (rel_interior S \ T \ T \ closure S)" by (metis assms closure_eq_between convex_closure_rel_interior convex_rel_interior_closure) lemma convex_less_in_riS: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "convex S" "rel_interior S \ domain f" assumes "\x\closure S. f x < a" shows "\x\rel_interior S. f x < a" proof- define g where "g x = (if x:closure S then (f x) else \)" for x hence "\x. g x < a" using assms by auto have convg: "convex_on UNIV g" unfolding g_def apply (subst convex_PInfty_outside) using assms convex_closure by auto hence *: "\x\rel_interior (domain g). g x < a" apply (subst convex_less_ri_domain) using assms g_def by auto have "convex (domain g)" by (metis convg convex_domain) moreover have "rel_interior S \ domain g \ domain g \ closure S" using g_def assms rel_interior_subset_closure unfolding domain_def by auto ultimately have "rel_interior (domain g) = rel_interior S" by (metis assms(2) rel_interior_eq_between) thus ?thesis by (metis "*" g_def less_ereal.simps(2)) qed lemma convex_less_inS: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "convex S" "S \ domain f" assumes "\x\closure S. f x < a" shows "\x\S. f x < a" using convex_less_in_riS[of f S a] rel_interior_subset[of S] assms by auto lemma convex_finite_geq_on_closure: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "convex S" "finite_on S f" assumes "\x\S. f x \ a" shows "\x\closure S. f x \ a" proof- have "S \ domain f" using assms unfolding finite_on_def domain_def by auto { assume "\(\x\closure S. f x \ a)" hence "\x\closure S. f x < a" by (simp add: not_le) hence False using convex_less_inS[of f S a] assms \S \ domain f\ by auto } thus ?thesis by auto qed lemma lsc_hull_of_convex_determined: fixes f g :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" "convex_on UNIV g" assumes "rel_interior (domain f) = rel_interior (domain g)" assumes "\x\rel_interior (domain f). f x = g x" shows "lsc_hull f = lsc_hull g" proof- have "rel_interior (Epigraph UNIV f) = rel_interior (Epigraph UNIV g)" apply (subst rel_interior_EpigraphI, metis assms)+ using assms by auto hence "closure (Epigraph UNIV f) = closure (Epigraph UNIV g)" by (metis assms convex_EpigraphI convex_UNIV convex_closure_rel_interior) thus ?thesis by (metis lsc_hull_expl) qed lemma domain_lsc_hull_between: fixes f :: "'a::euclidean_space \ ereal" shows "domain f \ domain (lsc_hull f) \ domain (lsc_hull f) \ closure (domain f)" proof- { fix x assume "x:domain f" hence "x:domain (lsc_hull f)" unfolding domain_def using lsc_hull_le[of f x] by auto } moreover { fix x assume "x:domain (lsc_hull f)" hence "min (f x) (Liminf (at x) f) < \" unfolding domain_def using lsc_hull_liminf_at[of f] by auto then obtain z where z_def: "min (f x) (Liminf (at x) f) < z \ z < \" by (metis dense) { fix e::real assume "e>0" hence "Inf (f ` ball x e) \ min (f x) (Liminf (at x) f)" unfolding min_Liminf_at apply (subst SUP_upper) by auto hence "\y. y \ ball x e \ f y \ z" using Inf_le_iff_less [of f "ball x e" "min (f x) (Liminf (at x) f)"] z_def by (auto simp add: Bex_def) hence "\y. dist x y < e \ y \ domain f" unfolding domain_def ball_def using z_def by auto } hence "x\closure(domain f)" unfolding closure_approachable by (auto simp add: dist_commute) } ultimately show ?thesis by auto qed lemma domain_vs_domain_lsc_hull: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "rel_interior(domain (lsc_hull f)) = rel_interior(domain f) \ closure(domain (lsc_hull f)) = closure(domain f) \ aff_dim(domain (lsc_hull f)) = aff_dim(domain f)" proof- have "convex (domain f)" by (metis assms convex_domain) moreover have "convex (domain (lsc_hull f))" by (metis assms convex_domain convex_lsc_hull) moreover have "rel_interior (domain f) \ domain (lsc_hull f) \ domain (lsc_hull f) \ closure (domain f)" by (metis domain_lsc_hull_between rel_interior_subset subset_trans) ultimately show ?thesis by (metis closure_eq_between rel_interior_aff_dim rel_interior_eq_between) qed lemma vertical_line_affine: fixes x :: "'a::euclidean_space" shows "affine {(x,m::real)|m. m:UNIV}" unfolding affine_def by (auto simp add: pth_8) lemma lsc_hull_of_convex_agrees_onRI: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "\x\rel_interior (domain f). (f x = (lsc_hull f) x)" proof- have cEpi: "convex (Epigraph UNIV f)" by (metis assms convex_EpigraphI convex_UNIV) { fix x assume x_def: "x : rel_interior (domain f)" hence "f x < \" unfolding domain_def using rel_interior_subset by auto then obtain r where r_def: "(x,r):rel_interior (Epigraph UNIV f)" using assms x_def rel_interior_Epigraph[of f x] by (metis ereal_dense2) define M where "M = {(x,m::real)|m. m:UNIV}" hence "affine M" using vertical_line_affine by auto moreover have "rel_interior (Epigraph UNIV f) Int M \ {}" using r_def M_def by auto ultimately have *: "closure (Epigraph UNIV f) Int M = closure (Epigraph UNIV f Int M)" using convex_affine_closure_Int[of "Epigraph UNIV f" M] cEpi by auto have "Epigraph UNIV f Int M = {x} \ {m. f x \ ereal m}" unfolding Epigraph_def M_def by auto moreover have "closed({x} \ {m. f x\ ereal m})" apply (subst closed_Times) using closed_ereal_semiline by auto ultimately have "{x} \ {m. f x \ ereal m} = closure (Epigraph UNIV f) Int M" by (metis "*" Int_commute closure_closed) also have "\=Epigraph UNIV (lsc_hull f) Int M" by (metis Int_commute epigraph_lsc_hull) also have "\={x} \ {m. ((lsc_hull f) x) \ ereal m}" unfolding Epigraph_def M_def by auto finally have "{m. f x \ ereal m} = {m. lsc_hull f x \ ereal m}" by auto hence "f x = (lsc_hull f) x" using ereal_semiline_unique by auto } thus ?thesis by auto qed lemma lsc_hull_of_convex_agrees_outside: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "\x. x \ closure (domain f) \ (f x = (lsc_hull f) x)" proof- { fix x assume "x \ closure (domain f)" hence "x \ domain (lsc_hull f)" using domain_lsc_hull_between by auto hence "(lsc_hull f) x = \" unfolding domain_def by auto hence "f x = (lsc_hull f) x" using lsc_hull_le[of f x] by auto } thus ?thesis by auto qed lemma lsc_hull_of_convex_agrees: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" shows "\x. (f x = (lsc_hull f) x) | x : rel_frontier (domain f)" by (metis DiffI assms lsc_hull_of_convex_agrees_onRI lsc_hull_of_convex_agrees_outside rel_frontier_def) lemma lsc_hull_of_proper_convex_proper: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" "proper f" shows "proper (lsc_hull f)" proof- obtain x where x_def: "x:rel_interior (domain f) \ f x < \" by (metis assms convex_less_ri_domain ereal_less_PInfty proper_iff) hence "f x = (lsc_hull f) x" using lsc_hull_of_convex_agrees[of f] assms unfolding rel_frontier_def by auto moreover have "f x > -\" using assms proper_iff by auto ultimately have "(lsc_hull f) x < \ \ (lsc_hull f) x > -\" using x_def by auto thus ?thesis using convex_lsc_improper[of "lsc_hull f" x] lsc_lsc_hull[of f] assms convex_lsc_hull[of f] by auto qed lemma lsc_hull_of_proper_convex: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" "proper f" shows "lsc (lsc_hull f) \ proper (lsc_hull f) \ convex_on UNIV (lsc_hull f) \ (\x. (f x = (lsc_hull f) x) | x : rel_frontier (domain f))" by (metis assms convex_lsc_hull lsc_hull_of_convex_agrees lsc_hull_of_proper_convex_proper lsc_lsc_hull) lemma affine_no_rel_frontier: fixes S :: "('n::euclidean_space) set" assumes "affine S" shows "rel_frontier S = {}" unfolding rel_frontier_def using assms affine_closed[of S] closure_closed[of S] affine_rel_open[of S] rel_open_def[of S] by auto lemma convex_with_affine_domain_is_lsc: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "affine (domain f)" shows "lsc f" by (metis assms affine_no_rel_frontier emptyE lsc_def lsc_hull_liminf_at lsc_hull_of_convex_agrees lsc_liminf_at_eq) lemma convex_finite_is_lsc: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "finite_on UNIV f" shows "lsc f" proof- have "affine (domain f)" using assms affine_UNIV unfolding finite_on_def domain_def by auto thus ?thesis by (metis assms(1) convex_with_affine_domain_is_lsc) qed lemma always_eventually_within: "(\x\S. P x) \ eventually P (at x within S)" unfolding eventually_at_filter by auto lemma ereal_divide_pos: assumes "(a::ereal)>0" "b>0" shows "a/(ereal b)>0" by (metis PInfty_eq_infinity assms ereal.simps(2) ereal_less(2) ereal_less_divide_pos ereal_mult_zero) lemma real_interval_limpt: assumes "a0 \ cball b e \ T" using open_contains_cball[of T] by auto hence "(b-e):cball b e" unfolding cball_def dist_norm by auto moreover { assume "a\b-e" hence "a:cball b e" unfolding cball_def dist_norm using \a by auto } ultimately have "max a (b-e):cball b e" by (metis max.absorb1 max.absorb2 linear) hence "max a (b-e):T" using e_def by auto moreover have "max a (b-e):{a..a by auto ultimately have "\y\{a.. y \ b" by auto } thus ?thesis unfolding islimpt_def by auto qed lemma lsc_hull_of_convex_aux: "Limsup (at 1 within {0..<1}) (\m. ereal ((1-m)*a+m*b)) \ ereal b" proof- have nontr: "~trivial_limit (at 1 within {0..< 1::real})" apply (subst trivial_limit_within) using real_interval_limpt by auto have "((\m. ereal ((1-m)*a+m*b)) \ (1 - 1) * a + 1 * b) (at 1 within {0..<1})" unfolding lim_ereal by (intro tendsto_intros) from lim_imp_Limsup[OF nontr this] show ?thesis by simp qed lemma lsc_hull_of_convex: fixes f :: "'a::euclidean_space \ ereal" assumes "convex_on UNIV f" assumes "x : rel_interior (domain f)" shows "((\m. f((1-m)*\<^sub>R x + m *\<^sub>R y)) \ (lsc_hull f) y) (at 1 within {0..<1})" (is "(?g \ _ y) _") proof (cases "y=x") case True hence "?g = (\m. f y)" by (simp add: algebra_simps) hence "(?g \ f y) (at 1 within {0..<1})" by simp moreover have "(lsc_hull f) y = f y" by (metis \y=x\ assms lsc_hull_of_convex_agrees_onRI) ultimately show ?thesis by auto next case False have aux: "\m. y - ((1 - m) *\<^sub>R x + m *\<^sub>R y) = (1-m)*\<^sub>R (y-x)" by (simp add: algebra_simps) have "(lsc_hull f) y = min (f y) (Liminf (at y) f)" by (metis lsc_hull_liminf_at) also have "\ \ Liminf (at 1 within {0..<1}) ?g" unfolding min_Liminf_at unfolding Liminf_within apply (subst SUP_mono) apply (rule_tac x="n/norm(y-x)" in bexI) apply (subst INF_mono) apply (rule_tac x="(1 - m) *\<^sub>R x + m *\<^sub>R y" in bexI) prefer 2 unfolding ball_def dist_norm by (auto simp add: aux \y\x\ less_divide_eq) finally have *: "(lsc_hull f) y \ Liminf (at 1 within {0..<1}) ?g" by auto { fix b assume "ereal b\(lsc_hull f) y" hence yb: "(y,b):closure(Epigraph UNIV f)" by (metis epigraph_lsc_hull mem_Epigraph UNIV_I) have "x : domain f" by (metis assms(2) rel_interior_subset rev_subsetD) hence "f x<\" unfolding domain_def by auto then obtain a where"ereal a>f x" by (metis ereal_dense2) hence xa: "(x,a):rel_interior(Epigraph UNIV f)" by (metis assms rel_interior_Epigraph) { fix m :: real assume "0 \ m \ m < 1" hence "(y, b) - (1-m) *\<^sub>R ((y, b) - (x, a)) : rel_interior (Epigraph UNIV f)" apply (subst rel_interior_closure_convex_shrink) apply (metis assms(1) convex_Epigraph convex_UNIV convex_on_ereal_univ) using yb xa by auto hence "f (y - (1-m) *\<^sub>R (y-x) ) < ereal (b-(1-m)*(b-a))" using assms(1) rel_interior_Epigraph by auto hence "?g m \ ereal ((1-m)*a+m*b)" by (simp add: algebra_simps) } hence "eventually (\m. ?g m \ ereal ((1-m)*a+m*b)) (at 1 within {0..<1})" apply (subst always_eventually_within) by auto hence "Limsup (at 1 within {0..<1}) ?g \ Limsup (at 1 within {0..<1}) (\m. ereal ((1-m)*a+m*b))" apply (subst Limsup_mono) by auto also have "\ \ ereal b" using lsc_hull_of_convex_aux by auto finally have "Limsup (at 1 within {0..<1}) ?g \ereal b" by auto } hence "Limsup (at 1 within {0..<1}) ?g \ (lsc_hull f) y" using ereal_le_real[of "(lsc_hull f) y"] by auto moreover have nontr: "~trivial_limit (at (1::real) within {0..<1})" apply (subst trivial_limit_within) using real_interval_limpt by auto moreover hence "Liminf (at 1 within {0..<1}) ?g \ Limsup (at 1 within {0..<1}) ?g" apply (subst Liminf_le_Limsup) by auto ultimately have "Limsup (at 1 within {0..<1}) ?g = (lsc_hull f) y \ Liminf (at 1 within {0..<1}) ?g = (lsc_hull f) y" using * by auto thus ?thesis apply (subst Liminf_eq_Limsup) using nontr by auto qed end diff --git a/thys/Ordinary_Differential_Equations/IVP/Reachability_Analysis.thy b/thys/Ordinary_Differential_Equations/IVP/Reachability_Analysis.thy --- a/thys/Ordinary_Differential_Equations/IVP/Reachability_Analysis.thy +++ b/thys/Ordinary_Differential_Equations/IVP/Reachability_Analysis.thy @@ -1,1030 +1,1030 @@ theory Reachability_Analysis imports Flow Poincare_Map begin lemma not_mem_eq_mem_not: "a \ A \ a \ - A" by auto lemma continuous_orderD: fixes g::"'b::t2_space \ 'c::order_topology" assumes "continuous (at x within S) g" shows "g x > c \ \\<^sub>F y in at x within S. g y > c" "g x < c \ \\<^sub>F y in at x within S. g y < c" using order_tendstoD[OF assms[unfolded continuous_within]] by auto lemma frontier_halfspace_component_ge: "n \ 0 \ frontier {x. c \ x \ n} = plane n c" apply (subst (1) inner_commute) apply (subst (2) inner_commute) apply (subst frontier_halfspace_ge[of n c]) by auto lemma closed_Collect_le_within: fixes f g :: "'a :: topological_space \ 'b::linorder_topology" assumes f: "continuous_on UNIV f" and g: "continuous_on UNIV g" and "closed R" shows "closed {x \ R. f x \ g x}" proof - have *: "- R \ {x. g x < f x} = - {x \ R. f x \ g x}" by auto have "open (-R)" using assms by auto from open_Un[OF this open_Collect_less [OF g f], unfolded *] show ?thesis by (simp add: closed_open) qed subsection \explicit representation of hyperplanes / halfspaces\ datatype 'a sctn = Sctn (normal: 'a) (pstn: real) definition "le_halfspace sctn x \ x \ normal sctn \ pstn sctn" definition "lt_halfspace sctn x \ x \ normal sctn < pstn sctn" definition "ge_halfspace sctn x \ x \ normal sctn \ pstn sctn" definition "gt_halfspace sctn x \ x \ normal sctn > pstn sctn" definition "plane_of sctn = {x. x \ normal sctn = pstn sctn}" definition "above_halfspace sctn = Collect (ge_halfspace sctn)" definition "below_halfspace sctn = Collect (le_halfspace sctn)" definition "sbelow_halfspace sctn = Collect (lt_halfspace sctn)" definition "sabove_halfspace sctn = Collect (gt_halfspace sctn)" subsection \explicit H representation of polytopes (mind \Polytopes.thy\)\ definition below_halfspaces where "below_halfspaces sctns = \(below_halfspace ` sctns)" definition sbelow_halfspaces where "sbelow_halfspaces sctns = \(sbelow_halfspace ` sctns)" definition above_halfspaces where "above_halfspaces sctns = \(above_halfspace ` sctns)" definition sabove_halfspaces where "sabove_halfspaces sctns = \(sabove_halfspace ` sctns)" lemmas halfspace_simps = above_halfspace_def sabove_halfspace_def below_halfspace_def sbelow_halfspace_def below_halfspaces_def sbelow_halfspaces_def above_halfspaces_def sabove_halfspaces_def ge_halfspace_def[abs_def] gt_halfspace_def[abs_def] le_halfspace_def[abs_def] lt_halfspace_def[abs_def] subsection \predicates for reachability analysis\ context c1_on_open_euclidean begin definition flowpipe :: "(('a::euclidean_space) \ ('a \\<^sub>L 'a)) set \ real \ real \ ('a \ ('a \\<^sub>L 'a)) set \ ('a \ ('a \\<^sub>L 'a)) set \ bool" where "flowpipe X0 hl hu CX X1 \ 0 \ hl \ hl \ hu \ fst ` X0 \ X \ fst ` CX \ X \ fst ` X1 \ X \ (\(x0, d0) \ X0. \h \ {hl .. hu}. h \ existence_ivl0 x0 \ (flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ X1 \ (\h' \ {0 .. h}. (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX))" lemma flowpipeD: assumes "flowpipe X0 hl hu CX X1" shows flowpipe_safeD: "fst ` X0 \ fst ` CX \ fst ` X1 \ X" and flowpipe_nonneg: "0 \ hl" "hl \ hu" and flowpipe_exivl: "hl \ h \ h \ hu \ (x0, d0) \ X0 \ h \ existence_ivl0 x0" and flowpipe_discrete: "hl \ h \ h \ hu \ (x0, d0) \ X0 \ (flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ X1" and flowpipe_cont: "hl \ h \ h \ hu \ (x0, d0) \ X0 \ 0 \ h' \ h' \ h \ (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX" using assms by (auto simp: flowpipe_def) lemma flowpipe_source_subset: "flowpipe X0 hl hu CX X1 \ X0 \ CX" apply (auto dest: bspec[where x=hl] bspec[where x=0] simp: flowpipe_def) apply (drule bspec) apply (assumption) apply auto apply (drule bspec[where x=hl]) apply auto apply (drule bspec[where x=0]) by (auto simp: flow_initial_time_if) definition "flowsto X0 T CX X1 \ (\(x0, d0) \ X0. \h \ T. h \ existence_ivl0 x0 \ (flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ X1 \ (\h' \ open_segment 0 h. (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX))" lemma flowsto_to_empty_iff[simp]: "flowsto a t b {} \ a = {}" by (auto simp: simp: flowsto_def) lemma flowsto_from_empty_iff[simp]: "flowsto {} t b c" by (auto simp: simp: flowsto_def) lemma flowsto_empty_time_iff[simp]: "flowsto a {} b c \ a = {}" by (auto simp: simp: flowsto_def) lemma flowstoE: assumes "flowsto X0 T CX X1" "(x0, d0) \ X0" obtains h where "h \ T" "h \ existence_ivl0 x0" "(flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ X1" "\h'. h' \ open_segment 0 h \ (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX" using assms by (auto simp: flowsto_def) lemma flowsto_safeD: "flowsto X0 T CX X1 \ fst ` X0 \ X" by (auto simp: flowsto_def split_beta' mem_existence_ivl_iv_defined) lemma flowsto_union: assumes 1: "flowsto X0 T CX Y" and 2: "flowsto Z S CZ W" shows "flowsto (X0 \ Z) (T \ S) (CX \ CZ) (Y \ W)" using assms unfolding flowsto_def by force lemma flowsto_subset: assumes "flowsto X0 T CX Y" assumes "Z \ X0" "T \ S" "CX \ CZ" "Y \ W" shows "flowsto Z S CZ W" unfolding flowsto_def using assms by (auto elim!: flowstoE) blast lemmas flowsto_unionI = flowsto_subset[OF flowsto_union] lemma flowsto_unionE: assumes "flowsto X0 T CX (Y \ Z)" obtains X1 X2 where "X0 = X1 \ X2" "flowsto X1 T CX Y" "flowsto X2 T CX Z" proof - let ?X1 = "{x\X0. flowsto {x} T CX Y}" let ?X2 = "{x\X0. flowsto {x} T CX Z}" from assms have "X0 = ?X1 \ ?X2" "flowsto ?X1 T CX Y" "flowsto ?X2 T CX Z" by (auto simp: flowsto_def) thus ?thesis .. qed lemma flowsto_trans: assumes A: "flowsto A S B C" and C: "flowsto C T D E" shows "flowsto A {s + t |s t. s \ S \ t \ T} (B \ D \ C) E" unfolding flowsto_def proof safe fix x0 d0 assume x0: "(x0, d0) \ A" from flowstoE[OF A x0] obtain h where h: "h \ S" "h \ existence_ivl0 x0" "(flow0 x0 h, (Dflow x0 h) o\<^sub>L d0) \ C" "\h'. h' \ {0<-- (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ B" by auto from h(2) have x0[simp]: "x0 \ X" by auto from flowstoE[OF C \_ \ C\] obtain i where i: "i \ T" "i \ existence_ivl0 (flow0 x0 h)" "(flow0 (flow0 x0 h) i, Dflow (flow0 x0 h) i o\<^sub>L Dflow x0 h o\<^sub>L d0) \ E" "\h'. h' \ {0<-- (flow0 (flow0 x0 h) h', Dflow (flow0 x0 h) h' o\<^sub>L (Dflow x0 h o\<^sub>L d0)) \ D" by (auto simp: ac_simps) have hi: "h + i \ existence_ivl0 x0" using \h \ existence_ivl0 x0\ \i \ existence_ivl0 (flow0 x0 h)\ existence_ivl_trans by blast moreover have "(flow0 x0 (h + i), Dflow x0 (h + i) o\<^sub>L d0) \ E" apply (subst flow_trans) apply fact apply fact apply (subst Dflow_trans) apply fact apply fact apply fact done moreover have "(flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ B \ D \ C" if "h'\{0<-- {0 <--< h}" then show ?thesis using h by simp next assume "h' \ {0 <--< h}" with that have h': "h' - h \ {0 <--< i}" if "h' \ h" using that by (auto simp: open_segment_eq_real_ivl closed_segment_eq_real_ivl split: if_splits) from i(4)[OF this] show ?thesis apply (cases "h' = h") subgoal using h by force subgoal apply simp apply (subst (asm) flow_trans[symmetric]) subgoal by (rule h) subgoal using \_ \ h' - h \ {0<-- i(2) local.in_existence_between_zeroI apply auto using open_closed_segment by blast subgoal unfolding blinfun_compose_assoc[symmetric] apply (subst (asm) Dflow_trans[symmetric]) apply auto apply fact+ done done done qed ultimately show "\h\{s + t |s t. s \ S \ t \ T}. h \ existence_ivl0 x0 \ (flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ E \ (\h'\{0<--L d0) \ B \ D \ C)" using \h \ S\ \i \ T\ by (auto intro!: bexI[where x="h + i"]) qed lemma flowsto_step: assumes A: "flowsto A S B C" assumes D: "flowsto D T E F" shows "flowsto A (S \ {s + t |s t. s \ S \ t \ T}) (B \ E \ C \ D) (C - D \ F)" proof - have "C = (C \ D) \ (C - D)" (is "_ = ?C1 \ ?C2") by auto then have "flowsto A S B (?C1 \ ?C2)" using A by simp from flowsto_unionE[OF this] obtain A1 A2 where "A = A1 \ A2" and A1: "flowsto A1 S B ?C1" and A2: "flowsto A2 S B ?C2" by auto have "flowsto ?C1 T E F" using D by (rule flowsto_subset) auto from flowsto_union[OF flowsto_trans[OF A1 this] A2] show ?thesis by (auto simp add: \A = _\ ac_simps) qed lemma flowsto_stepI: "flowsto X0 U B C \ flowsto D T E F \ Z \ X0 \ (\s. s \ U \ s \ S) \ (\s t. s \ U \ t \ T \ s + t \ S) \ B \ E \ D \ C \ CZ \ C - D \ F \ W \ flowsto Z S CZ W" by (rule flowsto_subset[OF flowsto_step]) auto lemma flowsto_imp_flowsto: "flowpipe Y h h CY Z \ flowsto Y {h} (CY) Z" unfolding flowpipe_def flowsto_def by (auto simp: open_segment_eq_real_ivl split_beta') lemma connected_below_halfspace: assumes "x \ below_halfspace sctn" assumes "x \ S" "connected S" assumes "S \ plane_of sctn = {}" shows "S \ below_halfspace sctn" proof - note \connected S\ moreover have "open {x. x \ normal sctn < pstn sctn}" (is "open ?X") and "open {x. x \ normal sctn > pstn sctn}" (is "open ?Y") by (auto intro!: open_Collect_less continuous_intros) - moreover have "S \ ?X \ ?Y" "?X \ ?Y \ S = {}" + moreover have "?X \ ?Y \ S = {}" "S \ ?X \ ?Y" using assms by (auto simp: plane_of_def) ultimately have "?X \ S = {} \ ?Y \ S = {}" by (rule connectedD) then show ?thesis using assms by (force simp: below_halfspace_def le_halfspace_def plane_of_def) qed lemma inter_Collect_eq_empty: assumes "\x. x \ X0 \ \ g x" shows "X0 \ Collect g = {}" using assms by auto subsection \Poincare Map\ lemma closed_plane_of[simp]: "closed (plane_of sctn)" by (auto simp: plane_of_def intro!: closed_Collect_eq continuous_intros) definition "poincare_mapsto P X0 S CX Y \ (\(x, d) \ X0. returns_to P x \ fst ` X0 \ S \ (return_time P differentiable at x within S) \ (\D. (poincare_map P has_derivative blinfun_apply D) (at x within S) \ (poincare_map P x, D o\<^sub>L d) \ Y) \ (\t\{0<.. CX))" lemma poincare_mapsto_empty[simp]: "poincare_mapsto P {} S CX Y" by (auto simp: poincare_mapsto_def) lemma flowsto_eventually_mem_cont: assumes "flowsto X0 T CX Y" "(x, d) \ X0" "T \ {0<..}" shows "\\<^sub>F t in at_right 0. (flow0 x t, Dflow x t o\<^sub>L d) \ CX" proof - from flowstoE[OF assms(1,2)] assms(3) obtain h where h: "0 < h" "h \ T" "h \ existence_ivl0 x" "(flow0 x h, (Dflow x h) o\<^sub>L d) \ Y" "\h'. h' \ {0<-- (flow0 x h', (Dflow x h') o\<^sub>L d) \ CX" by (auto simp: subset_iff) have "\\<^sub>F x in at_right 0. 0 < x \ x < h" apply (rule eventually_conj[OF eventually_at_right_less]) using eventually_at_right h(1) by blast then show ?thesis by eventually_elim (auto intro!: h simp: open_segment_eq_real_ivl) qed lemma frontier_aux_lemma: fixes R :: "'n::euclidean_space set" assumes "closed R" "R \ {x. x \ n = c}" and [simp]: "n \ 0" shows "frontier {x \ R. c \ x \ n} = {x \ R. c = x \ n}" apply (auto simp: frontier_closures) subgoal by (metis (full_types) Collect_subset assms(1) closure_minimal subsetD) subgoal premises prems for x proof - note prems have "closed {x \ R. c \ x \ n}" by (auto intro!: closed_Collect_le_within continuous_intros assms) from closure_closed[OF this] prems(1) have "x \ R" "c \ x \ n" by auto with assms show ?thesis by auto qed subgoal for x using closure_subset by fastforce subgoal premises prems for x proof - note prems have *: "{xa \ R. x \ n \ xa \ n} = R" using assms prems by auto have "interior R \ interior (plane n c)" by (rule interior_mono) (use assms in auto) also have "\ = {}" by (subst inner_commute) simp finally have R: "interior R = {}" by simp have "x \ closure (- R)" unfolding closure_complement by (auto simp: R) then show ?thesis unfolding * by simp qed done lemma blinfun_minus_comp_distrib: "(a - b) o\<^sub>L c = (a o\<^sub>L c) - (b o\<^sub>L c)" by (auto intro!: blinfun_eqI simp: blinfun.bilinear_simps) lemma flowpipe_split_at_above_halfspace: assumes "flowpipe X0 hl t CX Y" "fst ` X0 \ {x. x \ n \ c} = {}" and [simp]: "n \ 0" assumes cR: "closed R" and Rs: "R \ plane n c" assumes PDP: "\x d. (x, d) \ CX \ x \ n = c \ (x, d - (blinfun_scaleR_left (f (x)) o\<^sub>L (blinfun_scaleR_left (inverse (f x \ n)) o\<^sub>L (blinfun_inner_left n o\<^sub>L d)))) \ PDP" assumes PDP_nz: "\x d. (x, d) \ PDP \ f x \ n \ 0" assumes PDP_inR: "\x d. (x, d) \ PDP \ x \ R" assumes PDP_in: "\x d. (x, d) \ PDP \ \\<^sub>F x in at x within plane n c. x \ R" obtains X1 X2 where "X0 = X1 \ X2" "flowsto X1 {0<..t} (CX \ {x. x \ n < c} \ UNIV) (CX \ {x \ R. x \ n = c} \ UNIV)" "flowsto X2 {hl .. t} (CX \ {x. x \ n < c} \ UNIV) (Y \ ({x. x \ n < c} \ UNIV))" "poincare_mapsto {x \ R. x \ n = c} X1 UNIV (fst ` CX \ {x. x \ n < c}) PDP" proof - let ?sB = "{x. x \ n < c}" let ?A = "{x. x \ n \ c}" let ?P = "{x \ R. x \ n = c}" have [intro]: "closed ?A" "closed ?P" by (auto intro!: closed_Collect_le_within closed_levelset_within continuous_intros cR closed_halfspace_component_ge) let ?CX = "CX \ ?sB \ UNIV" let ?X1 = "{x\X0. flowsto {x} {0 <.. t} ?CX (CX \ (?P \ UNIV))}" let ?X2 = "{x\X0. flowsto {x} {hl .. t} ?CX (Y \ (?sB \ UNIV))}" have "(x, d) \ ?X1 \ (x, d) \ ?X2" if "(x, d) \ X0" for x d proof - from that assms have t: "t \ existence_ivl0 x" "\s. 0 \ s \ s \ t \ (flow0 x s, Dflow x s o\<^sub>L d) \ CX" "(flow0 x t, Dflow x t o\<^sub>L d) \ Y" apply (auto simp: flowpipe_def dest!: bspec[where x=t]) apply (drule bspec[where x="(x, d)"], assumption) apply simp apply (drule bspec[where x=t], force) apply auto done show ?thesis proof (cases "\s\{0..t}. flow0 x s \ ?sB") case True then have "(x, d) \ ?X2" using assms t \(x, d) \ X0\ by (auto simp: flowpipe_def flowsto_def open_segment_eq_real_ivl dest!: bspec[where x="(x, d)"]) then show ?thesis .. next case False then obtain s where s: "0 \ s" "s \ t" "flow0 x s \ ?A" by (auto simp: not_less) let ?I = "flow0 x -` ?A \ {0 .. s}" from s have exivlI: "0 \ s' \ s' \ s \ s' \ existence_ivl0 x" for s' using ivl_subset_existence_ivl[OF \t \ existence_ivl0 x\] by auto then have "compact ?I" unfolding compact_eq_bounded_closed by (intro conjI bounded_Int bounded_closed_interval disjI2 closed_vimage_Int) (auto intro!: continuous_intros closed_Collect_le_within cR) moreover from s have "?I \ {}" by auto ultimately have "\s\?I. \t\?I. s \ t" by (rule compact_attains_inf) then obtain s' where s': "\s''. 0 \ s'' \ s'' < s' \ flow0 x s'' \ ?A" "flow0 x s' \ ?A" "0 \ s'" "s' \ s" by (force simp: Ball_def) have "flow0 x 0 = x" using local.mem_existence_ivl_iv_defined(2) t(1) by auto also have "\ \ ?A" using assms \(x, d) \ X0\ by auto finally have "s' \ 0" using s' by auto then have "0 < s'" using \s' \ 0\ by simp have False if "flow0 x s' \ interior ?A" proof - from that obtain e where "e > 0" and subset: "ball (flow0 x s') e \ ?A" by (auto simp: mem_interior) from subset have "\\<^sub>F s'' in at_left s'. ball (flow0 x s') e \ ?A" by simp moreover from flow_continuous[OF exivlI[OF \0 \ s'\ \s' \ s\]] have "flow0 x \s'\ flow0 x s'" unfolding isCont_def . from tendstoD[OF this \0 < e\] have "\\<^sub>F xa in at_left s'. dist (flow0 x xa) (flow0 x s') < e" using eventually_at_split by blast then have "\\<^sub>F s'' in at_left s'. flow0 x s'' \ ball (flow0 x s') e" by (simp add: dist_commute) moreover have "\\<^sub>F s'' in at_left s'. 0 < s''" using \0 < s'\ using eventually_at_left by blast moreover have "\\<^sub>F s'' in at_left s'. s'' < s'" by (auto simp: eventually_at_filter) ultimately have "\\<^sub>F s'' in at_left s'. False" by eventually_elim (use s' in auto) then show False by auto qed then have "flow0 x s' \ frontier ?A" unfolding frontier_def using \closed ?A\ s' by auto with s' have "(x, d) \ ?X1" using assms that s t \0 < s'\ ivl_subset_existence_ivl[OF \t \ existence_ivl0 x\] frontier_subset_closed[OF \closed ?A\] apply (auto simp: flowsto_def flowpipe_def open_segment_eq_real_ivl frontier_halfspace_component_ge intro!: dest!: bspec[where x="(x, d)"] intro: exivlI) apply (safe intro!: bexI[where x=s']) subgoal by force subgoal premises prems proof - have CX: "(flow0 x s', Dflow x s' o\<^sub>L d) \ CX" using prems by (auto intro!: prems) have "flow0 x s' \ n = c" using prems by auto from PDP_inR[OF PDP[OF CX this]] show "flow0 x s' \ R" . qed subgoal by (auto simp: not_le) subgoal by force done then show ?thesis .. qed qed then have "X0 = ?X1 \ ?X2" by auto moreover have X1: "flowsto ?X1 {0 <.. t} ?CX (CX \ (?P \ UNIV))" and X2: "flowsto ?X2 {hl .. t} ?CX (Y \ (?sB \ UNIV))" by (auto simp: flowsto_def flowpipe_def) moreover from assms(2) X1 have "poincare_mapsto ?P ?X1 UNIV (fst ` CX \ {x. x \ n < c}) PDP" unfolding poincare_mapsto_def flowsto_def apply clarsimp subgoal premises prems for x d t proof - note prems have ret: "returns_to ?P x" apply (rule returns_to_outsideI[where t=t]) using prems \closed ?P\ by auto moreover have ret_le: "return_time ?P x \ t" apply (rule return_time_le[OF ret _ _ \0 < t\]) using prems \closed ?P\ by auto from prems have CX: "(flow0 x h', (Dflow x h') o\<^sub>L d) \ CX" if "0 < h'" "h' \ t" for h' using that by (auto simp: open_segment_eq_real_ivl) have PDP: "(poincare_map ?P x, Dpoincare_map' n c R x o\<^sub>L d) \ PDP" unfolding poincare_map_def Dpoincare_map'_def unfolding blinfun_compose_assoc blinfun_minus_comp_distrib apply (rule PDP) using poincare_map_returns[OF ret \closed ?P\] ret_le by (auto simp: poincare_map_def intro!: CX return_time_pos ret) have "eventually (returns_to ({x \ R. x \ n - c = 0})) (at x)" apply (rule eventually_returns_to) using PDP_nz[OF PDP] assms(2) \(x, d) \ X0\ cR PDP_in[OF PDP] by (auto intro!: ret derivative_eq_intros blinfun_inner_left.rep_eq[symmetric] simp: eventually_at_filter) moreover have "return_time ?P differentiable at x" apply (rule differentiableI) apply (rule return_time_plane_has_derivative) using prems ret PDP_nz[OF PDP] PDP cR PDP_in[OF PDP] by (auto simp: eventually_at_filter) moreover have "(\D. (poincare_map ?P has_derivative blinfun_apply D) (at x) \ (poincare_map ?P x, D o\<^sub>L d) \ PDP)" apply (intro exI[where x="Dpoincare_map' n c R x"]) using prems ret PDP_nz[OF PDP] PDP cR PDP_in[OF PDP] by (auto simp: eventually_at_filter intro!: poincare_map_plane_has_derivative) moreover have "flow0 x h \ fst ` CX \ (c > flow0 x h \ n)" if "0 < h" "h < return_time ?P x" for h using CX[of h] ret that ret_le \0 < h\ apply (auto simp: open_segment_eq_real_ivl intro!: image_eqI[where x="(flow0 x h, (Dflow x h) o\<^sub>L d)"]) using prems by (auto simp add: open_segment_eq_real_ivl dest!: bspec[where x=t]) ultimately show ?thesis unfolding prems(7)[symmetric] by force qed done ultimately show ?thesis .. qed lemma poincare_map_has_derivative_step: assumes Deriv: "(poincare_map P has_derivative blinfun_apply D) (at (flow0 x0 h))" assumes ret: "returns_to P x0" assumes cont: "continuous (at x0 within S) (return_time P)" assumes less: "0 \ h" "h < return_time P x0" assumes cP: "closed P" and x0: "x0 \ S" shows "((\x. poincare_map P x) has_derivative (D o\<^sub>L Dflow x0 h)) (at x0 within S)" proof (rule has_derivative_transform_eventually) note return_time_tendsto = cont[unfolded continuous_within, rule_format] have "return_time P x0 \ existence_ivl0 x0" by (auto intro!: return_time_exivl cP ret) from ivl_subset_existence_ivl[OF this] less have hex: "h \ existence_ivl0 x0" by auto from eventually_mem_existence_ivl[OF this] have "\\<^sub>F x in at x0 within S. h \ existence_ivl0 x" by (auto simp: eventually_at) moreover have "\\<^sub>F x in at x0 within S. h < return_time P x" apply (rule order_tendstoD) apply (rule return_time_tendsto) by (auto intro!: x0 less) moreover have evret: "eventually (returns_to P) (at x0 within S)" by (rule eventually_returns_to_continuousI; fact) ultimately show "\\<^sub>F x in at x0 within S. poincare_map P (flow0 x h) = poincare_map P x" apply eventually_elim apply (cases "h = 0") subgoal by auto subgoal for x apply (rule poincare_map_step_flow) using \0 \ h\ return_time_least[of P x ] by (auto simp: \closed P\) done show "poincare_map P (flow0 x0 h) = poincare_map P x0" using less ret x0 cP hex apply (cases "h = 0") subgoal by auto subgoal apply (rule poincare_map_step_flow) using \0 \ h\ return_time_least[of P x0] ret by (auto simp: \closed P\) done show "x0 \ S" by fact show "((\x. poincare_map P (flow0 x h)) has_derivative blinfun_apply (D o\<^sub>L Dflow x0 h)) (at x0 within S)" apply (rule has_derivative_compose[where g="poincare_map P" and f="\x. flow0 x h", OF _ Deriv, THEN has_derivative_eq_rhs]) by (auto intro!: derivative_eq_intros simp: hex flowderiv_def) qed lemma poincare_mapsto_trans: assumes "poincare_mapsto p1 X0 S CX P1" assumes "poincare_mapsto p2 P1 UNIV CY P2" assumes "CX \ CY \ fst ` P1 \ CZ" assumes "p2 \ (CX \ fst ` P1) = {}" assumes [intro, simp]: "closed p1" assumes [intro, simp]: "closed p2" assumes cont: "\x d. (x, d) \ X0 \ continuous (at x within S) (return_time p2)" shows "poincare_mapsto p2 X0 S CZ P2" unfolding poincare_mapsto_def proof (auto, goal_cases) fix x0 d0 assume x0: "(x0, d0) \ X0" from assms(1) x0 obtain D1 dR1 where 1: "returns_to p1 x0" "fst ` X0 \ S" "(return_time p1 has_derivative dR1) (at x0 within S)" "(poincare_map p1 has_derivative blinfun_apply D1) (at x0 within S)" "(poincare_map p1 x0, D1 o\<^sub>L d0) \ P1" "\t. 0 < t \ t < return_time p1 x0 \ flow0 x0 t \ CX" by (auto simp: poincare_mapsto_def differentiable_def) then have crt1: "continuous (at x0 within S) (return_time p1)" by (auto intro!: has_derivative_continuous) show "x0 \ S" using 1 x0 by auto let ?x0 = "poincare_map p1 x0" from assms(2) x0 \_ \ P1\ obtain D2 dR2 where 2: "returns_to p2 ?x0" "(return_time p2 has_derivative dR2) (at ?x0)" "(poincare_map p2 has_derivative blinfun_apply D2) (at ?x0)" "(poincare_map p2 ?x0, D2 o\<^sub>L (D1 o\<^sub>L d0)) \ P2" "\t. t\{0<.. flow0 ?x0 t \ CY" by (auto simp: poincare_mapsto_def differentiable_def) have "\\<^sub>F t in at_right 0. t < return_time p1 x0" by (rule order_tendstoD) (auto intro!: return_time_pos 1) moreover have "\\<^sub>F t in at_right 0. 0 < t" by (auto simp: eventually_at_filter) ultimately have evnotp2: "\\<^sub>F t in at_right 0. flow0 x0 t \ p2" by eventually_elim (use assms 1 in auto) from 2(1) show ret2: "returns_to p2 x0" unfolding poincare_map_def by (rule returns_to_earlierI) (use evnotp2 in \auto intro!: less_imp_le return_time_pos 1 return_time_exivl\) have not_p2: "0 < t \ t \ return_time p1 x0 \ flow0 x0 t \ p2" for t using 1(5) 1(6)[of t] assms(4) by (force simp: poincare_map_def set_eq_iff) have pm_eq: "poincare_map p2 x0 = poincare_map p2 (poincare_map p1 x0)" using not_p2 apply (auto simp: poincare_map_def) apply (subst flow_trans[symmetric]) apply (auto intro!: return_time_exivl 1 2[unfolded poincare_map_def]) apply (subst return_time_step) by (auto simp: return_time_step intro!: return_time_exivl 1 2[unfolded poincare_map_def] return_time_pos) have evret2: "\\<^sub>F x in at ?x0. returns_to p2 x" by (auto intro!: eventually_returns_to_continuousI 2 has_derivative_continuous) have evret1: "\\<^sub>F x in at x0 within S. returns_to p1 x" by (auto intro!: eventually_returns_to_continuousI 1 has_derivative_continuous) moreover from evret2[unfolded eventually_at_topological] 2(1) obtain U where U: "open U" "poincare_map p1 x0 \ U" "\x. x \ U \ returns_to p2 x" by force have "continuous (at x0 within S) (poincare_map p1)" by (rule has_derivative_continuous) (rule 1) note [tendsto_intros] = this[unfolded continuous_within] have "eventually (\x. poincare_map p1 x \ U) (at x0 within S)" by (rule topological_tendstoD) (auto intro!: tendsto_eq_intros U) then have evret_flow: "\\<^sub>F x in at x0 within S. returns_to p2 (flow0 x (return_time p1 x))" unfolding poincare_map_def[symmetric] apply eventually_elim apply (rule U) apply auto done moreover have h_less_rt: "return_time p1 x0 < return_time p2 x0" by (rule return_time_gt; fact) then have "0 < return_time p2 x0 - return_time p1 x0" by (simp ) from _ this have "\\<^sub>F x in at x0 within S. 0 < return_time p2 x - return_time p1 x" apply (rule order_tendstoD) using cont \(x0, _) \ _\ by (auto intro!: tendsto_eq_intros crt1 simp: continuous_within[symmetric] continuous_on_def) then have evpm2: "\\<^sub>F x in at x0 within S. \s. 0 < s \ s \ return_time p1 x \ flow0 x s \ p2" apply eventually_elim apply safe subgoal for x s using return_time_least[of p2 x s] by (auto simp add: return_time_pos_returns_to) done ultimately have pm_eq_at: "\\<^sub>F x in at x0 within S. poincare_map p2 (poincare_map p1 x) = poincare_map p2 x" apply (eventually_elim) apply (auto simp: poincare_map_def) apply (subst flow_trans[symmetric]) apply (auto intro!: return_time_exivl) apply (subst return_time_step) by (auto simp: return_time_step intro!: return_time_exivl return_time_pos) from _ this have "(poincare_map p2 has_derivative blinfun_apply (D2 o\<^sub>L D1)) (at x0 within S)" apply (rule has_derivative_transform_eventually) apply (rule has_derivative_compose[OF 1(4) 2(3), THEN has_derivative_eq_rhs]) by (auto simp: \x0 \ S\ pm_eq) moreover have "(poincare_map p2 x0, (D2 o\<^sub>L D1) o\<^sub>L d0) \ P2" using 2(4) unfolding pm_eq blinfun_compose_assoc . ultimately show "\D. (poincare_map p2 has_derivative blinfun_apply D) (at x0 within S) \ (poincare_map p2 x0, D o\<^sub>L d0) \ P2" by auto show "0 < t \ t < return_time p2 x0 \ flow0 x0 t \ CZ" for t apply (cases "t < return_time p1 x0") subgoal apply (drule 1) using assms by auto subgoal apply (cases "t = return_time p1 x0") subgoal using 1(5) assms by (auto simp: poincare_map_def) subgoal premises prems proof - have "flow0 x0 t = flow0 ?x0 (t - return_time p1 x0)" unfolding poincare_map_def apply (subst flow_trans[symmetric]) using prems by (auto simp: intro!: return_time_exivl 1 diff_existence_ivl_trans less_return_time_imp_exivl[OF _ ret2]) also have "\ \ CY" apply (rule 2) using prems apply auto using "1"(1) "2"(1) assms poincare_map_def ret2 return_time_exivl return_time_least return_time_pos return_time_step by auto also have "\ \ CZ" using assms by auto finally show "flow0 x0 t \ CZ" by simp qed done done have rt_eq: "return_time p2 (poincare_map p1 x0) + return_time p1 x0 = return_time p2 x0" apply (auto simp: poincare_map_def) apply (subst return_time_step) by (auto simp: return_time_step poincare_map_def[symmetric] not_p2 intro!: return_time_exivl return_time_pos 1 2) have evrt_eq: "\\<^sub>F x in at x0 within S. return_time p2 (poincare_map p1 x) + return_time p1 x = return_time p2 x" using evret_flow evret1 evpm2 apply (eventually_elim) apply (auto simp: poincare_map_def) apply (subst return_time_step) by (auto simp: return_time_step intro!: return_time_exivl return_time_pos) from _ evrt_eq have "(return_time p2 has_derivative (\x. dR2 (blinfun_apply D1 x) + dR1 x)) (at x0 within S)" by (rule has_derivative_transform_eventually) (auto intro!: derivative_eq_intros has_derivative_compose[OF 1(4) 2(2)] 1(3) \x0 \ S\ simp: rt_eq) then show "return_time p2 differentiable at x0 within S" by (auto intro!: differentiableI) qed lemma flowsto_poincare_trans:\ \TODO: the proof is close to @{thm poincare_mapsto_trans}\ assumes f: "flowsto X0 T CX P1" assumes "poincare_mapsto p2 P1 UNIV CY P2" assumes nn: "\t. t \ T \ t \ 0" assumes "fst ` CX \ CY \ fst ` P1 \ CZ" assumes "p2 \ (fst ` CX \ fst ` P1) = {}" assumes [intro, simp]: "closed p2" assumes cont: "\x d. (x, d) \ X0 \ continuous (at x within S) (return_time p2)" assumes subset: "fst ` X0 \ S" shows "poincare_mapsto p2 X0 S CZ P2" unfolding poincare_mapsto_def proof (auto, goal_cases) fix x0 d0 assume x0: "(x0, d0) \ X0" from flowstoE[OF f x0] obtain h where 1: "h \ T" "h \ existence_ivl0 x0" "(flow0 x0 h, Dflow x0 h o\<^sub>L d0) \ P1" (is "(?x0, _) \ _") "(\h'. h' \ {0<-- (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX)" by auto then have CX: "(\h'. 0 < h' \ h' < h \ (flow0 x0 h', Dflow x0 h' o\<^sub>L d0) \ CX)" by (auto simp: nn open_segment_eq_real_ivl) from 1 have "0 \ h" by (auto simp: nn) from assms have CX_p2D: "x \ CX \ fst x \ p2" for x by auto from assms have P1_p2D: "x \ P1 \ fst x \ p2" for x by auto show "x0 \ S" using x0 1 subset by auto let ?D1 = "Dflow x0 h" from assms(2) x0 \_ \ P1\ obtain D2 dR2 where 2: "returns_to p2 ?x0" "(return_time p2 has_derivative dR2) (at ?x0)" "(poincare_map p2 has_derivative blinfun_apply D2) (at ?x0)" "(poincare_map p2 ?x0, D2 o\<^sub>L (?D1 o\<^sub>L d0)) \ P2" "\t. t\{0<.. flow0 ?x0 t \ CY" by (auto simp: poincare_mapsto_def differentiable_def) { assume pos: "h > 0" have "\\<^sub>F t in at_right 0. t < h" by (rule order_tendstoD) (auto intro!: return_time_pos 1 pos) moreover have "\\<^sub>F t in at_right 0. 0 < t" by (auto simp: eventually_at_filter) ultimately have "\\<^sub>F t in at_right 0. flow0 x0 t \ p2" by eventually_elim (use assms in \force dest: CX CX_p2D\) } note evnotp2 = this from 2(1) show ret2: "returns_to p2 x0" apply (cases "h = 0") subgoal using 1 by auto unfolding poincare_map_def by (rule returns_to_earlierI) (use evnotp2 \0 \ h\ in \auto intro!: less_imp_le return_time_pos 1 return_time_exivl \) have not_p2: "0 < t \ t \ h \ flow0 x0 t \ p2" for t using 1(1-3) CX[of t] assms(4) CX_p2D P1_p2D by (cases "h = t") (auto simp: poincare_map_def set_eq_iff subset_iff) have pm_eq: "poincare_map p2 x0 = poincare_map p2 ?x0" apply (cases "h = 0", use 1 in force) using not_p2 \0 \ h\ apply (auto simp: poincare_map_def) apply (subst flow_trans[symmetric]) apply (auto intro!: return_time_exivl 1 2[unfolded poincare_map_def]) apply (subst return_time_step) by (auto simp: return_time_step intro!: return_time_exivl 1 2[unfolded poincare_map_def] return_time_pos) have evret2: "\\<^sub>F x in at ?x0. returns_to p2 x" by (auto intro!: eventually_returns_to_continuousI 2 has_derivative_continuous) have "\\<^sub>F x in at x0. h \ existence_ivl0 x" by (simp add: 1 eventually_mem_existence_ivl) then have evex: "\\<^sub>F x in at x0 within S. h \ existence_ivl0 x" by (auto simp: eventually_at) moreover from evret2[unfolded eventually_at_topological] 2(1) obtain U where U: "open U" "flow0 x0 h \ U" "\x. x \ U \ returns_to p2 x" by force note [tendsto_intros] = this[unfolded continuous_within] have "eventually (\x. flow0 x h \ U) (at x0 within S)" by (rule topological_tendstoD) (auto intro!: tendsto_eq_intros U 1) then have evret_flow: "\\<^sub>F x in at x0 within S. returns_to p2 (flow0 x h)" unfolding poincare_map_def[symmetric] apply eventually_elim apply (rule U) apply auto done moreover have h_less_rt: "h < return_time p2 x0" by (rule return_time_gt; fact) then have "0 < return_time p2 x0 - h" by (simp ) from _ this have "\\<^sub>F x in at x0 within S. 0 < return_time p2 x - h" apply (rule order_tendstoD) using cont \(x0, _) \ _\ by (auto intro!: tendsto_eq_intros simp: continuous_within[symmetric] continuous_on_def) then have evpm2: "\\<^sub>F x in at x0 within S. \s. 0 < s \ s \ h \ flow0 x s \ p2" apply eventually_elim apply safe subgoal for x s using return_time_least[of p2 x s] by (auto simp add: return_time_pos_returns_to) done ultimately have pm_eq_at: "\\<^sub>F x in at x0 within S. poincare_map p2 (flow0 x h) = poincare_map p2 x" apply (eventually_elim) apply (cases "h = 0") subgoal by auto apply (auto simp: poincare_map_def) apply (subst flow_trans[symmetric]) apply (auto intro!: return_time_exivl) apply (subst return_time_step) using \0 \ h\ by (auto simp: return_time_step intro!: return_time_exivl return_time_pos) from _ this have "(poincare_map p2 has_derivative blinfun_apply (D2 o\<^sub>L ?D1)) (at x0 within S)" apply (rule has_derivative_transform_eventually) apply (rule has_derivative_at_withinI) apply (rule has_derivative_compose[OF flow_has_space_derivative 2(3), THEN has_derivative_eq_rhs]) by (auto simp: \x0 \ S\ pm_eq 1) moreover have "(poincare_map p2 x0, (D2 o\<^sub>L ?D1) o\<^sub>L d0) \ P2" using 2(4) unfolding pm_eq blinfun_compose_assoc . ultimately show "\D. (poincare_map p2 has_derivative blinfun_apply D) (at x0 within S) \ (poincare_map p2 x0, D o\<^sub>L d0) \ P2" by auto show "0 < t \ t < return_time p2 x0 \ flow0 x0 t \ CZ" for t apply (cases "t < h") subgoal apply (drule CX) using assms by auto subgoal apply (cases "t = h") subgoal using 1 assms by (auto simp: poincare_map_def) subgoal premises prems proof - have "flow0 x0 t = flow0 ?x0 (t - h)" unfolding poincare_map_def apply (subst flow_trans[symmetric]) using prems by (auto simp: intro!: return_time_exivl 1 diff_existence_ivl_trans less_return_time_imp_exivl[OF _ ret2]) also have "\ \ CY" apply (cases "h = 0") subgoal using "1"(2) "2"(5) prems(1) prems(2) by auto subgoal apply (rule 2) using prems apply auto apply (subst return_time_step) apply (rule returns_to_laterI) using ret2 \0 \ h\ \h \ existence_ivl0 x0\ not_p2 by auto done also have "\ \ CZ" using assms by auto finally show "flow0 x0 t \ CZ" by simp qed done done have rt_eq: "return_time p2 ?x0 + h = return_time p2 x0" apply (cases "h = 0") subgoal using 1 by auto subgoal apply (subst return_time_step) using \0 \ h\ by (auto simp: return_time_step poincare_map_def[symmetric] not_p2 intro!: return_time_exivl return_time_pos 1 2) done have evrt_eq: "\\<^sub>F x in at x0 within S. return_time p2 (flow0 x h) + h = return_time p2 x" using evret_flow evpm2 evex apply (eventually_elim) apply (cases "h = 0") subgoal using 1 by auto subgoal apply (subst return_time_step) using \0 \ h\ by (auto simp: return_time_step intro!: return_time_exivl return_time_pos) done from _ evrt_eq have "(return_time p2 has_derivative (\x. dR2 (blinfun_apply ?D1 x))) (at x0 within S)" apply (rule has_derivative_transform_eventually) apply (rule has_derivative_at_withinI) by (auto intro!: derivative_eq_intros has_derivative_compose[OF flow_has_space_derivative 2(2)] 1 \x0 \ S\ simp: rt_eq) then show "return_time p2 differentiable at x0 within S" by (auto intro!: differentiableI) qed subsection \conditions for continuous return time\ definition "section s Ds S \ (\x. (s has_derivative blinfun_apply (Ds x)) (at x)) \ (\x. isCont Ds x) \ (\x \ S. s x = (0::real) \ Ds x (f x) \ 0) \ closed S \ S \ X" lemma sectionD: assumes "section s Ds S" shows "(s has_derivative blinfun_apply (Ds x)) (at x)" "isCont Ds x" "x \ S \ s x = 0 \ Ds x (f x) \ 0" "closed S" "S \ X" using assms by (auto simp: section_def) definition "transversal p \ (\x \ p. \\<^sub>F t in at_right 0. flow0 x t \ p)" lemma transversalD: "transversal p \ x \ p \ \\<^sub>F t in at_right 0. flow0 x t \ p" by (auto simp: transversal_def) lemma transversal_section: fixes c::real assumes "section s Ds S" shows "transversal {x \ S. s x = 0}" using assms unfolding section_def transversal_def proof (safe, goal_cases) case (1 x) then have "x \ X" by auto have "\\<^sub>F t in at_right 0. flow0 x t \ {xa \ S. s xa = 0}" by (rule flow_avoids_surface_eventually_at_right) (rule disjI2 assms 1[rule_format] refl \x \ X\)+ then show ?case by simp qed lemma section_closed[intro, simp]: "section s Ds S \ closed {x \ S. s x = 0}" by (auto intro!: closed_levelset_within simp: section_def intro!: has_derivative_continuous_on has_derivative_at_withinI[where s=S]) lemma return_time_continuous_belowI: assumes ft: "flowsto X0 T CX X1" assumes pos: "\t. t \ T \ t > 0" assumes X0: "fst ` X0 \ {x \ S. s x = 0}" assumes CX: "fst ` CX \ {x \ S. s x = 0} = {}" assumes X1: "fst ` X1 \ {x \ S. s x = 0}" assumes sec: "section s Ds S" assumes nz: "\x. x \ S \ s x = 0 \ Ds x (f x) \ 0" assumes Dneg: "(\x. (Ds x) (f x)) ` fst ` X0 \ {..<0}" assumes rel_int: "\x. x \ fst ` X1 \ \\<^sub>F x in at x. s x = 0 \ x \ S" assumes "(x, d) \ X0" shows "continuous (at x within {x. s x \ 0}) (return_time {x \ S. s x = 0})" proof (rule return_time_continuous_below) from assms have "x \ S" "s x = 0" "x \ {x \ S. s x = 0}" by auto note cs = section_closed[OF sec] note sectionD[OF sec] from flowstoE[OF ft \(x, d) \ X0\] obtain h where h: "h \ T" "h \ existence_ivl0 x" "(flow0 x h, Dflow x h o\<^sub>L d) \ X1" "(\h'. h' \ {0<-- (flow0 x h', Dflow x h' o\<^sub>L d) \ CX)" by blast show ret: "returns_to {x \ S. s x = 0} x" apply (rule returns_toI) apply (rule pos) apply (rule h) subgoal by (rule h) subgoal using h(3) X1 by auto subgoal apply (intro transversalD) apply (rule transversal_section) apply (rule sec) apply fact done subgoal by fact done show "(s has_derivative blinfun_apply (Ds x)) (at x)" for x by fact show "closed S" by fact show "isCont Ds x" for x by fact show "x \ S" "s x = 0" by fact+ let ?p = "poincare_map {x \ S. s x = 0} x" have "?p \ {x \ S. s x = 0}" using poincare_map_returns[OF ret cs] . with nz show "Ds ?p (f ?p) \ 0" by auto from Dneg \(x, _) \ X0\ show "Ds x (f x) < 0" by force from \_ \ X1\ X1 CX h have "return_time {x \ S. s x = 0} x = h" by (fastforce intro!: return_time_eqI cs pos h simp: open_segment_eq_real_ivl) then have "?p \ fst ` X1" using \_ \ X1\ by (force simp: poincare_map_def) from rel_int[OF this] show " \\<^sub>F x in at (poincare_map {x \ S. s x = 0} x). s x = 0 \ x \ S" by auto qed end end