/- Copyright (c) 2026 Raphael Coelho. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Raphael Coelho -/ module public import MathFin.Foundations.ItoFormulaLocalized public import MathFin.Foundations.ItoFormulaProcess public import MathFin.Foundations.ExitTime /-! # The unrestricted-`C³` Itô formula via stopping-time localization (Summit C) The process Itô formula `ito_formula_td_process` requires **globally bounded** derivatives. This file removes the bound entirely: for a general `C³` `f` (the six partials continuous, no growth or boundedness hypothesis), the compensated process `M_t = f(t, B_t) − f(0, B_0) − ∫₀ᵗ (f_t + ½f_xx)(s, B_s) ds` is a **continuous local martingale** on the null-augmented Brownian filtration. ## Strategy — localize in space *and* time, glue with the exit times The single gating ingredient is the genuine localizing sequence `exitTime` (`ExitTime.lean`). The local-martingale property is delivered here in **explicit form** (a localizing sequence + per-`N` continuous true martingales agreeing with `M` on the stochastic intervals) — this *is* the textbook definition of a continuous local martingale; the packaging into Degenne's `IsLocalMartingale` *typeclass* is `ito_formula_unrestricted` in `ItoFormulaUnrestrictedLocMart.lean` (it consumes the all-time-agreement step below). Three steps: * **Double truncation** (this section). `fTrunc N (t, x) = f(cut N t, cut N x)` cuts **both** arguments smoothly onto the compact square `[−M₀(N+1), M₀(N+1)]²`, on which the continuous partials of `f` are bounded by constants. The chain rule gives `fTrunc N`'s six partials in closed form, each globally bounded — so `ito_formula_td_process` applies, giving a `[0,∞)` integrand `Fᴺ` and the truncated Itô identity. The Itô integral of `Fᴺ` admits a global **true-martingale** continuous modification `Mₙ` (`exists_continuous_martingale_modification_infinite`). * **Agreement on `{· ≤ σ_N}`**, where `σ_N = min(exitTime N, N)`. There `t ≤ N` (time cut inert) and `|B_s| ≤ N` for `s ≤ t` (space cut inert), so `fTrunc N = f`, `drift_trunc = drift`, hence `Mₙ_t =ᵐ M_t` on `{t ≤ σ_N}` — the per-`t` agreement the headline `ito_formula_unrestricted_local` returns. As `N → ∞` the exit times escape, so `M` is *locally* a true martingale. * **All-time indistinguishability** (`indistinguishable_on_stochInterval`). The per-`t` agreement lifts to `∀ᵐ ω, ∀ u ≤ σ_N, M_u = Mₙ_u` (continuity + countable rationals + `Set.EqOn.closure`). This is the all-time-agreement crux consumed by the `IsLocalMartingale`-typeclass wrapper (`ItoFormulaUnrestrictedLocMart.lean`, `ito_formula_unrestricted`), which stops the indicator processes and invokes `Martingale.stoppedProcess_indicator`. That wrapper is **complete** — the one remaining ingredient, the drift-integral adaptedness of `M`, is discharged via `StronglyMeasurable.integral_prod_right` (a time-clamped Carathéodory argument). The time cut is essential: `cut N` confines `x`, but a general `C³` `f` has `t`-derivatives unbounded over `t ∈ ℝ`; capping the localizer at `N` keeps `t ≤ N` so the time cut is inert exactly where the agreement is used. -/ @[expose] public section namespace MathFin open MeasureTheory ProbabilityTheory Filter Topology open scoped NNReal ENNReal Topology open ItoIntegralL2 ItoIntegralBrownian ItoIntegralCLM ItoIntegralProcess ItoIntegralProcessGeneral open ItoIntegralProcessL2Infinite ItoIntegralProcessLocalMartingaleGeneral namespace SmoothTrunc /-- On the plateau `|y| < 1` where `φ = id`, the second derivative vanishes: `φ'' y = 0` (`φ'` is locally the constant `1`, so its derivative is `0`). -/ lemma phi''_eq_zero_of_lt (S : SmoothTrunc) {y : ℝ} (hy : |y| < 1) : S.φ'' y = 0 := by have h2 : HasDerivAt S.φ' 0 y := (hasDerivAt_const y (1 : ℝ)).congr_of_eventuallyEq (by filter_upwards [(isOpen_lt continuous_abs continuous_const).mem_nhds hy] with z hz exact S.phi'_eq_one_of_lt hz) exact (S.hasDeriv₂ y).unique h2 /-- For `|x| < n + 1` the second cutoff derivative vanishes: `φₙ''(x) = 0` (it is the identity there). -/ lemma cutD2_eq_zero_of_abs_lt (S : SmoothTrunc) {n : ℕ} {x : ℝ} (hx : |x| < (n : ℝ) + 1) : S.cutD2 n x = 0 := by have hn1 : (0 : ℝ) < (n : ℝ) + 1 := by positivity rw [cutD2, S.phi''_eq_zero_of_lt (by rw [abs_div, abs_of_pos hn1, div_lt_one hn1]; exact hx), zero_div] end SmoothTrunc /-- **The drift primitive is continuous.** `t ↦ ∫_{(0,t]} h dτ` for continuous `h` and `τ = timeMeasure` (finite on compacts): dominated convergence, the integrand `t ↦ 𝟙_{(0,t]}(s)·h(s)` having its only discontinuity in `t` at the τ-null point `t = s`. -/ lemma continuous_timeMeasure_primitive {h : ℝ≥0 → ℝ} (hh : Continuous h) : Continuous fun t : ℝ≥0 ↦ ∫ s in Set.Ioc 0 t, h s ∂ItoIntegralL2.timeMeasure := by have hrw : (fun t : ℝ≥0 ↦ ∫ s in Set.Ioc 0 t, h s ∂ItoIntegralL2.timeMeasure) = fun t ↦ ∫ s, (Set.Ioc 0 t).indicator h s ∂ItoIntegralL2.timeMeasure := by funext t; rw [integral_indicator measurableSet_Ioc] rw [hrw] refine continuous_iff_continuousAt.mpr fun t₀ ↦ ?_ refine continuousAt_of_dominated (bound := fun s ↦ (Set.Icc 0 (t₀ + 1)).indicator (fun u ↦ |h u|) s) (Filter.Eventually.of_forall fun t ↦ (hh.stronglyMeasurable.indicator measurableSet_Ioc).aestronglyMeasurable) (Filter.eventually_of_mem (Iio_mem_nhds (lt_add_one t₀)) fun t ht ↦ Filter.Eventually.of_forall fun s ↦ ?_) ?_ ?_ · -- pointwise domination by `𝟙_{[0,t₀+1]}·|h|` by_cases hmem : s ∈ Set.Ioc 0 t · rw [Set.indicator_of_mem hmem, Real.norm_eq_abs, Set.indicator_of_mem (show s ∈ Set.Icc 0 (t₀ + 1) from ⟨zero_le, le_of_lt (lt_of_le_of_lt hmem.2 ht)⟩)] · rw [Set.indicator_of_notMem hmem, norm_zero] exact Set.indicator_nonneg (fun s _ ↦ abs_nonneg _) s · -- the dominator is integrable (continuous on a compact, finite measure there) exact (integrable_indicator_iff measurableSet_Icc).mpr (hh.abs.continuousOn.integrableOn_compact isCompact_Icc) · -- a.e.-`s` continuity in `t` (off the null point `t₀`) have hne : ∀ᵐ s ∂ItoIntegralL2.timeMeasure, s ≠ t₀ := by rw [ae_iff]; simp only [not_not, Set.setOf_eq_eq_singleton] exact ItoIntegralL2.timeMeasure_singleton t₀ filter_upwards [hne] with s hs by_cases hs0 : 0 < s · rcases lt_or_gt_of_ne hs with hlt | hgt · refine (continuousAt_congr ?_).mpr (continuousAt_const (y := h s)) filter_upwards [Ioi_mem_nhds hlt] with t ht exact Set.indicator_of_mem (Set.mem_Ioc.mpr ⟨hs0, le_of_lt ht⟩) h · refine (continuousAt_congr ?_).mpr (continuousAt_const (y := (0 : ℝ))) filter_upwards [Iio_mem_nhds hgt] with t ht exact Set.indicator_of_notMem (fun hmem ↦ absurd (Set.mem_Ioc.mp hmem).2 (not_le.mpr ht)) h · refine (continuousAt_congr ?_).mpr (continuousAt_const (y := (0 : ℝ))) have hs00 : s = 0 := le_antisymm (not_lt.mp hs0) (zero_le) filter_upwards with t exact Set.indicator_of_notMem (by rw [hs00]; exact fun hmem ↦ lt_irrefl 0 (Set.mem_Ioc.mp hmem).1) h namespace SummitC variable {f f_t f_x f_xx f_tt f_tx f_xxx : ℝ → ℝ → ℝ} /-- The double cutoff `fTrunc N (t,x) = f(φₙ t, φₙ x)` — `f` confined to the compact square. -/ noncomputable def fTrunc (f : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f (S.cut N t) (S.cut N x) /-- `∂_t fTrunc = f_t(φₙ t, φₙ x)·φₙ'(t)`. -/ noncomputable def fTruncT (f_t : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_t (S.cut N t) (S.cut N x) * S.cutD1 N t /-- `∂_x fTrunc = f_x(φₙ t, φₙ x)·φₙ'(x)`. -/ noncomputable def fTruncX (f_x : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_x (S.cut N t) (S.cut N x) * S.cutD1 N x /-- `∂_tt fTrunc = f_tt·(φₙ' t)² + f_t·φₙ''(t)`. -/ noncomputable def fTruncTT (f_t f_tt : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_tt (S.cut N t) (S.cut N x) * (S.cutD1 N t * S.cutD1 N t) + f_t (S.cut N t) (S.cut N x) * S.cutD2 N t /-- `∂_tx fTrunc = f_tx·φₙ'(x)·φₙ'(t)`. -/ noncomputable def fTruncTX (f_tx : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_tx (S.cut N t) (S.cut N x) * S.cutD1 N x * S.cutD1 N t /-- `∂_xx fTrunc = f_xx·(φₙ' x)² + f_x·φₙ''(x)`. -/ noncomputable def fTruncXX (f_x f_xx : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_xx (S.cut N t) (S.cut N x) * (S.cutD1 N x * S.cutD1 N x) + f_x (S.cut N t) (S.cut N x) * S.cutD2 N x /-- `∂_xxx fTrunc = f_xxx·(φₙ' x)³ + 3 f_xx·φₙ'(x)·φₙ''(x) + f_x·φₙ'''(x)`. -/ noncomputable def fTruncXXX (f_x f_xx f_xxx : ℝ → ℝ → ℝ) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : ℝ := f_xxx (S.cut N t) (S.cut N x) * (S.cutD1 N x * S.cutD1 N x * S.cutD1 N x) + 3 * f_xx (S.cut N t) (S.cut N x) * S.cutD1 N x * S.cutD2 N x + f_x (S.cut N t) (S.cut N x) * S.cutD3 N x /-- `∂_t fTrunc` exists with value `fTruncT` (chain rule through the time cut). -/ lemma fTrunc_hasDerivAt_t (hf_t : ∀ t x, HasDerivAt (fun s ↦ f s x) (f_t t x) t) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun s ↦ fTrunc f S N s x) (fTruncT f_t S N t x) t := (hf_t (S.cut N t) (S.cut N x)).comp t (S.cut_hasDerivAt N t) /-- `∂_x fTrunc` exists with value `fTruncX` (chain rule through the space cut). -/ lemma fTrunc_hasDerivAt_x (hf_x : ∀ t x, HasDerivAt (fun u ↦ f t u) (f_x t x) x) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun u ↦ fTrunc f S N t u) (fTruncX f_x S N t x) x := (hf_x (S.cut N t) (S.cut N x)).comp x (S.cut_hasDerivAt N x) /-- `∂_t fTruncT = fTruncTT` (product rule, `t`-derivative). -/ lemma fTrunc_hasDerivAt_tt (hf_tt : ∀ t x, HasDerivAt (fun s ↦ f_t s x) (f_tt t x) t) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun s ↦ fTruncT f_t S N s x) (fTruncTT f_t f_tt S N t x) t := by have hu : HasDerivAt (fun s ↦ f_t (S.cut N s) (S.cut N x)) (f_tt (S.cut N t) (S.cut N x) * S.cutD1 N t) t := (hf_tt (S.cut N t) (S.cut N x)).comp t (S.cut_hasDerivAt N t) have hv : HasDerivAt (fun s ↦ S.cutD1 N s) (S.cutD2 N t) t := S.cutD1_hasDerivAt N t rw [show fTruncTT f_t f_tt S N t x = f_tt (S.cut N t) (S.cut N x) * S.cutD1 N t * S.cutD1 N t + f_t (S.cut N t) (S.cut N x) * S.cutD2 N t from by unfold fTruncTT; ring] exact hu.mul hv /-- `∂_x fTruncT = fTruncTX` (product rule, `x`-derivative; `φₙ'(t)` is constant in `x`). -/ lemma fTrunc_hasDerivAt_tx (hf_tx : ∀ t x, HasDerivAt (fun u ↦ f_t t u) (f_tx t x) x) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun u ↦ fTruncT f_t S N t u) (fTruncTX f_tx S N t x) x := by have h := ((hf_tx (S.cut N t) (S.cut N x)).comp x (S.cut_hasDerivAt N x)).mul_const (S.cutD1 N t) rw [show fTruncTX f_tx S N t x = f_tx (S.cut N t) (S.cut N x) * S.cutD1 N x * S.cutD1 N t from by unfold fTruncTX; ring] exact h /-- `∂_x fTruncX = fTruncXX` (product rule, `x`-derivative). -/ lemma fTrunc_hasDerivAt_xx (hf_xx : ∀ t x, HasDerivAt (fun u ↦ f_x t u) (f_xx t x) x) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun u ↦ fTruncX f_x S N t u) (fTruncXX f_x f_xx S N t x) x := by have hu : HasDerivAt (fun u ↦ f_x (S.cut N t) (S.cut N u)) (f_xx (S.cut N t) (S.cut N x) * S.cutD1 N x) x := (hf_xx (S.cut N t) (S.cut N x)).comp x (S.cut_hasDerivAt N x) have hv : HasDerivAt (fun u ↦ S.cutD1 N u) (S.cutD2 N x) x := S.cutD1_hasDerivAt N x rw [show fTruncXX f_x f_xx S N t x = f_xx (S.cut N t) (S.cut N x) * S.cutD1 N x * S.cutD1 N x + f_x (S.cut N t) (S.cut N x) * S.cutD2 N x from by unfold fTruncXX; ring] exact hu.mul hv /-- `∂_x fTruncXX = fTruncXXX` (sum + product + chain rules). -/ lemma fTrunc_hasDerivAt_xxx (hf_xx : ∀ t x, HasDerivAt (fun u ↦ f_x t u) (f_xx t x) x) (hf_xxx : ∀ t x, HasDerivAt (fun u ↦ f_xx t u) (f_xxx t x) x) (S : SmoothTrunc) (N : ℕ) (t x : ℝ) : HasDerivAt (fun u ↦ fTruncXX f_x f_xx S N t u) (fTruncXXX f_x f_xx f_xxx S N t x) x := by -- term 1 : f_xx(·,φₙ ·)·(φₙ' ·)² have h_fxx : HasDerivAt (fun u ↦ f_xx (S.cut N t) (S.cut N u)) (f_xxx (S.cut N t) (S.cut N x) * S.cutD1 N x) x := (hf_xxx (S.cut N t) (S.cut N x)).comp x (S.cut_hasDerivAt N x) have h_cD1 : HasDerivAt (fun u ↦ S.cutD1 N u) (S.cutD2 N x) x := S.cutD1_hasDerivAt N x have h_cD1sq : HasDerivAt (fun u ↦ S.cutD1 N u * S.cutD1 N u) (S.cutD2 N x * S.cutD1 N x + S.cutD1 N x * S.cutD2 N x) x := h_cD1.mul h_cD1 have hterm1 := h_fxx.mul h_cD1sq -- term 2 : f_x(·,φₙ ·)·(φₙ'' ·) have h_fx : HasDerivAt (fun u ↦ f_x (S.cut N t) (S.cut N u)) (f_xx (S.cut N t) (S.cut N x) * S.cutD1 N x) x := (hf_xx (S.cut N t) (S.cut N x)).comp x (S.cut_hasDerivAt N x) have h_cD2 : HasDerivAt (fun u ↦ S.cutD2 N u) (S.cutD3 N x) x := S.cutD2_hasDerivAt N x have hterm2 := h_fx.mul h_cD2 rw [show fTruncXXX f_x f_xx f_xxx S N t x = f_xxx (S.cut N t) (S.cut N x) * S.cutD1 N x * (S.cutD1 N x * S.cutD1 N x) + f_xx (S.cut N t) (S.cut N x) * (S.cutD2 N x * S.cutD1 N x + S.cutD1 N x * S.cutD2 N x) + (f_xx (S.cut N t) (S.cut N x) * S.cutD1 N x * S.cutD2 N x + f_x (S.cut N t) (S.cut N x) * S.cutD3 N x) from by unfold fTruncXXX; ring] exact hterm1.add hterm2 /-! ### Constant bounds on the truncated partials -/ /-- `|a·b| ≤ A·B` from `|a| ≤ A` and `|b| ≤ B`. -/ private lemma abs_mul_le_of {a b A B : ℝ} (ha : |a| ≤ A) (hb : |b| ≤ B) : |a * b| ≤ A * B := by rw [abs_mul]; exact mul_le_mul ha hb (abs_nonneg _) (le_trans (abs_nonneg _) ha) /-- A jointly-continuous `g` is bounded after both arguments pass through the cutoff `φₙ` (which maps into the compact square `[−M₀(N+1), M₀(N+1)]²`). -/ lemma exists_bound_cut (S : SmoothTrunc) (N : ℕ) {g : ℝ → ℝ → ℝ} (hg : Continuous fun p : ℝ × ℝ ↦ g p.1 p.2) : ∃ C : ℝ, ∀ t x, |g (S.cut N t) (S.cut N x)| ≤ C := by set r : ℝ := S.M₀ * ((N : ℝ) + 1) obtain ⟨C, hC⟩ := ((isCompact_Icc (a := -r) (b := r)).prod (isCompact_Icc (a := -r) (b := r))).exists_bound_of_continuousOn hg.continuousOn refine ⟨C, fun t x ↦ ?_⟩ have hmem : ((S.cut N t, S.cut N x) : ℝ × ℝ) ∈ Set.Icc (-r) r ×ˢ Set.Icc (-r) r := ⟨by rw [Set.mem_Icc, ← abs_le]; exact S.cut_bdd N t, by rw [Set.mem_Icc, ← abs_le]; exact S.cut_bdd N x⟩ have := hC _ hmem rwa [Real.norm_eq_abs] at this lemma fTruncT_bdd (S : SmoothTrunc) (N : ℕ) (hcont : Continuous fun p : ℝ × ℝ ↦ f_t p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncT f_t S N t x| ≤ C := by obtain ⟨B, hB⟩ := exists_bound_cut S N hcont exact ⟨B * S.M₁, fun t x ↦ abs_mul_le_of (hB t x) (S.cutD1_bdd N t)⟩ lemma fTruncX_bdd (S : SmoothTrunc) (N : ℕ) (hcont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncX f_x S N t x| ≤ C := by obtain ⟨B, hB⟩ := exists_bound_cut S N hcont exact ⟨B * S.M₁, fun t x ↦ abs_mul_le_of (hB t x) (S.cutD1_bdd N x)⟩ lemma fTruncTX_bdd (S : SmoothTrunc) (N : ℕ) (hcont : Continuous fun p : ℝ × ℝ ↦ f_tx p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncTX f_tx S N t x| ≤ C := by obtain ⟨B, hB⟩ := exists_bound_cut S N hcont exact ⟨B * S.M₁ * S.M₁, fun t x ↦ abs_mul_le_of (abs_mul_le_of (hB t x) (S.cutD1_bdd N x)) (S.cutD1_bdd N t)⟩ lemma fTruncTT_bdd (S : SmoothTrunc) (N : ℕ) (hf_t_cont : Continuous fun p : ℝ × ℝ ↦ f_t p.1 p.2) (hf_tt_cont : Continuous fun p : ℝ × ℝ ↦ f_tt p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncTT f_t f_tt S N t x| ≤ C := by obtain ⟨Bt, hBt⟩ := exists_bound_cut S N hf_t_cont obtain ⟨Btt, hBtt⟩ := exists_bound_cut S N hf_tt_cont refine ⟨Btt * (S.M₁ * S.M₁) + Bt * S.M₂, fun t x ↦ ?_⟩ unfold fTruncTT refine (abs_add_le _ _).trans (add_le_add ?_ ?_) · exact abs_mul_le_of (hBtt t x) (abs_mul_le_of (S.cutD1_bdd N t) (S.cutD1_bdd N t)) · exact abs_mul_le_of (hBt t x) (S.cutD2_bdd N t) lemma fTruncXX_bdd (S : SmoothTrunc) (N : ℕ) (hf_x_cont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) (hf_xx_cont : Continuous fun p : ℝ × ℝ ↦ f_xx p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncXX f_x f_xx S N t x| ≤ C := by obtain ⟨Bx, hBx⟩ := exists_bound_cut S N hf_x_cont obtain ⟨Bxx, hBxx⟩ := exists_bound_cut S N hf_xx_cont refine ⟨Bxx * (S.M₁ * S.M₁) + Bx * S.M₂, fun t x ↦ ?_⟩ unfold fTruncXX refine (abs_add_le _ _).trans (add_le_add ?_ ?_) · exact abs_mul_le_of (hBxx t x) (abs_mul_le_of (S.cutD1_bdd N x) (S.cutD1_bdd N x)) · exact abs_mul_le_of (hBx t x) (S.cutD2_bdd N x) lemma fTruncXXX_bdd (S : SmoothTrunc) (N : ℕ) (hf_x_cont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) (hf_xx_cont : Continuous fun p : ℝ × ℝ ↦ f_xx p.1 p.2) (hf_xxx_cont : Continuous fun p : ℝ × ℝ ↦ f_xxx p.1 p.2) : ∃ C : ℝ, ∀ t x, |fTruncXXX f_x f_xx f_xxx S N t x| ≤ C := by obtain ⟨Bx, hBx⟩ := exists_bound_cut S N hf_x_cont obtain ⟨Bxx, hBxx⟩ := exists_bound_cut S N hf_xx_cont obtain ⟨Bxxx, hBxxx⟩ := exists_bound_cut S N hf_xxx_cont refine ⟨Bxxx * (S.M₁ * S.M₁ * S.M₁) + 3 * Bxx * S.M₁ * S.M₂ + Bx * S.M₃, fun t x ↦ ?_⟩ unfold fTruncXXX refine (abs_add_le _ _).trans (add_le_add ((abs_add_le _ _).trans (add_le_add ?_ ?_)) ?_) · exact abs_mul_le_of (hBxxx t x) (abs_mul_le_of (abs_mul_le_of (S.cutD1_bdd N x) (S.cutD1_bdd N x)) (S.cutD1_bdd N x)) · refine abs_mul_le_of (abs_mul_le_of ?_ (S.cutD1_bdd N x)) (S.cutD2_bdd N x) rw [abs_mul, abs_of_nonneg (by norm_num : (0 : ℝ) ≤ 3)] exact mul_le_mul_of_nonneg_left (hBxx t x) (by norm_num) · exact abs_mul_le_of (hBx t x) (S.cutD3_bdd N x) /-! ### Joint continuity of the two partials `ito_formula_td_process` requires -/ /-- `p ↦ (φₙ p.1, φₙ p.2)` is continuous. -/ private lemma continuous_cut_pair (S : SmoothTrunc) (N : ℕ) : Continuous fun p : ℝ × ℝ ↦ ((S.cut N p.1, S.cut N p.2) : ℝ × ℝ) := ((S.continuous_cut N).comp continuous_fst).prodMk ((S.continuous_cut N).comp continuous_snd) lemma fTruncX_continuous (S : SmoothTrunc) (N : ℕ) (hf_x_cont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) : Continuous fun p : ℝ × ℝ ↦ fTruncX f_x S N p.1 p.2 := by simp only [fTruncX] exact (hf_x_cont.comp (continuous_cut_pair S N)).mul ((S.continuous_cutD1 N).comp continuous_snd) lemma fTruncXX_continuous (S : SmoothTrunc) (N : ℕ) (hf_x_cont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) (hf_xx_cont : Continuous fun p : ℝ × ℝ ↦ f_xx p.1 p.2) : Continuous fun p : ℝ × ℝ ↦ fTruncXX f_x f_xx S N p.1 p.2 := by simp only [fTruncXX] refine ((hf_xx_cont.comp (continuous_cut_pair S N)).mul (((S.continuous_cutD1 N).comp continuous_snd).mul ((S.continuous_cutD1 N).comp continuous_snd))).add ?_ exact (hf_x_cont.comp (continuous_cut_pair S N)).mul ((S.continuous_cutD2 N).comp continuous_snd) /-! ### Cut inactivity — where `|z| ≤ N` the truncation is the identity -/ /-- Where `|z| ≤ N` the cutoff is inert: `φₙ z = z`, `φₙ' z = 1`, `φₙ'' z = 0` (the plateau `[−(N+1), N+1] ⊋ [−N, N]`). -/ lemma cut_inactive (S : SmoothTrunc) {N : ℕ} {z : ℝ} (hz : |z| ≤ (N : ℝ)) : S.cut N z = z ∧ S.cutD1 N z = 1 ∧ S.cutD2 N z = 0 := ⟨S.cut_eq_id_of_abs_le (le_trans hz (by linarith)), S.cutD1_eq_one_of_abs_lt (lt_of_le_of_lt hz (by linarith)), S.cutD2_eq_zero_of_abs_lt (lt_of_le_of_lt hz (by linarith))⟩ /-- On the inert region `fTrunc N = f`. -/ lemma fTrunc_eq_of (S : SmoothTrunc) {N : ℕ} {s y : ℝ} (hs : |s| ≤ (N : ℝ)) (hy : |y| ≤ (N : ℝ)) : fTrunc f S N s y = f s y := by unfold fTrunc; rw [(cut_inactive S hs).1, (cut_inactive S hy).1] /-- On the inert region the truncated drift is the true drift. -/ lemma truncDrift_eq_of (S : SmoothTrunc) {N : ℕ} {s y : ℝ} (hs : |s| ≤ (N : ℝ)) (hy : |y| ≤ (N : ℝ)) : fTruncT f_t S N s y + (1 / 2) * fTruncXX f_x f_xx S N s y = f_t s y + (1 / 2) * f_xx s y := by obtain ⟨hcs, hc1s, _⟩ := cut_inactive S hs obtain ⟨hcy, hc1y, hc2y⟩ := cut_inactive S hy unfold fTruncT fTruncXX rw [hcs, hcy, hc1s, hc1y, hc2y]; ring end SummitC variable {Ω : Type*} {mΩ : MeasurableSpace Ω} {μ : Measure Ω} {B : ℝ≥0 → Ω → ℝ} /-- **The path stays confined up to the exit time.** On `{s ≤ τ_N}` with `0 < s`, `|B_s| ≤ N`: for `u < s ≤ τ_N` the exit has not happened (`|B_u| < N`), and left-continuity carries the bound to the boundary value at `s`. -/ lemma abs_le_N_of_le_exitTime (hBcont : ∀ ω, Continuous fun s : ℝ≥0 ↦ B s ω) {N : ℕ} {s : ℝ≥0} {ω : Ω} (hs0 : 0 < s) (h : (s : WithTop ℝ≥0) ≤ exitTime B N ω) : |B s ω| ≤ (N : ℝ) := by have hbelow : ∀ u : ℝ≥0, u < s → |B u ω| < (N : ℝ) := by intro u hu by_contra hN rw [not_lt] at hN have hle : exitTime B N ω ≤ (u : WithTop ℝ≥0) := (exitTime_le_iff hBcont N u ω).mpr ⟨u, ⟨zero_le, le_refl u⟩, hN⟩ exact absurd hle (not_le.mpr (lt_of_lt_of_le (by exact_mod_cast hu) h)) have htend : Tendsto (fun u : ℝ≥0 ↦ |B u ω|) (𝓝[<] s) (𝓝 (|B s ω|)) := (continuous_abs.comp (hBcont ω)).continuousWithinAt haveI : (𝓝[<] s).NeBot := nhdsWithin_Iio_neBot' ⟨0, hs0⟩ le_rfl exact le_of_tendsto htend (eventually_nhdsWithin_of_forall fun u hu ↦ le_of_lt (hbelow u hu)) /-- The exit time capped at the level: `σ_N = min(τ_N, N)`. Capping the **time** keeps `t ≤ N` on `{t ≤ σ_N}`, where the truncation's time cut is inert; still a genuine localizing sequence (the exit times localize, and `min` with `N ↑ ⊤` preserves all three properties). -/ noncomputable def sigmaSeq (B : ℝ≥0 → Ω → ℝ) (N : ℕ) (ω : Ω) : WithTop ℝ≥0 := min (exitTime B N ω) ((N : ℝ≥0) : WithTop ℝ≥0) lemma isLocalizingSequence_sigma [IsProbabilityMeasure μ] (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun s : ℝ≥0 ↦ B s ω) : IsLocalizingSequence (augFiltration (μ := μ) hBmeas) (fun N ↦ sigmaSeq B N) μ where isStoppingTime := fun N ↦ ((isLocalizingSequence_exitTime hBmeas hBcont).isStoppingTime N).min (isStoppingTime_const' _ _) tendsto_top := Filter.Eventually.of_forall fun ω ↦ by have htop := exitTime_tendsto_top hBcont ω rw [WithTop.tendsto_nhds_top_iff] at htop ⊢ intro c have h2 : ∀ᶠ N : ℕ in atTop, (c : WithTop ℝ≥0) < ((N : ℝ≥0) : WithTop ℝ≥0) := by filter_upwards [eventually_gt_atTop ⌈c⌉₊] with N hN have hcN : (c : ℝ≥0) < (N : ℝ≥0) := lt_of_le_of_lt (Nat.le_ceil c) (by exact_mod_cast hN) exact_mod_cast hcN filter_upwards [htop c, h2] with N hN1 hN2 exact lt_min hN1 hN2 mono := Filter.Eventually.of_forall fun ω _ _ hNM ↦ min_le_min (exitTime_monotone hBcont ω hNM) (by exact_mod_cast hNM) open SummitC variable {f f_t f_x f_xx f_tt f_tx f_xxx : ℝ → ℝ → ℝ} /-- **The unrestricted-`C³` Itô formula in explicit local-martingale form (Summit C).** For a general `C³` `f` (six partials with `HasDerivAt` witnesses, all jointly continuous — **no** growth or boundedness hypothesis), the compensated process `M_t = f(t, B_t) − f(0, B_0) − ∫₀ᵗ (f_t + ½f_xx)(s, B_s) ds` is everywhere-continuous, satisfies the Itô identity by construction, and is a **continuous local martingale** in explicit form: there is a localizing sequence `σ_N = min(τ_N, N) ↑ ⊤` (`τ_N` the exit times) and, for each `N`, a continuous **true** martingale `Mₙ` on the null-augmented Brownian filtration with `M = Mₙ` on the stochastic interval `{t ≤ σ_N}`. The localization is genuine: `Mₙ` is the continuous global-martingale modification of the Itô integral of the time-and-space–truncated `fTrunc N = f(φₙ·, φₙ·)`, whose globally-bounded derivatives let `ito_formula_td_process` apply; on `{t ≤ σ_N}` the cuts are inert, so the truncated formula collapses to the true one and `Mₙ` agrees with `M`. As `N → ∞` the exit times escape, so `M` is locally a martingale on all of `[0, ∞)`. -/ theorem ito_formula_unrestricted_local [IsProbabilityMeasure μ] (hB : IsPreBrownianReal B μ) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun s : ℝ≥0 ↦ B s ω) (hf_t : ∀ t x, HasDerivAt (fun s ↦ f s x) (f_t t x) t) (hf_tt : ∀ t x, HasDerivAt (fun s ↦ f_t s x) (f_tt t x) t) (hf_tx : ∀ t x, HasDerivAt (fun u ↦ f_t t u) (f_tx t x) x) (hf_x : ∀ t x, HasDerivAt (fun u ↦ f t u) (f_x t x) x) (hf_xx : ∀ t x, HasDerivAt (fun u ↦ f_x t u) (f_xx t x) x) (hf_xxx : ∀ t x, HasDerivAt (fun u ↦ f_xx t u) (f_xxx t x) x) (hf_cont : Continuous fun p : ℝ × ℝ ↦ f p.1 p.2) (hf_t_cont : Continuous fun p : ℝ × ℝ ↦ f_t p.1 p.2) (hf_x_cont : Continuous fun p : ℝ × ℝ ↦ f_x p.1 p.2) (hf_xx_cont : Continuous fun p : ℝ × ℝ ↦ f_xx p.1 p.2) (hf_tt_cont : Continuous fun p : ℝ × ℝ ↦ f_tt p.1 p.2) (hf_tx_cont : Continuous fun p : ℝ × ℝ ↦ f_tx p.1 p.2) (hf_xxx_cont : Continuous fun p : ℝ × ℝ ↦ f_xxx p.1 p.2) : ∃ M : ℝ≥0 → Ω → ℝ, (∀ ω, Continuous fun t ↦ M t ω) ∧ (∀ t : ℝ≥0, (fun ω ↦ f (t : ℝ) (B t ω) - f 0 (B 0 ω)) =ᵐ[μ] (fun ω ↦ M t ω + ∫ s in Set.Ioc 0 t, (f_t (s : ℝ) (B s ω) + (1 / 2) * f_xx (s : ℝ) (B s ω)) ∂ItoIntegralL2.timeMeasure)) ∧ ∃ σ : ℕ → Ω → WithTop ℝ≥0, IsLocalizingSequence (augFiltration (μ := μ) hBmeas) σ μ ∧ ∀ N : ℕ, ∃ Mₙ : ℝ≥0 → Ω → ℝ, Martingale Mₙ (augFiltration (μ := μ) hBmeas) μ ∧ (∀ ω, Continuous fun t ↦ Mₙ t ω) ∧ ∀ t : ℝ≥0, ∀ᵐ ω ∂μ, (t : WithTop ℝ≥0) ≤ σ N ω → M t ω = Mₙ t ω := by obtain ⟨S⟩ := smoothTrunc_exists set M : ℝ≥0 → Ω → ℝ := fun t ω ↦ f (t : ℝ) (B t ω) - f 0 (B 0 ω) - ∫ s in Set.Ioc 0 t, (f_t (s : ℝ) (B s ω) + (1 / 2) * f_xx (s : ℝ) (B s ω)) ∂ItoIntegralL2.timeMeasure with hM -- continuity of `M` (the drift primitive is continuous; `f∘(↑·,B)` is continuous) have hMcont : ∀ ω, Continuous fun t ↦ M t ω := by intro ω simp only [hM] exact ((hf_cont.comp (NNReal.continuous_coe.prodMk (hBcont ω))).sub continuous_const).sub (continuous_timeMeasure_primitive ((hf_t_cont.comp (NNReal.continuous_coe.prodMk (hBcont ω))).add (continuous_const.mul (hf_xx_cont.comp (NNReal.continuous_coe.prodMk (hBcont ω)))))) refine ⟨M, hMcont, fun t ↦ Filter.Eventually.of_forall fun ω ↦ by simp only [hM]; ring, fun N ↦ sigmaSeq B N, isLocalizingSequence_sigma hBmeas hBcont, fun N ↦ ?_⟩ -- the truncated process formula at horizon `N` obtain ⟨Ct, hCt⟩ := fTruncT_bdd S N hf_t_cont obtain ⟨C1, hC1⟩ := fTruncX_bdd S N hf_x_cont obtain ⟨C2, hC2⟩ := fTruncXX_bdd S N hf_x_cont hf_xx_cont obtain ⟨Ctt, hCtt⟩ := fTruncTT_bdd S N hf_t_cont hf_tt_cont obtain ⟨Ctx, hCtx⟩ := fTruncTX_bdd S N hf_tx_cont obtain ⟨Cxxx, hCxxx⟩ := fTruncXXX_bdd S N hf_x_cont hf_xx_cont hf_xxx_cont obtain ⟨F, hform, -, -⟩ := ito_formula_td_process hB hBmeas hBcont (N : ℝ≥0) (f := fTrunc f S N) (f_t := fTruncT f_t S N) (f_x := fTruncX f_x S N) (f_xx := fTruncXX f_x f_xx S N) (f_tt := fTruncTT f_t f_tt S N) (f_tx := fTruncTX f_tx S N) (f_xxx := fTruncXXX f_x f_xx f_xxx S N) (fTrunc_hasDerivAt_t hf_t S N) (fTrunc_hasDerivAt_tt hf_tt S N) (fTrunc_hasDerivAt_tx hf_tx S N) (fTrunc_hasDerivAt_x hf_x S N) (fTrunc_hasDerivAt_xx hf_xx S N) (fTrunc_hasDerivAt_xxx hf_xx hf_xxx S N) (fTruncX_continuous S N hf_x_cont) (fTruncXX_continuous S N hf_x_cont hf_xx_cont) hCt hC1 hC2 hCtt hCtx hCxxx -- the continuous GLOBAL martingale modification of the truncated Itô integral obtain ⟨X, hmodX, hcontX, hmartX⟩ := ItoLocalMartingaleInfinite.exists_continuous_martingale_modification_infinite hB hBmeas hBcont F refine ⟨X, hmartX, hcontX, fun t ↦ ?_⟩ -- agreement `M t = X t` on `{t ≤ σ_N}` have hN0 : |(0 : ℝ)| ≤ (N : ℝ) := by rw [abs_zero]; exact Nat.cast_nonneg N rcases eq_zero_or_pos t with ht0 | ht0 · -- `t = 0`: both sides are `0` (`hform 0` gives `itoProcessL2Inf 0 F =ᵐ 0`) subst ht0 filter_upwards [hform 0 zero_le, hmodX 0] with ω hf hmod _ simp only [hM, hmod, NNReal.coe_zero, Set.Ioc_self, MeasureTheory.setIntegral_empty, add_zero, sub_self] at hf ⊢ linarith [hf] · by_cases htN : t ≤ (N : ℝ≥0) · filter_upwards [hform t htN, hmodX t, eval_zero_ae hB hBmeas] with ω hf hmod hB0 hev have hexit : (t : WithTop ℝ≥0) ≤ exitTime B N ω := le_trans hev (min_le_left _ _) have hBt : |B t ω| ≤ (N : ℝ) := abs_le_N_of_le_exitTime hBcont ht0 hexit have htNr : (t : ℝ) ≤ (N : ℝ) := by exact_mod_cast htN have hb1 : fTrunc f S N (t : ℝ) (B t ω) = f (t : ℝ) (B t ω) := fTrunc_eq_of S (by rw [abs_of_nonneg t.coe_nonneg]; exact htNr) hBt have hb0 : fTrunc f S N 0 (B 0 ω) = f 0 (B 0 ω) := by rw [hB0]; exact fTrunc_eq_of S hN0 hN0 have hdr : (∫ s in Set.Ioc 0 t, (fTruncT f_t S N (s : ℝ) (B s ω) + (1 / 2) * fTruncXX f_x f_xx S N (s : ℝ) (B s ω)) ∂ItoIntegralL2.timeMeasure) = ∫ s in Set.Ioc 0 t, (f_t (s : ℝ) (B s ω) + (1 / 2) * f_xx (s : ℝ) (B s ω)) ∂ItoIntegralL2.timeMeasure := by refine setIntegral_congr_fun measurableSet_Ioc (fun s hs ↦ ?_) have hsexit : (s : WithTop ℝ≥0) ≤ exitTime B N ω := le_trans (by exact_mod_cast hs.2) hexit have hBs : |B s ω| ≤ (N : ℝ) := abs_le_N_of_le_exitTime hBcont hs.1 hsexit have hsN : (s : ℝ) ≤ N := le_trans (by exact_mod_cast hs.2) htNr exact truncDrift_eq_of S (by rw [abs_of_nonneg s.coe_nonneg]; exact hsN) hBs rw [hb1, hb0, hdr] at hf simp only [hM, hmod] linarith [hf] · -- `t > N`: vacuous, since `t ≤ σ_N ≤ N` refine Filter.Eventually.of_forall fun ω hev ↦ ?_ exact absurd (by exact_mod_cast le_trans hev (min_le_right _ _) : t ≤ (N : ℝ≥0)) htN /-- **The indistinguishability upgrade.** Two continuous processes that agree a.s. at every deterministic time below a stopping time `σ` agree, a.s., on the whole stochastic interval `[0, σ]` — the per-deterministic-`t` modification lifted to all-`t` by continuity on the dense countable set, then to the closed interval by left-continuity at the boundary. This is the staging lemma for the `IsLocalMartingale`-typeclass wrapper of Summit C: it upgrades the per-`t` agreement that `ito_formula_unrestricted_local` returns to the all-time agreement a `Martingale.stoppedProcess_indicator` argument needs. It is consumed by `ito_formula_unrestricted` in `ItoFormulaUnrestrictedLocMart.lean`. -/ lemma indistinguishable_on_stochInterval {M' X' : ℝ≥0 → Ω → ℝ} {σ : Ω → WithTop ℝ≥0} (hM'cont : ∀ ω, Continuous fun t ↦ M' t ω) (hX'cont : ∀ ω, Continuous fun t ↦ X' t ω) (hagree : ∀ t : ℝ≥0, ∀ᵐ ω ∂μ, (t : WithTop ℝ≥0) ≤ σ ω → M' t ω = X' t ω) : ∀ᵐ ω ∂μ, ⊥ < σ ω → ∀ u : ℝ≥0, (u : WithTop ℝ≥0) ≤ σ ω → M' u ω = X' u ω := by obtain ⟨D, D_count, D_dense⟩ := TopologicalSpace.exists_countable_dense ℝ≥0 have hco : ∀ᵐ ω ∂μ, ∀ d ∈ D, (d : WithTop ℝ≥0) ≤ σ ω → M' d ω = X' d ω := (ae_ball_iff D_count).mpr fun d _ ↦ hagree d filter_upwards [hco] with ω hω hpos u hu have hUopen : IsOpen {t : ℝ≥0 | (t : WithTop ℝ≥0) < σ ω} := isOpen_Iio.preimage WithTop.continuous_coe have hEqU : Set.EqOn (fun t ↦ M' t ω) (fun t ↦ X' t ω) {t | (t : WithTop ℝ≥0) < σ ω} := Set.EqOn.of_subset_closure (fun d hd ↦ hω d hd.1 (le_of_lt hd.2)) (hM'cont ω).continuousOn (hX'cont ω).continuousOn Set.inter_subset_right (subset_closure_dense_inter D_dense hUopen) have humem : u ∈ closure {t : ℝ≥0 | (t : WithTop ℝ≥0) < σ ω} := by rcases lt_or_eq_of_le hu with hlt | heq · exact subset_closure hlt · have hu0 : (0 : ℝ≥0) < u := by have h : (0 : WithTop ℝ≥0) < (u : WithTop ℝ≥0) := by rw [← heq] at hpos; simpa using hpos rwa [← WithTop.coe_zero, WithTop.coe_lt_coe] at h have hIio : Set.Iio u ⊆ {t : ℝ≥0 | (t : WithTop ℝ≥0) < σ ω} := fun s hs ↦ by rw [Set.mem_setOf_eq, ← heq, WithTop.coe_lt_coe]; exact hs exact closure_mono hIio ((closure_Iio' (a := u) ⟨0, hu0⟩).ge Set.self_mem_Iic) exact hEqU.closure (hM'cont ω) (hX'cont ω) humem end MathFin