src/HOL/Multivariate_Analysis/Path_Connected.thy
changeset 61738 c4f6031f1310
parent 61711 21d7910d6816
child 61762 d50b993b4fb9
equal deleted inserted replaced
61736:d6b2d638af23 61738:c4f6031f1310
     1 (*  Title:      HOL/Multivariate_Analysis/Path_Connected.thy
     1 (*  Title:      HOL/Multivariate_Analysis/Path_Connected.thy
     2     Author:     Robert Himmelmann, TU Muenchen, and LCP with material from HOL Light
     2     Author:     Robert Himmelmann, TU Muenchen, and LC Paulson with material from HOL Light
     3 *)
     3 *)
     4 
     4 
     5 section \<open>Continuous paths and path-connected sets\<close>
     5 section \<open>Continuous paths and path-connected sets\<close>
     6 
     6 
     7 theory Path_Connected
     7 theory Path_Connected
     8 imports Convex_Euclidean_Space
     8 imports Convex_Euclidean_Space
     9 begin
     9 begin
    10 
       
    11 (*FIXME move up?*)
       
    12 lemma image_affinity_interval:
       
    13   fixes c :: "'a::ordered_real_vector"
       
    14   shows "((\<lambda>x. m *\<^sub>R x + c) ` {a..b}) = (if {a..b}={} then {}
       
    15             else if 0 <= m then {m *\<^sub>R a + c .. m  *\<^sub>R b + c}
       
    16             else {m *\<^sub>R b + c .. m *\<^sub>R a + c})"
       
    17   apply (case_tac "m=0", force)
       
    18   apply (auto simp: scaleR_left_mono)
       
    19   apply (rule_tac x="inverse m *\<^sub>R (x-c)" in rev_image_eqI, auto simp: pos_le_divideR_eq le_diff_eq scaleR_left_mono_neg)
       
    20   apply (metis diff_le_eq inverse_inverse_eq order.not_eq_order_implies_strict pos_le_divideR_eq positive_imp_inverse_positive)
       
    21   apply (rule_tac x="inverse m *\<^sub>R (x-c)" in rev_image_eqI, auto simp: not_le neg_le_divideR_eq diff_le_eq)
       
    22   using le_diff_eq scaleR_le_cancel_left_neg
       
    23   apply fastforce
       
    24   done
       
    25 
    10 
    26 subsection \<open>Paths and Arcs\<close>
    11 subsection \<open>Paths and Arcs\<close>
    27 
    12 
    28 definition path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    13 definition path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    29   where "path g \<longleftrightarrow> continuous_on {0..1} g"
    14   where "path g \<longleftrightarrow> continuous_on {0..1} g"
  1017 lemma simple_path_linepath[intro]: "a \<noteq> b \<Longrightarrow> simple_path (linepath a b)"
  1002 lemma simple_path_linepath[intro]: "a \<noteq> b \<Longrightarrow> simple_path (linepath a b)"
  1018   by (simp add: arc_imp_simple_path arc_linepath)
  1003   by (simp add: arc_imp_simple_path arc_linepath)
  1019 
  1004 
  1020 lemma linepath_trivial [simp]: "linepath a a x = a"
  1005 lemma linepath_trivial [simp]: "linepath a a x = a"
  1021   by (simp add: linepath_def real_vector.scale_left_diff_distrib)
  1006   by (simp add: linepath_def real_vector.scale_left_diff_distrib)
  1022     
  1007 
  1023 lemma subpath_refl: "subpath a a g = linepath (g a) (g a)"
  1008 lemma subpath_refl: "subpath a a g = linepath (g a) (g a)"
  1024   by (simp add: subpath_def linepath_def algebra_simps)
  1009   by (simp add: subpath_def linepath_def algebra_simps)
  1025 
  1010 
  1026 
  1011 
  1027 subsection \<open>Bounding a point away from a path\<close>
  1012 subsection \<open>Bounding a point away from a path\<close>
  1331     shows "path_connected (open_segment a b)"
  1316     shows "path_connected (open_segment a b)"
  1332   by (simp add: convex_imp_path_connected)
  1317   by (simp add: convex_imp_path_connected)
  1333 
  1318 
  1334 lemma homeomorphic_path_connectedness:
  1319 lemma homeomorphic_path_connectedness:
  1335   "s homeomorphic t \<Longrightarrow> path_connected s \<longleftrightarrow> path_connected t"
  1320   "s homeomorphic t \<Longrightarrow> path_connected s \<longleftrightarrow> path_connected t"
  1336   unfolding homeomorphic_def homeomorphism_def
  1321   unfolding homeomorphic_def homeomorphism_def by (metis path_connected_continuous_image)
  1337   apply (erule exE|erule conjE)+
       
  1338   apply rule
       
  1339   apply (drule_tac f=f in path_connected_continuous_image)
       
  1340   prefer 3
       
  1341   apply (drule_tac f=g in path_connected_continuous_image)
       
  1342   apply auto
       
  1343   done
       
  1344 
  1322 
  1345 lemma path_connected_empty: "path_connected {}"
  1323 lemma path_connected_empty: "path_connected {}"
  1346   unfolding path_connected_def by auto
  1324   unfolding path_connected_def by auto
  1347 
  1325 
  1348 lemma path_connected_singleton: "path_connected {a}"
  1326 lemma path_connected_singleton: "path_connected {a}"
  2807   by (simp add: homotopic_paths_def homotopic_with_imp_subset1 homotopic_with_imp_subset2 path_image_def)
  2785   by (simp add: homotopic_paths_def homotopic_with_imp_subset1 homotopic_with_imp_subset2 path_image_def)
  2808 
  2786 
  2809 proposition homotopic_paths_refl [simp]: "homotopic_paths s p p \<longleftrightarrow> path p \<and> path_image p \<subseteq> s"
  2787 proposition homotopic_paths_refl [simp]: "homotopic_paths s p p \<longleftrightarrow> path p \<and> path_image p \<subseteq> s"
  2810 by (simp add: homotopic_paths_def homotopic_with_refl path_def path_image_def)
  2788 by (simp add: homotopic_paths_def homotopic_with_refl path_def path_image_def)
  2811 
  2789 
  2812 proposition homotopic_paths_sym: "homotopic_paths s p q \<longleftrightarrow> homotopic_paths s q p"
  2790 proposition homotopic_paths_sym: "homotopic_paths s p q \<Longrightarrow> homotopic_paths s q p"
  2813   by (metis (mono_tags) homotopic_paths_def homotopic_paths_imp_pathfinish homotopic_paths_imp_pathstart homotopic_with_symD)+
  2791   by (metis (mono_tags) homotopic_paths_def homotopic_paths_imp_pathfinish homotopic_paths_imp_pathstart homotopic_with_symD)
       
  2792 
       
  2793 proposition homotopic_paths_sym_eq: "homotopic_paths s p q \<longleftrightarrow> homotopic_paths s q p"
       
  2794   by (metis homotopic_paths_sym)
  2814 
  2795 
  2815 proposition homotopic_paths_trans:
  2796 proposition homotopic_paths_trans:
  2816      "\<lbrakk>homotopic_paths s p q; homotopic_paths s q r\<rbrakk> \<Longrightarrow> homotopic_paths s p r"
  2797      "\<lbrakk>homotopic_paths s p q; homotopic_paths s q r\<rbrakk> \<Longrightarrow> homotopic_paths s p r"
  2817   apply (simp add: homotopic_paths_def)
  2798   apply (simp add: homotopic_paths_def)
  2818   apply (rule homotopic_with_trans, assumption)
  2799   apply (rule homotopic_with_trans, assumption)
  2936   done
  2917   done
  2937 
  2918 
  2938 proposition homotopic_paths_lid:
  2919 proposition homotopic_paths_lid:
  2939    "\<lbrakk>path p; path_image p \<subseteq> s\<rbrakk> \<Longrightarrow> homotopic_paths s (linepath (pathstart p) (pathstart p) +++ p) p"
  2920    "\<lbrakk>path p; path_image p \<subseteq> s\<rbrakk> \<Longrightarrow> homotopic_paths s (linepath (pathstart p) (pathstart p) +++ p) p"
  2940 using homotopic_paths_rid [of "reversepath p" s]
  2921 using homotopic_paths_rid [of "reversepath p" s]
  2941   by (metis homotopic_paths_reversepath path_image_reversepath path_reversepath pathfinish_linepath 
  2922   by (metis homotopic_paths_reversepath path_image_reversepath path_reversepath pathfinish_linepath
  2942         pathfinish_reversepath reversepath_joinpaths reversepath_linepath)
  2923         pathfinish_reversepath reversepath_joinpaths reversepath_linepath)
  2943 
  2924 
  2944 proposition homotopic_paths_assoc:
  2925 proposition homotopic_paths_assoc:
  2945    "\<lbrakk>path p; path_image p \<subseteq> s; path q; path_image q \<subseteq> s; path r; path_image r \<subseteq> s; pathfinish p = pathstart q;
  2926    "\<lbrakk>path p; path_image p \<subseteq> s; path q; path_image q \<subseteq> s; path r; path_image r \<subseteq> s; pathfinish p = pathstart q;
  2946      pathfinish q = pathstart r\<rbrakk>
  2927      pathfinish q = pathstart r\<rbrakk>
  2959 proposition homotopic_paths_rinv:
  2940 proposition homotopic_paths_rinv:
  2960   assumes "path p" "path_image p \<subseteq> s"
  2941   assumes "path p" "path_image p \<subseteq> s"
  2961     shows "homotopic_paths s (p +++ reversepath p) (linepath (pathstart p) (pathstart p))"
  2942     shows "homotopic_paths s (p +++ reversepath p) (linepath (pathstart p) (pathstart p))"
  2962 proof -
  2943 proof -
  2963   have "continuous_on ({0..1} \<times> {0..1}) (\<lambda>x. (subpath 0 (fst x) p +++ reversepath (subpath 0 (fst x) p)) (snd x))"
  2944   have "continuous_on ({0..1} \<times> {0..1}) (\<lambda>x. (subpath 0 (fst x) p +++ reversepath (subpath 0 (fst x) p)) (snd x))"
  2964     using assms 
  2945     using assms
  2965     apply (simp add: joinpaths_def subpath_def reversepath_def path_def del: le_divide_eq_numeral1)
  2946     apply (simp add: joinpaths_def subpath_def reversepath_def path_def del: le_divide_eq_numeral1)
  2966     apply (rule continuous_on_cases_le)
  2947     apply (rule continuous_on_cases_le)
  2967     apply (rule_tac [2] continuous_on_compose [of _ _ p, unfolded o_def])
  2948     apply (rule_tac [2] continuous_on_compose [of _ _ p, unfolded o_def])
  2968     apply (rule continuous_on_compose [of _ _ p, unfolded o_def])
  2949     apply (rule continuous_on_compose [of _ _ p, unfolded o_def])
  2969     apply (auto intro!: continuous_intros simp del: eq_divide_eq_numeral1)
  2950     apply (auto intro!: continuous_intros simp del: eq_divide_eq_numeral1)
  2970     apply (force elim!: continuous_on_subset simp add: mult_le_one)+
  2951     apply (force elim!: continuous_on_subset simp add: mult_le_one)+
  2971     done
  2952     done
  2972   then show ?thesis
  2953   then show ?thesis
  2973     using assms
  2954     using assms
  2974     apply (subst homotopic_paths_sym)
  2955     apply (subst homotopic_paths_sym_eq)
  2975     apply (simp add: homotopic_paths_def homotopic_with_def)
  2956     unfolding homotopic_paths_def homotopic_with_def
  2976     apply (rule_tac x="(\<lambda>y. (subpath 0 (fst y) p +++ reversepath(subpath 0 (fst y) p)) (snd y))" in exI)
  2957     apply (rule_tac x="(\<lambda>y. (subpath 0 (fst y) p +++ reversepath(subpath 0 (fst y) p)) (snd y))" in exI)
  2977     apply (simp add: path_defs joinpaths_def subpath_def reversepath_def)
  2958     apply (simp add: path_defs joinpaths_def subpath_def reversepath_def)
  2978     apply (force simp: mult_le_one)
  2959     apply (force simp: mult_le_one)
  2979     done
  2960     done
  2980 qed
  2961 qed
  3007 proposition homotopic_loops_imp_path:
  2988 proposition homotopic_loops_imp_path:
  3008      "homotopic_loops s p q \<Longrightarrow> path p \<and> path q"
  2989      "homotopic_loops s p q \<Longrightarrow> path p \<and> path q"
  3009   unfolding homotopic_loops_def path_def
  2990   unfolding homotopic_loops_def path_def
  3010   using homotopic_with_imp_continuous by blast
  2991   using homotopic_with_imp_continuous by blast
  3011 
  2992 
  3012 proposition homotopic_loops_imp_subset1:
  2993 proposition homotopic_loops_imp_subset:
  3013      "homotopic_loops s p q \<Longrightarrow> path_image p \<subseteq> s"
  2994      "homotopic_loops s p q \<Longrightarrow> path_image p \<subseteq> s \<and> path_image q \<subseteq> s"
  3014   unfolding homotopic_loops_def path_image_def
  2995   unfolding homotopic_loops_def path_image_def
  3015   using homotopic_with_imp_subset1  by blast
  2996   by (metis homotopic_with_imp_subset1 homotopic_with_imp_subset2)
  3016 
       
  3017 proposition homotopic_loops_imp_subset2:
       
  3018      "homotopic_loops s p q \<Longrightarrow> path_image q \<subseteq> s"
       
  3019   unfolding homotopic_loops_def path_image_def
       
  3020   using homotopic_with_imp_subset2 by blast
       
  3021 
  2997 
  3022 proposition homotopic_loops_refl:
  2998 proposition homotopic_loops_refl:
  3023      "homotopic_loops s p p \<longleftrightarrow>
  2999      "homotopic_loops s p p \<longleftrightarrow>
  3024       path p \<and> path_image p \<subseteq> s \<and> pathfinish p = pathstart p"
  3000       path p \<and> path_image p \<subseteq> s \<and> pathfinish p = pathstart p"
  3025   by (simp add: homotopic_loops_def homotopic_with_refl path_image_def path_def)
  3001   by (simp add: homotopic_loops_def homotopic_with_refl path_image_def path_def)
  3026 
  3002 
  3027 proposition homotopic_loops_sym:
  3003 proposition homotopic_loops_sym: "homotopic_loops s p q \<Longrightarrow> homotopic_loops s q p"
  3028    "homotopic_loops s p q \<longleftrightarrow> homotopic_loops s q p"
       
  3029   by (simp add: homotopic_loops_def homotopic_with_sym)
  3004   by (simp add: homotopic_loops_def homotopic_with_sym)
       
  3005 
       
  3006 proposition homotopic_loops_sym_eq: "homotopic_loops s p q \<longleftrightarrow> homotopic_loops s q p"
       
  3007   by (metis homotopic_loops_sym)
  3030 
  3008 
  3031 proposition homotopic_loops_trans:
  3009 proposition homotopic_loops_trans:
  3032    "\<lbrakk>homotopic_loops s p q; homotopic_loops s q r\<rbrakk> \<Longrightarrow> homotopic_loops s p r"
  3010    "\<lbrakk>homotopic_loops s p q; homotopic_loops s q r\<rbrakk> \<Longrightarrow> homotopic_loops s p r"
  3033   unfolding homotopic_loops_def by (blast intro: homotopic_with_trans)
  3011   unfolding homotopic_loops_def by (blast intro: homotopic_with_trans)
  3034 
  3012 
  3063   assumes "homotopic_loops s p (linepath a a)"
  3041   assumes "homotopic_loops s p (linepath a a)"
  3064     shows "homotopic_paths s p (linepath (pathstart p) (pathstart p))"
  3042     shows "homotopic_paths s p (linepath (pathstart p) (pathstart p))"
  3065 proof -
  3043 proof -
  3066   have "path p" by (metis assms homotopic_loops_imp_path)
  3044   have "path p" by (metis assms homotopic_loops_imp_path)
  3067   have ploop: "pathfinish p = pathstart p" by (metis assms homotopic_loops_imp_loop)
  3045   have ploop: "pathfinish p = pathstart p" by (metis assms homotopic_loops_imp_loop)
  3068   have pip: "path_image p \<subseteq> s" by (metis assms homotopic_loops_imp_subset1)
  3046   have pip: "path_image p \<subseteq> s" by (metis assms homotopic_loops_imp_subset)
  3069   obtain h where conth: "continuous_on ({0..1::real} \<times> {0..1}) h"
  3047   obtain h where conth: "continuous_on ({0..1::real} \<times> {0..1}) h"
  3070              and hs: "h ` ({0..1} \<times> {0..1}) \<subseteq> s"
  3048              and hs: "h ` ({0..1} \<times> {0..1}) \<subseteq> s"
  3071              and [simp]: "\<And>x. x \<in> {0..1} \<Longrightarrow> h(0,x) = p x"
  3049              and [simp]: "\<And>x. x \<in> {0..1} \<Longrightarrow> h(0,x) = p x"
  3072              and [simp]: "\<And>x. x \<in> {0..1} \<Longrightarrow> h(1,x) = a"
  3050              and [simp]: "\<And>x. x \<in> {0..1} \<Longrightarrow> h(1,x) = a"
  3073              and ends: "\<And>t. t \<in> {0..1} \<Longrightarrow> pathfinish (h \<circ> Pair t) = pathstart (h \<circ> Pair t)"
  3051              and ends: "\<And>t. t \<in> {0..1} \<Longrightarrow> pathfinish (h \<circ> Pair t) = pathstart (h \<circ> Pair t)"
  3103                   \<Longrightarrow> homotopic_paths s (p +++ linepath a a +++ reversepath p) (linepath x x)"
  3081                   \<Longrightarrow> homotopic_paths s (p +++ linepath a a +++ reversepath p) (linepath x x)"
  3104     by (metis homotopic_paths_lid homotopic_paths_join
  3082     by (metis homotopic_paths_lid homotopic_paths_join
  3105               homotopic_paths_trans homotopic_paths_sym homotopic_paths_rinv)
  3083               homotopic_paths_trans homotopic_paths_sym homotopic_paths_rinv)
  3106   have 1: "homotopic_paths s p (p +++ linepath (pathfinish p) (pathfinish p))"
  3084   have 1: "homotopic_paths s p (p +++ linepath (pathfinish p) (pathfinish p))"
  3107     using \<open>path p\<close> homotopic_paths_rid homotopic_paths_sym pip by blast
  3085     using \<open>path p\<close> homotopic_paths_rid homotopic_paths_sym pip by blast
  3108   moreover have "homotopic_paths s (p +++ linepath (pathfinish p) (pathfinish p)) 
  3086   moreover have "homotopic_paths s (p +++ linepath (pathfinish p) (pathfinish p))
  3109                                    (linepath (pathstart p) (pathstart p) +++ p +++ linepath (pathfinish p) (pathfinish p))"
  3087                                    (linepath (pathstart p) (pathstart p) +++ p +++ linepath (pathfinish p) (pathfinish p))"
  3110     apply (subst homotopic_paths_sym)
  3088     apply (rule homotopic_paths_sym)
  3111     using homotopic_paths_lid [of "p +++ linepath (pathfinish p) (pathfinish p)" s]
  3089     using homotopic_paths_lid [of "p +++ linepath (pathfinish p) (pathfinish p)" s]
  3112     by (metis 1 homotopic_paths_imp_path homotopic_paths_imp_pathstart homotopic_paths_imp_subset)
  3090     by (metis 1 homotopic_paths_imp_path homotopic_paths_imp_pathstart homotopic_paths_imp_subset)
  3113   moreover have "homotopic_paths s (linepath (pathstart p) (pathstart p) +++ p +++ linepath (pathfinish p) (pathfinish p)) 
  3091   moreover have "homotopic_paths s (linepath (pathstart p) (pathstart p) +++ p +++ linepath (pathfinish p) (pathfinish p))
  3114                                    ((\<lambda>u. h (u, 0)) +++ linepath a a +++ reversepath (\<lambda>u. h (u, 0)))"
  3092                                    ((\<lambda>u. h (u, 0)) +++ linepath a a +++ reversepath (\<lambda>u. h (u, 0)))"
  3115     apply (simp add: homotopic_paths_def homotopic_with_def)
  3093     apply (simp add: homotopic_paths_def homotopic_with_def)
  3116     apply (rule_tac x="\<lambda>y. (subpath 0 (fst y) (\<lambda>u. h (u, 0)) +++ (\<lambda>u. h (Pair (fst y) u)) +++ subpath (fst y) 0 (\<lambda>u. h (u, 0))) (snd y)" in exI)
  3094     apply (rule_tac x="\<lambda>y. (subpath 0 (fst y) (\<lambda>u. h (u, 0)) +++ (\<lambda>u. h (Pair (fst y) u)) +++ subpath (fst y) 0 (\<lambda>u. h (u, 0))) (snd y)" in exI)
  3117     apply (simp add: subpath_reversepath)
  3095     apply (simp add: subpath_reversepath)
  3118     apply (intro conjI homotopic_join_lemma)
  3096     apply (intro conjI homotopic_join_lemma)
  3119     using ploop 
  3097     using ploop
  3120     apply (simp_all add: path_defs joinpaths_def o_def subpath_def conth c1 c2)
  3098     apply (simp_all add: path_defs joinpaths_def o_def subpath_def conth c1 c2)
  3121     apply (force simp: algebra_simps mult_le_one mult_left_le intro: hs [THEN subsetD] adhoc_le)
  3099     apply (force simp: algebra_simps mult_le_one mult_left_le intro: hs [THEN subsetD] adhoc_le)
  3122     done
  3100     done
  3123   moreover have "homotopic_paths s ((\<lambda>u. h (u, 0)) +++ linepath a a +++ reversepath (\<lambda>u. h (u, 0))) 
  3101   moreover have "homotopic_paths s ((\<lambda>u. h (u, 0)) +++ linepath a a +++ reversepath (\<lambda>u. h (u, 0)))
  3124                                    (linepath (pathstart p) (pathstart p))"
  3102                                    (linepath (pathstart p) (pathstart p))"
  3125     apply (rule *)
  3103     apply (rule *)
  3126     apply (simp add: pih0 pathstart_def pathfinish_def conth0)
  3104     apply (simp add: pih0 pathstart_def pathfinish_def conth0)
  3127     apply (simp add: reversepath_def joinpaths_def)
  3105     apply (simp add: reversepath_def joinpaths_def)
  3128     done
  3106     done
  3130     by (blast intro: homotopic_paths_trans)
  3108     by (blast intro: homotopic_paths_trans)
  3131 qed
  3109 qed
  3132 
  3110 
  3133 proposition homotopic_loops_conjugate:
  3111 proposition homotopic_loops_conjugate:
  3134   fixes s :: "'a::real_normed_vector set"
  3112   fixes s :: "'a::real_normed_vector set"
  3135   assumes "path p" "path q" and pip: "path_image p \<subseteq> s" and piq: "path_image q \<subseteq> s" 
  3113   assumes "path p" "path q" and pip: "path_image p \<subseteq> s" and piq: "path_image q \<subseteq> s"
  3136       and papp: "pathfinish p = pathstart q" and qloop: "pathfinish q = pathstart q"
  3114       and papp: "pathfinish p = pathstart q" and qloop: "pathfinish q = pathstart q"
  3137     shows "homotopic_loops s (p +++ q +++ reversepath p) q"
  3115     shows "homotopic_loops s (p +++ q +++ reversepath p) q"
  3138 proof -
  3116 proof -
  3139   have contp: "continuous_on {0..1} p"  using \<open>path p\<close> [unfolded path_def] by blast
  3117   have contp: "continuous_on {0..1} p"  using \<open>path p\<close> [unfolded path_def] by blast
  3140   have contq: "continuous_on {0..1} q"  using \<open>path q\<close> [unfolded path_def] by blast
  3118   have contq: "continuous_on {0..1} q"  using \<open>path q\<close> [unfolded path_def] by blast
  3149     apply (force simp: mult_le_one intro!: continuous_intros)
  3127     apply (force simp: mult_le_one intro!: continuous_intros)
  3150     apply (rule continuous_on_subset [OF contp])
  3128     apply (rule continuous_on_subset [OF contp])
  3151     apply (auto simp: algebra_simps add_increasing2 mult_left_le_one_le)
  3129     apply (auto simp: algebra_simps add_increasing2 mult_left_le_one_le)
  3152     done
  3130     done
  3153   have ps1: "\<And>a b. \<lbrakk>b * 2 \<le> 1; 0 \<le> b; 0 \<le> a; a \<le> 1\<rbrakk> \<Longrightarrow> p ((1 - a) * (2 * b) + a) \<in> s"
  3131   have ps1: "\<And>a b. \<lbrakk>b * 2 \<le> 1; 0 \<le> b; 0 \<le> a; a \<le> 1\<rbrakk> \<Longrightarrow> p ((1 - a) * (2 * b) + a) \<in> s"
  3154     using sum_le_prod1   
  3132     using sum_le_prod1
  3155     by (force simp: algebra_simps add_increasing2 mult_left_le intro: pip [unfolded path_image_def, THEN subsetD])
  3133     by (force simp: algebra_simps add_increasing2 mult_left_le intro: pip [unfolded path_image_def, THEN subsetD])
  3156   have ps2: "\<And>a b. \<lbrakk>\<not> 4 * b \<le> 3; b \<le> 1; 0 \<le> a; a \<le> 1\<rbrakk> \<Longrightarrow> p ((a - 1) * (4 * b - 3) + 1) \<in> s"
  3134   have ps2: "\<And>a b. \<lbrakk>\<not> 4 * b \<le> 3; b \<le> 1; 0 \<le> a; a \<le> 1\<rbrakk> \<Longrightarrow> p ((a - 1) * (4 * b - 3) + 1) \<in> s"
  3157     apply (rule pip [unfolded path_image_def, THEN subsetD])
  3135     apply (rule pip [unfolded path_image_def, THEN subsetD])
  3158     apply (rule image_eqI, blast)
  3136     apply (rule image_eqI, blast)
  3159     apply (simp add: algebra_simps)
  3137     apply (simp add: algebra_simps)
  3160     by (metis add_mono_thms_linordered_semiring(1) affine_ineq linear mult.commute mult.left_neutral mult_right_mono not_le 
  3138     by (metis add_mono_thms_linordered_semiring(1) affine_ineq linear mult.commute mult.left_neutral mult_right_mono not_le
  3161               add.commute zero_le_numeral)
  3139               add.commute zero_le_numeral)
  3162   have qs: "\<And>a b. \<lbrakk>4 * b \<le> 3; \<not> b * 2 \<le> 1\<rbrakk> \<Longrightarrow> q (4 * b - 2) \<in> s"
  3140   have qs: "\<And>a b. \<lbrakk>4 * b \<le> 3; \<not> b * 2 \<le> 1\<rbrakk> \<Longrightarrow> q (4 * b - 2) \<in> s"
  3163     using path_image_def piq by fastforce
  3141     using path_image_def piq by fastforce
  3164   have "homotopic_loops s (p +++ q +++ reversepath p) 
  3142   have "homotopic_loops s (p +++ q +++ reversepath p)
  3165                           (linepath (pathstart q) (pathstart q) +++ q +++ linepath (pathstart q) (pathstart q))"
  3143                           (linepath (pathstart q) (pathstart q) +++ q +++ linepath (pathstart q) (pathstart q))"
  3166     apply (simp add: homotopic_loops_def homotopic_with_def)
  3144     apply (simp add: homotopic_loops_def homotopic_with_def)
  3167     apply (rule_tac x="(\<lambda>y. (subpath (fst y) 1 p +++ q +++ subpath 1 (fst y) p) (snd y))" in exI)
  3145     apply (rule_tac x="(\<lambda>y. (subpath (fst y) 1 p +++ q +++ subpath 1 (fst y) p) (snd y))" in exI)
  3168     apply (simp add: subpath_refl subpath_reversepath)
  3146     apply (simp add: subpath_refl subpath_reversepath)
  3169     apply (intro conjI homotopic_join_lemma)
  3147     apply (intro conjI homotopic_join_lemma)
  3176   proof -
  3154   proof -
  3177     have "homotopic_paths s (linepath (pathfinish q) (pathfinish q) +++ q) q"
  3155     have "homotopic_paths s (linepath (pathfinish q) (pathfinish q) +++ q) q"
  3178       using \<open>path q\<close> homotopic_paths_lid qloop piq by auto
  3156       using \<open>path q\<close> homotopic_paths_lid qloop piq by auto
  3179     hence 1: "\<And>f. homotopic_paths s f q \<or> \<not> homotopic_paths s f (linepath (pathfinish q) (pathfinish q) +++ q)"
  3157     hence 1: "\<And>f. homotopic_paths s f q \<or> \<not> homotopic_paths s f (linepath (pathfinish q) (pathfinish q) +++ q)"
  3180       using homotopic_paths_trans by blast
  3158       using homotopic_paths_trans by blast
  3181     hence "homotopic_paths s (linepath (pathfinish q) (pathfinish q) +++ q +++ linepath (pathfinish q) (pathfinish q)) q"    
  3159     hence "homotopic_paths s (linepath (pathfinish q) (pathfinish q) +++ q +++ linepath (pathfinish q) (pathfinish q)) q"
  3182     proof -
  3160     proof -
  3183       have "homotopic_paths s (q +++ linepath (pathfinish q) (pathfinish q)) q"
  3161       have "homotopic_paths s (q +++ linepath (pathfinish q) (pathfinish q)) q"
  3184         by (simp add: \<open>path q\<close> homotopic_paths_rid piq)
  3162         by (simp add: \<open>path q\<close> homotopic_paths_rid piq)
  3185       thus ?thesis
  3163       thus ?thesis
  3186         by (metis (no_types) 1 \<open>path q\<close> homotopic_paths_join homotopic_paths_rinv homotopic_paths_sym 
  3164         by (metis (no_types) 1 \<open>path q\<close> homotopic_paths_join homotopic_paths_rinv homotopic_paths_sym
  3187                   homotopic_paths_trans qloop pathfinish_linepath piq)
  3165                   homotopic_paths_trans qloop pathfinish_linepath piq)
  3188     qed 
  3166     qed
  3189     thus ?thesis
  3167     thus ?thesis
  3190       by (metis (no_types) qloop homotopic_loops_sym homotopic_paths_imp_homotopic_loops homotopic_paths_imp_pathfinish homotopic_paths_sym)
  3168       by (metis (no_types) qloop homotopic_loops_sym homotopic_paths_imp_homotopic_loops homotopic_paths_imp_pathfinish homotopic_paths_sym)
  3191   qed
  3169   qed
  3192   ultimately show ?thesis
  3170   ultimately show ?thesis
  3193     by (blast intro: homotopic_loops_trans)
  3171     by (blast intro: homotopic_loops_trans)
  3194 qed
  3172 qed
  3195 
  3173 
       
  3174 
       
  3175 subsection\<open> Homotopy of "nearby" function, paths and loops.\<close>
       
  3176 
       
  3177 lemma homotopic_with_linear:
       
  3178   fixes f g :: "_ \<Rightarrow> 'b::real_normed_vector"
       
  3179   assumes contf: "continuous_on s f"
       
  3180       and contg:"continuous_on s g"
       
  3181       and sub: "\<And>x. x \<in> s \<Longrightarrow> closed_segment (f x) (g x) \<subseteq> t"
       
  3182     shows "homotopic_with (\<lambda>z. True) s t f g"
       
  3183   apply (simp add: homotopic_with_def)
       
  3184   apply (rule_tac x="\<lambda>y. ((1 - (fst y)) *\<^sub>R f(snd y) + (fst y) *\<^sub>R g(snd y))" in exI)
       
  3185   apply (intro conjI)
       
  3186   apply (rule subset_refl continuous_intros continuous_on_subset [OF contf] continuous_on_compose2 [where g=f]
       
  3187                                             continuous_on_subset [OF contg] continuous_on_compose2 [where g=g]| simp)+
       
  3188   using sub closed_segment_def apply fastforce+
       
  3189   done
       
  3190 
       
  3191 lemma homotopic_paths_linear:
       
  3192   fixes g h :: "real \<Rightarrow> 'a::real_normed_vector"
       
  3193   assumes "path g" "path h" "pathstart h = pathstart g" "pathfinish h = pathfinish g"
       
  3194           "\<And>t x. t \<in> {0..1} \<Longrightarrow> closed_segment (g t) (h t) \<subseteq> s"
       
  3195     shows "homotopic_paths s g h"
       
  3196   using assms
       
  3197   unfolding path_def
       
  3198   apply (simp add: pathstart_def pathfinish_def homotopic_paths_def homotopic_with_def)
       
  3199   apply (rule_tac x="\<lambda>y. ((1 - (fst y)) *\<^sub>R g(snd y) + (fst y) *\<^sub>R h(snd y))" in exI)
       
  3200   apply (auto intro!: continuous_intros intro: continuous_on_compose2 [where g=g] continuous_on_compose2 [where g=h] )
       
  3201   apply (force simp: closed_segment_def)
       
  3202   apply (simp_all add: algebra_simps)
       
  3203   done
       
  3204 
       
  3205 lemma homotopic_loops_linear:
       
  3206   fixes g h :: "real \<Rightarrow> 'a::real_normed_vector"
       
  3207   assumes "path g" "path h" "pathfinish g = pathstart g" "pathfinish h = pathstart h"
       
  3208           "\<And>t x. t \<in> {0..1} \<Longrightarrow> closed_segment (g t) (h t) \<subseteq> s"
       
  3209     shows "homotopic_loops s g h"
       
  3210   using assms
       
  3211   unfolding path_def
       
  3212   apply (simp add: pathstart_def pathfinish_def homotopic_loops_def homotopic_with_def)
       
  3213   apply (rule_tac x="\<lambda>y. ((1 - (fst y)) *\<^sub>R g(snd y) + (fst y) *\<^sub>R h(snd y))" in exI)
       
  3214   apply (auto intro!: continuous_intros intro: continuous_on_compose2 [where g=g] continuous_on_compose2 [where g=h])
       
  3215   apply (force simp: closed_segment_def)
       
  3216   done
       
  3217 
       
  3218 lemma homotopic_paths_nearby_explicit:
       
  3219   assumes "path g" "path h" "pathstart h = pathstart g" "pathfinish h = pathfinish g"
       
  3220       and no: "\<And>t x. \<lbrakk>t \<in> {0..1}; x \<notin> s\<rbrakk> \<Longrightarrow> norm(h t - g t) < norm(g t - x)"
       
  3221     shows "homotopic_paths s g h"
       
  3222   apply (rule homotopic_paths_linear [OF assms(1-4)])
       
  3223   by (metis no segment_bound(1) subsetI norm_minus_commute not_le)
       
  3224 
       
  3225 lemma homotopic_loops_nearby_explicit:
       
  3226   assumes "path g" "path h" "pathfinish g = pathstart g" "pathfinish h = pathstart h"
       
  3227       and no: "\<And>t x. \<lbrakk>t \<in> {0..1}; x \<notin> s\<rbrakk> \<Longrightarrow> norm(h t - g t) < norm(g t - x)"
       
  3228     shows "homotopic_loops s g h"
       
  3229   apply (rule homotopic_loops_linear [OF assms(1-4)])
       
  3230   by (metis no segment_bound(1) subsetI norm_minus_commute not_le)
       
  3231 
       
  3232 lemma homotopic_nearby_paths:
       
  3233   fixes g h :: "real \<Rightarrow> 'a::euclidean_space"
       
  3234   assumes "path g" "open s" "path_image g \<subseteq> s"
       
  3235     shows "\<exists>e. 0 < e \<and>
       
  3236                (\<forall>h. path h \<and>
       
  3237                     pathstart h = pathstart g \<and> pathfinish h = pathfinish g \<and>
       
  3238                     (\<forall>t \<in> {0..1}. norm(h t - g t) < e) \<longrightarrow> homotopic_paths s g h)"
       
  3239 proof -
       
  3240   obtain e where "e > 0" and e: "\<And>x y. x \<in> path_image g \<Longrightarrow> y \<in> - s \<Longrightarrow> e \<le> dist x y"
       
  3241     using separate_compact_closed [of "path_image g" "-s"] assms by force
       
  3242   show ?thesis
       
  3243     apply (intro exI conjI)
       
  3244     using e [unfolded dist_norm]
       
  3245     apply (auto simp: intro!: homotopic_paths_nearby_explicit assms  \<open>e > 0\<close>)
       
  3246     by (metis atLeastAtMost_iff imageI le_less_trans not_le path_image_def)
       
  3247 qed
       
  3248 
       
  3249 lemma homotopic_nearby_loops:
       
  3250   fixes g h :: "real \<Rightarrow> 'a::euclidean_space"
       
  3251   assumes "path g" "open s" "path_image g \<subseteq> s" "pathfinish g = pathstart g"
       
  3252     shows "\<exists>e. 0 < e \<and>
       
  3253                (\<forall>h. path h \<and> pathfinish h = pathstart h \<and>
       
  3254                     (\<forall>t \<in> {0..1}. norm(h t - g t) < e) \<longrightarrow> homotopic_loops s g h)"
       
  3255 proof -
       
  3256   obtain e where "e > 0" and e: "\<And>x y. x \<in> path_image g \<Longrightarrow> y \<in> - s \<Longrightarrow> e \<le> dist x y"
       
  3257     using separate_compact_closed [of "path_image g" "-s"] assms by force
       
  3258   show ?thesis
       
  3259     apply (intro exI conjI)
       
  3260     using e [unfolded dist_norm]
       
  3261     apply (auto simp: intro!: homotopic_loops_nearby_explicit assms  \<open>e > 0\<close>)
       
  3262     by (metis atLeastAtMost_iff imageI le_less_trans not_le path_image_def)
       
  3263 qed
       
  3264 
  3196 end
  3265 end