src/HOL/Multivariate_Analysis/Path_Connected.thy
changeset 61694 6571c78c9667
parent 61518 ff12606337e9
child 61699 a81dc5c4d6a9
equal deleted inserted replaced
61693:f6b9f528c89c 61694:6571c78c9667
   425 
   425 
   426 subsection\<open>The operations on paths\<close>
   426 subsection\<open>The operations on paths\<close>
   427 
   427 
   428 lemma path_image_subset_reversepath: "path_image(reversepath g) \<le> path_image g"
   428 lemma path_image_subset_reversepath: "path_image(reversepath g) \<le> path_image g"
   429   by (auto simp: path_image_def reversepath_def)
   429   by (auto simp: path_image_def reversepath_def)
   430 
       
   431 lemma continuous_on_op_minus: "continuous_on (s::real set) (op - x)"
       
   432   by (rule continuous_intros | simp)+
       
   433 
   430 
   434 lemma path_imp_reversepath: "path g \<Longrightarrow> path(reversepath g)"
   431 lemma path_imp_reversepath: "path g \<Longrightarrow> path(reversepath g)"
   435   apply (auto simp: path_def reversepath_def)
   432   apply (auto simp: path_def reversepath_def)
   436   using continuous_on_compose [of "{0..1}" "\<lambda>x. 1 - x" g]
   433   using continuous_on_compose [of "{0..1}" "\<lambda>x. 1 - x" g]
   437   apply (auto simp: continuous_on_op_minus)
   434   apply (auto simp: continuous_on_op_minus)
  1139 
  1136 
  1140 lemma path_connected_component: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. path_component s x y)"
  1137 lemma path_connected_component: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. \<forall>y\<in>s. path_component s x y)"
  1141   unfolding path_connected_def path_component_def by auto
  1138   unfolding path_connected_def path_component_def by auto
  1142 
  1139 
  1143 lemma path_connected_component_set: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. path_component_set s x = s)"
  1140 lemma path_connected_component_set: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. path_component_set s x = s)"
  1144   unfolding path_connected_component path_component_subset 
  1141   unfolding path_connected_component path_component_subset
  1145   using path_component_mem by blast
  1142   using path_component_mem by blast
  1146 
  1143 
  1147 lemma path_component_maximal:
  1144 lemma path_component_maximal:
  1148      "\<lbrakk>x \<in> t; path_connected t; t \<subseteq> s\<rbrakk> \<Longrightarrow> t \<subseteq> (path_component_set s x)"
  1145      "\<lbrakk>x \<in> t; path_connected t; t \<subseteq> s\<rbrakk> \<Longrightarrow> t \<subseteq> (path_component_set s x)"
  1149   by (metis path_component_mono path_connected_component_set)
  1146   by (metis path_component_mono path_connected_component_set)
  2453     shows "\<lbrakk>bounded s; DIM('a) \<ge> 2\<rbrakk> \<Longrightarrow> (c \<in> components (- s) \<and> ~bounded c \<longleftrightarrow> c = outside s)"
  2450     shows "\<lbrakk>bounded s; DIM('a) \<ge> 2\<rbrakk> \<Longrightarrow> (c \<in> components (- s) \<and> ~bounded c \<longleftrightarrow> c = outside s)"
  2454   apply (rule iffI)
  2451   apply (rule iffI)
  2455   apply (metis cobounded_unique_unbounded_components connected_outside double_compl outside_bounded_nonempty outside_in_components unbounded_outside)
  2452   apply (metis cobounded_unique_unbounded_components connected_outside double_compl outside_bounded_nonempty outside_in_components unbounded_outside)
  2456   by (simp add: connected_outside outside_bounded_nonempty outside_in_components unbounded_outside)
  2453   by (simp add: connected_outside outside_bounded_nonempty outside_in_components unbounded_outside)
  2457 
  2454 
       
  2455 section\<open> Homotopy of maps p,q : X=>Y with property P of all intermediate maps.\<close>
       
  2456 
       
  2457 text\<open> We often just want to require that it fixes some subset, but to take in
       
  2458   the case of a loop homotopy, it's convenient to have a general property P.\<close>
       
  2459 
       
  2460 definition homotopic_with ::
       
  2461   "[('a::topological_space \<Rightarrow> 'b::topological_space) \<Rightarrow> bool, 'a set, 'b set, 'a \<Rightarrow> 'b, 'a \<Rightarrow> 'b] \<Rightarrow> bool"
       
  2462 where
       
  2463  "homotopic_with P X Y p q \<equiv>
       
  2464    (\<exists>h:: real \<times> 'a \<Rightarrow> 'b.
       
  2465        continuous_on ({0..1} \<times> X) h \<and>
       
  2466        h ` ({0..1} \<times> X) \<subseteq> Y \<and>
       
  2467        (\<forall>x. h(0, x) = p x) \<and>
       
  2468        (\<forall>x. h(1, x) = q x) \<and>
       
  2469        (\<forall>t \<in> {0..1}. P(\<lambda>x. h(t, x))))"
       
  2470 
       
  2471 
       
  2472 text\<open> We often want to just localize the ending function equality or whatever.\<close>
       
  2473 proposition homotopic_with:
       
  2474   fixes X :: "'a::topological_space set" and Y :: "'b::topological_space set"
       
  2475   assumes "\<And>h k. (\<And>x. x \<in> X \<Longrightarrow> h x = k x) \<Longrightarrow> (P h \<longleftrightarrow> P k)"
       
  2476   shows "homotopic_with P X Y p q \<longleftrightarrow>
       
  2477            (\<exists>h :: real \<times> 'a \<Rightarrow> 'b.
       
  2478               continuous_on ({0..1} \<times> X) h \<and>
       
  2479               h ` ({0..1} \<times> X) \<subseteq> Y \<and>
       
  2480               (\<forall>x \<in> X. h(0,x) = p x) \<and>
       
  2481               (\<forall>x \<in> X. h(1,x) = q x) \<and>
       
  2482               (\<forall>t \<in> {0..1}. P(\<lambda>x. h(t, x))))"
       
  2483   unfolding homotopic_with_def
       
  2484   apply (rule iffI, blast, clarify)
       
  2485   apply (rule_tac x="\<lambda>(u,v). if v \<in> X then h(u,v) else if u = 0 then p v else q v" in exI)
       
  2486   apply (auto simp:)
       
  2487   apply (force elim: continuous_on_eq)
       
  2488   apply (drule_tac x=t in bspec, force)
       
  2489   apply (subst assms; simp)
       
  2490   done
       
  2491 
       
  2492 proposition homotopic_with_eq:
       
  2493    assumes h: "homotopic_with P X Y f g"
       
  2494        and f': "\<And>x. x \<in> X \<Longrightarrow> f' x = f x"
       
  2495        and g': "\<And>x. x \<in> X \<Longrightarrow> g' x = g x"
       
  2496        and P:  "(\<And>h k. (\<And>x. x \<in> X \<Longrightarrow> h x = k x) \<Longrightarrow> (P h \<longleftrightarrow> P k))"
       
  2497    shows "homotopic_with P X Y f' g'"
       
  2498   using h unfolding homotopic_with_def
       
  2499   apply safe
       
  2500   apply (rule_tac x="\<lambda>(u,v). if v \<in> X then h(u,v) else if u = 0 then f' v else g' v" in exI)
       
  2501   apply (simp add: f' g', safe)
       
  2502   apply (fastforce intro: continuous_on_eq)
       
  2503   apply fastforce
       
  2504   apply (subst P; fastforce)
       
  2505   done
       
  2506 
       
  2507 proposition homotopic_with_equal:
       
  2508    assumes contf: "continuous_on X f" and fXY: "f ` X \<subseteq> Y"
       
  2509        and gf: "\<And>x. x \<in> X \<Longrightarrow> g x = f x"
       
  2510        and P:  "P f" "P g"
       
  2511    shows "homotopic_with P X Y f g"
       
  2512   unfolding homotopic_with_def
       
  2513   apply (rule_tac x="\<lambda>(u,v). if u = 1 then g v else f v" in exI)
       
  2514   using assms
       
  2515   apply (intro conjI)
       
  2516   apply (rule continuous_on_eq [where f = "f o snd"])
       
  2517   apply (rule continuous_intros | force)+
       
  2518   apply clarify
       
  2519   apply (case_tac "t=1"; force)
       
  2520   done
       
  2521 
       
  2522 
       
  2523 lemma image_Pair_const: "(\<lambda>x. (x, c)) ` A = A \<times> {c}"
       
  2524   by (auto simp:)
       
  2525 
       
  2526 lemma homotopic_constant_maps:
       
  2527    "homotopic_with (\<lambda>x. True) s t (\<lambda>x. a) (\<lambda>x. b) \<longleftrightarrow> s = {} \<or> path_component t a b"
       
  2528 proof (cases "s = {} \<or> t = {}")
       
  2529   case True with continuous_on_const show ?thesis
       
  2530     by (auto simp: homotopic_with path_component_def)
       
  2531 next
       
  2532   case False
       
  2533   then obtain c where "c \<in> s" by blast
       
  2534   show ?thesis
       
  2535   proof
       
  2536     assume "homotopic_with (\<lambda>x. True) s t (\<lambda>x. a) (\<lambda>x. b)"
       
  2537     then obtain h :: "real \<times> 'a \<Rightarrow> 'b"
       
  2538         where conth: "continuous_on ({0..1} \<times> s) h"
       
  2539           and h: "h ` ({0..1} \<times> s) \<subseteq> t" "(\<forall>x\<in>s. h (0, x) = a)" "(\<forall>x\<in>s. h (1, x) = b)"
       
  2540       by (auto simp: homotopic_with)
       
  2541     have "continuous_on {0..1} (h \<circ> (\<lambda>t. (t, c)))"
       
  2542       apply (rule continuous_intros conth | simp add: image_Pair_const)+
       
  2543       apply (blast intro:  \<open>c \<in> s\<close> continuous_on_subset [OF conth] )
       
  2544       done
       
  2545     with \<open>c \<in> s\<close> h show "s = {} \<or> path_component t a b"
       
  2546       apply (simp_all add: homotopic_with path_component_def)
       
  2547       apply (auto simp:)
       
  2548       apply (drule_tac x="h o (\<lambda>t. (t, c))" in spec)
       
  2549       apply (auto simp: pathstart_def pathfinish_def path_image_def path_def)
       
  2550       done
       
  2551   next
       
  2552     assume "s = {} \<or> path_component t a b"
       
  2553     with False show "homotopic_with (\<lambda>x. True) s t (\<lambda>x. a) (\<lambda>x. b)"
       
  2554       apply (clarsimp simp: homotopic_with path_component_def pathstart_def pathfinish_def path_image_def path_def)
       
  2555       apply (rule_tac x="g o fst" in exI)
       
  2556       apply (rule conjI continuous_intros | force)+
       
  2557       done
       
  2558   qed
       
  2559 qed
       
  2560 
       
  2561 
       
  2562 subsection\<open> Trivial properties.\<close>
       
  2563 
       
  2564 lemma homotopic_with_imp_property: "homotopic_with P X Y f g \<Longrightarrow> P f \<and> P g"
       
  2565   unfolding homotopic_with_def Ball_def
       
  2566   apply clarify
       
  2567   apply (frule_tac x=0 in spec)
       
  2568   apply (drule_tac x=1 in spec)
       
  2569   apply (auto simp:)
       
  2570   done
       
  2571 
       
  2572 lemma continuous_on_o_Pair: "\<lbrakk>continuous_on (T \<times> X) h; t \<in> T\<rbrakk> \<Longrightarrow> continuous_on X (h o Pair t)"
       
  2573   by (fast intro: continuous_intros elim!: continuous_on_subset)
       
  2574 
       
  2575 lemma homotopic_with_imp_continuous:
       
  2576     assumes "homotopic_with P X Y f g"
       
  2577     shows "continuous_on X f \<and> continuous_on X g"
       
  2578 proof -
       
  2579   obtain h :: "real \<times> 'a \<Rightarrow> 'b"
       
  2580     where conth: "continuous_on ({0..1} \<times> X) h"
       
  2581       and h: "\<forall>x. h (0, x) = f x" "\<forall>x. h (1, x) = g x"
       
  2582     using assms by (auto simp: homotopic_with_def)
       
  2583   have *: "t \<in> {0..1} \<Longrightarrow> continuous_on X (h o (\<lambda>x. (t,x)))" for t
       
  2584     by (rule continuous_intros continuous_on_subset [OF conth] | force)+
       
  2585   show ?thesis
       
  2586     using h *[of 0] *[of 1] by auto
       
  2587 qed
       
  2588 
       
  2589 proposition homotopic_with_imp_subset1:
       
  2590      "homotopic_with P X Y f g \<Longrightarrow> f ` X \<subseteq> Y"
       
  2591   by (simp add: homotopic_with_def image_subset_iff) (metis atLeastAtMost_iff order_refl zero_le_one)
       
  2592 
       
  2593 proposition homotopic_with_imp_subset2:
       
  2594      "homotopic_with P X Y f g \<Longrightarrow> g ` X \<subseteq> Y"
       
  2595   by (simp add: homotopic_with_def image_subset_iff) (metis atLeastAtMost_iff order_refl zero_le_one)
       
  2596 
       
  2597 proposition homotopic_with_mono:
       
  2598     assumes hom: "homotopic_with P X Y f g"
       
  2599         and Q: "\<And>h. \<lbrakk>continuous_on X h; image h X \<subseteq> Y \<and> P h\<rbrakk> \<Longrightarrow> Q h"
       
  2600       shows "homotopic_with Q X Y f g"
       
  2601   using hom
       
  2602   apply (simp add: homotopic_with_def)
       
  2603   apply (erule ex_forward)
       
  2604   apply (force simp: intro!: Q dest: continuous_on_o_Pair)
       
  2605   done
       
  2606 
       
  2607 proposition homotopic_with_subset_left:
       
  2608      "\<lbrakk>homotopic_with P X Y f g; Z \<subseteq> X\<rbrakk> \<Longrightarrow> homotopic_with P Z Y f g"
       
  2609   apply (simp add: homotopic_with_def)
       
  2610   apply (fast elim!: continuous_on_subset ex_forward)
       
  2611   done
       
  2612 
       
  2613 proposition homotopic_with_subset_right:
       
  2614      "\<lbrakk>homotopic_with P X Y f g; Y \<subseteq> Z\<rbrakk> \<Longrightarrow> homotopic_with P X Z f g"
       
  2615   apply (simp add: homotopic_with_def)
       
  2616   apply (fast elim!: continuous_on_subset ex_forward)
       
  2617   done
       
  2618 
       
  2619 proposition homotopic_with_compose_continuous_right:
       
  2620     "\<lbrakk>homotopic_with (\<lambda>f. p (f \<circ> h)) X Y f g; continuous_on W h; h ` W \<subseteq> X\<rbrakk>
       
  2621      \<Longrightarrow> homotopic_with p W Y (f o h) (g o h)"
       
  2622   apply (clarsimp simp add: homotopic_with_def)
       
  2623   apply (rename_tac k)
       
  2624   apply (rule_tac x="k o (\<lambda>y. (fst y, h (snd y)))" in exI)
       
  2625   apply (rule conjI continuous_intros continuous_on_compose [where f=snd and g=h, unfolded o_def] | simp)+
       
  2626   apply (erule continuous_on_subset)
       
  2627   apply (fastforce simp: o_def)+
       
  2628   done
       
  2629 
       
  2630 proposition homotopic_compose_continuous_right:
       
  2631      "\<lbrakk>homotopic_with (\<lambda>f. True) X Y f g; continuous_on W h; h ` W \<subseteq> X\<rbrakk>
       
  2632       \<Longrightarrow> homotopic_with (\<lambda>f. True) W Y (f o h) (g o h)"
       
  2633   using homotopic_with_compose_continuous_right by fastforce
       
  2634 
       
  2635 proposition homotopic_with_compose_continuous_left:
       
  2636      "\<lbrakk>homotopic_with (\<lambda>f. p (h \<circ> f)) X Y f g; continuous_on Y h; h ` Y \<subseteq> Z\<rbrakk>
       
  2637       \<Longrightarrow> homotopic_with p X Z (h o f) (h o g)"
       
  2638   apply (clarsimp simp add: homotopic_with_def)
       
  2639   apply (rename_tac k)
       
  2640   apply (rule_tac x="h o k" in exI)
       
  2641   apply (rule conjI continuous_intros continuous_on_compose [where f=snd and g=h, unfolded o_def] | simp)+
       
  2642   apply (erule continuous_on_subset)
       
  2643   apply (fastforce simp: o_def)+
       
  2644   done
       
  2645 
       
  2646 proposition homotopic_compose_continuous_left:
       
  2647    "homotopic_with (\<lambda>f. True) X Y f g \<and>
       
  2648         continuous_on Y h \<and> image h Y \<subseteq> Z
       
  2649         \<Longrightarrow> homotopic_with (\<lambda>f. True) X Z (h o f) (h o g)"
       
  2650   using homotopic_with_compose_continuous_left by fastforce
       
  2651 
       
  2652 proposition homotopic_with_Pair:
       
  2653    assumes hom: "homotopic_with p s t f g" "homotopic_with p' s' t' f' g'"
       
  2654        and q: "\<And>f g. \<lbrakk>p f; p' g\<rbrakk> \<Longrightarrow> q(\<lambda>(x,y). (f x, g y))"
       
  2655      shows "homotopic_with q (s \<times> s') (t \<times> t')
       
  2656                   (\<lambda>(x,y). (f x, f' y)) (\<lambda>(x,y). (g x, g' y))"
       
  2657   using hom
       
  2658   apply (clarsimp simp add: homotopic_with_def)
       
  2659   apply (rename_tac k k')
       
  2660   apply (rule_tac x="\<lambda>z. ((k o (\<lambda>x. (fst x, fst (snd x)))) z, (k' o (\<lambda>x. (fst x, snd (snd x)))) z)" in exI)
       
  2661   apply (rule conjI continuous_intros | erule continuous_on_subset | clarsimp)+
       
  2662   apply (auto intro!: q [unfolded case_prod_unfold])
       
  2663   done
       
  2664 
       
  2665 lemma homotopic_on_empty: "homotopic_with (\<lambda>x. True) {} t f g"
       
  2666   by (metis continuous_on_def empty_iff homotopic_with_equal image_subset_iff)
       
  2667 
       
  2668 
       
  2669 text\<open>Homotopy with P is an equivalence relation (on continuous functions mapping X into Y that satisfy P,
       
  2670      though this only affects reflexivity.\<close>
       
  2671 
       
  2672 
       
  2673 proposition homotopic_with_refl:
       
  2674    "homotopic_with P X Y f f \<longleftrightarrow> continuous_on X f \<and> image f X \<subseteq> Y \<and> P f"
       
  2675   apply (rule iffI)
       
  2676   using homotopic_with_imp_continuous homotopic_with_imp_property homotopic_with_imp_subset2 apply blast
       
  2677   apply (simp add: homotopic_with_def)
       
  2678   apply (rule_tac x="f o snd" in exI)
       
  2679   apply (rule conjI continuous_intros | force)+
       
  2680   done
       
  2681 
       
  2682 lemma homotopic_with_symD:
       
  2683   fixes X :: "'a::real_normed_vector set"
       
  2684     assumes "homotopic_with P X Y f g"
       
  2685       shows "homotopic_with P X Y g f"
       
  2686   using assms
       
  2687   apply (clarsimp simp add: homotopic_with_def)
       
  2688   apply (rename_tac h)
       
  2689   apply (rule_tac x="h o (\<lambda>y. (1 - fst y, snd y))" in exI)
       
  2690   apply (rule conjI continuous_intros | erule continuous_on_subset | force simp add: image_subset_iff)+
       
  2691   done
       
  2692 
       
  2693 proposition homotopic_with_sym:
       
  2694     fixes X :: "'a::real_normed_vector set"
       
  2695     shows "homotopic_with P X Y f g \<longleftrightarrow> homotopic_with P X Y g f"
       
  2696   using homotopic_with_symD by blast
       
  2697 
       
  2698 lemma split_01_prod: "{0..1::real} \<times> X = ({0..1/2} \<times> X) \<union> ({1/2..1} \<times> X)"
       
  2699   by force
       
  2700 
       
  2701 proposition homotopic_with_trans:
       
  2702     fixes X :: "'a::real_normed_vector set"
       
  2703     assumes "homotopic_with P X Y f g" and "homotopic_with P X Y g h"
       
  2704       shows "homotopic_with P X Y f h"
       
  2705 proof -
       
  2706   have clo1: "closedin (subtopology euclidean ({0..1/2} \<times> X \<union> {1/2..1} \<times> X)) ({0..1/2::real} \<times> X)"
       
  2707     apply (simp add: closedin_closed split_01_prod [symmetric])
       
  2708     apply (rule_tac x="{0..1/2} \<times> UNIV" in exI)
       
  2709     apply (force simp add: closed_Times)
       
  2710     done
       
  2711   have clo2: "closedin (subtopology euclidean ({0..1/2} \<times> X \<union> {1/2..1} \<times> X)) ({1/2..1::real} \<times> X)"
       
  2712     apply (simp add: closedin_closed split_01_prod [symmetric])
       
  2713     apply (rule_tac x="{1/2..1} \<times> UNIV" in exI)
       
  2714     apply (force simp add: closed_Times)
       
  2715     done
       
  2716   { fix k1 k2:: "real \<times> 'a \<Rightarrow> 'b"
       
  2717     assume cont: "continuous_on ({0..1} \<times> X) k1" "continuous_on ({0..1} \<times> X) k2"
       
  2718        and Y: "k1 ` ({0..1} \<times> X) \<subseteq> Y" "k2 ` ({0..1} \<times> X) \<subseteq> Y"
       
  2719        and geq: "\<forall>x. k1 (1, x) = g x" "\<forall>x. k2 (0, x) = g x"
       
  2720        and k12: "\<forall>x. k1 (0, x) = f x" "\<forall>x. k2 (1, x) = h x"
       
  2721        and P:   "\<forall>t\<in>{0..1}. P (\<lambda>x. k1 (t, x))" "\<forall>t\<in>{0..1}. P (\<lambda>x. k2 (t, x))"
       
  2722     def k \<equiv> "\<lambda>y. if fst y \<le> 1 / 2 then (k1 o (\<lambda>x. (2 *\<^sub>R fst x, snd x))) y
       
  2723                                    else (k2 o (\<lambda>x. (2 *\<^sub>R fst x -1, snd x))) y"
       
  2724     have keq: "k1 (2 * u, v) = k2 (2 * u - 1, v)" if "u = 1/2"  for u v
       
  2725       by (simp add: geq that)
       
  2726     have "continuous_on ({0..1} \<times> X) k"
       
  2727       using cont
       
  2728       apply (simp add: split_01_prod k_def)
       
  2729       apply (rule clo1 clo2 continuous_on_cases_local continuous_intros | erule continuous_on_subset | simp add: linear image_subset_iff)+
       
  2730       apply (force simp add: keq)
       
  2731       done
       
  2732     moreover have "k ` ({0..1} \<times> X) \<subseteq> Y"
       
  2733       using Y by (force simp add: k_def)
       
  2734     moreover have "\<forall>x. k (0, x) = f x"
       
  2735       by (simp add: k_def k12)
       
  2736     moreover have "(\<forall>x. k (1, x) = h x)"
       
  2737       by (simp add: k_def k12)
       
  2738     moreover have "\<forall>t\<in>{0..1}. P (\<lambda>x. k (t, x))"
       
  2739       using P
       
  2740       apply (clarsimp simp add: k_def)
       
  2741       apply (case_tac "t \<le> 1/2")
       
  2742       apply (auto simp:)
       
  2743       done
       
  2744     ultimately have *: "\<exists>k :: real \<times> 'a \<Rightarrow> 'b.
       
  2745                        continuous_on ({0..1} \<times> X) k \<and> k ` ({0..1} \<times> X) \<subseteq> Y \<and>
       
  2746                        (\<forall>x. k (0, x) = f x) \<and> (\<forall>x. k (1, x) = h x) \<and> (\<forall>t\<in>{0..1}. P (\<lambda>x. k (t, x)))"
       
  2747       by blast
       
  2748   } note * = this
       
  2749   show ?thesis
       
  2750     using assms by (auto intro: * simp add: homotopic_with_def)
       
  2751 qed
       
  2752 
       
  2753 proposition homotopic_compose:
       
  2754       fixes s :: "'a::real_normed_vector set"
       
  2755       shows "\<lbrakk>homotopic_with (\<lambda>x. True) s t f f'; homotopic_with (\<lambda>x. True) t u g g'\<rbrakk>
       
  2756              \<Longrightarrow> homotopic_with (\<lambda>x. True) s u (g o f) (g' o f')"
       
  2757   apply (rule homotopic_with_trans [where g = "g o f'"])
       
  2758   apply (metis homotopic_compose_continuous_left homotopic_with_imp_continuous homotopic_with_imp_subset1)
       
  2759   by (metis homotopic_compose_continuous_right homotopic_with_imp_continuous homotopic_with_imp_subset2)
       
  2760 
       
  2761 
       
  2762 subsection\<open>Homotopy of paths, maintaining the same endpoints.\<close>
       
  2763 
       
  2764 
       
  2765 definition homotopic_paths :: "['a set, real \<Rightarrow> 'a, real \<Rightarrow> 'a::topological_space] \<Rightarrow> bool"
       
  2766   where
       
  2767      "homotopic_paths s p q \<equiv>
       
  2768        homotopic_with (\<lambda>r. pathstart r = pathstart p \<and> pathfinish r = pathfinish p) {0..1} s p q"
       
  2769 
       
  2770 lemma homotopic_paths:
       
  2771    "homotopic_paths s p q \<longleftrightarrow>
       
  2772       (\<exists>h. continuous_on ({0..1} \<times> {0..1}) h \<and>
       
  2773           h ` ({0..1} \<times> {0..1}) \<subseteq> s \<and>
       
  2774           (\<forall>x \<in> {0..1}. h(0,x) = p x) \<and>
       
  2775           (\<forall>x \<in> {0..1}. h(1,x) = q x) \<and>
       
  2776           (\<forall>t \<in> {0..1::real}. pathstart(h o Pair t) = pathstart p \<and>
       
  2777                         pathfinish(h o Pair t) = pathfinish p))"
       
  2778   by (auto simp: homotopic_paths_def homotopic_with pathstart_def pathfinish_def)
       
  2779 
       
  2780 proposition homotopic_paths_imp_pathstart:
       
  2781      "homotopic_paths s p q \<Longrightarrow> pathstart p = pathstart q"
       
  2782   by (metis (mono_tags, lifting) homotopic_paths_def homotopic_with_imp_property)
       
  2783 
       
  2784 proposition homotopic_paths_imp_pathfinish:
       
  2785      "homotopic_paths s p q \<Longrightarrow> pathfinish p = pathfinish q"
       
  2786   by (metis (mono_tags, lifting) homotopic_paths_def homotopic_with_imp_property)
       
  2787 
       
  2788 lemma homotopic_paths_imp_path:
       
  2789      "homotopic_paths s p q \<Longrightarrow> path p \<and> path q"
       
  2790   using homotopic_paths_def homotopic_with_imp_continuous path_def by blast
       
  2791 
       
  2792 lemma homotopic_paths_imp_subset:
       
  2793      "homotopic_paths s p q \<Longrightarrow> path_image p \<subseteq> s \<and> path_image q \<subseteq> s"
       
  2794   by (simp add: homotopic_paths_def homotopic_with_imp_subset1 homotopic_with_imp_subset2 path_image_def)
       
  2795 
       
  2796 proposition homotopic_paths_refl [simp]: "homotopic_paths s p p \<longleftrightarrow> path p \<and> path_image p \<subseteq> s"
       
  2797 by (simp add: homotopic_paths_def homotopic_with_refl path_def path_image_def)
       
  2798 
       
  2799 proposition homotopic_paths_sym: "homotopic_paths s p q \<longleftrightarrow> homotopic_paths s q p"
       
  2800   by (metis (mono_tags) homotopic_paths_def homotopic_paths_imp_pathfinish homotopic_paths_imp_pathstart homotopic_with_symD)+
       
  2801 
       
  2802 proposition homotopic_paths_trans:
       
  2803      "\<lbrakk>homotopic_paths s p q; homotopic_paths s q r\<rbrakk> \<Longrightarrow> homotopic_paths s p r"
       
  2804   apply (simp add: homotopic_paths_def)
       
  2805   apply (rule homotopic_with_trans, assumption)
       
  2806   by (metis (mono_tags, lifting) homotopic_with_imp_property homotopic_with_mono)
       
  2807 
       
  2808 proposition homotopic_paths_eq:
       
  2809      "\<lbrakk>path p; path_image p \<subseteq> s; \<And>t. t \<in> {0..1} \<Longrightarrow> p t = q t\<rbrakk> \<Longrightarrow> homotopic_paths s p q"
       
  2810   apply (simp add: homotopic_paths_def)
       
  2811   apply (rule homotopic_with_eq)
       
  2812   apply (auto simp: path_def homotopic_with_refl pathstart_def pathfinish_def path_image_def elim: continuous_on_eq)
       
  2813   done
       
  2814 
       
  2815 proposition homotopic_paths_reparametrize:
       
  2816   assumes "path p"
       
  2817       and pips: "path_image p \<subseteq> s"
       
  2818       and contf: "continuous_on {0..1} f"
       
  2819       and f01:"f ` {0..1} \<subseteq> {0..1}"
       
  2820       and [simp]: "f(0) = 0" "f(1) = 1"
       
  2821       and q: "\<And>t. t \<in> {0..1} \<Longrightarrow> q(t) = p(f t)"
       
  2822     shows "homotopic_paths s p q"
       
  2823 proof -
       
  2824   have contp: "continuous_on {0..1} p"
       
  2825     by (metis \<open>path p\<close> path_def)
       
  2826   then have "continuous_on {0..1} (p o f)"
       
  2827     using contf continuous_on_compose continuous_on_subset f01 by blast
       
  2828   then have "path q"
       
  2829     by (simp add: path_def) (metis q continuous_on_cong)
       
  2830   have piqs: "path_image q \<subseteq> s"
       
  2831     by (metis (no_types, hide_lams) pips f01 image_subset_iff path_image_def q)
       
  2832   have fb0: "\<And>a b. \<lbrakk>0 \<le> a; a \<le> 1; 0 \<le> b; b \<le> 1\<rbrakk> \<Longrightarrow> 0 \<le> (1 - a) * f b + a * b"
       
  2833     using f01 by force
       
  2834   have fb1: "\<lbrakk>0 \<le> a; a \<le> 1; 0 \<le> b; b \<le> 1\<rbrakk> \<Longrightarrow> (1 - a) * f b + a * b \<le> 1" for a b
       
  2835     using f01 [THEN subsetD, of "f b"] by (simp add: convex_bound_le)
       
  2836   have "homotopic_paths s q p"
       
  2837   proof (rule homotopic_paths_trans)
       
  2838     show "homotopic_paths s q (p \<circ> f)"
       
  2839       using q by (force intro: homotopic_paths_eq [OF  \<open>path q\<close> piqs])
       
  2840   next
       
  2841     show "homotopic_paths s (p \<circ> f) p"
       
  2842       apply (simp add: homotopic_paths_def homotopic_with_def)
       
  2843       apply (rule_tac x="p o (\<lambda>y. (1 - (fst y)) *\<^sub>R ((f o snd) y) + (fst y) *\<^sub>R snd y)"  in exI)
       
  2844       apply (rule conjI contf continuous_intros continuous_on_subset [OF contp] | simp)+
       
  2845       using pips [unfolded path_image_def]
       
  2846       apply (auto simp: fb0 fb1 pathstart_def pathfinish_def)
       
  2847       done
       
  2848   qed
       
  2849   then show ?thesis
       
  2850     by (simp add: homotopic_paths_sym)
       
  2851 qed
       
  2852 
       
  2853 lemma homotopic_paths_subset: "\<lbrakk>homotopic_paths s p q; s \<subseteq> t\<rbrakk> \<Longrightarrow> homotopic_paths t p q"
       
  2854   using homotopic_paths_def homotopic_with_subset_right by blast
       
  2855 
       
  2856 
       
  2857 text\<open> A slightly ad-hoc but useful lemma in constructing homotopies.\<close>
       
  2858 lemma homotopic_join_lemma:
       
  2859   fixes q :: "[real,real] \<Rightarrow> 'a::topological_space"
       
  2860   assumes p: "continuous_on ({0..1} \<times> {0..1}) (\<lambda>y. p (fst y) (snd y))"
       
  2861       and q: "continuous_on ({0..1} \<times> {0..1}) (\<lambda>y. q (fst y) (snd y))"
       
  2862       and pf: "\<And>t. t \<in> {0..1} \<Longrightarrow> pathfinish(p t) = pathstart(q t)"
       
  2863     shows "continuous_on ({0..1} \<times> {0..1}) (\<lambda>y. (p(fst y) +++ q(fst y)) (snd y))"
       
  2864 proof -
       
  2865   have 1: "(\<lambda>y. p (fst y) (2 * snd y)) = (\<lambda>y. p (fst y) (snd y)) o (\<lambda>y. (fst y, 2 * snd y))"
       
  2866     by (rule ext) (simp )
       
  2867   have 2: "(\<lambda>y. q (fst y) (2 * snd y - 1)) = (\<lambda>y. q (fst y) (snd y)) o (\<lambda>y. (fst y, 2 * snd y - 1))"
       
  2868     by (rule ext) (simp )
       
  2869   show ?thesis
       
  2870     apply (simp add: joinpaths_def)
       
  2871     apply (rule continuous_on_cases_le)
       
  2872     apply (simp_all only: 1 2)
       
  2873     apply (rule continuous_intros continuous_on_subset [OF p] continuous_on_subset [OF q] | force)+
       
  2874     using pf
       
  2875     apply (auto simp: mult.commute pathstart_def pathfinish_def)
       
  2876     done
       
  2877 qed
       
  2878 
       
  2879 text\<open> Congruence properties of homotopy w.r.t. path-combining operations.\<close>
       
  2880 
       
  2881 lemma homotopic_paths_reversepath_D:
       
  2882       assumes "homotopic_paths s p q"
       
  2883       shows   "homotopic_paths s (reversepath p) (reversepath q)"
       
  2884   using assms
       
  2885   apply (simp add: homotopic_paths_def homotopic_with_def, clarify)
       
  2886   apply (rule_tac x="h o (\<lambda>x. (fst x, 1 - snd x))" in exI)
       
  2887   apply (rule conjI continuous_intros)+
       
  2888   apply (auto simp: reversepath_def pathstart_def pathfinish_def elim!: continuous_on_subset)
       
  2889   done
       
  2890 
       
  2891 proposition homotopic_paths_reversepath:
       
  2892      "homotopic_paths s (reversepath p) (reversepath q) \<longleftrightarrow> homotopic_paths s p q"
       
  2893   using homotopic_paths_reversepath_D by force
       
  2894 
       
  2895 
       
  2896 proposition homotopic_paths_join:
       
  2897     "\<lbrakk>homotopic_paths s p p'; homotopic_paths s q q'; pathfinish p = pathstart q\<rbrakk> \<Longrightarrow> homotopic_paths s (p +++ q) (p' +++ q')"
       
  2898   apply (simp add: homotopic_paths_def homotopic_with_def, clarify)
       
  2899   apply (rename_tac k1 k2)
       
  2900   apply (rule_tac x="(\<lambda>y. ((k1 o Pair (fst y)) +++ (k2 o Pair (fst y))) (snd y))" in exI)
       
  2901   apply (rule conjI continuous_intros homotopic_join_lemma)+
       
  2902   apply (auto simp: joinpaths_def pathstart_def pathfinish_def path_image_def)
       
  2903   done
       
  2904 
       
  2905 proposition homotopic_paths_continuous_image:
       
  2906     "\<lbrakk>homotopic_paths s f g; continuous_on s h; h ` s \<subseteq> t\<rbrakk> \<Longrightarrow> homotopic_paths t (h o f) (h o g)"
       
  2907   unfolding homotopic_paths_def
       
  2908   apply (rule homotopic_with_compose_continuous_left [of _ _ _ s])
       
  2909   apply (auto simp: pathstart_def pathfinish_def elim!: homotopic_with_mono)
       
  2910   done
       
  2911 
  2458 end
  2912 end