# Theory Existence

```section ‹Existence›
theory Existence imports
Piecewise_Continuous
begin

subsection ‹Definition›

definition has_laplace :: "(real ⇒ complex) ⇒ complex ⇒ complex ⇒ bool"
(infixr "has'_laplace" 46)
where "(f has_laplace L) s ⟷ ((λt. exp (t *⇩R - s) * f t) has_integral L) {0..}"

lemma has_laplaceI:
assumes "((λt. exp (t *⇩R - s) * f t) has_integral L) {0..}"
shows "(f has_laplace L) s"
using assms
by (auto simp: has_laplace_def)

lemma has_laplaceD:
assumes "(f has_laplace L) s"
shows "((λt. exp (t *⇩R - s) * f t) has_integral L) {0..}"
using assms
by (auto simp: has_laplace_def)

lemma has_laplace_unique:
"L = M" if
"(f has_laplace L) s"
"(f has_laplace M) s"
using that
by (auto simp: has_laplace_def has_integral_unique)

subsection ‹Condition for Existence: Exponential Order›

definition "exponential_order M c f ⟷ 0 < M ∧ (∀⇩F t in at_top. norm (f t) ≤ M * exp (c * t))"

lemma exponential_orderI:
assumes "0 < M" and eo: "∀⇩F t in at_top. norm (f t) ≤ M * exp (c * t)"
shows "exponential_order M c f"
by (auto intro!: assms simp: exponential_order_def)

lemma exponential_orderD:
assumes "exponential_order M c f"
shows "0 < M" "∀⇩F t in at_top. norm (f t) ≤ M * exp (c * t)"
using assms by (auto simp: exponential_order_def)

context
fixes f::"real ⇒ complex"
begin

definition laplace_integrand::"complex ⇒ real ⇒ complex"
where "laplace_integrand s t = exp (t *⇩R - s) * f t"

lemma laplace_integrand_absolutely_integrable_on_Icc:
"laplace_integrand s absolutely_integrable_on {a..b}"
if "AE x∈{a..b} in lebesgue. cmod (f x) ≤ B" "f integrable_on {a..b}"
apply (cases "b ≤ a")
subgoal by (auto intro!: absolutely_integrable_onI integrable_negligible[OF negligible_real_ivlI])
proof goal_cases
case 1
have "compact ((λx. exp (- (x *⇩R s))) ` {a .. b})"
by (rule compact_continuous_image) (auto intro!: continuous_intros)
then obtain C where C: "0 ≤ C" "a ≤ x ⟹ x ≤ b ⟹ cmod (exp (- (x *⇩R s))) ≤ C" for x
using 1
apply (auto simp: bounded_iff dest!: compact_imp_bounded)
by (metis atLeastAtMost_iff exp_ge_zero order_refl order_trans scaleR_complex.sel(1))

have m: "(λx. indicator {a..b} x *⇩R f x) ∈ borel_measurable lebesgue"
apply (rule has_integral_implies_lebesgue_measurable)
apply (rule integrable_integral)
apply (rule that)
done
have "complex_set_integrable lebesgue {a..b} (λx. exp (- (x *⇩R s)) * (indicator {a .. b} x *⇩R f x))"
unfolding set_integrable_def
apply (rule integrableI_bounded_set_indicator[where B="C * B"])
apply (simp; fail)
apply (rule borel_measurable_times)
apply measurable
apply (simp add: measurable_completion)
apply (simp add: measurable_completion)
apply (rule m)
apply (simp add: emeasure_lborel_Icc_eq)
using that(1)
apply eventually_elim
apply (auto simp: norm_mult)
apply (rule mult_mono)
using C
by auto
then show ?case
unfolding set_integrable_def
by (simp add: laplace_integrand_def[abs_def] indicator_inter_arith[symmetric])
qed

lemma laplace_integrand_integrable_on_Icc:
"laplace_integrand s integrable_on {a..b}"
if "AE x∈{a..b} in lebesgue. cmod (f x) ≤ B" "f integrable_on {a..b}"
using laplace_integrand_absolutely_integrable_on_Icc[OF that]
using set_lebesgue_integral_eq_integral(1) by blast

lemma eventually_laplace_integrand_le:
"∀⇩F t in at_top. cmod (laplace_integrand s t) ≤ M * exp (- (Re s - c) * t)"
if "exponential_order M c f"
using exponential_orderD(2)[OF that]
proof (eventually_elim)
case (elim t)
show ?case
unfolding laplace_integrand_def
apply (rule norm_mult_ineq[THEN order_trans])
apply (auto intro!: mult_left_mono[THEN order_trans, OF elim])
apply (auto simp: exp_minus divide_simps algebra_simps exp_add[symmetric])
done
qed

lemma
assumes eo: "exponential_order M c f"
and cs: "c < Re s"
shows laplace_integrand_integrable_on_Ici_iff:
"laplace_integrand s integrable_on {a..} ⟷
(∀k>a. laplace_integrand s integrable_on {a..k})"
(is ?th1)
and laplace_integrand_absolutely_integrable_on_Ici_iff:
"laplace_integrand s absolutely_integrable_on {a..} ⟷
(∀k>a. laplace_integrand s absolutely_integrable_on {a..k})"
(is ?th2)
proof -
have "∀⇩F t in at_top. a < (t::real)"
using eventually_gt_at_top by blast
then have "∀⇩F t in at_top. t > a ∧ cmod (laplace_integrand s t) ≤ M * exp (- (Re s - c) * t)"
using eventually_laplace_integrand_le[OF eo]
by eventually_elim (auto)
then obtain A where A: "A > a" and le: "t ≥ A ⟹ cmod (laplace_integrand s t) ≤ M * exp (- (Re s - c) * t)" for t
unfolding eventually_at_top_linorder
by blast

let ?f = "λ(k::real) (t::real). indicat_real {A..k} t *⇩R laplace_integrand s t"

from exponential_orderD[OF eo] have "M ≠ 0" by simp
have 2: "(λt. M * exp (- (Re s - c) * t)) integrable_on {A..}"
unfolding integrable_on_cmult_iff[OF ‹M ≠ 0›] norm_exp_eq_Re
by (rule integrable_on_exp_minus_to_infinity) (simp add: cs)

have 3: "t∈{A..} ⟹ cmod (?f k t) ≤ M * exp (- (Re s - c) * t)"
(is "t∈_⟹ ?lhs t ≤ ?rhs t")
for t k
proof safe
fix t assume "A ≤ t"
have "?lhs t ≤ cmod (laplace_integrand s t)"
by (auto simp: indicator_def)
also have "… ≤ ?rhs t" using ‹A ≤ t› le by (simp add: laplace_integrand_def)
finally show "?lhs t ≤ ?rhs t" .
qed

have 4: "∀t∈{A..}. ((λk. ?f k t) ⤏ laplace_integrand s t) at_top"
proof safe
fix t assume t: "t ≥ A"
have "∀⇩F k in at_top. k ≥ t"
by (simp add: eventually_ge_at_top)
then have "∀⇩F k in at_top. laplace_integrand s t = ?f k t"
by eventually_elim (use t in ‹auto simp: indicator_def›)
then show "((λk. ?f k t) ⤏ laplace_integrand s t) at_top" using tendsto_const
by (rule Lim_transform_eventually[rotated])
qed

show th1: ?th1
proof safe
assume "∀k>a. laplace_integrand s integrable_on {a..k}"
note li = this[rule_format]
have liA: "laplace_integrand s integrable_on {A..k}" for k
proof cases
assume "k ≤ A"
then have "{A..k} = (if A = k then {k} else {})" by auto
then show ?thesis by (auto intro!: integrable_negligible)
next
assume n: "¬ k ≤ A"
show ?thesis
by (rule integrable_on_subinterval[OF li[of k]]) (use A n in auto)
qed
have "?f k integrable_on {A..k}" for k
using liA[of k] negligible_empty
by (rule integrable_spike) auto
then have 1: "?f k integrable_on {A..}" for k
by (rule integrable_on_superset) auto
note 1 2 3 4
note * = this[unfolded set_integrable_def]
from li[of A] dominated_convergence_at_top(1)[OF *]
show "laplace_integrand s integrable_on {a..}"
by (rule integrable_Un') (use ‹a < A› in ‹auto simp: max_def li›)
qed (rule integrable_on_subinterval, assumption, auto)

show ?th2
proof safe
assume ai: "∀k>a. laplace_integrand s absolutely_integrable_on {a..k}"
then have "laplace_integrand s absolutely_integrable_on {a..A}"
using A by auto
moreover
from ai have "∀k>a. laplace_integrand s integrable_on {a..k}"
using set_lebesgue_integral_eq_integral(1) by blast
with th1 have i: "laplace_integrand s integrable_on {a..}" by auto
have 1: "?f k integrable_on {A..}" for k
apply (rule integrable_on_superset[where S="{A..k}"])
using _ negligible_empty
apply (rule integrable_spike[where f="laplace_integrand s"])
apply (rule integrable_on_subinterval)
apply (rule i)
by (use ‹a < A› in auto)
have "laplace_integrand s absolutely_integrable_on {A..}"
using _ dominated_convergence_at_top(1)[OF 1 2 3 4] 2
by (rule absolutely_integrable_integrable_bound) (use le in auto)
ultimately
have "laplace_integrand s absolutely_integrable_on ({a..A} ∪ {A..})"
by (rule set_integrable_Un) auto
also have "{a..A} ∪ {A..} = {a..}" using ‹a < A› by auto
finally show "local.laplace_integrand s absolutely_integrable_on {a..}" .
qed (rule set_integrable_subset, assumption, auto)
qed

theorem laplace_exists_laplace_integrandI:
assumes "laplace_integrand s integrable_on {0..}"
obtains F where "(f has_laplace F) s"
proof -
from assms
have "(f has_laplace integral {0..} (laplace_integrand s)) s"
unfolding has_laplace_def laplace_integrand_def by blast
thus ?thesis ..
qed

lemma
assumes eo: "exponential_order M c f"
and pc: "⋀k. AE x∈{0..k} in lebesgue. cmod (f x) ≤ B k" "⋀k. f integrable_on {0..k}"
and s: "Re s > c"
shows laplace_integrand_integrable: "laplace_integrand s integrable_on {0..}" (is ?th1)
and laplace_integrand_absolutely_integrable:
"laplace_integrand s absolutely_integrable_on {0..}" (is ?th2)
using eo laplace_integrand_absolutely_integrable_on_Icc[OF pc] s
by (auto simp: laplace_integrand_integrable_on_Ici_iff
laplace_integrand_absolutely_integrable_on_Ici_iff
set_lebesgue_integral_eq_integral)

lemma piecewise_continuous_on_AE_boundedE:
assumes pc: "⋀k. piecewise_continuous_on a k (I k) f"
obtains B where "⋀k. AE x∈{a..k} in lebesgue. cmod (f x) ≤ B k"
apply atomize_elim
apply (rule choice)
apply (rule allI)
subgoal for k
using bounded_piecewise_continuous_image[OF pc[of k]]
by (force simp: bounded_iff)
done

theorem piecewise_continuous_on_has_laplace:
assumes eo: "exponential_order M c f"
and pc: "⋀k. piecewise_continuous_on 0 k (I k) f"
and s: "Re s > c"
obtains F where "(f has_laplace F) s"
proof -
from piecewise_continuous_on_AE_boundedE[OF pc]
obtain B where AE: "AE x∈{0..k} in lebesgue. cmod (f x) ≤ B k" for k by force
have int: "f integrable_on {0..k}" for k
using pc
by (rule piecewise_continuous_on_integrable)
show ?thesis
using pc
apply (rule piecewise_continuous_on_AE_boundedE)
apply (rule laplace_exists_laplace_integrandI)
apply (rule laplace_integrand_integrable)
apply (rule eo)
apply assumption
apply (rule int)
apply (rule s)
by (rule that)
qed

end

subsection ‹Concrete Laplace Transforms›

lemma exp_scaleR_has_vector_derivative_left'[derivative_intros]:
"((λt. exp (t *⇩R A)) has_vector_derivative A * exp (t *⇩R A)) (at t within S)"
by (metis exp_scaleR_has_vector_derivative_right exp_times_scaleR_commute)

lemma
fixes a::complex―‹TODO: generalize›
assumes a: "0 < Re a"
shows integrable_on_cexp_minus_to_infinity: "(λx. exp (x *⇩R - a)) integrable_on {c..}"
and integral_cexp_minus_to_infinity:  "integral {c..} (λx. exp (x *⇩R - a)) = exp (c *⇩R - a) / a"
proof -
from a have "a ≠ 0" by auto
define f where "f = (λk x. if x ∈ {c..real k} then exp (x *⇩R -a) else 0)"
{
fix k :: nat assume k: "of_nat k ≥ c"
from ‹a ≠ 0› k
have "((λx. exp (x *⇩R -a)) has_integral (-exp (k *⇩R -a)/a - (-exp (c *⇩R -a)/a))) {c..real k}"
by (intro fundamental_theorem_of_calculus)
(auto intro!: derivative_eq_intros exp_scaleR_has_vector_derivative_left
simp: divide_inverse_commute
simp del: scaleR_minus_left scaleR_minus_right)
hence "(f k has_integral (exp (c *⇩R -a)/a - exp (k *⇩R -a)/a)) {c..}" unfolding f_def
by (subst has_integral_restrict) simp_all
} note has_integral_f = this

have integrable_fk: "f k integrable_on {c..}" for k
proof -
have "(λx. exp (x *⇩R -a)) integrable_on {c..of_real k}" (is ?P)
unfolding f_def by (auto intro!: continuous_intros integrable_continuous_real)
then have int: "(f k) integrable_on {c..of_real k}"
by (rule integrable_eq) (simp add: f_def)
show ?thesis
by (rule integrable_on_superset[OF int]) (auto simp: f_def)
qed
have limseq: "⋀x. x ∈{c..} ⟹ (λk. f k x) ⇢ exp (x *⇩R - a)"
apply (auto intro!: Lim_transform_eventually[OF tendsto_const] simp: f_def)
by (meson eventually_sequentiallyI nat_ceiling_le_eq)
have bnd: "⋀x. x ∈ {c..} ⟹ cmod (f k x) ≤ exp (- Re a * x)" for k
by (auto simp: f_def)

have [simp]: "f k = (λ_. 0)" if "of_nat k < c" for k using that by (auto simp: fun_eq_iff f_def)
have integral_f: "integral {c..} (f k) =
(if real k ≥ c then exp (c *⇩R -a)/a - exp (k *⇩R -a)/a else 0)"
for k using integral_unique[OF has_integral_f[of k]] by simp

have "(λk. exp (c *⇩R -a)/a - exp (k *⇩R -a)/a) ⇢ exp (c*⇩R-a)/a - 0/a"
apply (intro tendsto_intros filterlim_compose[OF exp_at_bot]
filterlim_tendsto_neg_mult_at_bot[OF tendsto_const] filterlim_real_sequentially)+
apply (rule tendsto_norm_zero_cancel)
by (auto intro!: assms ‹a ≠ 0› filterlim_real_sequentially
filterlim_compose[OF exp_at_bot] filterlim_compose[OF filterlim_uminus_at_bot_at_top]
filterlim_at_top_mult_tendsto_pos[OF tendsto_const])
moreover
note A = dominated_convergence[where g="λx. exp (x *⇩R -a)",
OF integrable_fk integrable_on_exp_minus_to_infinity[where a="Re a" and c=c, OF ‹0 < Re a›]
bnd limseq]
from A(1) show "(λx. exp (x *⇩R - a)) integrable_on {c..}" .
from eventually_gt_at_top[of "nat ⌈c⌉"] have "eventually (λk. of_nat k > c) sequentially"
by eventually_elim linarith
hence "eventually (λk. exp (c *⇩R -a)/a - exp (k *⇩R -a)/a = integral {c..} (f k)) sequentially"
by eventually_elim (simp add: integral_f)
ultimately have "(λk. integral {c..} (f k)) ⇢ exp (c *⇩R -a)/a - 0/a"
by (rule Lim_transform_eventually)
from LIMSEQ_unique[OF A(2) this]
show "integral {c..} (λx. exp (x *⇩R -a)) = exp (c *⇩R -a)/a" by simp
qed

lemma has_integral_cexp_minus_to_infinity:
fixes a::complex―‹TODO: generalize›
assumes a: "0 < Re a"
shows "((λx. exp (x *⇩R - a)) has_integral exp (c *⇩R - a) / a) {c..}"
using integral_cexp_minus_to_infinity[OF assms]
integrable_on_cexp_minus_to_infinity[OF assms]
using has_integral_integrable_integral by blast

lemma has_laplace_one:
"((λ_. 1) has_laplace inverse s) s" if "Re s > 0"
proof (safe intro!: has_laplaceI)
from that have "((λt. exp (t *⇩R - s)) has_integral inverse s) {0..}"
by (rule has_integral_cexp_minus_to_infinity[THEN has_integral_eq_rhs])
(auto simp: inverse_eq_divide)
then show "((λt. exp (t *⇩R - s) * 1) has_integral inverse s) {0..}" by simp
qed

lemma has_laplace_add:
assumes f: "(f has_laplace F) S"
assumes g: "(g has_laplace G) S"
shows "((λx. f x + g x) has_laplace F + G) S"
apply (rule has_laplaceI)
using has_integral_add[OF has_laplaceD[OF f ] has_laplaceD[OF g]]
by (auto simp: algebra_simps)

lemma has_laplace_cmul:
assumes "(f has_laplace F) S"
shows "((λx. r *⇩R f x) has_laplace r *⇩R F) S"
apply (rule has_laplaceI)
using has_laplaceD[OF assms, THEN has_integral_cmul[where c=r]]
by auto

lemma has_laplace_uminus:
assumes "(f has_laplace F) S"
shows "((λx. - f x) has_laplace - F) S"
using has_laplace_cmul[OF assms, of "-1"]
by auto

lemma has_laplace_minus:
assumes f: "(f has_laplace F) S"
assumes g: "(g has_laplace G) S"
shows "((λx. f x - g x) has_laplace F - G) S"
using has_laplace_add[OF f has_laplace_uminus[OF g]]
by simp

lemma has_laplace_spike:
"(f has_laplace L) s"
if L: "(g has_laplace L) s"
and "negligible T"
and "⋀t. t ∉ T ⟹ t ≥ 0 ⟹ f t = g t"
by (auto intro!: has_laplaceI has_integral_spike[where S="T", OF _ _ has_laplaceD[OF L]] that)

lemma has_laplace_frequency_shift:―‹First Translation Theorem in Schiff›
"((λt. exp (t *⇩R b) * f t) has_laplace L) s"
if "(f has_laplace L) (s - b)"
using that
by (auto intro!: has_laplaceI dest!: has_laplaceD
simp: mult_exp_exp algebra_simps)

theorem has_laplace_derivative_time_domain:
"(f' has_laplace s * L - f0) s"
if L: "(f has_laplace L) s"
and f': "⋀t. t > 0 ⟹ (f has_vector_derivative f' t) (at t)"
and f0: "(f ⤏ f0) (at_right 0)"
and eo: "exponential_order M c f"
and cs: "c < Re s"
―‹Proof and statement follow "The Laplace Transform: Theory and Applications" by Joel L. Schiff.›
proof (rule has_laplaceI)
have ce: "continuous_on S (λt. exp (t *⇩R - s))" for S
by (auto intro!: continuous_intros)
have de: "((λt. exp (t *⇩R - s)) has_vector_derivative (- s * exp (- (t *⇩R s)))) (at t)" for t
by (auto simp: has_vector_derivative_def intro!: derivative_eq_intros ext)
have "((λx. -s * (f x * exp (- (x *⇩R s)))) has_integral - s * L) {0..}"
apply (rule has_integral_mult_right)
using has_laplaceD[OF L]
by (auto simp: ac_simps)

define g where "g x = (if x ≤ 0 then f0 else f x)" for x

have eog: "exponential_order M c g"
proof -
from exponential_orderD[OF eo] have "0 < M"
and ev: "∀⇩F t in at_top. cmod (f t) ≤ M * exp (c * t)" .
have "∀⇩F t::real in at_top. t > 0" by simp
with ev have "∀⇩F t in at_top. cmod (g t) ≤ M * exp (c * t)"
by eventually_elim (auto simp: g_def)
with ‹0 < M› show ?thesis
by (rule exponential_orderI)
qed
have Lg: "(g has_laplace L) s"
using L
by (rule has_laplace_spike[where T="{0}"]) (auto simp: g_def)
have g': "⋀t. 0 < t ⟹ (g has_vector_derivative f' t) (at t)"
using f'
by (rule has_vector_derivative_transform_within_open[where S="{0<..}"]) (auto simp: g_def)
have cg: "continuous_on {0..k} g" for k
apply (auto simp: g_def continuous_on_def)
apply (rule filterlim_at_within_If)
subgoal by (rule tendsto_intros)
subgoal
apply (rule tendsto_within_subset)
apply (rule f0)
by auto
subgoal premises prems for x
proof -
from prems have "0 < x" by auto
from order_tendstoD[OF tendsto_ident_at this]
have "eventually ((<) 0) (at x within {0..k})" by auto
then have "∀⇩F x in at x within {0..k}. f x = (if x ≤ 0 then f0 else f x)"
by eventually_elim auto
moreover
note [simp] = at_within_open[where S="{0<..}"]
have "continuous_on {0<..} f"
by (rule continuous_on_vector_derivative)
(auto simp add: intro!: f')
then have "(f ⤏ f x) (at x within {0..k})"
using ‹0 < x›
by (auto simp: continuous_on_def intro: Lim_at_imp_Lim_at_within)
ultimately show ?thesis
by (rule Lim_transform_eventually[rotated])
qed
done
then have pcg: "piecewise_continuous_on 0 k {} g" for k
by (auto simp: piecewise_continuous_on_def)
from piecewise_continuous_on_AE_boundedE[OF this]
obtain B where B: "AE x∈{0..k} in lebesgue. cmod (g x) ≤ B k" for k by auto
have 1: "laplace_integrand g s absolutely_integrable_on {0..}"
apply (rule laplace_integrand_absolutely_integrable[OF eog])
apply (rule B)
apply (rule piecewise_continuous_on_integrable)
apply (rule pcg)
apply (rule cs)
done
then have csi: "complex_set_integrable lebesgue {0..} (λx. exp (x *⇩R - s) * g x)"
by (auto simp: laplace_integrand_def[abs_def])
from has_laplaceD[OF Lg, THEN has_integral_improperE, OF csi]
obtain J where J: "⋀k. ((λt. exp (t *⇩R - s) * g t) has_integral J k) {0..k}"
and [tendsto_intros]: "(J ⤏ L) at_top"
by auto
have "((λx. -s * (exp (x *⇩R - s) * g x)) has_integral -s * J k) {0..k}" for k
by (rule has_integral_mult_right) (rule J)
then have *: "((λx. g x * (- s * exp (- (x *⇩R s)))) has_integral -s * J k) {0..k}" for k
by (auto simp: algebra_simps)
have "∀⇩F k::real in at_top. k ≥ 0"
using eventually_ge_at_top by blast
then have evI: "∀⇩F k in at_top. ((λt. exp (t *⇩R - s) * f' t) has_integral
g k * exp (k *⇩R - s) + s * J k - g 0) {0..k}"
proof eventually_elim
case (elim k)
show ?case
apply (subst mult.commute)
apply (rule integration_by_parts_interior[OF bounded_bilinear_mult], fact)
apply (rule cg) apply (rule ce) apply (rule g') apply force apply (rule de)
apply (rule has_integral_eq_rhs)
apply (rule *)
by auto
qed
have t1: "((λx. g x * exp (x *⇩R - s)) ⤏ 0) at_top"
apply (subst mult.commute)
unfolding laplace_integrand_def[symmetric]
apply (rule Lim_null_comparison)
apply (rule eventually_laplace_integrand_le[OF eog])
apply (rule tendsto_mult_right_zero)
apply (rule filterlim_compose[OF exp_at_bot])
apply (rule filterlim_tendsto_neg_mult_at_bot)
apply (rule tendsto_intros)
using cs apply simp
apply (rule filterlim_ident)
done
show "((λt. exp (t *⇩R - s) * f' t) has_integral s * L - f0) {0..}"
apply (rule has_integral_improper_at_topI[OF evI])
subgoal
apply (rule tendsto_eq_intros)
apply (rule tendsto_intros)
apply (rule t1)
apply (rule tendsto_intros)
apply (rule tendsto_intros)
apply (rule tendsto_intros)
apply (rule tendsto_intros)
by (simp add: g_def)
done
qed

lemma exp_times_has_integral:
"((λt. exp (c * t)) has_integral (if c = 0 then t else exp (c * t) / c) - (if c = 0 then t0 else exp (c * t0) / c)) {t0 .. t}"
if "t0 ≤ t"
for c t::real
apply (cases "c = 0")
subgoal
using that
apply auto
apply (rule has_integral_eq_rhs)
apply (rule has_integral_const_real)
by auto
subgoal
apply (rule fundamental_theorem_of_calculus)
using that
by (auto simp: has_vector_derivative_def intro!: derivative_eq_intros)
done

lemma integral_exp_times:
"integral {t0 .. t} (λt. exp (c * t)) = (if c = 0 then t - t0 else exp (c * t) / c - exp (c * t0) / c)"
if "t0 ≤ t"
for c t::real
using exp_times_has_integral[OF that, of c] that
by (auto split: if_splits)

lemma filtermap_times_pos_at_top: "filtermap ((*) e) at_top = at_top"
if "e > 0"
for e::real
apply (rule filtermap_fun_inverse[of "(*) (inverse e)"])
apply (rule filterlim_tendsto_pos_mult_at_top)
apply (rule tendsto_intros)
subgoal using that by simp
apply (rule filterlim_ident)
apply (rule filterlim_tendsto_pos_mult_at_top)
apply (rule tendsto_intros)
subgoal using that by simp
apply (rule filterlim_ident)
using that by auto

lemma exponential_order_additiveI:
assumes "0 < M" and eo: "∀⇩F t in at_top. norm (f t) ≤ K + M * exp (c * t)" and "c ≥ 0"
obtains M' where "exponential_order M' c f"
proof -
consider "c = 0" | "c > 0" using ‹c ≥ 0› by arith
then show ?thesis
proof cases
assume "c = 0"
have "exponential_order (max K 0 + M) c f"
using eo
apply (auto intro!: exponential_orderI add_nonneg_pos ‹0 < M› simp: ‹c = 0›)
apply (auto simp: max_def)
using eventually_elim2 by force
then show ?thesis ..
next
assume "c > 0"
have "∀⇩F t in at_top. norm (f t) ≤ K + M * exp (c * t)"
by fact
moreover
have "∀⇩F t in (filtermap exp (filtermap ((*) c) at_top)). K < t"
by (simp add: filtermap_times_pos_at_top ‹c > 0› filtermap_exp_at_top)
then have "∀⇩F t in at_top. K < exp (c * t)"
by (simp add: eventually_filtermap)
ultimately
have "∀⇩F t in at_top. norm (f t) ≤ (1 + M) * exp (c * t)"
by eventually_elim (auto simp: algebra_simps)
with add_nonneg_pos[OF zero_le_one ‹0 < M›]
have "exponential_order (1 + M) c f"
by (rule exponential_orderI)
then show ?thesis ..
qed
qed

lemma exponential_order_integral:
fixes f::"real ⇒ 'a::banach"
assumes I: "⋀t. t ≥ a ⟹ (f has_integral I t) {a .. t}"
and eo: "exponential_order M c f"
and "c > 0"
obtains M' where "exponential_order M' c I"
proof -
from exponential_orderD[OF eo] have "0 < M"
and bound: "∀⇩F t in at_top. norm (f t) ≤ M * exp (c * t)"
by auto
have "∀⇩F t in at_top. t > a"
by simp
from bound this
have "∀⇩F t in at_top. norm (f t) ≤ M * exp (c * t) ∧ t > a"
by eventually_elim auto
then obtain t0 where t0: "⋀t. t ≥ t0 ⟹ norm (f t) ≤ M * exp (c * t)" "t0 > a"
by (auto simp: eventually_at_top_linorder)
have "∀⇩F t in at_top. t > t0" by simp
then have "∀⇩F t in at_top. norm (I t) ≤ norm (integral {a..t0} f) - M * exp (c * t0) / c + (M / c) * exp (c * t)"
proof eventually_elim
case (elim t) then have that: "t ≥ t0" by simp
from t0 have "a ≤ t0" by simp
have "f integrable_on {a .. t0}" "f integrable_on {t0 .. t}"
subgoal by (rule has_integral_integrable[OF I[OF ‹a ≤ t0›]])
subgoal
apply (rule integrable_on_subinterval[OF has_integral_integrable[OF I[where t=t]]])
using ‹t0 > a› that by auto
done
have "I t = integral {a .. t0} f + integral {t0 .. t} f"
by (smt I ‹a ≤ t0› ‹f integrable_on {t0..t}› has_integral_combine has_integral_integrable_integral that)
also have "norm … ≤ norm (integral {a .. t0} f) + norm (integral {t0 .. t} f)" by norm
also
have "norm (integral {t0 .. t} f) ≤ integral {t0 .. t} (λt. M * exp (c * t))"
apply (rule integral_norm_bound_integral)
apply fact
by (auto intro!: integrable_continuous_interval continuous_intros t0)
also have "… = M * integral {t0 .. t} (λt. exp (c * t))"
by simp
also have "integral {t0 .. t} (λt. exp (c * t)) = exp (c * t) / c - exp (c * t0) / c"
using ‹c > 0› ‹t0 ≤ t›
by (subst integral_exp_times) auto
finally show ?case
using ‹c > 0›
by (auto simp: algebra_simps)
qed
from exponential_order_additiveI[OF divide_pos_pos[OF ‹0 < M› ‹0 < c›] this less_imp_le[OF ‹0 < c›]]
obtain M' where "exponential_order M' c I" .
then show ?thesis ..
qed

lemma integral_has_vector_derivative_piecewise_continuous:
fixes f :: "real ⇒ 'a::euclidean_space"―‹TODO: generalize?›
assumes "piecewise_continuous_on a b D f"
shows "⋀x. x ∈ {a .. b} - D ⟹
((λu. integral {a..u} f) has_vector_derivative f(x)) (at x within {a..b} - D)"
using assms
proof (induction a b D f rule: piecewise_continuous_on_induct)
case (empty a b f)
then show ?case
by (auto intro: integral_has_vector_derivative)
next
case (combine a i b I f1 f2 f)
then consider "x < i" | "i < x" by auto arith

then show ?case
proof cases―‹TODO: this is very explicit...›
case 1
have evless: "∀⇩F xa in nhds x. xa < i"
apply (rule order_tendstoD[OF _ ‹x < i›])
by (simp add: filterlim_ident)
have eq: "at x within {a..b} - insert i I = at x within {a .. i} - I"
unfolding filter_eq_iff
proof safe
fix P
assume "eventually P (at x within {a..i} - I)"
with evless show "eventually P (at x within {a..b} - insert i I)"
unfolding eventually_at_filter
by eventually_elim auto
next
fix P
assume "eventually P (at x within {a..b} - insert i I)"
with evless show "eventually P (at x within {a..i} - I)"
unfolding eventually_at_filter
apply eventually_elim
using 1 combine
by auto
qed
have "f x = f1 x" using combine 1 by auto
have i_eq: "integral {a..y} f = integral {a..y} f1" if "y < i" for y
using negligible_empty
apply (rule integral_spike)
using combine 1 that
by auto
from evless have ev_eq: "∀⇩F x in nhds x. x ∈ {a..i} - I ⟶ integral {a..x} f = integral {a..x} f1"
by eventually_elim (auto simp: i_eq)
show ?thesis unfolding eq ‹f x = f1 x›
apply (subst has_vector_derivative_cong_ev[OF ev_eq])
using combine.IH[of x]
using combine.hyps combine.prems 1
by (auto simp: i_eq)
next
case 2
have evless: "∀⇩F xa in nhds x. xa > i"
apply (rule order_tendstoD[OF _ ‹x > i›])
by (simp add: filterlim_ident)
have eq: "at x within {a..b} - insert i I = at x within {i .. b} - I"
unfolding filter_eq_iff
proof safe
fix P
assume "eventually P (at x within {i..b} - I)"
with evless show "eventually P (at x within {a..b} - insert i I)"
unfolding eventually_at_filter
by eventually_elim auto
next
fix P
assume "eventually P (at x within {a..b} - insert i I)"
with evless show "eventually P (at x within {i..b} - I)"
unfolding eventually_at_filter
apply eventually_elim
using 2 combine
by auto
qed
have "f x = f2 x" using combine 2 by auto
have i_eq: "integral {a..y} f = integral {a..i} f + integral {i..y} f2" if "i < y" "y ≤ b" for y
proof -
have "integral {a..y} f = integral {a..i} f + integral {i..y} f"
apply (cases "i = y")
subgoal by auto
subgoal
apply (rule Henstock_Kurzweil_Integration.integral_combine[symmetric])
using combine that apply auto
apply (rule integrable_Un'[where A="{a .. i}" and B="{i..y}"])
subgoal
by (rule integrable_spike[where S="{i}" and f="f1"])
(auto intro: piecewise_continuous_on_integrable)
subgoal
apply (rule integrable_on_subinterval[where S="{i..b}"])
by (rule integrable_spike[where S="{i}" and f="f2"])
(auto intro: piecewise_continuous_on_integrable)
subgoal by (auto simp: max_def min_def)
subgoal by auto
done
done
also have "integral {i..y} f = integral {i..y} f2"
apply (rule integral_spike[where S="{i}"])
using combine 2 that
by auto
finally show ?thesis .
qed
from evless have ev_eq: "∀⇩F y in nhds x. y ∈ {i..b} - I ⟶ integral {a..y} f = integral {a..i} f + integral {i..y} f2"
by eventually_elim (auto simp: i_eq)
show ?thesis unfolding eq
apply (subst has_vector_derivative_cong_ev[OF ev_eq])
using combine.IH[of x] combine.prems combine.hyps 2
by (auto simp: i_eq intro!: derivative_eq_intros)
qed
qed (auto intro: has_vector_derivative_within_subset)

lemma has_derivative_at_split:
"(f has_derivative f') (at x) ⟷ (f has_derivative f') (at_left x) ∧ (f has_derivative f') (at_right x)"
for x::"'a::{linorder_topology, real_normed_vector}"
by (auto simp: has_derivative_at_within filterlim_at_split)

lemma has_vector_derivative_at_split:
"(f has_vector_derivative f') (at x) ⟷
(f has_vector_derivative f') (at_left x) ∧
(f has_vector_derivative f') (at_right x)"
using has_derivative_at_split[of f "λh. h *⇩R f'" x]
by (simp add: has_vector_derivative_def)

lemmas differentiableI_vector[intro]

lemma differentiable_at_splitD:
"f differentiable at_left x"
"f differentiable at_right x"
if "f differentiable (at x)"
for x::real
using that[unfolded vector_derivative_works has_vector_derivative_at_split]
by auto

lemma integral_differentiable:
fixes f :: "real ⇒ 'a::banach"
assumes "continuous_on {a..b} f"
and "x ∈ {a..b}"
shows "(λu. integral {a..u} f) differentiable at x within {a..b}"
using integral_has_vector_derivative[OF assms]
by blast

theorem integral_has_vector_derivative_piecewise_continuous':
fixes f :: "real ⇒ 'a::euclidean_space"―‹TODO: generalize?›
assumes "piecewise_continuous_on a b D f" "a < b"
shows
"(∀x. a < x ⟶ x < b ⟶ x ∉ D ⟶ (λu. integral {a..u} f) differentiable at x) ∧
(∀x. a ≤ x ⟶ x < b ⟶ (λt. integral {a..t} f) differentiable at_right x) ∧
(∀x. a < x ⟶ x ≤ b ⟶ (λt. integral {a..t} f) differentiable at_left x)"
using assms
proof (induction a b D f rule: piecewise_continuous_on_induct)
case (empty a b f)
have "a < x ⟹ x < b ⟹ (λu. integral {a..u} f) differentiable (at x)" for x
using integral_differentiable[OF empty(1), of x]
by (auto simp: at_within_interior)
then show ?case
using integral_differentiable[OF empty(1), of a]
integral_differentiable[OF empty(1), of b]
‹a < b›
by (auto simp: at_within_Icc_at_right at_within_Icc_at_left le_less
intro: differentiable_at_withinI)
next
case (combine a i b I f1 f2 f)
from ‹piecewise_continuous_on a i I f1› have "finite I"
by (auto elim!: piecewise_continuous_onE)

from combine(4) have "piecewise_continuous_on a i (insert i I) f1"
by (rule piecewise_continuous_on_insert_rightI)
then have "piecewise_continuous_on a i (insert i I) f"
by (rule piecewise_continuous_on_congI) (auto simp: combine)
moreover
from combine(5) have "piecewise_continuous_on i b (insert i I) f2"
by (rule piecewise_continuous_on_insert_leftI)
then have "piecewise_continuous_on i b (insert i I) f"
by (rule piecewise_continuous_on_congI) (auto simp: combine)
ultimately have "piecewise_continuous_on a b (insert i I) f"
by (rule piecewise_continuous_on_combine)
then have f_int: "f integrable_on {a .. b}"
by (rule piecewise_continuous_on_integrable)

from combine.IH
have f1: "x>a ⟹ x < i ⟹ x ∉ I ⟹ (λu. integral {a..u} f1) differentiable (at x)"
"x≥a ⟹ x < i ⟹ (λt. integral {a..t} f1) differentiable (at_right x)"
"x>a ⟹ x ≤ i ⟹ (λt. integral {a..t} f1) differentiable (at_left x)"
and f2: "x>i ⟹ x < b ⟹ x ∉ I ⟹ (λu. integral {i..u} f2) differentiable (at x)"
"x≥i ⟹ x < b ⟹ (λt. integral {i..t} f2) differentiable (at_right x)"
"x>i ⟹ x ≤ b ⟹ (λt. integral {i..t} f2) differentiable (at_left x)"
for x
by auto

have "(λu. integral {a..u} f) differentiable at x" if "a < x" "x < b" "x ≠ i" "x ∉ I" for x
proof -
from that consider "x < i" |"i < x" by arith
then show ?thesis
proof cases
case 1
have at: "at x within {a<..<i} - I = at x"
using that 1
by (intro at_within_open) (auto intro!: open_Diff finite_imp_closed ‹finite I›)
then have "(λu. integral {a..u} f1) differentiable at x within {a<..<i} - I"
using that 1 f1 by auto
then have "(λu. integral {a..u} f) differentiable at x within {a<..<i} - I"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 1 by (auto intro!: integral_cong)
then show ?thesis by (simp add: at)
next
case 2
have at: "at x within {i<..<b} - I = at x"
using that 2
by (intro at_within_open) (auto intro!: open_Diff finite_imp_closed ‹finite I›)
then have "(λu. integral {a..i} f + integral {i..u} f2) differentiable at x within {i<..<b} - I"
using that 2 f2 by auto
then have "(λu. integral {a..i} f + integral {i..u} f) differentiable at x within {i<..<b} - I"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 2 by (auto intro!: integral_spike[where S="{i,x}"])
then have "(λu. integral {a..u} f) differentiable at x within {i<..<b} - I"
apply (rule differentiable_transform_within[OF _ zero_less_one])
subgoal using that 2 by auto
apply auto
apply (subst Henstock_Kurzweil_Integration.integral_combine)
using that 2 ‹a ≤ i›
apply auto
by (auto intro: integrable_on_subinterval f_int)
then show ?thesis by (simp add: at)
qed
qed
moreover
have "(λt. integral {a..t} f) differentiable at_right x" if "a ≤ x" "x < b" for x
proof -
from that consider "x < i" |"i ≤ x" by arith
then show ?thesis
proof cases
case 1
have at: "at x within {x..i} = at_right x"
using ‹x < i› by (rule at_within_Icc_at_right)
then have "(λu. integral {a..u} f1) differentiable at x within {x..i}"
using that 1 f1 by auto
then have "(λu. integral {a..u} f) differentiable at x within {x..i}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 1 by (auto intro!: integral_spike[where S="{i,x}"])
then show ?thesis by (simp add: at)
next
case 2
have at: "at x within {x..b} = at_right x"
using ‹x < b› by (rule at_within_Icc_at_right)
then have "(λu. integral {a..i} f + integral {i..u} f2) differentiable at x within {x..b}"
using that 2 f2 by auto
then have "(λu. integral {a..i} f + integral {i..u} f) differentiable at x within {x..b}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 2 by (auto intro!: integral_spike[where S="{i,x}"])
then have "(λu. integral {a..u} f) differentiable at x within {x..b}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
subgoal using that 2 by auto
apply auto
apply (subst Henstock_Kurzweil_Integration.integral_combine)
using that 2 ‹a ≤ i›
apply auto
by (auto intro: integrable_on_subinterval f_int)
then show ?thesis by (simp add: at)
qed
qed
moreover
have "(λt. integral {a..t} f) differentiable at_left x" if "a < x" "x ≤ b" for x
proof -
from that consider "x ≤ i" |"i < x" by arith
then show ?thesis
proof cases
case 1
have at: "at x within {a..x} = at_left x"
using ‹a < x› by (rule at_within_Icc_at_left)
then have "(λu. integral {a..u} f1) differentiable at x within {a..x}"
using that 1 f1 by auto
then have "(λu. integral {a..u} f) differentiable at x within {a..x}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 1 by (auto intro!: integral_spike[where S="{i,x}"])
then show ?thesis by (simp add: at)
next
case 2
have at: "at x within {i..x} = at_left x"
using ‹i < x› by (rule at_within_Icc_at_left)
then have "(λu. integral {a..i} f + integral {i..u} f2) differentiable at x within {i..x}"
using that 2 f2 by auto
then have "(λu. integral {a..i} f + integral {i..u} f) differentiable at x within {i..x}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
using that combine.hyps 2 by (auto intro!: integral_spike[where S="{i,x}"])
then have "(λu. integral {a..u} f) differentiable at x within {i..x}"
apply (rule differentiable_transform_within[OF _ zero_less_one])
subgoal using that 2 by auto
apply auto
apply (subst Henstock_Kurzweil_Integration.integral_combine)
using that 2 ‹a ≤ i›
apply auto
by (auto intro: integrable_on_subinterval f_int)
then show ?thesis by (simp add: at)
qed
qed
ultimately
show ?case
by auto
next
case (weaken a b i I f)
from weaken.IH[OF ‹a < b›]
obtain l u where IH:
"⋀x. a < x ⟹ x < b ⟹ x ∉ I ⟹ (λu. integral {a..u} f) differentiable (at x)"
"⋀x. a ≤ x ⟹ x < b ⟹ (λt. integral {a..t} f) differentiable (at_right x)"
"⋀x. a < x ⟹ x ≤ b ⟹ (λt. integral {a..t} f) differentiable (at_left x)"
by metis
then show ?case by auto
qed

lemma "closure (-S) ∩ closure S = frontier S"
by (auto simp add: frontier_def closure_complement)

theorem integral_time_domain_has_laplace:
"((λt. integral {0 .. t} f) has_laplace L / s) s"
if pc: "⋀k. piecewise_continuous_on 0 k D f"
and eo: "exponential_order M c f"
and L: "(f has_laplace L) s"
and s: "Re s > c"
and c: "c > 0"
and TODO: "D = {}" ― ‹TODO: generalize to actual ‹piecewise_continuous_on››
for f::"real ⇒ complex"
proof -
define I where "I = (λt. integral {0 .. t} f)"
have I': "(I has_vector_derivative f t) (at t within {0..x} - D)"
if "t ∈ {0 .. x} - D"
for x t
unfolding I_def
by (rule integral_has_vector_derivative_piecewise_continuous; fact)
have fi: "f integrable_on {0..t}" for t
by (rule piecewise_continuous_on_integrable) fact
have Ic: "continuous_on {0 .. t} I" for t
unfolding I_def using fi
by (rule indefinite_integral_continuous_1)
have Ipc: "piecewise_continuous_on 0 t {} I" for t
by (rule piecewise_continuous_onI) (auto intro!: Ic)
have I: "(f has_integral I t) {0 .. t}" for t
unfolding I_def
using fi
by (rule integrable_integral)
from exponential_order_integral[OF I eo ‹0 < c›] obtain M'
where Ieo: "exponential_order M' c I" .
have Ili: "laplace_integrand I s integrable_on {0..}"
using Ipc
apply (rule piecewise_continuous_on_AE_boundedE)
apply (rule laplace_integrand_integrable)
apply (rule Ieo)
apply assumption
apply (rule integrable_continuous_interval)
apply (rule Ic)
apply (rule s)
done
then obtain LI where LI: "(I has_laplace LI) s"
by (rule laplace_exists_laplace_integrandI)

from piecewise_continuous_onE[OF pc] have ‹finite D› by auto
have I'2: "(I has_vector_derivative f t) (at t)" if "t > 0" "t ∉ D" for t
apply (subst at_within_open[symmetric, where S="{0<..<t+1} - D"])
subgoal using that by auto
subgoal by (auto intro!:open_Diff finite_imp_closed ‹finite D›)
subgoal using I'[where x="t + 1"]
apply (rule has_vector_derivative_within_subset)
using that
by auto
done
have I_tndsto: "(I ⤏ 0) (at_right 0)"
apply (rule tendsto_eq_rhs)
apply (rule continuous_on_Icc_at_rightD)
apply (rule Ic)
apply (rule zero_less_one)
by (auto simp: I_def)
have "(f has_laplace s * LI - 0) s"
by (rule has_laplace_derivative_time_domain[OF LI I'2 I_tndsto Ieo s])
(auto simp: TODO)
from has_laplace_unique[OF this L] have "LI = L / s"
using s c by auto
with LI show "(I has_laplace L / s) s" by simp
qed

subsection ‹higher derivatives›

definition "nderiv i f X = ((λf. (λx. vector_derivative f (at x within X)))^^i) f"

definition "ndiff n f X ⟷ (∀i<n. ∀x ∈ X. nderiv i f X differentiable at x within X)"

lemma nderiv_zero[simp]: "nderiv 0 f X = f"
by (auto simp: nderiv_def)

lemma nderiv_Suc[simp]:
"nderiv (Suc i) f X x = vector_derivative (nderiv i f X) (at x within X)"
by (auto simp: nderiv_def)

lemma ndiff_zero[simp]: "ndiff 0 f X"
by (auto simp: ndiff_def)

lemma ndiff_Sucs[simp]:
"ndiff (Suc i) f X ⟷
(ndiff i f X) ∧
(∀x ∈ X. (nderiv i f X) differentiable (at x within X))"
apply (auto simp: ndiff_def )
using less_antisym by blast

theorem has_laplace_vector_derivative:
"((λt. vector_derivative f (at t)) has_laplace s * L - f0) s"
if L: "(f has_laplace L) s"
and f': "⋀t. t > 0 ⟹ f differentiable (at t)"
and f0: "(f ⤏ f0) (at_right 0)"
and eo: "exponential_order M c f"
and cs: "c < Re s"
proof -
have f': "(⋀t. 0 < t ⟹ (f has_vector_derivative vector_derivative f (at t)) (at t))"
using f'
by (subst vector_derivative_works[symmetric])
show ?thesis
by (rule has_laplace_derivative_time_domain[OF L f' f0 eo cs])
qed

lemma has_laplace_nderiv:
"(nderiv n f {0<..} has_laplace s^n * L - (∑i<n. s^(n - Suc i) * f0 i)) s"
if L: "(f has_laplace L) s"
and f': "ndiff n f {0<..}"
and f0: "⋀i. i < n ⟹ (nderiv i f {0<..} ⤏ f0 i) (at_right 0)"
and eo: "⋀i. i < n ⟹ exponential_order M c (nderiv i f {0<..})"
and cs: "c < Re s"
using f' f0 eo
proof (induction n)
case 0
then show ?case
by (auto simp: L)
next
case (Suc n)
have awo: "at t within {0<..} = at t" if "t > 0" for t::real
using that
by (subst at_within_open) auto
have "((λa. vector_derivative (nderiv n f {0<..}) (at a)) has_laplace
s * ( s ^ n * L - (∑i<n. s^(n - Suc i) * f0 i)) - f0 n) s"
(is "(_ has_laplace ?L) _")
apply (rule has_laplace_vector_derivative)
apply (rule Suc.IH)
subgoal using Suc.prems by auto
subgoal using Suc.prems by auto
subgoal using Suc.prems by auto
subgoal using Suc.prems by (auto simp: awo)
subgoal using Suc.prems by auto
apply (rule Suc.prems; force)
apply (rule cs)
done
also have "?L = s ^ Suc n * L - (∑i<Suc n. s ^ (Suc n - Suc i) * f0 i)"
by (auto simp: algebra_simps sum_distrib_left diff_Suc Suc_diff_le
split: nat.splits
intro!: sum.cong)
finally show ?case
by (rule has_laplace_spike[where T="{0}"]) (auto simp: awo)
qed

end```