New material about paths, and some lemmas
authorpaulson
Tue May 26 21:58:04 2015 +0100 (2015-05-26)
changeset 6030300c06f1315d0
parent 60302 6dcb8aa0966a
child 60304 3f429b7d8eb5
New material about paths, and some lemmas
src/HOL/Finite_Set.thy
src/HOL/Fun.thy
src/HOL/Library/Convex.thy
src/HOL/Library/Countable_Set.thy
src/HOL/Multivariate_Analysis/Brouwer_Fixpoint.thy
src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy
src/HOL/Multivariate_Analysis/Linear_Algebra.thy
src/HOL/Multivariate_Analysis/Path_Connected.thy
src/HOL/Real_Vector_Spaces.thy
     1.1 --- a/src/HOL/Finite_Set.thy	Mon May 25 22:52:17 2015 +0200
     1.2 +++ b/src/HOL/Finite_Set.thy	Tue May 26 21:58:04 2015 +0100
     1.3 @@ -277,7 +277,8 @@
     1.4    then have B_A: "insert x B = f ` A" by simp
     1.5    then obtain y where "x = f y" and "y \<in> A" by blast
     1.6    from B_A `x \<notin> B` have "B = f ` A - {x}" by blast
     1.7 -  with B_A `x \<notin> B` `x = f y` `inj_on f A` `y \<in> A` have "B = f ` (A - {y})" by (simp add: inj_on_image_set_diff)
     1.8 +  with B_A `x \<notin> B` `x = f y` `inj_on f A` `y \<in> A` have "B = f ` (A - {y})" 
     1.9 +    by (simp add: inj_on_image_set_diff Set.Diff_subset)
    1.10    moreover from `inj_on f A` have "inj_on f (A - {y})" by (rule inj_on_diff)
    1.11    ultimately have "finite (A - {y})" by (rule insert.hyps)
    1.12    then show "finite A" by simp
     2.1 --- a/src/HOL/Fun.thy	Mon May 25 22:52:17 2015 +0200
     2.2 +++ b/src/HOL/Fun.thy	Tue May 26 21:58:04 2015 +0100
     2.3 @@ -478,16 +478,14 @@
     2.4  
     2.5  lemma inj_on_image_Int:
     2.6     "[| inj_on f C;  A<=C;  B<=C |] ==> f`(A Int B) = f`A Int f`B"
     2.7 -apply (simp add: inj_on_def, blast)
     2.8 -done
     2.9 +  by (simp add: inj_on_def, blast)
    2.10  
    2.11  lemma inj_on_image_set_diff:
    2.12 -   "[| inj_on f C;  A<=C;  B<=C |] ==> f`(A-B) = f`A - f`B"
    2.13 -apply (simp add: inj_on_def, blast)
    2.14 -done
    2.15 +   "[| inj_on f C;  A-B \<subseteq> C;  B \<subseteq> C |] ==> f`(A-B) = f`A - f`B"
    2.16 +  by (simp add: inj_on_def, blast)
    2.17  
    2.18  lemma image_Int: "inj f ==> f`(A Int B) = f`A Int f`B"
    2.19 -by (simp add: inj_on_def, blast)
    2.20 +  by (simp add: inj_on_def, blast)
    2.21  
    2.22  lemma image_set_diff: "inj f ==> f`(A-B) = f`A - f`B"
    2.23  by (simp add: inj_on_def, blast)
     3.1 --- a/src/HOL/Library/Convex.thy	Mon May 25 22:52:17 2015 +0200
     3.2 +++ b/src/HOL/Library/Convex.thy	Tue May 26 21:58:04 2015 +0100
     3.3 @@ -48,13 +48,13 @@
     3.4    shows "((1 - u) *\<^sub>R a + u *\<^sub>R b) \<in> s"
     3.5    using assms unfolding convex_alt by auto
     3.6  
     3.7 -lemma convex_empty[intro]: "convex {}"
     3.8 +lemma convex_empty[intro,simp]: "convex {}"
     3.9    unfolding convex_def by simp
    3.10  
    3.11 -lemma convex_singleton[intro]: "convex {a}"
    3.12 +lemma convex_singleton[intro,simp]: "convex {a}"
    3.13    unfolding convex_def by (auto simp: scaleR_left_distrib[symmetric])
    3.14  
    3.15 -lemma convex_UNIV[intro]: "convex UNIV"
    3.16 +lemma convex_UNIV[intro,simp]: "convex UNIV"
    3.17    unfolding convex_def by auto
    3.18  
    3.19  lemma convex_Inter: "(\<forall>s\<in>f. convex s) \<Longrightarrow> convex(\<Inter> f)"
     4.1 --- a/src/HOL/Library/Countable_Set.thy	Mon May 25 22:52:17 2015 +0200
     4.2 +++ b/src/HOL/Library/Countable_Set.thy	Tue May 26 21:58:04 2015 +0100
     4.3 @@ -182,6 +182,9 @@
     4.4      by (blast dest: comp_inj_on subset_inj_on intro: countableI)
     4.5  qed
     4.6  
     4.7 +lemma countable_image_inj_on: "countable (f ` A) \<Longrightarrow> inj_on f A \<Longrightarrow> countable A"
     4.8 +  by (metis countable_image the_inv_into_onto)
     4.9 +
    4.10  lemma countable_UN[intro, simp]:
    4.11    fixes I :: "'i set" and A :: "'i => 'a set"
    4.12    assumes I: "countable I"
    4.13 @@ -221,6 +224,9 @@
    4.14  lemma countable_Diff[intro, simp]: "countable A \<Longrightarrow> countable (A - B)"
    4.15    by (blast intro: countable_subset)
    4.16  
    4.17 +lemma countable_insert_eq [simp]: "countable (insert x A) = countable A"
    4.18 +    by auto (metis Diff_insert_absorb countable_Diff insert_absorb)
    4.19 +
    4.20  lemma countable_vimage: "B \<subseteq> range f \<Longrightarrow> countable (f -` B) \<Longrightarrow> countable B"
    4.21    by (metis Int_absorb2 assms countable_image image_vimage_eq)
    4.22  
    4.23 @@ -325,4 +331,7 @@
    4.24    "uncountable A \<Longrightarrow> countable B \<Longrightarrow> uncountable (A - B)"
    4.25    using countable_Un[of B "A - B"] assms by auto
    4.26  
    4.27 +lemma countable_Diff_eq [simp]: "countable (A - {x}) = countable A"
    4.28 +  by (meson countable_Diff countable_empty countable_insert uncountable_minus_countable)
    4.29 +
    4.30  end
     5.1 --- a/src/HOL/Multivariate_Analysis/Brouwer_Fixpoint.thy	Mon May 25 22:52:17 2015 +0200
     5.2 +++ b/src/HOL/Multivariate_Analysis/Brouwer_Fixpoint.thy	Tue May 26 21:58:04 2015 +0100
     5.3 @@ -30,7 +30,7 @@
     5.4    have "f ` (A - {a}) = g ` (A - {a})"
     5.5      by (intro image_cong) (simp_all add: eq)
     5.6    then have "B - {f a} = B - {g a}"
     5.7 -    using f g a by (auto simp: bij_betw_def inj_on_image_set_diff set_eq_iff)
     5.8 +    using f g a  by (auto simp: bij_betw_def inj_on_image_set_diff set_eq_iff Diff_subset)
     5.9    moreover have "f a \<in> B" "g a \<in> B"
    5.10      using f g a by (auto simp: bij_betw_def)
    5.11    ultimately show ?thesis
    5.12 @@ -211,7 +211,7 @@
    5.13      moreover obtain a where "rl a = Suc n" "a \<in> s"
    5.14        by (metis atMost_iff image_iff le_Suc_eq rl)
    5.15      ultimately have n: "{..n} = rl ` (s - {a})"
    5.16 -      by (auto simp add: inj_on_image_set_diff rl)
    5.17 +      by (auto simp add: inj_on_image_set_diff Diff_subset rl)
    5.18      have "{a\<in>s. rl ` (s - {a}) = {..n}} = {a}"
    5.19        using inj_rl `a \<in> s` by (auto simp add: n inj_on_image_eq_iff[OF inj_rl] Diff_subset)
    5.20      then show "card ?S = 1"
    5.21 @@ -234,7 +234,7 @@
    5.22  
    5.23        { fix x assume "x \<in> s" "x \<notin> {a, b}"
    5.24          then have "rl ` s - {rl x} = rl ` ((s - {a}) - {x})"
    5.25 -          by (auto simp: eq inj_on_image_set_diff[OF inj])
    5.26 +          by (auto simp: eq Diff_subset inj_on_image_set_diff[OF inj])
    5.27          also have "\<dots> = rl ` (s - {x})"
    5.28            using ab `x \<notin> {a, b}` by auto
    5.29          also assume "\<dots> = rl ` s"
    5.30 @@ -597,8 +597,8 @@
    5.31        have "\<And>i. Suc ` {..< i} = {..< Suc i} - {0}"
    5.32          by (auto simp: image_iff Ball_def) arith
    5.33        then have upd_Suc: "\<And>i. i \<le> n \<Longrightarrow> (upd\<circ>Suc) ` {..< i} = upd ` {..< Suc i} - {n}"
    5.34 -        using `upd 0 = n`
    5.35 -        by (simp add: image_comp[symmetric] inj_on_image_set_diff[OF inj_upd])
    5.36 +        using `upd 0 = n` upd_inj
    5.37 +        by (auto simp add: image_comp[symmetric] inj_on_image_set_diff[OF inj_upd])
    5.38        have n_in_upd: "\<And>i. n \<in> upd ` {..< Suc i}"
    5.39          using `upd 0 = n` by auto
    5.40  
    5.41 @@ -773,7 +773,7 @@
    5.42        by auto
    5.43      finally have eq: "s - {a} = f' ` {.. n} - {f' n}"
    5.44        unfolding s_eq `a = enum i` `i = 0`
    5.45 -      by (simp add: inj_on_image_set_diff[OF inj_enum] inj_on_image_set_diff[OF inj_f'])
    5.46 +      by (simp add: Diff_subset inj_on_image_set_diff[OF inj_enum] inj_on_image_set_diff[OF inj_f'])
    5.47  
    5.48      have "enum 0 < f' 0"
    5.49        using `n \<noteq> 0` by (simp add: enum_strict_mono f'_eq_enum)
    5.50 @@ -887,9 +887,9 @@
    5.51        by auto
    5.52      finally have eq: "s - {a} = b.enum ` {.. n} - {b.enum 0}"
    5.53        unfolding s_eq `a = enum i` `i = n`
    5.54 -      using inj_on_image_set_diff[OF inj_enum order_refl, of "{n}"]
    5.55 -            inj_on_image_set_diff[OF b.inj_enum order_refl, of "{0}"]
    5.56 -      by (simp add: comp_def)
    5.57 +      using inj_on_image_set_diff[OF inj_enum Diff_subset, of "{n}"]
    5.58 +            inj_on_image_set_diff[OF b.inj_enum Diff_subset, of "{0}"]
    5.59 +      by (simp add: comp_def )
    5.60  
    5.61      have "b.enum 0 \<le> b.enum n"
    5.62        by (simp add: b.enum_mono)
    5.63 @@ -980,8 +980,8 @@
    5.64        by (intro image_cong) auto
    5.65      then have eq: "s - {a} = b.enum ` {.. n} - {b.enum i}"
    5.66        unfolding s_eq `a = enum i`
    5.67 -      using inj_on_image_set_diff[OF inj_enum order_refl `{i} \<subseteq> {..n}`]
    5.68 -            inj_on_image_set_diff[OF b.inj_enum order_refl `{i} \<subseteq> {..n}`]
    5.69 +      using inj_on_image_set_diff[OF inj_enum Diff_subset `{i} \<subseteq> {..n}`]
    5.70 +            inj_on_image_set_diff[OF b.inj_enum Diff_subset `{i} \<subseteq> {..n}`]
    5.71        by (simp add: comp_def)
    5.72  
    5.73      have "a \<noteq> b.enum i"
     6.1 --- a/src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy	Mon May 25 22:52:17 2015 +0200
     6.2 +++ b/src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy	Tue May 26 21:58:04 2015 +0100
     6.3 @@ -384,13 +384,13 @@
     6.4  lemma affine_UNIV[intro]: "affine UNIV"
     6.5    unfolding affine_def by auto
     6.6  
     6.7 -lemma affine_Inter: "(\<forall>s\<in>f. affine s) \<Longrightarrow> affine (\<Inter> f)"
     6.8 +lemma affine_Inter[intro]: "(\<forall>s\<in>f. affine s) \<Longrightarrow> affine (\<Inter> f)"
     6.9    unfolding affine_def by auto
    6.10  
    6.11 -lemma affine_Int: "affine s \<Longrightarrow> affine t \<Longrightarrow> affine (s \<inter> t)"
    6.12 +lemma affine_Int[intro]: "affine s \<Longrightarrow> affine t \<Longrightarrow> affine (s \<inter> t)"
    6.13    unfolding affine_def by auto
    6.14  
    6.15 -lemma affine_affine_hull: "affine(affine hull s)"
    6.16 +lemma affine_affine_hull [simp]: "affine(affine hull s)"
    6.17    unfolding hull_def
    6.18    using affine_Inter[of "{t. affine t \<and> s \<subseteq> t}"] by auto
    6.19  
    6.20 @@ -2355,13 +2355,13 @@
    6.21  lemma affine_hull_translation: "affine hull ((\<lambda>x. a + x) `  S) = (\<lambda>x. a + x) ` (affine hull S)"
    6.22  proof -
    6.23    have "affine ((\<lambda>x. a + x) ` (affine hull S))"
    6.24 -    using affine_translation affine_affine_hull by auto
    6.25 +    using affine_translation affine_affine_hull by blast
    6.26    moreover have "(\<lambda>x. a + x) `  S \<subseteq> (\<lambda>x. a + x) ` (affine hull S)"
    6.27      using hull_subset[of S] by auto
    6.28    ultimately have h1: "affine hull ((\<lambda>x. a + x) `  S) \<subseteq> (\<lambda>x. a + x) ` (affine hull S)"
    6.29      by (metis hull_minimal)
    6.30    have "affine((\<lambda>x. -a + x) ` (affine hull ((\<lambda>x. a + x) `  S)))"
    6.31 -    using affine_translation affine_affine_hull by (auto simp del: uminus_add_conv_diff)
    6.32 +    using affine_translation affine_affine_hull by blast
    6.33    moreover have "(\<lambda>x. -a + x) ` (\<lambda>x. a + x) `  S \<subseteq> (\<lambda>x. -a + x) ` (affine hull ((\<lambda>x. a + x) `  S))"
    6.34      using hull_subset[of "(\<lambda>x. a + x) `  S"] by auto
    6.35    moreover have "S = (\<lambda>x. -a + x) ` (\<lambda>x. a + x) `  S"
    6.36 @@ -2933,7 +2933,7 @@
    6.37    have "dim (affine hull S) \<ge> dim S"
    6.38      using dim_subset by auto
    6.39    moreover have "dim (span S) \<ge> dim (affine hull S)"
    6.40 -    using dim_subset affine_hull_subset_span by auto
    6.41 +    using dim_subset affine_hull_subset_span by blast
    6.42    moreover have "dim (span S) = dim S"
    6.43      using dim_span by auto
    6.44    ultimately show ?thesis by auto
    6.45 @@ -3178,13 +3178,13 @@
    6.46    "rel_interior S = {x \<in> S. \<exists>e. e > 0 \<and> cball x e \<inter> affine hull S \<subseteq> S}"
    6.47    using mem_rel_interior_cball [of _ S] by auto
    6.48  
    6.49 -lemma rel_interior_empty: "rel_interior {} = {}"
    6.50 +lemma rel_interior_empty [simp]: "rel_interior {} = {}"
    6.51     by (auto simp add: rel_interior_def)
    6.52  
    6.53 -lemma affine_hull_sing: "affine hull {a :: 'n::euclidean_space} = {a}"
    6.54 +lemma affine_hull_sing [simp]: "affine hull {a :: 'n::euclidean_space} = {a}"
    6.55    by (metis affine_hull_eq affine_sing)
    6.56  
    6.57 -lemma rel_interior_sing: "rel_interior {a :: 'n::euclidean_space} = {a}"
    6.58 +lemma rel_interior_sing [simp]: "rel_interior {a :: 'n::euclidean_space} = {a}"
    6.59    unfolding rel_interior_ball affine_hull_sing
    6.60    apply auto
    6.61    apply (rule_tac x = "1 :: real" in exI)
    6.62 @@ -3218,6 +3218,12 @@
    6.63      unfolding rel_interior interior_def by auto
    6.64  qed
    6.65  
    6.66 +lemma rel_interior_interior:
    6.67 +  fixes S :: "'n::euclidean_space set"
    6.68 +  assumes "affine hull S = UNIV"
    6.69 +  shows "rel_interior S = interior S"
    6.70 +  using assms unfolding rel_interior interior_def by auto
    6.71 +
    6.72  lemma rel_interior_open:
    6.73    fixes S :: "'n::euclidean_space set"
    6.74    assumes "open S"
    6.75 @@ -3694,7 +3700,7 @@
    6.76      unfolding affine_hull_insert_span_gen span_substd_basis[OF assms,symmetric] * ..
    6.77  qed
    6.78  
    6.79 -lemma affine_hull_convex_hull: "affine hull (convex hull S) = affine hull S"
    6.80 +lemma affine_hull_convex_hull [simp]: "affine hull (convex hull S) = affine hull S"
    6.81    by (metis Int_absorb1 Int_absorb2 convex_hull_subset_affine_hull hull_hull hull_mono hull_subset)
    6.82  
    6.83  
    6.84 @@ -8040,22 +8046,14 @@
    6.85      and "convex T"
    6.86    shows "rel_interior (S \<times> T) = rel_interior S \<times> rel_interior T"
    6.87  proof -
    6.88 -  {
    6.89 -    assume "S = {}"
    6.90 +  { assume "S = {}"
    6.91      then have ?thesis
    6.92 -      apply auto
    6.93 -      using rel_interior_empty
    6.94 -      apply auto
    6.95 -      done
    6.96 +      by auto
    6.97    }
    6.98    moreover
    6.99 -  {
   6.100 -    assume "T = {}"
   6.101 +  { assume "T = {}"
   6.102      then have ?thesis
   6.103 -      apply auto
   6.104 -      using rel_interior_empty
   6.105 -      apply auto
   6.106 -      done
   6.107 +       by auto
   6.108    }
   6.109    moreover
   6.110    {
     7.1 --- a/src/HOL/Multivariate_Analysis/Linear_Algebra.thy	Mon May 25 22:52:17 2015 +0200
     7.2 +++ b/src/HOL/Multivariate_Analysis/Linear_Algebra.thy	Tue May 26 21:58:04 2015 +0100
     7.3 @@ -29,12 +29,7 @@
     7.4    fixes e :: real
     7.5    shows "e > 0 \<Longrightarrow> \<exists>d. 0 < d \<and> (\<forall>y. \<bar>y - x\<bar> < d \<longrightarrow> \<bar>y * y - x * x\<bar> < e)"
     7.6    using isCont_power[OF continuous_ident, of x, unfolded isCont_def LIM_eq, rule_format, of e 2]
     7.7 -  apply (auto simp add: power2_eq_square)
     7.8 -  apply (rule_tac x="s" in exI)
     7.9 -  apply auto
    7.10 -  apply (erule_tac x=y in allE)
    7.11 -  apply auto
    7.12 -  done
    7.13 +  by (force simp add: power2_eq_square)
    7.14  
    7.15  text{* Hence derive more interesting properties of the norm. *}
    7.16  
    7.17 @@ -1594,6 +1589,12 @@
    7.18    shows "independent S \<Longrightarrow> finite S \<and> card S \<le> DIM('a)"
    7.19    using independent_span_bound[OF finite_Basis, of S] by auto
    7.20  
    7.21 +corollary 
    7.22 +  fixes S :: "'a::euclidean_space set"
    7.23 +  assumes "independent S"
    7.24 +  shows independent_imp_finite: "finite S" and independent_card_le:"card S \<le> DIM('a)"
    7.25 +using assms independent_bound by auto
    7.26 +  
    7.27  lemma dependent_biggerset:
    7.28    fixes S :: "'a::euclidean_space set"
    7.29    shows "(finite S \<Longrightarrow> card S > DIM('a)) \<Longrightarrow> dependent S"
    7.30 @@ -1785,7 +1786,7 @@
    7.31    shows "(finite S \<Longrightarrow> card S > dim S) \<Longrightarrow> dependent S"
    7.32    using independent_bound_general[of S] by (metis linorder_not_le)
    7.33  
    7.34 -lemma dim_span:
    7.35 +lemma dim_span [simp]:
    7.36    fixes S :: "'a::euclidean_space set"
    7.37    shows "dim (span S) = dim S"
    7.38  proof -
     8.1 --- a/src/HOL/Multivariate_Analysis/Path_Connected.thy	Mon May 25 22:52:17 2015 +0200
     8.2 +++ b/src/HOL/Multivariate_Analysis/Path_Connected.thy	Tue May 26 21:58:04 2015 +0100
     8.3 @@ -1,5 +1,5 @@
     8.4  (*  Title:      HOL/Multivariate_Analysis/Path_Connected.thy
     8.5 -    Author:     Robert Himmelmann, TU Muenchen
     8.6 +    Author:     Robert Himmelmann, TU Muenchen, and LCP with material from HOL Light
     8.7  *)
     8.8  
     8.9  section {* Continuous paths and path-connected sets *}
    8.10 @@ -8,7 +8,73 @@
    8.11  imports Convex_Euclidean_Space
    8.12  begin
    8.13  
    8.14 -subsection {* Paths. *}
    8.15 +(*FIXME move up?*)
    8.16 +lemma image_add_atLeastAtMost [simp]:
    8.17 +  fixes d::"'a::linordered_idom" shows "(op + d ` {a..b}) = {a+d..b+d}"
    8.18 +  apply auto
    8.19 +  apply (rule_tac x="x-d" in rev_image_eqI, auto)
    8.20 +  done
    8.21 +
    8.22 +lemma image_diff_atLeastAtMost [simp]:
    8.23 +  fixes d::"'a::linordered_idom" shows "(op - d ` {a..b}) = {d-b..d-a}"
    8.24 +  apply auto
    8.25 +  apply (rule_tac x="d-x" in rev_image_eqI, auto)
    8.26 +  done
    8.27 +
    8.28 +lemma image_mult_atLeastAtMost [simp]:
    8.29 +  fixes d::"'a::linordered_field"
    8.30 +  assumes "d>0" shows "(op * d ` {a..b}) = {d*a..d*b}"
    8.31 +  using assms
    8.32 +  apply auto
    8.33 +  apply (rule_tac x="x/d" in rev_image_eqI)
    8.34 +  apply (auto simp: field_simps)
    8.35 +  done
    8.36 +
    8.37 +lemma image_affinity_interval:
    8.38 +  fixes c :: "'a::ordered_real_vector"
    8.39 +  shows "((\<lambda>x. m *\<^sub>R x + c) ` {a..b}) = (if {a..b}={} then {}
    8.40 +            else if 0 <= m then {m *\<^sub>R a + c .. m  *\<^sub>R b + c}
    8.41 +            else {m *\<^sub>R b + c .. m *\<^sub>R a + c})"
    8.42 +  apply (case_tac "m=0", force)
    8.43 +  apply (auto simp: scaleR_left_mono)
    8.44 +  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)
    8.45 +  apply (metis diff_le_eq inverse_inverse_eq order.not_eq_order_implies_strict pos_le_divideR_eq positive_imp_inverse_positive)
    8.46 +  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)
    8.47 +  using le_diff_eq scaleR_le_cancel_left_neg 
    8.48 +  apply fastforce
    8.49 +  done
    8.50 +
    8.51 +lemma image_affinity_atLeastAtMost:
    8.52 +  fixes c :: "'a::linordered_field"
    8.53 +  shows "((\<lambda>x. m*x + c) ` {a..b}) = (if {a..b}={} then {}
    8.54 +            else if 0 \<le> m then {m*a + c .. m *b + c}
    8.55 +            else {m*b + c .. m*a + c})"
    8.56 +  apply (case_tac "m=0", auto)
    8.57 +  apply (rule_tac x="inverse m*(x-c)" in rev_image_eqI, auto simp: field_simps)
    8.58 +  apply (rule_tac x="inverse m*(x-c)" in rev_image_eqI, auto simp: field_simps)
    8.59 +  done
    8.60 +
    8.61 +lemma image_affinity_atLeastAtMost_diff:
    8.62 +  fixes c :: "'a::linordered_field"
    8.63 +  shows "((\<lambda>x. m*x - c) ` {a..b}) = (if {a..b}={} then {}
    8.64 +            else if 0 \<le> m then {m*a - c .. m*b - c}
    8.65 +            else {m*b - c .. m*a - c})"
    8.66 +  using image_affinity_atLeastAtMost [of m "-c" a b]
    8.67 +  by simp
    8.68 +
    8.69 +lemma image_affinity_atLeastAtMost_div_diff:
    8.70 +  fixes c :: "'a::linordered_field"
    8.71 +  shows "((\<lambda>x. x/m - c) ` {a..b}) = (if {a..b}={} then {}
    8.72 +            else if 0 \<le> m then {a/m - c .. b/m - c}
    8.73 +            else {b/m - c .. a/m - c})"
    8.74 +  using image_affinity_atLeastAtMost_diff [of "inverse m" c a b]
    8.75 +  by (simp add: field_class.field_divide_inverse algebra_simps)
    8.76 +
    8.77 +lemma closed_segment_real_eq:
    8.78 +  fixes u::real shows "closed_segment u v = (\<lambda>x. (v - u) * x + u) ` {0..1}"
    8.79 +  by (simp add: add.commute [of u] image_affinity_atLeastAtMost [where c=u] closed_segment_eq_real_ivl)
    8.80 +
    8.81 +subsection {* Paths and Arcs *}
    8.82  
    8.83  definition path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    8.84    where "path g \<longleftrightarrow> continuous_on {0..1} g"
    8.85 @@ -31,17 +97,134 @@
    8.86  
    8.87  definition simple_path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    8.88    where "simple_path g \<longleftrightarrow>
    8.89 -    (\<forall>x\<in>{0..1}. \<forall>y\<in>{0..1}. g x = g y \<longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0)"
    8.90 +     path g \<and> (\<forall>x\<in>{0..1}. \<forall>y\<in>{0..1}. g x = g y \<longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0)"
    8.91  
    8.92 -definition injective_path :: "(real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
    8.93 -  where "injective_path g \<longleftrightarrow> (\<forall>x\<in>{0..1}. \<forall>y\<in>{0..1}. g x = g y \<longrightarrow> x = y)"
    8.94 +definition arc :: "(real \<Rightarrow> 'a :: topological_space) \<Rightarrow> bool"
    8.95 +  where "arc g \<longleftrightarrow> path g \<and> inj_on g {0..1}"
    8.96  
    8.97  
    8.98 -subsection {* Some lemmas about these concepts. *}
    8.99 +subsection{*Invariance theorems*}
   8.100 +
   8.101 +lemma path_eq: "path p \<Longrightarrow> (\<And>t. t \<in> {0..1} \<Longrightarrow> p t = q t) \<Longrightarrow> path q"
   8.102 +  using continuous_on_eq path_def by blast
   8.103 +
   8.104 +lemma path_continuous_image: "path g \<Longrightarrow> continuous_on (path_image g) f \<Longrightarrow> path(f o g)"
   8.105 +  unfolding path_def path_image_def
   8.106 +  using continuous_on_compose by blast
   8.107 +
   8.108 +lemma path_translation_eq:
   8.109 +  fixes g :: "real \<Rightarrow> 'a :: real_normed_vector"
   8.110 +  shows "path((\<lambda>x. a + x) o g) = path g"
   8.111 +proof -
   8.112 +  have g: "g = (\<lambda>x. -a + x) o ((\<lambda>x. a + x) o g)"
   8.113 +    by (rule ext) simp
   8.114 +  show ?thesis
   8.115 +    unfolding path_def
   8.116 +    apply safe
   8.117 +    apply (subst g)
   8.118 +    apply (rule continuous_on_compose)
   8.119 +    apply (auto intro: continuous_intros)
   8.120 +    done
   8.121 +qed
   8.122 +
   8.123 +lemma path_linear_image_eq:
   8.124 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
   8.125 +   assumes "linear f" "inj f"
   8.126 +     shows "path(f o g) = path g"
   8.127 +proof -
   8.128 +  from linear_injective_left_inverse [OF assms]
   8.129 +  obtain h where h: "linear h" "h \<circ> f = id"
   8.130 +    by blast
   8.131 +  then have g: "g = h o (f o g)"
   8.132 +    by (metis comp_assoc id_comp)
   8.133 +  show ?thesis
   8.134 +    unfolding path_def
   8.135 +    using h assms
   8.136 +    by (metis g continuous_on_compose linear_continuous_on linear_conv_bounded_linear)
   8.137 +qed
   8.138 +
   8.139 +lemma pathstart_translation: "pathstart((\<lambda>x. a + x) o g) = a + pathstart g"
   8.140 +  by (simp add: pathstart_def)
   8.141 +
   8.142 +lemma pathstart_linear_image_eq: "linear f \<Longrightarrow> pathstart(f o g) = f(pathstart g)"
   8.143 +  by (simp add: pathstart_def)
   8.144 +
   8.145 +lemma pathfinish_translation: "pathfinish((\<lambda>x. a + x) o g) = a + pathfinish g"
   8.146 +  by (simp add: pathfinish_def)
   8.147 +
   8.148 +lemma pathfinish_linear_image: "linear f \<Longrightarrow> pathfinish(f o g) = f(pathfinish g)"
   8.149 +  by (simp add: pathfinish_def)
   8.150 +
   8.151 +lemma path_image_translation: "path_image((\<lambda>x. a + x) o g) = (\<lambda>x. a + x) ` (path_image g)"
   8.152 +  by (simp add: image_comp path_image_def)
   8.153 +
   8.154 +lemma path_image_linear_image: "linear f \<Longrightarrow> path_image(f o g) = f ` (path_image g)"
   8.155 +  by (simp add: image_comp path_image_def)
   8.156 +
   8.157 +lemma reversepath_translation: "reversepath((\<lambda>x. a + x) o g) = (\<lambda>x. a + x) o reversepath g"
   8.158 +  by (rule ext) (simp add: reversepath_def)
   8.159  
   8.160 -lemma injective_imp_simple_path: "injective_path g \<Longrightarrow> simple_path g"
   8.161 -  unfolding injective_path_def simple_path_def
   8.162 -  by auto
   8.163 +lemma reversepath_linear_image: "linear f \<Longrightarrow> reversepath(f o g) = f o reversepath g"
   8.164 +  by (rule ext) (simp add: reversepath_def)
   8.165 +
   8.166 +lemma joinpaths_translation:
   8.167 +    "((\<lambda>x. a + x) o g1) +++ ((\<lambda>x. a + x) o g2) = (\<lambda>x. a + x) o (g1 +++ g2)"
   8.168 +  by (rule ext) (simp add: joinpaths_def)
   8.169 +
   8.170 +lemma joinpaths_linear_image: "linear f \<Longrightarrow> (f o g1) +++ (f o g2) = f o (g1 +++ g2)"
   8.171 +  by (rule ext) (simp add: joinpaths_def)
   8.172 +
   8.173 +lemma simple_path_translation_eq: 
   8.174 +  fixes g :: "real \<Rightarrow> 'a::euclidean_space"
   8.175 +  shows "simple_path((\<lambda>x. a + x) o g) = simple_path g"
   8.176 +  by (simp add: simple_path_def path_translation_eq)
   8.177 +
   8.178 +lemma simple_path_linear_image_eq:
   8.179 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
   8.180 +  assumes "linear f" "inj f"
   8.181 +    shows "simple_path(f o g) = simple_path g"
   8.182 +  using assms inj_on_eq_iff [of f]
   8.183 +  by (auto simp: path_linear_image_eq simple_path_def path_translation_eq)
   8.184 +
   8.185 +lemma arc_translation_eq:
   8.186 +  fixes g :: "real \<Rightarrow> 'a::euclidean_space"
   8.187 +  shows "arc((\<lambda>x. a + x) o g) = arc g"
   8.188 +  by (auto simp: arc_def inj_on_def path_translation_eq)
   8.189 +
   8.190 +lemma arc_linear_image_eq:
   8.191 +  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
   8.192 +   assumes "linear f" "inj f"
   8.193 +     shows  "arc(f o g) = arc g"
   8.194 +  using assms inj_on_eq_iff [of f]
   8.195 +  by (auto simp: arc_def inj_on_def path_linear_image_eq)
   8.196 +
   8.197 +subsection{*Basic lemmas about paths*}
   8.198 +
   8.199 +lemma arc_imp_simple_path: "arc g \<Longrightarrow> simple_path g"
   8.200 +  by (simp add: arc_def inj_on_def simple_path_def)
   8.201 +
   8.202 +lemma arc_imp_path: "arc g \<Longrightarrow> path g"
   8.203 +  using arc_def by blast
   8.204 +
   8.205 +lemma simple_path_imp_path: "simple_path g \<Longrightarrow> path g"
   8.206 +  using simple_path_def by blast
   8.207 +
   8.208 +lemma simple_path_cases: "simple_path g \<Longrightarrow> arc g \<or> pathfinish g = pathstart g"
   8.209 +  unfolding simple_path_def arc_def inj_on_def pathfinish_def pathstart_def
   8.210 +  by (force)
   8.211 +
   8.212 +lemma simple_path_imp_arc: "simple_path g \<Longrightarrow> pathfinish g \<noteq> pathstart g \<Longrightarrow> arc g"
   8.213 +  using simple_path_cases by auto
   8.214 +
   8.215 +lemma arc_distinct_ends: "arc g \<Longrightarrow> pathfinish g \<noteq> pathstart g"
   8.216 +  unfolding arc_def inj_on_def pathfinish_def pathstart_def
   8.217 +  by fastforce
   8.218 +
   8.219 +lemma arc_simple_path: "arc g \<longleftrightarrow> simple_path g \<and> pathfinish g \<noteq> pathstart g"
   8.220 +  using arc_distinct_ends arc_imp_simple_path simple_path_cases by blast
   8.221 +
   8.222 +lemma simple_path_eq_arc: "pathfinish g \<noteq> pathstart g \<Longrightarrow> (simple_path g = arc g)"
   8.223 +  by (simp add: arc_simple_path)
   8.224  
   8.225  lemma path_image_nonempty: "path_image g \<noteq> {}"
   8.226    unfolding path_image_def image_is_empty box_eq_empty
   8.227 @@ -57,15 +240,11 @@
   8.228  
   8.229  lemma connected_path_image[intro]: "path g \<Longrightarrow> connected (path_image g)"
   8.230    unfolding path_def path_image_def
   8.231 -  apply (erule connected_continuous_image)
   8.232 -  apply (rule convex_connected, rule convex_real_interval)
   8.233 -  done
   8.234 +  using connected_continuous_image connected_Icc by blast
   8.235  
   8.236  lemma compact_path_image[intro]: "path g \<Longrightarrow> compact (path_image g)"
   8.237    unfolding path_def path_image_def
   8.238 -  apply (erule compact_continuous_image)
   8.239 -  apply (rule compact_Icc)
   8.240 -  done
   8.241 +  using compact_continuous_image connected_Icc by blast
   8.242  
   8.243  lemma reversepath_reversepath[simp]: "reversepath (reversepath g) = g"
   8.244    unfolding reversepath_def
   8.245 @@ -91,12 +270,7 @@
   8.246  proof -
   8.247    have *: "\<And>g. path_image (reversepath g) \<subseteq> path_image g"
   8.248      unfolding path_image_def subset_eq reversepath_def Ball_def image_iff
   8.249 -    apply rule
   8.250 -    apply rule
   8.251 -    apply (erule bexE)
   8.252 -    apply (rule_tac x="1 - xa" in bexI)
   8.253 -    apply auto
   8.254 -    done
   8.255 +    by force
   8.256    show ?thesis
   8.257      using *[of g] *[of "reversepath g"]
   8.258      unfolding reversepath_reversepath
   8.259 @@ -119,6 +293,28 @@
   8.260      by (rule iffI)
   8.261  qed
   8.262  
   8.263 +lemma arc_reversepath:
   8.264 +  assumes "arc g" shows "arc(reversepath g)"
   8.265 +proof -
   8.266 +  have injg: "inj_on g {0..1}"
   8.267 +    using assms
   8.268 +    by (simp add: arc_def)
   8.269 +  have **: "\<And>x y::real. 1-x = 1-y \<Longrightarrow> x = y"
   8.270 +    by simp
   8.271 +  show ?thesis
   8.272 +    apply (auto simp: arc_def inj_on_def path_reversepath)
   8.273 +    apply (simp add: arc_imp_path assms)
   8.274 +    apply (rule **)
   8.275 +    apply (rule inj_onD [OF injg])
   8.276 +    apply (auto simp: reversepath_def)
   8.277 +    done
   8.278 +qed
   8.279 +
   8.280 +lemma simple_path_reversepath: "simple_path g \<Longrightarrow> simple_path (reversepath g)"
   8.281 +  apply (simp add: simple_path_def)
   8.282 +  apply (force simp: reversepath_def)
   8.283 +  done
   8.284 +
   8.285  lemmas reversepath_simps =
   8.286    path_reversepath path_image_reversepath pathstart_reversepath pathfinish_reversepath
   8.287  
   8.288 @@ -162,6 +358,44 @@
   8.289      done
   8.290  qed
   8.291  
   8.292 +section {*Path Images*}
   8.293 +
   8.294 +lemma bounded_path_image: "path g \<Longrightarrow> bounded(path_image g)"
   8.295 +  by (simp add: compact_imp_bounded compact_path_image)
   8.296 +
   8.297 +lemma closed_path_image: 
   8.298 +  fixes g :: "real \<Rightarrow> 'a::t2_space"
   8.299 +  shows "path g \<Longrightarrow> closed(path_image g)"
   8.300 +  by (metis compact_path_image compact_imp_closed)
   8.301 +
   8.302 +lemma connected_simple_path_image: "simple_path g \<Longrightarrow> connected(path_image g)"
   8.303 +  by (metis connected_path_image simple_path_imp_path)
   8.304 +
   8.305 +lemma compact_simple_path_image: "simple_path g \<Longrightarrow> compact(path_image g)"
   8.306 +  by (metis compact_path_image simple_path_imp_path)
   8.307 +
   8.308 +lemma bounded_simple_path_image: "simple_path g \<Longrightarrow> bounded(path_image g)"
   8.309 +  by (metis bounded_path_image simple_path_imp_path)
   8.310 +
   8.311 +lemma closed_simple_path_image:
   8.312 +  fixes g :: "real \<Rightarrow> 'a::t2_space"
   8.313 +  shows "simple_path g \<Longrightarrow> closed(path_image g)"
   8.314 +  by (metis closed_path_image simple_path_imp_path)
   8.315 +
   8.316 +lemma connected_arc_image: "arc g \<Longrightarrow> connected(path_image g)"
   8.317 +  by (metis connected_path_image arc_imp_path)
   8.318 +
   8.319 +lemma compact_arc_image: "arc g \<Longrightarrow> compact(path_image g)"
   8.320 +  by (metis compact_path_image arc_imp_path)
   8.321 +
   8.322 +lemma bounded_arc_image: "arc g \<Longrightarrow> bounded(path_image g)"
   8.323 +  by (metis bounded_path_image arc_imp_path)
   8.324 +
   8.325 +lemma closed_arc_image:
   8.326 +  fixes g :: "real \<Rightarrow> 'a::t2_space"
   8.327 +  shows "arc g \<Longrightarrow> closed(path_image g)"
   8.328 +  by (metis closed_path_image arc_imp_path)
   8.329 +
   8.330  lemma path_image_join_subset: "path_image (g1 +++ g2) \<subseteq> path_image g1 \<union> path_image g2"
   8.331    unfolding path_image_def joinpaths_def
   8.332    by auto
   8.333 @@ -174,34 +408,16 @@
   8.334    by auto
   8.335  
   8.336  lemma path_image_join:
   8.337 -  assumes "pathfinish g1 = pathstart g2"
   8.338 -  shows "path_image (g1 +++ g2) = path_image g1 \<union> path_image g2"
   8.339 -  apply rule
   8.340 -  apply (rule path_image_join_subset)
   8.341 -  apply rule
   8.342 -  unfolding Un_iff
   8.343 -proof (erule disjE)
   8.344 -  fix x
   8.345 -  assume "x \<in> path_image g1"
   8.346 -  then obtain y where y: "y \<in> {0..1}" "x = g1 y"
   8.347 -    unfolding path_image_def image_iff by auto
   8.348 -  then show "x \<in> path_image (g1 +++ g2)"
   8.349 -    unfolding joinpaths_def path_image_def image_iff
   8.350 -    apply (rule_tac x="(1/2) *\<^sub>R y" in bexI)
   8.351 -    apply auto
   8.352 -    done
   8.353 -next
   8.354 -  fix x
   8.355 -  assume "x \<in> path_image g2"
   8.356 -  then obtain y where y: "y \<in> {0..1}" "x = g2 y"
   8.357 -    unfolding path_image_def image_iff by auto
   8.358 -  then show "x \<in> path_image (g1 +++ g2)"
   8.359 -    unfolding joinpaths_def path_image_def image_iff
   8.360 -    apply (rule_tac x="(1/2) *\<^sub>R (y + 1)" in bexI)
   8.361 -    using assms(1)[unfolded pathfinish_def pathstart_def]
   8.362 -    apply (auto simp add: add_divide_distrib)
   8.363 -    done
   8.364 -qed
   8.365 +    "pathfinish g1 = pathstart g2 \<Longrightarrow> path_image(g1 +++ g2) = path_image g1 \<union> path_image g2"
   8.366 +  apply (rule subset_antisym [OF path_image_join_subset])
   8.367 +  apply (auto simp: pathfinish_def pathstart_def path_image_def joinpaths_def image_def)
   8.368 +  apply (drule sym)
   8.369 +  apply (rule_tac x="xa/2" in bexI, auto)
   8.370 +  apply (rule ccontr)
   8.371 +  apply (drule_tac x="(xa+1)/2" in bspec)
   8.372 +  apply (auto simp: field_simps)
   8.373 +  apply (drule_tac x="1/2" in bspec, auto)
   8.374 +  done
   8.375  
   8.376  lemma not_in_path_image_join:
   8.377    assumes "x \<notin> path_image g1"
   8.378 @@ -210,166 +426,380 @@
   8.379    using assms and path_image_join_subset[of g1 g2]
   8.380    by auto
   8.381  
   8.382 -lemma simple_path_reversepath:
   8.383 -  assumes "simple_path g"
   8.384 -  shows "simple_path (reversepath g)"
   8.385 -  using assms
   8.386 -  unfolding simple_path_def reversepath_def
   8.387 -  apply -
   8.388 -  apply (rule ballI)+
   8.389 -  apply (erule_tac x="1-x" in ballE)
   8.390 -  apply (erule_tac x="1-y" in ballE)
   8.391 -  apply auto
   8.392 +lemma pathstart_compose: "pathstart(f o p) = f(pathstart p)"
   8.393 +  by (simp add: pathstart_def)
   8.394 +
   8.395 +lemma pathfinish_compose: "pathfinish(f o p) = f(pathfinish p)"
   8.396 +  by (simp add: pathfinish_def)
   8.397 +
   8.398 +lemma path_image_compose: "path_image (f o p) = f ` (path_image p)"
   8.399 +  by (simp add: image_comp path_image_def)
   8.400 +
   8.401 +lemma path_compose_join: "f o (p +++ q) = (f o p) +++ (f o q)"
   8.402 +  by (rule ext) (simp add: joinpaths_def)
   8.403 +
   8.404 +lemma path_compose_reversepath: "f o reversepath p = reversepath(f o p)"
   8.405 +  by (rule ext) (simp add: reversepath_def)
   8.406 +
   8.407 +lemma join_paths_eq:
   8.408 +  "(\<And>t. t \<in> {0..1} \<Longrightarrow> p t = p' t) \<Longrightarrow>
   8.409 +   (\<And>t. t \<in> {0..1} \<Longrightarrow> q t = q' t)
   8.410 +   \<Longrightarrow>  t \<in> {0..1} \<Longrightarrow> (p +++ q) t = (p' +++ q') t"
   8.411 +  by (auto simp: joinpaths_def)
   8.412 +
   8.413 +lemma simple_path_inj_on: "simple_path g \<Longrightarrow> inj_on g {0<..<1}"
   8.414 +  by (auto simp: simple_path_def path_image_def inj_on_def less_eq_real_def Ball_def)
   8.415 +
   8.416 +
   8.417 +subsection{*Simple paths with the endpoints removed*}
   8.418 +
   8.419 +lemma simple_path_endless:
   8.420 +    "simple_path c \<Longrightarrow> path_image c - {pathstart c,pathfinish c} = c ` {0<..<1}"
   8.421 +  apply (auto simp: simple_path_def path_image_def pathstart_def pathfinish_def Ball_def Bex_def image_def)
   8.422 +  apply (metis eq_iff le_less_linear)
   8.423 +  apply (metis leD linear)
   8.424 +  using less_eq_real_def zero_le_one apply blast
   8.425 +  using less_eq_real_def zero_le_one apply blast
   8.426    done
   8.427  
   8.428 +lemma connected_simple_path_endless:
   8.429 +    "simple_path c \<Longrightarrow> connected(path_image c - {pathstart c,pathfinish c})"
   8.430 +apply (simp add: simple_path_endless)
   8.431 +apply (rule connected_continuous_image)
   8.432 +apply (meson continuous_on_subset greaterThanLessThan_subseteq_atLeastAtMost_iff le_numeral_extra(3) le_numeral_extra(4) path_def simple_path_imp_path)
   8.433 +by auto
   8.434 +
   8.435 +lemma nonempty_simple_path_endless:
   8.436 +    "simple_path c \<Longrightarrow> path_image c - {pathstart c,pathfinish c} \<noteq> {}"
   8.437 +  by (simp add: simple_path_endless)
   8.438 +
   8.439 +
   8.440 +subsection{* The operations on paths*}
   8.441 +
   8.442 +lemma path_image_subset_reversepath: "path_image(reversepath g) \<le> path_image g"
   8.443 +  by (auto simp: path_image_def reversepath_def)
   8.444 +
   8.445 +lemma continuous_on_op_minus: "continuous_on (s::real set) (op - x)"
   8.446 +  by (rule continuous_intros | simp)+
   8.447 +
   8.448 +lemma path_imp_reversepath: "path g \<Longrightarrow> path(reversepath g)"
   8.449 +  apply (auto simp: path_def reversepath_def)
   8.450 +  using continuous_on_compose [of "{0..1}" "\<lambda>x. 1 - x" g]
   8.451 +  apply (auto simp: continuous_on_op_minus)
   8.452 +  done
   8.453 +
   8.454 +lemma forall_01_trivial: "(\<forall>x\<in>{0..1}. x \<le> 0 \<longrightarrow> P x) \<longleftrightarrow> P (0::real)"
   8.455 +  by auto
   8.456 +
   8.457 +lemma forall_half1_trivial: "(\<forall>x\<in>{1/2..1}. x * 2 \<le> 1 \<longrightarrow> P x) \<longleftrightarrow> P (1/2::real)"
   8.458 +  by auto (metis add_divide_distrib mult_2_right real_sum_of_halves)
   8.459 +
   8.460 +lemma continuous_on_joinpaths:
   8.461 +  assumes "continuous_on {0..1} g1" "continuous_on {0..1} g2" "pathfinish g1 = pathstart g2"
   8.462 +    shows "continuous_on {0..1} (g1 +++ g2)"
   8.463 +proof -
   8.464 +  have *: "{0..1::real} = {0..1/2} \<union> {1/2..1}"
   8.465 +    by auto
   8.466 +  have gg: "g2 0 = g1 1"
   8.467 +    by (metis assms(3) pathfinish_def pathstart_def)
   8.468 +  have 1: "continuous_on {0..1 / 2} (g1 +++ g2)"
   8.469 +    apply (rule continuous_on_eq [of _ "g1 o (\<lambda>x. 2*x)"])
   8.470 +    apply (simp add: joinpaths_def)
   8.471 +    apply (rule continuous_intros | simp add: assms)+
   8.472 +    done
   8.473 +  have 2: "continuous_on {1 / 2..1} (g1 +++ g2)"
   8.474 +    apply (rule continuous_on_eq [of _ "g2 o (\<lambda>x. 2*x-1)"])
   8.475 +    apply (simp add: joinpaths_def)
   8.476 +    apply (rule continuous_intros | simp add: forall_half1_trivial gg)+
   8.477 +    apply (rule continuous_on_subset)
   8.478 +    apply (rule assms, auto)
   8.479 +    done
   8.480 +  show ?thesis
   8.481 +    apply (subst *)
   8.482 +    apply (rule continuous_on_union)
   8.483 +    using 1 2
   8.484 +    apply auto
   8.485 +    done
   8.486 +qed
   8.487 +
   8.488 +lemma path_join_imp: "\<lbrakk>path g1; path g2; pathfinish g1 = pathstart g2\<rbrakk> \<Longrightarrow> path(g1 +++ g2)"
   8.489 +  by (simp add: path_join)
   8.490 +
   8.491 +lemmas join_paths_simps = path_join path_image_join pathstart_join pathfinish_join
   8.492 +
   8.493  lemma simple_path_join_loop:
   8.494 -  assumes "injective_path g1"
   8.495 -    and "injective_path g2"
   8.496 -    and "pathfinish g2 = pathstart g1"
   8.497 -    and "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   8.498 -  shows "simple_path (g1 +++ g2)"
   8.499 -  unfolding simple_path_def
   8.500 -proof (intro ballI impI)
   8.501 -  let ?g = "g1 +++ g2"
   8.502 -  note inj = assms(1,2)[unfolded injective_path_def, rule_format]
   8.503 -  fix x y :: real
   8.504 -  assume xy: "x \<in> {0..1}" "y \<in> {0..1}" "?g x = ?g y"
   8.505 -  show "x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0"
   8.506 -  proof (cases "x \<le> 1/2", case_tac[!] "y \<le> 1/2", unfold not_le)
   8.507 -    assume as: "x \<le> 1 / 2" "y \<le> 1 / 2"
   8.508 -    then have "g1 (2 *\<^sub>R x) = g1 (2 *\<^sub>R y)"
   8.509 -      using xy(3)
   8.510 -      unfolding joinpaths_def
   8.511 -      by auto
   8.512 -    moreover have "2 *\<^sub>R x \<in> {0..1}" "2 *\<^sub>R y \<in> {0..1}"
   8.513 -      using xy(1,2) as
   8.514 -      by auto
   8.515 -    ultimately show ?thesis
   8.516 -      using inj(1)[of "2*\<^sub>R x" "2*\<^sub>R y"]
   8.517 -      by auto
   8.518 -  next
   8.519 -    assume as: "x > 1 / 2" "y > 1 / 2"
   8.520 -    then have "g2 (2 *\<^sub>R x - 1) = g2 (2 *\<^sub>R y - 1)"
   8.521 -      using xy(3)
   8.522 -      unfolding joinpaths_def
   8.523 -      by auto
   8.524 -    moreover have "2 *\<^sub>R x - 1 \<in> {0..1}" "2 *\<^sub>R y - 1 \<in> {0..1}"
   8.525 -      using xy(1,2) as
   8.526 -      by auto
   8.527 -    ultimately show ?thesis
   8.528 -      using inj(2)[of "2*\<^sub>R x - 1" "2*\<^sub>R y - 1"] by auto
   8.529 -  next
   8.530 -    assume as: "x \<le> 1 / 2" "y > 1 / 2"
   8.531 -    then have "?g x \<in> path_image g1" "?g y \<in> path_image g2"
   8.532 -      unfolding path_image_def joinpaths_def
   8.533 -      using xy(1,2) by auto
   8.534 -    moreover have "?g y \<noteq> pathstart g2"
   8.535 -      using as(2)
   8.536 -      unfolding pathstart_def joinpaths_def
   8.537 -      using inj(2)[of "2 *\<^sub>R y - 1" 0] and xy(2)
   8.538 -      by (auto simp add: field_simps)
   8.539 -    ultimately have *: "?g x = pathstart g1"
   8.540 -      using assms(4)
   8.541 -      unfolding xy(3)
   8.542 -      by auto
   8.543 -    then have "x = 0"
   8.544 -      unfolding pathstart_def joinpaths_def
   8.545 -      using as(1) and xy(1)
   8.546 -      using inj(1)[of "2 *\<^sub>R x" 0]
   8.547 -      by auto
   8.548 -    moreover have "y = 1"
   8.549 -      using *
   8.550 -      unfolding xy(3) assms(3)[symmetric]
   8.551 -      unfolding joinpaths_def pathfinish_def
   8.552 -      using as(2) and xy(2)
   8.553 -      using inj(2)[of "2 *\<^sub>R y - 1" 1]
   8.554 -      by auto
   8.555 -    ultimately show ?thesis
   8.556 -      by auto
   8.557 -  next
   8.558 -    assume as: "x > 1 / 2" "y \<le> 1 / 2"
   8.559 -    then have "?g x \<in> path_image g2" and "?g y \<in> path_image g1"
   8.560 -      unfolding path_image_def joinpaths_def
   8.561 -      using xy(1,2) by auto
   8.562 -    moreover have "?g x \<noteq> pathstart g2"
   8.563 -      using as(1)
   8.564 -      unfolding pathstart_def joinpaths_def
   8.565 -      using inj(2)[of "2 *\<^sub>R x - 1" 0] and xy(1)
   8.566 -      by (auto simp add: field_simps)
   8.567 -    ultimately have *: "?g y = pathstart g1"
   8.568 -      using assms(4)
   8.569 -      unfolding xy(3)
   8.570 -      by auto
   8.571 -    then have "y = 0"
   8.572 -      unfolding pathstart_def joinpaths_def
   8.573 -      using as(2) and xy(2)
   8.574 -      using inj(1)[of "2 *\<^sub>R y" 0]
   8.575 -      by auto
   8.576 -    moreover have "x = 1"
   8.577 -      using *
   8.578 -      unfolding xy(3)[symmetric] assms(3)[symmetric]
   8.579 -      unfolding joinpaths_def pathfinish_def using as(1) and xy(1)
   8.580 -      using inj(2)[of "2 *\<^sub>R x - 1" 1]
   8.581 -      by auto
   8.582 -    ultimately show ?thesis
   8.583 -      by auto
   8.584 -  qed
   8.585 +  assumes "arc g1" "arc g2" 
   8.586 +          "pathfinish g1 = pathstart g2"  "pathfinish g2 = pathstart g1" 
   8.587 +          "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g1, pathstart g2}"
   8.588 +  shows "simple_path(g1 +++ g2)"
   8.589 +proof -
   8.590 +  have injg1: "inj_on g1 {0..1}"
   8.591 +    using assms
   8.592 +    by (simp add: arc_def)
   8.593 +  have injg2: "inj_on g2 {0..1}"
   8.594 +    using assms
   8.595 +    by (simp add: arc_def)
   8.596 +  have g12: "g1 1 = g2 0" 
   8.597 +   and g21: "g2 1 = g1 0" 
   8.598 +   and sb:  "g1 ` {0..1} \<inter> g2 ` {0..1} \<subseteq> {g1 0, g2 0}"
   8.599 +    using assms
   8.600 +    by (simp_all add: arc_def pathfinish_def pathstart_def path_image_def)
   8.601 +  { fix x and y::real
   8.602 +    assume xyI: "x = 1 \<longrightarrow> y \<noteq> 0" 
   8.603 +       and xy: "x \<le> 1" "0 \<le> y" " y * 2 \<le> 1" "\<not> x * 2 \<le> 1" "g2 (2 * x - 1) = g1 (2 * y)"
   8.604 +    have g1im: "g1 (2 * y) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   8.605 +      using xy
   8.606 +      apply simp
   8.607 +      apply (rule_tac x="2 * x - 1" in image_eqI, auto)
   8.608 +      done
   8.609 +    have False
   8.610 +      using subsetD [OF sb g1im] xy 
   8.611 +      apply auto
   8.612 +      apply (drule inj_onD [OF injg1])
   8.613 +      using g21 [symmetric] xyI
   8.614 +      apply (auto dest: inj_onD [OF injg2])
   8.615 +      done
   8.616 +   } note * = this
   8.617 +  { fix x and y::real
   8.618 +    assume xy: "y \<le> 1" "0 \<le> x" "\<not> y * 2 \<le> 1" "x * 2 \<le> 1" "g1 (2 * x) = g2 (2 * y - 1)"
   8.619 +    have g1im: "g1 (2 * x) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   8.620 +      using xy
   8.621 +      apply simp
   8.622 +      apply (rule_tac x="2 * x" in image_eqI, auto)
   8.623 +      done
   8.624 +    have "x = 0 \<and> y = 1"
   8.625 +      using subsetD [OF sb g1im] xy 
   8.626 +      apply auto
   8.627 +      apply (force dest: inj_onD [OF injg1])
   8.628 +      using  g21 [symmetric]
   8.629 +      apply (auto dest: inj_onD [OF injg2])
   8.630 +      done
   8.631 +   } note ** = this
   8.632 +  show ?thesis
   8.633 +    using assms
   8.634 +    apply (simp add: arc_def simple_path_def path_join, clarify)
   8.635 +    apply (simp add: joinpaths_def split: split_if_asm)
   8.636 +    apply (force dest: inj_onD [OF injg1])
   8.637 +    apply (metis *)
   8.638 +    apply (metis **)
   8.639 +    apply (force dest: inj_onD [OF injg2])
   8.640 +    done
   8.641 +qed
   8.642 +
   8.643 +lemma arc_join:
   8.644 +  assumes "arc g1" "arc g2" 
   8.645 +          "pathfinish g1 = pathstart g2"
   8.646 +          "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g2}"
   8.647 +    shows "arc(g1 +++ g2)"
   8.648 +proof -
   8.649 +  have injg1: "inj_on g1 {0..1}"
   8.650 +    using assms
   8.651 +    by (simp add: arc_def)
   8.652 +  have injg2: "inj_on g2 {0..1}"
   8.653 +    using assms
   8.654 +    by (simp add: arc_def)
   8.655 +  have g11: "g1 1 = g2 0"
   8.656 +   and sb:  "g1 ` {0..1} \<inter> g2 ` {0..1} \<subseteq> {g2 0}"
   8.657 +    using assms
   8.658 +    by (simp_all add: arc_def pathfinish_def pathstart_def path_image_def)
   8.659 +  { fix x and y::real
   8.660 +    assume xy: "x \<le> 1" "0 \<le> y" " y * 2 \<le> 1" "\<not> x * 2 \<le> 1" "g2 (2 * x - 1) = g1 (2 * y)"       
   8.661 +    have g1im: "g1 (2 * y) \<in> g1 ` {0..1} \<inter> g2 ` {0..1}"
   8.662 +      using xy
   8.663 +      apply simp
   8.664 +      apply (rule_tac x="2 * x - 1" in image_eqI, auto)
   8.665 +      done
   8.666 +    have False
   8.667 +      using subsetD [OF sb g1im] xy 
   8.668 +      by (auto dest: inj_onD [OF injg2])
   8.669 +   } note * = this
   8.670 +  show ?thesis
   8.671 +    apply (simp add: arc_def inj_on_def)
   8.672 +    apply (clarsimp simp add: arc_imp_path assms path_join)
   8.673 +    apply (simp add: joinpaths_def split: split_if_asm)
   8.674 +    apply (force dest: inj_onD [OF injg1])
   8.675 +    apply (metis *)
   8.676 +    apply (metis *)
   8.677 +    apply (force dest: inj_onD [OF injg2])
   8.678 +    done
   8.679 +qed
   8.680 +
   8.681 +lemma reversepath_joinpaths:
   8.682 +    "pathfinish g1 = pathstart g2 \<Longrightarrow> reversepath(g1 +++ g2) = reversepath g2 +++ reversepath g1"
   8.683 +  unfolding reversepath_def pathfinish_def pathstart_def joinpaths_def
   8.684 +  by (rule ext) (auto simp: mult.commute)
   8.685 +
   8.686 +
   8.687 +subsection{* Choosing a subpath of an existing path*}
   8.688 +    
   8.689 +definition subpath :: "real \<Rightarrow> real \<Rightarrow> (real \<Rightarrow> 'a) \<Rightarrow> real \<Rightarrow> 'a::real_normed_vector"
   8.690 +  where "subpath a b g \<equiv> \<lambda>x. g((b - a) * x + a)"
   8.691 +
   8.692 +lemma path_image_subpath_gen [simp]: 
   8.693 +  fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   8.694 +  shows "path_image(subpath u v g) = g ` (closed_segment u v)"
   8.695 +  apply (simp add: closed_segment_real_eq path_image_def subpath_def)
   8.696 +  apply (subst o_def [of g, symmetric])
   8.697 +  apply (simp add: image_comp [symmetric])
   8.698 +  done
   8.699 +
   8.700 +lemma path_image_subpath [simp]:
   8.701 +  fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   8.702 +  shows "path_image(subpath u v g) = (if u \<le> v then g ` {u..v} else g ` {v..u})"
   8.703 +  by (simp add: closed_segment_eq_real_ivl)
   8.704 +
   8.705 +lemma path_subpath [simp]:
   8.706 +  fixes g :: "real \<Rightarrow> 'a::real_normed_vector"
   8.707 +  assumes "path g" "u \<in> {0..1}" "v \<in> {0..1}"
   8.708 +    shows "path(subpath u v g)"
   8.709 +proof -
   8.710 +  have "continuous_on {0..1} (g o (\<lambda>x. ((v-u) * x+ u)))"
   8.711 +    apply (rule continuous_intros | simp)+
   8.712 +    apply (simp add: image_affinity_atLeastAtMost [where c=u])
   8.713 +    using assms
   8.714 +    apply (auto simp: path_def continuous_on_subset)
   8.715 +    done
   8.716 +  then show ?thesis
   8.717 +    by (simp add: path_def subpath_def)
   8.718  qed
   8.719  
   8.720 -lemma injective_path_join:
   8.721 -  assumes "injective_path g1"
   8.722 -    and "injective_path g2"
   8.723 -    and "pathfinish g1 = pathstart g2"
   8.724 -    and "path_image g1 \<inter> path_image g2 \<subseteq> {pathstart g2}"
   8.725 -  shows "injective_path (g1 +++ g2)"
   8.726 -  unfolding injective_path_def
   8.727 -proof (rule, rule, rule)
   8.728 -  let ?g = "g1 +++ g2"
   8.729 -  note inj = assms(1,2)[unfolded injective_path_def, rule_format]
   8.730 -  fix x y
   8.731 -  assume xy: "x \<in> {0..1}" "y \<in> {0..1}" "(g1 +++ g2) x = (g1 +++ g2) y"
   8.732 -  show "x = y"
   8.733 -  proof (cases "x \<le> 1/2", case_tac[!] "y \<le> 1/2", unfold not_le)
   8.734 -    assume "x \<le> 1 / 2" and "y \<le> 1 / 2"
   8.735 -    then show ?thesis
   8.736 -      using inj(1)[of "2*\<^sub>R x" "2*\<^sub>R y"] and xy
   8.737 -      unfolding joinpaths_def by auto
   8.738 -  next
   8.739 -    assume "x > 1 / 2" and "y > 1 / 2"
   8.740 -    then show ?thesis
   8.741 -      using inj(2)[of "2*\<^sub>R x - 1" "2*\<^sub>R y - 1"] and xy
   8.742 -      unfolding joinpaths_def by auto
   8.743 -  next
   8.744 -    assume as: "x \<le> 1 / 2" "y > 1 / 2"
   8.745 -    then have "?g x \<in> path_image g1" and "?g y \<in> path_image g2"
   8.746 -      unfolding path_image_def joinpaths_def
   8.747 -      using xy(1,2)
   8.748 -      by auto
   8.749 -    then have "?g x = pathfinish g1" and "?g y = pathstart g2"
   8.750 -      using assms(4)
   8.751 -      unfolding assms(3) xy(3)
   8.752 -      by auto
   8.753 -    then show ?thesis
   8.754 -      using as and inj(1)[of "2 *\<^sub>R x" 1] inj(2)[of "2 *\<^sub>R y - 1" 0] and xy(1,2)
   8.755 -      unfolding pathstart_def pathfinish_def joinpaths_def
   8.756 -      by auto
   8.757 -  next
   8.758 -    assume as:"x > 1 / 2" "y \<le> 1 / 2"
   8.759 -    then have "?g x \<in> path_image g2" and "?g y \<in> path_image g1"
   8.760 -      unfolding path_image_def joinpaths_def
   8.761 -      using xy(1,2)
   8.762 -      by auto
   8.763 -    then have "?g x = pathstart g2" and "?g y = pathfinish g1"
   8.764 -      using assms(4)
   8.765 -      unfolding assms(3) xy(3)
   8.766 -      by auto
   8.767 -    then show ?thesis using as and inj(2)[of "2 *\<^sub>R x - 1" 0] inj(1)[of "2 *\<^sub>R y" 1] and xy(1,2)
   8.768 -      unfolding pathstart_def pathfinish_def joinpaths_def
   8.769 -      by auto
   8.770 -  qed
   8.771 +lemma pathstart_subpath [simp]: "pathstart(subpath u v g) = g(u)"
   8.772 +  by (simp add: pathstart_def subpath_def)
   8.773 +
   8.774 +lemma pathfinish_subpath [simp]: "pathfinish(subpath u v g) = g(v)"
   8.775 +  by (simp add: pathfinish_def subpath_def)
   8.776 +
   8.777 +lemma subpath_trivial [simp]: "subpath 0 1 g = g"
   8.778 +  by (simp add: subpath_def)
   8.779 +
   8.780 +lemma subpath_reversepath: "subpath 1 0 g = reversepath g"
   8.781 +  by (simp add: reversepath_def subpath_def)
   8.782 +
   8.783 +lemma reversepath_subpath: "reversepath(subpath u v g) = subpath v u g"
   8.784 +  by (simp add: reversepath_def subpath_def algebra_simps)
   8.785 +
   8.786 +lemma subpath_translation: "subpath u v ((\<lambda>x. a + x) o g) = (\<lambda>x. a + x) o subpath u v g"
   8.787 +  by (rule ext) (simp add: subpath_def)
   8.788 +
   8.789 +lemma subpath_linear_image: "linear f \<Longrightarrow> subpath u v (f o g) = f o subpath u v g"
   8.790 +  by (rule ext) (simp add: subpath_def)
   8.791 +
   8.792 +lemma affine_ineq: 
   8.793 +  fixes x :: "'a::linordered_idom" 
   8.794 +  assumes "x \<le> 1" "v < u"
   8.795 +    shows "v + x * u \<le> u + x * v"
   8.796 +proof -
   8.797 +  have "(1-x)*(u-v) \<ge> 0"
   8.798 +    using assms by auto
   8.799 +  then show ?thesis
   8.800 +    by (simp add: algebra_simps)
   8.801  qed
   8.802  
   8.803 -lemmas join_paths_simps = path_join path_image_join pathstart_join pathfinish_join
   8.804 +lemma simple_path_subpath_eq: 
   8.805 +  "simple_path(subpath u v g) \<longleftrightarrow>
   8.806 +     path(subpath u v g) \<and> u\<noteq>v \<and>
   8.807 +     (\<forall>x y. x \<in> closed_segment u v \<and> y \<in> closed_segment u v \<and> g x = g y
   8.808 +                \<longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u)"
   8.809 +    (is "?lhs = ?rhs")
   8.810 +proof (rule iffI)
   8.811 +  assume ?lhs
   8.812 +  then have p: "path (\<lambda>x. g ((v - u) * x + u))"
   8.813 +        and sim: "(\<And>x y. \<lbrakk>x\<in>{0..1}; y\<in>{0..1}; g ((v - u) * x + u) = g ((v - u) * y + u)\<rbrakk> 
   8.814 +                  \<Longrightarrow> x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0)"
   8.815 +    by (auto simp: simple_path_def subpath_def)
   8.816 +  { fix x y
   8.817 +    assume "x \<in> closed_segment u v" "y \<in> closed_segment u v" "g x = g y"
   8.818 +    then have "x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   8.819 +    using sim [of "(x-u)/(v-u)" "(y-u)/(v-u)"] p
   8.820 +    by (auto simp: closed_segment_real_eq image_affinity_atLeastAtMost divide_simps 
   8.821 +       split: split_if_asm)
   8.822 +  } moreover
   8.823 +  have "path(subpath u v g) \<and> u\<noteq>v"
   8.824 +    using sim [of "1/3" "2/3"] p
   8.825 +    by (auto simp: subpath_def)
   8.826 +  ultimately show ?rhs
   8.827 +    by metis
   8.828 +next
   8.829 +  assume ?rhs
   8.830 +  then 
   8.831 +  have d1: "\<And>x y. \<lbrakk>g x = g y; u \<le> x; x \<le> v; u \<le> y; y \<le> v\<rbrakk> \<Longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   8.832 +   and d2: "\<And>x y. \<lbrakk>g x = g y; v \<le> x; x \<le> u; v \<le> y; y \<le> u\<rbrakk> \<Longrightarrow> x = y \<or> x = u \<and> y = v \<or> x = v \<and> y = u"
   8.833 +   and ne: "u < v \<or> v < u"
   8.834 +   and psp: "path (subpath u v g)"
   8.835 +    by (auto simp: closed_segment_real_eq image_affinity_atLeastAtMost)
   8.836 +  have [simp]: "\<And>x. u + x * v = v + x * u \<longleftrightarrow> u=v \<or> x=1"
   8.837 +    by algebra
   8.838 +  show ?lhs using psp ne
   8.839 +    unfolding simple_path_def subpath_def
   8.840 +    by (fastforce simp add: algebra_simps affine_ineq mult_left_mono crossproduct_eq dest: d1 d2)
   8.841 +qed
   8.842 +
   8.843 +lemma arc_subpath_eq: 
   8.844 +  "arc(subpath u v g) \<longleftrightarrow> path(subpath u v g) \<and> u\<noteq>v \<and> inj_on g (closed_segment u v)"
   8.845 +    (is "?lhs = ?rhs")
   8.846 +proof (rule iffI)
   8.847 +  assume ?lhs
   8.848 +  then have p: "path (\<lambda>x. g ((v - u) * x + u))"
   8.849 +        and sim: "(\<And>x y. \<lbrakk>x\<in>{0..1}; y\<in>{0..1}; g ((v - u) * x + u) = g ((v - u) * y + u)\<rbrakk> 
   8.850 +                  \<Longrightarrow> x = y)"
   8.851 +    by (auto simp: arc_def inj_on_def subpath_def)
   8.852 +  { fix x y
   8.853 +    assume "x \<in> closed_segment u v" "y \<in> closed_segment u v" "g x = g y"
   8.854 +    then have "x = y"
   8.855 +    using sim [of "(x-u)/(v-u)" "(y-u)/(v-u)"] p
   8.856 +    by (force simp add: inj_on_def closed_segment_real_eq image_affinity_atLeastAtMost divide_simps 
   8.857 +       split: split_if_asm)
   8.858 +  } moreover
   8.859 +  have "path(subpath u v g) \<and> u\<noteq>v"
   8.860 +    using sim [of "1/3" "2/3"] p
   8.861 +    by (auto simp: subpath_def)
   8.862 +  ultimately show ?rhs
   8.863 +    unfolding inj_on_def   
   8.864 +    by metis
   8.865 +next
   8.866 +  assume ?rhs
   8.867 +  then 
   8.868 +  have d1: "\<And>x y. \<lbrakk>g x = g y; u \<le> x; x \<le> v; u \<le> y; y \<le> v\<rbrakk> \<Longrightarrow> x = y"
   8.869 +   and d2: "\<And>x y. \<lbrakk>g x = g y; v \<le> x; x \<le> u; v \<le> y; y \<le> u\<rbrakk> \<Longrightarrow> x = y"
   8.870 +   and ne: "u < v \<or> v < u"
   8.871 +   and psp: "path (subpath u v g)"
   8.872 +    by (auto simp: inj_on_def closed_segment_real_eq image_affinity_atLeastAtMost)
   8.873 +  show ?lhs using psp ne
   8.874 +    unfolding arc_def subpath_def inj_on_def
   8.875 +    by (auto simp: algebra_simps affine_ineq mult_left_mono crossproduct_eq dest: d1 d2)
   8.876 +qed
   8.877 +
   8.878 +
   8.879 +lemma simple_path_subpath: 
   8.880 +  assumes "simple_path g" "u \<in> {0..1}" "v \<in> {0..1}" "u \<noteq> v"
   8.881 +  shows "simple_path(subpath u v g)"
   8.882 +  using assms
   8.883 +  apply (simp add: simple_path_subpath_eq simple_path_imp_path)
   8.884 +  apply (simp add: simple_path_def closed_segment_real_eq image_affinity_atLeastAtMost, fastforce)
   8.885 +  done
   8.886 +
   8.887 +lemma arc_simple_path_subpath:
   8.888 +    "\<lbrakk>simple_path g; u \<in> {0..1}; v \<in> {0..1}; g u \<noteq> g v\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   8.889 +  by (force intro: simple_path_subpath simple_path_imp_arc)
   8.890 +
   8.891 +lemma arc_subpath_arc:
   8.892 +    "\<lbrakk>arc g; u \<in> {0..1}; v \<in> {0..1}; u \<noteq> v\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   8.893 +  by (meson arc_def arc_imp_simple_path arc_simple_path_subpath inj_onD)
   8.894 +
   8.895 +lemma arc_simple_path_subpath_interior: 
   8.896 +    "\<lbrakk>simple_path g; u \<in> {0..1}; v \<in> {0..1}; u \<noteq> v; \<bar>u-v\<bar> < 1\<rbrakk> \<Longrightarrow> arc(subpath u v g)"
   8.897 +    apply (rule arc_simple_path_subpath)
   8.898 +    apply (force simp: simple_path_def)+
   8.899 +    done
   8.900 +
   8.901 +lemma path_image_subpath_subset: 
   8.902 +    "\<lbrakk>path g; u \<in> {0..1}; v \<in> {0..1}\<rbrakk> \<Longrightarrow> path_image(subpath u v g) \<subseteq> path_image g"
   8.903 +  apply (simp add: closed_segment_real_eq image_affinity_atLeastAtMost)
   8.904 +  apply (auto simp: path_image_def)
   8.905 +  done
   8.906 +
   8.907 +lemma join_subpaths_middle: "subpath (0) ((1 / 2)) p +++ subpath ((1 / 2)) 1 p = p"
   8.908 +  by (rule ext) (simp add: joinpaths_def subpath_def divide_simps)
   8.909  
   8.910  
   8.911  subsection {* Reparametrizing a closed curve to start at some chosen point *}
   8.912 @@ -500,22 +930,15 @@
   8.913  
   8.914  lemma path_image_linepath[simp]: "path_image (linepath a b) = closed_segment a b"
   8.915    unfolding path_image_def segment linepath_def
   8.916 -  apply (rule set_eqI)
   8.917 -  apply rule
   8.918 -  defer
   8.919 -  unfolding mem_Collect_eq image_iff
   8.920 -  apply (erule exE)
   8.921 -  apply (rule_tac x="u *\<^sub>R 1" in bexI)
   8.922 -  apply auto
   8.923 -  done
   8.924 +  by auto
   8.925  
   8.926  lemma reversepath_linepath[simp]: "reversepath (linepath a b) = linepath b a"
   8.927    unfolding reversepath_def linepath_def
   8.928    by auto
   8.929  
   8.930 -lemma injective_path_linepath:
   8.931 +lemma arc_linepath:
   8.932    assumes "a \<noteq> b"
   8.933 -  shows "injective_path (linepath a b)"
   8.934 +  shows "arc (linepath a b)"
   8.935  proof -
   8.936    {
   8.937      fix x y :: "real"
   8.938 @@ -526,12 +949,12 @@
   8.939        by simp
   8.940    }
   8.941    then show ?thesis
   8.942 -    unfolding injective_path_def linepath_def
   8.943 -    by (auto simp add: algebra_simps)
   8.944 +    unfolding arc_def inj_on_def 
   8.945 +    by (simp add:  path_linepath) (force simp: algebra_simps linepath_def)
   8.946  qed
   8.947  
   8.948  lemma simple_path_linepath[intro]: "a \<noteq> b \<Longrightarrow> simple_path (linepath a b)"
   8.949 -  by (auto intro!: injective_imp_simple_path injective_path_linepath)
   8.950 +  by (simp add: arc_imp_simple_path arc_linepath)
   8.951  
   8.952  
   8.953  subsection {* Bounding a point away from a path *}
   8.954 @@ -623,29 +1046,16 @@
   8.955  lemma path_component_set:
   8.956    "{y. path_component s x y} =
   8.957      {y. (\<exists>g. path g \<and> path_image g \<subseteq> s \<and> pathstart g = x \<and> pathfinish g = y)}"
   8.958 -  apply (rule set_eqI)
   8.959 -  unfolding mem_Collect_eq
   8.960 -  unfolding path_component_def
   8.961 +  unfolding mem_Collect_eq path_component_def
   8.962    apply auto
   8.963    done
   8.964  
   8.965  lemma path_component_subset: "{y. path_component s x y} \<subseteq> s"
   8.966 -  apply rule
   8.967 -  apply (rule path_component_mem(2))
   8.968 -  apply auto
   8.969 -  done
   8.970 +  by (auto simp add: path_component_mem(2))
   8.971  
   8.972  lemma path_component_eq_empty: "{y. path_component s x y} = {} \<longleftrightarrow> x \<notin> s"
   8.973 -  apply rule
   8.974 -  apply (drule equals0D[of _ x])
   8.975 -  defer
   8.976 -  apply (rule equals0I)
   8.977 -  unfolding mem_Collect_eq
   8.978 -  apply (drule path_component_mem(1))
   8.979 -  using path_component_refl
   8.980 -  apply auto
   8.981 -  done
   8.982 -
   8.983 +  using path_component_mem path_component_refl_eq
   8.984 +    by fastforce
   8.985  
   8.986  subsection {* Path connectedness of a space *}
   8.987  
   8.988 @@ -656,15 +1066,9 @@
   8.989    unfolding path_connected_def path_component_def by auto
   8.990  
   8.991  lemma path_connected_component_set: "path_connected s \<longleftrightarrow> (\<forall>x\<in>s. {y. path_component s x y} = s)"
   8.992 -  unfolding path_connected_component
   8.993 -  apply rule
   8.994 -  apply rule
   8.995 -  apply rule
   8.996 -  apply (rule path_component_subset)
   8.997 -  unfolding subset_eq mem_Collect_eq Ball_def
   8.998 +  unfolding path_connected_component path_component_subset 
   8.999    apply auto
  8.1000 -  done
  8.1001 -
  8.1002 +  using path_component_mem(2) by blast
  8.1003  
  8.1004  subsection {* Some useful lemmas about path-connectedness *}
  8.1005  
     9.1 --- a/src/HOL/Real_Vector_Spaces.thy	Mon May 25 22:52:17 2015 +0200
     9.2 +++ b/src/HOL/Real_Vector_Spaces.thy	Tue May 26 21:58:04 2015 +0100
     9.3 @@ -518,6 +518,13 @@
     9.4  
     9.5  end
     9.6  
     9.7 +lemma neg_le_divideR_eq:
     9.8 +  fixes a :: "'a :: ordered_real_vector"
     9.9 +  assumes "c < 0"
    9.10 +  shows "a \<le> b /\<^sub>R c \<longleftrightarrow> b \<le> c *\<^sub>R a"
    9.11 +  using pos_le_divideR_eq [of "-c" a "-b"] assms
    9.12 +  by simp
    9.13 +
    9.14  lemma scaleR_nonneg_nonneg: "0 \<le> a \<Longrightarrow> 0 \<le> (x::'a::ordered_real_vector) \<Longrightarrow> 0 \<le> a *\<^sub>R x"
    9.15    using scaleR_left_mono [of 0 x a]
    9.16    by simp