src/HOL/Analysis/Cauchy_Integral_Theorem.thy
 author nipkow Sat Dec 29 15:43:53 2018 +0100 (6 months ago) changeset 69529 4ab9657b3257 parent 69517 dc20f278e8f3 child 69530 fc0da2166cda permissions -rw-r--r--
capitalize proper names in lemma names
1 section \<open>Complex Path Integrals and Cauchy's Integral Theorem\<close>
3 text\<open>By John Harrison et al.  Ported from HOL Light by L C Paulson (2015)\<close>
5 theory Cauchy_Integral_Theorem
6 imports Complex_Transcendental Weierstrass_Theorems Ordered_Euclidean_Space
7 begin
9 subsection%unimportant \<open>Homeomorphisms of arc images\<close>
11 lemma homeomorphism_arc:
12   fixes g :: "real \<Rightarrow> 'a::t2_space"
13   assumes "arc g"
14   obtains h where "homeomorphism {0..1} (path_image g) g h"
15 using assms by (force simp: arc_def homeomorphism_compact path_def path_image_def)
17 lemma homeomorphic_arc_image_interval:
18   fixes g :: "real \<Rightarrow> 'a::t2_space" and a::real
19   assumes "arc g" "a < b"
20   shows "(path_image g) homeomorphic {a..b}"
21 proof -
22   have "(path_image g) homeomorphic {0..1::real}"
23     by (meson assms(1) homeomorphic_def homeomorphic_sym homeomorphism_arc)
24   also have "\<dots> homeomorphic {a..b}"
25     using assms by (force intro: homeomorphic_closed_intervals_real)
26   finally show ?thesis .
27 qed
29 lemma homeomorphic_arc_images:
30   fixes g :: "real \<Rightarrow> 'a::t2_space" and h :: "real \<Rightarrow> 'b::t2_space"
31   assumes "arc g" "arc h"
32   shows "(path_image g) homeomorphic (path_image h)"
33 proof -
34   have "(path_image g) homeomorphic {0..1::real}"
35     by (meson assms homeomorphic_def homeomorphic_sym homeomorphism_arc)
36   also have "\<dots> homeomorphic (path_image h)"
37     by (meson assms homeomorphic_def homeomorphism_arc)
38   finally show ?thesis .
39 qed
41 lemma path_connected_arc_complement:
42   fixes \<gamma> :: "real \<Rightarrow> 'a::euclidean_space"
43   assumes "arc \<gamma>" "2 \<le> DIM('a)"
44   shows "path_connected(- path_image \<gamma>)"
45 proof -
46   have "path_image \<gamma> homeomorphic {0..1::real}"
47     by (simp add: assms homeomorphic_arc_image_interval)
48   then
49   show ?thesis
50     apply (rule path_connected_complement_homeomorphic_convex_compact)
51       apply (auto simp: assms)
52     done
53 qed
55 lemma connected_arc_complement:
56   fixes \<gamma> :: "real \<Rightarrow> 'a::euclidean_space"
57   assumes "arc \<gamma>" "2 \<le> DIM('a)"
58   shows "connected(- path_image \<gamma>)"
59   by (simp add: assms path_connected_arc_complement path_connected_imp_connected)
61 lemma inside_arc_empty:
62   fixes \<gamma> :: "real \<Rightarrow> 'a::euclidean_space"
63   assumes "arc \<gamma>"
64     shows "inside(path_image \<gamma>) = {}"
65 proof (cases "DIM('a) = 1")
66   case True
67   then show ?thesis
68     using assms connected_arc_image connected_convex_1_gen inside_convex by blast
69 next
70   case False
71   show ?thesis
72   proof (rule inside_bounded_complement_connected_empty)
73     show "connected (- path_image \<gamma>)"
74       apply (rule connected_arc_complement [OF assms])
75       using False
76       by (metis DIM_ge_Suc0 One_nat_def Suc_1 not_less_eq_eq order_class.order.antisym)
77     show "bounded (path_image \<gamma>)"
78       by (simp add: assms bounded_arc_image)
79   qed
80 qed
82 lemma inside_simple_curve_imp_closed:
83   fixes \<gamma> :: "real \<Rightarrow> 'a::euclidean_space"
84     shows "\<lbrakk>simple_path \<gamma>; x \<in> inside(path_image \<gamma>)\<rbrakk> \<Longrightarrow> pathfinish \<gamma> = pathstart \<gamma>"
85   using arc_simple_path  inside_arc_empty by blast
88 subsection%unimportant \<open>Piecewise differentiable functions\<close>
90 definition piecewise_differentiable_on
91            (infixr "piecewise'_differentiable'_on" 50)
92   where "f piecewise_differentiable_on i  \<equiv>
93            continuous_on i f \<and>
94            (\<exists>S. finite S \<and> (\<forall>x \<in> i - S. f differentiable (at x within i)))"
96 lemma piecewise_differentiable_on_imp_continuous_on:
97     "f piecewise_differentiable_on S \<Longrightarrow> continuous_on S f"
98 by (simp add: piecewise_differentiable_on_def)
100 lemma piecewise_differentiable_on_subset:
101     "f piecewise_differentiable_on S \<Longrightarrow> T \<le> S \<Longrightarrow> f piecewise_differentiable_on T"
102   using continuous_on_subset
103   unfolding piecewise_differentiable_on_def
104   apply safe
105   apply (blast elim: continuous_on_subset)
106   by (meson Diff_iff differentiable_within_subset subsetCE)
108 lemma differentiable_on_imp_piecewise_differentiable:
109   fixes a:: "'a::{linorder_topology,real_normed_vector}"
110   shows "f differentiable_on {a..b} \<Longrightarrow> f piecewise_differentiable_on {a..b}"
111   apply (simp add: piecewise_differentiable_on_def differentiable_imp_continuous_on)
112   apply (rule_tac x="{a,b}" in exI, simp add: differentiable_on_def)
113   done
115 lemma differentiable_imp_piecewise_differentiable:
116     "(\<And>x. x \<in> S \<Longrightarrow> f differentiable (at x within S))
117          \<Longrightarrow> f piecewise_differentiable_on S"
118 by (auto simp: piecewise_differentiable_on_def differentiable_imp_continuous_on differentiable_on_def
119          intro: differentiable_within_subset)
121 lemma piecewise_differentiable_const [iff]: "(\<lambda>x. z) piecewise_differentiable_on S"
122   by (simp add: differentiable_imp_piecewise_differentiable)
124 lemma piecewise_differentiable_compose:
125     "\<lbrakk>f piecewise_differentiable_on S; g piecewise_differentiable_on (f ` S);
126       \<And>x. finite (S \<inter> f-`{x})\<rbrakk>
127       \<Longrightarrow> (g \<circ> f) piecewise_differentiable_on S"
128   apply (simp add: piecewise_differentiable_on_def, safe)
129   apply (blast intro: continuous_on_compose2)
130   apply (rename_tac A B)
131   apply (rule_tac x="A \<union> (\<Union>x\<in>B. S \<inter> f-`{x})" in exI)
132   apply (blast intro!: differentiable_chain_within)
133   done
135 lemma piecewise_differentiable_affine:
136   fixes m::real
137   assumes "f piecewise_differentiable_on ((\<lambda>x. m *\<^sub>R x + c) ` S)"
138   shows "(f \<circ> (\<lambda>x. m *\<^sub>R x + c)) piecewise_differentiable_on S"
139 proof (cases "m = 0")
140   case True
141   then show ?thesis
142     unfolding o_def
143     by (force intro: differentiable_imp_piecewise_differentiable differentiable_const)
144 next
145   case False
146   show ?thesis
147     apply (rule piecewise_differentiable_compose [OF differentiable_imp_piecewise_differentiable])
148     apply (rule assms derivative_intros | simp add: False vimage_def real_vector_affinity_eq)+
149     done
150 qed
152 lemma piecewise_differentiable_cases:
153   fixes c::real
154   assumes "f piecewise_differentiable_on {a..c}"
155           "g piecewise_differentiable_on {c..b}"
156            "a \<le> c" "c \<le> b" "f c = g c"
157   shows "(\<lambda>x. if x \<le> c then f x else g x) piecewise_differentiable_on {a..b}"
158 proof -
159   obtain S T where st: "finite S" "finite T"
160                and fd: "\<And>x. x \<in> {a..c} - S \<Longrightarrow> f differentiable at x within {a..c}"
161                and gd: "\<And>x. x \<in> {c..b} - T \<Longrightarrow> g differentiable at x within {c..b}"
162     using assms
163     by (auto simp: piecewise_differentiable_on_def)
164   have finabc: "finite ({a,b,c} \<union> (S \<union> T))"
165     by (metis \<open>finite S\<close> \<open>finite T\<close> finite_Un finite_insert finite.emptyI)
166   have "continuous_on {a..c} f" "continuous_on {c..b} g"
167     using assms piecewise_differentiable_on_def by auto
168   then have "continuous_on {a..b} (\<lambda>x. if x \<le> c then f x else g x)"
169     using continuous_on_cases [OF closed_real_atLeastAtMost [of a c],
170                                OF closed_real_atLeastAtMost [of c b],
171                                of f g "\<lambda>x. x\<le>c"]  assms
172     by (force simp: ivl_disj_un_two_touch)
173   moreover
174   { fix x
175     assume x: "x \<in> {a..b} - ({a,b,c} \<union> (S \<union> T))"
176     have "(\<lambda>x. if x \<le> c then f x else g x) differentiable at x within {a..b}" (is "?diff_fg")
177     proof (cases x c rule: le_cases)
178       case le show ?diff_fg
179       proof (rule differentiable_transform_within [where d = "dist x c"])
180         have "f differentiable at x"
181           using x le fd [of x] at_within_interior [of x "{a..c}"] by simp
182         then show "f differentiable at x within {a..b}"
183           by (simp add: differentiable_at_withinI)
184       qed (use x le st dist_real_def in auto)
185     next
186       case ge show ?diff_fg
187       proof (rule differentiable_transform_within [where d = "dist x c"])
188         have "g differentiable at x"
189           using x ge gd [of x] at_within_interior [of x "{c..b}"] by simp
190         then show "g differentiable at x within {a..b}"
191           by (simp add: differentiable_at_withinI)
192       qed (use x ge st dist_real_def in auto)
193     qed
194   }
195   then have "\<exists>S. finite S \<and>
196                  (\<forall>x\<in>{a..b} - S. (\<lambda>x. if x \<le> c then f x else g x) differentiable at x within {a..b})"
197     by (meson finabc)
198   ultimately show ?thesis
199     by (simp add: piecewise_differentiable_on_def)
200 qed
202 lemma piecewise_differentiable_neg:
203     "f piecewise_differentiable_on S \<Longrightarrow> (\<lambda>x. -(f x)) piecewise_differentiable_on S"
204   by (auto simp: piecewise_differentiable_on_def continuous_on_minus)
207   assumes "f piecewise_differentiable_on i"
208           "g piecewise_differentiable_on i"
209     shows "(\<lambda>x. f x + g x) piecewise_differentiable_on i"
210 proof -
211   obtain S T where st: "finite S" "finite T"
212                        "\<forall>x\<in>i - S. f differentiable at x within i"
213                        "\<forall>x\<in>i - T. g differentiable at x within i"
214     using assms by (auto simp: piecewise_differentiable_on_def)
215   then have "finite (S \<union> T) \<and> (\<forall>x\<in>i - (S \<union> T). (\<lambda>x. f x + g x) differentiable at x within i)"
216     by auto
217   moreover have "continuous_on i f" "continuous_on i g"
218     using assms piecewise_differentiable_on_def by auto
219   ultimately show ?thesis
220     by (auto simp: piecewise_differentiable_on_def continuous_on_add)
221 qed
223 lemma piecewise_differentiable_diff:
224     "\<lbrakk>f piecewise_differentiable_on S;  g piecewise_differentiable_on S\<rbrakk>
225      \<Longrightarrow> (\<lambda>x. f x - g x) piecewise_differentiable_on S"
227   by (metis piecewise_differentiable_add piecewise_differentiable_neg)
229 lemma continuous_on_joinpaths_D1:
230     "continuous_on {0..1} (g1 +++ g2) \<Longrightarrow> continuous_on {0..1} g1"
231   apply (rule continuous_on_eq [of _ "(g1 +++ g2) \<circ> ((*)(inverse 2))"])
232   apply (rule continuous_intros | simp)+
233   apply (auto elim!: continuous_on_subset simp: joinpaths_def)
234   done
236 lemma continuous_on_joinpaths_D2:
237     "\<lbrakk>continuous_on {0..1} (g1 +++ g2); pathfinish g1 = pathstart g2\<rbrakk> \<Longrightarrow> continuous_on {0..1} g2"
238   apply (rule continuous_on_eq [of _ "(g1 +++ g2) \<circ> (\<lambda>x. inverse 2*x + 1/2)"])
239   apply (rule continuous_intros | simp)+
240   apply (auto elim!: continuous_on_subset simp add: joinpaths_def pathfinish_def pathstart_def Ball_def)
241   done
243 lemma piecewise_differentiable_D1:
244   assumes "(g1 +++ g2) piecewise_differentiable_on {0..1}"
245   shows "g1 piecewise_differentiable_on {0..1}"
246 proof -
247   obtain S where cont: "continuous_on {0..1} g1" and "finite S"
248     and S: "\<And>x. x \<in> {0..1} - S \<Longrightarrow> g1 +++ g2 differentiable at x within {0..1}"
249     using assms unfolding piecewise_differentiable_on_def
250     by (blast dest!: continuous_on_joinpaths_D1)
251   show ?thesis
252     unfolding piecewise_differentiable_on_def
253   proof (intro exI conjI ballI cont)
254     show "finite (insert 1 (((*)2) ` S))"
255       by (simp add: \<open>finite S\<close>)
256     show "g1 differentiable at x within {0..1}" if "x \<in> {0..1} - insert 1 ((*) 2 ` S)" for x
257     proof (rule_tac d="dist (x/2) (1/2)" in differentiable_transform_within)
258       have "g1 +++ g2 differentiable at (x / 2) within {0..1/2}"
259         by (rule differentiable_subset [OF S [of "x/2"]] | use that in force)+
260       then show "g1 +++ g2 \<circ> (*) (inverse 2) differentiable at x within {0..1}"
261         by (auto intro: differentiable_chain_within)
262     qed (use that in \<open>auto simp: joinpaths_def\<close>)
263   qed
264 qed
266 lemma piecewise_differentiable_D2:
267   assumes "(g1 +++ g2) piecewise_differentiable_on {0..1}" and eq: "pathfinish g1 = pathstart g2"
268   shows "g2 piecewise_differentiable_on {0..1}"
269 proof -
270   have [simp]: "g1 1 = g2 0"
271     using eq by (simp add: pathfinish_def pathstart_def)
272   obtain S where cont: "continuous_on {0..1} g2" and "finite S"
273     and S: "\<And>x. x \<in> {0..1} - S \<Longrightarrow> g1 +++ g2 differentiable at x within {0..1}"
274     using assms unfolding piecewise_differentiable_on_def
275     by (blast dest!: continuous_on_joinpaths_D2)
276   show ?thesis
277     unfolding piecewise_differentiable_on_def
278   proof (intro exI conjI ballI cont)
279     show "finite (insert 0 ((\<lambda>x. 2*x-1)`S))"
280       by (simp add: \<open>finite S\<close>)
281     show "g2 differentiable at x within {0..1}" if "x \<in> {0..1} - insert 0 ((\<lambda>x. 2*x-1)`S)" for x
282     proof (rule_tac d="dist ((x+1)/2) (1/2)" in differentiable_transform_within)
283       have x2: "(x + 1) / 2 \<notin> S"
284         using that
285         apply (clarsimp simp: image_iff)
286         by (metis add.commute add_diff_cancel_left' mult_2 field_sum_of_halves)
287       have "g1 +++ g2 \<circ> (\<lambda>x. (x+1) / 2) differentiable at x within {0..1}"
288         by (rule differentiable_chain_within differentiable_subset [OF S [of "(x+1)/2"]] | use x2 that in force)+
289       then show "g1 +++ g2 \<circ> (\<lambda>x. (x+1) / 2) differentiable at x within {0..1}"
290         by (auto intro: differentiable_chain_within)
291       show "(g1 +++ g2 \<circ> (\<lambda>x. (x + 1) / 2)) x' = g2 x'" if "x' \<in> {0..1}" "dist x' x < dist ((x + 1) / 2) (1/2)" for x'
292       proof -
293         have [simp]: "(2*x'+2)/2 = x'+1"
294           by (simp add: divide_simps)
295         show ?thesis
296           using that by (auto simp: joinpaths_def)
297       qed
298     qed (use that in \<open>auto simp: joinpaths_def\<close>)
299   qed
300 qed
303 subsection\<open>The concept of continuously differentiable\<close>
305 text \<open>
306 John Harrison writes as follows:
308 ``The usual assumption in complex analysis texts is that a path \<open>\<gamma>\<close> should be piecewise
309 continuously differentiable, which ensures that the path integral exists at least for any continuous
310 f, since all piecewise continuous functions are integrable. However, our notion of validity is
311 weaker, just piecewise differentiability\ldots{} [namely] continuity plus differentiability except on a
312 finite set\ldots{} [Our] underlying theory of integration is the Kurzweil-Henstock theory. In contrast to
313 the Riemann or Lebesgue theory (but in common with a simple notion based on antiderivatives), this
314 can integrate all derivatives.''
316 "Formalizing basic complex analysis." From Insight to Proof: Festschrift in Honour of Andrzej Trybulec.
317 Studies in Logic, Grammar and Rhetoric 10.23 (2007): 151-165.
319 And indeed he does not assume that his derivatives are continuous, but the penalty is unreasonably
320 difficult proofs concerning winding numbers. We need a self-contained and straightforward theorem
321 asserting that all derivatives can be integrated before we can adopt Harrison's choice.\<close>
323 definition%important C1_differentiable_on :: "(real \<Rightarrow> 'a::real_normed_vector) \<Rightarrow> real set \<Rightarrow> bool"
324            (infix "C1'_differentiable'_on" 50)
325   where
326   "f C1_differentiable_on S \<longleftrightarrow>
327    (\<exists>D. (\<forall>x \<in> S. (f has_vector_derivative (D x)) (at x)) \<and> continuous_on S D)"
329 lemma C1_differentiable_on_eq:
330     "f C1_differentiable_on S \<longleftrightarrow>
331      (\<forall>x \<in> S. f differentiable at x) \<and> continuous_on S (\<lambda>x. vector_derivative f (at x))"
332      (is "?lhs = ?rhs")
333 proof
334   assume ?lhs
335   then show ?rhs
336     unfolding C1_differentiable_on_def
337     by (metis (no_types, lifting) continuous_on_eq  differentiableI_vector vector_derivative_at)
338 next
339   assume ?rhs
340   then show ?lhs
341     using C1_differentiable_on_def vector_derivative_works by fastforce
342 qed
344 lemma C1_differentiable_on_subset:
345   "f C1_differentiable_on T \<Longrightarrow> S \<subseteq> T \<Longrightarrow> f C1_differentiable_on S"
346   unfolding C1_differentiable_on_def  continuous_on_eq_continuous_within
347   by (blast intro:  continuous_within_subset)
349 lemma C1_differentiable_compose:
350   assumes fg: "f C1_differentiable_on S" "g C1_differentiable_on (f ` S)" and fin: "\<And>x. finite (S \<inter> f-`{x})"
351   shows "(g \<circ> f) C1_differentiable_on S"
352 proof -
353   have "\<And>x. x \<in> S \<Longrightarrow> g \<circ> f differentiable at x"
354     by (meson C1_differentiable_on_eq assms differentiable_chain_at imageI)
355   moreover have "continuous_on S (\<lambda>x. vector_derivative (g \<circ> f) (at x))"
356   proof (rule continuous_on_eq [of _ "\<lambda>x. vector_derivative f (at x) *\<^sub>R vector_derivative g (at (f x))"])
357     show "continuous_on S (\<lambda>x. vector_derivative f (at x) *\<^sub>R vector_derivative g (at (f x)))"
358       using fg
359       apply (clarsimp simp add: C1_differentiable_on_eq)
360       apply (rule Limits.continuous_on_scaleR, assumption)
361       by (metis (mono_tags, lifting) continuous_at_imp_continuous_on continuous_on_compose continuous_on_cong differentiable_imp_continuous_within o_def)
362     show "\<And>x. x \<in> S \<Longrightarrow> vector_derivative f (at x) *\<^sub>R vector_derivative g (at (f x)) = vector_derivative (g \<circ> f) (at x)"
363       by (metis (mono_tags, hide_lams) C1_differentiable_on_eq fg imageI vector_derivative_chain_at)
364   qed
365   ultimately show ?thesis
366     by (simp add: C1_differentiable_on_eq)
367 qed
369 lemma C1_diff_imp_diff: "f C1_differentiable_on S \<Longrightarrow> f differentiable_on S"
370   by (simp add: C1_differentiable_on_eq differentiable_at_imp_differentiable_on)
372 lemma C1_differentiable_on_ident [simp, derivative_intros]: "(\<lambda>x. x) C1_differentiable_on S"
373   by (auto simp: C1_differentiable_on_eq continuous_on_const)
375 lemma C1_differentiable_on_const [simp, derivative_intros]: "(\<lambda>z. a) C1_differentiable_on S"
376   by (auto simp: C1_differentiable_on_eq continuous_on_const)
378 lemma C1_differentiable_on_add [simp, derivative_intros]:
379   "f C1_differentiable_on S \<Longrightarrow> g C1_differentiable_on S \<Longrightarrow> (\<lambda>x. f x + g x) C1_differentiable_on S"
380   unfolding C1_differentiable_on_eq  by (auto intro: continuous_intros)
382 lemma C1_differentiable_on_minus [simp, derivative_intros]:
383   "f C1_differentiable_on S \<Longrightarrow> (\<lambda>x. - f x) C1_differentiable_on S"
384   unfolding C1_differentiable_on_eq  by (auto intro: continuous_intros)
386 lemma C1_differentiable_on_diff [simp, derivative_intros]:
387   "f C1_differentiable_on S \<Longrightarrow> g C1_differentiable_on S \<Longrightarrow> (\<lambda>x. f x - g x) C1_differentiable_on S"
388   unfolding C1_differentiable_on_eq  by (auto intro: continuous_intros)
390 lemma C1_differentiable_on_mult [simp, derivative_intros]:
391   fixes f g :: "real \<Rightarrow> 'a :: real_normed_algebra"
392   shows "f C1_differentiable_on S \<Longrightarrow> g C1_differentiable_on S \<Longrightarrow> (\<lambda>x. f x * g x) C1_differentiable_on S"
393   unfolding C1_differentiable_on_eq
394   by (auto simp: continuous_on_add continuous_on_mult continuous_at_imp_continuous_on differentiable_imp_continuous_within)
396 lemma C1_differentiable_on_scaleR [simp, derivative_intros]:
397   "f C1_differentiable_on S \<Longrightarrow> g C1_differentiable_on S \<Longrightarrow> (\<lambda>x. f x *\<^sub>R g x) C1_differentiable_on S"
398   unfolding C1_differentiable_on_eq
399   by (rule continuous_intros | simp add: continuous_at_imp_continuous_on differentiable_imp_continuous_within)+
402 definition%important piecewise_C1_differentiable_on
403            (infixr "piecewise'_C1'_differentiable'_on" 50)
404   where "f piecewise_C1_differentiable_on i  \<equiv>
405            continuous_on i f \<and>
406            (\<exists>S. finite S \<and> (f C1_differentiable_on (i - S)))"
408 lemma C1_differentiable_imp_piecewise:
409     "f C1_differentiable_on S \<Longrightarrow> f piecewise_C1_differentiable_on S"
410   by (auto simp: piecewise_C1_differentiable_on_def C1_differentiable_on_eq continuous_at_imp_continuous_on differentiable_imp_continuous_within)
412 lemma piecewise_C1_imp_differentiable:
413     "f piecewise_C1_differentiable_on i \<Longrightarrow> f piecewise_differentiable_on i"
414   by (auto simp: piecewise_C1_differentiable_on_def piecewise_differentiable_on_def
415            C1_differentiable_on_def differentiable_def has_vector_derivative_def
416            intro: has_derivative_at_withinI)
418 lemma piecewise_C1_differentiable_compose:
419   assumes fg: "f piecewise_C1_differentiable_on S" "g piecewise_C1_differentiable_on (f ` S)" and fin: "\<And>x. finite (S \<inter> f-`{x})"
420   shows "(g \<circ> f) piecewise_C1_differentiable_on S"
421 proof -
422   have "continuous_on S (\<lambda>x. g (f x))"
423     by (metis continuous_on_compose2 fg order_refl piecewise_C1_differentiable_on_def)
424   moreover have "\<exists>T. finite T \<and> g \<circ> f C1_differentiable_on S - T"
425   proof -
426     obtain F where "finite F" and F: "f C1_differentiable_on S - F" and f: "f piecewise_C1_differentiable_on S"
427       using fg by (auto simp: piecewise_C1_differentiable_on_def)
428     obtain G where "finite G" and G: "g C1_differentiable_on f ` S - G" and g: "g piecewise_C1_differentiable_on f ` S"
429       using fg by (auto simp: piecewise_C1_differentiable_on_def)
430     show ?thesis
431     proof (intro exI conjI)
432       show "finite (F \<union> (\<Union>x\<in>G. S \<inter> f-`{x}))"
433         using fin by (auto simp only: Int_Union \<open>finite F\<close> \<open>finite G\<close> finite_UN finite_imageI)
434       show "g \<circ> f C1_differentiable_on S - (F \<union> (\<Union>x\<in>G. S \<inter> f -` {x}))"
435         apply (rule C1_differentiable_compose)
436           apply (blast intro: C1_differentiable_on_subset [OF F])
437           apply (blast intro: C1_differentiable_on_subset [OF G])
438         by (simp add:  C1_differentiable_on_subset G Diff_Int_distrib2 fin)
439     qed
440   qed
441   ultimately show ?thesis
442     by (simp add: piecewise_C1_differentiable_on_def)
443 qed
445 lemma piecewise_C1_differentiable_on_subset:
446     "f piecewise_C1_differentiable_on S \<Longrightarrow> T \<le> S \<Longrightarrow> f piecewise_C1_differentiable_on T"
447   by (auto simp: piecewise_C1_differentiable_on_def elim!: continuous_on_subset C1_differentiable_on_subset)
449 lemma C1_differentiable_imp_continuous_on:
450   "f C1_differentiable_on S \<Longrightarrow> continuous_on S f"
451   unfolding C1_differentiable_on_eq continuous_on_eq_continuous_within
452   using differentiable_at_withinI differentiable_imp_continuous_within by blast
454 lemma C1_differentiable_on_empty [iff]: "f C1_differentiable_on {}"
455   unfolding C1_differentiable_on_def
456   by auto
458 lemma piecewise_C1_differentiable_affine:
459   fixes m::real
460   assumes "f piecewise_C1_differentiable_on ((\<lambda>x. m * x + c) ` S)"
461   shows "(f \<circ> (\<lambda>x. m *\<^sub>R x + c)) piecewise_C1_differentiable_on S"
462 proof (cases "m = 0")
463   case True
464   then show ?thesis
465     unfolding o_def by (auto simp: piecewise_C1_differentiable_on_def continuous_on_const)
466 next
467   case False
468   have *: "\<And>x. finite (S \<inter> {y. m * y + c = x})"
469     using False not_finite_existsD by fastforce
470   show ?thesis
471     apply (rule piecewise_C1_differentiable_compose [OF C1_differentiable_imp_piecewise])
472     apply (rule * assms derivative_intros | simp add: False vimage_def)+
473     done
474 qed
476 lemma piecewise_C1_differentiable_cases:
477   fixes c::real
478   assumes "f piecewise_C1_differentiable_on {a..c}"
479           "g piecewise_C1_differentiable_on {c..b}"
480            "a \<le> c" "c \<le> b" "f c = g c"
481   shows "(\<lambda>x. if x \<le> c then f x else g x) piecewise_C1_differentiable_on {a..b}"
482 proof -
483   obtain S T where st: "f C1_differentiable_on ({a..c} - S)"
484                        "g C1_differentiable_on ({c..b} - T)"
485                        "finite S" "finite T"
486     using assms
487     by (force simp: piecewise_C1_differentiable_on_def)
488   then have f_diff: "f differentiable_on {a..<c} - S"
489         and g_diff: "g differentiable_on {c<..b} - T"
490     by (simp_all add: C1_differentiable_on_eq differentiable_at_withinI differentiable_on_def)
491   have "continuous_on {a..c} f" "continuous_on {c..b} g"
492     using assms piecewise_C1_differentiable_on_def by auto
493   then have cab: "continuous_on {a..b} (\<lambda>x. if x \<le> c then f x else g x)"
494     using continuous_on_cases [OF closed_real_atLeastAtMost [of a c],
495                                OF closed_real_atLeastAtMost [of c b],
496                                of f g "\<lambda>x. x\<le>c"]  assms
497     by (force simp: ivl_disj_un_two_touch)
498   { fix x
499     assume x: "x \<in> {a..b} - insert c (S \<union> T)"
500     have "(\<lambda>x. if x \<le> c then f x else g x) differentiable at x" (is "?diff_fg")
501     proof (cases x c rule: le_cases)
502       case le show ?diff_fg
503         apply (rule differentiable_transform_within [where f=f and d = "dist x c"])
504         using x dist_real_def le st by (auto simp: C1_differentiable_on_eq)
505     next
506       case ge show ?diff_fg
507         apply (rule differentiable_transform_within [where f=g and d = "dist x c"])
508         using dist_nz x dist_real_def ge st x by (auto simp: C1_differentiable_on_eq)
509     qed
510   }
511   then have "(\<forall>x \<in> {a..b} - insert c (S \<union> T). (\<lambda>x. if x \<le> c then f x else g x) differentiable at x)"
512     by auto
513   moreover
514   { assume fcon: "continuous_on ({a<..<c} - S) (\<lambda>x. vector_derivative f (at x))"
515        and gcon: "continuous_on ({c<..<b} - T) (\<lambda>x. vector_derivative g (at x))"
516     have "open ({a<..<c} - S)"  "open ({c<..<b} - T)"
517       using st by (simp_all add: open_Diff finite_imp_closed)
518     moreover have "continuous_on ({a<..<c} - S) (\<lambda>x. vector_derivative (\<lambda>x. if x \<le> c then f x else g x) (at x))"
519     proof -
520       have "((\<lambda>x. if x \<le> c then f x else g x) has_vector_derivative vector_derivative f (at x))            (at x)"
521         if "a < x" "x < c" "x \<notin> S" for x
522       proof -
523         have f: "f differentiable at x"
524           by (meson C1_differentiable_on_eq Diff_iff atLeastAtMost_iff less_eq_real_def st(1) that)
525         show ?thesis
526           using that
527           apply (rule_tac f=f and d="dist x c" in has_vector_derivative_transform_within)
528              apply (auto simp: dist_norm vector_derivative_works [symmetric] f)
529           done
530       qed
531       then show ?thesis
532         by (metis (no_types, lifting) continuous_on_eq [OF fcon] DiffE greaterThanLessThan_iff vector_derivative_at)
533     qed
534     moreover have "continuous_on ({c<..<b} - T) (\<lambda>x. vector_derivative (\<lambda>x. if x \<le> c then f x else g x) (at x))"
535     proof -
536       have "((\<lambda>x. if x \<le> c then f x else g x) has_vector_derivative vector_derivative g (at x))            (at x)"
537         if "c < x" "x < b" "x \<notin> T" for x
538       proof -
539         have g: "g differentiable at x"
540           by (metis C1_differentiable_on_eq DiffD1 DiffI atLeastAtMost_diff_ends greaterThanLessThan_iff st(2) that)
541         show ?thesis
542           using that
543           apply (rule_tac f=g and d="dist x c" in has_vector_derivative_transform_within)
544              apply (auto simp: dist_norm vector_derivative_works [symmetric] g)
545           done
546       qed
547       then show ?thesis
548         by (metis (no_types, lifting) continuous_on_eq [OF gcon] DiffE greaterThanLessThan_iff vector_derivative_at)
549     qed
550     ultimately have "continuous_on ({a<..<b} - insert c (S \<union> T))
551         (\<lambda>x. vector_derivative (\<lambda>x. if x \<le> c then f x else g x) (at x))"
552       by (rule continuous_on_subset [OF continuous_on_open_Un], auto)
553   } note * = this
554   have "continuous_on ({a<..<b} - insert c (S \<union> T)) (\<lambda>x. vector_derivative (\<lambda>x. if x \<le> c then f x else g x) (at x))"
555     using st
556     by (auto simp: C1_differentiable_on_eq elim!: continuous_on_subset intro: *)
557   ultimately have "\<exists>S. finite S \<and> ((\<lambda>x. if x \<le> c then f x else g x) C1_differentiable_on {a..b} - S)"
558     apply (rule_tac x="{a,b,c} \<union> S \<union> T" in exI)
559     using st  by (auto simp: C1_differentiable_on_eq elim!: continuous_on_subset)
560   with cab show ?thesis
561     by (simp add: piecewise_C1_differentiable_on_def)
562 qed
564 lemma piecewise_C1_differentiable_neg:
565     "f piecewise_C1_differentiable_on S \<Longrightarrow> (\<lambda>x. -(f x)) piecewise_C1_differentiable_on S"
566   unfolding piecewise_C1_differentiable_on_def
567   by (auto intro!: continuous_on_minus C1_differentiable_on_minus)
570   assumes "f piecewise_C1_differentiable_on i"
571           "g piecewise_C1_differentiable_on i"
572     shows "(\<lambda>x. f x + g x) piecewise_C1_differentiable_on i"
573 proof -
574   obtain S t where st: "finite S" "finite t"
575                        "f C1_differentiable_on (i-S)"
576                        "g C1_differentiable_on (i-t)"
577     using assms by (auto simp: piecewise_C1_differentiable_on_def)
578   then have "finite (S \<union> t) \<and> (\<lambda>x. f x + g x) C1_differentiable_on i - (S \<union> t)"
579     by (auto intro: C1_differentiable_on_add elim!: C1_differentiable_on_subset)
580   moreover have "continuous_on i f" "continuous_on i g"
581     using assms piecewise_C1_differentiable_on_def by auto
582   ultimately show ?thesis
583     by (auto simp: piecewise_C1_differentiable_on_def continuous_on_add)
584 qed
586 lemma piecewise_C1_differentiable_diff:
587     "\<lbrakk>f piecewise_C1_differentiable_on S;  g piecewise_C1_differentiable_on S\<rbrakk>
588      \<Longrightarrow> (\<lambda>x. f x - g x) piecewise_C1_differentiable_on S"
590   by (metis piecewise_C1_differentiable_add piecewise_C1_differentiable_neg)
592 lemma piecewise_C1_differentiable_D1:
593   fixes g1 :: "real \<Rightarrow> 'a::real_normed_field"
594   assumes "(g1 +++ g2) piecewise_C1_differentiable_on {0..1}"
595     shows "g1 piecewise_C1_differentiable_on {0..1}"
596 proof -
597   obtain S where "finite S"
598              and co12: "continuous_on ({0..1} - S) (\<lambda>x. vector_derivative (g1 +++ g2) (at x))"
599              and g12D: "\<forall>x\<in>{0..1} - S. g1 +++ g2 differentiable at x"
600     using assms  by (auto simp: piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
601   have g1D: "g1 differentiable at x" if "x \<in> {0..1} - insert 1 ((*) 2 ` S)" for x
602   proof (rule differentiable_transform_within)
603     show "g1 +++ g2 \<circ> (*) (inverse 2) differentiable at x"
604       using that g12D
605       apply (simp only: joinpaths_def)
606       by (rule differentiable_chain_at derivative_intros | force)+
607     show "\<And>x'. \<lbrakk>dist x' x < dist (x/2) (1/2)\<rbrakk>
608           \<Longrightarrow> (g1 +++ g2 \<circ> (*) (inverse 2)) x' = g1 x'"
609       using that by (auto simp: dist_real_def joinpaths_def)
610   qed (use that in \<open>auto simp: dist_real_def\<close>)
611   have [simp]: "vector_derivative (g1 \<circ> (*) 2) (at (x/2)) = 2 *\<^sub>R vector_derivative g1 (at x)"
612                if "x \<in> {0..1} - insert 1 ((*) 2 ` S)" for x
613     apply (subst vector_derivative_chain_at)
614     using that
615     apply (rule derivative_eq_intros g1D | simp)+
616     done
617   have "continuous_on ({0..1/2} - insert (1/2) S) (\<lambda>x. vector_derivative (g1 +++ g2) (at x))"
618     using co12 by (rule continuous_on_subset) force
619   then have coDhalf: "continuous_on ({0..1/2} - insert (1/2) S) (\<lambda>x. vector_derivative (g1 \<circ> (*)2) (at x))"
620   proof (rule continuous_on_eq [OF _ vector_derivative_at])
621     show "(g1 +++ g2 has_vector_derivative vector_derivative (g1 \<circ> (*) 2) (at x)) (at x)"
622       if "x \<in> {0..1/2} - insert (1/2) S" for x
623     proof (rule has_vector_derivative_transform_within)
624       show "(g1 \<circ> (*) 2 has_vector_derivative vector_derivative (g1 \<circ> (*) 2) (at x)) (at x)"
625         using that
626         by (force intro: g1D differentiable_chain_at simp: vector_derivative_works [symmetric])
627       show "\<And>x'. \<lbrakk>dist x' x < dist x (1/2)\<rbrakk> \<Longrightarrow> (g1 \<circ> (*) 2) x' = (g1 +++ g2) x'"
628         using that by (auto simp: dist_norm joinpaths_def)
629     qed (use that in \<open>auto simp: dist_norm\<close>)
630   qed
631   have "continuous_on ({0..1} - insert 1 ((*) 2 ` S))
632                       ((\<lambda>x. 1/2 * vector_derivative (g1 \<circ> (*)2) (at x)) \<circ> (*)(1/2))"
633     apply (rule continuous_intros)+
634     using coDhalf
635     apply (simp add: scaleR_conv_of_real image_set_diff image_image)
636     done
637   then have con_g1: "continuous_on ({0..1} - insert 1 ((*) 2 ` S)) (\<lambda>x. vector_derivative g1 (at x))"
638     by (rule continuous_on_eq) (simp add: scaleR_conv_of_real)
639   have "continuous_on {0..1} g1"
640     using continuous_on_joinpaths_D1 assms piecewise_C1_differentiable_on_def by blast
641   with \<open>finite S\<close> show ?thesis
642     apply (clarsimp simp add: piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
643     apply (rule_tac x="insert 1 (((*)2)`S)" in exI)
644     apply (simp add: g1D con_g1)
645   done
646 qed
648 lemma piecewise_C1_differentiable_D2:
649   fixes g2 :: "real \<Rightarrow> 'a::real_normed_field"
650   assumes "(g1 +++ g2) piecewise_C1_differentiable_on {0..1}" "pathfinish g1 = pathstart g2"
651     shows "g2 piecewise_C1_differentiable_on {0..1}"
652 proof -
653   obtain S where "finite S"
654              and co12: "continuous_on ({0..1} - S) (\<lambda>x. vector_derivative (g1 +++ g2) (at x))"
655              and g12D: "\<forall>x\<in>{0..1} - S. g1 +++ g2 differentiable at x"
656     using assms  by (auto simp: piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
657   have g2D: "g2 differentiable at x" if "x \<in> {0..1} - insert 0 ((\<lambda>x. 2*x-1) ` S)" for x
658   proof (rule differentiable_transform_within)
659     show "g1 +++ g2 \<circ> (\<lambda>x. (x + 1) / 2) differentiable at x"
660       using g12D that
661       apply (simp only: joinpaths_def)
662       apply (drule_tac x= "(x+1) / 2" in bspec, force simp: divide_simps)
663       apply (rule differentiable_chain_at derivative_intros | force)+
664       done
665     show "\<And>x'. dist x' x < dist ((x + 1) / 2) (1/2) \<Longrightarrow> (g1 +++ g2 \<circ> (\<lambda>x. (x + 1) / 2)) x' = g2 x'"
666       using that by (auto simp: dist_real_def joinpaths_def field_simps)
667     qed (use that in \<open>auto simp: dist_norm\<close>)
668   have [simp]: "vector_derivative (g2 \<circ> (\<lambda>x. 2*x-1)) (at ((x+1)/2)) = 2 *\<^sub>R vector_derivative g2 (at x)"
669                if "x \<in> {0..1} - insert 0 ((\<lambda>x. 2*x-1) ` S)" for x
670     using that  by (auto simp: vector_derivative_chain_at divide_simps g2D)
671   have "continuous_on ({1/2..1} - insert (1/2) S) (\<lambda>x. vector_derivative (g1 +++ g2) (at x))"
672     using co12 by (rule continuous_on_subset) force
673   then have coDhalf: "continuous_on ({1/2..1} - insert (1/2) S) (\<lambda>x. vector_derivative (g2 \<circ> (\<lambda>x. 2*x-1)) (at x))"
674   proof (rule continuous_on_eq [OF _ vector_derivative_at])
675     show "(g1 +++ g2 has_vector_derivative vector_derivative (g2 \<circ> (\<lambda>x. 2 * x - 1)) (at x))
676           (at x)"
677       if "x \<in> {1 / 2..1} - insert (1 / 2) S" for x
678     proof (rule_tac f="g2 \<circ> (\<lambda>x. 2*x-1)" and d="dist (3/4) ((x+1)/2)" in has_vector_derivative_transform_within)
679       show "(g2 \<circ> (\<lambda>x. 2 * x - 1) has_vector_derivative vector_derivative (g2 \<circ> (\<lambda>x. 2 * x - 1)) (at x))
680             (at x)"
681         using that by (force intro: g2D differentiable_chain_at simp: vector_derivative_works [symmetric])
682       show "\<And>x'. \<lbrakk>dist x' x < dist (3 / 4) ((x + 1) / 2)\<rbrakk> \<Longrightarrow> (g2 \<circ> (\<lambda>x. 2 * x - 1)) x' = (g1 +++ g2) x'"
683         using that by (auto simp: dist_norm joinpaths_def add_divide_distrib)
684     qed (use that in \<open>auto simp: dist_norm\<close>)
685   qed
686   have [simp]: "((\<lambda>x. (x+1) / 2) ` ({0..1} - insert 0 ((\<lambda>x. 2 * x - 1) ` S))) = ({1/2..1} - insert (1/2) S)"
687     apply (simp add: image_set_diff inj_on_def image_image)
688     apply (auto simp: image_affinity_atLeastAtMost_div add_divide_distrib)
689     done
690   have "continuous_on ({0..1} - insert 0 ((\<lambda>x. 2*x-1) ` S))
691                       ((\<lambda>x. 1/2 * vector_derivative (g2 \<circ> (\<lambda>x. 2*x-1)) (at x)) \<circ> (\<lambda>x. (x+1)/2))"
692     by (rule continuous_intros | simp add:  coDhalf)+
693   then have con_g2: "continuous_on ({0..1} - insert 0 ((\<lambda>x. 2*x-1) ` S)) (\<lambda>x. vector_derivative g2 (at x))"
694     by (rule continuous_on_eq) (simp add: scaleR_conv_of_real)
695   have "continuous_on {0..1} g2"
696     using continuous_on_joinpaths_D2 assms piecewise_C1_differentiable_on_def by blast
697   with \<open>finite S\<close> show ?thesis
698     apply (clarsimp simp add: piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
699     apply (rule_tac x="insert 0 ((\<lambda>x. 2 * x - 1) ` S)" in exI)
700     apply (simp add: g2D con_g2)
701   done
702 qed
704 subsection \<open>Valid paths, and their start and finish\<close>
706 definition%important valid_path :: "(real \<Rightarrow> 'a :: real_normed_vector) \<Rightarrow> bool"
707   where "valid_path f \<equiv> f piecewise_C1_differentiable_on {0..1::real}"
709 definition closed_path :: "(real \<Rightarrow> 'a :: real_normed_vector) \<Rightarrow> bool"
710   where "closed_path g \<equiv> g 0 = g 1"
712 text\<open>In particular, all results for paths apply\<close>
714 lemma valid_path_imp_path: "valid_path g \<Longrightarrow> path g"
715   by (simp add: path_def piecewise_C1_differentiable_on_def valid_path_def)
717 lemma connected_valid_path_image: "valid_path g \<Longrightarrow> connected(path_image g)"
718   by (metis connected_path_image valid_path_imp_path)
720 lemma compact_valid_path_image: "valid_path g \<Longrightarrow> compact(path_image g)"
721   by (metis compact_path_image valid_path_imp_path)
723 lemma bounded_valid_path_image: "valid_path g \<Longrightarrow> bounded(path_image g)"
724   by (metis bounded_path_image valid_path_imp_path)
726 lemma closed_valid_path_image: "valid_path g \<Longrightarrow> closed(path_image g)"
727   by (metis closed_path_image valid_path_imp_path)
729 lemma valid_path_compose:
730   assumes "valid_path g"
731       and der: "\<And>x. x \<in> path_image g \<Longrightarrow> f field_differentiable (at x)"
732       and con: "continuous_on (path_image g) (deriv f)"
733     shows "valid_path (f \<circ> g)"
734 proof -
735   obtain S where "finite S" and g_diff: "g C1_differentiable_on {0..1} - S"
736     using \<open>valid_path g\<close> unfolding valid_path_def piecewise_C1_differentiable_on_def by auto
737   have "f \<circ> g differentiable at t" when "t\<in>{0..1} - S" for t
738     proof (rule differentiable_chain_at)
739       show "g differentiable at t" using \<open>valid_path g\<close>
740         by (meson C1_differentiable_on_eq \<open>g C1_differentiable_on {0..1} - S\<close> that)
741     next
742       have "g t\<in>path_image g" using that DiffD1 image_eqI path_image_def by metis
743       then show "f differentiable at (g t)"
744         using der[THEN field_differentiable_imp_differentiable] by auto
745     qed
746   moreover have "continuous_on ({0..1} - S) (\<lambda>x. vector_derivative (f \<circ> g) (at x))"
747     proof (rule continuous_on_eq [where f = "\<lambda>x. vector_derivative g (at x) * deriv f (g x)"],
748         rule continuous_intros)
749       show "continuous_on ({0..1} - S) (\<lambda>x. vector_derivative g (at x))"
750         using g_diff C1_differentiable_on_eq by auto
751     next
752       have "continuous_on {0..1} (\<lambda>x. deriv f (g x))"
753         using continuous_on_compose[OF _ con[unfolded path_image_def],unfolded comp_def]
754           \<open>valid_path g\<close> piecewise_C1_differentiable_on_def valid_path_def
755         by blast
756       then show "continuous_on ({0..1} - S) (\<lambda>x. deriv f (g x))"
757         using continuous_on_subset by blast
758     next
759       show "vector_derivative g (at t) * deriv f (g t) = vector_derivative (f \<circ> g) (at t)"
760           when "t \<in> {0..1} - S" for t
761         proof (rule vector_derivative_chain_at_general[symmetric])
762           show "g differentiable at t" by (meson C1_differentiable_on_eq g_diff that)
763         next
764           have "g t\<in>path_image g" using that DiffD1 image_eqI path_image_def by metis
765           then show "f field_differentiable at (g t)" using der by auto
766         qed
767     qed
768   ultimately have "f \<circ> g C1_differentiable_on {0..1} - S"
769     using C1_differentiable_on_eq by blast
770   moreover have "path (f \<circ> g)"
771     apply (rule path_continuous_image[OF valid_path_imp_path[OF \<open>valid_path g\<close>]])
772     using der
773     by (simp add: continuous_at_imp_continuous_on field_differentiable_imp_continuous_at)
774   ultimately show ?thesis unfolding valid_path_def piecewise_C1_differentiable_on_def path_def
775     using \<open>finite S\<close> by auto
776 qed
778 lemma valid_path_uminus_comp[simp]:
779   fixes g::"real \<Rightarrow> 'a ::real_normed_field"
780   shows "valid_path (uminus \<circ> g) \<longleftrightarrow> valid_path g"
781 proof
782   show "valid_path g \<Longrightarrow> valid_path (uminus \<circ> g)" for g::"real \<Rightarrow> 'a"
783     by (auto intro!: valid_path_compose derivative_intros simp add: deriv_linear[of "-1",simplified])
784   then show "valid_path g" when "valid_path (uminus \<circ> g)"
785     by (metis fun.map_comp group_add_class.minus_comp_minus id_comp that)
786 qed
788 lemma valid_path_offset[simp]:
789   shows "valid_path (\<lambda>t. g t - z) \<longleftrightarrow> valid_path g"
790 proof
791   show *: "valid_path (g::real\<Rightarrow>'a) \<Longrightarrow> valid_path (\<lambda>t. g t - z)" for g z
792     unfolding valid_path_def
793     by (fastforce intro:derivative_intros C1_differentiable_imp_piecewise piecewise_C1_differentiable_diff)
794   show "valid_path (\<lambda>t. g t - z) \<Longrightarrow> valid_path g"
795     using *[of "\<lambda>t. g t - z" "-z",simplified] .
796 qed
799 subsection\<open>Contour Integrals along a path\<close>
801 text\<open>This definition is for complex numbers only, and does not generalise to line integrals in a vector field\<close>
803 text\<open>piecewise differentiable function on [0,1]\<close>
805 definition%important has_contour_integral :: "(complex \<Rightarrow> complex) \<Rightarrow> complex \<Rightarrow> (real \<Rightarrow> complex) \<Rightarrow> bool"
806            (infixr "has'_contour'_integral" 50)
807   where "(f has_contour_integral i) g \<equiv>
808            ((\<lambda>x. f(g x) * vector_derivative g (at x within {0..1}))
809             has_integral i) {0..1}"
811 definition%important contour_integrable_on
812            (infixr "contour'_integrable'_on" 50)
813   where "f contour_integrable_on g \<equiv> \<exists>i. (f has_contour_integral i) g"
815 definition%important contour_integral
816   where "contour_integral g f \<equiv> SOME i. (f has_contour_integral i) g \<or> \<not> f contour_integrable_on g \<and> i=0"
818 lemma not_integrable_contour_integral: "\<not> f contour_integrable_on g \<Longrightarrow> contour_integral g f = 0"
819   unfolding contour_integrable_on_def contour_integral_def by blast
821 lemma contour_integral_unique: "(f has_contour_integral i) g \<Longrightarrow> contour_integral g f = i"
822   apply (simp add: contour_integral_def has_contour_integral_def contour_integrable_on_def)
823   using has_integral_unique by blast
825 lemma has_contour_integral_eqpath:
826      "\<lbrakk>(f has_contour_integral y) p; f contour_integrable_on \<gamma>;
827        contour_integral p f = contour_integral \<gamma> f\<rbrakk>
828       \<Longrightarrow> (f has_contour_integral y) \<gamma>"
829 using contour_integrable_on_def contour_integral_unique by auto
831 lemma has_contour_integral_integral:
832     "f contour_integrable_on i \<Longrightarrow> (f has_contour_integral (contour_integral i f)) i"
833   by (metis contour_integral_unique contour_integrable_on_def)
835 lemma has_contour_integral_unique:
836     "(f has_contour_integral i) g \<Longrightarrow> (f has_contour_integral j) g \<Longrightarrow> i = j"
837   using has_integral_unique
838   by (auto simp: has_contour_integral_def)
840 lemma has_contour_integral_integrable: "(f has_contour_integral i) g \<Longrightarrow> f contour_integrable_on g"
841   using contour_integrable_on_def by blast
843 text\<open>Show that we can forget about the localized derivative.\<close>
845 lemma has_integral_localized_vector_derivative:
846     "((\<lambda>x. f (g x) * vector_derivative g (at x within {a..b})) has_integral i) {a..b} \<longleftrightarrow>
847      ((\<lambda>x. f (g x) * vector_derivative g (at x)) has_integral i) {a..b}"
848 proof -
849   have *: "{a..b} - {a,b} = interior {a..b}"
850     by (simp add: atLeastAtMost_diff_ends)
851   show ?thesis
852     apply (rule has_integral_spike_eq [of "{a,b}"])
853     apply (auto simp: at_within_interior [of _ "{a..b}"])
854     done
855 qed
857 lemma integrable_on_localized_vector_derivative:
858     "(\<lambda>x. f (g x) * vector_derivative g (at x within {a..b})) integrable_on {a..b} \<longleftrightarrow>
859      (\<lambda>x. f (g x) * vector_derivative g (at x)) integrable_on {a..b}"
860   by (simp add: integrable_on_def has_integral_localized_vector_derivative)
862 lemma has_contour_integral:
863      "(f has_contour_integral i) g \<longleftrightarrow>
864       ((\<lambda>x. f (g x) * vector_derivative g (at x)) has_integral i) {0..1}"
865   by (simp add: has_integral_localized_vector_derivative has_contour_integral_def)
867 lemma contour_integrable_on:
868      "f contour_integrable_on g \<longleftrightarrow>
869       (\<lambda>t. f(g t) * vector_derivative g (at t)) integrable_on {0..1}"
870   by (simp add: has_contour_integral integrable_on_def contour_integrable_on_def)
872 subsection%unimportant \<open>Reversing a path\<close>
874 lemma valid_path_imp_reverse:
875   assumes "valid_path g"
876     shows "valid_path(reversepath g)"
877 proof -
878   obtain S where "finite S" and S: "g C1_differentiable_on ({0..1} - S)"
879     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def)
880   then have "finite ((-) 1 ` S)"
881     by auto
882   moreover have "(reversepath g C1_differentiable_on ({0..1} - (-) 1 ` S))"
883     unfolding reversepath_def
884     apply (rule C1_differentiable_compose [of "\<lambda>x::real. 1-x" _ g, unfolded o_def])
885     using S
886     by (force simp: finite_vimageI inj_on_def C1_differentiable_on_eq continuous_on_const elim!: continuous_on_subset)+
887   ultimately show ?thesis using assms
888     by (auto simp: valid_path_def piecewise_C1_differentiable_on_def path_def [symmetric])
889 qed
891 lemma valid_path_reversepath [simp]: "valid_path(reversepath g) \<longleftrightarrow> valid_path g"
892   using valid_path_imp_reverse by force
894 lemma has_contour_integral_reversepath:
895   assumes "valid_path g" and f: "(f has_contour_integral i) g"
896     shows "(f has_contour_integral (-i)) (reversepath g)"
897 proof -
898   { fix S x
899     assume xs: "g C1_differentiable_on ({0..1} - S)" "x \<notin> (-) 1 ` S" "0 \<le> x" "x \<le> 1"
900     have "vector_derivative (\<lambda>x. g (1 - x)) (at x within {0..1}) =
901             - vector_derivative g (at (1 - x) within {0..1})"
902     proof -
903       obtain f' where f': "(g has_vector_derivative f') (at (1 - x))"
904         using xs
905         by (force simp: has_vector_derivative_def C1_differentiable_on_def)
906       have "(g \<circ> (\<lambda>x. 1 - x) has_vector_derivative -1 *\<^sub>R f') (at x)"
907         by (intro vector_diff_chain_within has_vector_derivative_at_within [OF f'] derivative_eq_intros | simp)+
908       then have mf': "((\<lambda>x. g (1 - x)) has_vector_derivative -f') (at x)"
909         by (simp add: o_def)
910       show ?thesis
911         using xs
912         by (auto simp: vector_derivative_at_within_ivl [OF mf'] vector_derivative_at_within_ivl [OF f'])
913     qed
914   } note * = this
915   obtain S where S: "continuous_on {0..1} g" "finite S" "g C1_differentiable_on {0..1} - S"
916     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def)
917   have "((\<lambda>x. - (f (g (1 - x)) * vector_derivative g (at (1 - x) within {0..1}))) has_integral -i)
918        {0..1}"
919     using has_integral_affinity01 [where m= "-1" and c=1, OF f [unfolded has_contour_integral_def]]
920     by (simp add: has_integral_neg)
921   then show ?thesis
922     using S
923     apply (clarsimp simp: reversepath_def has_contour_integral_def)
924     apply (rule_tac S = "(\<lambda>x. 1 - x) ` S" in has_integral_spike_finite)
925       apply (auto simp: *)
926     done
927 qed
929 lemma contour_integrable_reversepath:
930     "valid_path g \<Longrightarrow> f contour_integrable_on g \<Longrightarrow> f contour_integrable_on (reversepath g)"
931   using has_contour_integral_reversepath contour_integrable_on_def by blast
933 lemma contour_integrable_reversepath_eq:
934     "valid_path g \<Longrightarrow> (f contour_integrable_on (reversepath g) \<longleftrightarrow> f contour_integrable_on g)"
935   using contour_integrable_reversepath valid_path_reversepath by fastforce
937 lemma contour_integral_reversepath:
938   assumes "valid_path g"
939     shows "contour_integral (reversepath g) f = - (contour_integral g f)"
940 proof (cases "f contour_integrable_on g")
941   case True then show ?thesis
942     by (simp add: assms contour_integral_unique has_contour_integral_integral has_contour_integral_reversepath)
943 next
944   case False then have "\<not> f contour_integrable_on (reversepath g)"
945     by (simp add: assms contour_integrable_reversepath_eq)
946   with False show ?thesis by (simp add: not_integrable_contour_integral)
947 qed
950 subsection%unimportant \<open>Joining two paths together\<close>
952 lemma valid_path_join:
953   assumes "valid_path g1" "valid_path g2" "pathfinish g1 = pathstart g2"
954     shows "valid_path(g1 +++ g2)"
955 proof -
956   have "g1 1 = g2 0"
957     using assms by (auto simp: pathfinish_def pathstart_def)
958   moreover have "(g1 \<circ> (\<lambda>x. 2*x)) piecewise_C1_differentiable_on {0..1/2}"
959     apply (rule piecewise_C1_differentiable_compose)
960     using assms
961     apply (auto simp: valid_path_def piecewise_C1_differentiable_on_def continuous_on_joinpaths)
962     apply (force intro: finite_vimageI [where h = "(*)2"] inj_onI)
963     done
964   moreover have "(g2 \<circ> (\<lambda>x. 2*x-1)) piecewise_C1_differentiable_on {1/2..1}"
965     apply (rule piecewise_C1_differentiable_compose)
966     using assms unfolding valid_path_def piecewise_C1_differentiable_on_def
967     by (auto intro!: continuous_intros finite_vimageI [where h = "(\<lambda>x. 2*x - 1)"] inj_onI
968              simp: image_affinity_atLeastAtMost_diff continuous_on_joinpaths)
969   ultimately show ?thesis
970     apply (simp only: valid_path_def continuous_on_joinpaths joinpaths_def)
971     apply (rule piecewise_C1_differentiable_cases)
972     apply (auto simp: o_def)
973     done
974 qed
976 lemma valid_path_join_D1:
977   fixes g1 :: "real \<Rightarrow> 'a::real_normed_field"
978   shows "valid_path (g1 +++ g2) \<Longrightarrow> valid_path g1"
979   unfolding valid_path_def
980   by (rule piecewise_C1_differentiable_D1)
982 lemma valid_path_join_D2:
983   fixes g2 :: "real \<Rightarrow> 'a::real_normed_field"
984   shows "\<lbrakk>valid_path (g1 +++ g2); pathfinish g1 = pathstart g2\<rbrakk> \<Longrightarrow> valid_path g2"
985   unfolding valid_path_def
986   by (rule piecewise_C1_differentiable_D2)
988 lemma valid_path_join_eq [simp]:
989   fixes g2 :: "real \<Rightarrow> 'a::real_normed_field"
990   shows "pathfinish g1 = pathstart g2 \<Longrightarrow> (valid_path(g1 +++ g2) \<longleftrightarrow> valid_path g1 \<and> valid_path g2)"
991   using valid_path_join_D1 valid_path_join_D2 valid_path_join by blast
993 lemma has_contour_integral_join:
994   assumes "(f has_contour_integral i1) g1" "(f has_contour_integral i2) g2"
995           "valid_path g1" "valid_path g2"
996     shows "(f has_contour_integral (i1 + i2)) (g1 +++ g2)"
997 proof -
998   obtain s1 s2
999     where s1: "finite s1" "\<forall>x\<in>{0..1} - s1. g1 differentiable at x"
1000       and s2: "finite s2" "\<forall>x\<in>{0..1} - s2. g2 differentiable at x"
1001     using assms
1002     by (auto simp: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
1003   have 1: "((\<lambda>x. f (g1 x) * vector_derivative g1 (at x)) has_integral i1) {0..1}"
1004    and 2: "((\<lambda>x. f (g2 x) * vector_derivative g2 (at x)) has_integral i2) {0..1}"
1005     using assms
1006     by (auto simp: has_contour_integral)
1007   have i1: "((\<lambda>x. (2*f (g1 (2*x))) * vector_derivative g1 (at (2*x))) has_integral i1) {0..1/2}"
1008    and i2: "((\<lambda>x. (2*f (g2 (2*x - 1))) * vector_derivative g2 (at (2*x - 1))) has_integral i2) {1/2..1}"
1009     using has_integral_affinity01 [OF 1, where m= 2 and c=0, THEN has_integral_cmul [where c=2]]
1010           has_integral_affinity01 [OF 2, where m= 2 and c="-1", THEN has_integral_cmul [where c=2]]
1011     by (simp_all only: image_affinity_atLeastAtMost_div_diff, simp_all add: scaleR_conv_of_real mult_ac)
1012   have g1: "\<lbrakk>0 \<le> z; z*2 < 1; z*2 \<notin> s1\<rbrakk> \<Longrightarrow>
1013             vector_derivative (\<lambda>x. if x*2 \<le> 1 then g1 (2*x) else g2 (2*x - 1)) (at z) =
1014             2 *\<^sub>R vector_derivative g1 (at (z*2))" for z
1015     apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g1(2*x))" and d = "\<bar>z - 1/2\<bar>"]])
1016     apply (simp_all add: dist_real_def abs_if split: if_split_asm)
1017     apply (rule vector_diff_chain_at [of "\<lambda>x. 2*x" 2 _ g1, simplified o_def])
1018     apply (simp add: has_vector_derivative_def has_derivative_def bounded_linear_mult_left)
1019     using s1
1020     apply (auto simp: algebra_simps vector_derivative_works)
1021     done
1022   have g2: "\<lbrakk>1 < z*2; z \<le> 1; z*2 - 1 \<notin> s2\<rbrakk> \<Longrightarrow>
1023             vector_derivative (\<lambda>x. if x*2 \<le> 1 then g1 (2*x) else g2 (2*x - 1)) (at z) =
1024             2 *\<^sub>R vector_derivative g2 (at (z*2 - 1))" for z
1025     apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g2 (2*x - 1))" and d = "\<bar>z - 1/2\<bar>"]])
1026     apply (simp_all add: dist_real_def abs_if split: if_split_asm)
1027     apply (rule vector_diff_chain_at [of "\<lambda>x. 2*x - 1" 2 _ g2, simplified o_def])
1028     apply (simp add: has_vector_derivative_def has_derivative_def bounded_linear_mult_left)
1029     using s2
1030     apply (auto simp: algebra_simps vector_derivative_works)
1031     done
1032   have "((\<lambda>x. f ((g1 +++ g2) x) * vector_derivative (g1 +++ g2) (at x)) has_integral i1) {0..1/2}"
1033     apply (rule has_integral_spike_finite [OF _ _ i1, of "insert (1/2) ((*)2 -` s1)"])
1034     using s1
1035     apply (force intro: finite_vimageI [where h = "(*)2"] inj_onI)
1036     apply (clarsimp simp add: joinpaths_def scaleR_conv_of_real mult_ac g1)
1037     done
1038   moreover have "((\<lambda>x. f ((g1 +++ g2) x) * vector_derivative (g1 +++ g2) (at x)) has_integral i2) {1/2..1}"
1039     apply (rule has_integral_spike_finite [OF _ _ i2, of "insert (1/2) ((\<lambda>x. 2*x-1) -` s2)"])
1040     using s2
1041     apply (force intro: finite_vimageI [where h = "\<lambda>x. 2*x-1"] inj_onI)
1042     apply (clarsimp simp add: joinpaths_def scaleR_conv_of_real mult_ac g2)
1043     done
1044   ultimately
1045   show ?thesis
1046     apply (simp add: has_contour_integral)
1047     apply (rule has_integral_combine [where c = "1/2"], auto)
1048     done
1049 qed
1051 lemma contour_integrable_joinI:
1052   assumes "f contour_integrable_on g1" "f contour_integrable_on g2"
1053           "valid_path g1" "valid_path g2"
1054     shows "f contour_integrable_on (g1 +++ g2)"
1055   using assms
1056   by (meson has_contour_integral_join contour_integrable_on_def)
1058 lemma contour_integrable_joinD1:
1059   assumes "f contour_integrable_on (g1 +++ g2)" "valid_path g1"
1060     shows "f contour_integrable_on g1"
1061 proof -
1062   obtain s1
1063     where s1: "finite s1" "\<forall>x\<in>{0..1} - s1. g1 differentiable at x"
1064     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
1065   have "(\<lambda>x. f ((g1 +++ g2) (x/2)) * vector_derivative (g1 +++ g2) (at (x/2))) integrable_on {0..1}"
1066     using assms
1067     apply (auto simp: contour_integrable_on)
1068     apply (drule integrable_on_subcbox [where a=0 and b="1/2"])
1069     apply (auto intro: integrable_affinity [of _ 0 "1/2::real" "1/2" 0, simplified])
1070     done
1071   then have *: "(\<lambda>x. (f ((g1 +++ g2) (x/2))/2) * vector_derivative (g1 +++ g2) (at (x/2))) integrable_on {0..1}"
1072     by (auto dest: integrable_cmul [where c="1/2"] simp: scaleR_conv_of_real)
1073   have g1: "\<lbrakk>0 < z; z < 1; z \<notin> s1\<rbrakk> \<Longrightarrow>
1074             vector_derivative (\<lambda>x. if x*2 \<le> 1 then g1 (2*x) else g2 (2*x - 1)) (at (z/2)) =
1075             2 *\<^sub>R vector_derivative g1 (at z)"  for z
1076     apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g1(2*x))" and d = "\<bar>(z-1)/2\<bar>"]])
1077     apply (simp_all add: field_simps dist_real_def abs_if split: if_split_asm)
1078     apply (rule vector_diff_chain_at [of "\<lambda>x. x*2" 2 _ g1, simplified o_def])
1079     using s1
1080     apply (auto simp: vector_derivative_works has_vector_derivative_def has_derivative_def bounded_linear_mult_left)
1081     done
1082   show ?thesis
1083     using s1
1084     apply (auto simp: contour_integrable_on)
1085     apply (rule integrable_spike_finite [of "{0,1} \<union> s1", OF _ _ *])
1086     apply (auto simp: joinpaths_def scaleR_conv_of_real g1)
1087     done
1088 qed
1090 lemma contour_integrable_joinD2:
1091   assumes "f contour_integrable_on (g1 +++ g2)" "valid_path g2"
1092     shows "f contour_integrable_on g2"
1093 proof -
1094   obtain s2
1095     where s2: "finite s2" "\<forall>x\<in>{0..1} - s2. g2 differentiable at x"
1096     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
1097   have "(\<lambda>x. f ((g1 +++ g2) (x/2 + 1/2)) * vector_derivative (g1 +++ g2) (at (x/2 + 1/2))) integrable_on {0..1}"
1098     using assms
1099     apply (auto simp: contour_integrable_on)
1100     apply (drule integrable_on_subcbox [where a="1/2" and b=1], auto)
1101     apply (drule integrable_affinity [of _ "1/2::real" 1 "1/2" "1/2", simplified])
1102     apply (simp add: image_affinity_atLeastAtMost_diff)
1103     done
1104   then have *: "(\<lambda>x. (f ((g1 +++ g2) (x/2 + 1/2))/2) * vector_derivative (g1 +++ g2) (at (x/2 + 1/2)))
1105                 integrable_on {0..1}"
1106     by (auto dest: integrable_cmul [where c="1/2"] simp: scaleR_conv_of_real)
1107   have g2: "\<lbrakk>0 < z; z < 1; z \<notin> s2\<rbrakk> \<Longrightarrow>
1108             vector_derivative (\<lambda>x. if x*2 \<le> 1 then g1 (2*x) else g2 (2*x - 1)) (at (z/2+1/2)) =
1109             2 *\<^sub>R vector_derivative g2 (at z)" for z
1110     apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g2(2*x-1))" and d = "\<bar>z/2\<bar>"]])
1111     apply (simp_all add: field_simps dist_real_def abs_if split: if_split_asm)
1112     apply (rule vector_diff_chain_at [of "\<lambda>x. x*2-1" 2 _ g2, simplified o_def])
1113     using s2
1114     apply (auto simp: has_vector_derivative_def has_derivative_def bounded_linear_mult_left
1116     done
1117   show ?thesis
1118     using s2
1119     apply (auto simp: contour_integrable_on)
1120     apply (rule integrable_spike_finite [of "{0,1} \<union> s2", OF _ _ *])
1121     apply (auto simp: joinpaths_def scaleR_conv_of_real g2)
1122     done
1123 qed
1125 lemma contour_integrable_join [simp]:
1126   shows
1127     "\<lbrakk>valid_path g1; valid_path g2\<rbrakk>
1128      \<Longrightarrow> f contour_integrable_on (g1 +++ g2) \<longleftrightarrow> f contour_integrable_on g1 \<and> f contour_integrable_on g2"
1129 using contour_integrable_joinD1 contour_integrable_joinD2 contour_integrable_joinI by blast
1131 lemma contour_integral_join [simp]:
1132   shows
1133     "\<lbrakk>f contour_integrable_on g1; f contour_integrable_on g2; valid_path g1; valid_path g2\<rbrakk>
1134         \<Longrightarrow> contour_integral (g1 +++ g2) f = contour_integral g1 f + contour_integral g2 f"
1135   by (simp add: has_contour_integral_integral has_contour_integral_join contour_integral_unique)
1138 subsection%unimportant \<open>Shifting the starting point of a (closed) path\<close>
1140 lemma shiftpath_alt_def: "shiftpath a f = (\<lambda>x. if x \<le> 1-a then f (a + x) else f (a + x - 1))"
1141   by (auto simp: shiftpath_def)
1143 lemma valid_path_shiftpath [intro]:
1144   assumes "valid_path g" "pathfinish g = pathstart g" "a \<in> {0..1}"
1145     shows "valid_path(shiftpath a g)"
1146   using assms
1147   apply (auto simp: valid_path_def shiftpath_alt_def)
1148   apply (rule piecewise_C1_differentiable_cases)
1149   apply (auto simp: algebra_simps)
1150   apply (rule piecewise_C1_differentiable_affine [of g 1 a, simplified o_def scaleR_one])
1151   apply (auto simp: pathfinish_def pathstart_def elim: piecewise_C1_differentiable_on_subset)
1152   apply (rule piecewise_C1_differentiable_affine [of g 1 "a-1", simplified o_def scaleR_one algebra_simps])
1153   apply (auto simp: pathfinish_def pathstart_def elim: piecewise_C1_differentiable_on_subset)
1154   done
1156 lemma has_contour_integral_shiftpath:
1157   assumes f: "(f has_contour_integral i) g" "valid_path g"
1158       and a: "a \<in> {0..1}"
1159     shows "(f has_contour_integral i) (shiftpath a g)"
1160 proof -
1161   obtain s
1162     where s: "finite s" and g: "\<forall>x\<in>{0..1} - s. g differentiable at x"
1163     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
1164   have *: "((\<lambda>x. f (g x) * vector_derivative g (at x)) has_integral i) {0..1}"
1165     using assms by (auto simp: has_contour_integral)
1166   then have i: "i = integral {a..1} (\<lambda>x. f (g x) * vector_derivative g (at x)) +
1167                     integral {0..a} (\<lambda>x. f (g x) * vector_derivative g (at x))"
1168     apply (rule has_integral_unique)
1169     apply (subst add.commute)
1170     apply (subst integral_combine)
1171     using assms * integral_unique by auto
1172   { fix x
1173     have "0 \<le> x \<Longrightarrow> x + a < 1 \<Longrightarrow> x \<notin> (\<lambda>x. x - a) ` s \<Longrightarrow>
1174          vector_derivative (shiftpath a g) (at x) = vector_derivative g (at (x + a))"
1175       unfolding shiftpath_def
1176       apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g(a+x))" and d = "dist(1-a) x"]])
1177         apply (auto simp: field_simps dist_real_def abs_if split: if_split_asm)
1178       apply (rule vector_diff_chain_at [of "\<lambda>x. x+a" 1 _ g, simplified o_def scaleR_one])
1179        apply (intro derivative_eq_intros | simp)+
1180       using g
1181        apply (drule_tac x="x+a" in bspec)
1182       using a apply (auto simp: has_vector_derivative_def vector_derivative_works image_def add.commute)
1183       done
1184   } note vd1 = this
1185   { fix x
1186     have "1 < x + a \<Longrightarrow> x \<le> 1 \<Longrightarrow> x \<notin> (\<lambda>x. x - a + 1) ` s \<Longrightarrow>
1187           vector_derivative (shiftpath a g) (at x) = vector_derivative g (at (x + a - 1))"
1188       unfolding shiftpath_def
1189       apply (rule vector_derivative_at [OF has_vector_derivative_transform_within [where f = "(\<lambda>x. g(a+x-1))" and d = "dist (1-a) x"]])
1190         apply (auto simp: field_simps dist_real_def abs_if split: if_split_asm)
1191       apply (rule vector_diff_chain_at [of "\<lambda>x. x+a-1" 1 _ g, simplified o_def scaleR_one])
1192        apply (intro derivative_eq_intros | simp)+
1193       using g
1194       apply (drule_tac x="x+a-1" in bspec)
1195       using a apply (auto simp: has_vector_derivative_def vector_derivative_works image_def add.commute)
1196       done
1197   } note vd2 = this
1198   have va1: "(\<lambda>x. f (g x) * vector_derivative g (at x)) integrable_on ({a..1})"
1199     using * a   by (fastforce intro: integrable_subinterval_real)
1200   have v0a: "(\<lambda>x. f (g x) * vector_derivative g (at x)) integrable_on ({0..a})"
1201     apply (rule integrable_subinterval_real)
1202     using * a by auto
1203   have "((\<lambda>x. f (shiftpath a g x) * vector_derivative (shiftpath a g) (at x))
1204         has_integral  integral {a..1} (\<lambda>x. f (g x) * vector_derivative g (at x)))  {0..1 - a}"
1205     apply (rule has_integral_spike_finite
1206              [where S = "{1-a} \<union> (\<lambda>x. x-a) ` s" and f = "\<lambda>x. f(g(a+x)) * vector_derivative g (at(a+x))"])
1207       using s apply blast
1208      using a apply (auto simp: algebra_simps vd1)
1209      apply (force simp: shiftpath_def add.commute)
1210     using has_integral_affinity [where m=1 and c=a, simplified, OF integrable_integral [OF va1]]
1211     apply (simp add: image_affinity_atLeastAtMost_diff [where m=1 and c=a, simplified] add.commute)
1212     done
1213   moreover
1214   have "((\<lambda>x. f (shiftpath a g x) * vector_derivative (shiftpath a g) (at x))
1215         has_integral  integral {0..a} (\<lambda>x. f (g x) * vector_derivative g (at x)))  {1 - a..1}"
1216     apply (rule has_integral_spike_finite
1217              [where S = "{1-a} \<union> (\<lambda>x. x-a+1) ` s" and f = "\<lambda>x. f(g(a+x-1)) * vector_derivative g (at(a+x-1))"])
1218       using s apply blast
1219      using a apply (auto simp: algebra_simps vd2)
1220      apply (force simp: shiftpath_def add.commute)
1221     using has_integral_affinity [where m=1 and c="a-1", simplified, OF integrable_integral [OF v0a]]
1222     apply (simp add: image_affinity_atLeastAtMost [where m=1 and c="1-a", simplified])
1223     apply (simp add: algebra_simps)
1224     done
1225   ultimately show ?thesis
1226     using a
1227     by (auto simp: i has_contour_integral intro: has_integral_combine [where c = "1-a"])
1228 qed
1230 lemma has_contour_integral_shiftpath_D:
1231   assumes "(f has_contour_integral i) (shiftpath a g)"
1232           "valid_path g" "pathfinish g = pathstart g" "a \<in> {0..1}"
1233     shows "(f has_contour_integral i) g"
1234 proof -
1235   obtain s
1236     where s: "finite s" and g: "\<forall>x\<in>{0..1} - s. g differentiable at x"
1237     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq)
1238   { fix x
1239     assume x: "0 < x" "x < 1" "x \<notin> s"
1240     then have gx: "g differentiable at x"
1241       using g by auto
1242     have "vector_derivative g (at x within {0..1}) =
1243           vector_derivative (shiftpath (1 - a) (shiftpath a g)) (at x within {0..1})"
1244       apply (rule vector_derivative_at_within_ivl
1245                   [OF has_vector_derivative_transform_within_open
1246                       [where f = "(shiftpath (1 - a) (shiftpath a g))" and S = "{0<..<1}-s"]])
1247       using s g assms x
1248       apply (auto simp: finite_imp_closed open_Diff shiftpath_shiftpath
1249                         at_within_interior [of _ "{0..1}"] vector_derivative_works [symmetric])
1250       apply (rule differentiable_transform_within [OF gx, of "min x (1-x)"])
1251       apply (auto simp: dist_real_def shiftpath_shiftpath abs_if split: if_split_asm)
1252       done
1253   } note vd = this
1254   have fi: "(f has_contour_integral i) (shiftpath (1 - a) (shiftpath a g))"
1255     using assms  by (auto intro!: has_contour_integral_shiftpath)
1256   show ?thesis
1257     apply (simp add: has_contour_integral_def)
1258     apply (rule has_integral_spike_finite [of "{0,1} \<union> s", OF _ _  fi [unfolded has_contour_integral_def]])
1259     using s assms vd
1260     apply (auto simp: Path_Connected.shiftpath_shiftpath)
1261     done
1262 qed
1264 lemma has_contour_integral_shiftpath_eq:
1265   assumes "valid_path g" "pathfinish g = pathstart g" "a \<in> {0..1}"
1266     shows "(f has_contour_integral i) (shiftpath a g) \<longleftrightarrow> (f has_contour_integral i) g"
1267   using assms has_contour_integral_shiftpath has_contour_integral_shiftpath_D by blast
1269 lemma contour_integrable_on_shiftpath_eq:
1270   assumes "valid_path g" "pathfinish g = pathstart g" "a \<in> {0..1}"
1271     shows "f contour_integrable_on (shiftpath a g) \<longleftrightarrow> f contour_integrable_on g"
1272 using assms contour_integrable_on_def has_contour_integral_shiftpath_eq by auto
1274 lemma contour_integral_shiftpath:
1275   assumes "valid_path g" "pathfinish g = pathstart g" "a \<in> {0..1}"
1276     shows "contour_integral (shiftpath a g) f = contour_integral g f"
1277    using assms
1278    by (simp add: contour_integral_def contour_integrable_on_def has_contour_integral_shiftpath_eq)
1281 subsection%unimportant \<open>More about straight-line paths\<close>
1283 lemma has_vector_derivative_linepath_within:
1284     "(linepath a b has_vector_derivative (b - a)) (at x within s)"
1285 apply (simp add: linepath_def has_vector_derivative_def algebra_simps)
1286 apply (rule derivative_eq_intros | simp)+
1287 done
1289 lemma vector_derivative_linepath_within:
1290     "x \<in> {0..1} \<Longrightarrow> vector_derivative (linepath a b) (at x within {0..1}) = b - a"
1291   apply (rule vector_derivative_within_cbox [of 0 "1::real", simplified])
1292   apply (auto simp: has_vector_derivative_linepath_within)
1293   done
1295 lemma vector_derivative_linepath_at [simp]: "vector_derivative (linepath a b) (at x) = b - a"
1296   by (simp add: has_vector_derivative_linepath_within vector_derivative_at)
1298 lemma valid_path_linepath [iff]: "valid_path (linepath a b)"
1299   apply (simp add: valid_path_def piecewise_C1_differentiable_on_def C1_differentiable_on_eq continuous_on_linepath)
1300   apply (rule_tac x="{}" in exI)
1301   apply (simp add: differentiable_on_def differentiable_def)
1302   using has_vector_derivative_def has_vector_derivative_linepath_within
1303   apply (fastforce simp add: continuous_on_eq_continuous_within)
1304   done
1306 lemma has_contour_integral_linepath:
1307   shows "(f has_contour_integral i) (linepath a b) \<longleftrightarrow>
1308          ((\<lambda>x. f(linepath a b x) * (b - a)) has_integral i) {0..1}"
1309   by (simp add: has_contour_integral vector_derivative_linepath_at)
1311 lemma linepath_in_path:
1312   shows "x \<in> {0..1} \<Longrightarrow> linepath a b x \<in> closed_segment a b"
1313   by (auto simp: segment linepath_def)
1315 lemma linepath_image_01: "linepath a b ` {0..1} = closed_segment a b"
1316   by (auto simp: segment linepath_def)
1318 lemma linepath_in_convex_hull:
1319     fixes x::real
1320     assumes a: "a \<in> convex hull s"
1321         and b: "b \<in> convex hull s"
1322         and x: "0\<le>x" "x\<le>1"
1323        shows "linepath a b x \<in> convex hull s"
1324   apply (rule closed_segment_subset_convex_hull [OF a b, THEN subsetD])
1325   using x
1326   apply (auto simp: linepath_image_01 [symmetric])
1327   done
1329 lemma Re_linepath: "Re(linepath (of_real a) (of_real b) x) = (1 - x)*a + x*b"
1330   by (simp add: linepath_def)
1332 lemma Im_linepath: "Im(linepath (of_real a) (of_real b) x) = 0"
1333   by (simp add: linepath_def)
1335 lemma has_contour_integral_trivial [iff]: "(f has_contour_integral 0) (linepath a a)"
1336   by (simp add: has_contour_integral_linepath)
1338 lemma has_contour_integral_trivial_iff [simp]: "(f has_contour_integral i) (linepath a a) \<longleftrightarrow> i=0"
1339   using has_contour_integral_unique by blast
1341 lemma contour_integral_trivial [simp]: "contour_integral (linepath a a) f = 0"
1342   using has_contour_integral_trivial contour_integral_unique by blast
1344 lemma differentiable_linepath [intro]: "linepath a b differentiable at x within A"
1345   by (auto simp: linepath_def)
1347 lemma bounded_linear_linepath:
1348   assumes "bounded_linear f"
1349   shows   "f (linepath a b x) = linepath (f a) (f b) x"
1350 proof -
1351   interpret f: bounded_linear f by fact
1352   show ?thesis by (simp add: linepath_def f.add f.scale)
1353 qed
1355 lemma bounded_linear_linepath':
1356   assumes "bounded_linear f"
1357   shows   "f \<circ> linepath a b = linepath (f a) (f b)"
1358   using bounded_linear_linepath[OF assms] by (simp add: fun_eq_iff)
1360 lemma cnj_linepath: "cnj (linepath a b x) = linepath (cnj a) (cnj b) x"
1361   by (simp add: linepath_def)
1363 lemma cnj_linepath': "cnj \<circ> linepath a b = linepath (cnj a) (cnj b)"
1364   by (simp add: linepath_def fun_eq_iff)
1366 subsection\<open>Relation to subpath construction\<close>
1368 lemma valid_path_subpath:
1369   fixes g :: "real \<Rightarrow> 'a :: real_normed_vector"
1370   assumes "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}"
1371     shows "valid_path(subpath u v g)"
1372 proof (cases "v=u")
1373   case True
1374   then show ?thesis
1375     unfolding valid_path_def subpath_def
1376     by (force intro: C1_differentiable_on_const C1_differentiable_imp_piecewise)
1377 next
1378   case False
1379   have "(g \<circ> (\<lambda>x. ((v-u) * x + u))) piecewise_C1_differentiable_on {0..1}"
1380     apply (rule piecewise_C1_differentiable_compose)
1381     apply (simp add: C1_differentiable_imp_piecewise)
1382      apply (simp add: image_affinity_atLeastAtMost)
1383     using assms False
1384     apply (auto simp: algebra_simps valid_path_def piecewise_C1_differentiable_on_subset)
1385     apply (subst Int_commute)
1386     apply (auto simp: inj_on_def algebra_simps crossproduct_eq finite_vimage_IntI)
1387     done
1388   then show ?thesis
1389     by (auto simp: o_def valid_path_def subpath_def)
1390 qed
1392 lemma has_contour_integral_subpath_refl [iff]: "(f has_contour_integral 0) (subpath u u g)"
1393   by (simp add: has_contour_integral subpath_def)
1395 lemma contour_integrable_subpath_refl [iff]: "f contour_integrable_on (subpath u u g)"
1396   using has_contour_integral_subpath_refl contour_integrable_on_def by blast
1398 lemma contour_integral_subpath_refl [simp]: "contour_integral (subpath u u g) f = 0"
1399   by (simp add: has_contour_integral_subpath_refl contour_integral_unique)
1401 lemma has_contour_integral_subpath:
1402   assumes f: "f contour_integrable_on g" and g: "valid_path g"
1403       and uv: "u \<in> {0..1}" "v \<in> {0..1}" "u \<le> v"
1404     shows "(f has_contour_integral  integral {u..v} (\<lambda>x. f(g x) * vector_derivative g (at x)))
1405            (subpath u v g)"
1406 proof (cases "v=u")
1407   case True
1408   then show ?thesis
1409     using f   by (simp add: contour_integrable_on_def subpath_def has_contour_integral)
1410 next
1411   case False
1412   obtain s where s: "\<And>x. x \<in> {0..1} - s \<Longrightarrow> g differentiable at x" and fs: "finite s"
1413     using g unfolding piecewise_C1_differentiable_on_def C1_differentiable_on_eq valid_path_def by blast
1414   have *: "((\<lambda>x. f (g ((v - u) * x + u)) * vector_derivative g (at ((v - u) * x + u)))
1415             has_integral (1 / (v - u)) * integral {u..v} (\<lambda>t. f (g t) * vector_derivative g (at t)))
1416            {0..1}"
1417     using f uv
1418     apply (simp add: contour_integrable_on subpath_def has_contour_integral)
1419     apply (drule integrable_on_subcbox [where a=u and b=v, simplified])
1420     apply (simp_all add: has_integral_integral)
1421     apply (drule has_integral_affinity [where m="v-u" and c=u, simplified])
1422     apply (simp_all add: False image_affinity_atLeastAtMost_div_diff scaleR_conv_of_real)
1423     apply (simp add: divide_simps False)
1424     done
1425   { fix x
1426     have "x \<in> {0..1} \<Longrightarrow>
1427            x \<notin> (\<lambda>t. (v-u) *\<^sub>R t + u) -` s \<Longrightarrow>
1428            vector_derivative (\<lambda>x. g ((v-u) * x + u)) (at x) = (v-u) *\<^sub>R vector_derivative g (at ((v-u) * x + u))"
1429       apply (rule vector_derivative_at [OF vector_diff_chain_at [simplified o_def]])
1430       apply (intro derivative_eq_intros | simp)+
1431       apply (cut_tac s [of "(v - u) * x + u"])
1432       using uv mult_left_le [of x "v-u"]
1433       apply (auto simp:  vector_derivative_works)
1434       done
1435   } note vd = this
1436   show ?thesis
1437     apply (cut_tac has_integral_cmul [OF *, where c = "v-u"])
1438     using fs assms
1439     apply (simp add: False subpath_def has_contour_integral)
1440     apply (rule_tac S = "(\<lambda>t. ((v-u) *\<^sub>R t + u)) -` s" in has_integral_spike_finite)
1441     apply (auto simp: inj_on_def False finite_vimageI vd scaleR_conv_of_real)
1442     done
1443 qed
1445 lemma contour_integrable_subpath:
1446   assumes "f contour_integrable_on g" "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}"
1447     shows "f contour_integrable_on (subpath u v g)"
1448   apply (cases u v rule: linorder_class.le_cases)
1449    apply (metis contour_integrable_on_def has_contour_integral_subpath [OF assms])
1450   apply (subst reversepath_subpath [symmetric])
1451   apply (rule contour_integrable_reversepath)
1452    using assms apply (blast intro: valid_path_subpath)
1453   apply (simp add: contour_integrable_on_def)
1454   using assms apply (blast intro: has_contour_integral_subpath)
1455   done
1457 lemma has_integral_contour_integral_subpath:
1458   assumes "f contour_integrable_on g" "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}" "u \<le> v"
1459     shows "(((\<lambda>x. f(g x) * vector_derivative g (at x)))
1460             has_integral  contour_integral (subpath u v g) f) {u..v}"
1461   using assms
1462   apply (auto simp: has_integral_integrable_integral)
1463   apply (rule integrable_on_subcbox [where a=u and b=v and S = "{0..1}", simplified])
1464   apply (auto simp: contour_integral_unique [OF has_contour_integral_subpath] contour_integrable_on)
1465   done
1467 lemma contour_integral_subcontour_integral:
1468   assumes "f contour_integrable_on g" "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}" "u \<le> v"
1469     shows "contour_integral (subpath u v g) f =
1470            integral {u..v} (\<lambda>x. f(g x) * vector_derivative g (at x))"
1471   using assms has_contour_integral_subpath contour_integral_unique by blast
1473 lemma contour_integral_subpath_combine_less:
1474   assumes "f contour_integrable_on g" "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}" "w \<in> {0..1}"
1475           "u<v" "v<w"
1476     shows "contour_integral (subpath u v g) f + contour_integral (subpath v w g) f =
1477            contour_integral (subpath u w g) f"
1478   using assms apply (auto simp: contour_integral_subcontour_integral)
1479   apply (rule integral_combine, auto)
1480   apply (rule integrable_on_subcbox [where a=u and b=w and S = "{0..1}", simplified])
1481   apply (auto simp: contour_integrable_on)
1482   done
1484 lemma contour_integral_subpath_combine:
1485   assumes "f contour_integrable_on g" "valid_path g" "u \<in> {0..1}" "v \<in> {0..1}" "w \<in> {0..1}"
1486     shows "contour_integral (subpath u v g) f + contour_integral (subpath v w g) f =
1487            contour_integral (subpath u w g) f"
1488 proof (cases "u\<noteq>v \<and> v\<noteq>w \<and> u\<noteq>w")
1489   case True
1490     have *: "subpath v u g = reversepath(subpath u v g) \<and>
1491              subpath w u g = reversepath(subpath u w g) \<and>
1492              subpath w v g = reversepath(subpath v w g)"
1493       by (auto simp: reversepath_subpath)
1494     have "u < v \<and> v < w \<or>
1495           u < w \<and> w < v \<or>
1496           v < u \<and> u < w \<or>
1497           v < w \<and> w < u \<or>
1498           w < u \<and> u < v \<or>
1499           w < v \<and> v < u"
1500       using True assms by linarith
1501     with assms show ?thesis
1502       using contour_integral_subpath_combine_less [of f g u v w]
1503             contour_integral_subpath_combine_less [of f g u w v]
1504             contour_integral_subpath_combine_less [of f g v u w]
1505             contour_integral_subpath_combine_less [of f g v w u]
1506             contour_integral_subpath_combine_less [of f g w u v]
1507             contour_integral_subpath_combine_less [of f g w v u]
1508       apply simp
1509       apply (elim disjE)
1510       apply (auto simp: * contour_integral_reversepath contour_integrable_subpath
1511                    valid_path_reversepath valid_path_subpath algebra_simps)
1512       done
1513 next
1514   case False
1515   then show ?thesis
1516     apply (auto simp: contour_integral_subpath_refl)
1517     using assms
1518     by (metis eq_neg_iff_add_eq_0 contour_integrable_subpath contour_integral_reversepath reversepath_subpath valid_path_subpath)
1519 qed
1521 lemma contour_integral_integral:
1522      "contour_integral g f = integral {0..1} (\<lambda>x. f (g x) * vector_derivative g (at x))"
1523   by (simp add: contour_integral_def integral_def has_contour_integral contour_integrable_on)
1525 lemma contour_integral_cong:
1526   assumes "g = g'" "\<And>x. x \<in> path_image g \<Longrightarrow> f x = f' x"
1527   shows   "contour_integral g f = contour_integral g' f'"
1528   unfolding contour_integral_integral using assms
1529   by (intro integral_cong) (auto simp: path_image_def)
1532 text \<open>Contour integral along a segment on the real axis\<close>
1534 lemma has_contour_integral_linepath_Reals_iff:
1535   fixes a b :: complex and f :: "complex \<Rightarrow> complex"
1536   assumes "a \<in> Reals" "b \<in> Reals" "Re a < Re b"
1537   shows   "(f has_contour_integral I) (linepath a b) \<longleftrightarrow>
1538              ((\<lambda>x. f (of_real x)) has_integral I) {Re a..Re b}"
1539 proof -
1540   from assms have [simp]: "of_real (Re a) = a" "of_real (Re b) = b"
1541     by (simp_all add: complex_eq_iff)
1542   from assms have "a \<noteq> b" by auto
1543   have "((\<lambda>x. f (of_real x)) has_integral I) (cbox (Re a) (Re b)) \<longleftrightarrow>
1544           ((\<lambda>x. f (a + b * of_real x - a * of_real x)) has_integral I /\<^sub>R (Re b - Re a)) {0..1}"
1545     by (subst has_integral_affinity_iff [of "Re b - Re a" _ "Re a", symmetric])
1546        (insert assms, simp_all add: field_simps scaleR_conv_of_real)
1547   also have "(\<lambda>x. f (a + b * of_real x - a * of_real x)) =
1548                (\<lambda>x. (f (a + b * of_real x - a * of_real x) * (b - a)) /\<^sub>R (Re b - Re a))"
1549     using \<open>a \<noteq> b\<close> by (auto simp: field_simps fun_eq_iff scaleR_conv_of_real)
1550   also have "(\<dots> has_integral I /\<^sub>R (Re b - Re a)) {0..1} \<longleftrightarrow>
1551                ((\<lambda>x. f (linepath a b x) * (b - a)) has_integral I) {0..1}" using assms
1552     by (subst has_integral_cmul_iff) (auto simp: linepath_def scaleR_conv_of_real algebra_simps)
1553   also have "\<dots> \<longleftrightarrow> (f has_contour_integral I) (linepath a b)" unfolding has_contour_integral_def
1554     by (intro has_integral_cong) (simp add: vector_derivative_linepath_within)
1555   finally show ?thesis by simp
1556 qed
1558 lemma contour_integrable_linepath_Reals_iff:
1559   fixes a b :: complex and f :: "complex \<Rightarrow> complex"
1560   assumes "a \<in> Reals" "b \<in> Reals" "Re a < Re b"
1561   shows   "(f contour_integrable_on linepath a b) \<longleftrightarrow>
1562              (\<lambda>x. f (of_real x)) integrable_on {Re a..Re b}"
1563   using has_contour_integral_linepath_Reals_iff[OF assms, of f]
1564   by (auto simp: contour_integrable_on_def integrable_on_def)
1566 lemma contour_integral_linepath_Reals_eq:
1567   fixes a b :: complex and f :: "complex \<Rightarrow> complex"
1568   assumes "a \<in> Reals" "b \<in> Reals" "Re a < Re b"
1569   shows   "contour_integral (linepath a b) f = integral {Re a..Re b} (\<lambda>x. f (of_real x))"
1570 proof (cases "f contour_integrable_on linepath a b")
1571   case True
1572   thus ?thesis using has_contour_integral_linepath_Reals_iff[OF assms, of f]
1573     using has_contour_integral_integral has_contour_integral_unique by blast
1574 next
1575   case False
1576   thus ?thesis using contour_integrable_linepath_Reals_iff[OF assms, of f]
1577     by (simp add: not_integrable_contour_integral not_integrable_integral)
1578 qed
1582 text\<open>Cauchy's theorem where there's a primitive\<close>
1584 lemma contour_integral_primitive_lemma:
1585   fixes f :: "complex \<Rightarrow> complex" and g :: "real \<Rightarrow> complex"
1586   assumes "a \<le> b"
1587       and "\<And>x. x \<in> s \<Longrightarrow> (f has_field_derivative f' x) (at x within s)"
1588       and "g piecewise_differentiable_on {a..b}"  "\<And>x. x \<in> {a..b} \<Longrightarrow> g x \<in> s"
1589     shows "((\<lambda>x. f'(g x) * vector_derivative g (at x within {a..b}))
1590              has_integral (f(g b) - f(g a))) {a..b}"
1591 proof -
1592   obtain k where k: "finite k" "\<forall>x\<in>{a..b} - k. g differentiable (at x within {a..b})" and cg: "continuous_on {a..b} g"
1593     using assms by (auto simp: piecewise_differentiable_on_def)
1594   have cfg: "continuous_on {a..b} (\<lambda>x. f (g x))"
1595     apply (rule continuous_on_compose [OF cg, unfolded o_def])
1596     using assms
1597     apply (metis field_differentiable_def field_differentiable_imp_continuous_at continuous_on_eq_continuous_within continuous_on_subset image_subset_iff)
1598     done
1599   { fix x::real
1600     assume a: "a < x" and b: "x < b" and xk: "x \<notin> k"
1601     then have "g differentiable at x within {a..b}"
1602       using k by (simp add: differentiable_at_withinI)
1603     then have "(g has_vector_derivative vector_derivative g (at x within {a..b})) (at x within {a..b})"
1604       by (simp add: vector_derivative_works has_field_derivative_def scaleR_conv_of_real)
1605     then have gdiff: "(g has_derivative (\<lambda>u. u * vector_derivative g (at x within {a..b}))) (at x within {a..b})"
1606       by (simp add: has_vector_derivative_def scaleR_conv_of_real)
1607     have "(f has_field_derivative (f' (g x))) (at (g x) within g ` {a..b})"
1608       using assms by (metis a atLeastAtMost_iff b DERIV_subset image_subset_iff less_eq_real_def)
1609     then have fdiff: "(f has_derivative (*) (f' (g x))) (at (g x) within g ` {a..b})"
1610       by (simp add: has_field_derivative_def)
1611     have "((\<lambda>x. f (g x)) has_vector_derivative f' (g x) * vector_derivative g (at x within {a..b})) (at x within {a..b})"
1612       using diff_chain_within [OF gdiff fdiff]
1613       by (simp add: has_vector_derivative_def scaleR_conv_of_real o_def mult_ac)
1614   } note * = this
1615   show ?thesis
1616     apply (rule fundamental_theorem_of_calculus_interior_strong)
1617     using k assms cfg *
1618     apply (auto simp: at_within_Icc_at)
1619     done
1620 qed
1622 lemma contour_integral_primitive:
1623   assumes "\<And>x. x \<in> s \<Longrightarrow> (f has_field_derivative f' x) (at x within s)"
1624       and "valid_path g" "path_image g \<subseteq> s"
1625     shows "(f' has_contour_integral (f(pathfinish g) - f(pathstart g))) g"
1626   using assms
1627   apply (simp add: valid_path_def path_image_def pathfinish_def pathstart_def has_contour_integral_def)
1628   apply (auto intro!: piecewise_C1_imp_differentiable contour_integral_primitive_lemma [of 0 1 s])
1629   done
1631 corollary Cauchy_theorem_primitive:
1632   assumes "\<And>x. x \<in> s \<Longrightarrow> (f has_field_derivative f' x) (at x within s)"
1633       and "valid_path g"  "path_image g \<subseteq> s" "pathfinish g = pathstart g"
1634     shows "(f' has_contour_integral 0) g"
1635   using assms
1636   by (metis diff_self contour_integral_primitive)
1638 text\<open>Existence of path integral for continuous function\<close>
1639 lemma contour_integrable_continuous_linepath:
1640   assumes "continuous_on (closed_segment a b) f"
1641   shows "f contour_integrable_on (linepath a b)"
1642 proof -
1643   have "continuous_on {0..1} ((\<lambda>x. f x * (b - a)) \<circ> linepath a b)"
1644     apply (rule continuous_on_compose [OF continuous_on_linepath], simp add: linepath_image_01)
1645     apply (rule continuous_intros | simp add: assms)+
1646     done
1647   then show ?thesis
1648     apply (simp add: contour_integrable_on_def has_contour_integral_def integrable_on_def [symmetric])
1649     apply (rule integrable_continuous [of 0 "1::real", simplified])
1650     apply (rule continuous_on_eq [where f = "\<lambda>x. f(linepath a b x)*(b - a)"])
1651     apply (auto simp: vector_derivative_linepath_within)
1652     done
1653 qed
1655 lemma has_field_der_id: "((\<lambda>x. x\<^sup>2 / 2) has_field_derivative x) (at x)"
1656   by (rule has_derivative_imp_has_field_derivative)
1657      (rule derivative_intros | simp)+
1659 lemma contour_integral_id [simp]: "contour_integral (linepath a b) (\<lambda>y. y) = (b^2 - a^2)/2"
1660   apply (rule contour_integral_unique)
1661   using contour_integral_primitive [of UNIV "\<lambda>x. x^2/2" "\<lambda>x. x" "linepath a b"]
1662   apply (auto simp: field_simps has_field_der_id)
1663   done
1665 lemma contour_integrable_on_const [iff]: "(\<lambda>x. c) contour_integrable_on (linepath a b)"
1666   by (simp add: continuous_on_const contour_integrable_continuous_linepath)
1668 lemma contour_integrable_on_id [iff]: "(\<lambda>x. x) contour_integrable_on (linepath a b)"
1669   by (simp add: continuous_on_id contour_integrable_continuous_linepath)
1671 subsection%unimportant \<open>Arithmetical combining theorems\<close>
1673 lemma has_contour_integral_neg:
1674     "(f has_contour_integral i) g \<Longrightarrow> ((\<lambda>x. -(f x)) has_contour_integral (-i)) g"
1675   by (simp add: has_integral_neg has_contour_integral_def)
1678     "\<lbrakk>(f1 has_contour_integral i1) g; (f2 has_contour_integral i2) g\<rbrakk>
1679      \<Longrightarrow> ((\<lambda>x. f1 x + f2 x) has_contour_integral (i1 + i2)) g"
1680   by (simp add: has_integral_add has_contour_integral_def algebra_simps)
1682 lemma has_contour_integral_diff:
1683   "\<lbrakk>(f1 has_contour_integral i1) g; (f2 has_contour_integral i2) g\<rbrakk>
1684          \<Longrightarrow> ((\<lambda>x. f1 x - f2 x) has_contour_integral (i1 - i2)) g"
1685   by (simp add: has_integral_diff has_contour_integral_def algebra_simps)
1687 lemma has_contour_integral_lmul:
1688   "(f has_contour_integral i) g \<Longrightarrow> ((\<lambda>x. c * (f x)) has_contour_integral (c*i)) g"
1689 apply (simp add: has_contour_integral_def)
1690 apply (drule has_integral_mult_right)
1691 apply (simp add: algebra_simps)
1692 done
1694 lemma has_contour_integral_rmul:
1695   "(f has_contour_integral i) g \<Longrightarrow> ((\<lambda>x. (f x) * c) has_contour_integral (i*c)) g"
1696 apply (drule has_contour_integral_lmul)
1697 apply (simp add: mult.commute)
1698 done
1700 lemma has_contour_integral_div:
1701   "(f has_contour_integral i) g \<Longrightarrow> ((\<lambda>x. f x/c) has_contour_integral (i/c)) g"
1702   by (simp add: field_class.field_divide_inverse) (metis has_contour_integral_rmul)
1704 lemma has_contour_integral_eq:
1705     "\<lbrakk>(f has_contour_integral y) p; \<And>x. x \<in> path_image p \<Longrightarrow> f x = g x\<rbrakk> \<Longrightarrow> (g has_contour_integral y) p"
1706 apply (simp add: path_image_def has_contour_integral_def)
1707 by (metis (no_types, lifting) image_eqI has_integral_eq)
1709 lemma has_contour_integral_bound_linepath:
1710   assumes "(f has_contour_integral i) (linepath a b)"
1711           "0 \<le> B" "\<And>x. x \<in> closed_segment a b \<Longrightarrow> norm(f x) \<le> B"
1712     shows "norm i \<le> B * norm(b - a)"
1713 proof -
1714   { fix x::real
1715     assume x: "0 \<le> x" "x \<le> 1"
1716   have "norm (f (linepath a b x)) *
1717         norm (vector_derivative (linepath a b) (at x within {0..1})) \<le> B * norm (b - a)"
1718     by (auto intro: mult_mono simp: assms linepath_in_path of_real_linepath vector_derivative_linepath_within x)
1719   } note * = this
1720   have "norm i \<le> (B * norm (b - a)) * content (cbox 0 (1::real))"
1721     apply (rule has_integral_bound
1722        [of _ "\<lambda>x. f (linepath a b x) * vector_derivative (linepath a b) (at x within {0..1})"])
1723     using assms * unfolding has_contour_integral_def
1724     apply (auto simp: norm_mult)
1725     done
1726   then show ?thesis
1727     by (auto simp: content_real)
1728 qed
1730 (*UNUSED
1731 lemma has_contour_integral_bound_linepath_strong:
1732   fixes a :: real and f :: "complex \<Rightarrow> real"
1733   assumes "(f has_contour_integral i) (linepath a b)"
1734           "finite k"
1735           "0 \<le> B" "\<And>x::real. x \<in> closed_segment a b - k \<Longrightarrow> norm(f x) \<le> B"
1736     shows "norm i \<le> B*norm(b - a)"
1737 *)
1739 lemma has_contour_integral_const_linepath: "((\<lambda>x. c) has_contour_integral c*(b - a))(linepath a b)"
1740   unfolding has_contour_integral_linepath
1741   by (metis content_real diff_0_right has_integral_const_real lambda_one of_real_1 scaleR_conv_of_real zero_le_one)
1743 lemma has_contour_integral_0: "((\<lambda>x. 0) has_contour_integral 0) g"
1744   by (simp add: has_contour_integral_def)
1746 lemma has_contour_integral_is_0:
1747     "(\<And>z. z \<in> path_image g \<Longrightarrow> f z = 0) \<Longrightarrow> (f has_contour_integral 0) g"
1748   by (rule has_contour_integral_eq [OF has_contour_integral_0]) auto
1750 lemma has_contour_integral_sum:
1751     "\<lbrakk>finite s; \<And>a. a \<in> s \<Longrightarrow> (f a has_contour_integral i a) p\<rbrakk>
1752      \<Longrightarrow> ((\<lambda>x. sum (\<lambda>a. f a x) s) has_contour_integral sum i s) p"
1753   by (induction s rule: finite_induct) (auto simp: has_contour_integral_0 has_contour_integral_add)
1755 subsection%unimportant \<open>Operations on path integrals\<close>
1757 lemma contour_integral_const_linepath [simp]: "contour_integral (linepath a b) (\<lambda>x. c) = c*(b - a)"
1758   by (rule contour_integral_unique [OF has_contour_integral_const_linepath])
1760 lemma contour_integral_neg:
1761     "f contour_integrable_on g \<Longrightarrow> contour_integral g (\<lambda>x. -(f x)) = -(contour_integral g f)"
1762   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_neg)
1765     "f1 contour_integrable_on g \<Longrightarrow> f2 contour_integrable_on g \<Longrightarrow> contour_integral g (\<lambda>x. f1 x + f2 x) =
1766                 contour_integral g f1 + contour_integral g f2"
1767   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_add)
1769 lemma contour_integral_diff:
1770     "f1 contour_integrable_on g \<Longrightarrow> f2 contour_integrable_on g \<Longrightarrow> contour_integral g (\<lambda>x. f1 x - f2 x) =
1771                 contour_integral g f1 - contour_integral g f2"
1772   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_diff)
1774 lemma contour_integral_lmul:
1775   shows "f contour_integrable_on g
1776            \<Longrightarrow> contour_integral g (\<lambda>x. c * f x) = c*contour_integral g f"
1777   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_lmul)
1779 lemma contour_integral_rmul:
1780   shows "f contour_integrable_on g
1781         \<Longrightarrow> contour_integral g (\<lambda>x. f x * c) = contour_integral g f * c"
1782   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_rmul)
1784 lemma contour_integral_div:
1785   shows "f contour_integrable_on g
1786         \<Longrightarrow> contour_integral g (\<lambda>x. f x / c) = contour_integral g f / c"
1787   by (simp add: contour_integral_unique has_contour_integral_integral has_contour_integral_div)
1789 lemma contour_integral_eq:
1790     "(\<And>x. x \<in> path_image p \<Longrightarrow> f x = g x) \<Longrightarrow> contour_integral p f = contour_integral p g"
1791   apply (simp add: contour_integral_def)
1792   using has_contour_integral_eq
1793   by (metis contour_integral_unique has_contour_integral_integrable has_contour_integral_integral)
1795 lemma contour_integral_eq_0:
1796     "(\<And>z. z \<in> path_image g \<Longrightarrow> f z = 0) \<Longrightarrow> contour_integral g f = 0"
1797   by (simp add: has_contour_integral_is_0 contour_integral_unique)
1799 lemma contour_integral_bound_linepath:
1800   shows
1801     "\<lbrakk>f contour_integrable_on (linepath a b);
1802       0 \<le> B; \<And>x. x \<in> closed_segment a b \<Longrightarrow> norm(f x) \<le> B\<rbrakk>
1803      \<Longrightarrow> norm(contour_integral (linepath a b) f) \<le> B*norm(b - a)"
1804   apply (rule has_contour_integral_bound_linepath [of f])
1805   apply (auto simp: has_contour_integral_integral)
1806   done
1808 lemma contour_integral_0 [simp]: "contour_integral g (\<lambda>x. 0) = 0"
1809   by (simp add: contour_integral_unique has_contour_integral_0)
1811 lemma contour_integral_sum:
1812     "\<lbrakk>finite s; \<And>a. a \<in> s \<Longrightarrow> (f a) contour_integrable_on p\<rbrakk>
1813      \<Longrightarrow> contour_integral p (\<lambda>x. sum (\<lambda>a. f a x) s) = sum (\<lambda>a. contour_integral p (f a)) s"
1814   by (auto simp: contour_integral_unique has_contour_integral_sum has_contour_integral_integral)
1816 lemma contour_integrable_eq:
1817     "\<lbrakk>f contour_integrable_on p; \<And>x. x \<in> path_image p \<Longrightarrow> f x = g x\<rbrakk> \<Longrightarrow> g contour_integrable_on p"
1818   unfolding contour_integrable_on_def
1819   by (metis has_contour_integral_eq)
1822 subsection%unimportant \<open>Arithmetic theorems for path integrability\<close>
1824 lemma contour_integrable_neg:
1825     "f contour_integrable_on g \<Longrightarrow> (\<lambda>x. -(f x)) contour_integrable_on g"
1826   using has_contour_integral_neg contour_integrable_on_def by blast
1829     "\<lbrakk>f1 contour_integrable_on g; f2 contour_integrable_on g\<rbrakk> \<Longrightarrow> (\<lambda>x. f1 x + f2 x) contour_integrable_on g"
1830   using has_contour_integral_add contour_integrable_on_def
1831   by fastforce
1833 lemma contour_integrable_diff:
1834     "\<lbrakk>f1 contour_integrable_on g; f2 contour_integrable_on g\<rbrakk> \<Longrightarrow> (\<lambda>x. f1 x - f2 x) contour_integrable_on g"
1835   using has_contour_integral_diff contour_integrable_on_def
1836   by fastforce
1838 lemma contour_integrable_lmul:
1839     "f contour_integrable_on g \<Longrightarrow> (\<lambda>x. c * f x) contour_integrable_on g"
1840   using has_contour_integral_lmul contour_integrable_on_def
1841   by fastforce
1843 lemma contour_integrable_rmul:
1844     "f contour_integrable_on g \<Longrightarrow> (\<lambda>x. f x * c) contour_integrable_on g"
1845   using has_contour_integral_rmul contour_integrable_on_def
1846   by fastforce
1848 lemma contour_integrable_div:
1849     "f contour_integrable_on g \<Longrightarrow> (\<lambda>x. f x / c) contour_integrable_on g"
1850   using has_contour_integral_div contour_integrable_on_def
1851   by fastforce
1853 lemma contour_integrable_sum:
1854     "\<lbrakk>finite s; \<And>a. a \<in> s \<Longrightarrow> (f a) contour_integrable_on p\<rbrakk>
1855      \<Longrightarrow> (\<lambda>x. sum (\<lambda>a. f a x) s) contour_integrable_on p"
1856    unfolding contour_integrable_on_def
1857    by (metis has_contour_integral_sum)
1860 subsection%unimportant \<open>Reversing a path integral\<close>
1862 lemma has_contour_integral_reverse_linepath:
1863     "(f has_contour_integral i) (linepath a b)
1864      \<Longrightarrow> (f has_contour_integral (-i)) (linepath b a)"
1865   using has_contour_integral_reversepath valid_path_linepath by fastforce
1867 lemma contour_integral_reverse_linepath:
1868     "continuous_on (closed_segment a b) f
1869      \<Longrightarrow> contour_integral (linepath a b) f = - (contour_integral(linepath b a) f)"
1870 apply (rule contour_integral_unique)
1871 apply (rule has_contour_integral_reverse_linepath)
1872 by (simp add: closed_segment_commute contour_integrable_continuous_linepath has_contour_integral_integral)
1875 (* Splitting a path integral in a flat way.*)
1877 lemma has_contour_integral_split:
1878   assumes f: "(f has_contour_integral i) (linepath a c)" "(f has_contour_integral j) (linepath c b)"
1879       and k: "0 \<le> k" "k \<le> 1"
1880       and c: "c - a = k *\<^sub>R (b - a)"
1881     shows "(f has_contour_integral (i + j)) (linepath a b)"
1882 proof (cases "k = 0 \<or> k = 1")
1883   case True
1884   then show ?thesis
1885     using assms by auto
1886 next
1887   case False
1888   then have k: "0 < k" "k < 1" "complex_of_real k \<noteq> 1"
1889     using assms by auto
1890   have c': "c = k *\<^sub>R (b - a) + a"
1891     by (metis diff_add_cancel c)
1892   have bc: "(b - c) = (1 - k) *\<^sub>R (b - a)"
1893     by (simp add: algebra_simps c')
1894   { assume *: "((\<lambda>x. f ((1 - x) *\<^sub>R a + x *\<^sub>R c) * (c - a)) has_integral i) {0..1}"
1895     have **: "\<And>x. ((k - x) / k) *\<^sub>R a + (x / k) *\<^sub>R c = (1 - x) *\<^sub>R a + x *\<^sub>R b"
1896       using False apply (simp add: c' algebra_simps)
1897       apply (simp add: real_vector.scale_left_distrib [symmetric] divide_simps)
1898       done
1899     have "((\<lambda>x. f ((1 - x) *\<^sub>R a + x *\<^sub>R b) * (b - a)) has_integral i) {0..k}"
1900       using k has_integral_affinity01 [OF *, of "inverse k" "0"]
1901       apply (simp add: divide_simps mult.commute [of _ "k"] image_affinity_atLeastAtMost ** c)
1902       apply (auto dest: has_integral_cmul [where c = "inverse k"])
1903       done
1904   } note fi = this
1905   { assume *: "((\<lambda>x. f ((1 - x) *\<^sub>R c + x *\<^sub>R b) * (b - c)) has_integral j) {0..1}"
1906     have **: "\<And>x. (((1 - x) / (1 - k)) *\<^sub>R c + ((x - k) / (1 - k)) *\<^sub>R b) = ((1 - x) *\<^sub>R a + x *\<^sub>R b)"
1907       using k
1908       apply (simp add: c' field_simps)
1909       apply (simp add: scaleR_conv_of_real divide_simps)
1910       apply (simp add: field_simps)
1911       done
1912     have "((\<lambda>x. f ((1 - x) *\<^sub>R a + x *\<^sub>R b) * (b - a)) has_integral j) {k..1}"
1913       using k has_integral_affinity01 [OF *, of "inverse(1 - k)" "-(k/(1 - k))"]
1914       apply (simp add: divide_simps mult.commute [of _ "1-k"] image_affinity_atLeastAtMost ** bc)
1915       apply (auto dest: has_integral_cmul [where k = "(1 - k) *\<^sub>R j" and c = "inverse (1 - k)"])
1916       done
1917   } note fj = this
1918   show ?thesis
1919     using f k
1920     apply (simp add: has_contour_integral_linepath)
1921     apply (simp add: linepath_def)
1922     apply (rule has_integral_combine [OF _ _ fi fj], simp_all)
1923     done
1924 qed
1926 lemma continuous_on_closed_segment_transform:
1927   assumes f: "continuous_on (closed_segment a b) f"
1928       and k: "0 \<le> k" "k \<le> 1"
1929       and c: "c - a = k *\<^sub>R (b - a)"
1930     shows "continuous_on (closed_segment a c) f"
1931 proof -
1932   have c': "c = (1 - k) *\<^sub>R a + k *\<^sub>R b"
1933     using c by (simp add: algebra_simps)
1934   have "closed_segment a c \<subseteq> closed_segment a b"
1935     by (metis c' ends_in_segment(1) in_segment(1) k subset_closed_segment)
1936   then show "continuous_on (closed_segment a c) f"
1937     by (rule continuous_on_subset [OF f])
1938 qed
1940 lemma contour_integral_split:
1941   assumes f: "continuous_on (closed_segment a b) f"
1942       and k: "0 \<le> k" "k \<le> 1"
1943       and c: "c - a = k *\<^sub>R (b - a)"
1944     shows "contour_integral(linepath a b) f = contour_integral(linepath a c) f + contour_integral(linepath c b) f"
1945 proof -
1946   have c': "c = (1 - k) *\<^sub>R a + k *\<^sub>R b"
1947     using c by (simp add: algebra_simps)
1948   have "closed_segment a c \<subseteq> closed_segment a b"
1949     by (metis c' ends_in_segment(1) in_segment(1) k subset_closed_segment)
1950   moreover have "closed_segment c b \<subseteq> closed_segment a b"
1951     by (metis c' ends_in_segment(2) in_segment(1) k subset_closed_segment)
1952   ultimately
1953   have *: "continuous_on (closed_segment a c) f" "continuous_on (closed_segment c b) f"
1954     by (auto intro: continuous_on_subset [OF f])
1955   show ?thesis
1956     by (rule contour_integral_unique) (meson "*" c contour_integrable_continuous_linepath has_contour_integral_integral has_contour_integral_split k)
1957 qed
1959 lemma contour_integral_split_linepath:
1960   assumes f: "continuous_on (closed_segment a b) f"
1961       and c: "c \<in> closed_segment a b"
1962     shows "contour_integral(linepath a b) f = contour_integral(linepath a c) f + contour_integral(linepath c b) f"
1963   using c by (auto simp: closed_segment_def algebra_simps intro!: contour_integral_split [OF f])
1965 text\<open>The special case of midpoints used in the main quadrisection\<close>
1967 lemma has_contour_integral_midpoint:
1968   assumes "(f has_contour_integral i) (linepath a (midpoint a b))"
1969           "(f has_contour_integral j) (linepath (midpoint a b) b)"
1970     shows "(f has_contour_integral (i + j)) (linepath a b)"
1971   apply (rule has_contour_integral_split [where c = "midpoint a b" and k = "1/2"])
1972   using assms
1973   apply (auto simp: midpoint_def algebra_simps scaleR_conv_of_real)
1974   done
1976 lemma contour_integral_midpoint:
1977    "continuous_on (closed_segment a b) f
1978     \<Longrightarrow> contour_integral (linepath a b) f =
1979         contour_integral (linepath a (midpoint a b)) f + contour_integral (linepath (midpoint a b) b) f"
1980   apply (rule contour_integral_split [where c = "midpoint a b" and k = "1/2"])
1981   apply (auto simp: midpoint_def algebra_simps scaleR_conv_of_real)
1982   done
1985 text\<open>A couple of special case lemmas that are useful below\<close>
1987 lemma triangle_linear_has_chain_integral:
1988     "((\<lambda>x. m*x + d) has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
1989   apply (rule Cauchy_theorem_primitive [of UNIV "\<lambda>x. m/2 * x^2 + d*x"])
1990   apply (auto intro!: derivative_eq_intros)
1991   done
1993 lemma has_chain_integral_chain_integral3:
1994      "(f has_contour_integral i) (linepath a b +++ linepath b c +++ linepath c d)
1995       \<Longrightarrow> contour_integral (linepath a b) f + contour_integral (linepath b c) f + contour_integral (linepath c d) f = i"
1996   apply (subst contour_integral_unique [symmetric], assumption)
1997   apply (drule has_contour_integral_integrable)
1998   apply (simp add: valid_path_join)
1999   done
2001 lemma has_chain_integral_chain_integral4:
2002      "(f has_contour_integral i) (linepath a b +++ linepath b c +++ linepath c d +++ linepath d e)
2003       \<Longrightarrow> contour_integral (linepath a b) f + contour_integral (linepath b c) f + contour_integral (linepath c d) f + contour_integral (linepath d e) f = i"
2004   apply (subst contour_integral_unique [symmetric], assumption)
2005   apply (drule has_contour_integral_integrable)
2006   apply (simp add: valid_path_join)
2007   done
2009 subsection\<open>Reversing the order in a double path integral\<close>
2011 text\<open>The condition is stronger than needed but it's often true in typical situations\<close>
2013 lemma fst_im_cbox [simp]: "cbox c d \<noteq> {} \<Longrightarrow> (fst ` cbox (a,c) (b,d)) = cbox a b"
2014   by (auto simp: cbox_Pair_eq)
2016 lemma snd_im_cbox [simp]: "cbox a b \<noteq> {} \<Longrightarrow> (snd ` cbox (a,c) (b,d)) = cbox c d"
2017   by (auto simp: cbox_Pair_eq)
2019 proposition contour_integral_swap:
2020   assumes fcon:  "continuous_on (path_image g \<times> path_image h) (\<lambda>(y1,y2). f y1 y2)"
2021       and vp:    "valid_path g" "valid_path h"
2022       and gvcon: "continuous_on {0..1} (\<lambda>t. vector_derivative g (at t))"
2023       and hvcon: "continuous_on {0..1} (\<lambda>t. vector_derivative h (at t))"
2024   shows "contour_integral g (\<lambda>w. contour_integral h (f w)) =
2025          contour_integral h (\<lambda>z. contour_integral g (\<lambda>w. f w z))"
2026 proof -
2027   have gcon: "continuous_on {0..1} g" and hcon: "continuous_on {0..1} h"
2028     using assms by (auto simp: valid_path_def piecewise_C1_differentiable_on_def)
2029   have fgh1: "\<And>x. (\<lambda>t. f (g x) (h t)) = (\<lambda>(y1,y2). f y1 y2) \<circ> (\<lambda>t. (g x, h t))"
2030     by (rule ext) simp
2031   have fgh2: "\<And>x. (\<lambda>t. f (g t) (h x)) = (\<lambda>(y1,y2). f y1 y2) \<circ> (\<lambda>t. (g t, h x))"
2032     by (rule ext) simp
2033   have fcon_im1: "\<And>x. 0 \<le> x \<Longrightarrow> x \<le> 1 \<Longrightarrow> continuous_on ((\<lambda>t. (g x, h t)) ` {0..1}) (\<lambda>(x, y). f x y)"
2034     by (rule continuous_on_subset [OF fcon]) (auto simp: path_image_def)
2035   have fcon_im2: "\<And>x. 0 \<le> x \<Longrightarrow> x \<le> 1 \<Longrightarrow> continuous_on ((\<lambda>t. (g t, h x)) ` {0..1}) (\<lambda>(x, y). f x y)"
2036     by (rule continuous_on_subset [OF fcon]) (auto simp: path_image_def)
2037   have "\<And>y. y \<in> {0..1} \<Longrightarrow> continuous_on {0..1} (\<lambda>x. f (g x) (h y))"
2038     by (subst fgh2) (rule fcon_im2 gcon continuous_intros | simp)+
2039   then have vdg: "\<And>y. y \<in> {0..1} \<Longrightarrow> (\<lambda>x. f (g x) (h y) * vector_derivative g (at x)) integrable_on {0..1}"
2040     using continuous_on_mult gvcon integrable_continuous_real by blast
2041   have "(\<lambda>z. vector_derivative g (at (fst z))) = (\<lambda>x. vector_derivative g (at x)) \<circ> fst"
2042     by auto
2043   then have gvcon': "continuous_on (cbox (0, 0) (1, 1::real)) (\<lambda>x. vector_derivative g (at (fst x)))"
2044     apply (rule ssubst)
2045     apply (rule continuous_intros | simp add: gvcon)+
2046     done
2047   have "(\<lambda>z. vector_derivative h (at (snd z))) = (\<lambda>x. vector_derivative h (at x)) \<circ> snd"
2048     by auto
2049   then have hvcon': "continuous_on (cbox (0, 0) (1::real, 1)) (\<lambda>x. vector_derivative h (at (snd x)))"
2050     apply (rule ssubst)
2051     apply (rule continuous_intros | simp add: hvcon)+
2052     done
2053   have "(\<lambda>x. f (g (fst x)) (h (snd x))) = (\<lambda>(y1,y2). f y1 y2) \<circ> (\<lambda>w. ((g \<circ> fst) w, (h \<circ> snd) w))"
2054     by auto
2055   then have fgh: "continuous_on (cbox (0, 0) (1, 1)) (\<lambda>x. f (g (fst x)) (h (snd x)))"
2056     apply (rule ssubst)
2057     apply (rule gcon hcon continuous_intros | simp)+
2058     apply (auto simp: path_image_def intro: continuous_on_subset [OF fcon])
2059     done
2060   have "integral {0..1} (\<lambda>x. contour_integral h (f (g x)) * vector_derivative g (at x)) =
2061         integral {0..1} (\<lambda>x. contour_integral h (\<lambda>y. f (g x) y * vector_derivative g (at x)))"
2062   proof (rule integral_cong [OF contour_integral_rmul [symmetric]])
2063     show "\<And>x. x \<in> {0..1} \<Longrightarrow> f (g x) contour_integrable_on h"
2064       unfolding contour_integrable_on
2065     apply (rule integrable_continuous_real)
2066     apply (rule continuous_on_mult [OF _ hvcon])
2067     apply (subst fgh1)
2068     apply (rule fcon_im1 hcon continuous_intros | simp)+
2069       done
2070   qed
2071   also have "\<dots> = integral {0..1}
2072                      (\<lambda>y. contour_integral g (\<lambda>x. f x (h y) * vector_derivative h (at y)))"
2073     unfolding contour_integral_integral
2074     apply (subst integral_swap_continuous [where 'a = real and 'b = real, of 0 0 1 1, simplified])
2075      apply (rule fgh gvcon' hvcon' continuous_intros | simp add: split_def)+
2076     unfolding integral_mult_left [symmetric]
2077     apply (simp only: mult_ac)
2078     done
2079   also have "\<dots> = contour_integral h (\<lambda>z. contour_integral g (\<lambda>w. f w z))"
2080     unfolding contour_integral_integral
2081     apply (rule integral_cong)
2082     unfolding integral_mult_left [symmetric]
2083     apply (simp add: algebra_simps)
2084     done
2085   finally show ?thesis
2086     by (simp add: contour_integral_integral)
2087 qed
2090 subsection%unimportant \<open>The key quadrisection step\<close>
2092 lemma norm_sum_half:
2093   assumes "norm(a + b) \<ge> e"
2094     shows "norm a \<ge> e/2 \<or> norm b \<ge> e/2"
2095 proof -
2096   have "e \<le> norm (- a - b)"
2097     by (simp add: add.commute assms norm_minus_commute)
2098   thus ?thesis
2099     using norm_triangle_ineq4 order_trans by fastforce
2100 qed
2102 lemma norm_sum_lemma:
2103   assumes "e \<le> norm (a + b + c + d)"
2104     shows "e / 4 \<le> norm a \<or> e / 4 \<le> norm b \<or> e / 4 \<le> norm c \<or> e / 4 \<le> norm d"
2105 proof -
2106   have "e \<le> norm ((a + b) + (c + d))" using assms
2107     by (simp add: algebra_simps)
2108   then show ?thesis
2109     by (auto dest!: norm_sum_half)
2110 qed
2113   assumes f: "continuous_on (convex hull {a,b,c}) f"
2114       and dist: "dist a b \<le> K" "dist b c \<le> K" "dist c a \<le> K"
2115       and e: "e * K^2 \<le>
2116               norm (contour_integral(linepath a b) f + contour_integral(linepath b c) f + contour_integral(linepath c a) f)"
2117   shows "\<exists>a' b' c'.
2118            a' \<in> convex hull {a,b,c} \<and> b' \<in> convex hull {a,b,c} \<and> c' \<in> convex hull {a,b,c} \<and>
2119            dist a' b' \<le> K/2  \<and>  dist b' c' \<le> K/2  \<and>  dist c' a' \<le> K/2  \<and>
2120            e * (K/2)^2 \<le> norm(contour_integral(linepath a' b') f + contour_integral(linepath b' c') f + contour_integral(linepath c' a') f)"
2121          (is "\<exists>x y z. ?\<Phi> x y z")
2122 proof -
2123   note divide_le_eq_numeral1 [simp del]
2124   define a' where "a' = midpoint b c"
2125   define b' where "b' = midpoint c a"
2126   define c' where "c' = midpoint a b"
2127   have fabc: "continuous_on (closed_segment a b) f" "continuous_on (closed_segment b c) f" "continuous_on (closed_segment c a) f"
2128     using f continuous_on_subset segments_subset_convex_hull by metis+
2129   have fcont': "continuous_on (closed_segment c' b') f"
2130                "continuous_on (closed_segment a' c') f"
2131                "continuous_on (closed_segment b' a') f"
2132     unfolding a'_def b'_def c'_def
2133     by (rule continuous_on_subset [OF f],
2134            metis midpoints_in_convex_hull convex_hull_subset hull_subset insert_subset segment_convex_hull)+
2135   let ?pathint = "\<lambda>x y. contour_integral(linepath x y) f"
2136   have *: "?pathint a b + ?pathint b c + ?pathint c a =
2137           (?pathint a c' + ?pathint c' b' + ?pathint b' a) +
2138           (?pathint a' c' + ?pathint c' b + ?pathint b a') +
2139           (?pathint a' c + ?pathint c b' + ?pathint b' a') +
2140           (?pathint a' b' + ?pathint b' c' + ?pathint c' a')"
2141     by (simp add: fcont' contour_integral_reverse_linepath) (simp add: a'_def b'_def c'_def contour_integral_midpoint fabc)
2142   have [simp]: "\<And>x y. cmod (x * 2 - y * 2) = cmod (x - y) * 2"
2143     by (metis left_diff_distrib mult.commute norm_mult_numeral1)
2144   have [simp]: "\<And>x y. cmod (x - y) = cmod (y - x)"
2145     by (simp add: norm_minus_commute)
2146   consider "e * K\<^sup>2 / 4 \<le> cmod (?pathint a c' + ?pathint c' b' + ?pathint b' a)" |
2147            "e * K\<^sup>2 / 4 \<le> cmod (?pathint a' c' + ?pathint c' b + ?pathint b a')" |
2148            "e * K\<^sup>2 / 4 \<le> cmod (?pathint a' c + ?pathint c b' + ?pathint b' a')" |
2149            "e * K\<^sup>2 / 4 \<le> cmod (?pathint a' b' + ?pathint b' c' + ?pathint c' a')"
2150     using assms unfolding * by (blast intro: that dest!: norm_sum_lemma)
2151   then show ?thesis
2152   proof cases
2153     case 1 then have "?\<Phi> a c' b'"
2154       using assms
2155       apply (clarsimp simp: c'_def b'_def midpoints_in_convex_hull hull_subset [THEN subsetD])
2156       apply (auto simp: midpoint_def dist_norm scaleR_conv_of_real divide_simps)
2157       done
2158     then show ?thesis by blast
2159   next
2160     case 2 then  have "?\<Phi> a' c' b"
2161       using assms
2162       apply (clarsimp simp: a'_def c'_def midpoints_in_convex_hull hull_subset [THEN subsetD])
2163       apply (auto simp: midpoint_def dist_norm scaleR_conv_of_real divide_simps)
2164       done
2165     then show ?thesis by blast
2166   next
2167     case 3 then have "?\<Phi> a' c b'"
2168       using assms
2169       apply (clarsimp simp: a'_def b'_def midpoints_in_convex_hull hull_subset [THEN subsetD])
2170       apply (auto simp: midpoint_def dist_norm scaleR_conv_of_real divide_simps)
2171       done
2172     then show ?thesis by blast
2173   next
2174     case 4 then have "?\<Phi> a' b' c'"
2175       using assms
2176       apply (clarsimp simp: a'_def c'_def b'_def midpoints_in_convex_hull hull_subset [THEN subsetD])
2177       apply (auto simp: midpoint_def dist_norm scaleR_conv_of_real divide_simps)
2178       done
2179     then show ?thesis by blast
2180   qed
2181 qed
2183 subsection%unimportant \<open>Cauchy's theorem for triangles\<close>
2185 lemma triangle_points_closer:
2186   fixes a::complex
2187   shows "\<lbrakk>x \<in> convex hull {a,b,c};  y \<in> convex hull {a,b,c}\<rbrakk>
2188          \<Longrightarrow> norm(x - y) \<le> norm(a - b) \<or>
2189              norm(x - y) \<le> norm(b - c) \<or>
2190              norm(x - y) \<le> norm(c - a)"
2191   using simplex_extremal_le [of "{a,b,c}"]
2192   by (auto simp: norm_minus_commute)
2194 lemma holomorphic_point_small_triangle:
2195   assumes x: "x \<in> S"
2196       and f: "continuous_on S f"
2197       and cd: "f field_differentiable (at x within S)"
2198       and e: "0 < e"
2199     shows "\<exists>k>0. \<forall>a b c. dist a b \<le> k \<and> dist b c \<le> k \<and> dist c a \<le> k \<and>
2200               x \<in> convex hull {a,b,c} \<and> convex hull {a,b,c} \<subseteq> S
2201               \<longrightarrow> norm(contour_integral(linepath a b) f + contour_integral(linepath b c) f +
2202                        contour_integral(linepath c a) f)
2203                   \<le> e*(dist a b + dist b c + dist c a)^2"
2204            (is "\<exists>k>0. \<forall>a b c. _ \<longrightarrow> ?normle a b c")
2205 proof -
2206   have le_of_3: "\<And>a x y z. \<lbrakk>0 \<le> x*y; 0 \<le> x*z; 0 \<le> y*z; a \<le> (e*(x + y + z))*x + (e*(x + y + z))*y + (e*(x + y + z))*z\<rbrakk>
2207                      \<Longrightarrow> a \<le> e*(x + y + z)^2"
2208     by (simp add: algebra_simps power2_eq_square)
2209   have disj_le: "\<lbrakk>x \<le> a \<or> x \<le> b \<or> x \<le> c; 0 \<le> a; 0 \<le> b; 0 \<le> c\<rbrakk> \<Longrightarrow> x \<le> a + b + c"
2210              for x::real and a b c
2211     by linarith
2212   have fabc: "f contour_integrable_on linepath a b" "f contour_integrable_on linepath b c" "f contour_integrable_on linepath c a"
2213               if "convex hull {a, b, c} \<subseteq> S" for a b c
2214     using segments_subset_convex_hull that
2215     by (metis continuous_on_subset f contour_integrable_continuous_linepath)+
2216   note path_bound = has_contour_integral_bound_linepath [simplified norm_minus_commute, OF has_contour_integral_integral]
2217   { fix f' a b c d
2218     assume d: "0 < d"
2219        and f': "\<And>y. \<lbrakk>cmod (y - x) \<le> d; y \<in> S\<rbrakk> \<Longrightarrow> cmod (f y - f x - f' * (y - x)) \<le> e * cmod (y - x)"
2220        and le: "cmod (a - b) \<le> d" "cmod (b - c) \<le> d" "cmod (c - a) \<le> d"
2221        and xc: "x \<in> convex hull {a, b, c}"
2222        and S: "convex hull {a, b, c} \<subseteq> S"
2223     have pa: "contour_integral (linepath a b) f + contour_integral (linepath b c) f + contour_integral (linepath c a) f =
2224               contour_integral (linepath a b) (\<lambda>y. f y - f x - f'*(y - x)) +
2225               contour_integral (linepath b c) (\<lambda>y. f y - f x - f'*(y - x)) +
2226               contour_integral (linepath c a) (\<lambda>y. f y - f x - f'*(y - x))"
2227       apply (simp add: contour_integral_diff contour_integral_lmul contour_integrable_lmul contour_integrable_diff fabc [OF S])
2228       apply (simp add: field_simps)
2229       done
2230     { fix y
2231       assume yc: "y \<in> convex hull {a,b,c}"
2232       have "cmod (f y - f x - f' * (y - x)) \<le> e*norm(y - x)"
2233       proof (rule f')
2234         show "cmod (y - x) \<le> d"
2235           by (metis triangle_points_closer [OF xc yc] le norm_minus_commute order_trans)
2236       qed (use S yc in blast)
2237       also have "\<dots> \<le> e * (cmod (a - b) + cmod (b - c) + cmod (c - a))"
2238         by (simp add: yc e xc disj_le [OF triangle_points_closer])
2239       finally have "cmod (f y - f x - f' * (y - x)) \<le> e * (cmod (a - b) + cmod (b - c) + cmod (c - a))" .
2240     } note cm_le = this
2241     have "?normle a b c"
2242       unfolding dist_norm pa
2243       apply (rule le_of_3)
2244       using f' xc S e
2245       apply simp_all
2246       apply (intro norm_triangle_le add_mono path_bound)
2247       apply (simp_all add: contour_integral_diff contour_integral_lmul contour_integrable_lmul contour_integrable_diff fabc)
2248       apply (blast intro: cm_le elim: dest: segments_subset_convex_hull [THEN subsetD])+
2249       done
2250   } note * = this
2251   show ?thesis
2252     using cd e
2253     apply (simp add: field_differentiable_def has_field_derivative_def has_derivative_within_alt approachable_lt_le2 Ball_def)
2254     apply (clarify dest!: spec mp)
2255     using * unfolding dist_norm
2256     apply blast
2257     done
2258 qed
2261 text\<open>Hence the most basic theorem for a triangle.\<close>
2263 locale Chain =
2264   fixes x0 At Follows
2265   assumes At0: "At x0 0"
2266       and AtSuc: "\<And>x n. At x n \<Longrightarrow> \<exists>x'. At x' (Suc n) \<and> Follows x' x"
2267 begin
2268   primrec f where
2269     "f 0 = x0"
2270   | "f (Suc n) = (SOME x. At x (Suc n) \<and> Follows x (f n))"
2272   lemma At: "At (f n) n"
2273   proof (induct n)
2274     case 0 show ?case
2275       by (simp add: At0)
2276   next
2277     case (Suc n) show ?case
2278       by (metis (no_types, lifting) AtSuc [OF Suc] f.simps(2) someI_ex)
2279   qed
2281   lemma Follows: "Follows (f(Suc n)) (f n)"
2282     by (metis (no_types, lifting) AtSuc [OF At [of n]] f.simps(2) someI_ex)
2284   declare f.simps(2) [simp del]
2285 end
2287 lemma Chain3:
2288   assumes At0: "At x0 y0 z0 0"
2289       and AtSuc: "\<And>x y z n. At x y z n \<Longrightarrow> \<exists>x' y' z'. At x' y' z' (Suc n) \<and> Follows x' y' z' x y z"
2290   obtains f g h where
2291     "f 0 = x0" "g 0 = y0" "h 0 = z0"
2292                       "\<And>n. At (f n) (g n) (h n) n"
2293                        "\<And>n. Follows (f(Suc n)) (g(Suc n)) (h(Suc n)) (f n) (g n) (h n)"
2294 proof -
2295   interpret three: Chain "(x0,y0,z0)" "\<lambda>(x,y,z). At x y z" "\<lambda>(x',y',z'). \<lambda>(x,y,z). Follows x' y' z' x y z"
2296     apply unfold_locales
2297     using At0 AtSuc by auto
2298   show ?thesis
2299   apply (rule that [of "\<lambda>n. fst (three.f n)"  "\<lambda>n. fst (snd (three.f n))" "\<lambda>n. snd (snd (three.f n))"])
2300   using three.At three.Follows
2301   apply simp_all
2302   apply (simp_all add: split_beta')
2303   done
2304 qed
2306 proposition%unimportant Cauchy_theorem_triangle:
2307   assumes "f holomorphic_on (convex hull {a,b,c})"
2308     shows "(f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2309 proof -
2310   have contf: "continuous_on (convex hull {a,b,c}) f"
2311     by (metis assms holomorphic_on_imp_continuous_on)
2312   let ?pathint = "\<lambda>x y. contour_integral(linepath x y) f"
2313   { fix y::complex
2314     assume fy: "(f has_contour_integral y) (linepath a b +++ linepath b c +++ linepath c a)"
2315        and ynz: "y \<noteq> 0"
2316     define K where "K = 1 + max (dist a b) (max (dist b c) (dist c a))"
2317     define e where "e = norm y / K^2"
2318     have K1: "K \<ge> 1"  by (simp add: K_def max.coboundedI1)
2319     then have K: "K > 0" by linarith
2320     have [iff]: "dist a b \<le> K" "dist b c \<le> K" "dist c a \<le> K"
2321       by (simp_all add: K_def)
2322     have e: "e > 0"
2323       unfolding e_def using ynz K1 by simp
2324     define At where "At x y z n \<longleftrightarrow>
2325         convex hull {x,y,z} \<subseteq> convex hull {a,b,c} \<and>
2326         dist x y \<le> K/2^n \<and> dist y z \<le> K/2^n \<and> dist z x \<le> K/2^n \<and>
2327         norm(?pathint x y + ?pathint y z + ?pathint z x) \<ge> e*(K/2^n)^2"
2328       for x y z n
2329     have At0: "At a b c 0"
2330       using fy
2331       by (simp add: At_def e_def has_chain_integral_chain_integral3)
2332     { fix x y z n
2333       assume At: "At x y z n"
2334       then have contf': "continuous_on (convex hull {x,y,z}) f"
2335         using contf At_def continuous_on_subset by metis
2336       have "\<exists>x' y' z'. At x' y' z' (Suc n) \<and> convex hull {x',y',z'} \<subseteq> convex hull {x,y,z}"
2337         using At Cauchy_theorem_quadrisection [OF contf', of "K/2^n" e]
2338         apply (simp add: At_def algebra_simps)
2339         apply (meson convex_hull_subset empty_subsetI insert_subset subsetCE)
2340         done
2341     } note AtSuc = this
2342     obtain fa fb fc
2343       where f0 [simp]: "fa 0 = a" "fb 0 = b" "fc 0 = c"
2344         and cosb: "\<And>n. convex hull {fa n, fb n, fc n} \<subseteq> convex hull {a,b,c}"
2345         and dist: "\<And>n. dist (fa n) (fb n) \<le> K/2^n"
2346                   "\<And>n. dist (fb n) (fc n) \<le> K/2^n"
2347                   "\<And>n. dist (fc n) (fa n) \<le> K/2^n"
2348         and no: "\<And>n. norm(?pathint (fa n) (fb n) +
2349                            ?pathint (fb n) (fc n) +
2350                            ?pathint (fc n) (fa n)) \<ge> e * (K/2^n)^2"
2351         and conv_le: "\<And>n. convex hull {fa(Suc n), fb(Suc n), fc(Suc n)} \<subseteq> convex hull {fa n, fb n, fc n}"
2352       apply (rule Chain3 [of At, OF At0 AtSuc])
2353       apply (auto simp: At_def)
2354       done
2355     obtain x where x: "\<And>n. x \<in> convex hull {fa n, fb n, fc n}"
2356     proof (rule bounded_closed_nest)
2357       show "\<And>n. closed (convex hull {fa n, fb n, fc n})"
2358         by (simp add: compact_imp_closed finite_imp_compact_convex_hull)
2359       show "\<And>m n. m \<le> n \<Longrightarrow> convex hull {fa n, fb n, fc n} \<subseteq> convex hull {fa m, fb m, fc m}"
2360         by (erule transitive_stepwise_le) (auto simp: conv_le)
2361     qed (fastforce intro: finite_imp_bounded_convex_hull)+
2362     then have xin: "x \<in> convex hull {a,b,c}"
2363       using assms f0 by blast
2364     then have fx: "f field_differentiable at x within (convex hull {a,b,c})"
2365       using assms holomorphic_on_def by blast
2366     { fix k n
2367       assume k: "0 < k"
2368          and le:
2369             "\<And>x' y' z'.
2370                \<lbrakk>dist x' y' \<le> k; dist y' z' \<le> k; dist z' x' \<le> k;
2371                 x \<in> convex hull {x',y',z'};
2372                 convex hull {x',y',z'} \<subseteq> convex hull {a,b,c}\<rbrakk>
2373                \<Longrightarrow>
2374                cmod (?pathint x' y' + ?pathint y' z' + ?pathint z' x') * 10
2375                      \<le> e * (dist x' y' + dist y' z' + dist z' x')\<^sup>2"
2376          and Kk: "K / k < 2 ^ n"
2377       have "K / 2 ^ n < k" using Kk k
2378         by (auto simp: field_simps)
2379       then have DD: "dist (fa n) (fb n) \<le> k" "dist (fb n) (fc n) \<le> k" "dist (fc n) (fa n) \<le> k"
2380         using dist [of n]  k
2381         by linarith+
2382       have dle: "(dist (fa n) (fb n) + dist (fb n) (fc n) + dist (fc n) (fa n))\<^sup>2
2383                \<le> (3 * K / 2 ^ n)\<^sup>2"
2384         using dist [of n] e K
2385         by (simp add: abs_le_square_iff [symmetric])
2386       have less10: "\<And>x y::real. 0 < x \<Longrightarrow> y \<le> 9*x \<Longrightarrow> y < x*10"
2387         by linarith
2388       have "e * (dist (fa n) (fb n) + dist (fb n) (fc n) + dist (fc n) (fa n))\<^sup>2 \<le> e * (3 * K / 2 ^ n)\<^sup>2"
2389         using ynz dle e mult_le_cancel_left_pos by blast
2390       also have "\<dots> <
2391           cmod (?pathint (fa n) (fb n) + ?pathint (fb n) (fc n) + ?pathint (fc n) (fa n)) * 10"
2392         using no [of n] e K
2393         apply (simp add: e_def field_simps)
2394         apply (simp only: zero_less_norm_iff [symmetric])
2395         done
2396       finally have False
2397         using le [OF DD x cosb] by auto
2398     } then
2399     have ?thesis
2400       using holomorphic_point_small_triangle [OF xin contf fx, of "e/10"] e
2401       apply clarsimp
2402       apply (rule_tac y1="K/k" in exE [OF real_arch_pow[of 2]], force+)
2403       done
2404   }
2405   moreover have "f contour_integrable_on (linepath a b +++ linepath b c +++ linepath c a)"
2406     by simp (meson contf continuous_on_subset contour_integrable_continuous_linepath segments_subset_convex_hull(1)
2407                    segments_subset_convex_hull(3) segments_subset_convex_hull(5))
2408   ultimately show ?thesis
2409     using has_contour_integral_integral by fastforce
2410 qed
2412 subsection%unimportant \<open>Version needing function holomorphic in interior only\<close>
2414 lemma Cauchy_theorem_flat_lemma:
2415   assumes f: "continuous_on (convex hull {a,b,c}) f"
2416       and c: "c - a = k *\<^sub>R (b - a)"
2417       and k: "0 \<le> k"
2418     shows "contour_integral (linepath a b) f + contour_integral (linepath b c) f +
2419           contour_integral (linepath c a) f = 0"
2420 proof -
2421   have fabc: "continuous_on (closed_segment a b) f" "continuous_on (closed_segment b c) f" "continuous_on (closed_segment c a) f"
2422     using f continuous_on_subset segments_subset_convex_hull by metis+
2423   show ?thesis
2424   proof (cases "k \<le> 1")
2425     case True show ?thesis
2426       by (simp add: contour_integral_split [OF fabc(1) k True c] contour_integral_reverse_linepath fabc)
2427   next
2428     case False then show ?thesis
2429       using fabc c
2430       apply (subst contour_integral_split [of a c f "1/k" b, symmetric])
2431       apply (metis closed_segment_commute fabc(3))
2432       apply (auto simp: k contour_integral_reverse_linepath)
2433       done
2434   qed
2435 qed
2437 lemma Cauchy_theorem_flat:
2438   assumes f: "continuous_on (convex hull {a,b,c}) f"
2439       and c: "c - a = k *\<^sub>R (b - a)"
2440     shows "contour_integral (linepath a b) f +
2441            contour_integral (linepath b c) f +
2442            contour_integral (linepath c a) f = 0"
2443 proof (cases "0 \<le> k")
2444   case True with assms show ?thesis
2445     by (blast intro: Cauchy_theorem_flat_lemma)
2446 next
2447   case False
2448   have "continuous_on (closed_segment a b) f" "continuous_on (closed_segment b c) f" "continuous_on (closed_segment c a) f"
2449     using f continuous_on_subset segments_subset_convex_hull by metis+
2450   moreover have "contour_integral (linepath b a) f + contour_integral (linepath a c) f +
2451         contour_integral (linepath c b) f = 0"
2452     apply (rule Cauchy_theorem_flat_lemma [of b a c f "1-k"])
2453     using False c
2454     apply (auto simp: f insert_commute scaleR_conv_of_real algebra_simps)
2455     done
2456   ultimately show ?thesis
2457     apply (auto simp: contour_integral_reverse_linepath)
2458     using add_eq_0_iff by force
2459 qed
2461 lemma Cauchy_theorem_triangle_interior:
2462   assumes contf: "continuous_on (convex hull {a,b,c}) f"
2463       and holf:  "f holomorphic_on interior (convex hull {a,b,c})"
2464      shows "(f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2465 proof -
2466   have fabc: "continuous_on (closed_segment a b) f" "continuous_on (closed_segment b c) f" "continuous_on (closed_segment c a) f"
2467     using contf continuous_on_subset segments_subset_convex_hull by metis+
2468   have "bounded (f ` (convex hull {a,b,c}))"
2469     by (simp add: compact_continuous_image compact_convex_hull compact_imp_bounded contf)
2470   then obtain B where "0 < B" and Bnf: "\<And>x. x \<in> convex hull {a,b,c} \<Longrightarrow> norm (f x) \<le> B"
2471      by (auto simp: dest!: bounded_pos [THEN iffD1])
2472   have "bounded (convex hull {a,b,c})"
2473     by (simp add: bounded_convex_hull)
2474   then obtain C where C: "0 < C" and Cno: "\<And>y. y \<in> convex hull {a,b,c} \<Longrightarrow> norm y < C"
2475     using bounded_pos_less by blast
2476   then have diff_2C: "norm(x - y) \<le> 2*C"
2477            if x: "x \<in> convex hull {a, b, c}" and y: "y \<in> convex hull {a, b, c}" for x y
2478   proof -
2479     have "cmod x \<le> C"
2480       using x by (meson Cno not_le not_less_iff_gr_or_eq)
2481     hence "cmod (x - y) \<le> C + C"
2482       using y by (meson Cno add_mono_thms_linordered_field(4) less_eq_real_def norm_triangle_ineq4 order_trans)
2483     thus "cmod (x - y) \<le> 2 * C"
2484       by (metis mult_2)
2485   qed
2486   have contf': "continuous_on (convex hull {b,a,c}) f"
2487     using contf by (simp add: insert_commute)
2488   { fix y::complex
2489     assume fy: "(f has_contour_integral y) (linepath a b +++ linepath b c +++ linepath c a)"
2490        and ynz: "y \<noteq> 0"
2491     have pi_eq_y: "contour_integral (linepath a b) f + contour_integral (linepath b c) f + contour_integral (linepath c a) f = y"
2492       by (rule has_chain_integral_chain_integral3 [OF fy])
2493     have ?thesis
2494     proof (cases "c=a \<or> a=b \<or> b=c")
2495       case True then show ?thesis
2496         using Cauchy_theorem_flat [OF contf, of 0]
2497         using has_chain_integral_chain_integral3 [OF fy] ynz
2498         by (force simp: fabc contour_integral_reverse_linepath)
2499     next
2500       case False
2501       then have car3: "card {a, b, c} = Suc (DIM(complex))"
2502         by auto
2503       { assume "interior(convex hull {a,b,c}) = {}"
2504         then have "collinear{a,b,c}"
2505           using interior_convex_hull_eq_empty [OF car3]
2506           by (simp add: collinear_3_eq_affine_dependent)
2507         with False obtain d where "c \<noteq> a" "a \<noteq> b" "b \<noteq> c" "c - b = d *\<^sub>R (a - b)"
2508           by (auto simp: collinear_3 collinear_lemma)
2509         then have "False"
2510           using False Cauchy_theorem_flat [OF contf'] pi_eq_y ynz
2511           by (simp add: fabc add_eq_0_iff contour_integral_reverse_linepath)
2512       }
2513       then obtain d where d: "d \<in> interior (convex hull {a, b, c})"
2514         by blast
2515       { fix d1
2516         assume d1_pos: "0 < d1"
2517            and d1: "\<And>x x'. \<lbrakk>x\<in>convex hull {a, b, c}; x'\<in>convex hull {a, b, c}; cmod (x' - x) < d1\<rbrakk>
2518                            \<Longrightarrow> cmod (f x' - f x) < cmod y / (24 * C)"
2519         define e where "e = min 1 (min (d1/(4*C)) ((norm y / 24 / C) / B))"
2520         define shrink where "shrink x = x - e *\<^sub>R (x - d)" for x
2521         let ?pathint = "\<lambda>x y. contour_integral(linepath x y) f"
2522         have e: "0 < e" "e \<le> 1" "e \<le> d1 / (4 * C)" "e \<le> cmod y / 24 / C / B"
2523           using d1_pos \<open>C>0\<close> \<open>B>0\<close> ynz by (simp_all add: e_def)
2524         then have eCB: "24 * e * C * B \<le> cmod y"
2525           using \<open>C>0\<close> \<open>B>0\<close>  by (simp add: field_simps)
2526         have e_le_d1: "e * (4 * C) \<le> d1"
2527           using e \<open>C>0\<close> by (simp add: field_simps)
2528         have "shrink a \<in> interior(convex hull {a,b,c})"
2529              "shrink b \<in> interior(convex hull {a,b,c})"
2530              "shrink c \<in> interior(convex hull {a,b,c})"
2531           using d e by (auto simp: hull_inc mem_interior_convex_shrink shrink_def)
2532         then have fhp0: "(f has_contour_integral 0)
2533                 (linepath (shrink a) (shrink b) +++ linepath (shrink b) (shrink c) +++ linepath (shrink c) (shrink a))"
2534           by (simp add: Cauchy_theorem_triangle holomorphic_on_subset [OF holf] hull_minimal)
2535         then have f_0_shrink: "?pathint (shrink a) (shrink b) + ?pathint (shrink b) (shrink c) + ?pathint (shrink c) (shrink a) = 0"
2536           by (simp add: has_chain_integral_chain_integral3)
2537         have fpi_abc: "f contour_integrable_on linepath (shrink a) (shrink b)"
2538                       "f contour_integrable_on linepath (shrink b) (shrink c)"
2539                       "f contour_integrable_on linepath (shrink c) (shrink a)"
2540           using fhp0  by (auto simp: valid_path_join dest: has_contour_integral_integrable)
2541         have cmod_shr: "\<And>x y. cmod (shrink y - shrink x - (y - x)) = e * cmod (x - y)"
2542           using e by (simp add: shrink_def real_vector.scale_right_diff_distrib [symmetric])
2543         have sh_eq: "\<And>a b d::complex. (b - e *\<^sub>R (b - d)) - (a - e *\<^sub>R (a - d)) - (b - a) = e *\<^sub>R (a - b)"
2544           by (simp add: algebra_simps)
2545         have "cmod y / (24 * C) \<le> cmod y / cmod (b - a) / 12"
2546           using False \<open>C>0\<close> diff_2C [of b a] ynz
2547           by (auto simp: divide_simps hull_inc)
2548         have less_C: "\<lbrakk>u \<in> convex hull {a, b, c}; 0 \<le> x; x \<le> 1\<rbrakk> \<Longrightarrow> x * cmod u < C" for x u
2549           apply (cases "x=0", simp add: \<open>0<C\<close>)
2550           using Cno [of u] mult_left_le_one_le [of "cmod u" x] le_less_trans norm_ge_zero by blast
2551         { fix u v
2552           assume uv: "u \<in> convex hull {a, b, c}" "v \<in> convex hull {a, b, c}" "u\<noteq>v"
2553              and fpi_uv: "f contour_integrable_on linepath (shrink u) (shrink v)"
2554           have shr_uv: "shrink u \<in> interior(convex hull {a,b,c})"
2555                        "shrink v \<in> interior(convex hull {a,b,c})"
2556             using d e uv
2557             by (auto simp: hull_inc mem_interior_convex_shrink shrink_def)
2558           have cmod_fuv: "\<And>x. 0\<le>x \<Longrightarrow> x\<le>1 \<Longrightarrow> cmod (f (linepath (shrink u) (shrink v) x)) \<le> B"
2559             using shr_uv by (blast intro: Bnf linepath_in_convex_hull interior_subset [THEN subsetD])
2560           have By_uv: "B * (12 * (e * cmod (u - v))) \<le> cmod y"
2561             apply (rule order_trans [OF _ eCB])
2562             using e \<open>B>0\<close> diff_2C [of u v] uv
2563             by (auto simp: field_simps)
2564           { fix x::real   assume x: "0\<le>x" "x\<le>1"
2565             have cmod_less_4C: "cmod ((1 - x) *\<^sub>R u - (1 - x) *\<^sub>R d) + cmod (x *\<^sub>R v - x *\<^sub>R d) < (C+C) + (C+C)"
2566               apply (rule add_strict_mono; rule norm_triangle_half_l [of _ 0])
2567               using uv x d interior_subset
2568               apply (auto simp: hull_inc intro!: less_C)
2569               done
2570             have ll: "linepath (shrink u) (shrink v) x - linepath u v x = -e * ((1 - x) *\<^sub>R (u - d) + x *\<^sub>R (v - d))"
2571               by (simp add: linepath_def shrink_def algebra_simps scaleR_conv_of_real)
2572             have cmod_less_dt: "cmod (linepath (shrink u) (shrink v) x - linepath u v x) < d1"
2573               apply (simp only: ll norm_mult scaleR_diff_right)
2574               using \<open>e>0\<close> cmod_less_4C apply (force intro: norm_triangle_lt less_le_trans [OF _ e_le_d1])
2575               done
2576             have "cmod (f (linepath (shrink u) (shrink v) x) - f (linepath u v x)) < cmod y / (24 * C)"
2577               using x uv shr_uv cmod_less_dt
2578               by (auto simp: hull_inc intro: d1 interior_subset [THEN subsetD] linepath_in_convex_hull)
2579             also have "\<dots> \<le> cmod y / cmod (v - u) / 12"
2580               using False uv \<open>C>0\<close> diff_2C [of v u] ynz
2581               by (auto simp: divide_simps hull_inc)
2582             finally have "cmod (f (linepath (shrink u) (shrink v) x) - f (linepath u v x)) \<le> cmod y / cmod (v - u) / 12"
2583               by simp
2584             then have cmod_12_le: "cmod (v - u) * cmod (f (linepath (shrink u) (shrink v) x) - f (linepath u v x)) * 12 \<le> cmod y"
2585               using uv False by (auto simp: field_simps)
2586             have "cmod (f (linepath (shrink u) (shrink v) x)) * cmod (shrink v - shrink u - (v - u)) +
2587                           cmod (v - u) * cmod (f (linepath (shrink u) (shrink v) x) - f (linepath u v x))
2588                           \<le> B * (cmod y / 24 / C / B * 2 * C) + 2 * C * (cmod y / 24 / C)"
2589               apply (rule add_mono [OF mult_mono])
2590               using By_uv e \<open>0 < B\<close> \<open>0 < C\<close> x apply (simp_all add: cmod_fuv cmod_shr cmod_12_le)
2591               apply (simp add: field_simps)
2592               done
2593             also have "\<dots> \<le> cmod y / 6"
2594               by simp
2595             finally have "cmod (f (linepath (shrink u) (shrink v) x)) * cmod (shrink v - shrink u - (v - u)) +
2596                           cmod (v - u) * cmod (f (linepath (shrink u) (shrink v) x) - f (linepath u v x))
2597                           \<le> cmod y / 6" .
2598           } note cmod_diff_le = this
2599           have f_uv: "continuous_on (closed_segment u v) f"
2600             by (blast intro: uv continuous_on_subset [OF contf closed_segment_subset_convex_hull])
2601           have **: "\<And>f' x' f x::complex. f'*x' - f*x = f'*(x' - x) + x*(f' - f)"
2602             by (simp add: algebra_simps)
2603           have "norm (?pathint (shrink u) (shrink v) - ?pathint u v)
2604                 \<le> (B*(norm y /24/C/B)*2*C + (2*C)*(norm y/24/C)) * content (cbox 0 (1::real))"
2605             apply (rule has_integral_bound
2606                     [of _ "\<lambda>x. f(linepath (shrink u) (shrink v) x) * (shrink v - shrink u) - f(linepath u v x)*(v - u)"
2607                         _ 0 1])
2608             using ynz \<open>0 < B\<close> \<open>0 < C\<close>
2609               apply (simp_all del: le_divide_eq_numeral1)
2610             apply (simp add: has_integral_diff has_contour_integral_linepath [symmetric] has_contour_integral_integral
2611                 fpi_uv f_uv contour_integrable_continuous_linepath)
2612             apply (auto simp: ** norm_triangle_le norm_mult cmod_diff_le simp del: le_divide_eq_numeral1)
2613             done
2614           also have "\<dots> \<le> norm y / 6"
2615             by simp
2616           finally have "norm (?pathint (shrink u) (shrink v) - ?pathint u v) \<le> norm y / 6" .
2617           } note * = this
2618           have "norm (?pathint (shrink a) (shrink b) - ?pathint a b) \<le> norm y / 6"
2619             using False fpi_abc by (rule_tac *) (auto simp: hull_inc)
2620           moreover
2621           have "norm (?pathint (shrink b) (shrink c) - ?pathint b c) \<le> norm y / 6"
2622             using False fpi_abc by (rule_tac *) (auto simp: hull_inc)
2623           moreover
2624           have "norm (?pathint (shrink c) (shrink a) - ?pathint c a) \<le> norm y / 6"
2625             using False fpi_abc by (rule_tac *) (auto simp: hull_inc)
2626           ultimately
2627           have "norm((?pathint (shrink a) (shrink b) - ?pathint a b) +
2628                      (?pathint (shrink b) (shrink c) - ?pathint b c) + (?pathint (shrink c) (shrink a) - ?pathint c a))
2629                 \<le> norm y / 6 + norm y / 6 + norm y / 6"
2630             by (metis norm_triangle_le add_mono)
2631           also have "\<dots> = norm y / 2"
2632             by simp
2633           finally have "norm((?pathint (shrink a) (shrink b) + ?pathint (shrink b) (shrink c) + ?pathint (shrink c) (shrink a)) -
2634                           (?pathint a b + ?pathint b c + ?pathint c a))
2635                 \<le> norm y / 2"
2636             by (simp add: algebra_simps)
2637           then
2638           have "norm(?pathint a b + ?pathint b c + ?pathint c a) \<le> norm y / 2"
2640           then have "False"
2641             using pi_eq_y ynz by auto
2642         }
2643         moreover have "uniformly_continuous_on (convex hull {a,b,c}) f"
2644           by (simp add: contf compact_convex_hull compact_uniformly_continuous)
2645         ultimately have "False"
2646           unfolding uniformly_continuous_on_def
2647           by (force simp: ynz \<open>0 < C\<close> dist_norm)
2648         then show ?thesis ..
2649       qed
2650   }
2651   moreover have "f contour_integrable_on (linepath a b +++ linepath b c +++ linepath c a)"
2652     using fabc contour_integrable_continuous_linepath by auto
2653   ultimately show ?thesis
2654     using has_contour_integral_integral by fastforce
2655 qed
2657 subsection%unimportant \<open>Version allowing finite number of exceptional points\<close>
2659 proposition%unimportant Cauchy_theorem_triangle_cofinite:
2660   assumes "continuous_on (convex hull {a,b,c}) f"
2661       and "finite S"
2662       and "(\<And>x. x \<in> interior(convex hull {a,b,c}) - S \<Longrightarrow> f field_differentiable (at x))"
2663      shows "(f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2664 using assms
2665 proof (induction "card S" arbitrary: a b c S rule: less_induct)
2666   case (less S a b c)
2667   show ?case
2668   proof (cases "S={}")
2669     case True with less show ?thesis
2670       by (fastforce simp: holomorphic_on_def field_differentiable_at_within Cauchy_theorem_triangle_interior)
2671   next
2672     case False
2673     then obtain d S' where d: "S = insert d S'" "d \<notin> S'"
2674       by (meson Set.set_insert all_not_in_conv)
2675     then show ?thesis
2676     proof (cases "d \<in> convex hull {a,b,c}")
2677       case False
2678       show "(f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2679       proof (rule less.hyps)
2680         show "\<And>x. x \<in> interior (convex hull {a, b, c}) - S' \<Longrightarrow> f field_differentiable at x"
2681         using False d interior_subset by (auto intro!: less.prems)
2682     qed (use d less.prems in auto)
2683     next
2684       case True
2685       have *: "convex hull {a, b, d} \<subseteq> convex hull {a, b, c}"
2686         by (meson True hull_subset insert_subset convex_hull_subset)
2687       have abd: "(f has_contour_integral 0) (linepath a b +++ linepath b d +++ linepath d a)"
2688       proof (rule less.hyps)
2689         show "\<And>x. x \<in> interior (convex hull {a, b, d}) - S' \<Longrightarrow> f field_differentiable at x"
2690           using d not_in_interior_convex_hull_3
2691           by (clarsimp intro!: less.prems) (metis * insert_absorb insert_subset interior_mono)
2692       qed (use d continuous_on_subset [OF  _ *] less.prems in auto)
2693       have *: "convex hull {b, c, d} \<subseteq> convex hull {a, b, c}"
2694         by (meson True hull_subset insert_subset convex_hull_subset)
2695       have bcd: "(f has_contour_integral 0) (linepath b c +++ linepath c d +++ linepath d b)"
2696       proof (rule less.hyps)
2697         show "\<And>x. x \<in> interior (convex hull {b, c, d}) - S' \<Longrightarrow> f field_differentiable at x"
2698           using d not_in_interior_convex_hull_3
2699           by (clarsimp intro!: less.prems) (metis * insert_absorb insert_subset interior_mono)
2700       qed (use d continuous_on_subset [OF  _ *] less.prems in auto)
2701       have *: "convex hull {c, a, d} \<subseteq> convex hull {a, b, c}"
2702         by (meson True hull_subset insert_subset convex_hull_subset)
2703       have cad: "(f has_contour_integral 0) (linepath c a +++ linepath a d +++ linepath d c)"
2704       proof (rule less.hyps)
2705         show "\<And>x. x \<in> interior (convex hull {c, a, d}) - S' \<Longrightarrow> f field_differentiable at x"
2706           using d not_in_interior_convex_hull_3
2707           by (clarsimp intro!: less.prems) (metis * insert_absorb insert_subset interior_mono)
2708       qed (use d continuous_on_subset [OF  _ *] less.prems in auto)
2709       have "f contour_integrable_on linepath a b"
2710         using less.prems abd contour_integrable_joinD1 contour_integrable_on_def by blast
2711       moreover have "f contour_integrable_on linepath b c"
2712         using less.prems bcd contour_integrable_joinD1 contour_integrable_on_def by blast
2713       moreover have "f contour_integrable_on linepath c a"
2714         using less.prems cad contour_integrable_joinD1 contour_integrable_on_def by blast
2715       ultimately have fpi: "f contour_integrable_on (linepath a b +++ linepath b c +++ linepath c a)"
2716         by auto
2717       { fix y::complex
2718         assume fy: "(f has_contour_integral y) (linepath a b +++ linepath b c +++ linepath c a)"
2719            and ynz: "y \<noteq> 0"
2720         have cont_ad: "continuous_on (closed_segment a d) f"
2721           by (meson "*" continuous_on_subset less.prems(1) segments_subset_convex_hull(3))
2722         have cont_bd: "continuous_on (closed_segment b d) f"
2723           by (meson True closed_segment_subset_convex_hull continuous_on_subset hull_subset insert_subset less.prems(1))
2724         have cont_cd: "continuous_on (closed_segment c d) f"
2725           by (meson "*" continuous_on_subset less.prems(1) segments_subset_convex_hull(2))
2726         have "contour_integral  (linepath a b) f = - (contour_integral (linepath b d) f + (contour_integral (linepath d a) f))"
2727              "contour_integral  (linepath b c) f = - (contour_integral (linepath c d) f + (contour_integral (linepath d b) f))"
2728              "contour_integral  (linepath c a) f = - (contour_integral (linepath a d) f + contour_integral (linepath d c) f)"
2729             using has_chain_integral_chain_integral3 [OF abd]
2730                   has_chain_integral_chain_integral3 [OF bcd]
2731                   has_chain_integral_chain_integral3 [OF cad]
2733         then have ?thesis
2734           using cont_ad cont_bd cont_cd fy has_chain_integral_chain_integral3 contour_integral_reverse_linepath by fastforce
2735       }
2736       then show ?thesis
2737         using fpi contour_integrable_on_def by blast
2738     qed
2739   qed
2740 qed
2742 subsection%unimportant \<open>Cauchy's theorem for an open starlike set\<close>
2744 lemma starlike_convex_subset:
2745   assumes S: "a \<in> S" "closed_segment b c \<subseteq> S" and subs: "\<And>x. x \<in> S \<Longrightarrow> closed_segment a x \<subseteq> S"
2746     shows "convex hull {a,b,c} \<subseteq> S"
2747       using S
2748       apply (clarsimp simp add: convex_hull_insert [of "{b,c}" a] segment_convex_hull)
2749       apply (meson subs convexD convex_closed_segment ends_in_segment(1) ends_in_segment(2) subsetCE)
2750       done
2752 lemma triangle_contour_integrals_starlike_primitive:
2753   assumes contf: "continuous_on S f"
2754       and S: "a \<in> S" "open S"
2755       and x: "x \<in> S"
2756       and subs: "\<And>y. y \<in> S \<Longrightarrow> closed_segment a y \<subseteq> S"
2757       and zer: "\<And>b c. closed_segment b c \<subseteq> S
2758                    \<Longrightarrow> contour_integral (linepath a b) f + contour_integral (linepath b c) f +
2759                        contour_integral (linepath c a) f = 0"
2760     shows "((\<lambda>x. contour_integral(linepath a x) f) has_field_derivative f x) (at x)"
2761 proof -
2762   let ?pathint = "\<lambda>x y. contour_integral(linepath x y) f"
2763   { fix e y
2764     assume e: "0 < e" and bxe: "ball x e \<subseteq> S" and close: "cmod (y - x) < e"
2765     have y: "y \<in> S"
2766       using bxe close  by (force simp: dist_norm norm_minus_commute)
2767     have cont_ayf: "continuous_on (closed_segment a y) f"
2768       using contf continuous_on_subset subs y by blast
2769     have xys: "closed_segment x y \<subseteq> S"
2770       apply (rule order_trans [OF _ bxe])
2771       using close
2772       by (auto simp: dist_norm ball_def norm_minus_commute dest: segment_bound)
2773     have "?pathint a y - ?pathint a x = ?pathint x y"
2774       using zer [OF xys]  contour_integral_reverse_linepath [OF cont_ayf]  add_eq_0_iff by force
2775   } note [simp] = this
2776   { fix e::real
2777     assume e: "0 < e"
2778     have cont_atx: "continuous (at x) f"
2779       using x S contf continuous_on_eq_continuous_at by blast
2780     then obtain d1 where d1: "d1>0" and d1_less: "\<And>y. cmod (y - x) < d1 \<Longrightarrow> cmod (f y - f x) < e/2"
2781       unfolding continuous_at Lim_at dist_norm  using e
2782       by (drule_tac x="e/2" in spec) force
2783     obtain d2 where d2: "d2>0" "ball x d2 \<subseteq> S" using  \<open>open S\<close> x
2784       by (auto simp: open_contains_ball)
2785     have dpos: "min d1 d2 > 0" using d1 d2 by simp
2786     { fix y
2787       assume yx: "y \<noteq> x" and close: "cmod (y - x) < min d1 d2"
2788       have y: "y \<in> S"
2789         using d2 close  by (force simp: dist_norm norm_minus_commute)
2790       have "closed_segment x y \<subseteq> S"
2791         using close d2  by (auto simp: dist_norm norm_minus_commute dest!: segment_bound(1))
2792       then have fxy: "f contour_integrable_on linepath x y"
2793         by (metis contour_integrable_continuous_linepath continuous_on_subset [OF contf])
2794       then obtain i where i: "(f has_contour_integral i) (linepath x y)"
2795         by (auto simp: contour_integrable_on_def)
2796       then have "((\<lambda>w. f w - f x) has_contour_integral (i - f x * (y - x))) (linepath x y)"
2797         by (rule has_contour_integral_diff [OF _ has_contour_integral_const_linepath])
2798       then have "cmod (i - f x * (y - x)) \<le> e / 2 * cmod (y - x)"
2799       proof (rule has_contour_integral_bound_linepath)
2800         show "\<And>u. u \<in> closed_segment x y \<Longrightarrow> cmod (f u - f x) \<le> e / 2"
2801           by (meson close d1_less le_less_trans less_imp_le min.strict_boundedE segment_bound1)
2802       qed (use e in simp)
2803       also have "\<dots> < e * cmod (y - x)"
2804         by (simp add: e yx)
2805       finally have "cmod (?pathint x y - f x * (y-x)) / cmod (y-x) < e"
2806         using i yx  by (simp add: contour_integral_unique divide_less_eq)
2807     }
2808     then have "\<exists>d>0. \<forall>y. y \<noteq> x \<and> cmod (y-x) < d \<longrightarrow> cmod (?pathint x y - f x * (y-x)) / cmod (y-x) < e"
2809       using dpos by blast
2810   }
2811   then have *: "(\<lambda>y. (?pathint x y - f x * (y - x)) /\<^sub>R cmod (y - x)) \<midarrow>x\<rightarrow> 0"
2812     by (simp add: Lim_at dist_norm inverse_eq_divide)
2813   show ?thesis
2814     apply (simp add: has_field_derivative_def has_derivative_at2 bounded_linear_mult_right)
2815     apply (rule Lim_transform [OF * Lim_eventually])
2816     using \<open>open S\<close> x apply (force simp: dist_norm open_contains_ball inverse_eq_divide [symmetric] eventually_at)
2817     done
2818 qed
2820 (** Existence of a primitive.*)
2821 lemma holomorphic_starlike_primitive:
2822   fixes f :: "complex \<Rightarrow> complex"
2823   assumes contf: "continuous_on S f"
2824       and S: "starlike S" and os: "open S"
2825       and k: "finite k"
2826       and fcd: "\<And>x. x \<in> S - k \<Longrightarrow> f field_differentiable at x"
2827     shows "\<exists>g. \<forall>x \<in> S. (g has_field_derivative f x) (at x)"
2828 proof -
2829   obtain a where a: "a\<in>S" and a_cs: "\<And>x. x\<in>S \<Longrightarrow> closed_segment a x \<subseteq> S"
2830     using S by (auto simp: starlike_def)
2831   { fix x b c
2832     assume "x \<in> S" "closed_segment b c \<subseteq> S"
2833     then have abcs: "convex hull {a, b, c} \<subseteq> S"
2834       by (simp add: a a_cs starlike_convex_subset)
2835     then have "continuous_on (convex hull {a, b, c}) f"
2836       by (simp add: continuous_on_subset [OF contf])
2837     then have "(f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2838       using abcs interior_subset by (force intro: fcd Cauchy_theorem_triangle_cofinite [OF _ k])
2839   } note 0 = this
2840   show ?thesis
2841     apply (intro exI ballI)
2842     apply (rule triangle_contour_integrals_starlike_primitive [OF contf a os], assumption)
2843     apply (metis a_cs)
2844     apply (metis has_chain_integral_chain_integral3 0)
2845     done
2846 qed
2848 lemma Cauchy_theorem_starlike:
2849  "\<lbrakk>open S; starlike S; finite k; continuous_on S f;
2850    \<And>x. x \<in> S - k \<Longrightarrow> f field_differentiable at x;
2851    valid_path g; path_image g \<subseteq> S; pathfinish g = pathstart g\<rbrakk>
2852    \<Longrightarrow> (f has_contour_integral 0)  g"
2853   by (metis holomorphic_starlike_primitive Cauchy_theorem_primitive at_within_open)
2855 lemma Cauchy_theorem_starlike_simple:
2856   "\<lbrakk>open S; starlike S; f holomorphic_on S; valid_path g; path_image g \<subseteq> S; pathfinish g = pathstart g\<rbrakk>
2857    \<Longrightarrow> (f has_contour_integral 0) g"
2858 apply (rule Cauchy_theorem_starlike [OF _ _ finite.emptyI])
2859 apply (simp_all add: holomorphic_on_imp_continuous_on)
2860 apply (metis at_within_open holomorphic_on_def)
2861 done
2863 subsection\<open>Cauchy's theorem for a convex set\<close>
2865 text\<open>For a convex set we can avoid assuming openness and boundary analyticity\<close>
2867 lemma triangle_contour_integrals_convex_primitive:
2868   assumes contf: "continuous_on S f"
2869       and S: "a \<in> S" "convex S"
2870       and x: "x \<in> S"
2871       and zer: "\<And>b c. \<lbrakk>b \<in> S; c \<in> S\<rbrakk>
2872                    \<Longrightarrow> contour_integral (linepath a b) f + contour_integral (linepath b c) f +
2873                        contour_integral (linepath c a) f = 0"
2874     shows "((\<lambda>x. contour_integral(linepath a x) f) has_field_derivative f x) (at x within S)"
2875 proof -
2876   let ?pathint = "\<lambda>x y. contour_integral(linepath x y) f"
2877   { fix y
2878     assume y: "y \<in> S"
2879     have cont_ayf: "continuous_on (closed_segment a y) f"
2880       using S y  by (meson contf continuous_on_subset convex_contains_segment)
2881     have xys: "closed_segment x y \<subseteq> S"  (*?*)
2882       using convex_contains_segment S x y by auto
2883     have "?pathint a y - ?pathint a x = ?pathint x y"
2884       using zer [OF x y]  contour_integral_reverse_linepath [OF cont_ayf]  add_eq_0_iff by force
2885   } note [simp] = this
2886   { fix e::real
2887     assume e: "0 < e"
2888     have cont_atx: "continuous (at x within S) f"
2889       using x S contf  by (simp add: continuous_on_eq_continuous_within)
2890     then obtain d1 where d1: "d1>0" and d1_less: "\<And>y. \<lbrakk>y \<in> S; cmod (y - x) < d1\<rbrakk> \<Longrightarrow> cmod (f y - f x) < e/2"
2891       unfolding continuous_within Lim_within dist_norm using e
2892       by (drule_tac x="e/2" in spec) force
2893     { fix y
2894       assume yx: "y \<noteq> x" and close: "cmod (y - x) < d1" and y: "y \<in> S"
2895       have fxy: "f contour_integrable_on linepath x y"
2896         using convex_contains_segment S x y
2897         by (blast intro!: contour_integrable_continuous_linepath continuous_on_subset [OF contf])
2898       then obtain i where i: "(f has_contour_integral i) (linepath x y)"
2899         by (auto simp: contour_integrable_on_def)
2900       then have "((\<lambda>w. f w - f x) has_contour_integral (i - f x * (y - x))) (linepath x y)"
2901         by (rule has_contour_integral_diff [OF _ has_contour_integral_const_linepath])
2902       then have "cmod (i - f x * (y - x)) \<le> e / 2 * cmod (y - x)"
2903       proof (rule has_contour_integral_bound_linepath)
2904         show "\<And>u. u \<in> closed_segment x y \<Longrightarrow> cmod (f u - f x) \<le> e / 2"
2905           by (meson assms(3) close convex_contains_segment d1_less le_less_trans less_imp_le segment_bound1 subset_iff x y)
2906       qed (use e in simp)
2907       also have "\<dots> < e * cmod (y - x)"
2908         by (simp add: e yx)
2909       finally have "cmod (?pathint x y - f x * (y-x)) / cmod (y-x) < e"
2910         using i yx  by (simp add: contour_integral_unique divide_less_eq)
2911     }
2912     then have "\<exists>d>0. \<forall>y\<in>S. y \<noteq> x \<and> cmod (y-x) < d \<longrightarrow> cmod (?pathint x y - f x * (y-x)) / cmod (y-x) < e"
2913       using d1 by blast
2914   }
2915   then have *: "((\<lambda>y. (contour_integral (linepath x y) f - f x * (y - x)) /\<^sub>R cmod (y - x)) \<longlongrightarrow> 0) (at x within S)"
2916     by (simp add: Lim_within dist_norm inverse_eq_divide)
2917   show ?thesis
2918     apply (simp add: has_field_derivative_def has_derivative_within bounded_linear_mult_right)
2919     apply (rule Lim_transform [OF * Lim_eventually])
2920     using linordered_field_no_ub
2921     apply (force simp: inverse_eq_divide [symmetric] eventually_at)
2922     done
2923 qed
2925 lemma contour_integral_convex_primitive:
2926   assumes "convex S" "continuous_on S f"
2927           "\<And>a b c. \<lbrakk>a \<in> S; b \<in> S; c \<in> S\<rbrakk> \<Longrightarrow> (f has_contour_integral 0) (linepath a b +++ linepath b c +++ linepath c a)"
2928   obtains g where "\<And>x. x \<in> S \<Longrightarrow> (g has_field_derivative f x) (at x within S)"
2929 proof (cases "S={}")
2930   case False
2931   with assms that show ?thesis
2932     by (blast intro: triangle_contour_integrals_convex_primitive has_chain_integral_chain_integral3)
2933 qed auto
2935 lemma holomorphic_convex_primitive:
2936   fixes f :: "complex \<Rightarrow> complex"
2937   assumes "convex S" "finite K" and contf: "continuous_on S f"
2938     and fd: "\<And>x. x \<in> interior S - K \<Longrightarrow> f field_differentiable at x"
2939   obtains g where "\<And>x. x \<in> S \<Longrightarrow> (g has_field_derivative f x) (at x within S)"
2940 proof (rule contour_integral_convex_primitive [OF \<open>convex S\<close> contf Cauchy_theorem_triangle_cofinite])
2941   have *: "convex hull {a, b, c} \<subseteq> S" if "a \<in> S" "b \<in> S" "c \<in> S" for a b c
2942     by (simp add: \<open>convex S\<close> hull_minimal that)
2943   show "continuous_on (convex hull {a, b, c}) f" if "a \<in> S" "b \<in> S" "c \<in> S" for a b c
2944     by (meson "*" contf continuous_on_subset that)
2945   show "f field_differentiable at x" if "a \<in> S" "b \<in> S" "c \<in> S" "x \<in> interior (convex hull {a, b, c}) - K" for a b c x
2946     by (metis "*" DiffD1 DiffD2 DiffI fd interior_mono subsetCE that)
2947 qed (use assms in \<open>force+\<close>)
2949 lemma holomorphic_convex_primitive':
2950   fixes f :: "complex \<Rightarrow> complex"
2951   assumes "convex S" and "open S" and "f holomorphic_on S"
2952   obtains g where "\<And>x. x \<in> S \<Longrightarrow> (g has_field_derivative f x) (at x within S)"
2953 proof (rule holomorphic_convex_primitive)
2954   fix x assume "x \<in> interior S - {}"
2955   with assms show "f field_differentiable at x"
2956     by (auto intro!: holomorphic_on_imp_differentiable_at simp: interior_open)
2957 qed (use assms in \<open>auto intro: holomorphic_on_imp_continuous_on\<close>)
2959 corollary%unimportant Cauchy_theorem_convex:
2960     "\<lbrakk>continuous_on S f; convex S; finite K;
2961       \<And>x. x \<in> interior S - K \<Longrightarrow> f field_differentiable at x;
2962       valid_path g; path_image g \<subseteq> S; pathfinish g = pathstart g\<rbrakk>
2963      \<Longrightarrow> (f has_contour_integral 0) g"
2964   by (metis holomorphic_convex_primitive Cauchy_theorem_primitive)
2966 corollary Cauchy_theorem_convex_simple:
2967     "\<lbrakk>f holomorphic_on S; convex S;
2968      valid_path g; path_image g \<subseteq> S;
2969      pathfinish g = pathstart g\<rbrakk> \<Longrightarrow> (f has_contour_integral 0) g"
2970   apply (rule Cauchy_theorem_convex [where K = "{}"])
2971   apply (simp_all add: holomorphic_on_imp_continuous_on)
2972   using at_within_interior holomorphic_on_def interior_subset by fastforce
2974 text\<open>In particular for a disc\<close>
2975 corollary%unimportant Cauchy_theorem_disc:
2976     "\<lbrakk>finite K; continuous_on (cball a e) f;
2977       \<And>x. x \<in> ball a e - K \<Longrightarrow> f field_differentiable at x;
2978      valid_path g; path_image g \<subseteq> cball a e;
2979      pathfinish g = pathstart g\<rbrakk> \<Longrightarrow> (f has_contour_integral 0) g"
2980   by (auto intro: Cauchy_theorem_convex)
2982 corollary%unimportant Cauchy_theorem_disc_simple:
2983     "\<lbrakk>f holomorphic_on (ball a e); valid_path g; path_image g \<subseteq> ball a e;
2984      pathfinish g = pathstart g\<rbrakk> \<Longrightarrow> (f has_contour_integral 0) g"
2985 by (simp add: Cauchy_theorem_convex_simple)
2987 subsection%unimportant \<open>Generalize integrability to local primitives\<close>
2989 lemma contour_integral_local_primitive_lemma:
2990   fixes f :: "complex\<Rightarrow>complex"
2991   shows
2992     "\<lbrakk>g piecewise_differentiable_on {a..b};
2993       \<And>x. x \<in> s \<Longrightarrow> (f has_field_derivative f' x) (at x within s);
2994       \<And>x. x \<in> {a..b} \<Longrightarrow> g x \<in> s\<rbrakk>
2995      \<Longrightarrow> (\<lambda>x. f' (g x) * vector_derivative g (at x within {a..b}))
2996             integrable_on {a..b}"
2997   apply (cases "cbox a b = {}", force)
2998   apply (simp add: integrable_on_def)
2999   apply (rule exI)
3000   apply (rule contour_integral_primitive_lemma, assumption+)
3001   using atLeastAtMost_iff by blast
3003 lemma contour_integral_local_primitive_any:
3004   fixes f :: "complex \<Rightarrow> complex"
3005   assumes gpd: "g piecewise_differentiable_on {a..b}"
3006       and dh: "\<And>x. x \<in> s
3007                \<Longrightarrow> \<exists>d h. 0 < d \<and>
3008                          (\<forall>y. norm(y - x) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
3009       and gs: "\<And>x. x \<in> {a..b} \<Longrightarrow> g x \<in> s"
3010   shows "(\<lambda>x. f(g x) * vector_derivative g (at x)) integrable_on {a..b}"
3011 proof -
3012   { fix x
3013     assume x: "a \<le> x" "x \<le> b"
3014     obtain d h where d: "0 < d"
3015                and h: "(\<And>y. norm(y - g x) < d \<Longrightarrow> (h has_field_derivative f y) (at y within s))"
3016       using x gs dh by (metis atLeastAtMost_iff)
3017     have "continuous_on {a..b} g" using gpd piecewise_differentiable_on_def by blast
3018     then obtain e where e: "e>0" and lessd: "\<And>x'. x' \<in> {a..b} \<Longrightarrow> \<bar>x' - x\<bar> < e \<Longrightarrow> cmod (g x' - g x) < d"
3019       using x d
3020       apply (auto simp: dist_norm continuous_on_iff)
3021       apply (drule_tac x=x in bspec)
3022       using x apply simp
3023       apply (drule_tac x=d in spec, auto)
3024       done
3025     have "\<exists>d>0. \<forall>u v. u \<le> x \<and> x \<le> v \<and> {u..v} \<subseteq> ball x d \<and> (u \<le> v \<longrightarrow> a \<le> u \<and> v \<le> b) \<longrightarrow>
3026                           (\<lambda>x. f (g x) * vector_derivative g (at x)) integrable_on {u..v}"
3027       apply (rule_tac x=e in exI)
3028       using e
3029       apply (simp add: integrable_on_localized_vector_derivative [symmetric], clarify)
3030       apply (rule_tac f = h and s = "g ` {u..v}" in contour_integral_local_primitive_lemma)
3031         apply (meson atLeastatMost_subset_iff gpd piecewise_differentiable_on_subset)
3032        apply (force simp: ball_def dist_norm intro: lessd gs DERIV_subset [OF h], force)
3033       done
3034   } then
3035   show ?thesis
3036     by (force simp: intro!: integrable_on_little_subintervals [of a b, simplified])
3037 qed
3039 lemma contour_integral_local_primitive:
3040   fixes f :: "complex \<Rightarrow> complex"
3041   assumes g: "valid_path g" "path_image g \<subseteq> s"
3042       and dh: "\<And>x. x \<in> s
3043                \<Longrightarrow> \<exists>d h. 0 < d \<and>
3044                          (\<forall>y. norm(y - x) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
3045   shows "f contour_integrable_on g"
3046   using g
3047   apply (simp add: valid_path_def path_image_def contour_integrable_on_def has_contour_integral_def
3048             has_integral_localized_vector_derivative integrable_on_def [symmetric])
3049   using contour_integral_local_primitive_any [OF _ dh]
3050   by (meson image_subset_iff piecewise_C1_imp_differentiable)
3053 text\<open>In particular if a function is holomorphic\<close>
3055 lemma contour_integrable_holomorphic:
3056   assumes contf: "continuous_on s f"
3057       and os: "open s"
3058       and k: "finite k"
3059       and g: "valid_path g" "path_image g \<subseteq> s"
3060       and fcd: "\<And>x. x \<in> s - k \<Longrightarrow> f field_differentiable at x"
3061     shows "f contour_integrable_on g"
3062 proof -
3063   { fix z
3064     assume z: "z \<in> s"
3065     obtain d where "d>0" and d: "ball z d \<subseteq> s" using  \<open>open s\<close> z
3066       by (auto simp: open_contains_ball)
3067     then have contfb: "continuous_on (ball z d) f"
3068       using contf continuous_on_subset by blast
3069     obtain h where "\<forall>y\<in>ball z d. (h has_field_derivative f y) (at y within ball z d)"
3070       by (metis holomorphic_convex_primitive [OF convex_ball k contfb fcd] d interior_subset Diff_iff set_mp)
3071     then have "\<forall>y\<in>ball z d. (h has_field_derivative f y) (at y within s)"
3072       by (metis open_ball at_within_open d os subsetCE)
3073     then have "\<exists>h. (\<forall>y. cmod (y - z) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
3074       by (force simp: dist_norm norm_minus_commute)
3075     then have "\<exists>d h. 0 < d \<and> (\<forall>y. cmod (y - z) < d \<longrightarrow> (h has_field_derivative f y) (at y within s))"
3076       using \<open>0 < d\<close> by blast
3077   }
3078   then show ?thesis
3079     by (rule contour_integral_local_primitive [OF g])
3080 qed
3082 lemma contour_integrable_holomorphic_simple:
3083   assumes fh: "f holomorphic_on S"
3084       and os: "open S"
3085       and g: "valid_path g" "path_image g \<subseteq> S"
3086     shows "f contour_integrable_on g"
3087   apply (rule contour_integrable_holomorphic [OF _ os Finite_Set.finite.emptyI g])
3088   apply (simp add: fh holomorphic_on_imp_continuous_on)
3089   using fh  by (simp add: field_differentiable_def holomorphic_on_open os)
3091 lemma continuous_on_inversediff:
3092   fixes z:: "'a::real_normed_field" shows "z \<notin> S \<Longrightarrow> continuous_on S (\<lambda>w. 1 / (w - z))"
3093   by (rule continuous_intros | force)+
3095 lemma contour_integrable_inversediff:
3096     "\<lbrakk>valid_path g; z \<notin> path_image g\<rbrakk> \<Longrightarrow> (\<lambda>w. 1 / (w-z)) contour_integrable_on g"
3097 apply (rule contour_integrable_holomorphic_simple [of _ "UNIV-{z}"])
3098 apply (auto simp: holomorphic_on_open open_delete intro!: derivative_eq_intros)
3099 done
3101 text\<open>Key fact that path integral is the same for a "nearby" path. This is the
3102  main lemma for the homotopy form of Cauchy's theorem and is also useful
3103  if we want "without loss of generality" to assume some nice properties of a
3104  path (e.g. smoothness). It can also be used to define the integrals of
3105  analytic functions over arbitrary continuous paths. This is just done for
3106  winding numbers now.
3107 \<close>
3109 text\<open>A technical definition to avoid duplication of similar proofs,
3110      for paths joined at the ends versus looping paths\<close>
3111 definition linked_paths :: "bool \<Rightarrow> (real \<Rightarrow> 'a) \<Rightarrow> (real \<Rightarrow> 'a::topological_space) \<Rightarrow> bool"
3112   where "linked_paths atends g h ==
3113         (if atends then pathstart h = pathstart g \<and> pathfinish h = pathfinish g
3114                    else pathfinish g = pathstart g \<and> pathfinish h = pathstart h)"
3116 text\<open>This formulation covers two cases: @{term g} and @{term h} share their
3117       start and end points; @{term g} and @{term h} both loop upon themselves.\<close>
3118 lemma contour_integral_nearby:
3119   assumes os: "open S" and p: "path p" "path_image p \<subseteq> S"
3120   shows "\<exists>d. 0 < d \<and>
3121             (\<forall>g h. valid_path g \<and> valid_path h \<and>
3122                   (\<forall>t \<in> {0..1}. norm(g t - p t) < d \<and> norm(h t - p t) < d) \<and>
3123                   linked_paths atends g h
3124                   \<longrightarrow> path_image g \<subseteq> S \<and> path_image h \<subseteq> S \<and>
3125                       (\<forall>f. f holomorphic_on S \<longrightarrow> contour_integral h f = contour_integral g f))"
3126 proof -
3127   have "\<forall>z. \<exists>e. z \<in> path_image p \<longrightarrow> 0 < e \<and> ball z e \<subseteq> S"
3128     using open_contains_ball os p(2) by blast
3129   then obtain ee where ee: "\<And>z. z \<in> path_image p \<Longrightarrow> 0 < ee z \<and> ball z (ee z) \<subseteq> S"
3130     by metis
3131   define cover where "cover = (\<lambda>z. ball z (ee z/3)) ` (path_image p)"
3132   have "compact (path_image p)"
3133     by (metis p(1) compact_path_image)
3134   moreover have "path_image p \<subseteq> (\<Union>c\<in>path_image p. ball c (ee c / 3))"
3135     using ee by auto
3136   ultimately have "\<exists>D \<subseteq> cover. finite D \<and> path_image p \<subseteq> \<Union>D"
3137     by (simp add: compact_eq_Heine_Borel cover_def)
3138   then obtain D where D: "D \<subseteq> cover" "finite D" "path_image p \<subseteq> \<Union>D"
3139     by blast
3140   then obtain k where k: "k \<subseteq> {0..1}" "finite k" and D_eq: "D = ((\<lambda>z. ball z (ee z / 3)) \<circ> p) ` k"
3141     apply (simp add: cover_def path_image_def image_comp)
3142     apply (blast dest!: finite_subset_image [OF \<open>finite D\<close>])
3143     done
3144   then have kne: "k \<noteq> {}"
3145     using D by auto
3146   have pi: "\<And>i. i \<in> k \<Longrightarrow> p i \<in> path_image p"
3147     using k  by (auto simp: path_image_def)
3148   then have eepi: "\<And>i. i \<in> k \<Longrightarrow> 0 < ee((p i))"
3149     by (metis ee)
3150   define e where "e = Min((ee \<circ> p) ` k)"
3151   have fin_eep: "finite ((ee \<circ> p) ` k)"
3152     using k  by blast
3153   have "0 < e"
3154     using ee k  by (simp add: kne e_def Min_gr_iff [OF fin_eep] eepi)
3155   have "uniformly_continuous_on {0..1} p"
3156     using p  by (simp add: path_def compact_uniformly_continuous)
3157   then obtain d::real where d: "d>0"
3158           and de: "\<And>x x'. \<bar>x' - x\<bar> < d \<Longrightarrow> x\<in>{0..1} \<Longrightarrow> x'\<in>{0..1} \<Longrightarrow> cmod (p x' - p x) < e/3"
3159     unfolding uniformly_continuous_on_def dist_norm real_norm_def
3160     by (metis divide_pos_pos \<open>0 < e\<close> zero_less_numeral)
3161   then obtain N::nat where N: "N>0" "inverse N < d"
3162     using real_arch_inverse [of d]   by auto
3163   show ?thesis
3164   proof (intro exI conjI allI; clarify?)
3165     show "e/3 > 0"
3166       using \<open>0 < e\<close> by simp
3167     fix g h
3168     assume g: "valid_path g" and ghp: "\<forall>t\<in>{0..1}. cmod (g t - p t) < e / 3 \<and>  cmod (h t - p t) < e / 3"
3169        and h: "valid_path h"
3170        and joins: "linked_paths atends g h"
3171     { fix t::real
3172       assume t: "0 \<le> t" "t \<le> 1"
3173       then obtain u where u: "u \<in> k" and ptu: "p t \<in> ball(p u) (ee(p u) / 3)"
3174         using \<open>path_image p \<subseteq> \<Union>D\<close> D_eq by (force simp: path_image_def)
3175       then have ele: "e \<le> ee (p u)" using fin_eep
3176         by (simp add: e_def)
3177       have "cmod (g t - p t) < e / 3" "cmod (h t - p t) < e / 3"
3178         using ghp t by auto
3179       with ele have "cmod (g t - p t) < ee (p u) / 3"
3180                     "cmod (h t - p t) < ee (p u) / 3"
3181         by linarith+
3182       then have "g t \<in> ball(p u) (ee(p u))"  "h t \<in> ball(p u) (ee(p u))"
3183         using norm_diff_triangle_ineq [of "g t" "p t" "p t" "p u"]
3184               norm_diff_triangle_ineq [of "h t" "p t" "p t" "p u"] ptu eepi u
3185         by (force simp: dist_norm ball_def norm_minus_commute)+
3186       then have "g t \<in> S" "h t \<in> S" using ee u k
3187         by (auto simp: path_image_def ball_def)
3188     }
3189     then have ghs: "path_image g \<subseteq> S" "path_image h \<subseteq> S"
3190       by (auto simp: path_image_def)
3191     moreover
3192     { fix f
3193       assume fhols: "f holomorphic_on S"
3194       then have fpa: "f contour_integrable_on g"  "f contour_integrable_on h"
3195         using g ghs h holomorphic_on_imp_continuous_on os contour_integrable_holomorphic_simple
3196         by blast+
3197       have contf: "continuous_on S f"
3198         by (simp add: fhols holomorphic_on_imp_continuous_on)
3199       { fix z
3200         assume z: "z \<in> path_image p"
3201         have "f holomorphic_on ball z (ee z)"
3202           using fhols ee z holomorphic_on_subset by blast
3203         then have "\<exists>ff. (\<forall>w \<in> ball z (ee z). (ff has_field_derivative f w) (at w))"
3204           using holomorphic_convex_primitive [of "ball z (ee z)" "{}" f, simplified]
3205           by (metis open_ball at_within_open holomorphic_on_def holomorphic_on_imp_continuous_on mem_ball)
3206       }
3207       then obtain ff where ff:
3208             "\<And>z w. \<lbrakk>z \<in> path_image p; w \<in> ball z (ee z)\<rbrakk> \<Longrightarrow> (ff z has_field_derivative f w) (at w)"
3209         by metis
3210       { fix n
3211         assume n: "n \<le> N"
3212         then have "contour_integral(subpath 0 (n/N) h) f - contour_integral(subpath 0 (n/N) g) f =
3213                    contour_integral(linepath (g(n/N)) (h(n/N))) f - contour_integral(linepath (g 0) (h 0)) f"
3214         proof (induct n)
3215           case 0 show ?case by simp
3216         next
3217           case (Suc n)
3218           obtain t where t: "t \<in> k" and "p (n/N) \<in> ball(p t) (ee(p t) / 3)"
3219             using \<open>path_image p \<subseteq> \<Union>D\<close> [THEN subsetD, where c="p (n/N)"] D_eq N Suc.prems
3220             by (force simp: path_image_def)
3221           then have ptu: "cmod (p t - p (n/N)) < ee (p t) / 3"
3222             by (simp add: dist_norm)
3223           have e3le: "e/3 \<le> ee (p t) / 3"  using fin_eep t
3224             by (simp add: e_def)
3225           { fix x
3226             assume x: "n/N \<le> x" "x \<le> (1 + n)/N"
3227             then have nN01: "0 \<le> n/N" "(1 + n)/N \<le> 1"
3228               using Suc.prems by auto
3229             then have x01: "0 \<le> x" "x \<le> 1"
3230               using x by linarith+
3231             have "cmod (p t - p x)  < ee (p t) / 3 + e/3"
3232             proof (rule norm_diff_triangle_less [OF ptu de])
3233               show "\<bar>real n / real N - x\<bar> < d"
3234                 using x N by (auto simp: field_simps)
3235             qed (use x01 Suc.prems in auto)
3236             then have ptx: "cmod (p t - p x) < 2*ee (p t)/3"
3237               using e3le eepi [OF t] by simp
3238             have "cmod (p t - g x) < 2*ee (p t)/3 + e/3 "
3239               apply (rule norm_diff_triangle_less [OF ptx])
3240               using ghp x01 by (simp add: norm_minus_commute)
3241             also have "\<dots> \<le> ee (p t)"
3242               using e3le eepi [OF t] by simp
3243             finally have gg: "cmod (p t - g x) < ee (p t)" .
3244             have "cmod (p t - h x) < 2*ee (p t)/3 + e/3 "
3245               apply (rule norm_diff_triangle_less [OF ptx])
3246               using ghp x01 by (simp add: norm_minus_commute)
3247             also have "\<dots> \<le> ee (p t)"
3248               using e3le eepi [OF t] by simp
3249             finally have "cmod (p t - g x) < ee (p t)"
3250                          "cmod (p t - h x) < ee (p t)"
3251               using gg by auto
3252           } note ptgh_ee = this
3253           have "closed_segment (g (real n / real N)) (h (real n / real N)) = path_image (linepath (h (n/N)) (g (n/N)))"
3254             by (simp add: closed_segment_commute)
3255           also have pi_hgn: "\<dots> \<subseteq> ball (p t) (ee (p t))"
3256             using ptgh_ee [of "n/N"] Suc.prems
3257             by (auto simp: field_simps dist_norm dest: segment_furthest_le [where y="p t"])
3258           finally have gh_ns: "closed_segment (g (n/N)) (h (n/N)) \<subseteq> S"
3259             using ee pi t by blast
3260           have pi_ghn': "path_image (linepath (g ((1 + n) / N)) (h ((1 + n) / N))) \<subseteq> ball (p t) (ee (p t))"
3261             using ptgh_ee [of "(1+n)/N"] Suc.prems
3262             by (auto simp: field_simps dist_norm dest: segment_furthest_le [where y="p t"])
3263           then have gh_n's: "closed_segment (g ((1 + n) / N)) (h ((1 + n) / N)) \<subseteq> S"
3264             using \<open>N>0\<close> Suc.prems ee pi t
3265             by (auto simp: Path_Connected.path_image_join field_simps)
3266           have pi_subset_ball:
3267                 "path_image (subpath (n/N) ((1+n) / N) g +++ linepath (g ((1+n) / N)) (h ((1+n) / N)) +++
3268                              subpath ((1+n) / N) (n/N) h +++ linepath (h (n/N)) (g (n/N)))
3269                  \<subseteq> ball (p t) (ee (p t))"
3270             apply (intro subset_path_image_join pi_hgn pi_ghn')
3271             using \<open>N>0\<close> Suc.prems
3272             apply (auto simp: path_image_subpath dist_norm field_simps closed_segment_eq_real_ivl ptgh_ee)
3273             done
3274           have pi0: "(f has_contour_integral 0)
3275                        (subpath (n/ N) ((Suc n)/N) g +++ linepath(g ((Suc n) / N)) (h((Suc n) / N)) +++
3276                         subpath ((Suc n) / N) (n/N) h +++ linepath(h (n/N)) (g (n/N)))"
3277             apply (rule Cauchy_theorem_primitive [of "ball(p t) (ee(p t))" "ff (p t)" "f"])
3278             apply (metis ff open_ball at_within_open pi t)
3279             using Suc.prems pi_subset_ball apply (simp_all add: valid_path_join valid_path_subpath g h)
3280             done
3281           have fpa1: "f contour_integrable_on subpath (real n / real N) (real (Suc n) / real N) g"
3282             using Suc.prems by (simp add: contour_integrable_subpath g fpa)
3283           have fpa2: "f contour_integrable_on linepath (g (real (Suc n) / real N)) (h (real (Suc n) / real N))"
3284             using gh_n's
3285             by (auto intro!: contour_integrable_continuous_linepath continuous_on_subset [OF contf])
3286           have fpa3: "f contour_integrable_on linepath (h (real n / real N)) (g (real n / real N))"
3287             using gh_ns
3288             by (auto simp: closed_segment_commute intro!: contour_integrable_continuous_linepath continuous_on_subset [OF contf])
3289           have eq0: "contour_integral (subpath (n/N) ((Suc n) / real N) g) f +
3290                      contour_integral (linepath (g ((Suc n) / N)) (h ((Suc n) / N))) f +
3291                      contour_integral (subpath ((Suc n) / N) (n/N) h) f +
3292                      contour_integral (linepath (h (n/N)) (g (n/N))) f = 0"
3293             using contour_integral_unique [OF pi0] Suc.prems
3294             by (simp add: g h fpa valid_path_subpath contour_integrable_subpath
3295                           fpa1 fpa2 fpa3 algebra_simps del: of_nat_Suc)
3296           have *: "\<And>hn he hn' gn gd gn' hgn ghn gh0 ghn'.
3297                     \<lbrakk>hn - gn = ghn - gh0;
3298                      gd + ghn' + he + hgn = (0::complex);
3299                      hn - he = hn'; gn + gd = gn'; hgn = -ghn\<rbrakk> \<Longrightarrow> hn' - gn' = ghn' - gh0"
3300             by (auto simp: algebra_simps)
3301           have "contour_integral (subpath 0 (n/N) h) f - contour_integral (subpath ((Suc n) / N) (n/N) h) f =
3302                 contour_integral (subpath 0 (n/N) h) f + contour_integral (subpath (n/N) ((Suc n) / N) h) f"
3303             unfolding reversepath_subpath [symmetric, of "((Suc n) / N)"]
3304             using Suc.prems by (simp add: h fpa contour_integral_reversepath valid_path_subpath contour_integrable_subpath)
3305           also have "\<dots> = contour_integral (subpath 0 ((Suc n) / N) h) f"
3306             using Suc.prems by (simp add: contour_integral_subpath_combine h fpa)
3307           finally have pi0_eq:
3308                "contour_integral (subpath 0 (n/N) h) f - contour_integral (subpath ((Suc n) / N) (n/N) h) f =
3309                 contour_integral (subpath 0 ((Suc n) / N) h) f" .
3310           show ?case
3311             apply (rule * [OF Suc.hyps eq0 pi0_eq])
3312             using Suc.prems
3313             apply (simp_all add: g h fpa contour_integral_subpath_combine
3314                      contour_integral_reversepath [symmetric] contour_integrable_continuous_linepath
3315                      continuous_on_subset [OF contf gh_ns])
3316             done
3317       qed
3318       } note ind = this
3319       have "contour_integral h f = contour_integral g f"
3320         using ind [OF order_refl] N joins
3321         by (simp add: linked_paths_def pathstart_def pathfinish_def split: if_split_asm)
3322     }
3323     ultimately
3324     show "path_image g \<subseteq> S \<and> path_image h \<subseteq> S \<and> (\<forall>f. f holomorphic_on S \<longrightarrow> contour_integral h f = contour_integral g f)"
3325       by metis
3326   qed
3327 qed
3330 lemma
3331   assumes "open S" "path p" "path_image p \<subseteq> S"
3332     shows contour_integral_nearby_ends:
3333       "\<exists>d. 0 < d \<and>
3334               (\<forall>g h. valid_path g \<and> valid_path h \<and>
3335                     (\<forall>t \<in> {0..1}. norm(g t - p t) < d \<and> norm(h t - p t) < d) \<and>
3336                     pathstart h = pathstart g \<and> pathfinish h = pathfinish g
3337                     \<longrightarrow> path_image g \<subseteq> S \<and>
3338                         path_image h \<subseteq> S \<and>
3339                         (\<forall>f. f holomorphic_on S
3340                             \<longrightarrow> contour_integral h f = contour_integral g f))"
3341     and contour_integral_nearby_loops:
3342       "\<exists>d. 0 < d \<and>
3343               (\<forall>g h. valid_path g \<and> valid_path h \<and>
3344                     (\<forall>t \<in> {0..1}. norm(g t - p t) < d \<and> norm(h t - p t) < d) \<and>
3345                     pathfinish g = pathstart g \<and> pathfinish h = pathstart h
3346                     \<longrightarrow> path_image g \<subseteq> S \<and>
3347                         path_image h \<subseteq> S \<and>
3348                         (\<forall>f. f holomorphic_on S
3349                             \<longrightarrow> contour_integral h f = contour_integral g f))"
3350   using contour_integral_nearby [OF assms, where atends=True]
3351   using contour_integral_nearby [OF assms, where atends=False]
3352   unfolding linked_paths_def by simp_all
3354 lemma C1_differentiable_polynomial_function:
3355   fixes p :: "real \<Rightarrow> 'a::euclidean_space"
3356   shows "polynomial_function p \<Longrightarrow> p C1_differentiable_on S"
3357   by (metis continuous_on_polymonial_function C1_differentiable_on_def  has_vector_derivative_polynomial_function)
3359 lemma valid_path_polynomial_function:
3360   fixes p :: "real \<Rightarrow> 'a::euclidean_space"
3361   shows "polynomial_function p \<Longrightarrow> valid_path p"
3362 by (force simp: valid_path_def piecewise_C1_differentiable_on_def continuous_on_polymonial_function C1_differentiable_polynomial_function)
3364 lemma valid_path_subpath_trivial [simp]:
3365     fixes g :: "real \<Rightarrow> 'a::euclidean_space"
3366     shows "z \<noteq> g x \<Longrightarrow> valid_path (subpath x x g)"
3367   by (simp add: subpath_def valid_path_polynomial_function)
3369 lemma contour_integral_bound_exists:
3370 assumes S: "open S"
3371     and g: "valid_path g"
3372     and pag: "path_image g \<subseteq> S"
3373   shows "\<exists>L. 0 < L \<and>
3374              (\<forall>f B. f holomorphic_on S \<and> (\<forall>z \<in> S. norm(f z) \<le> B)
3375                \<longrightarrow> norm(contour_integral g f) \<le> L*B)"
3376 proof -
3377   have "path g" using g
3378     by (simp add: valid_path_imp_path)
3379   then obtain d::real and p
3380     where d: "0 < d"
3381       and p: "polynomial_function p" "path_image p \<subseteq> S"
3382       and pi: "\<And>f. f holomorphic_on S \<Longrightarrow> contour_integral g f = contour_integral p f"
3383     using contour_integral_nearby_ends [OF S \<open>path g\<close> pag]
3384     apply clarify
3385     apply (drule_tac x=g in spec)
3386     apply (simp only: assms)
3387     apply (force simp: valid_path_polynomial_function dest: path_approx_polynomial_function)
3388     done
3389   then obtain p' where p': "polynomial_function p'"
3390     "\<And>x. (p has_vector_derivative (p' x)) (at x)"
3391     by (blast intro: has_vector_derivative_polynomial_function that)
3392   then have "bounded(p' ` {0..1})"
3393     using continuous_on_polymonial_function
3394     by (force simp: intro!: compact_imp_bounded compact_continuous_image)
3395   then obtain L where L: "L>0" and nop': "\<And>x. \<lbrakk>0 \<le> x; x \<le> 1\<rbrakk> \<Longrightarrow> norm (p' x) \<le> L"
3396     by (force simp: bounded_pos)
3397   { fix f B
3398     assume f: "f holomorphic_on S" and B: "\<And>z. z\<in>S \<Longrightarrow> cmod (f z) \<le> B"
3399     then have "f contour_integrable_on p \<and> valid_path p"
3400       using p S
3401       by (blast intro: valid_path_polynomial_function contour_integrable_holomorphic_simple holomorphic_on_imp_continuous_on)
3402     moreover have "cmod (vector_derivative p (at x)) * cmod (f (p x)) \<le> L * B" if "0 \<le> x" "x \<le> 1" for x
3403     proof (rule mult_mono)
3404       show "cmod (vector_derivative p (at x)) \<le> L"
3405         by (metis nop' p'(2) that vector_derivative_at)
3406       show "cmod (f (p x)) \<le> B"
3407         by (metis B atLeastAtMost_iff imageI p(2) path_defs(4) subset_eq that)
3408     qed (use \<open>L>0\<close> in auto)
3409     ultimately have "cmod (contour_integral g f) \<le> L * B"
3410       apply (simp only: pi [OF f])
3411       apply (simp only: contour_integral_integral)
3412       apply (rule order_trans [OF integral_norm_bound_integral])
3413          apply (auto simp: mult.commute integral_norm_bound_integral contour_integrable_on [symmetric] norm_mult)
3414       done
3415   } then
3416   show ?thesis
3417     by (force simp: L contour_integral_integral)
3418 qed
3420 text\<open>We can treat even non-rectifiable paths as having a "length" for bounds on analytic functions in open sets.\<close>
3422 subsection \<open>Winding Numbers\<close>
3424 definition%important winding_number_prop :: "[real \<Rightarrow> complex, complex, real, real \<Rightarrow> complex, complex] \<Rightarrow> bool" where
3425   "winding_number_prop \<gamma> z e p n \<equiv>
3426       valid_path p \<and> z \<notin> path_image p \<and>
3427       pathstart p = pathstart \<gamma> \<and>
3428       pathfinish p = pathfinish \<gamma> \<and>
3429       (\<forall>t \<in> {0..1}. norm(\<gamma> t - p t) < e) \<and>
3430       contour_integral p (\<lambda>w. 1/(w - z)) = 2 * pi * \<i> * n"
3432 definition%important winding_number:: "[real \<Rightarrow> complex, complex] \<Rightarrow> complex" where
3433   "winding_number \<gamma> z \<equiv> SOME n. \<forall>e > 0. \<exists>p. winding_number_prop \<gamma> z e p n"
3436 lemma winding_number:
3437   assumes "path \<gamma>" "z \<notin> path_image \<gamma>" "0 < e"
3438     shows "\<exists>p. winding_number_prop \<gamma> z e p (winding_number \<gamma> z)"
3439 proof -
3440   have "path_image \<gamma> \<subseteq> UNIV - {z}"
3441     using assms by blast
3442   then obtain d
3443     where d: "d>0"
3444       and pi_eq: "\<And>h1 h2. valid_path h1 \<and> valid_path h2 \<and>
3445                     (\<forall>t\<in>{0..1}. cmod (h1 t - \<gamma> t) < d \<and> cmod (h2 t - \<gamma> t) < d) \<and>
3446                     pathstart h2 = pathstart h1 \<and> pathfinish h2 = pathfinish h1 \<longrightarrow>
3447                       path_image h1 \<subseteq> UNIV - {z} \<and> path_image h2 \<subseteq> UNIV - {z} \<and>
3448                       (\<forall>f. f holomorphic_on UNIV - {z} \<longrightarrow> contour_integral h2 f = contour_integral h1 f)"
3449     using contour_integral_nearby_ends [of "UNIV - {z}" \<gamma>] assms by (auto simp: open_delete)
3450   then obtain h where h: "polynomial_function h \<and> pathstart h = pathstart \<gamma> \<and> pathfinish h = pathfinish \<gamma> \<and>
3451                           (\<forall>t \<in> {0..1}. norm(h t - \<gamma> t) < d/2)"
3452     using path_approx_polynomial_function [OF \<open>path \<gamma>\<close>, of "d/2"] d by auto
3453   define nn where "nn = 1/(2* pi*\<i>) * contour_integral h (\<lambda>w. 1/(w - z))"
3454   have "\<exists>n. \<forall>e > 0. \<exists>p. winding_number_prop \<gamma> z e p n"
3455     proof (rule_tac x=nn in exI, clarify)
3456       fix e::real
3457       assume e: "e>0"
3458       obtain p where p: "polynomial_function p \<and>
3459             pathstart p = pathstart \<gamma> \<and> pathfinish p = pathfinish \<gamma> \<and> (\<forall>t\<in>{0..1}. cmod (p t - \<gamma> t) < min e (d/2))"
3460         using path_approx_polynomial_function [OF \<open>path \<gamma>\<close>, of "min e (d/2)"] d \<open>0<e\<close> by auto
3461       have "(\<lambda>w. 1 / (w - z)) holomorphic_on UNIV - {z}"
3462         by (auto simp: intro!: holomorphic_intros)
3463       then show "\<exists>p. winding_number_prop \<gamma> z e p nn"
3464         apply (rule_tac x=p in exI)
3465         using pi_eq [of h p] h p d
3466         apply (auto simp: valid_path_polynomial_function norm_minus_commute nn_def winding_number_prop_def)
3467         done
3468     qed
3469   then show ?thesis
3470     unfolding winding_number_def by (rule someI2_ex) (blast intro: \<open>0<e\<close>)
3471 qed
3473 lemma winding_number_unique:
3474   assumes \<gamma>: "path \<gamma>" "z \<notin> path_image \<gamma>"
3475       and pi: "\<And>e. e>0 \<Longrightarrow> \<exists>p. winding_number_prop \<gamma> z e p n"
3476    shows "winding_number \<gamma> z = n"
3477 proof -
3478   have "path_image \<gamma> \<subseteq> UNIV - {z}"
3479     using assms by blast
3480   then obtain e
3481     where e: "e>0"
3482       and pi_eq: "\<And>h1 h2 f. \<lbrakk>valid_path h1; valid_path h2;
3483                     (\<forall>t\<in>{0..1}. cmod (h1 t - \<gamma> t) < e \<and> cmod (h2 t - \<gamma> t) < e);
3484                     pathstart h2 = pathstart h1; pathfinish h2 = pathfinish h1; f holomorphic_on UNIV - {z}\<rbrakk> \<Longrightarrow>
3485                     contour_integral h2 f = contour_integral h1 f"
3486     using contour_integral_nearby_ends [of "UNIV - {z}" \<gamma>] assms  by (auto simp: open_delete)
3487   obtain p where p: "winding_number_prop \<gamma> z e p n"
3488     using pi [OF e] by blast
3489   obtain q where q: "winding_number_prop \<gamma> z e q (winding_number \<gamma> z)"
3490     using winding_number [OF \<gamma> e] by blast
3491   have "2 * complex_of_real pi * \<i> * n = contour_integral p (\<lambda>w. 1 / (w - z))"
3492     using p by (auto simp: winding_number_prop_def)
3493   also have "\<dots> = contour_integral q (\<lambda>w. 1 / (w - z))"
3494   proof (rule pi_eq)
3495     show "(\<lambda>w. 1 / (w - z)) holomorphic_on UNIV - {z}"
3496       by (auto intro!: holomorphic_intros)
3497   qed (use p q in \<open>auto simp: winding_number_prop_def norm_minus_commute\<close>)
3498   also have "\<dots> = 2 * complex_of_real pi * \<i> * winding_number \<gamma> z"
3499     using q by (auto simp: winding_number_prop_def)
3500   finally have "2 * complex_of_real pi * \<i> * n = 2 * complex_of_real pi * \<i> * winding_number \<gamma> z" .
3501   then show ?thesis
3502     by simp
3503 qed
3505 (*NB not winding_number_prop here due to the loop in p*)
3506 lemma winding_number_unique_loop:
3507   assumes \<gamma>: "path \<gamma>" "z \<notin> path_image \<gamma>"
3508       and loop: "pathfinish \<gamma> = pathstart \<gamma>"
3509       and pi:
3510         "\<And>e. e>0 \<Longrightarrow> \<exists>p. valid_path p \<and> z \<notin> path_image p \<and>
3511                            pathfinish p = pathstart p \<and>
3512                            (\<forall>t \<in> {0..1}. norm (\<gamma> t - p t) < e) \<and>
3513                            contour_integral p (\<lambda>w. 1/(w - z)) = 2 * pi * \<i> * n"
3514    shows "winding_number \<gamma> z = n"
3515 proof -
3516   have "path_image \<gamma> \<subseteq> UNIV - {z}"
3517     using assms by blast
3518   then obtain e
3519     where e: "e>0"
3520       and pi_eq: "\<And>h1 h2 f. \<lbrakk>valid_path h1; valid_path h2;
3521                     (\<forall>t\<in>{0..1}. cmod (h1 t - \<gamma> t) < e \<and> cmod (h2 t - \<gamma> t) < e);
3522                     pathfinish h1 = pathstart h1; pathfinish h2 = pathstart h2; f holomorphic_on UNIV - {z}\<rbrakk> \<Longrightarrow>
3523                     contour_integral h2 f = contour_integral h1 f"
3524     using contour_integral_nearby_loops [of "UNIV - {z}" \<gamma>] assms  by (auto simp: open_delete)
3525   obtain p where p:
3526      "valid_path p \<and> z \<notin> path_image p \<and> pathfinish p = pathstart p \<and>
3527       (\<forall>t \<in> {0..1}. norm (\<gamma> t - p t) < e) \<and>
3528       contour_integral p (\<lambda>w. 1/(w - z)) = 2 * pi * \<i> * n"
3529     using pi [OF e] by blast
3530   obtain q where q: "winding_number_prop \<gamma> z e q (winding_number \<gamma> z)"
3531     using winding_number [OF \<gamma> e] by blast
3532   have "2 * complex_of_real pi * \<i> * n = contour_integral p (\<lambda>w. 1 / (w - z))"
3533     using p by auto
3534   also have "\<dots> = contour_integral q (\<lambda>w. 1 / (w - z))"
3535   proof (rule pi_eq)
3536     show "(\<lambda>w. 1 / (w - z)) holomorphic_on UNIV - {z}"
3537       by (auto intro!: holomorphic_intros)
3538   qed (use p q loop in \<open>auto simp: winding_number_prop_def norm_minus_commute\<close>)
3539   also have "\<dots> = 2 * complex_of_real pi * \<i> * winding_number \<gamma> z"
3540     using q by (auto simp: winding_number_prop_def)
3541   finally have "2 * complex_of_real pi * \<i> * n = 2 * complex_of_real pi * \<i> * winding_number \<gamma> z" .
3542   then show ?thesis
3543     by simp
3544 qed
3546 proposition winding_number_valid_path:
3547   assumes "valid_path \<gamma>" "z \<notin> path_image \<gamma>"
3548   shows "winding_number \<gamma> z = 1/(2*pi*\<i>) * contour_integral \<gamma> (\<lambda>w. 1/(w - z))"
3549   by (rule winding_number_unique)
3550   (use assms in \<open>auto simp: valid_path_imp_path winding_number_prop_def\<close>)
3552 proposition has_contour_integral_winding_number:
3553   assumes \<gamma>: "valid_path \<gamma>" "z \<notin> path_image \<gamma>"
3554     shows "((\<lambda>w. 1/(w - z)) has_contour_integral (2*pi*\<i>*winding_number \<gamma> z)) \<gamma>"
3555 by (simp add: winding_number_valid_path has_contour_integral_integral contour_integrable_inversediff assms)
3557 lemma winding_number_trivial [simp]: "z \<noteq> a \<Longrightarrow> winding_number(linepath a a) z = 0"
3558   by (simp add: winding_number_valid_path)
3560 lemma winding_number_subpath_trivial [simp]: "z \<noteq> g x \<Longrightarrow> winding_number (subpath x x g) z = 0"
3561   by (simp add: path_image_subpath winding_number_valid_path)
3563 lemma winding_number_join:
3564   assumes \<gamma>1: "path \<gamma>1" "z \<notin> path_image \<gamma>1"
3565       and \<gamma>2: "path \<gamma>2" "z \<notin> path_image \<gamma>2"
3566       and "pathfinish \<gamma>1 = pathstart \<gamma>2"
3567     shows "winding_number(\<gamma>1 +++ \<gamma>2) z = winding_number \<gamma>1 z + winding_number \<gamma>2 z"
3568 proof (rule winding_number_unique)
3569   show "\<exists>p. winding_number_prop (\<gamma>1 +++ \<gamma>2) z e p
3570               (winding_number \<gamma>1 z + winding_number \<gamma>2 z)" if "e > 0" for e
3571   proof -
3572     obtain p1 where "winding_number_prop \<gamma>1 z e p1 (winding_number \<gamma>1 z)"
3573       using \<open>0 < e\<close> \<gamma>1 winding_number by blast
3574     moreover
3575     obtain p2 where "winding_number_prop \<gamma>2 z e p2 (winding_number \<gamma>2 z)"
3576       using \<open>0 < e\<close> \<gamma>2 winding_number by blast
3577     ultimately
3578     have "winding_number_prop (\<gamma>1+++\<gamma>2) z e (p1+++p2) (winding_number \<gamma>1 z + winding_number \<gamma>2 z)"
3579       using assms
3580       apply (simp add: winding_number_prop_def not_in_path_image_join contour_integrable_inversediff algebra_simps)
3581       apply (auto simp: joinpaths_def)
3582       done
3583     then show ?thesis
3584       by blast
3585   qed
3586 qed (use assms in \<open>auto simp: not_in_path_image_join\<close>)
3588 lemma winding_number_reversepath:
3589   assumes "path \<gamma>" "z \<notin> path_image \<gamma>"
3590     shows "winding_number(reversepath \<gamma>) z = - (winding_number \<gamma> z)"
3591 proof (rule winding_number_unique)
3592   show "\<exists>p. winding_number_prop (reversepath \<gamma>) z e p (- winding_number \<gamma> z)" if "e > 0" for e
3593   proof -
3594     obtain p where "winding_number_prop \<gamma> z e p (winding_number \<gamma> z)"
3595       using \<open>0 < e\<close> assms winding_number by blast
3596     then have "winding_number_prop (reversepath \<gamma>) z e (reversepath p) (- winding_number \<gamma> z)"
3597       using assms
3598       apply (simp add: winding_number_prop_def contour_integral_reversepath contour_integrable_inversediff valid_path_imp_reverse)
3599       apply (auto simp: reversepath_def)
3600       done
3601     then show ?thesis
3602       by blast
3603   qed
3604 qed (use assms in auto)
3606 lemma winding_number_shiftpath:
3607   assumes \<gamma>: "path \<gamma>" "z \<notin> path_image \<gamma>"
3608       and "pathfinish \<gamma> = pathstart \<gamma>" "a \<in> {0..1}"
3609     shows "winding_number(shiftpath a \<gamma>) z = winding_number \<gamma> z"
3610 proof (rule winding_number_unique_loop)
3611   show "\<exists>p. valid_path p \<and> z \<notin> path_image p \<and> pathfinish p = pathstart p \<and>
3612             (\<forall>t\<in>{0..1}. cmod (shiftpath a \<gamma> t - p t) < e) \<and>
3613             contour_integral p (\<lambda>w. 1 / (w - z)) =
3614             complex_of_real (2 * pi) * \<i> * winding_number \<gamma> z"
3615     if "e > 0" for e
3616   proof -
3617     obtain p where "winding_number_prop \<gamma> z e p (winding_number \<gamma> z)"
3618       using \<open>0 < e\<close> assms winding_number by blast
3619     then show ?thesis
3620       apply (rule_tac x="shiftpath a p" in exI)
3621       using assms that
3622       apply (auto simp: winding_number_prop_def path_image_shiftpath pathfinish_shiftpath pathstart_shiftpath contour_integral_shiftpath)
3623       apply (simp add: shiftpath_def)
3624       done
3625   qed
3626 qed (use assms in \<open>auto simp: path_shiftpath path_image_shiftpath pathfinish_shiftpath pathstart_shiftpath\<close>)
3628 lemma winding_number_split_linepath:
3629   assumes "c \<in> closed_segment a b" "z \<notin> closed_segment a b"
3630     shows "winding_number(linepath a b) z = winding_number(linepath a c) z + winding_number(linepath c b) z"
3631 proof -
3632   have "z \<notin> closed_segment a c" "z \<notin> closed_segment c b"
3633     using assms  by (meson convex_contains_segment convex_segment ends_in_segment subsetCE)+
3634   then show ?thesis
3635     using assms
3636     by (simp add: winding_number_valid_path contour_integral_split_linepath [symmetric] continuous_on_inversediff field_simps)
3637 qed
3639 lemma winding_number_cong:
3640    "(\<And>t. \<lbrakk>0 \<le> t; t \<le> 1\<rbrakk> \<Longrightarrow> p t = q t) \<Longrightarrow> winding_number p z = winding_number q z"
3641   by (simp add: winding_number_def winding_number_prop_def pathstart_def pathfinish_def)
3643 lemma winding_number_constI:
3644   assumes "c\<noteq>z" "\<And>t. \<lbrakk>0\<le>t; t\<le>1\<rbrakk> \<Longrightarrow> g t = c"
3645   shows "winding_number g z = 0"
3646 proof -
3647   have "winding_number g z = winding_number (linepath c c) z"
3648     apply (rule winding_number_cong)
3649     using assms unfolding linepath_def by auto
3650   moreover have "winding_number (linepath c c) z =0"
3651     apply (rule winding_number_trivial)
3652     using assms by auto
3653   ultimately show ?thesis by auto
3654 qed
3656 lemma winding_number_offset: "winding_number p z = winding_number (\<lambda>w. p w - z) 0"
3657   unfolding winding_number_def
3658 proof (intro ext arg_cong [where f = Eps] arg_cong [where f = All] imp_cong refl, safe)
3659   fix n e g
3660   assume "0 < e" and g: "winding_number_prop p z e g n"
3661   then show "\<exists>r. winding_number_prop (\<lambda>w. p w - z) 0 e r n"
3662     by (rule_tac x="\<lambda>t. g t - z" in exI)
3663        (force simp: winding_number_prop_def contour_integral_integral valid_path_def path_defs
3664                 vector_derivative_def has_vector_derivative_diff_const piecewise_C1_differentiable_diff C1_differentiable_imp_piecewise)
3665 next
3666   fix n e g
3667   assume "0 < e" and g: "winding_number_prop (\<lambda>w. p w - z) 0 e g n"
3668   then show "\<exists>r. winding_number_prop p z e r n"
3669     apply (rule_tac x="\<lambda>t. g t + z" in exI)
3670     apply (simp add: winding_number_prop_def contour_integral_integral valid_path_def path_defs
3672     apply (force simp: algebra_simps)
3673     done
3674 qed
3676 subsubsection%unimportant \<open>Some lemmas about negating a path\<close>
3678 lemma valid_path_negatepath: "valid_path \<gamma> \<Longrightarrow> valid_path (uminus \<circ> \<gamma>)"
3679    unfolding o_def using piecewise_C1_differentiable_neg valid_path_def by blast
3681 lemma has_contour_integral_negatepath:
3682   assumes \<gamma>: "valid_path \<gamma>" and cint: "((\<lambda>z. f (- z)) has_contour_integral - i) \<gamma>"
3683   shows "(f has_contour_integral i) (uminus \<circ> \<gamma>)"
3684 proof -
3685   obtain S where cont: "continuous_on {0..1} \<gamma>" and "finite S" and diff: "\<gamma> C1_differentiable_on {0..1} - S"
3686     using \<gamma> by (auto simp: valid_path_def piecewise_C1_differentiable_on_def)
3687   have "((\<lambda>x. - (f (- \<gamma> x) * vector_derivative \<gamma> (at x within {0..1}))) has_integral i) {0..1}"
3688     using cint by (auto simp: has_contour_integral_def dest: has_integral_neg)
3689   then
3690   have "((\<lambda>x. f (- \<gamma> x) * vector_derivative (uminus \<circ> \<gamma>) (at x within {0..1})) has_integral i) {0..1}"
3691   proof (rule rev_iffD1 [OF _ has_integral_spike_eq])
3692     show "negligible S"
3693       by (simp add: \<open>finite S\<close> negligible_finite)
3694     show "f (- \<gamma> x) * vector_derivative (uminus \<circ> \<gamma>) (at x within {0..1}) =
3695          - (f (- \<gamma> x) * vector_derivative \<gamma> (at x within {0..1}))"
3696       if "x \<in> {0..1} - S" for x
3697     proof -
3698       have "vector_derivative (uminus \<circ> \<gamma>) (at x within cbox 0 1) = - vector_derivative \<gamma> (at x within cbox 0 1)"
3699       proof (rule vector_derivative_within_cbox)
3700         show "(uminus \<circ> \<gamma> has_vector_derivative - vector_derivative \<gamma> (at x within cbox 0 1)) (at x within cbox 0 1)"
3701           using that unfolding o_def
3702           by (metis C1_differentiable_on_eq UNIV_I diff differentiable_subset has_vector_derivative_minus subsetI that vector_derivative_works)
3703       qed (use that in auto)
3704       then show ?thesis
3705         by simp
3706     qed
3707   qed
3708   then show ?thesis by (simp add: has_contour_integral_def)
3709 qed
3711 lemma winding_number_negatepath:
3712   assumes \<gamma>: "valid_path \<gamma>" and 0: "0 \<notin> path_image \<gamma>"
3713   shows "winding_number(uminus \<circ> \<gamma>) 0 = winding_number \<gamma> 0"
3714 proof -
3715   have "(/) 1 contour_integrable_on \<gamma>"
3716     using "0" \<gamma> contour_integrable_inversediff by fastforce
3717   then have "((\<lambda>z. 1/z) has_contour_integral contour_integral \<gamma> ((/) 1)) \<gamma>"
3718     by (rule has_contour_integral_integral)
3719   then have "((\<lambda>z. 1 / - z) has_contour_integral - contour_integral \<gamma> ((/) 1)) \<gamma>"
3720     using has_contour_integral_neg by auto
3721   then show ?thesis
3722     using assms
3723     apply (simp add: winding_number_valid_path valid_path_negatepath image_def path_defs)
3724     apply (simp add: contour_integral_unique has_contour_integral_negatepath)
3725     done
3726 qed
3728 lemma contour_integrable_negatepath:
3729   assumes \<gamma>: "valid_path \<gamma>" and pi: "(\<lambda>z. f (- z)) contour_integrable_on \<gamma>"
3730   shows "f contour_integrable_on (uminus \<circ> \<gamma>)"
3731   by (metis \<gamma> add.inverse_inverse contour_integrable_on_def has_contour_integral_negatepath pi)
3733 (* A combined theorem deducing several things piecewise.*)
3734 lemma winding_number_join_pos_combined:
3735      "\<lbrakk>valid_path \<gamma>1; z \<notin> path_image \<gamma>1; 0 < Re(winding_number \<gamma>1 z);
3736        valid_path \<gamma>2; z \<notin> path_image \<gamma>2; 0 < Re(winding_number \<gamma>2 z); pathfinish \<gamma>1 = pathstart \<gamma>2\<rbrakk>
3737       \<Longrightarrow> valid_path(\<gamma>1 +++ \<gamma>2) \<and> z \<notin> path_image(\<gamma>1 +++ \<gamma>2) \<and> 0 < Re(winding_number(\<gamma>1 +++ \<gamma>2) z)"
3738   by (simp add: valid_path_join path_image_join winding_number_join valid_path_imp_path)
3741 subsubsection%unimportant \<open>Useful sufficient conditions for the winding number to be positive\<close>
3743 lemma Re_winding_number:
3744     "\<lbrakk>valid_path \<gamma>; z \<notin> path_image \<gamma>\<rbrakk>
3745      \<Longrightarrow> Re(winding_number \<gamma> z) = Im(contour_integral \<gamma> (\<lambda>w. 1/(w - z))) / (2*pi)"
3746 by (simp add: winding_number_valid_path field_simps Re_divide power2_eq_square)
3748 lemma winding_number_pos_le:
3749   assumes \<gamma>: "valid_path \<gamma>" "z \<notin> path_image \<gamma>"
3750       and ge: "\<And>x. \<lbrakk>0 < x; x < 1\<rbrakk> \<Longrightarrow> 0 \<le> Im (vector_derivative \<gamma> (at x) * cnj(\<gamma> x - z))"
3751     shows "0 \<le> Re(winding_number \<gamma> z)"
3752 proof -
3753   have ge0: "0 \<le> Im (vector_derivative \<gamma> (at x) / (\<gamma> x - z))" if x: "0 < x" "x < 1" for x
3754     using ge by (simp add: Complex.Im_divide algebra_simps x)
3755   let ?vd = "\<lambda>x. 1 / (\<gamma> x - z) * vector_derivative \<gamma> (at x)"
3756   let ?int = "\<lambda>z. contour_integral \<gamma> (\<lambda>w. 1 / (w - z))"
3757   have hi: "(?vd has_integral ?int z) (cbox 0 1)"
3758     unfolding box_real
3759     apply (subst has_contour_integral [symmetric])
3760     using \<gamma> by (simp add: contour_integrable_inversediff has_contour_integral_integral)
3761   have "0 \<le> Im (?int z)"
3762   proof (rule has_integral_component_nonneg [of \<i>, simplified])
3763     show "\<And>x. x \<in> cbox 0 1 \<Longrightarrow> 0 \<le> Im (if 0 < x \<and> x < 1 then ?vd x else 0)"
3764       by (force simp: ge0)
3765     show "((\<lambda>x. if 0 < x \<and> x < 1 then ?vd x else 0) has_integral ?int z) (cbox 0 1)"
3766       by (rule has_integral_spike_interior [OF hi]) simp
3767   qed
3768   then show ?thesis
3769     by (simp add: Re_winding_number [OF \<gamma>] field_simps)
3770 qed
3772 lemma winding_number_pos_lt_lemma:
3773   assumes \<gamma>: "valid_path \<gamma>" "z \<notin> path_image \<gamma>"
3774       and e: "0 < e"
3775       and ge: "\<And>x. \<lbrakk>0 < x; x < 1\<rbrakk> \<Longrightarrow> e \<le> Im (vector_derivative \<gamma> (at x) / (\<gamma> x - z))"
3776     shows "0 < Re(winding_number \<gamma> z)"
3777 proof -
3778   let ?vd = "\<lambda>x. 1 / (\<gamma> x - z) * vector_derivative \<gamma> (at x)"
3779   let ?int = "\<lambda>z. contour_integral \<gamma> (\<lambda>w. 1 / (w - z))"
3780   have hi: "(?vd has_integral ?int z) (cbox 0 1)"
3781     unfolding box_real
3782     apply (subst has_contour_integral [symmetric])
3783     using \<gamma> by (simp add: contour_integrable_inversediff has_contour_integral_integral)
3784   have "e \<le> Im (contour_integral \<gamma> (\<lambda>w. 1 / (w - z)))"
3785   proof (rule has_integral_component_le [of \<i> "\<lambda>x. \<i>*e" "\<i>*e" "{0..1}", simplified])
3786     show "((\<lambda>x. if 0 < x \<and> x < 1 then ?vd x else \<i> * complex_of_real e) has_integral ?int z) {0..1}"
3787       by (rule has_integral_spike_interior [OF hi, simplified box_real]) (use e in simp)
3788     show "\<And>x. 0 \<le> x \<and> x \<le> 1 \<Longrightarrow>
3789               e \<le> Im (if 0 < x \<and> x < 1 then ?vd x else \<i> * complex_of_real e)"
3790       by (simp add: ge)
3791   qed (use has_integral_const_real [of _ 0 1] in auto)
3792   with e show ?thesis
3793     by (simp add: Re_winding_number [OF \<gamma>] field_simps)
3794 qed
3796 lemma winding_number_pos_lt:
3797   assumes \<gamma>: "valid_path \<gamma>" "z \<notin> path_image \<gamma>"
3798       and e: "0 < e"
3799       and ge: "\<And>x. \<lbrakk>0 < x; x < 1\<rbrakk> \<Longrightarrow> e \<le> Im (vector_derivative \<gamma> (at x) * cnj(\<gamma> x - z))"
3800     shows "0 < Re (winding_number \<gamma> z)"
3801 proof -
3802   have bm: "bounded ((\<lambda>w. w - z) ` (path_image \<gamma>))"
3803     using bounded_translation [of _ "-z"] \<gamma> by (simp add: bounded_valid_path_image)
3804   then obtain B where B: "B > 0" and Bno: "\<And>x. x \<in> (\<lambda>w. w - z) ` (path_image \<gamma>) \<Longrightarrow> norm x \<le> B"
3805     using bounded_pos [THEN iffD1, OF bm] by blast
3806   { fix x::real  assume x: "0 < x" "x < 1"
3807     then have B2: "cmod (\<gamma> x - z)^2 \<le> B^2" using Bno [of "\<gamma> x - z"]
3808       by (simp add: path_image_def power2_eq_square mult_mono')
3809     with x have "\<gamma> x \<noteq> z" using \<gamma>
3810       using path_image_def by fastforce
3811     then have "e / B\<^sup>2 \<le> Im (vector_derivative \<gamma> (at x) * cnj (\<gamma> x - z)) / (cmod (\<gamma> x - z))\<^sup>2"
3812       using B ge [OF x] B2 e
3813       apply (rule_tac y="e / (cmod (\<gamma> x - z))\<^sup>2" in order_trans)
3814       apply (auto simp: divide_left_mono divide_right_mono)
3815       done
3816     then have "e / B\<^sup>2 \<le> Im (vector_derivative \<gamma> (at x) / (\<gamma> x - z))"
3817       by (simp add: complex_div_cnj [of _ "\<gamma> x - z" for x] del: complex_cnj_diff times_complex.sel)
3818   } note * = this
3819   show ?thesis
3820     using e B by (simp add: * winding_number_pos_lt_lemma [OF \<gamma>, of "e/B^2"])
3821 qed
3823 subsection\<open>The winding number is an integer\<close>
3825 text\<open>Proof from the book Complex Analysis by Lars V. Ahlfors, Chapter 4, section 2.1,
3826      Also on page 134 of Serge Lang's book with the name title, etc.\<close>
3828 lemma exp_fg:
3829   fixes z::complex
3830   assumes g: "(g has_vector_derivative g') (at x within s)"
3831       and f: "(f has_vector_derivative (g' / (g x - z))) (at x within s)"
3832       and z: "g x \<noteq> z"
3833     shows "((\<lambda>x. exp(-f x) * (g x - z)) has_vector_derivative 0) (at x within s)"
3834 proof -
3835   have *: "(exp \<circ> (\<lambda>x. (- f x)) has_vector_derivative - (g' / (g x - z)) * exp (- f x)) (at x within s)"
3836     using assms unfolding has_vector_derivative_def scaleR_conv_of_real
3837     by (auto intro!: derivative_eq_intros)
3838   show ?thesis
3839     apply (rule has_vector_derivative_eq_rhs)
3840     using z
3841     apply (auto intro!: derivative_eq_intros * [unfolded o_def] g)
3842     done
3843 qed
3845 lemma winding_number_exp_integral:
3846   fixes z::complex
3847   assumes \<gamma>: "\<gamma> piecewise_C1_differentiable_on {a..b}"
3848       and ab: "a \<le> b"
3849       and z: "z \<notin> \<gamma> ` {a..b}"
3850     shows "(\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z)) integrable_on {a..b}"
3851           (is "?thesis1")
3852           "exp (- (integral {a..b} (\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z)))) * (\<gamma> b - z) = \<gamma> a - z"
3853           (is "?thesis2")
3854 proof -
3855   let ?D\<gamma> = "\<lambda>x. vector_derivative \<gamma> (at x)"
3856   have [simp]: "\<And>x. a \<le> x \<Longrightarrow> x \<le> b \<Longrightarrow> \<gamma> x \<noteq> z"
3857     using z by force
3858   have cong: "continuous_on {a..b} \<gamma>"
3859     using \<gamma> by (simp add: piecewise_C1_differentiable_on_def)
3860   obtain k where fink: "finite k" and g_C1_diff: "\<gamma> C1_differentiable_on ({a..b} - k)"
3861     using \<gamma> by (force simp: piecewise_C1_differentiable_on_def)
3862   have \<circ>: "open ({a<..<b} - k)"
3863     using \<open>finite k\<close> by (simp add: finite_imp_closed open_Diff)
3864   moreover have "{a<..<b} - k \<subseteq> {a..b} - k"
3865     by force
3866   ultimately have g_diff_at: "\<And>x. \<lbrakk>x \<notin> k; x \<in> {a<..<b}\<rbrakk> \<Longrightarrow> \<gamma> differentiable at x"
3867     by (metis Diff_iff differentiable_on_subset C1_diff_imp_diff [OF g_C1_diff] differentiable_on_def at_within_open)
3868   { fix w
3869     assume "w \<noteq> z"
3870     have "continuous_on (ball w (cmod (w - z))) (\<lambda>w. 1 / (w - z))"
3871       by (auto simp: dist_norm intro!: continuous_intros)
3872     moreover have "\<And>x. cmod (w - x) < cmod (w - z) \<Longrightarrow> \<exists>f'. ((\<lambda>w. 1 / (w - z)) has_field_derivative f') (at x)"
3873       by (auto simp: intro!: derivative_eq_intros)
3874     ultimately have "\<exists>h. \<forall>y. norm(y - w) < norm(w - z) \<longrightarrow> (h has_field_derivative 1/(y - z)) (at y)"
3875       using holomorphic_convex_primitive [of "ball w (norm(w - z))" "{}" "\<lambda>w. 1/(w - z)"]
3876       by (force simp: field_differentiable_def Ball_def dist_norm at_within_open_NO_MATCH norm_minus_commute)
3877   }
3878   then obtain h where h: "\<And>w y. w \<noteq> z \<Longrightarrow> norm(y - w) < norm(w - z) \<Longrightarrow> (h w has_field_derivative 1/(y - z)) (at y)"
3879     by meson
3880   have exy: "\<exists>y. ((\<lambda>x. inverse (\<gamma> x - z) * ?D\<gamma> x) has_integral y) {a..b}"
3881     unfolding integrable_on_def [symmetric]
3882   proof (rule contour_integral_local_primitive_any [OF piecewise_C1_imp_differentiable [OF \<gamma>]])
3883     show "\<exists>d h. 0 < d \<and>
3884                (\<forall>y. cmod (y - w) < d \<longrightarrow> (h has_field_derivative inverse (y - z))(at y within - {z}))"
3885           if "w \<in> - {z}" for w
3886       apply (rule_tac x="norm(w - z)" in exI)
3887       using that inverse_eq_divide has_field_derivative_at_within h
3888       by (metis Compl_insert DiffD2 insertCI right_minus_eq zero_less_norm_iff)
3889   qed simp
3890   have vg_int: "(\<lambda>x. ?D\<gamma> x / (\<gamma> x - z)) integrable_on {a..b}"
3891     unfolding box_real [symmetric] divide_inverse_commute
3892     by (auto intro!: exy integrable_subinterval simp add: integrable_on_def ab)
3893   with ab show ?thesis1
3894     by (simp add: divide_inverse_commute integral_def integrable_on_def)
3895   { fix t
3896     assume t: "t \<in> {a..b}"
3897     have cball: "continuous_on (ball (\<gamma> t) (dist (\<gamma> t) z)) (\<lambda>x. inverse (x - z))"
3898         using z by (auto intro!: continuous_intros simp: dist_norm)
3899     have icd: "\<And>x. cmod (\<gamma> t - x) < cmod (\<gamma> t - z) \<Longrightarrow> (\<lambda>w. inverse (w - z)) field_differentiable at x"
3900       unfolding field_differentiable_def by (force simp: intro!: derivative_eq_intros)
3901     obtain h where h: "\<And>x. cmod (\<gamma> t - x) < cmod (\<gamma> t - z) \<Longrightarrow>
3902                        (h has_field_derivative inverse (x - z)) (at x within {y. cmod (\<gamma> t - y) < cmod (\<gamma> t - z)})"
3903       using holomorphic_convex_primitive [where f = "\<lambda>w. inverse(w - z)", OF convex_ball finite.emptyI cball icd]
3904       by simp (auto simp: ball_def dist_norm that)
3905     { fix x D
3906       assume x: "x \<notin> k" "a < x" "x < b"
3907       then have "x \<in> interior ({a..b} - k)"
3908         using open_subset_interior [OF \<circ>] by fastforce
3909       then have con: "isCont ?D\<gamma> x"
3910         using g_C1_diff x by (auto simp: C1_differentiable_on_eq intro: continuous_on_interior)
3911       then have con_vd: "continuous (at x within {a..b}) (\<lambda>x. ?D\<gamma> x)"
3912         by (rule continuous_at_imp_continuous_within)
3913       have gdx: "\<gamma> differentiable at x"
3914         using x by (simp add: g_diff_at)
3915       have "\<And>d. \<lbrakk>x \<notin> k; a < x; x < b;
3916           (\<gamma> has_vector_derivative d) (at x); a \<le> t; t \<le> b\<rbrakk>
3917          \<Longrightarrow> ((\<lambda>x. integral {a..x}
3918                      (\<lambda>x. ?D\<gamma> x /
3919                            (\<gamma> x - z))) has_vector_derivative
3920               d / (\<gamma> x - z))
3921               (at x within {a..b})"
3922         apply (rule has_vector_derivative_eq_rhs)
3923          apply (rule integral_has_vector_derivative_continuous_at [where S = "{}", simplified])
3924         apply (rule con_vd continuous_intros cong vg_int | simp add: continuous_at_imp_continuous_within has_vector_derivative_continuous vector_derivative_at)+
3925         done
3926       then have "((\<lambda>c. exp (- integral {a..c} (\<lambda>x. ?D\<gamma> x / (\<gamma> x - z))) * (\<gamma> c - z)) has_derivative (\<lambda>h. 0))
3927           (at x within {a..b})"
3928         using x gdx t
3929         apply (clarsimp simp add: differentiable_iff_scaleR)
3930         apply (rule exp_fg [unfolded has_vector_derivative_def, simplified], blast intro: has_derivative_at_withinI)
3931         apply (simp_all add: has_vector_derivative_def [symmetric])
3932         done
3933       } note * = this
3934     have "exp (- (integral {a..t} (\<lambda>x. ?D\<gamma> x / (\<gamma> x - z)))) * (\<gamma> t - z) =\<gamma> a - z"
3935       apply (rule has_derivative_zero_unique_strong_interval [of "{a,b} \<union> k" a b])
3936       using t
3937       apply (auto intro!: * continuous_intros fink cong indefinite_integral_continuous_1 [OF vg_int]  simp add: ab)+
3938       done
3939    }
3940   with ab show ?thesis2
3941     by (simp add: divide_inverse_commute integral_def)
3942 qed
3944 lemma winding_number_exp_2pi:
3945     "\<lbrakk>path p; z \<notin> path_image p\<rbrakk>
3946      \<Longrightarrow> pathfinish p - z = exp (2 * pi * \<i> * winding_number p z) * (pathstart p - z)"
3947 using winding_number [of p z 1] unfolding valid_path_def path_image_def pathstart_def pathfinish_def winding_number_prop_def
3948   by (force dest: winding_number_exp_integral(2) [of _ 0 1 z] simp: field_simps contour_integral_integral exp_minus)
3950 lemma integer_winding_number_eq:
3951   assumes \<gamma>: "path \<gamma>" and z: "z \<notin> path_image \<gamma>"
3952   shows "winding_number \<gamma> z \<in> \<int> \<longleftrightarrow> pathfinish \<gamma> = pathstart \<gamma>"
3953 proof -
3954   obtain p where p: "valid_path p" "z \<notin> path_image p"
3955                     "pathstart p = pathstart \<gamma>" "pathfinish p = pathfinish \<gamma>"
3956            and eq: "contour_integral p (\<lambda>w. 1 / (w - z)) = complex_of_real (2 * pi) * \<i> * winding_number \<gamma> z"
3957     using winding_number [OF assms, of 1] unfolding winding_number_prop_def by auto
3958   then have wneq: "winding_number \<gamma> z = winding_number p z"
3959       using eq winding_number_valid_path by force
3960   have iff: "(winding_number \<gamma> z \<in> \<int>) \<longleftrightarrow> (exp (contour_integral p (\<lambda>w. 1 / (w - z))) = 1)"
3961     using eq by (simp add: exp_eq_1 complex_is_Int_iff)
3962   have "exp (contour_integral p (\<lambda>w. 1 / (w - z))) = (\<gamma> 1 - z) / (\<gamma> 0 - z)"
3963     using p winding_number_exp_integral(2) [of p 0 1 z]
3964     apply (simp add: valid_path_def path_defs contour_integral_integral exp_minus divide_simps)
3965     by (metis path_image_def pathstart_def pathstart_in_path_image)
3966   then have "winding_number p z \<in> \<int> \<longleftrightarrow> pathfinish p = pathstart p"
3967     using p wneq iff by (auto simp: path_defs)
3968   then show ?thesis using p eq
3969     by (auto simp: winding_number_valid_path)
3970 qed
3972 theorem integer_winding_number:
3973   "\<lbrakk>path \<gamma>; pathfinish \<gamma> = pathstart \<gamma>; z \<notin> path_image \<gamma>\<rbrakk> \<Longrightarrow> winding_number \<gamma> z \<in> \<int>"
3974 by (metis integer_winding_number_eq)
3977 text\<open>If the winding number's magnitude is at least one, then the path must contain points in every direction.*)
3978    We can thus bound the winding number of a path that doesn't intersect a given ray. \<close>
3980 lemma winding_number_pos_meets:
3981   fixes z::complex
3982   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and 1: "Re (winding_number \<gamma> z) \<ge> 1"
3983       and w: "w \<noteq> z"
3984   shows "\<exists>a::real. 0 < a \<and> z + a*(w - z) \<in> path_image \<gamma>"
3985 proof -
3986   have [simp]: "\<And>x. 0 \<le> x \<Longrightarrow> x \<le> 1 \<Longrightarrow> \<gamma> x \<noteq> z"
3987     using z by (auto simp: path_image_def)
3988   have [simp]: "z \<notin> \<gamma> ` {0..1}"
3989     using path_image_def z by auto
3990   have gpd: "\<gamma> piecewise_C1_differentiable_on {0..1}"
3991     using \<gamma> valid_path_def by blast
3992   define r where "r = (w - z) / (\<gamma> 0 - z)"
3993   have [simp]: "r \<noteq> 0"
3994     using w z by (auto simp: r_def)
3995   have cont: "continuous_on {0..1}
3996      (\<lambda>x. Im (integral {0..x} (\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z))))"
3997     by (intro continuous_intros indefinite_integral_continuous_1 winding_number_exp_integral [OF gpd]; simp)
3998   have "Arg2pi r \<le> 2*pi"
3999     by (simp add: Arg2pi less_eq_real_def)
4000   also have "\<dots> \<le> Im (integral {0..1} (\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z)))"
4001     using 1
4002     apply (simp add: winding_number_valid_path [OF \<gamma> z] contour_integral_integral)
4003     apply (simp add: Complex.Re_divide field_simps power2_eq_square)
4004     done
4005   finally have "Arg2pi r \<le> Im (integral {0..1} (\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z)))" .
4006   then have "\<exists>t. t \<in> {0..1} \<and> Im(integral {0..t} (\<lambda>x. vector_derivative \<gamma> (at x)/(\<gamma> x - z))) = Arg2pi r"
4007     by (simp add: Arg2pi_ge_0 cont IVT')
4008   then obtain t where t:     "t \<in> {0..1}"
4009                   and eqArg: "Im (integral {0..t} (\<lambda>x. vector_derivative \<gamma> (at x)/(\<gamma> x - z))) = Arg2pi r"
4010     by blast
4011   define i where "i = integral {0..t} (\<lambda>x. vector_derivative \<gamma> (at x) / (\<gamma> x - z))"
4012   have iArg: "Arg2pi r = Im i"
4013     using eqArg by (simp add: i_def)
4014   have gpdt: "\<gamma> piecewise_C1_differentiable_on {0..t}"
4015     by (metis atLeastAtMost_iff atLeastatMost_subset_iff order_refl piecewise_C1_differentiable_on_subset gpd t)
4016   have "exp (- i) * (\<gamma> t - z) = \<gamma> 0 - z"
4017     unfolding i_def
4018     apply (rule winding_number_exp_integral [OF gpdt])
4019     using t z unfolding path_image_def by force+
4020   then have *: "\<gamma> t - z = exp i * (\<gamma> 0 - z)"
4021     by (simp add: exp_minus field_simps)
4022   then have "(w - z) = r * (\<gamma> 0 - z)"
4023     by (simp add: r_def)
4024   then have "z + complex_of_real (exp (Re i)) * (w - z) / complex_of_real (cmod r) = \<gamma> t"
4025     apply simp
4026     apply (subst Complex_Transcendental.Arg2pi_eq [of r])
4027     apply (simp add: iArg)
4028     using * apply (simp add: exp_eq_polar field_simps)
4029     done
4030   with t show ?thesis
4031     by (rule_tac x="exp(Re i) / norm r" in exI) (auto simp: path_image_def)
4032 qed
4034 lemma winding_number_big_meets:
4035   fixes z::complex
4036   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and "\<bar>Re (winding_number \<gamma> z)\<bar> \<ge> 1"
4037       and w: "w \<noteq> z"
4038   shows "\<exists>a::real. 0 < a \<and> z + a*(w - z) \<in> path_image \<gamma>"
4039 proof -
4040   { assume "Re (winding_number \<gamma> z) \<le> - 1"
4041     then have "Re (winding_number (reversepath \<gamma>) z) \<ge> 1"
4042       by (simp add: \<gamma> valid_path_imp_path winding_number_reversepath z)
4043     moreover have "valid_path (reversepath \<gamma>)"
4044       using \<gamma> valid_path_imp_reverse by auto
4045     moreover have "z \<notin> path_image (reversepath \<gamma>)"
4046       by (simp add: z)
4047     ultimately have "\<exists>a::real. 0 < a \<and> z + a*(w - z) \<in> path_image (reversepath \<gamma>)"
4048       using winding_number_pos_meets w by blast
4049     then have ?thesis
4050       by simp
4051   }
4052   then show ?thesis
4053     using assms
4054     by (simp add: abs_if winding_number_pos_meets split: if_split_asm)
4055 qed
4057 lemma winding_number_less_1:
4058   fixes z::complex
4059   shows
4060   "\<lbrakk>valid_path \<gamma>; z \<notin> path_image \<gamma>; w \<noteq> z;
4061     \<And>a::real. 0 < a \<Longrightarrow> z + a*(w - z) \<notin> path_image \<gamma>\<rbrakk>
4062    \<Longrightarrow> Re(winding_number \<gamma> z) < 1"
4063    by (auto simp: not_less dest: winding_number_big_meets)
4065 text\<open>One way of proving that WN=1 for a loop.\<close>
4066 lemma winding_number_eq_1:
4067   fixes z::complex
4068   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>"
4069       and 0: "0 < Re(winding_number \<gamma> z)" and 2: "Re(winding_number \<gamma> z) < 2"
4070   shows "winding_number \<gamma> z = 1"
4071 proof -
4072   have "winding_number \<gamma> z \<in> Ints"
4073     by (simp add: \<gamma> integer_winding_number loop valid_path_imp_path z)
4074   then show ?thesis
4075     using 0 2 by (auto simp: Ints_def)
4076 qed
4078 subsection\<open>Continuity of winding number and invariance on connected sets\<close>
4080 lemma continuous_at_winding_number:
4081   fixes z::complex
4082   assumes \<gamma>: "path \<gamma>" and z: "z \<notin> path_image \<gamma>"
4083   shows "continuous (at z) (winding_number \<gamma>)"
4084 proof -
4085   obtain e where "e>0" and cbg: "cball z e \<subseteq> - path_image \<gamma>"
4086     using open_contains_cball [of "- path_image \<gamma>"]  z
4087     by (force simp: closed_def [symmetric] closed_path_image [OF \<gamma>])
4088   then have ppag: "path_image \<gamma> \<subseteq> - cball z (e/2)"
4089     by (force simp: cball_def dist_norm)
4090   have oc: "open (- cball z (e / 2))"
4091     by (simp add: closed_def [symmetric])
4092   obtain d where "d>0" and pi_eq:
4093     "\<And>h1 h2. \<lbrakk>valid_path h1; valid_path h2;
4094               (\<forall>t\<in>{0..1}. cmod (h1 t - \<gamma> t) < d \<and> cmod (h2 t - \<gamma> t) < d);
4095               pathstart h2 = pathstart h1; pathfinish h2 = pathfinish h1\<rbrakk>
4096              \<Longrightarrow>
4097                path_image h1 \<subseteq> - cball z (e / 2) \<and>
4098                path_image h2 \<subseteq> - cball z (e / 2) \<and>
4099                (\<forall>f. f holomorphic_on - cball z (e / 2) \<longrightarrow> contour_integral h2 f = contour_integral h1 f)"
4100     using contour_integral_nearby_ends [OF oc \<gamma> ppag] by metis
4101   obtain p where p: "valid_path p" "z \<notin> path_image p"
4102                     "pathstart p = pathstart \<gamma> \<and> pathfinish p = pathfinish \<gamma>"
4103               and pg: "\<And>t. t\<in>{0..1} \<Longrightarrow> cmod (\<gamma> t - p t) < min d e / 2"
4104               and pi: "contour_integral p (\<lambda>x. 1 / (x - z)) = complex_of_real (2 * pi) * \<i> * winding_number \<gamma> z"
4105     using winding_number [OF \<gamma> z, of "min d e / 2"] \<open>d>0\<close> \<open>e>0\<close> by (auto simp: winding_number_prop_def)
4106   { fix w
4107     assume d2: "cmod (w - z) < d/2" and e2: "cmod (w - z) < e/2"
4108     then have wnotp: "w \<notin> path_image p"
4109       using cbg \<open>d>0\<close> \<open>e>0\<close>
4110       apply (simp add: path_image_def cball_def dist_norm, clarify)
4111       apply (frule pg)
4112       apply (drule_tac c="\<gamma> x" in subsetD)
4113       apply (auto simp: less_eq_real_def norm_minus_commute norm_triangle_half_l)
4114       done
4115     have wnotg: "w \<notin> path_image \<gamma>"
4116       using cbg e2 \<open>e>0\<close> by (force simp: dist_norm norm_minus_commute)
4117     { fix k::real
4118       assume k: "k>0"
4119       then obtain q where q: "valid_path q" "w \<notin> path_image q"
4120                              "pathstart q = pathstart \<gamma> \<and> pathfinish q = pathfinish \<gamma>"
4121                     and qg: "\<And>t. t \<in> {0..1} \<Longrightarrow> cmod (\<gamma> t - q t) < min k (min d e) / 2"
4122                     and qi: "contour_integral q (\<lambda>u. 1 / (u - w)) = complex_of_real (2 * pi) * \<i> * winding_number \<gamma> w"
4123         using winding_number [OF \<gamma> wnotg, of "min k (min d e) / 2"] \<open>d>0\<close> \<open>e>0\<close> k
4124         by (force simp: min_divide_distrib_right winding_number_prop_def)
4125       have "contour_integral p (\<lambda>u. 1 / (u - w)) = contour_integral q (\<lambda>u. 1 / (u - w))"
4126         apply (rule pi_eq [OF \<open>valid_path q\<close> \<open>valid_path p\<close>, THEN conjunct2, THEN conjunct2, rule_format])
4127         apply (frule pg)
4128         apply (frule qg)
4129         using p q \<open>d>0\<close> e2
4130         apply (auto simp: dist_norm norm_minus_commute intro!: holomorphic_intros)
4131         done
4132       then have "contour_integral p (\<lambda>x. 1 / (x - w)) = complex_of_real (2 * pi) * \<i> * winding_number \<gamma> w"
4133         by (simp add: pi qi)
4134     } note pip = this
4135     have "path p"
4136       using p by (simp add: valid_path_imp_path)
4137     then have "winding_number p w = winding_number \<gamma> w"
4138       apply (rule winding_number_unique [OF _ wnotp])
4139       apply (rule_tac x=p in exI)
4140       apply (simp add: p wnotp min_divide_distrib_right pip winding_number_prop_def)
4141       done
4142   } note wnwn = this
4143   obtain pe where "pe>0" and cbp: "cball z (3 / 4 * pe) \<subseteq> - path_image p"
4144     using p open_contains_cball [of "- path_image p"]
4145     by (force simp: closed_def [symmetric] closed_path_image [OF valid_path_imp_path])
4146   obtain L
4147     where "L>0"
4148       and L: "\<And>f B. \<lbrakk>f holomorphic_on - cball z (3 / 4 * pe);
4149                       \<forall>z \<in> - cball z (3 / 4 * pe). cmod (f z) \<le> B\<rbrakk> \<Longrightarrow>
4150                       cmod (contour_integral p f) \<le> L * B"
4151     using contour_integral_bound_exists [of "- cball z (3/4*pe)" p] cbp \<open>valid_path p\<close> by force
4152   { fix e::real and w::complex
4153     assume e: "0 < e" and w: "cmod (w - z) < pe/4" "cmod (w - z) < e * pe\<^sup>2 / (8 * L)"
4154     then have [simp]: "w \<notin> path_image p"
4155       using cbp p(2) \<open>0 < pe\<close>
4156       by (force simp: dist_norm norm_minus_commute path_image_def cball_def)
4157     have [simp]: "contour_integral p (\<lambda>x. 1/(x - w)) - contour_integral p (\<lambda>x. 1/(x - z)) =
4158                   contour_integral p (\<lambda>x. 1/(x - w) - 1/(x - z))"
4159       by (simp add: p contour_integrable_inversediff contour_integral_diff)
4160     { fix x
4161       assume pe: "3/4 * pe < cmod (z - x)"
4162       have "cmod (w - x) < pe/4 + cmod (z - x)"
4163         by (meson add_less_cancel_right norm_diff_triangle_le order_refl order_trans_rules(21) w(1))
4164       then have wx: "cmod (w - x) < 4/3 * cmod (z - x)" using pe by simp
4165       have "cmod (z - x) \<le> cmod (z - w) + cmod (w - x)"
4166         using norm_diff_triangle_le by blast
4167       also have "\<dots> < pe/4 + cmod (w - x)"
4168         using w by (simp add: norm_minus_commute)
4169       finally have "pe/2 < cmod (w - x)"
4170         using pe by auto
4171       then have "(pe/2)^2 < cmod (w - x) ^ 2"
4172         apply (rule power_strict_mono)
4173         using \<open>pe>0\<close> by auto
4174       then have pe2: "pe^2 < 4 * cmod (w - x) ^ 2"
4175         by (simp add: power_divide)
4176       have "8 * L * cmod (w - z) < e * pe\<^sup>2"
4177         using w \<open>L>0\<close> by (simp add: field_simps)
4178       also have "\<dots> < e * 4 * cmod (w - x) * cmod (w - x)"
4179         using pe2 \<open>e>0\<close> by (simp add: power2_eq_square)
4180       also have "\<dots> < e * 4 * cmod (w - x) * (4/3 * cmod (z - x))"
4181         using wx
4182         apply (rule mult_strict_left_mono)
4183         using pe2 e not_less_iff_gr_or_eq by fastforce
4184       finally have "L * cmod (w - z) < 2/3 * e * cmod (w - x) * cmod (z - x)"
4185         by simp
4186       also have "\<dots> \<le> e * cmod (w - x) * cmod (z - x)"
4187          using e by simp
4188       finally have Lwz: "L * cmod (w - z) < e * cmod (w - x) * cmod (z - x)" .
4189       have "L * cmod (1 / (x - w) - 1 / (x - z)) \<le> e"
4190         apply (cases "x=z \<or> x=w")
4191         using pe \<open>pe>0\<close> w \<open>L>0\<close>
4192         apply (force simp: norm_minus_commute)
4193         using wx w(2) \<open>L>0\<close> pe pe2 Lwz
4194         apply (auto simp: divide_simps mult_less_0_iff norm_minus_commute norm_divide norm_mult power2_eq_square)
4195         done
4196     } note L_cmod_le = this
4197     have *: "cmod (contour_integral p (\<lambda>x. 1 / (x - w) - 1 / (x - z))) \<le> L * (e * pe\<^sup>2 / L / 4 * (inverse (pe / 2))\<^sup>2)"
4198       apply (rule L)
4199       using \<open>pe>0\<close> w
4200       apply (force simp: dist_norm norm_minus_commute intro!: holomorphic_intros)
4201       using \<open>pe>0\<close> w \<open>L>0\<close>
4202       apply (auto simp: cball_def dist_norm field_simps L_cmod_le  simp del: less_divide_eq_numeral1 le_divide_eq_numeral1)
4203       done
4204     have "cmod (contour_integral p (\<lambda>x. 1 / (x - w)) - contour_integral p (\<lambda>x. 1 / (x - z))) < 2*e"
4205       apply simp
4206       apply (rule le_less_trans [OF *])
4207       using \<open>L>0\<close> e
4208       apply (force simp: field_simps)
4209       done
4210     then have "cmod (winding_number p w - winding_number p z) < e"
4211       using pi_ge_two e
4212       by (force simp: winding_number_valid_path p field_simps norm_divide norm_mult intro: less_le_trans)
4213   } note cmod_wn_diff = this
4214   then have "isCont (winding_number p) z"
4215     apply (simp add: continuous_at_eps_delta, clarify)
4216     apply (rule_tac x="min (pe/4) (e/2*pe^2/L/4)" in exI)
4217     using \<open>pe>0\<close> \<open>L>0\<close>
4218     apply (simp add: dist_norm cmod_wn_diff)
4219     done
4220   then show ?thesis
4221     apply (rule continuous_transform_within [where d = "min d e / 2"])
4222     apply (auto simp: \<open>d>0\<close> \<open>e>0\<close> dist_norm wnwn)
4223     done
4224 qed
4226 corollary continuous_on_winding_number:
4227     "path \<gamma> \<Longrightarrow> continuous_on (- path_image \<gamma>) (\<lambda>w. winding_number \<gamma> w)"
4228   by (simp add: continuous_at_imp_continuous_on continuous_at_winding_number)
4230 subsection%unimportant \<open>The winding number is constant on a connected region\<close>
4232 lemma winding_number_constant:
4233   assumes \<gamma>: "path \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>" and cs: "connected S" and sg: "S \<inter> path_image \<gamma> = {}"
4234   shows "winding_number \<gamma> constant_on S"
4235 proof -
4236   have *: "1 \<le> cmod (winding_number \<gamma> y - winding_number \<gamma> z)"
4237       if ne: "winding_number \<gamma> y \<noteq> winding_number \<gamma> z" and "y \<in> S" "z \<in> S" for y z
4238   proof -
4239     have "winding_number \<gamma> y \<in> \<int>"  "winding_number \<gamma> z \<in>  \<int>"
4240       using that integer_winding_number [OF \<gamma> loop] sg \<open>y \<in> S\<close> by auto
4241     with ne show ?thesis
4242       by (auto simp: Ints_def simp flip: of_int_diff)
4243   qed
4244   have cont: "continuous_on S (\<lambda>w. winding_number \<gamma> w)"
4245     using continuous_on_winding_number [OF \<gamma>] sg
4246     by (meson continuous_on_subset disjoint_eq_subset_Compl)
4247   show ?thesis
4248     using "*" zero_less_one
4249     by (blast intro: continuous_discrete_range_constant [OF cs cont])
4250 qed
4252 lemma winding_number_eq:
4253      "\<lbrakk>path \<gamma>; pathfinish \<gamma> = pathstart \<gamma>; w \<in> S; z \<in> S; connected S; S \<inter> path_image \<gamma> = {}\<rbrakk>
4254       \<Longrightarrow> winding_number \<gamma> w = winding_number \<gamma> z"
4255   using winding_number_constant by (metis constant_on_def)
4257 lemma open_winding_number_levelsets:
4258   assumes \<gamma>: "path \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>"
4259     shows "open {z. z \<notin> path_image \<gamma> \<and> winding_number \<gamma> z = k}"
4260 proof -
4261   have opn: "open (- path_image \<gamma>)"
4262     by (simp add: closed_path_image \<gamma> open_Compl)
4263   { fix z assume z: "z \<notin> path_image \<gamma>" and k: "k = winding_number \<gamma> z"
4264     obtain e where e: "e>0" "ball z e \<subseteq> - path_image \<gamma>"
4265       using open_contains_ball [of "- path_image \<gamma>"] opn z
4266       by blast
4267     have "\<exists>e>0. \<forall>y. dist y z < e \<longrightarrow> y \<notin> path_image \<gamma> \<and> winding_number \<gamma> y = winding_number \<gamma> z"
4268       apply (rule_tac x=e in exI)
4269       using e apply (simp add: dist_norm ball_def norm_minus_commute)
4270       apply (auto simp: dist_norm norm_minus_commute intro!: winding_number_eq [OF assms, where S = "ball z e"])
4271       done
4272   } then
4273   show ?thesis
4274     by (auto simp: open_dist)
4275 qed
4277 subsection\<open>Winding number is zero "outside" a curve, in various senses\<close>
4279 proposition winding_number_zero_in_outside:
4280   assumes \<gamma>: "path \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>" and z: "z \<in> outside (path_image \<gamma>)"
4281     shows "winding_number \<gamma> z = 0"
4282 proof -
4283   obtain B::real where "0 < B" and B: "path_image \<gamma> \<subseteq> ball 0 B"
4284     using bounded_subset_ballD [OF bounded_path_image [OF \<gamma>]] by auto
4285   obtain w::complex where w: "w \<notin> ball 0 (B + 1)"
4286     by (metis abs_of_nonneg le_less less_irrefl mem_ball_0 norm_of_real)
4287   have "- ball 0 (B + 1) \<subseteq> outside (path_image \<gamma>)"
4288     apply (rule outside_subset_convex)
4289     using B subset_ball by auto
4290   then have wout: "w \<in> outside (path_image \<gamma>)"
4291     using w by blast
4292   moreover have "winding_number \<gamma> constant_on outside (path_image \<gamma>)"
4293     using winding_number_constant [OF \<gamma> loop, of "outside(path_image \<gamma>)"] connected_outside
4294     by (metis DIM_complex bounded_path_image dual_order.refl \<gamma> outside_no_overlap)
4295   ultimately have "winding_number \<gamma> z = winding_number \<gamma> w"
4296     by (metis (no_types, hide_lams) constant_on_def z)
4297   also have "\<dots> = 0"
4298   proof -
4299     have wnot: "w \<notin> path_image \<gamma>"  using wout by (simp add: outside_def)
4300     { fix e::real assume "0<e"
4301       obtain p where p: "polynomial_function p" "pathstart p = pathstart \<gamma>" "pathfinish p = pathfinish \<gamma>"
4302                  and pg1: "(\<And>t. \<lbrakk>0 \<le> t; t \<le> 1\<rbrakk> \<Longrightarrow> cmod (p t - \<gamma> t) < 1)"
4303                  and pge: "(\<And>t. \<lbrakk>0 \<le> t; t \<le> 1\<rbrakk> \<Longrightarrow> cmod (p t - \<gamma> t) < e)"
4304         using path_approx_polynomial_function [OF \<gamma>, of "min 1 e"] \<open>e>0\<close> by force
4305       have pip: "path_image p \<subseteq> ball 0 (B + 1)"
4306         using B
4307         apply (clarsimp simp add: path_image_def dist_norm ball_def)
4308         apply (frule (1) pg1)
4309         apply (fastforce dest: norm_add_less)
4310         done
4311       then have "w \<notin> path_image p"  using w by blast
4312       then have "\<exists>p. valid_path p \<and> w \<notin> path_image p \<and>
4313                      pathstart p = pathstart \<gamma> \<and> pathfinish p = pathfinish \<gamma> \<and>
4314                      (\<forall>t\<in>{0..1}. cmod (\<gamma> t - p t) < e) \<and> contour_integral p (\<lambda>wa. 1 / (wa - w)) = 0"
4315         apply (rule_tac x=p in exI)
4316         apply (simp add: p valid_path_polynomial_function)
4317         apply (intro conjI)
4318         using pge apply (simp add: norm_minus_commute)
4319         apply (rule contour_integral_unique [OF Cauchy_theorem_convex_simple [OF _ convex_ball [of 0 "B+1"]]])
4320         apply (rule holomorphic_intros | simp add: dist_norm)+
4321         using mem_ball_0 w apply blast
4322         using p apply (simp_all add: valid_path_polynomial_function loop pip)
4323         done
4324     }
4325     then show ?thesis
4326       by (auto intro: winding_number_unique [OF \<gamma>] simp add: winding_number_prop_def wnot)
4327   qed
4328   finally show ?thesis .
4329 qed
4331 corollary%unimportant winding_number_zero_const: "a \<noteq> z \<Longrightarrow> winding_number (\<lambda>t. a) z = 0"
4332   by (rule winding_number_zero_in_outside)
4333      (auto simp: pathfinish_def pathstart_def path_polynomial_function)
4335 corollary%unimportant winding_number_zero_outside:
4336     "\<lbrakk>path \<gamma>; convex s; pathfinish \<gamma> = pathstart \<gamma>; z \<notin> s; path_image \<gamma> \<subseteq> s\<rbrakk> \<Longrightarrow> winding_number \<gamma> z = 0"
4337   by (meson convex_in_outside outside_mono subsetCE winding_number_zero_in_outside)
4339 lemma winding_number_zero_at_infinity:
4340   assumes \<gamma>: "path \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>"
4341     shows "\<exists>B. \<forall>z. B \<le> norm z \<longrightarrow> winding_number \<gamma> z = 0"
4342 proof -
4343   obtain B::real where "0 < B" and B: "path_image \<gamma> \<subseteq> ball 0 B"
4344     using bounded_subset_ballD [OF bounded_path_image [OF \<gamma>]] by auto
4345   then show ?thesis
4346     apply (rule_tac x="B+1" in exI, clarify)
4347     apply (rule winding_number_zero_outside [OF \<gamma> convex_cball [of 0 B] loop])
4348     apply (meson less_add_one mem_cball_0 not_le order_trans)
4349     using ball_subset_cball by blast
4350 qed
4352 lemma winding_number_zero_point:
4353     "\<lbrakk>path \<gamma>; convex s; pathfinish \<gamma> = pathstart \<gamma>; open s; path_image \<gamma> \<subseteq> s\<rbrakk>
4354      \<Longrightarrow> \<exists>z. z \<in> s \<and> winding_number \<gamma> z = 0"
4355   using outside_compact_in_open [of "path_image \<gamma>" s] path_image_nonempty winding_number_zero_in_outside
4356   by (fastforce simp add: compact_path_image)
4359 text\<open>If a path winds round a set, it winds rounds its inside.\<close>
4360 lemma winding_number_around_inside:
4361   assumes \<gamma>: "path \<gamma>" and loop: "pathfinish \<gamma> = pathstart \<gamma>"
4362       and cls: "closed s" and cos: "connected s" and s_disj: "s \<inter> path_image \<gamma> = {}"
4363       and z: "z \<in> s" and wn_nz: "winding_number \<gamma> z \<noteq> 0" and w: "w \<in> s \<union> inside s"
4364     shows "winding_number \<gamma> w = winding_number \<gamma> z"
4365 proof -
4366   have ssb: "s \<subseteq> inside(path_image \<gamma>)"
4367   proof
4368     fix x :: complex
4369     assume "x \<in> s"
4370     hence "x \<notin> path_image \<gamma>"
4371       by (meson disjoint_iff_not_equal s_disj)
4372     thus "x \<in> inside (path_image \<gamma>)"
4373       using \<open>x \<in> s\<close> by (metis (no_types) ComplI UnE cos \<gamma> loop s_disj union_with_outside winding_number_eq winding_number_zero_in_outside wn_nz z)
4374 qed
4375   show ?thesis
4376     apply (rule winding_number_eq [OF \<gamma> loop w])
4377     using z apply blast
4378     apply (simp add: cls connected_with_inside cos)
4379     apply (simp add: Int_Un_distrib2 s_disj, safe)
4380     by (meson ssb inside_inside_compact_connected [OF cls, of "path_image \<gamma>"] compact_path_image connected_path_image contra_subsetD disjoint_iff_not_equal \<gamma> inside_no_overlap)
4381  qed
4384 text\<open>Bounding a WN by 1/2 for a path and point in opposite halfspaces.\<close>
4385 lemma winding_number_subpath_continuous:
4386   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>"
4387     shows "continuous_on {0..1} (\<lambda>x. winding_number(subpath 0 x \<gamma>) z)"
4388 proof -
4389   have *: "integral {0..x} (\<lambda>t. vector_derivative \<gamma> (at t) / (\<gamma> t - z)) / (2 * of_real pi * \<i>) =
4390          winding_number (subpath 0 x \<gamma>) z"
4391          if x: "0 \<le> x" "x \<le> 1" for x
4392   proof -
4393     have "integral {0..x} (\<lambda>t. vector_derivative \<gamma> (at t) / (\<gamma> t - z)) / (2 * of_real pi * \<i>) =
4394           1 / (2*pi*\<i>) * contour_integral (subpath 0 x \<gamma>) (\<lambda>w. 1/(w - z))"
4395       using assms x
4396       apply (simp add: contour_integral_subcontour_integral [OF contour_integrable_inversediff])
4397       done
4398     also have "\<dots> = winding_number (subpath 0 x \<gamma>) z"
4399       apply (subst winding_number_valid_path)
4400       using assms x
4401       apply (simp_all add: path_image_subpath valid_path_subpath)
4402       by (force simp: path_image_def)
4403     finally show ?thesis .
4404   qed
4405   show ?thesis
4406     apply (rule continuous_on_eq
4407                  [where f = "\<lambda>x. 1 / (2*pi*\<i>) *
4408                                  integral {0..x} (\<lambda>t. 1/(\<gamma> t - z) * vector_derivative \<gamma> (at t))"])
4409     apply (rule continuous_intros)+
4410     apply (rule indefinite_integral_continuous_1)
4411     apply (rule contour_integrable_inversediff [OF assms, unfolded contour_integrable_on])
4412       using assms
4413     apply (simp add: *)
4414     done
4415 qed
4417 lemma winding_number_ivt_pos:
4418     assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and "0 \<le> w" "w \<le> Re(winding_number \<gamma> z)"
4419       shows "\<exists>t \<in> {0..1}. Re(winding_number(subpath 0 t \<gamma>) z) = w"
4420   apply (rule ivt_increasing_component_on_1 [of 0 1, where ?k = "1::complex", simplified complex_inner_1_right], simp)
4421   apply (rule winding_number_subpath_continuous [OF \<gamma> z])
4422   using assms
4423   apply (auto simp: path_image_def image_def)
4424   done
4426 lemma winding_number_ivt_neg:
4427     assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and "Re(winding_number \<gamma> z) \<le> w" "w \<le> 0"
4428       shows "\<exists>t \<in> {0..1}. Re(winding_number(subpath 0 t \<gamma>) z) = w"
4429   apply (rule ivt_decreasing_component_on_1 [of 0 1, where ?k = "1::complex", simplified complex_inner_1_right], simp)
4430   apply (rule winding_number_subpath_continuous [OF \<gamma> z])
4431   using assms
4432   apply (auto simp: path_image_def image_def)
4433   done
4435 lemma winding_number_ivt_abs:
4436     assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and "0 \<le> w" "w \<le> \<bar>Re(winding_number \<gamma> z)\<bar>"
4437       shows "\<exists>t \<in> {0..1}. \<bar>Re (winding_number (subpath 0 t \<gamma>) z)\<bar> = w"
4438   using assms winding_number_ivt_pos [of \<gamma> z w] winding_number_ivt_neg [of \<gamma> z "-w"]
4439   by force
4441 lemma winding_number_lt_half_lemma:
4442   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>" and az: "a \<bullet> z \<le> b" and pag: "path_image \<gamma> \<subseteq> {w. a \<bullet> w > b}"
4443     shows "Re(winding_number \<gamma> z) < 1/2"
4444 proof -
4445   { assume "Re(winding_number \<gamma> z) \<ge> 1/2"
4446     then obtain t::real where t: "0 \<le> t" "t \<le> 1" and sub12: "Re (winding_number (subpath 0 t \<gamma>) z) = 1/2"
4447       using winding_number_ivt_pos [OF \<gamma> z, of "1/2"] by auto
4448     have gt: "\<gamma> t - z = - (of_real (exp (- (2 * pi * Im (winding_number (subpath 0 t \<gamma>) z)))) * (\<gamma> 0 - z))"
4449       using winding_number_exp_2pi [of "subpath 0 t \<gamma>" z]
4450       apply (simp add: t \<gamma> valid_path_imp_path)
4451       using closed_segment_eq_real_ivl path_image_def t z by (fastforce simp: path_image_subpath Euler sub12)
4452     have "b < a \<bullet> \<gamma> 0"
4453     proof -
4454       have "\<gamma> 0 \<in> {c. b < a \<bullet> c}"
4455         by (metis (no_types) pag atLeastAtMost_iff image_subset_iff order_refl path_image_def zero_le_one)
4456       thus ?thesis
4457         by blast
4458     qed
4459     moreover have "b < a \<bullet> \<gamma> t"
4460     proof -
4461       have "\<gamma> t \<in> {c. b < a \<bullet> c}"
4462         by (metis (no_types) pag atLeastAtMost_iff image_subset_iff path_image_def t)
4463       thus ?thesis
4464         by blast
4465     qed
4466     ultimately have "0 < a \<bullet> (\<gamma> 0 - z)" "0 < a \<bullet> (\<gamma> t - z)" using az
4467       by (simp add: inner_diff_right)+
4468     then have False
4469       by (simp add: gt inner_mult_right mult_less_0_iff)
4470   }
4471   then show ?thesis by force
4472 qed
4474 lemma winding_number_lt_half:
4475   assumes "valid_path \<gamma>" "a \<bullet> z \<le> b" "path_image \<gamma> \<subseteq> {w. a \<bullet> w > b}"
4476     shows "\<bar>Re (winding_number \<gamma> z)\<bar> < 1/2"
4477 proof -
4478   have "z \<notin> path_image \<gamma>" using assms by auto
4479   with assms show ?thesis
4480     apply (simp add: winding_number_lt_half_lemma abs_if del: less_divide_eq_numeral1)
4481     apply (metis complex_inner_1_right winding_number_lt_half_lemma [OF valid_path_imp_reverse, of \<gamma> z a b]
4482                  winding_number_reversepath valid_path_imp_path inner_minus_left path_image_reversepath)
4483     done
4484 qed
4486 lemma winding_number_le_half:
4487   assumes \<gamma>: "valid_path \<gamma>" and z: "z \<notin> path_image \<gamma>"
4488       and anz: "a \<noteq> 0" and azb: "a \<bullet> z \<le> b" and pag: "path_image \<gamma> \<subseteq> {w. a \<bullet> w \<ge> b}"
4489     shows "\<bar>Re (winding_number \<gamma> z)\<bar> \<le> 1/2"
4490 proof -
4491   { assume wnz_12: "\<bar>Re (winding_number \<gamma> z)\<bar> > 1/2"
4492     have "isCont (winding_number \<gamma>) z"
4493       by (metis continuous_at_winding_number valid_path_imp_path \<gamma> z)
4494     then obtain d where "d>0" and d: "\<And>x'. dist x' z < d \<Longrightarrow> dist (winding_number \<gamma> x') (winding_number \<gamma> z) < \<bar>Re(winding_number \<gamma> z)\<bar> - 1/2"
4495       using continuous_at_eps_delta wnz_12 diff_gt_0_iff_gt by blast
4496     define z' where "z' = z - (d / (2 * cmod a)) *\<^sub>R a"
4497     have *: "a \<bullet> z' \<le> b - d / 3 * cmod a"
4498       unfolding z'_def inner_mult_right' divide_inverse
4499       apply (simp add: divide_simps algebra_simps dot_square_norm power2_eq_square anz)
4500       apply (metis \<open>0 < d\<close> add_increasing azb less_eq_real_def mult_nonneg_nonneg mult_right_mono norm_ge_zero norm_numeral)
4501       done
4502     have "cmod (winding_number \<gamma> z' - winding_number \<gamma> z) < \<bar>Re (winding_number \<gamma> z)\<bar> - 1/2"
4503       using d [of z'] anz \<open>d>0\<close> by (simp add: dist_norm z'_def)
4504     then have "1/2 < \<bar>Re (winding_number \<gamma> z)\<bar> - cmod (winding_number \<gamma> z' - winding_number \<gamma> z)"
4505       by simp
4506     then have "1/2 < \<bar>Re (winding_number \<gamma> z)\<bar> - \<bar>Re (winding_number \<gamma> z') - Re (winding_number \<gamma> z)\<bar>"
4507       using abs_Re_le_cmod [of "winding_number \<gamma> z' - winding_number \<gamma> z"] by simp
4508     then have wnz_12': "\<bar>Re (winding_number \<gamma> z')\<bar> > 1/2"
4509       by linarith
4510     moreover have "\<bar>Re (winding_number \<gamma> z')\<bar> < 1/2"
4511       apply (rule winding_number_lt_half [OF \<gamma> *])
4512       using azb \<open>d>0\<close> pag
4513       apply (auto simp: add_strict_increasing anz divide_simps algebra_simps dest!: subsetD)
4514       done
4515     ultimately have False
4516       by simp
4517   }
4518   then show ?thesis by force
4519 qed
4521 lemma winding_number_lt_half_linepath: "z \<notin> closed_segment a b \<Longrightarrow> \<bar>Re (winding_number (linepath a b) z)\<bar> < 1/2"
4522   using separating_hyperplane_closed_point [of "closed_segment a b" z]
4523   apply auto
4524   apply (simp add: closed_segment_def)
4525   apply (drule less_imp_le)
4526   apply (frule winding_number_lt_half [OF valid_path_linepath [of a b]])
4527   apply (auto simp: segment)
4528   done
4531 text\<open> Positivity of WN for a linepath.\<close>
4532 lemma winding_number_linepath_pos_lt:
4533     assumes "0 < Im ((b - a) * cnj (b - z))"
4534       shows "0 < Re(winding_number(linepath a b) z)"
4535 proof -
4536   have z: "z \<notin> path_image (linepath a b)"
4537     using assms
4538     by (simp add: closed_segment_def) (force simp: algebra_simps)
4539   show ?thesis
4540     apply (rule winding_number_pos_lt [OF valid_path_linepath z assms])
4541     apply (simp add: linepath_def algebra_simps)
4542     done
4543 qed
4546 subsection\<open>Cauchy's integral formula, again for a convex enclosing set\<close>
4548 lemma Cauchy_integral_formula_weak:
4549     assumes s: "convex s" and "finite k" and conf: "continuous_on s f"
4550         and fcd: "(\<And>x. x \<in> interior s - k \<Longrightarrow> f field_differentiable at x)"
4551         and z: "z \<in> interior s - k" and vpg: "valid_path \<gamma>"
4552         and pasz: "path_image \<gamma> \<subseteq> s - {z}" and loop: "pathfinish \<gamma> = pathstart \<gamma>"
4553       shows "((\<lambda>w. f w / (w - z)) has_contour_integral (2*pi * \<i> * winding_number \<gamma> z * f z)) \<gamma>"
4554 proof -
4555   obtain f' where f': "(f has_field_derivative f') (at z)"
4556     using fcd [OF z] by (auto simp: field_differentiable_def)
4557   have pas: "path_image \<gamma> \<subseteq> s" and znotin: "z \<notin> path_image \<gamma>" using pasz by blast+
4558   have c: "continuous (at x within s) (\<lambda>w. if w = z then f' else (f w - f z) / (w - z))" if "x \<in> s" for x
4559   proof (cases "x = z")
4560     case True then show ?thesis
4561       apply (simp add: continuous_within)
4562       apply (rule Lim_transform_away_within [of _ "z+1" _ "\<lambda>w::complex. (f w - f z)/(w - z)"])
4563       using has_field_derivative_at_within has_field_derivative_iff f'
4564       apply (fastforce simp add:)+
4565       done
4566   next
4567     case False
4568     then have dxz: "dist x z > 0" by auto
4569     have cf: "continuous (at x within s) f"
4570       using conf continuous_on_eq_continuous_within that by blast
4571     have "continuous (at x within s) (\<lambda>w. (f w - f z) / (w - z))"
4572       by (rule cf continuous_intros | simp add: False)+
4573     then show ?thesis
4574       apply (rule continuous_transform_within [OF _ dxz that, of "\<lambda>w::complex. (f w - f z)/(w - z)"])
4575       apply (force simp: dist_commute)
4576       done
4577   qed
4578   have fink': "finite (insert z k)" using \<open>finite k\<close> by blast
4579   have *: "((\<lambda>w. if w = z then f' else (f w - f z) / (w - z)) has_contour_integral 0) \<gamma>"
4580     apply (rule Cauchy_theorem_convex [OF _ s fink' _ vpg pas loop])
4581     using c apply (force simp: continuous_on_eq_continuous_within)
4582     apply (rename_tac w)
4583     apply (rule_tac d="dist w z" and f = "\<lambda>w. (f w - f z)/(w - z)" in field_differentiable_transform_within)
4584     apply (simp_all add: dist_pos_lt dist_commute)
4585     apply (metis less_irrefl)
4586     apply (rule derivative_intros fcd | simp)+
4587     done
4588   show ?thesis
4589     apply (rule has_contour_integral_eq)
4590     using znotin has_contour_integral_add [OF has_contour_integral_lmul [OF has_contour_integral_winding_number [OF vpg znotin], of "f z"] *]
4591     apply (auto simp: mult_ac divide_simps)
4592     done
4593 qed
4595 theorem Cauchy_integral_formula_convex_simple:
4596     "\<lbrakk>convex s; f holomorphic_on s; z \<in> interior s; valid_path \<gamma>; path_image \<gamma> \<subseteq> s - {z};
4597       pathfinish \<gamma> = pathstart \<gamma>\<rbrakk>
4598      \<Longrightarrow> ((\<lambda>w. f w / (w - z)) has_contour_integral (2*pi * \<i> * winding_number \<gamma> z * f z)) \<gamma>"
4599   apply (rule Cauchy_integral_formula_weak [where k = "{}"])
4600   using holomorphic_on_imp_continuous_on
4601   by auto (metis at_within_interior holomorphic_on_def interiorE subsetCE)
4603 subsection\<open>Homotopy forms of Cauchy's theorem\<close>
4605 lemma Cauchy_theorem_homotopic:
4606     assumes hom: "if atends then homotopic_paths s g h else homotopic_loops s g h"
4607         and "open s" and f: "f holomorphic_on s"
4608         and vpg: "valid_path g" and vph: "valid_path h"
4609     shows "contour_integral g f = contour_integral h f"
4610 proof -
4611   have pathsf: "linked_paths atends g h"
4612     using hom  by (auto simp: linked_paths_def homotopic_paths_imp_pathstart homotopic_paths_imp_pathfinish homotopic_loops_imp_loop)
4613   obtain k :: "real \<times> real \<Rightarrow> complex"
4614     where contk: "continuous_on ({0..1} \<times> {0..1}) k"
4615       and ks: "k ` ({0..1} \<times> {0..1}) \<subseteq> s"
4616       and k [simp]: "\<forall>x. k (0, x) = g x" "\<forall>x. k (1, x) = h x"
4617       and ksf: "\<forall>t\<in>{0..1}. linked_paths atends g (\<lambda>x. k (t, x))"
4618       using hom pathsf by (auto simp: linked_paths_def homotopic_paths_def homotopic_loops_def homotopic_with_def split: if_split_asm)
4619   have ucontk: "uniformly_continuous_on ({0..1} \<times> {0..1}) k"
4620     by (blast intro: compact_Times compact_uniformly_continuous [OF contk])
4621   { fix t::real assume t: "t \<in> {0..1}"
4622     have pak: "path (k \<circ> (\<lambda>u. (t, u)))"
4623       unfolding path_def
4624       apply (rule continuous_intros continuous_on_subset [OF contk])+
4625       using t by force
4626     have pik: "path_image (k \<circ> Pair t) \<subseteq> s"
4627       using ks t by (auto simp: path_image_def)
4628     obtain e where "e>0" and e:
4629          "\<And>g h. \<lbrakk>valid_path g; valid_path h;
4630                   \<forall>u\<in>{0..1}. cmod (g u - (k \<circ> Pair t) u) < e \<and> cmod (h u - (k \<circ> Pair t) u) < e;
4631                   linked_paths atends g h\<rbrakk>
4632                  \<Longrightarrow> contour_integral h f = contour_integral g f"
4633       using contour_integral_nearby [OF \<open>open s\<close> pak pik, of atends] f by metis
4634     obtain d where "d>0" and d:
4635         "\<And>x x'. \<lbrakk>x \<in> {0..1} \<times> {0..1}; x' \<in> {0..1} \<times> {0..1}; norm (x'-x) < d\<rbrakk> \<Longrightarrow> norm (k x' - k x) < e/4"
4636       by (rule uniformly_continuous_onE [OF ucontk, of "e/4"]) (auto simp: dist_norm \<open>e>0\<close>)
4637     { fix t1 t2
4638       assume t1: "0 \<le> t1" "t1 \<le> 1" and t2: "0 \<le> t2" "t2 \<le> 1" and ltd: "\<bar>t1 - t\<bar> < d" "\<bar>t2 - t\<bar> < d"
4639       have no2: "\<And>g1 k1 kt. \<lbrakk>norm(g1 - k1) < e/4; norm(k1 - kt) < e/4\<rbrakk> \<Longrightarrow> norm(g1 - kt) < e"
4640         using \<open>e > 0\<close>
4641         apply (rule_tac y = k1 in norm_triangle_half_l)
4642         apply (auto simp: norm_minus_commute intro: order_less_trans)
4643         done
4644       have "\<exists>d>0. \<forall>g1 g2. valid_path g1 \<and> valid_path g2 \<and>
4645                           (\<forall>u\<in>{0..1}. cmod (g1 u - k (t1, u)) < d \<and> cmod (g2 u - k (t2, u)) < d) \<and>
4646                           linked_paths atends g1 g2 \<longrightarrow>
4647                           contour_integral g2 f = contour_integral g1 f"
4648         apply (rule_tac x="e/4" in exI)
4649         using t t1 t2 ltd \<open>e > 0\<close>
4650         apply (auto intro!: e simp: d no2 simp del: less_divide_eq_numeral1)
4651         done
4652     }
4653     then have "\<exists>e. 0 < e \<and>
4654               (\<forall>t1 t2. t1 \<in> {0..1} \<and> t2 \<in> {0..1} \<and> \<bar>t1 - t\<bar> < e \<and> \<bar>t2 - t\<bar> < e
4655                 \<longrightarrow> (\<exists>d. 0 < d \<and>
4656                      (\<forall>g1 g2. valid_path g1 \<and> valid_path g2 \<and>
4657                        (\<forall>u \<in> {0..1}.
4658                           norm(g1 u - k((t1,u))) < d \<and> norm(g2 u - k((t2,u))) < d) \<and>
4659                           linked_paths atends g1 g2
4660                           \<longrightarrow> contour_integral g2 f = contour_integral g1 f)))"
4661       by (rule_tac x=d in exI) (simp add: \<open>d > 0\<close>)
4662   }
4663   then obtain ee where ee:
4664        "\<And>t. t \<in> {0..1} \<Longrightarrow> ee t > 0 \<and>
4665           (\<forall>t1 t2. t1 \<in> {0..1} \<longrightarrow> t2 \<in> {0..1} \<longrightarrow> \<bar>t1 - t\<bar> < ee t \<longrightarrow> \<bar>t2 - t\<bar> < ee t
4666             \<longrightarrow> (\<exists>d. 0 < d \<and>
4667                  (\<forall>g1 g2. valid_path g1 \<and> valid_path g2 \<and>
4668                    (\<forall>u \<in> {0..1}.
4669                       norm(g1 u - k((t1,u))) < d \<and> norm(g2 u - k((t2,u))) < d) \<and>
4670                       linked_paths atends g1 g2
4671                       \<longrightarrow> contour_integral g2 f = contour_integral g1 f)))"
4672     by metis
4673   note ee_rule = ee [THEN conjunct2, rule_format]
4674   define C where "C = (\<lambda>t. ball t (ee t / 3)) ` {0..1}"
4675   obtain C' where C': "C' \<subseteq> C" "finite C'" and C'01: "{0..1} \<subseteq> \<Union>C'"
4676   proof (rule compactE [OF compact_interval])
4677     show "{0..1} \<subseteq> \<Union>C"
4678       using ee [THEN conjunct1] by (auto simp: C_def dist_norm)
4679   qed (use C_def in auto)
4680   define kk where "kk = {t \<in> {0..1}. ball t (ee t / 3) \<in> C'}"
4681   have kk01: "kk \<subseteq> {0..1}" by (auto simp: kk_def)
4682   define e where "e = Min (ee ` kk)"
4683   have C'_eq: "C' = (\<lambda>t. ball t (ee t / 3)) ` kk"
4684     using C' by (auto simp: kk_def C_def)
4685   have ee_pos[simp]: "\<And>t. t \<in> {0..1} \<Longrightarrow> ee t > 0"
4686     by (simp add: kk_def ee)
4687   moreover have "finite kk"
4688     using \<open>finite C'\<close> kk01 by (force simp: C'_eq inj_on_def ball_eq_ball_iff dest: ee_pos finite_imageD)
4689   moreover have "kk \<noteq> {}" using \<open>{0..1} \<subseteq> \<Union>C'\<close> C'_eq by force
4690   ultimately have "e > 0"
4691     using finite_less_Inf_iff [of "ee ` kk" 0] kk01 by (force simp: e_def)
4692   then obtain N::nat where "N > 0" and N: "1/N < e/3"
4693     by (meson divide_pos_pos nat_approx_posE zero_less_Suc zero_less_numeral)
4694   have e_le_ee: "\<And>i. i \<in> kk \<Longrightarrow> e \<le> ee i"
4695     using \<open>finite kk\<close> by (simp add: e_def Min_le_iff [of "ee ` kk"])
4696   have plus: "\<exists>t \<in> kk. x \<in> ball t (ee t / 3)" if "x \<in> {0..1}" for x
4697     using C' subsetD [OF C'01 that]  unfolding C'_eq by blast
4698   have [OF order_refl]:
4699       "\<exists>d. 0 < d \<and> (\<forall>j. valid_path j \<and> (\<forall>u \<in> {0..1}. norm(j u - k (n/N, u)) < d) \<and> linked_paths atends g j
4700                         \<longrightarrow> contour_integral j f = contour_integral g f)"
4701        if "n \<le> N" for n
4702   using that
4703   proof (induct n)
4704     case 0 show ?case using ee_rule [of 0 0 0]
4705       apply clarsimp
4706       apply (rule_tac x=d in exI, safe)
4707       by (metis diff_self vpg norm_zero)
4708   next
4709     case (Suc n)
4710     then have N01: "n/N \<in> {0..1}" "(Suc n)/N \<in> {0..1}"  by auto
4711     then obtain t where t: "t \<in> kk" "n/N \<in> ball t (ee t / 3)"
4712       using plus [of "n/N"] by blast
4713     then have nN_less: "\<bar>n/N - t\<bar> < ee t"
4714       by (simp add: dist_norm del: less_divide_eq_numeral1)
4715     have n'N_less: "\<bar>real (Suc n) / real N - t\<bar> < ee t"
4716       using t N \<open>N > 0\<close> e_le_ee [of t]
4717       by (simp add: dist_norm add_divide_distrib abs_diff_less_iff del: less_divide_eq_numeral1) (simp add: field_simps)
4718     have t01: "t \<in> {0..1}" using \<open>kk \<subseteq> {0..1}\<close> \<open>t \<in> kk\<close> by blast
4719     obtain d1 where "d1 > 0" and d1:
4720         "\<And>g1 g2. \<lbrakk>valid_path g1; valid_path g2;
4721                    \<forall>u\<in>{0..1}. cmod (g1 u - k (n/N, u)) < d1 \<and> cmod (g2 u - k ((Suc n) / N, u)) < d1;
4722                    linked_paths atends g1 g2\<rbrakk>
4723                    \<Longrightarrow> contour_integral g2 f = contour_integral g1 f"
4724       using ee [THEN conjunct2, rule_format, OF t01 N01 nN_less n'N_less] by fastforce
4725     have "n \<le> N" using Suc.prems by auto
4726     with Suc.hyps
4727     obtain d2 where "d2 > 0"
4728       and d2: "\<And>j. \<lbrakk>valid_path j; \<forall>u\<in>{0..1}. cmod (j u - k (n/N, u)) < d2; linked_paths atends g j\<rbrakk>
4729                      \<Longrightarrow> contour_integral j f = contour_integral g f"
4730         by auto
4731     have "continuous_on {0..1} (k \<circ> (\<lambda>u. (n/N, u)))"
4732       apply (rule continuous_intros continuous_on_subset [OF contk])+
4733       using N01 by auto
4734     then have pkn: "path (\<lambda>u. k (n/N, u))"
4735       by (simp add: path_def)
4736     have min12: "min d1 d2 > 0" by (simp add: \<open>0 < d1\<close> \<open>0 < d2\<close>)
4737     obtain p where "polynomial_function p"
4738         and psf: "pathstart p = pathstart (\<lambda>u. k (n/N, u))"
4739                  "pathfinish p = pathfinish (\<lambda>u. k (n/N, u))"
4740         and pk_le:  "\<And>t. t\<in>{0..1} \<Longrightarrow> cmod (p t - k (n/N, t)) < min d1 d2"
4741       using path_approx_polynomial_function [OF pkn min12] by blast
4742     then have vpp: "valid_path p" using valid_path_polynomial_function by blast
4743     have lpa: "linked_paths atends g p"
4744       by (metis (mono_tags, lifting) N01(1) ksf linked_paths_def pathfinish_def pathstart_def psf)
4745     show ?case
4746     proof (intro exI; safe)
4747       fix j
4748       assume "valid_path j" "linked_paths atends g j"
4749         and "\<forall>u\<in>{0..1}. cmod (j u - k (real (Suc n) / real N, u)) < min d1 d2"
4750       then have "contour_integral j f = contour_integral p f"
4751         using pk_le N01(1) ksf by (force intro!: vpp d1 simp add: linked_paths_def psf)
4752       also have "... = contour_integral g f"
4753         using pk_le by (force intro!: vpp d2 lpa)
4754       finally show "contour_integral j f = contour_integral g f" .
4755     qed (simp add: \<open>0 < d1\<close> \<open>0 < d2\<close>)
4756   qed
4757   then obtain d where "0 < d"
4758                        "\<And>j. valid_path j \<and> (\<forall>u \<in> {0..1}. norm(j u - k (1,u)) < d) \<and> linked_paths atends g j
4759                             \<Longrightarrow> contour_integral j f = contour_integral g f"
4760     using \<open>N>0\<close> by auto
4761   then have "linked_paths atends g h \<Longrightarrow> contour_integral h f = contour_integral g f"
4762     using \<open>N>0\<close> vph by fastforce
4763   then show ?thesis
4764     by (simp add: pathsf)
4765 qed
4767 proposition Cauchy_theorem_homotopic_paths:
4768     assumes hom: "homotopic_paths s g h"
4769         and "open s" and f: "f holomorphic_on s"
4770         and vpg: "valid_path g" and vph: "valid_path h"
4771     shows "contour_integral g f = contour_integral h f"
4772   using Cauchy_theorem_homotopic [of True s g h] assms by simp
4774 proposition Cauchy_theorem_homotopic_loops:
4775     assumes hom: "homotopic_loops s g h"
4776         and "open s" and f: "f holomorphic_on s"
4777         and vpg: "valid_path g" and vph: "valid_path h"
4778     shows "contour_integral g f = contour_integral h f"
4779   using Cauchy_theorem_homotopic [of False s g h] assms by simp
4781 lemma has_contour_integral_newpath:
4782     "\<lbrakk>(f has_contour_integral y) h; f contour_integrable_on g; contour_integral g f = contour_integral h f\<rbrakk>
4783      \<Longrightarrow> (f has_contour_integral y) g"
4784   using has_contour_integral_integral contour_integral_unique by auto
4786 lemma Cauchy_theorem_null_homotopic:
4787      "\<lbrakk>f holomorphic_on s; open s; valid_path g; homotopic_loops s g (linepath a a)\<rbrakk> \<Longrightarrow> (f has_contour_integral 0) g"
4788   apply (rule has_contour_integral_newpath [where h = "linepath a a"], simp)
4789   using contour_integrable_holomorphic_simple
4790     apply (blast dest: holomorphic_on_imp_continuous_on homotopic_loops_imp_subset)
4791   by (simp add: Cauchy_theorem_homotopic_loops)
4793 subsection%unimportant \<open>More winding number properties\<close>
4795 text\<open>including the fact that it's +-1 inside a simple closed curve.\<close>
4797 lemma winding_number_homotopic_paths:
4798     assumes "homotopic_paths (-{z}) g h"
4799       shows "winding_number g z = winding_number h z"
4800 proof -
4801   have "path g" "path h" using homotopic_paths_imp_path [OF assms] by auto
4802   moreover have pag: "z \<notin> path_image g" and pah: "z \<notin> path_image h"
4803     using homotopic_paths_imp_subset [OF assms] by auto
4804   ultimately obtain d e where "d > 0" "e > 0"
4805       and d: "\<And>p. \<lbrakk>path p; pathstart p = pathstart g; pathfinish p = pathfinish g; \<forall>t\<in>{0..1}. norm (p t - g t) < d\<rbrakk>
4806             \<Longrightarrow> homotopic_paths (-{z}) g p"
4807       and e: "\<And>q. \<lbrakk>path q; pathstart q = pathstart h; pathfinish q = pathfinish h; \<forall>t\<in>{0..1}. norm (q t - h t) < e\<rbrakk>
4808             \<Longrightarrow> homotopic_paths (-{z}) h q"
4809     using homotopic_nearby_paths [of g "-{z}"] homotopic_nearby_paths [of h "-{z}"] by force
4810   obtain p where p:
4811        "valid_path p" "z \<notin> path_image p"
4812        "pathstart p = pathstart g" "pathfinish p = pathfinish g"
4813        and gp_less:"\<forall>t\<in>{0..1}. cmod (g t - p t) < d"
4814        and pap: "contour_integral p (\<lambda>w. 1 / (w - z)) = complex_of_real (2 * pi) * \<i> * winding_number g z"
4815     using winding_number [OF \<open>path g\<close> pag \<open>0 < d\<close>] unfolding winding_number_prop_def by blast
4816   obtain q where q:
4817        "valid_path q" "z \<notin> path_image q"
4818        "pathstart q = pathstart h" "pathfinish q = pathfinish h"
4819        and hq_less: "\<forall>t\<in>{0..1}. cmod (h t - q t) < e"
4820        and paq:  "contour_integral q (\<lambda>w. 1 / (w - z)) = complex_of_real (2 * pi) * \<i> * winding_number h z"
4821     using winding_number [OF \<open>path h\<close> pah \<open>0 < e\<close>] unfolding winding_number_prop_def by blast
4822   have "homotopic_paths (- {z}) g p"
4823     by (simp add: d p valid_path_imp_path norm_minus_commute gp_less)
4824   moreover have "homotopic_paths (- {z}) h q"
4825     by (simp add: e q valid_path_imp_path norm_minus_commute hq_less)
4826   ultimately have "homotopic_paths (- {z}) p q"
4827     by (blast intro: homotopic_paths_trans homotopic_paths_sym assms)
4828   then have "contour_integral p (\<lambda>w. 1/(w - z)) = contour_integral q (\<lambda>w. 1/(w - z))"
4829     by (rule Cauchy_theorem_homotopic_paths) (auto intro!: holomorphic_intros simp: p q)
4830   then show ?thesis
4831     by (simp add: pap paq)
4832 qed
4834 lemma winding_number_homotopic_loops:
4835     assumes "homotopic_loops (-{z}) g h"
4836       shows "winding_number g z = winding_number h z"
4837 proof -
4838   have "path g" "path h" using homotopic_loops_imp_path [OF assms] by auto
4839   moreover have pag: "z \<notin> path_image g" and pah: "z \<notin> path_image h"
4840     using homotopic_loops_imp_subset [OF assms] by auto
4841   moreover have gloop: "pathfinish g = pathstart g" and hloop: "pathfinish h = pathstart h"
4842     using homotopic_loops_imp_loop [OF assms] by auto
4843   ultimately obtain d e where "d > 0" "e > 0"
4844       and d: "\<And>p. \<lbrakk>path p; pathfinish p = pathstart p; \<forall>t\<in>{0..1}. norm (p t - g t) < d\<rbrakk>
4845             \<Longrightarrow> homotopic_loops (-{z}) g p"
4846       and e: "\<And>q. \<lbrakk>path q; pathfinish q = pathstart q; \<forall>t\<in>{0..1}. norm (q t - h t) < e\<rbrakk>
4847             \<Longrightarrow> homotopic_loops (-{z}) h q"
4848     using homotopic_nearby_loops [of g "-{z}"] homotopic_nearby_loops [of h "-{z}"] by force
4849   obtain p where p:
4850        "valid_path p" "z \<notin> path_image p"
4851        "pathstart p = pathstart g" "pathfinish p = pathfinish g"
4852        and gp_less:"\<forall>t\<in>{0..1}. cmod (g t - p t) < d"
4853        and pap: "contour_integral p (\<lambda>w. 1 / (w - z)) = complex_of_real (2 * pi) * \<i> * winding_number g z"
4854     using winding_number [OF \<open>path g\<close> pag \<open>0 < d\<close>] unfolding winding_number_prop_def by blast
4855   obtain q where q:
4856        "valid_path q" "z \<notin> path_image q"
4857        "pathstart q = pathstart h" "pathfinish q = pathfinish h"
4858        and hq_less: "\<forall>t\<in>{0..1}. cmod (h t - q t) < e"
4859        and paq:  "contour_integral q (\<lambda>w. 1 / (w - z)) = complex_of_real (2 * pi) * \<i> * winding_number h z"
4860     using winding_number [OF \<open>path h\<close> pah \<open>0 < e\<close>] unfolding winding_number_prop_def by blast
4861   have gp: "homotopic_loops (- {z}) g p"
4862     by (simp add: gloop d gp_less norm_minus_commute p valid_path_imp_path)
4863   have hq: "homotopic_loops (- {z}) h q"
4864     by (simp add: e hloop hq_less norm_minus_commute q valid_path_imp_path)
4865   have "contour_integral p (\<lambda>w. 1/(w - z)) = contour_integral q (\<lambda>w. 1/(w - z))"
4866   proof (rule Cauchy_theorem_homotopic_loops)
4867     show "homotopic_loops (- {z}) p q"
4868       by (blast intro: homotopic_loops_trans homotopic_loops_sym gp hq assms)
4869   qed (auto intro!: holomorphic_intros simp: p q)
4870   then show ?thesis
4871     by (simp add: pap paq)
4872 qed
4874 lemma winding_number_paths_linear_eq:
4875   "\<lbrakk>path g; path h; pathstart h = pathstart g; pathfinish h = pathfinish g;
4876     \<And>t. t \<in> {0..1} \<Longrightarrow> z \<notin> closed_segment (g t) (h t)\<rbrakk>
4877         \<Longrightarrow> winding_number h z = winding_number g z"
4878   by (blast intro: sym homotopic_paths_linear winding_number_homotopic_paths)
4880 lemma winding_number_loops_linear_eq:
4881   "\<lbrakk>path g; path h; pathfinish g = pathstart g; pathfinish h = pathstart h;
4882     \<And>t. t \<in> {0..1} \<Longrightarrow> z \<notin> closed_segment (g t) (h t)\<rbrakk>
4883         \<Longrightarrow> winding_number h z = winding_number g z"
4884   by (blast intro: sym homotopic_loops_linear winding_number_homotopic_loops)
4886 lemma winding_number_nearby_paths_eq:
4887      "\<lbrakk>path g; path h; pathstart h = pathstart g; pathfinish h = pathfinish g;
4888       \<And>t. t \<in> {0..1} \<Longrightarrow> norm(h t - g t) < norm(g t - z)\<rbrakk>
4889       \<Longrightarrow> winding_number h z = winding_number g z"
4890   by (metis segment_bound(2) norm_minus_commute not_le winding_number_paths_linear_eq)
4892 lemma winding_number_nearby_loops_eq:
4893      "\<lbrakk>path g; path h; pathfinish g = pathstart g; pathfinish h = pathstart h;
4894       \<And>t. t \<in> {0..1} \<Longrightarrow> norm(h t - g t) < norm(g t - z)\<rbrakk>
4895       \<Longrightarrow> winding_number h z = winding_number g z"
4896   by (metis segment_bound(2) norm_minus_commute not_le winding_number_loops_linear_eq)
4899 lemma winding_number_subpath_combine:
4900     "\<lbrakk>path g; z \<notin> path_image g;
4901       u \<in> {0..1}; v \<in> {0..1}; w \<in> {0..1}\<rbrakk>
4902       \<Longrightarrow> winding_number (subpath u v g) z + winding_number (subpath v w g) z =
4903           winding_number (subpath u w g) z"
4904 apply (rule trans [OF winding_number_join [THEN sym]
4905                       winding_number_homotopic_paths [OF homotopic_join_subpaths]])
4906   using path_image_subpath_subset by auto
4908 subsection\<open>Partial circle path\<close>
4910 definition%important part_circlepath :: "[complex, real, real, real, real] \<Rightarrow> complex"
4911   where "part_circlepath z r s t \<equiv> \<lambda>x. z + of_real r * exp (\<i> * of_real (linepath s t x))"
4913 lemma pathstart_part_circlepath [simp]:
4914      "pathstart(part_circlepath z r s t) = z + r*exp(\<i> * s)"
4915 by (metis part_circlepath_def pathstart_def pathstart_linepath)
4917 lemma pathfinish_part_circlepath [simp]:
4918      "pathfinish(part_circlepath z r s t) = z + r*exp(\<i>*t)"
4919 by (metis part_circlepath_def pathfinish_def pathfinish_linepath)
4921 lemma reversepath_part_circlepath[simp]:
4922     "reversepath (part_circlepath z r s t) = part_circlepath z r t s"
4923   unfolding part_circlepath_def reversepath_def linepath_def
4924   by (auto simp:algebra_simps)
4926 lemma has_vector_derivative_part_circlepath [derivative_intros]:
4927     "((part_circlepath z r s t) has_vector_derivative
4928       (\<i> * r * (of_real t - of_real s) * exp(\<i> * linepath s t x)))
4929      (at x within X)"
4930   apply (simp add: part_circlepath_def linepath_def scaleR_conv_of_real)
4931   apply (rule has_vector_derivative_real_complex)
4932   apply (rule derivative_eq_intros | simp)+
4933   done
4935 lemma differentiable_part_circlepath:
4936   "part_circlepath c r a b differentiable at x within A"
4937   using has_vector_derivative_part_circlepath[of c r a b x A] differentiableI_vector by blast
4939 lemma vector_derivative_part_circlepath:
4940     "vector_derivative (part_circlepath z r s t) (at x) =
4941        \<i> * r * (of_real t - of_real s) * exp(\<i> * linepath s t x)"
4942   using has_vector_derivative_part_circlepath vector_derivative_at by blast
4944 lemma vector_derivative_part_circlepath01:
4945     "\<lbrakk>0 \<le> x; x \<le> 1\<rbrakk>
4946      \<Longrightarrow> vector_derivative (part_circlepath z r s t) (at x within {0..1}) =
4947           \<i> * r * (of_real t - of_real s) * exp(\<i> * linepath s t x)"
4948   using has_vector_derivative_part_circlepath
4949   by (auto simp: vector_derivative_at_within_ivl)
4951 lemma valid_path_part_circlepath [simp]: "valid_path (part_circlepath z r s t)"
4952   apply (simp add: valid_path_def)
4953   apply (rule C1_differentiable_imp_piecewise)
4954   apply (auto simp: C1_differentiable_on_eq vector_derivative_works vector_derivative_part_circlepath has_vector_derivative_part_circlepath
4955               intro!: continuous_intros)
4956   done
4958 lemma path_part_circlepath [simp]: "path (part_circlepath z r s t)"
4959   by (simp add: valid_path_imp_path)
4961 proposition path_image_part_circlepath:
4962   assumes "s \<le> t"
4963     shows "path_image (part_circlepath z r s t) = {z + r * exp(\<i> * of_real x) | x. s \<le> x \<and> x \<le> t}"
4964 proof -
4965   { fix z::real
4966     assume "0 \<le> z" "z \<le> 1"
4967     with \<open>s \<le> t\<close> have "\<exists>x. (exp (\<i> * linepath s t z) = exp (\<i> * of_real x)) \<and> s \<le> x \<and> x \<le> t"
4968       apply (rule_tac x="(1 - z) * s + z * t" in exI)
4969       apply (simp add: linepath_def scaleR_conv_of_real algebra_simps)
4970       apply (rule conjI)
4971       using mult_right_mono apply blast
4972       using affine_ineq  by (metis "mult.commute")
4973   }
4974   moreover
4975   { fix z
4976     assume "s \<le> z" "z \<le> t"
4977     then have "z + of_real r * exp (\<i> * of_real z) \<in> (\<lambda>x. z + of_real r * exp (\<i> * linepath s t x)) ` {0..1}"
4978       apply (rule_tac x="(z - s)/(t - s)" in image_eqI)
4979       apply (simp add: linepath_def scaleR_conv_of_real divide_simps exp_eq)
4980       apply (auto simp: algebra_simps divide_simps)
4981       done
4982   }
4983   ultimately show ?thesis
4984     by (fastforce simp add: path_image_def part_circlepath_def)
4985 qed
4987 lemma path_image_part_circlepath':
4988   "path_image (part_circlepath z r s t) = (\<lambda>x. z + r * cis x) ` closed_segment s t"
4989 proof -
4990   have "path_image (part_circlepath z r s t) =
4991           (\<lambda>x. z + r * exp(\<i> * of_real x)) ` linepath s t ` {0..1}"
4992     by (simp add: image_image path_image_def part_circlepath_def)
4993   also have "linepath s t ` {0..1} = closed_segment s t"
4994     by (rule linepath_image_01)
4995   finally show ?thesis by (simp add: cis_conv_exp)
4996 qed
4998 lemma path_image_part_circlepath_subset:
4999     "\<lbrakk>s \<le> t; 0 \<le> r\<rbrakk> \<Longrightarrow> path_image(part_circlepath z r s t) \<subseteq> sphere z r"
5000 by (auto simp: path_image_part_circlepath sphere_def dist_norm algebra_simps norm_mult)
5002 lemma in_path_image_part_circlepath:
5003   assumes "w \<in> path_image(part_circlepath z r s t)" "s \<le> t" "0 \<le> r"
5004     shows "norm(w - z) = r"
5005 proof -
5006   have "w \<in> {c. dist z c = r}"
5007     by (metis (no_types) path_image_part_circlepath_subset sphere_def subset_eq assms)
5008   thus ?thesis
5009     by (simp add: dist_norm norm_minus_commute)
5010 qed
5012 lemma path_image_part_circlepath_subset':
5013   assumes "r \<ge> 0"
5014   shows   "path_image (part_circlepath z r s t) \<subseteq> sphere z r"
5015 proof (cases "s \<le> t")
5016   case True
5017   thus ?thesis using path_image_part_circlepath_subset[of s t r z] assms by simp
5018 next
5019   case False
5020   thus ?thesis using path_image_part_circlepath_subset[of t s r z] assms
5021     by (subst reversepath_part_circlepath [symmetric], subst path_image_reversepath) simp_all
5022 qed
5024 lemma part_circlepath_cnj: "cnj (part_circlepath c r a b x) = part_circlepath (cnj c) r (-a) (-b) x"
5025   by (simp add: part_circlepath_def exp_cnj linepath_def algebra_simps)
5027 lemma contour_integral_bound_part_circlepath:
5028   assumes "f contour_integrable_on part_circlepath c r a b"
5029   assumes "B \<ge> 0" "r \<ge> 0" "\<And>x. x \<in> path_image (part_circlepath c r a b) \<Longrightarrow> norm (f x) \<le> B"
5030   shows   "norm (contour_integral (part_circlepath c r a b) f) \<le> B * r * \<bar>b - a\<bar>"
5031 proof -
5032   let ?I = "integral {0..1} (\<lambda>x. f (part_circlepath c r a b x) * \<i> * of_real (r * (b - a)) *
5033               exp (\<i> * linepath a b x))"
5034   have "norm ?I \<le> integral {0..1} (\<lambda>x::real. B * 1 * (r * \<bar>b - a\<bar>) * 1)"
5035   proof (rule integral_norm_bound_integral, goal_cases)
5036     case 1
5037     with assms(1) show ?case
5038       by (simp add: contour_integrable_on vector_derivative_part_circlepath mult_ac)
5039   next
5040     case (3 x)
5041     with assms(2-) show ?case unfolding norm_mult norm_of_real abs_mult
5042       by (intro mult_mono) (auto simp: path_image_def)
5043   qed auto
5044   also have "?I = contour_integral (part_circlepath c r a b) f"
5045     by (simp add: contour_integral_integral vector_derivative_part_circlepath mult_ac)
5046   finally show ?thesis by simp
5047 qed
5049 lemma has_contour_integral_part_circlepath_iff:
5050   assumes "a < b"
5051   shows "(f has_contour_integral I) (part_circlepath c r a b) \<longleftrightarrow>
5052            ((\<lambda>t. f (c + r * cis t) * r * \<i> * cis t) has_integral I) {a..b}"
5053 proof -
5054   have "(f has_contour_integral I) (part_circlepath c r a b) \<longleftrightarrow>
5055           ((\<lambda>x. f (part_circlepath c r a b x) * vector_derivative (part_circlepath c r a b)
5056            (at x within {0..1})) has_integral I) {0..1}"
5057     unfolding has_contour_integral_def ..
5058   also have "\<dots> \<longleftrightarrow> ((\<lambda>x. f (part_circlepath c r a b x) * r * (b - a) * \<i> *
5059                             cis (linepath a b x)) has_integral I) {0..1}"
5060     by (intro has_integral_cong, subst vector_derivative_part_circlepath01)
5061        (simp_all add: cis_conv_exp)
5062   also have "\<dots> \<longleftrightarrow> ((\<lambda>x. f (c + r * exp (\<i> * linepath (of_real a) (of_real b) x)) *
5063                        r * \<i> * exp (\<i> * linepath (of_real a) (of_real b) x) *
5064                        vector_derivative (linepath (of_real a) (of_real b))
5065                          (at x within {0..1})) has_integral I) {0..1}"
5066     by (intro has_integral_cong, subst vector_derivative_linepath_within)
5067        (auto simp: part_circlepath_def cis_conv_exp of_real_linepath [symmetric])
5068   also have "\<dots> \<longleftrightarrow> ((\<lambda>z. f (c + r * exp (\<i> * z)) * r * \<i> * exp (\<i> * z)) has_contour_integral I)
5069                       (linepath (of_real a) (of_real b))"
5070     by (simp add: has_contour_integral_def)
5071   also have "\<dots> \<longleftrightarrow> ((\<lambda>t. f (c + r * cis t) * r * \<i> * cis t) has_integral I) {a..b}" using assms
5072     by (subst has_contour_integral_linepath_Reals_iff) (simp_all add: cis_conv_exp)
5073   finally show ?thesis .
5074 qed
5076 lemma contour_integrable_part_circlepath_iff:
5077   assumes "a < b"
5078   shows "f contour_integrable_on (part_circlepath c r a b) \<longleftrightarrow>
5079            (\<lambda>t. f (c + r * cis t) * r * \<i> * cis t) integrable_on {a..b}"
5080   using assms by (auto simp: contour_integrable_on_def integrable_on_def
5081                              has_contour_integral_part_circlepath_iff)
5083 lemma contour_integral_part_circlepath_eq:
5084   assumes "a < b"
5085   shows "contour_integral (part_circlepath c r a b) f =
5086            integral {a..b} (\<lambda>t. f (c + r * cis t) * r * \<i> * cis t)"
5087 proof (cases "f contour_integrable_on part_circlepath c r a b")
5088   case True
5089   hence "(\<lambda>t. f (c + r * cis t) * r * \<i> * cis t) integrable_on {a..b}"
5090     using assms by (simp add: contour_integrable_part_circlepath_iff)
5091   with True show ?thesis
5092     using has_contour_integral_part_circlepath_iff[OF assms]
5093           contour_integral_unique has_integral_integrable_integral by blast
5094 next
5095   case False
5096   hence "\<not>(\<lambda>t. f (c + r * cis t) * r * \<i> * cis t) integrable_on {a..b}"
5097     using assms by (simp add: contour_integrable_part_circlepath_iff)
5098   with False show ?thesis
5099     by (simp add: not_integrable_contour_integral not_integrable_integral)
5100 qed
5102 lemma contour_integral_part_circlepath_reverse:
5103   "contour_integral (part_circlepath c r a b) f = -contour_integral (part_circlepath c r b a) f"
5104   by (subst reversepath_part_circlepath [symmetric], subst contour_integral_reversepath) simp_all
5106 lemma contour_integral_part_circlepath_reverse':
5107   "b < a \<Longrightarrow> contour_integral (part_circlepath c r a b) f =
5108                -contour_integral (part_circlepath c r b a) f"
5109   by (rule contour_integral_part_circlepath_reverse)
5111 lemma finite_bounded_log: "finite {z::complex. norm z \<le> b \<and> exp z = w}"
5112 proof (cases "w = 0")
5113   case True then show ?thesis by auto
5114 next
5115   case False
5116   have *: "finite {x. cmod (complex_of_real (2 * real_of_int x * pi) * \<i>) \<le> b + cmod (Ln w)}"
5117     apply (simp add: norm_mult finite_int_iff_bounded_le)
5118     apply (rule_tac x="\<lfloor>(b + cmod (Ln w)) / (2*pi)\<rfloor>" in exI)
5119     apply (auto simp: divide_simps le_floor_iff)
5120     done
5121   have [simp]: "\<And>P f. {z. P z \<and> (\<exists>n. z = f n)} = f ` {n. P (f n)}"
5122     by blast
5123   show ?thesis
5124     apply (subst exp_Ln [OF False, symmetric])
5125     apply (simp add: exp_eq)
5126     using norm_add_leD apply (fastforce intro: finite_subset [OF _ *])
5127     done
5128 qed
5130 lemma finite_bounded_log2:
5131   fixes a::complex
5132     assumes "a \<noteq> 0"
5133     shows "finite {z. norm z \<le> b \<and> exp(a*z) = w}"
5134 proof -
5135   have *: "finite ((\<lambda>z. z / a) ` {z. cmod z \<le> b * cmod a \<and> exp z = w})"
5136     by (rule finite_imageI [OF finite_bounded_log])
5137   show ?thesis
5138     by (rule finite_subset [OF _ *]) (force simp: assms norm_mult)
5139 qed
5141 lemma has_contour_integral_bound_part_circlepath_strong:
5142   assumes fi: "(f has_contour_integral i) (part_circlepath z r s t)"
5143       and "finite k" and le: "0 \<le> B" "0 < r" "s \<le> t"
5144       and B: "\<And>x. x \<in> path_image(part_circlepath z r s t) - k \<Longrightarrow> norm(f x) \<le> B"
5145     shows "cmod i \<le> B * r * (t - s)"
5146 proof -
5147   consider "s = t" | "s < t" using \<open>s \<le> t\<close> by linarith
5148   then show ?thesis
5149   proof cases
5150     case 1 with fi [unfolded has_contour_integral]
5151     have "i = 0"  by (simp add: vector_derivative_part_circlepath)
5152     with assms show ?thesis by simp
5153   next
5154     case 2
5155     have [simp]: "\<bar>r\<bar> = r" using \<open>r > 0\<close> by linarith
5156     have [simp]: "cmod (complex_of_real t - complex_of_real s) = t-s"
5157       by (metis "2" abs_of_pos diff_gt_0_iff_gt norm_of_real of_real_diff)
5158     have "finite (part_circlepath z r s t -` {y} \<inter> {0..1})" if "y \<in> k" for y
5159     proof -
5160       define w where "w = (y - z)/of_real r / exp(\<i> * of_real s)"
5161       have fin: "finite (of_real -` {z. cmod z \<le> 1 \<and> exp (\<i> * complex_of_real (t - s) * z) = w})"
5162         apply (rule finite_vimageI [OF finite_bounded_log2])
5163         using \<open>s < t\<close> apply (auto simp: inj_of_real)
5164         done
5165       show ?thesis
5166         apply (simp add: part_circlepath_def linepath_def vimage_def)
5167         apply (rule finite_subset [OF _ fin])
5168         using le
5169         apply (auto simp: w_def algebra_simps scaleR_conv_of_real exp_add exp_diff)
5170         done
5171     qed
5172     then have fin01: "finite ((part_circlepath z r s t) -` k \<inter> {0..1})"
5173       by (rule finite_finite_vimage_IntI [OF \<open>finite k\<close>])
5174     have **: "((\<lambda>x. if (part_circlepath z r s t x) \<in> k then 0
5175                     else f(part_circlepath z r s t x) *
5176                        vector_derivative (part_circlepath z r s t) (at x)) has_integral i)  {0..1}"
5177       by (rule has_integral_spike [OF negligible_finite [OF fin01]])  (use fi has_contour_integral in auto)
5178     have *: "\<And>x. \<lbrakk>0 \<le> x; x \<le> 1; part_circlepath z r s t x \<notin> k\<rbrakk> \<Longrightarrow> cmod (f (part_circlepath z r s t x)) \<le> B"
5179       by (auto intro!: B [unfolded path_image_def image_def, simplified])
5180     show ?thesis
5181       apply (rule has_integral_bound [where 'a=real, simplified, OF _ **, simplified])
5182       using assms apply force
5183       apply (simp add: norm_mult vector_derivative_part_circlepath)
5184       using le * "2" \<open>r > 0\<close> by auto
5185   qed
5186 qed
5188 lemma has_contour_integral_bound_part_circlepath:
5189       "\<lbrakk>(f has_contour_integral i) (part_circlepath z r s t);
5190         0 \<le> B; 0 < r; s \<le> t;
5191         \<And>x. x \<in> path_image(part_circlepath z r s t) \<Longrightarrow> norm(f x) \<le> B\<rbrakk>
5192        \<Longrightarrow> norm i \<le> B*r*(t - s)"
5193   by (auto intro: has_contour_integral_bound_part_circlepath_strong)
5195 lemma contour_integrable_continuous_part_circlepath:
5196      "continuous_on (path_image (part_circlepath z r s t)) f
5197       \<Longrightarrow> f contour_integrable_on (part_circlepath z r s t)"
5198   apply (simp add: contour_integrable_on has_contour_integral_def vector_derivative_part_circlepath path_image_def)
5199   apply (rule integrable_continuous_real)
5200   apply (fast intro: path_part_circlepath [unfolded path_def] continuous_intros continuous_on_compose2 [where g=f, OF _ _ order_refl])
5201   done
5203 proposition winding_number_part_circlepath_pos_less:
5204   assumes "s < t" and no: "norm(w - z) < r"
5205     shows "0 < Re (winding_number(part_circlepath z r s t) w)"
5206 proof -
5207   have "0 < r" by (meson no norm_not_less_zero not_le order.strict_trans2)
5208   note valid_path_part_circlepath
5209   moreover have " w \<notin> path_image (part_circlepath z r s t)"
5210     using assms by (auto simp: path_image_def image_def part_circlepath_def norm_mult linepath_def)
5211   moreover have "0 < r * (t - s) * (r - cmod (w - z))"
5212     using assms by (metis \<open>0 < r\<close> diff_gt_0_iff_gt mult_pos_pos)
5213   ultimately show ?thesis
5214     apply (rule winding_number_pos_lt [where e = "r*(t - s)*(r - norm(w - z))"])
5215     apply (simp add: vector_derivative_part_circlepath right_diff_distrib [symmetric] mult_ac)
5216     apply (rule mult_left_mono)+
5217     using Re_Im_le_cmod [of "w-z" "linepath s t x" for x]
5218     apply (simp add: exp_Euler cos_of_real sin_of_real part_circlepath_def algebra_simps cos_squared_eq [unfolded power2_eq_square])
5219     using assms \<open>0 < r\<close> by auto
5220 qed
5222 lemma simple_path_part_circlepath:
5223     "simple_path(part_circlepath z r s t) \<longleftrightarrow> (r \<noteq> 0 \<and> s \<noteq> t \<and> \<bar>s - t\<bar> \<le> 2*pi)"
5224 proof (cases "r = 0 \<or> s = t")
5225   case True
5226   then show ?thesis
5227     unfolding part_circlepath_def simple_path_def
5228     by (rule disjE) (force intro: bexI [where x = "1/4"] bexI [where x = "1/3"])+
5229 next
5230   case False then have "r \<noteq> 0" "s \<noteq> t" by auto
5231   have *: "\<And>x y z s t. \<i>*((1 - x) * s + x * t) = \<i>*(((1 - y) * s + y * t)) + z  \<longleftrightarrow> \<i>*(x - y) * (t - s) = z"
5232     by (simp add: algebra_simps)
5233   have abs01: "\<And>x y::real. 0 \<le> x \<and> x \<le> 1 \<and> 0 \<le> y \<and> y \<le> 1
5234                       \<Longrightarrow> (x = y \<or> x = 0 \<and> y = 1 \<or> x = 1 \<and> y = 0 \<longleftrightarrow> \<bar>x - y\<bar> \<in> {0,1})"
5235     by auto
5236   have **: "\<And>x y. (\<exists>n. (complex_of_real x - of_real y) * (of_real t - of_real s) = 2 * (of_int n * of_real pi)) \<longleftrightarrow>
5237                   (\<exists>n. \<bar>x - y\<bar> * (t - s) = 2 * (of_int n * pi))"
5238     by (force simp: algebra_simps abs_if dest: arg_cong [where f=Re] arg_cong [where f=complex_of_real]
5239                     intro: exI [where x = "-n" for n])
5240   have 1: "\<bar>s - t\<bar> \<le> 2 * pi"
5241     if "\<And>x. 0 \<le> x \<and> x \<le> 1 \<Longrightarrow> (\<exists>n. x * (t - s) = 2 * (real_of_int n * pi)) \<longrightarrow> x = 0 \<or> x = 1"
5242   proof (rule ccontr)
5243     assume "\<not> \<bar>s - t\<bar> \<le> 2 * pi"
5244     then have *: "\<And>n. t - s \<noteq> of_int n * \<bar>s - t\<bar>"
5245       using False that [of "2*pi / \<bar>t - s\<bar>"] by (simp add: abs_minus_commute divide_simps)
5246     show False
5247       using * [of 1] * [of "-1"] by auto
5248   qed
5249   have 2: "\<bar>s - t\<bar> = \<bar>2 * (real_of_int n * pi) / x\<bar>" if "x \<noteq> 0" "x * (t - s) = 2 * (real_of_int n * pi)" for x n
5250   proof -
5251     have "t-s = 2 * (real_of_int n * pi)/x"
5252       using that by (simp add: field_simps)
5253     then show ?thesis by (metis abs_minus_commute)
5254   qed
5255   have abs_away: "\<And>P. (\<forall>x\<in>{0..1}. \<forall>y\<in>{0..1}. P \<bar>x - y\<bar>) \<longleftrightarrow> (\<forall>x::real. 0 \<le> x \<and> x \<le> 1 \<longrightarrow> P x)"
5256     by force
5257   show ?thesis using False
5258     apply (simp add: simple_path_def)
5259     apply (simp add: part_circlepath_def linepath_def exp_eq  * ** abs01  del: Set.insert_iff)
5260     apply (subst abs_away)
5261     apply (auto simp: 1)
5262     apply (rule ccontr)
5263     apply (auto simp: 2 divide_simps abs_mult dest: of_int_leD)
5264     done
5265 qed
5267 lemma arc_part_circlepath:
5268   assumes "r \<noteq> 0" "s \<noteq> t" "\<bar>s - t\<bar> < 2*pi"
5269     shows "arc (part_circlepath z r s t)"
5270 proof -
5271   have *: "x = y" if eq: "\<i> * (linepath s t x) = \<i> * (linepath s t y) + 2 * of_int n * complex_of_real pi * \<i>"
5272     and x: "x \<in> {0..1}" and y: "y \<in> {0..1}" for x y n
5273   proof (rule ccontr)
5274     assume "x \<noteq> y"
5275     have "(linepath s t x) = (linepath s t y) + 2 * of_int n * complex_of_real pi"
5276       by (metis add_divide_eq_iff complex_i_not_zero mult.commute nonzero_mult_div_cancel_left eq)
5277     then have "s*y + t*x = s*x + (t*y + of_int n * (pi * 2))"
5278       by (force simp: algebra_simps linepath_def dest: arg_cong [where f=Re])
5279     with \<open>x \<noteq> y\<close> have st: "s-t = (of_int n * (pi * 2) / (y-x))"
5280       by (force simp: field_simps)
5281     have "\<bar>real_of_int n\<bar> < \<bar>y - x\<bar>"
5282       using assms \<open>x \<noteq> y\<close> by (simp add: st abs_mult field_simps)
5283     then show False
5284       using assms x y st by (auto dest: of_int_lessD)
5285   qed
5286   show ?thesis
5287     using assms
5288     apply (simp add: arc_def)
5289     apply (simp add: part_circlepath_def inj_on_def exp_eq)
5290     apply (blast intro: *)
5291     done
5292 qed
5294 subsection\<open>Special case of one complete circle\<close>
5296 definition%important circlepath :: "[complex, real, real] \<Rightarrow> complex"
5297   where "circlepath z r \<equiv> part_circlepath z r 0 (2*pi)"
5299 lemma circlepath: "circlepath z r = (\<lambda>x. z + r * exp(2 * of_real pi * \<i> * of_real x))"
5300   by (simp add: circlepath_def part_circlepath_def linepath_def algebra_simps)
5302 lemma pathstart_circlepath [simp]: "pathstart (circlepath z r) = z + r"
5303   by (simp add: circlepath_def)
5305 lemma pathfinish_circlepath [simp]: "pathfinish (circlepath z r) = z + r"
5306   by (simp add: circlepath_def) (metis exp_two_pi_i mult.commute)
5308 lemma circlepath_minus: "circlepath z (-r) x = circlepath z r (x + 1/2)"
5309 proof -
5310   have "z + of_real r * exp (2 * pi * \<i> * (x + 1/2)) =
5311         z + of_real r * exp (2 * pi * \<i> * x + pi * \<i>)"
5312     by (simp add: divide_simps) (simp add: algebra_simps)
5313   also have "\<dots> = z - r * exp (2 * pi * \<i> * x)"
5315   finally show ?thesis
5316     by (simp add: circlepath path_image_def sphere_def dist_norm)
5317 qed
5319 lemma circlepath_add1: "circlepath z r (x+1) = circlepath z r x"
5320   using circlepath_minus [of z r "x+1/2"] circlepath_minus [of z "-r" x]
5323 lemma circlepath_add_half: "circlepath z r (x + 1/2) = circlepath z r (x - 1/2)"
5324   using circlepath_add1 [of z r "x-1/2"]
5327 lemma path_image_circlepath_minus_subset:
5328      "path_image (circlepath z (-r)) \<subseteq> path_image (circlepath z r)"
5329   apply (simp add: path_image_def image_def circlepath_minus, clarify)
5330   apply (case_tac "xa \<le> 1/2", force)
5331   apply (force simp: circlepath_add_half)+
5332   done
5334 lemma path_image_circlepath_minus: "path_image (circlepath z (-r)) = path_image (circlepath z r)"
5335   using path_image_circlepath_minus_subset by fastforce
5337 lemma has_vector_derivative_circlepath [derivative_intros]:
5338  "((circlepath z r) has_vector_derivative (2 * pi * \<i> * r * exp (2 * of_real pi * \<i> * of_real x)))
5339    (at x within X)"
5340   apply (simp add: circlepath_def scaleR_conv_of_real)
5341   apply (rule derivative_eq_intros)
5342   apply (simp add: algebra_simps)
5343   done
5345 lemma vector_derivative_circlepath:
5346    "vector_derivative (circlepath z r) (at x) =
5347     2 * pi * \<i> * r * exp(2 * of_real pi * \<i> * x)"
5348 using has_vector_derivative_circlepath vector_derivative_at by blast
5350 lemma vector_derivative_circlepath01:
5351     "\<lbrakk>0 \<le> x; x \<le> 1\<rbrakk>
5352      \<Longrightarrow> vector_derivative (circlepath z r) (at x within {0..1}) =
5353           2 * pi * \<i> * r * exp(2 * of_real pi * \<i> * x)"
5354   using has_vector_derivative_circlepath
5355   by (auto simp: vector_derivative_at_within_ivl)
5357 lemma valid_path_circlepath [simp]: "valid_path (circlepath z r)"
5358   by (simp add: circlepath_def)
5360 lemma path_circlepath [simp]: "path (circlepath z r)"
5361   by (simp add: valid_path_imp_path)
5363 lemma path_image_circlepath_nonneg:
5364   assumes "0 \<le> r" shows "path_image (circlepath z r) = sphere z r"
5365 proof -
5366   have *: "x \<in> (\<lambda>u. z + (cmod (x - z)) * exp (\<i> * (of_real u * (of_real pi * 2)))) ` {0..1}" for x
5367   proof (cases "x = z")
5368     case True then show ?thesis by force
5369   next
5370     case False
5371     define w where "w = x - z"
5372     then have "w \<noteq> 0" by (simp add: False)
5373     have **: "\<And>t. \<lbrakk>Re w = cos t * cmod w; Im w = sin t * cmod w\<rbrakk> \<Longrightarrow> w = of_real (cmod w) * exp (\<i> * t)"
5374       using cis_conv_exp complex_eq_iff by auto
5375     show ?thesis
5376       apply (rule sincos_total_2pi [of "Re(w/of_real(norm w))" "Im(w/of_real(norm w))"])
5377       apply (simp add: divide_simps \<open>w \<noteq> 0\<close> cmod_power2 [symmetric])
5378       apply (rule_tac x="t / (2*pi)" in image_eqI)
5379       apply (simp add: divide_simps \<open>w \<noteq> 0\<close>)
5380       using False **
5381       apply (auto simp: w_def)
5382       done
5383   qed
5384   show ?thesis
5385     unfolding circlepath path_image_def sphere_def dist_norm
5386     by (force simp: assms algebra_simps norm_mult norm_minus_commute intro: *)
5387 qed
5389 lemma path_image_circlepath [simp]:
5390     "path_image (circlepath z r) = sphere z \<bar>r\<bar>"
5391   using path_image_circlepath_minus
5392   by (force simp: path_image_circlepath_nonneg abs_if)
5394 lemma has_contour_integral_bound_circlepath_strong:
5395       "\<lbrakk>(f has_contour_integral i) (circlepath z r);
5396         finite k; 0 \<le> B; 0 < r;
5397         \<And>x. \<lbrakk>norm(x - z) = r; x \<notin> k\<rbrakk> \<Longrightarrow> norm(f x) \<le> B\<rbrakk>
5398         \<Longrightarrow> norm i \<le> B*(2*pi*r)"
5399   unfolding circlepath_def
5400   by (auto simp: algebra_simps in_path_image_part_circlepath dest!: has_contour_integral_bound_part_circlepath_strong)
5402 lemma has_contour_integral_bound_circlepath:
5403       "\<lbrakk>(f has_contour_integral i) (circlepath z r);
5404         0 \<le> B; 0 < r; \<And>x. norm(x - z) = r \<Longrightarrow> norm(f x) \<le> B\<rbrakk>
5405         \<Longrightarrow> norm i \<le> B*(2*pi*r)"
5406   by (auto intro: has_contour_integral_bound_circlepath_strong)
5408 lemma contour_integrable_continuous_circlepath:
5409     "continuous_on (path_image (circlepath z r)) f
5410      \<Longrightarrow> f contour_integrable_on (circlepath z r)"
5411   by (simp add: circlepath_def contour_integrable_continuous_part_circlepath)
5413 lemma simple_path_circlepath: "simple_path(circlepath z r) \<longleftrightarrow> (r \<noteq> 0)"
5414   by (simp add: circlepath_def simple_path_part_circlepath)
5416 lemma notin_path_image_circlepath [simp]: "cmod (w - z) < r \<Longrightarrow> w \<notin> path_image (circlepath z r)"
5417   by (simp add: sphere_def dist_norm norm_minus_commute)
5419 lemma contour_integral_circlepath:
5420   assumes "r > 0"
5421   shows "contour_integral (circlepath z r) (\<lambda>w. 1 / (w - z)) = 2 * complex_of_real pi * \<i>"
5422 proof (rule contour_integral_unique)
5423   show "((\<lambda>w. 1 / (w - z)) has_contour_integral 2 * complex_of_real pi * \<i>) (circlepath z r)"
5424     unfolding has_contour_integral_def using assms
5425     apply (subst has_integral_cong)
5426      apply (simp add: vector_derivative_circlepath01)
5427     using has_integral_const_real [of _ 0 1] apply (force simp: circlepath)
5428     done
5429 qed
5431 lemma winding_number_circlepath_centre: "0 < r \<Longrightarrow> winding_number (circlepath z r) z = 1"
5432   apply (rule winding_number_unique_loop)
5433   apply (simp_all add: sphere_def valid_path_imp_path)
5434   apply (rule_tac x="circlepath z r" in exI)
5435   apply (simp add: sphere_def contour_integral_circlepath)
5436   done
5438 proposition winding_number_circlepath:
5439   assumes "norm(w - z) < r" shows "winding_number(circlepath z r) w = 1"
5440 proof (cases "w = z")
5441   case True then show ?thesis
5442     using assms winding_number_circlepath_centre by auto
5443 next
5444   case False
5445   have [simp]: "r > 0"
5446     using assms le_less_trans norm_ge_zero by blast
5447   define r' where "r' = norm(w - z)"
5448   have "r' < r"
5449     by (simp add: assms r'_def)
5450   have disjo: "cball z r' \<inter> sphere z r = {}"
5451     using \<open>r' < r\<close> by (force simp: cball_def sphere_def)
5452   have "winding_number(circlepath z r) w = winding_number(circlepath z r) z"
5453   proof (rule winding_number_around_inside [where s = "cball z r'"])
5454     show "winding_number (circlepath z r) z \<noteq> 0"
5455       by (simp add: winding_number_circlepath_centre)
5456     show "cball z r' \<inter> path_image (circlepath z r) = {}"
5457       by (simp add: disjo less_eq_real_def)
5458   qed (auto simp: r'_def dist_norm norm_minus_commute)
5459   also have "\<dots> = 1"
5460     by (simp add: winding_number_circlepath_centre)
5461   finally show ?thesis .
5462 qed
5465 text\<open> Hence the Cauchy formula for points inside a circle.\<close>
5467 theorem Cauchy_integral_circlepath:
5468   assumes contf: "continuous_on (cball z r) f" and holf: "f holomorphic_on (ball z r)" and wz: "norm(w - z) < r"
5469   shows "((\<lambda>u. f u/(u - w)) has_contour_integral (2 * of_real pi * \<i> * f w))
5470          (circlepath z r)"
5471 proof -
5472   have "r > 0"
5473     using assms le_less_trans norm_ge_zero by blast
5474   have "((\<lambda>u. f u / (u - w)) has_contour_integral (2 * pi) * \<i> * winding_number (circlepath z r) w * f w)
5475         (circlepath z r)"
5476   proof (rule Cauchy_integral_formula_weak [where s = "cball z r" and k = "{}"])
5477     show "\<And>x. x \<in> interior (cball z r) - {} \<Longrightarrow>
5478          f field_differentiable at x"
5479       using holf holomorphic_on_imp_differentiable_at by auto
5480     have "w \<notin> sphere z r"
5481       by simp (metis dist_commute dist_norm not_le order_refl wz)
5482     then show "path_image (circlepath z r) \<subseteq> cball z r - {w}"
5483       using \<open>r > 0\<close> by (auto simp add: cball_def sphere_def)
5484   qed (use wz in \<open>simp_all add: dist_norm norm_minus_commute contf\<close>)
5485   then show ?thesis
5486     by (simp add: winding_number_circlepath assms)
5487 qed
5489 corollary%unimportant Cauchy_integral_circlepath_simple:
5490   assumes "f holomorphic_on cball z r" "norm(w - z) < r"
5491   shows "((\<lambda>u. f u/(u - w)) has_contour_integral (2 * of_real pi * \<i> * f w))
5492          (circlepath z r)"
5493 using assms by (force simp: holomorphic_on_imp_continuous_on holomorphic_on_subset Cauchy_integral_circlepath)
5496 lemma no_bounded_connected_component_imp_winding_number_zero:
5497   assumes g: "path g" "path_image g \<subseteq> s" "pathfinish g = pathstart g" "z \<notin> s"
5498       and nb: "\<And>z. bounded (connected_component_set (- s) z) \<longrightarrow> z \<in> s"
5499   shows "winding_number g z = 0"
5500 apply (rule winding_number_zero_in_outside)
5501 apply (simp_all add: assms)
5502 by (metis nb [of z] \<open>path_image g \<subseteq> s\<close> \<open>z \<notin> s\<close> contra_subsetD mem_Collect_eq outside outside_mono)
5504 lemma no_bounded_path_component_imp_winding_number_zero:
5505   assumes g: "path g" "path_image g \<subseteq> s" "pathfinish g = pathstart g" "z \<notin> s"
5506       and nb: "\<And>z. bounded (path_component_set (- s) z) \<longrightarrow> z \<in> s"
5507   shows "winding_number g z = 0"
5508 apply (rule no_bounded_connected_component_imp_winding_number_zero [OF g])
5509 by (simp add: bounded_subset nb path_component_subset_connected_component)
5512 subsection\<open> Uniform convergence of path integral\<close>
5514 text\<open>Uniform convergence when the derivative of the path is bounded, and in particular for the special case of a circle.\<close>
5516 proposition contour_integral_uniform_limit:
5517   assumes ev_fint: "eventually (\<lambda>n::'a. (f n) contour_integrable_on \<gamma>) F"
5518       and ul_f: "uniform_limit (path_image \<gamma>) f l F"
5519       and noleB: "\<And>t. t \<in> {0..1} \<Longrightarrow> norm (vector_derivative \<gamma> (at t)) \<le> B"
5520       and \<gamma>: "valid_path \<gamma>"
5521       and [simp]: "\<not> trivial_limit F"
5522   shows "l contour_integrable_on \<gamma>" "((\<lambda>n. contour_integral \<gamma> (f n)) \<longlongrightarrow> contour_integral \<gamma> l) F"
5523 proof -
5524   have "0 \<le> B" by (meson noleB [of 0] atLeastAtMost_iff norm_ge_zero order_refl order_trans zero_le_one)
5525   { fix e::real
5526     assume "0 < e"
5527     then have "0 < e / (\<bar>B\<bar> + 1)" by simp
5528     then have "\<forall>\<^sub>F n in F. \<forall>x\<in>path_image \<gamma>. cmod (f n x - l x) < e / (\<bar>B\<bar> + 1)"
5529       using ul_f [unfolded uniform_limit_iff dist_norm] by auto
5530     with ev_fint
5531     obtain a where fga: "\<And>x. x \<in> {0..1} \<Longrightarrow> cmod (f a (\<gamma> x) - l (\<gamma> x)) < e / (\<bar>B\<bar> + 1)"
5532                and inta: "(\<lambda>t. f a (\<gamma> t) * vector_derivative \<gamma> (at t)) integrable_on {0..1}"
5533       using eventually_happens [OF eventually_conj]
5534       by (fastforce simp: contour_integrable_on path_image_def)
5535     have Ble: "B * e / (\<bar>B\<bar> + 1) \<le> e"
5536       using \<open>0 \<le> B\<close>  \<open>0 < e\<close> by (simp add: divide_simps)
5537     have "\<exists>h. (\<forall>x\<in>{0..1}. cmod (l (\<gamma> x) * vector_derivative \<gamma> (at x) - h x) \<le> e) \<and> h integrable_on {0..1}"
5538     proof (intro exI conjI ballI)
5539       show "cmod (l (\<gamma> x) * vector_derivative \<gamma> (at x) - f a (\<gamma> x) * vector_derivative \<gamma> (at x)) \<le> e"
5540         if "x \<in> {0..1}" for x
5541         apply (rule order_trans [OF _ Ble])
5542         using noleB [OF that] fga [OF that] \<open>0 \<le> B\<close> \<open>0 < e\<close>
5543         apply (simp add: norm_mult left_diff_distrib [symmetric] norm_minus_commute divide_simps)
5544         apply (fastforce simp: mult_ac dest: mult_mono [OF less_imp_le])
5545         done
5546     qed (rule inta)
5547   }
5548   then show lintg: "l contour_integrable_on \<gamma>"
5549     unfolding contour_integrable_on by (metis (mono_tags, lifting)integrable_uniform_limit_real)
5550   { fix e::real
5551     define B' where "B' = B + 1"
5552     have B': "B' > 0" "B' > B" using  \<open>0 \<le> B\<close> by (auto simp: B'_def)
5553     assume "0 < e"
5554     then have ev_no': "\<forall>\<^sub>F n in F. \<forall>x\<in>path_image \<gamma>. 2 * cmod (f n x - l x) < e / B'"
5555       using ul_f [unfolded uniform_limit_iff dist_norm, rule_format, of "e / B' / 2"] B'
5556         by (simp add: field_simps)
5557     have ie: "integral {0..1::real} (\<lambda>x. e / 2) < e" using \<open>0 < e\<close> by simp
5558     have *: "cmod (f x (\<gamma> t) * vector_derivative \<gamma> (at t) - l (\<gamma> t) * vector_derivative \<gamma> (at t)) \<le> e / 2"
5559              if t: "t\<in>{0..1}" and leB': "2 * cmod (f x (\<gamma> t) - l (\<gamma> t)) < e / B'" for x t
5560     proof -
5561       have "2 * cmod (f x (\<gamma> t) - l (\<gamma> t)) * cmod (vector_derivative \<gamma> (at t)) \<le> e * (B/ B')"
5562         using mult_mono [OF less_imp_le [OF leB'] noleB] B' \<open>0 < e\<close> t by auto
5563       also have "\<dots> < e"
5564         by (simp add: B' \<open>0 < e\<close> mult_imp_div_pos_less)
5565       finally have "2 * cmod (f x (\<gamma> t) - l (\<gamma> t)) * cmod (vector_derivative \<gamma> (at t)) < e" .
5566       then show ?thesis
5567         by (simp add: left_diff_distrib [symmetric] norm_mult)
5568     qed
5569     have le_e: "\<And>x. \<lbrakk>\<forall>xa\<in>{0..1}. 2 * cmod (f x (\<gamma> xa) - l (\<gamma> xa)) < e / B'; f x contour_integrable_on \<gamma>\<rbrakk>
5570          \<Longrightarrow> cmod (integral {0..1}
5571                     (\<lambda>u. f x (\<gamma> u) * vector_derivative \<gamma> (at u) - l (\<gamma> u) * vector_derivative \<gamma> (at u))) < e"
5572       apply (rule le_less_trans [OF integral_norm_bound_integral ie])
5573         apply (simp add: lintg integrable_diff contour_integrable_on [symmetric])
5574        apply (blast intro: *)+
5575       done
5576     have "\<forall>\<^sub>F x in F. dist (contour_integral \<gamma> (f x)) (contour_integral \<gamma> l) < e"
5577       apply (rule eventually_mono [OF eventually_conj [OF ev_no' ev_fint]])
5578       apply (simp add: dist_norm contour_integrable_on path_image_def contour_integral_integral)
5579       apply (simp add: lintg integral_diff [symmetric] contour_integrable_on [symmetric] le_e)
5580       done
5581   }
5582   then show "((\<lambda>n. contour_integral \<gamma> (f n)) \<longlongrightarrow> contour_integral \<gamma> l) F"
5583     by (rule tendstoI)
5584 qed
5586 corollary%unimportant contour_integral_uniform_limit_circlepath:
5587   assumes "\<forall>\<^sub>F n::'a in F. (f n) contour_integrable_on (circlepath z r)"
5588       and "uniform_limit (sphere z r) f l F"
5589       and "\<not> trivial_limit F" "0 < r"
5590     shows "l contour_integrable_on (circlepath z r)"
5591           "((\<lambda>n. contour_integral (circlepath z r) (f n)) \<longlongrightarrow> contour_integral (circlepath z r) l) F"
5592   using assms by (auto simp: vector_derivative_circlepath norm_mult intro!: contour_integral_uniform_limit)
5595 subsection%unimportant \<open>General stepping result for derivative formulas\<close>
5597 lemma Cauchy_next_derivative:
5598   assumes "continuous_on (path_image \<gamma>) f'"
5599       and leB: "\<And>t. t \<in> {0..1} \<Longrightarrow> norm (vector_derivative \<gamma> (at t)) \<le> B"
5600       and int: "\<And>w. w \<in> s - path_image \<gamma> \<Longrightarrow> ((\<lambda>u. f' u / (u - w)^k) has_contour_integral f w) \<gamma>"
5601       and k: "k \<noteq> 0"
5602       and "open s"