diff --git a/thys/Hybrid_Systems_VCs/HS_ODEs.thy b/thys/Hybrid_Systems_VCs/HS_ODEs.thy --- a/thys/Hybrid_Systems_VCs/HS_ODEs.thy +++ b/thys/Hybrid_Systems_VCs/HS_ODEs.thy @@ -1,571 +1,636 @@ (* Title: ODEs and Dynamical Systems for HS verification Author: Jonathan Julián Huerta y Munive, 2019 Maintainer: Jonathan Julián Huerta y Munive *) section \ Ordinary Differential Equations \ text \Vector fields @{text "f::real \ 'a \ ('a::real_normed_vector)"} represent systems of ordinary differential equations (ODEs). Picard-Lindeloef's theorem guarantees existence and uniqueness of local solutions to initial value problems involving Lipschitz continuous vector fields. A (local) flow @{text "\::real \ 'a \ ('a::real_normed_vector)"} for such a system is the function that maps initial conditions to their unique solutions. In dynamical systems, the set of all points @{text "\ t s::'a"} for a fixed @{text "s::'a"} is the flow's orbit. If the orbit of each @{text "s \ I"} is conatined in @{text I}, then @{text I} is an invariant set of this system. This section formalises these concepts with a focus on hybrid systems (HS) verification.\ theory HS_ODEs imports "HS_Preliminaries" begin subsection \ Initial value problems and orbits \ notation image ("\

") lemma image_le_pred[simp]: "(\

f A \ {s. G s}) = (\x\A. G (f x))" unfolding image_def by force definition ivp_sols :: "(real \ 'a \ ('a::real_normed_vector)) \ real set \ 'a set \ real \ 'a \ (real \ 'a) set" ("Sols") where "Sols f T S t\<^sub>0 s = {X |X. (D X = (\t. f t (X t)) on T) \ X t\<^sub>0 = s \ X \ T \ S}" lemma ivp_solsI: assumes "D X = (\t. f t (X t)) on T" "X t\<^sub>0 = s" "X \ T \ S" shows "X \ Sols f T S t\<^sub>0 s" using assms unfolding ivp_sols_def by blast lemma ivp_solsD: assumes "X \ Sols f T S t\<^sub>0 s" shows "D X = (\t. f t (X t)) on T" and "X t\<^sub>0 = s" and "X \ T \ S" using assms unfolding ivp_sols_def by auto abbreviation "down T t \ {\\T. \\ t}" definition g_orbit :: "(('a::ord) \ 'b) \ ('b \ bool) \ 'a set \ 'b set" ("\") where "\ X G T = \{\

X (down T t) |t. \

X (down T t) \ {s. G s}}" lemma g_orbit_eq: fixes X::"('a::preorder) \ 'b" shows "\ X G T = {X t |t. t \ T \ (\\\down T t. G (X \))}" unfolding g_orbit_def apply safe using le_left_mono by blast auto definition g_orbital :: "('a \ 'a) \ ('a \ bool) \ real set \ 'a set \ real \ ('a::real_normed_vector) \ 'a set" where "g_orbital f G T S t\<^sub>0 s = \{\ X G T |X. X \ ivp_sols (\t. f) T S t\<^sub>0 s}" lemma g_orbital_eq: "g_orbital f G T S t\<^sub>0 s = {X t |t X. t \ T \ \

X (down T t) \ {s. G s} \ X \ Sols (\t. f) T S t\<^sub>0 s }" unfolding g_orbital_def ivp_sols_def g_orbit_eq image_le_pred by auto lemma g_orbitalI: assumes "X \ Sols (\t. f) T S t\<^sub>0 s" and "t \ T" and "(\

X (down T t) \ {s. G s})" shows "X t \ g_orbital f G T S t\<^sub>0 s" using assms unfolding g_orbital_eq(1) by auto lemma g_orbitalD: assumes "s' \ g_orbital f G T S t\<^sub>0 s" obtains X and t where "X \ Sols (\t. f) T S t\<^sub>0 s" and "X t = s'" and "t \ T" and "(\

X (down T t) \ {s. G s})" using assms unfolding g_orbital_def g_orbit_eq by auto no_notation g_orbit ("\") subsection \ Differential Invariants \ definition diff_invariant :: "('a \ bool) \ (('a::real_normed_vector) \ 'a) \ real set \ 'a set \ real \ ('a \ bool) \ bool" where "diff_invariant I f T S t\<^sub>0 G \ (\ \ (\

(g_orbital f G T S t\<^sub>0))) {s. I s} \ {s. I s}" lemma diff_invariant_eq: "diff_invariant I f T S t\<^sub>0 G = (\s. I s \ (\X\Sols (\t. f) T S t\<^sub>0 s. (\t\T.(\\\(down T t). G (X \)) \ I (X t))))" unfolding diff_invariant_def g_orbital_eq image_le_pred by auto lemma diff_inv_eq_inv_set: "diff_invariant I f T S t\<^sub>0 G = (\s. I s \ (g_orbital f G T S t\<^sub>0 s) \ {s. I s})" unfolding diff_invariant_eq g_orbital_eq image_le_pred by auto named_theorems diff_invariant_rules "rules for certifying differential invariants." lemma diff_invariant_eq_rule [diff_invariant_rules]: assumes Thyp: "is_interval T" "t\<^sub>0 \ T" and "\X. (D X = (\\. f (X \)) on T) \ (D (\\. \ (X \) - \ (X \)) = ((*\<^sub>R) 0) on T)" shows "diff_invariant (\s. \ s = \ s) f T S t\<^sub>0 G" proof(simp add: diff_invariant_eq ivp_sols_def, clarsimp) fix X \ assume tHyp:"\ \ T" and x_ivp:"D X = (\\. f (X \)) on T" "\ (X t\<^sub>0) = \ (X t\<^sub>0)" hence obs1: "\t\T. D (\\. \ (X \) - \ (X \)) \ (\\. \ *\<^sub>R 0) at t within T" using assms by (auto simp: has_vderiv_on_def has_vector_derivative_def) have obs2: "{t\<^sub>0--\} \ T" using closed_segment_subset_interval tHyp Thyp by blast hence "D (\\. \ (X \) - \ (X \)) = (\\. \ *\<^sub>R 0) on {t\<^sub>0--\}" using obs1 x_ivp by (auto intro!: has_derivative_subset[OF _ obs2] simp: has_vderiv_on_def has_vector_derivative_def) then obtain t where "t \ {t\<^sub>0--\}" and "\ (X \) - \ (X \) - (\ (X t\<^sub>0) - \ (X t\<^sub>0)) = (\ - t\<^sub>0) * t *\<^sub>R 0" using mvt_very_simple_closed_segmentE by blast thus "\ (X \) = \ (X \)" by (simp add: x_ivp(2)) qed lemma diff_invariant_leq_rule [diff_invariant_rules]: fixes \::"'a::banach \ real" assumes Thyp: "is_interval T" "t\<^sub>0 \ T" and "\X. (D X = (\\. f (X \)) on T) \ (\\\T. (\ > t\<^sub>0 \ \' (X \) \ \' (X \)) \ (\ < t\<^sub>0 \ \' (X \) \ \' (X \))) \ (D (\\. \ (X \) - \ (X \)) = (\\. \' (X \) - \' (X \)) on T)" shows "diff_invariant (\s. \ s \ \ s) f T S t\<^sub>0 G" proof(simp add: diff_invariant_eq ivp_sols_def, clarsimp) fix X \ assume "\ \ T" and x_ivp:"D X = (\\. f (X \)) on T" "\ (X t\<^sub>0) \ \ (X t\<^sub>0)" {assume "\ \ t\<^sub>0" hence primed: "\\. \ \ T \ \ > t\<^sub>0 \ \' (X \) \ \' (X \)" "\\. \ \ T \ \ < t\<^sub>0 \ \' (X \) \ \' (X \)" using x_ivp assms by auto have obs1: "\t\T. D (\\. \ (X \) - \ (X \)) \ (\\. \ *\<^sub>R (\' (X t) - \' (X t))) at t within T" using assms x_ivp by (auto simp: has_vderiv_on_def has_vector_derivative_def) have obs2: "{t\<^sub>0<--<\} \ T" "{t\<^sub>0--\} \ T" using \\ \ T\ Thyp \\ \ t\<^sub>0\ by (auto simp: convex_contains_open_segment is_interval_convex_1 closed_segment_subset_interval) hence "D (\\. \ (X \) - \ (X \)) = (\\. \' (X \) - \' (X \)) on {t\<^sub>0--\}" using obs1 x_ivp by (auto intro!: has_derivative_subset[OF _ obs2(2)] simp: has_vderiv_on_def has_vector_derivative_def) then obtain t where "t \ {t\<^sub>0<--<\}" and "(\ (X \) - \ (X \)) - (\ (X t\<^sub>0) - \ (X t\<^sub>0)) = (\\. \ * (\' (X t) - \' (X t))) (\ - t\<^sub>0)" using mvt_simple_closed_segmentE \\ \ t\<^sub>0\ by blast hence mvt: "\ (X \) - \ (X \) = (\ - t\<^sub>0) * (\' (X t) - \' (X t)) + (\ (X t\<^sub>0) - \ (X t\<^sub>0))" by force have "\ > t\<^sub>0 \ t > t\<^sub>0" "\ t\<^sub>0 \ \ \ t < t\<^sub>0" "t \ T" using \t \ {t\<^sub>0<--<\}\ obs2 unfolding open_segment_eq_real_ivl by auto moreover have "t > t\<^sub>0 \ (\' (X t) - \' (X t)) \ 0" "t < t\<^sub>0 \ (\' (X t) - \' (X t)) \ 0" using primed(1,2)[OF \t \ T\] by auto ultimately have "(\ - t\<^sub>0) * (\' (X t) - \' (X t)) \ 0" apply(case_tac "\ \ t\<^sub>0") by (force, auto simp: split_mult_pos_le) hence "(\ - t\<^sub>0) * (\' (X t) - \' (X t)) + (\ (X t\<^sub>0) - \ (X t\<^sub>0)) \ 0" using x_ivp(2) by auto hence "\ (X \) \ \ (X \)" using mvt by simp} thus "\ (X \) \ \ (X \)" using x_ivp by blast qed lemma diff_invariant_less_rule [diff_invariant_rules]: fixes \::"'a::banach \ real" assumes Thyp: "is_interval T" "t\<^sub>0 \ T" and "\ X. (D X = (\\. f (X \)) on T) \ (\\\T. (\ > t\<^sub>0 \ \' (X \) \ \' (X \)) \ (\ < t\<^sub>0 \ \' (X \) \ \' (X \))) \ (D (\\. \ (X \) - \ (X \)) = (\\. \' (X \) - \' (X \)) on T)" shows "diff_invariant (\s. \ s < \ s) f T S t\<^sub>0 G" proof(simp add: diff_invariant_eq ivp_sols_def, clarsimp) fix X \ assume "\ \ T" and x_ivp:"D X = (\\. f (X \)) on T" "\ (X t\<^sub>0) < \ (X t\<^sub>0)" {assume "\ \ t\<^sub>0" hence primed: "\\. \ \ T \ \ > t\<^sub>0 \ \' (X \) \ \' (X \)" "\\. \ \ T \ \ < t\<^sub>0 \ \' (X \) \ \' (X \)" using x_ivp assms by auto have obs1: "\t\T. D (\\. \ (X \) - \ (X \)) \ (\\. \ *\<^sub>R (\' (X t) - \' (X t))) at t within T" using assms x_ivp by (auto simp: has_vderiv_on_def has_vector_derivative_def) have obs2: "{t\<^sub>0<--<\} \ T" "{t\<^sub>0--\} \ T" using \\ \ T\ Thyp \\ \ t\<^sub>0\ by (auto simp: convex_contains_open_segment is_interval_convex_1 closed_segment_subset_interval) hence "D (\\. \ (X \) - \ (X \)) = (\\. \' (X \) - \' (X \)) on {t\<^sub>0--\}" using obs1 x_ivp by (auto intro!: has_derivative_subset[OF _ obs2(2)] simp: has_vderiv_on_def has_vector_derivative_def) then obtain t where "t \ {t\<^sub>0<--<\}" and "(\ (X \) - \ (X \)) - (\ (X t\<^sub>0) - \ (X t\<^sub>0)) = (\\. \ * (\' (X t) - \' (X t))) (\ - t\<^sub>0)" using mvt_simple_closed_segmentE \\ \ t\<^sub>0\ by blast hence mvt: "\ (X \) - \ (X \) = (\ - t\<^sub>0) * (\' (X t) - \' (X t)) + (\ (X t\<^sub>0) - \ (X t\<^sub>0))" by force have "\ > t\<^sub>0 \ t > t\<^sub>0" "\ t\<^sub>0 \ \ \ t < t\<^sub>0" "t \ T" using \t \ {t\<^sub>0<--<\}\ obs2 unfolding open_segment_eq_real_ivl by auto moreover have "t > t\<^sub>0 \ (\' (X t) - \' (X t)) \ 0" "t < t\<^sub>0 \ (\' (X t) - \' (X t)) \ 0" using primed(1,2)[OF \t \ T\] by auto ultimately have "(\ - t\<^sub>0) * (\' (X t) - \' (X t)) \ 0" apply(case_tac "\ \ t\<^sub>0") by (force, auto simp: split_mult_pos_le) hence "(\ - t\<^sub>0) * (\' (X t) - \' (X t)) + (\ (X t\<^sub>0) - \ (X t\<^sub>0)) > 0" using x_ivp(2) by auto hence "\ (X \) < \ (X \)" using mvt by simp} thus "\ (X \) < \ (X \)" using x_ivp by blast qed +lemma diff_invariant_nleq_rule: + fixes \::"'a::banach \ real" + shows "diff_invariant (\s. \ \ s \ \ s) f T S t\<^sub>0 G \ diff_invariant (\s. \ s > \ s) f T S t\<^sub>0 G" + unfolding diff_invariant_eq apply safe + by (clarsimp, erule_tac x=s in allE, simp, erule_tac x=X in ballE, force, force)+ + +lemma diff_invariant_neq_rule [diff_invariant_rules]: + fixes \::"'a::banach \ real" + assumes "diff_invariant (\s. \ s < \ s) f T S t\<^sub>0 G" + and "diff_invariant (\s. \ s > \ s) f T S t\<^sub>0 G" + shows "diff_invariant (\s. \ s \ \ s) f T S t\<^sub>0 G" +proof(unfold diff_invariant_eq, clarsimp) + fix s::'a and X::"real \ 'a" and t::real + assume "\ s \ \ s" and Xhyp: "X \ Sols (\t. f) T S t\<^sub>0 s" + and thyp: "t \ T" and Ghyp: "\\. \ \ T \ \ \ t \ G (X \)" + hence "\ s < \ s \ \ s > \ s" + by linarith + moreover have "\ s < \ s \ \ (X t) < \ (X t)" + using assms(1) Xhyp thyp Ghyp unfolding diff_invariant_eq by auto + moreover have "\ s > \ s \ \ (X t) > \ (X t)" + using assms(2) Xhyp thyp Ghyp unfolding diff_invariant_eq by auto + ultimately show "\ (X t) = \ (X t) \ False" + by auto +qed + +lemma diff_invariant_neq_rule_converse: + fixes \::"'a::banach \ real" + assumes Thyp: "is_interval T" "t\<^sub>0 \ T" "\t\T. t\<^sub>0 \ t" + and conts: "\X. (D X = (\\. f (X \)) on T) \ + continuous_on (\

X T) \ \ continuous_on (\

X T) \" + and dIhyp:"diff_invariant (\s. \ s \ \ s) f T S t\<^sub>0 G" + shows "diff_invariant (\s. \ s < \ s) f T S t\<^sub>0 G" +proof(unfold diff_invariant_eq, clarsimp) + fix s::'a and X::"real \ 'a" and t::real + assume ineq0: "\ s < \ s" and Xhyp: "X \ Sols (\t. f) T S t\<^sub>0 s" + and Ghyp: "\\. \ \ T \ \ \ t \ G (X \)" and thyp: "t\T" + hence ineq1: "\ (X t\<^sub>0) < \ (X t\<^sub>0)" + by (auto simp: ivp_solsD) + have "t\<^sub>0 \ t" and "\ (X t) \ \ (X t)" + using \t \ T\ Thyp dIhyp thyp Xhyp Ghyp ineq0 + unfolding diff_invariant_eq by force+ + moreover + {assume ineq2:"\ (X t) > \ (X t)" + note continuous_on_compose[OF vderiv_on_continuous_on[OF ivp_solsD(1)[OF Xhyp]]] + hence "continuous_on T (\ \ X)" and "continuous_on T (\ \ X)" + using ivp_solsD(1)[OF Xhyp] conts by auto + also have "{t\<^sub>0--t} \ T" + using Thyp thyp by (simp add: closed_segment_subset_interval) + ultimately have "continuous_on {t\<^sub>0--t} (\\. \ (X \))" + and "continuous_on {t\<^sub>0--t} (\\. \ (X \))" + using continuous_on_subset by auto + then obtain \ where "\ \ {t\<^sub>0--t}" "\ (X \) = \ (X \)" + using IVT_two_functions_real_ivl[OF _ _ ineq1 ineq2] by force + hence "\r\down T \. G (X r)" and "\ \ T" + using Ghyp \\ \ {t\<^sub>0--t}\ \t\<^sub>0 \ t\ \{t\<^sub>0--t} \ T\ + by (auto simp: closed_segment_eq_real_ivl) + hence "\ (X \) \ \ (X \)" + using dIhyp Xhyp \\ s < \ s\ + unfolding diff_invariant_eq by force + hence "False" + using \\ (X \) = \ (X \)\ by blast} + ultimately show "\ (X t) < \ (X t)" + by fastforce +qed + lemma diff_invariant_conj_rule [diff_invariant_rules]: assumes "diff_invariant I\<^sub>1 f T S t\<^sub>0 G" and "diff_invariant I\<^sub>2 f T S t\<^sub>0 G" shows "diff_invariant (\s. I\<^sub>1 s \ I\<^sub>2 s) f T S t\<^sub>0 G" using assms unfolding diff_invariant_def by auto lemma diff_invariant_disj_rule [diff_invariant_rules]: assumes "diff_invariant I\<^sub>1 f T S t\<^sub>0 G" and "diff_invariant I\<^sub>2 f T S t\<^sub>0 G" shows "diff_invariant (\s. I\<^sub>1 s \ I\<^sub>2 s) f T S t\<^sub>0 G" using assms unfolding diff_invariant_def by auto subsection \ Picard-Lindeloef \ text\ A locale with the assumptions of Picard-Lindeloef theorem. It extends @{term "ll_on_open_it"} by providing an initial time @{term "t\<^sub>0 \ T"}.\ locale picard_lindeloef = fixes f::"real \ ('a::{heine_borel,banach}) \ 'a" and T::"real set" and S::"'a set" and t\<^sub>0::real assumes open_domain: "open T" "open S" and interval_time: "is_interval T" and init_time: "t\<^sub>0 \ T" and cont_vec_field: "\s \ S. continuous_on T (\t. f t s)" and lipschitz_vec_field: "local_lipschitz T S f" begin sublocale ll_on_open_it T f S t\<^sub>0 by (unfold_locales) (auto simp: cont_vec_field lipschitz_vec_field interval_time open_domain) lemmas subintervalI = closed_segment_subset_domain lemma csols_eq: "csols t\<^sub>0 s = {(X, t). t \ T \ X \ Sols f {t\<^sub>0--t} S t\<^sub>0 s}" unfolding ivp_sols_def csols_def solves_ode_def using subintervalI[OF init_time] by auto abbreviation "ex_ivl s \ existence_ivl t\<^sub>0 s" lemma unique_solution: assumes xivp: "D X = (\t. f t (X t)) on {t\<^sub>0--t}" "X t\<^sub>0 = s" "X \ {t\<^sub>0--t} \ S" and "t \ T" and yivp: "D Y = (\t. f t (Y t)) on {t\<^sub>0--t}" "Y t\<^sub>0 = s" "Y \ {t\<^sub>0--t} \ S" and "s \ S" shows "X t = Y t" proof- have "(X, t) \ csols t\<^sub>0 s" using xivp \t \ T\ unfolding csols_eq ivp_sols_def by auto hence ivl_fact: "{t\<^sub>0--t} \ ex_ivl s" unfolding existence_ivl_def by auto have obs: "\z T'. t\<^sub>0 \ T' \ is_interval T' \ T' \ ex_ivl s \ (z solves_ode f) T' S \ z t\<^sub>0 = flow t\<^sub>0 s t\<^sub>0 \ (\t\T'. z t = flow t\<^sub>0 s t)" using flow_usolves_ode[OF init_time \s \ S\] unfolding usolves_ode_from_def by blast have "\\\{t\<^sub>0--t}. X \ = flow t\<^sub>0 s \" using obs[of "{t\<^sub>0--t}" X] xivp ivl_fact flow_initial_time[OF init_time \s \ S\] unfolding solves_ode_def by simp also have "\\\{t\<^sub>0--t}. Y \ = flow t\<^sub>0 s \" using obs[of "{t\<^sub>0--t}" Y] yivp ivl_fact flow_initial_time[OF init_time \s \ S\] unfolding solves_ode_def by simp ultimately show "X t = Y t" by auto qed lemma solution_eq_flow: assumes xivp: "D X = (\t. f t (X t)) on ex_ivl s" "X t\<^sub>0 = s" "X \ ex_ivl s \ S" and "t \ ex_ivl s" and "s \ S" shows "X t = flow t\<^sub>0 s t" proof- have obs: "\z T'. t\<^sub>0 \ T' \ is_interval T' \ T' \ ex_ivl s \ (z solves_ode f) T' S \ z t\<^sub>0 = flow t\<^sub>0 s t\<^sub>0 \ (\t\T'. z t = flow t\<^sub>0 s t)" using flow_usolves_ode[OF init_time \s \ S\] unfolding usolves_ode_from_def by blast have "\\\ex_ivl s. X \ = flow t\<^sub>0 s \" using obs[of "ex_ivl s" X] existence_ivl_initial_time[OF init_time \s \ S\] xivp flow_initial_time[OF init_time \s \ S\] unfolding solves_ode_def by simp thus "X t = flow t\<^sub>0 s t" by (auto simp: \t \ ex_ivl s\) qed end lemma local_lipschitz_add: fixes f1 f2 :: "real \ 'a::banach \ 'a" assumes "local_lipschitz T S f1" and "local_lipschitz T S f2" shows "local_lipschitz T S (\t s. f1 t s + f2 t s)" proof(unfold local_lipschitz_def, clarsimp) fix s and t assume "s \ S" and "t \ T" obtain \\<^sub>1 L1 where "\\<^sub>1 > 0" and L1: "\\. \\cball t \\<^sub>1 \ T \ L1-lipschitz_on (cball s \\<^sub>1 \ S) (f1 \)" using local_lipschitzE[OF assms(1) \t \ T\ \s \ S\] by blast obtain \\<^sub>2 L2 where "\\<^sub>2 > 0" and L2: "\\. \\cball t \\<^sub>2 \ T \ L2-lipschitz_on (cball s \\<^sub>2 \ S) (f2 \)" using local_lipschitzE[OF assms(2) \t \ T\ \s \ S\] by blast have ballH: "cball s (min \\<^sub>1 \\<^sub>2) \ S \ cball s \\<^sub>1 \ S" "cball s (min \\<^sub>1 \\<^sub>2) \ S \ cball s \\<^sub>2 \ S" by auto have obs1: "\\\cball t \\<^sub>1 \ T. L1-lipschitz_on (cball s (min \\<^sub>1 \\<^sub>2) \ S) (f1 \)" using lipschitz_on_subset[OF L1 ballH(1)] by blast also have obs2: "\\\cball t \\<^sub>2 \ T. L2-lipschitz_on (cball s (min \\<^sub>1 \\<^sub>2) \ S) (f2 \)" using lipschitz_on_subset[OF L2 ballH(2)] by blast ultimately have "\\\cball t (min \\<^sub>1 \\<^sub>2) \ T. (L1 + L2)-lipschitz_on (cball s (min \\<^sub>1 \\<^sub>2) \ S) (\s. f1 \ s + f2 \ s)" using lipschitz_on_add by fastforce thus "\u>0. \L. \t\cball t u \ T. L-lipschitz_on (cball s u \ S) (\s. f1 t s + f2 t s)" apply(rule_tac x="min \\<^sub>1 \\<^sub>2" in exI) using \\\<^sub>1 > 0\ \\\<^sub>2 > 0\ by force qed lemma picard_lindeloef_add: "picard_lindeloef f1 T S t\<^sub>0 \ picard_lindeloef f2 T S t\<^sub>0 \ picard_lindeloef (\t s. f1 t s + f2 t s) T S t\<^sub>0" unfolding picard_lindeloef_def apply(clarsimp, rule conjI) using continuous_on_add apply fastforce using local_lipschitz_add by blast lemma picard_lindeloef_constant: "picard_lindeloef (\t s. c) UNIV UNIV t\<^sub>0" apply(unfold_locales, simp_all add: local_lipschitz_def lipschitz_on_def, clarsimp) by (rule_tac x=1 in exI, clarsimp, rule_tac x="1/2" in exI, simp) subsection \ Flows for ODEs \ text\ A locale designed for verification of hybrid systems. The user can select the interval of existence and the defining flow equation via the variables @{term "T"} and @{term "\"}.\ locale local_flow = picard_lindeloef "(\ t. f)" T S 0 for f::"'a::{heine_borel,banach} \ 'a" and T S L + fixes \ :: "real \ 'a \ 'a" assumes ivp: "\ t s. t \ T \ s \ S \ D (\t. \ t s) = (\t. f (\ t s)) on {0--t}" "\ s. s \ S \ \ 0 s = s" "\ t s. t \ T \ s \ S \ (\t. \ t s) \ {0--t} \ S" begin lemma in_ivp_sols_ivl: assumes "t \ T" "s \ S" shows "(\t. \ t s) \ Sols (\t. f) {0--t} S 0 s" apply(rule ivp_solsI) using ivp assms by auto lemma eq_solution_ivl: assumes xivp: "D X = (\t. f (X t)) on {0--t}" "X 0 = s" "X \ {0--t} \ S" and indom: "t \ T" "s \ S" shows "X t = \ t s" apply(rule unique_solution[OF xivp \t \ T\]) using \s \ S\ ivp indom by auto lemma ex_ivl_eq: assumes "s \ S" shows "ex_ivl s = T" using existence_ivl_subset[of s] apply safe unfolding existence_ivl_def csols_eq using in_ivp_sols_ivl[OF _ assms] by blast lemma has_derivative_on_open1: assumes "t > 0" "t \ T" "s \ S" obtains B where "t \ B" and "open B" and "B \ T" and "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ t s)) at t within B" proof- obtain r::real where rHyp: "r > 0" "ball t r \ T" using open_contains_ball_eq open_domain(1) \t \ T\ by blast moreover have "t + r/2 > 0" using \r > 0\ \t > 0\ by auto moreover have "{0--t} \ T" using subintervalI[OF init_time \t \ T\] . ultimately have subs: "{0<-- T" unfolding abs_le_eq abs_le_eq real_ivl_eqs[OF \t > 0\] real_ivl_eqs[OF \t + r/2 > 0\] by clarify (case_tac "t < x", simp_all add: cball_def ball_def dist_norm subset_eq field_simps) have "t + r/2 \ T" using rHyp unfolding real_ivl_eqs[OF rHyp(1)] by (simp add: subset_eq) hence "{0--t + r/2} \ T" using subintervalI[OF init_time] by blast hence "(D (\t. \ t s) = (\t. f (\ t s)) on {0--(t + r/2)})" using ivp(1)[OF _ \s \ S\] by auto hence vderiv: "(D (\t. \ t s) = (\t. f (\ t s)) on {0<--t + r/2 > 0\] by auto have "t \ {0<--t + r/2 > 0\] using rHyp \t > 0\ by simp moreover have "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ t s)) (at t within {0<--t + r/2 > 0\] by simp ultimately show ?thesis using subs that by blast qed lemma has_derivative_on_open2: assumes "t < 0" "t \ T" "s \ S" obtains B where "t \ B" and "open B" and "B \ T" and "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ t s)) at t within B" proof- obtain r::real where rHyp: "r > 0" "ball t r \ T" using open_contains_ball_eq open_domain(1) \t \ T\ by blast moreover have "t - r/2 < 0" using \r > 0\ \t < 0\ by auto moreover have "{0--t} \ T" using subintervalI[OF init_time \t \ T\] . ultimately have subs: "{0<-- T" unfolding open_segment_eq_real_ivl closed_segment_eq_real_ivl real_ivl_eqs[OF rHyp(1)] by(auto simp: subset_eq) have "t - r/2 \ T" using rHyp unfolding real_ivl_eqs by (simp add: subset_eq) hence "{0--t - r/2} \ T" using subintervalI[OF init_time] by blast hence "(D (\t. \ t s) = (\t. f (\ t s)) on {0--(t - r/2)})" using ivp(1)[OF _ \s \ S\] by auto hence vderiv: "(D (\t. \ t s) = (\t. f (\ t s)) on {0<-- {0<--t < 0\ by simp moreover have "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ t s)) (at t within {0<-- S" obtains B where "0 \ B" and "open B" and "B \ T" and "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ 0 s)) at 0 within B" proof- obtain r::real where rHyp: "r > 0" "ball 0 r \ T" using open_contains_ball_eq open_domain(1) init_time by blast hence "r/2 \ T" "-r/2 \ T" "r/2 > 0" unfolding real_ivl_eqs by auto hence subs: "{0--r/2} \ T" "{0--(-r/2)} \ T" using subintervalI[OF init_time] by auto hence "(D (\t. \ t s) = (\t. f (\ t s)) on {0--r/2})" "(D (\t. \ t s) = (\t. f (\ t s)) on {0--(-r/2)})" using ivp(1)[OF _ \s \ S\] by auto also have "{0--r/2} = {0--r/2} \ closure {0--r/2} \ closure {0--(-r/2)}" "{0--(-r/2)} = {0--(-r/2)} \ closure {0--r/2} \ closure {0--(-r/2)}" unfolding closed_segment_eq_real_ivl \r/2 > 0\ by auto ultimately have vderivs: "(D (\t. \ t s) = (\t. f (\ t s)) on {0--r/2} \ closure {0--r/2} \ closure {0--(-r/2)})" "(D (\t. \ t s) = (\t. f (\ t s)) on {0--(-r/2)} \ closure {0--r/2} \ closure {0--(-r/2)})" unfolding closed_segment_eq_real_ivl \r/2 > 0\ by auto have obs: "0 \ {-r/2<--r/2 > 0\ by auto have union: "{-r/2--r/2} = {0--r/2} \ {0--(-r/2)}" unfolding closed_segment_eq_real_ivl by auto hence "(D (\t. \ t s) = (\t. f (\ t s)) on {-r/2--r/2})" using has_vderiv_on_union[OF vderivs] by simp hence "(D (\t. \ t s) = (\t. f (\ t s)) on {-r/2<--\. \ \ s) \ (\\. \ *\<^sub>R f (\ 0 s)) (at 0 within {-r/2<-- T" using subs union segment_open_subset_closed by blast ultimately show ?thesis using obs that by blast qed lemma has_derivative_on_open: assumes "t \ T" "s \ S" obtains B where "t \ B" and "open B" and "B \ T" and "D (\\. \ \ s) \ (\\. \ *\<^sub>R f (\ t s)) at t within B" apply(subgoal_tac "t < 0 \ t = 0 \ t > 0") using has_derivative_on_open1[OF _ assms] has_derivative_on_open2[OF _ assms] has_derivative_on_open3[OF \s \ S\] by blast force lemma in_domain: assumes "s \ S" shows "(\t. \ t s) \ T \ S" unfolding ex_ivl_eq[symmetric] existence_ivl_def using local.mem_existence_ivl_subset ivp(3)[OF _ assms] by blast lemma has_vderiv_on_domain: assumes "s \ S" shows "D (\t. \ t s) = (\t. f (\ t s)) on T" proof(unfold has_vderiv_on_def has_vector_derivative_def, clarsimp) fix t assume "t \ T" then obtain B where "t \ B" and "open B" and "B \ T" and Dhyp: "D (\t. \ t s) \ (\\. \ *\<^sub>R f (\ t s)) at t within B" using assms has_derivative_on_open[OF \t \ T\] by blast hence "t \ interior B" using interior_eq by auto thus "D (\t. \ t s) \ (\\. \ *\<^sub>R f (\ t s)) at t within T" using has_derivative_at_within_mono[OF _ \B \ T\ Dhyp] by blast qed lemma in_ivp_sols: assumes "s \ S" shows "(\t. \ t s) \ Sols (\t. f) T S 0 s" using has_vderiv_on_domain ivp(2) in_domain apply(rule ivp_solsI) using assms by auto lemma eq_solution: assumes "X \ Sols (\t. f) T S 0 s" and "t \ T" and "s \ S" shows "X t = \ t s" proof- have "D X = (\t. f (X t)) on (ex_ivl s)" and "X 0 = s" and "X \ (ex_ivl s) \ S" using ivp_solsD[OF assms(1)] unfolding ex_ivl_eq[OF \s \ S\] by auto note solution_eq_flow[OF this] hence "X t = flow 0 s t" unfolding ex_ivl_eq[OF \s \ S\] using assms by blast also have "\ t s = flow 0 s t" apply(rule solution_eq_flow ivp) apply(simp_all add: assms(2,3) ivp(2)[OF \s \ S\]) unfolding ex_ivl_eq[OF \s \ S\] by (auto simp: has_vderiv_on_domain assms in_domain) ultimately show "X t = \ t s" by simp qed lemma ivp_sols_collapse: assumes "T = UNIV" and "s \ S" shows "Sols (\t. f) T S 0 s = {(\t. \ t s)}" using in_ivp_sols eq_solution assms by auto lemma additive_in_ivp_sols: assumes "s \ S" and "\

(\\. \ + t) T \ T" shows "(\\. \ (\ + t) s) \ Sols (\t. f) T S 0 (\ (0 + t) s)" apply(rule ivp_solsI, rule vderiv_on_compose_add) using has_vderiv_on_domain has_vderiv_on_subset assms apply blast using in_domain assms by auto lemma is_monoid_action: assumes "s \ S" and "T = UNIV" shows "\ 0 s = s" and "\ (t\<^sub>1 + t\<^sub>2) s = \ t\<^sub>1 (\ t\<^sub>2 s)" proof- show "\ 0 s = s" using ivp assms by simp have "\ (0 + t\<^sub>2) s = \ t\<^sub>2 s" by simp also have "\ t\<^sub>2 s \ S" using in_domain assms by auto finally show "\ (t\<^sub>1 + t\<^sub>2) s = \ t\<^sub>1 (\ t\<^sub>2 s)" using eq_solution[OF additive_in_ivp_sols] assms by auto qed definition orbit :: "'a \ 'a set" ("\\<^sup>\") where "\\<^sup>\ s = g_orbital f (\s. True) T S 0 s" lemma orbit_eq[simp]: assumes "s \ S" shows "\\<^sup>\ s = {\ t s| t. t \ T}" using eq_solution assms unfolding orbit_def g_orbital_eq ivp_sols_def by(auto intro!: has_vderiv_on_domain ivp(2) in_domain) lemma g_orbital_collapses: assumes "s \ S" shows "g_orbital f G T S 0 s = {\ t s| t. t \ T \ (\\\down T t. G (\ \ s))}" proof(rule subset_antisym, simp_all only: subset_eq) let ?gorbit = "{\ t s |t. t \ T \ (\\\down T t. G (\ \ s))}" {fix s' assume "s' \ g_orbital f G T S 0 s" then obtain X and t where x_ivp:"X \ Sols (\t. f) T S 0 s" and "X t = s'" and "t \ T" and guard:"(\

X (down T t) \ {s. G s})" unfolding g_orbital_def g_orbit_eq by auto have obs:"\\\(down T t). X \ = \ \ s" using eq_solution[OF x_ivp _ assms] by blast hence "\

(\t. \ t s) (down T t) \ {s. G s}" using guard by auto also have "\ t s = X t" using eq_solution[OF x_ivp \t \ T\ assms] by simp ultimately have "s' \ ?gorbit" using \X t = s'\ \t \ T\ by auto} thus "\s'\ g_orbital f G T S 0 s. s' \ ?gorbit" by blast next let ?gorbit = "{\ t s |t. t \ T \ (\\\down T t. G (\ \ s))}" {fix s' assume "s' \ ?gorbit" then obtain t where "\

(\t. \ t s) (down T t) \ {s. G s}" and "t \ T" and "\ t s = s'" by blast hence "s' \ g_orbital f G T S 0 s" using assms by(auto intro!: g_orbitalI in_ivp_sols)} thus "\s'\?gorbit. s' \ g_orbital f G T S 0 s" by blast qed end lemma line_is_local_flow: "0 \ T \ is_interval T \ open T \ local_flow (\ s. c) T UNIV (\ t s. s + t *\<^sub>R c)" apply(unfold_locales, simp_all add: local_lipschitz_def lipschitz_on_def, clarsimp) apply(rule_tac x=1 in exI, clarsimp, rule_tac x="1/2" in exI, simp) apply(rule_tac f'1="\ s. 0" and g'1="\ s. c" in has_vderiv_on_add[THEN has_vderiv_on_eq_rhs]) apply(rule derivative_intros, simp)+ by simp_all end \ No newline at end of file diff --git a/thys/Hybrid_Systems_VCs/HS_Preliminaries.thy b/thys/Hybrid_Systems_VCs/HS_Preliminaries.thy --- a/thys/Hybrid_Systems_VCs/HS_Preliminaries.thy +++ b/thys/Hybrid_Systems_VCs/HS_Preliminaries.thy @@ -1,308 +1,351 @@ (* Title: Preliminaries for hybrid systems verification Author: Jonathan Julián Huerta y Munive, 2019 Maintainer: Jonathan Julián Huerta y Munive *) section \ Hybrid Systems Preliminaries \ text \Hybrid systems combine continuous dynamics with discrete control. This section contains auxiliary lemmas for verification of hybrid systems.\ theory HS_Preliminaries imports "Ordinary_Differential_Equations.Picard_Lindeloef_Qualitative" begin subsection \ Real numbers \ lemma abs_le_eq: shows "(r::real) > 0 \ (\x\ < r) = (-r < x \ x < r)" and "(r::real) > 0 \ (\x\ \ r) = (-r \ x \ x \ r)" by linarith+ lemma real_ivl_eqs: assumes "0 < r" shows "ball x r = {x-r<--< x+r}" and "{x-r<--< x+r} = {x-r<..< x+r}" and "ball (r / 2) (r / 2) = {0<--2 + (x * sin t + y * cos t)\<^sup>2 = x\<^sup>2 + y\<^sup>2" and "(x * cos t + y * sin t)\<^sup>2 + (y * cos t - x * sin t)\<^sup>2 = x\<^sup>2 + y\<^sup>2" proof- have "(x * cos t - y * sin t)\<^sup>2 = x\<^sup>2 * (cos t)\<^sup>2 + y\<^sup>2 * (sin t)\<^sup>2 - 2 * (x * cos t) * (y * sin t)" by(simp add: power2_diff power_mult_distrib) also have "(x * sin t + y * cos t)\<^sup>2 = y\<^sup>2 * (cos t)\<^sup>2 + x\<^sup>2 * (sin t)\<^sup>2 + 2 * (x * cos t) * (y * sin t)" by(simp add: power2_sum power_mult_distrib) ultimately show "(x * cos t - y * sin t)\<^sup>2 + (x * sin t + y * cos t)\<^sup>2 = x\<^sup>2 + y\<^sup>2" by (simp add: Groups.mult_ac(2) Groups.mult_ac(3) right_diff_distrib sin_squared_eq) thus "(x * cos t + y * sin t)\<^sup>2 + (y * cos t - x * sin t)\<^sup>2 = x\<^sup>2 + y\<^sup>2" by (simp add: add.commute add.left_commute power2_diff power2_sum) qed subsection \ Single variable derivatives \ notation has_derivative ("(1(D _ \ (_))/ _)" [65,65] 61) notation has_vderiv_on ("(1 D _ = (_)/ on _)" [65,65] 61) notation norm ("(1\_\)" [65] 61) thy_deps named_theorems poly_derivatives "compilation of optimised miscellaneous derivative rules." declare has_vderiv_on_const [poly_derivatives] and has_vderiv_on_id [poly_derivatives] and has_vderiv_on_add[THEN has_vderiv_on_eq_rhs, poly_derivatives] and has_vderiv_on_diff[THEN has_vderiv_on_eq_rhs, poly_derivatives] and has_vderiv_on_mult[THEN has_vderiv_on_eq_rhs, poly_derivatives] lemma has_vderiv_on_compose_eq: assumes "D f = f' on g ` T" and " D g = g' on T" and "h = (\x. g' x *\<^sub>R f' (g x))" shows "D (\t. f (g t)) = h on T" apply(subst ssubst[of h], simp) using assms has_vderiv_on_compose by auto lemma vderiv_on_compose_add [derivative_intros]: assumes "D x = x' on (\\. \ + t) ` T" shows "D (\\. x (\ + t)) = (\\. x' (\ + t)) on T" apply(rule has_vderiv_on_compose_eq[OF assms]) by(auto intro: derivative_intros) lemma has_vderiv_on_divide_cnst: "a \ 0 \ D (\t. t/a) = (\t. 1/a) on T" unfolding has_vderiv_on_def has_vector_derivative_def apply clarify apply(rule_tac f'1="\t. t" and g'1="\ x. 0" in has_derivative_divide[THEN has_derivative_eq_rhs]) by(auto intro: derivative_eq_intros) lemma has_vderiv_on_power: "n \ 1 \ D (\t. t ^ n) = (\t. n * (t ^ (n - 1))) on T" unfolding has_vderiv_on_def has_vector_derivative_def by (auto intro!: derivative_eq_intros) lemma has_vderiv_on_exp: "D (\t. exp t) = (\t. exp t) on T" unfolding has_vderiv_on_def has_vector_derivative_def by (auto intro: derivative_intros) lemma has_vderiv_on_cos_comp: "D (f::real \ real) = f' on T \ D (\t. cos (f t)) = (\t. - (f' t) * sin (f t)) on T" apply(rule has_vderiv_on_compose_eq[of "\t. cos t"]) unfolding has_vderiv_on_def has_vector_derivative_def apply clarify by(auto intro!: derivative_eq_intros simp: fun_eq_iff) lemma has_vderiv_on_sin_comp: "D (f::real \ real) = f' on T \ D (\t. sin (f t)) = (\t. (f' t) * cos (f t)) on T" apply(rule has_vderiv_on_compose_eq[of "\t. sin t"]) unfolding has_vderiv_on_def has_vector_derivative_def apply clarify by(auto intro!: derivative_eq_intros simp: fun_eq_iff) lemma has_vderiv_on_exp_comp: "D (f::real \ real) = f' on T \ D (\t. exp (f t)) = (\t. (f' t) * exp (f t)) on T" apply(rule has_vderiv_on_compose_eq[of "\t. exp t"]) by (rule has_vderiv_on_exp, simp_all add: mult.commute) lemma vderiv_uminus_intro [poly_derivatives]: "D f = f' on T \ g = (\t. - f' t) \ D (\t. - f t) = g on T" using has_vderiv_on_uminus by auto lemma vderiv_div_cnst_intro [poly_derivatives]: assumes "(a::real) \ 0" and "D f = f' on T" and "g = (\t. (f' t)/a)" shows "D (\t. (f t)/a) = g on T" apply(rule has_vderiv_on_compose_eq[of "\t. t/a" "\t. 1/a"]) using assms by(auto intro: has_vderiv_on_divide_cnst) lemma vderiv_npow_intro [poly_derivatives]: fixes f::"real \ real" assumes "n \ 1" and "D f = f' on T" and "g = (\t. n * (f' t) * (f t)^(n-1))" shows "D (\t. (f t)^n) = g on T" apply(rule has_vderiv_on_compose_eq[of "\t. t^n"]) using assms(1) apply(rule has_vderiv_on_power) using assms by auto lemma vderiv_cos_intro [poly_derivatives]: assumes "D (f::real \ real) = f' on T" and "g = (\t. - (f' t) * sin (f t))" shows "D (\t. cos (f t)) = g on T" using assms and has_vderiv_on_cos_comp by auto lemma vderiv_sin_intro [poly_derivatives]: assumes "D (f::real \ real) = f' on T" and "g = (\t. (f' t) * cos (f t))" shows "D (\t. sin (f t)) = g on T" using assms and has_vderiv_on_sin_comp by auto lemma vderiv_exp_intro [poly_derivatives]: assumes "D (f::real \ real) = f' on T" and "g = (\t. (f' t) * exp (f t))" shows "D (\t. exp (f t)) = g on T" using assms and has_vderiv_on_exp_comp by auto \ \Examples for checking derivatives\ lemma "D (\t. a * t\<^sup>2 / 2 + v * t + x) = (\t. a * t + v) on T" by(auto intro!: poly_derivatives) lemma "D (\t. v * t - a * t\<^sup>2 / 2 + x) = (\x. v - a * x) on T" by(auto intro!: poly_derivatives) lemma "c \ 0 \ D (\t. a5 * t^5 + a3 * (t^3 / c) - a2 * exp (t^2) + a1 * cos t + a0) = (\t. 5 * a5 * t^4 + 3 * a3 * (t^2 / c) - 2 * a2 * t * exp (t^2) - a1 * sin t) on T" by(auto intro!: poly_derivatives) lemma "c \ 0 \ D (\t. - a3 * exp (t^3 / c) + a1 * sin t + a2 * t^2) = (\t. a1 * cos t + 2 * a2 * t - 3 * a3 * t^2 / c * exp (t^3 / c)) on T" apply(intro poly_derivatives) using poly_derivatives(1,2) by force+ lemma "c \ 0 \ D (\t. exp (a * sin (cos (t^4) / c))) = (\t. - 4 * a * t^3 * sin (t^4) / c * cos (cos (t^4) / c) * exp (a * sin (cos (t^4) / c))) on T" apply(intro poly_derivatives) using poly_derivatives(1,2) by force+ +subsection \ Intermediate Value Theorem \ + +lemma IVT_two_functions: + fixes f :: "('a::{linear_continuum_topology, real_vector}) \ + ('b::{linorder_topology,real_normed_vector,ordered_ab_group_add})" + assumes conts: "continuous_on {a..b} f" "continuous_on {a..b} g" + and ahyp: "f a < g a" and bhyp: "g b < f b " and "a \ b" + shows "\x\{a..b}. f x = g x" +proof- + let "?h x" = "f x - g x" + have "?h a \ 0" and "?h b \ 0" + using ahyp bhyp by simp_all + also have "continuous_on {a..b} ?h" + using conts continuous_on_diff by blast + ultimately obtain x where "a \ x" "x \ b" and "?h x = 0" + using IVT'[of "?h"] \a \ b\ by blast + thus ?thesis + using \a \ b\ by auto +qed + +lemma IVT_two_functions_real_ivl: + fixes f :: "real \ real" + assumes conts: "continuous_on {a--b} f" "continuous_on {a--b} g" + and ahyp: "f a < g a" and bhyp: "g b < f b " + shows "\x\{a--b}. f x = g x" +proof(cases "a \ b") + case True + then show ?thesis + using IVT_two_functions assms + unfolding closed_segment_eq_real_ivl by auto +next + case False + hence "a \ b" + by auto + hence "continuous_on {b..a} f" "continuous_on {b..a} g" + using conts False unfolding closed_segment_eq_real_ivl by auto + hence "\x\{b..a}. g x = f x" + using IVT_two_functions[of b a g f] assms(3,4) False by auto + then show ?thesis + using \a \ b\ unfolding closed_segment_eq_real_ivl by auto force +qed + + subsection \ Filters \ lemma eventually_at_within_mono: assumes "t \ interior T" and "T \ S" and "eventually P (at t within T)" shows "eventually P (at t within S)" by (meson assms eventually_within_interior interior_mono subsetD) lemma netlimit_at_within_mono: fixes t::"'a::{perfect_space,t2_space}" assumes "t \ interior T" and "T \ S" shows "netlimit (at t within S) = t" using assms(1) interior_mono[OF \T \ S\] netlimit_within_interior by auto lemma has_derivative_at_within_mono: assumes "(t::real) \ interior T" and "T \ S" and "D f \ f' at t within T" shows "D f \ f' at t within S" using assms(3) apply(unfold has_derivative_def tendsto_iff, safe) unfolding netlimit_at_within_mono[OF assms(1,2)] netlimit_within_interior[OF assms(1)] by (rule eventually_at_within_mono[OF assms(1,2)]) simp lemma eventually_all_finite2: fixes P :: "('a::finite) \ 'b \ bool" assumes h:"\i. eventually (P i) F" shows "eventually (\x. \i. P i x) F" proof(unfold eventually_def) let ?F = "Rep_filter F" have obs: "\i. ?F (P i)" using h by auto have "?F (\x. \i \ UNIV. P i x)" apply(rule finite_induct) by(auto intro: eventually_conj simp: obs h) thus "?F (\x. \i. P i x)" by simp qed lemma eventually_all_finite_mono: fixes P :: "('a::finite) \ 'b \ bool" assumes h1: "\i. eventually (P i) F" and h2: "\x. (\i. (P i x)) \ Q x" shows "eventually Q F" proof- have "eventually (\x. \i. P i x) F" using h1 eventually_all_finite2 by blast thus "eventually Q F" unfolding eventually_def using h2 eventually_mono by auto qed subsection \ Multivariable derivatives \ lemma frechet_vec_lambda: fixes f::"real \ ('a::banach)^('m::finite)" and x::real and T::"real set" defines "x\<^sub>0 \ netlimit (at x within T)" and "m \ real CARD('m)" assumes "\i. ((\y. (f y $ i - f x\<^sub>0 $ i - (y - x\<^sub>0) *\<^sub>R f' x $ i) /\<^sub>R (\y - x\<^sub>0\)) \ 0) (at x within T)" shows "((\y. (f y - f x\<^sub>0 - (y - x\<^sub>0) *\<^sub>R f' x) /\<^sub>R (\y - x\<^sub>0\)) \ 0) (at x within T)" proof(simp add: tendsto_iff, clarify) fix \::real assume "0 < \" let "?\" = "\y. y - x\<^sub>0" and "?\f" = "\y. f y - f x\<^sub>0" let "?P" = "\i e y. inverse \?\ y\ * (\f y $ i - f x\<^sub>0 $ i - ?\ y *\<^sub>R f' x $ i\) < e" and "?Q" = "\y. inverse \?\ y\ * (\?\f y - ?\ y *\<^sub>R f' x\) < \" have "0 < \ / sqrt m" using \0 < \\ by (auto simp: assms) hence "\i. eventually (\y. ?P i (\ / sqrt m) y) (at x within T)" using assms unfolding tendsto_iff by simp thus "eventually ?Q (at x within T)" proof(rule eventually_all_finite_mono, simp add: norm_vec_def L2_set_def, clarify) fix t::real let ?c = "inverse \t - x\<^sub>0\" and "?u t" = "\i. f t $ i - f x\<^sub>0 $ i - ?\ t *\<^sub>R f' x $ i" assume hyp:"\i. ?c * (\?u t i\) < \ / sqrt m" hence "\i. (?c *\<^sub>R (\?u t i\))\<^sup>2 < (\ / sqrt m)\<^sup>2" by (simp add: power_strict_mono) hence "\i. ?c\<^sup>2 * ((\?u t i\))\<^sup>2 < \\<^sup>2 / m" by (simp add: power_mult_distrib power_divide assms) hence "\i. ?c\<^sup>2 * ((\?u t i\))\<^sup>2 < \\<^sup>2 / m" by (auto simp: assms) also have "({}::'m set) \ UNIV \ finite (UNIV :: 'm set)" by simp ultimately have "(\i\UNIV. ?c\<^sup>2 * ((\?u t i\))\<^sup>2) < (\(i::'m)\UNIV. \\<^sup>2 / m)" by (metis (lifting) sum_strict_mono) moreover have "?c\<^sup>2 * (\i\UNIV. (\?u t i\)\<^sup>2) = (\i\UNIV. ?c\<^sup>2 * (\?u t i\)\<^sup>2)" using sum_distrib_left by blast ultimately have "?c\<^sup>2 * (\i\UNIV. (\?u t i\)\<^sup>2) < \\<^sup>2" by (simp add: assms) hence "sqrt (?c\<^sup>2 * (\i\UNIV. (\?u t i\)\<^sup>2)) < sqrt (\\<^sup>2)" using real_sqrt_less_iff by blast also have "... = \" using \0 < \\ by auto moreover have "?c * sqrt (\i\UNIV. (\?u t i\)\<^sup>2) = sqrt (?c\<^sup>2 * (\i\UNIV. (\?u t i\)\<^sup>2))" by (simp add: real_sqrt_mult) ultimately show "?c * sqrt (\i\UNIV. (\?u t i\)\<^sup>2) < \" by simp qed qed lemma tendsto_norm_bound: "\x. \G x - L\ \ \F x - L\ \ (F \ L) net \ (G \ L) net" apply(unfold tendsto_iff dist_norm, clarsimp) apply(rule_tac P="\x. \F x - L\ < e" in eventually_mono, simp) by (rename_tac e z) (erule_tac x=z in allE, simp) lemma tendsto_zero_norm_bound: "\x. \G x\ \ \F x\ \ (F \ 0) net \ (G \ 0) net" apply(unfold tendsto_iff dist_norm, clarsimp) apply(rule_tac P="\x. \F x\ < e" in eventually_mono, simp) by (rename_tac e z) (erule_tac x=z in allE, simp) lemma frechet_vec_nth: fixes f::"real \ ('a::real_normed_vector)^'m" assumes "((\x. (f x - f x\<^sub>0 - (x - x\<^sub>0) *\<^sub>R f' t) /\<^sub>R (\x - x\<^sub>0\)) \ 0) (at t within T)" shows "((\x. (f x $ i - f x\<^sub>0 $ i - (x - x\<^sub>0) *\<^sub>R f' t $ i) /\<^sub>R (\x - x\<^sub>0\)) \ 0) (at t within T)" apply(rule_tac F="(\x. (f x - f x\<^sub>0 - (x - x\<^sub>0) *\<^sub>R f' t) /\<^sub>R (\x - x\<^sub>0\))" in tendsto_zero_norm_bound) apply(clarsimp, rule mult_left_mono) apply (metis Finite_Cartesian_Product.norm_nth_le vector_minus_component vector_scaleR_component) using assms by simp_all lemma has_derivative_vec_lambda: fixes f::"real \ ('a::banach)^('n::finite)" assumes "\i. D (\t. f t $ i) \ (\ h. h *\<^sub>R f' x $ i) (at x within T)" shows "D f \ (\h. h *\<^sub>R f' x) at x within T" apply(unfold has_derivative_def, safe) apply(force simp: bounded_linear_def bounded_linear_axioms_def) using assms frechet_vec_lambda[of x T ] unfolding has_derivative_def by auto lemma has_derivative_vec_nth: assumes "D f \ (\h. h *\<^sub>R f' x) at x within T" shows "D (\t. f t $ i) \ (\h. h *\<^sub>R f' x $ i) at x within T" apply(unfold has_derivative_def, safe) apply(force simp: bounded_linear_def bounded_linear_axioms_def) using frechet_vec_nth assms unfolding has_derivative_def by auto lemma has_vderiv_on_vec_eq[simp]: fixes x::"real \ ('a::banach)^('n::finite)" shows "(D x = x' on T) = (\i. D (\t. x t $ i) = (\t. x' t $ i) on T)" unfolding has_vderiv_on_def has_vector_derivative_def apply safe using has_derivative_vec_nth has_derivative_vec_lambda by blast+ end \ No newline at end of file