Skip to content

Commit a5480a3

Browse files
grunwegb-mehta
authored andcommitted
feat: add and use custom (d)elaborators for mvfderiv, add basic API lemmas (leanprover-community#39554)
Add a custom elaborator (scoped to the `Manifold` namespace) shortening `mvfderiv I f` to `d% f`, and have a corresponding delaborator also. Their implementation is fully analogous to the existing elaborators. Also, rewrite Lie bracket lemmas to use `mvfderiv` instead of open-coding it. Part of leanprover-community#36036, i.e. from the path towards the Levi-Civita connection and Riemanian curvature. Related to fixing defeq abuses related to tangent space and scalar multiplication in mathlib. Co-authored-by: Heather Macbeth [25316162+hrmacbeth@users.noreply.github.com](mailto:25316162+hrmacbeth@users.noreply.github.com) Co-authored-by: Patrick Massot [patrickmassot@free.fr](mailto:patrickmassot@free.fr)
1 parent 4dc7979 commit a5480a3

3 files changed

Lines changed: 94 additions & 24 deletions

File tree

Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ differentiability.
1818
1919
In addition to the above, this file provides
2020
* results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), and
21-
* `mvfderiv`: the exterior derivative of a scalar function, as a section of the cotangent bundle
21+
* `mvfderiv`: the exterior derivative of a vector-valued function, as a section of the
22+
cotangent bundle; adds notation `d% f` for `mvfderiv I f` via a custom elaborator scoped to the
23+
`Manifold` namespace, with a corresponding delaborator, and
24+
adds basic lemmas about `mvfderiv` (such as addition, subtraction, multiplication and constants).
2225
2326
-/
2427

@@ -404,26 +407,98 @@ as a section of the cotangent bundle.
404407
405408
Future: this could be generalised to functions into additive torsors over abelian Lie groups.
406409
-/
407-
noncomputable abbrev mvfderiv (g : M → F) :
410+
@[expose]
411+
noncomputable def mvfderiv (g : M → F) :
408412
Π x : M, TangentSpace I x →L[𝕜] F :=
409413
fun x ↦ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x)
410-
411414
@[deprecated (since := "2026-05-17")] alias extDerivFun := mvfderiv
412415

413-
@[simp]
416+
namespace Manifold
417+
open scoped Bundle Manifold ContDiff
418+
419+
open Lean Meta Elab Tactic
420+
421+
/-- `d% f x` (scoped to the `Manifold` namespace) elaborates to `mvfderiv I J f x`,
422+
trying to determine `I` and `J` from the local context. -/
423+
scoped elab:max "d%" ppSpace t:term:arg : term => do
424+
let e ← ensureIsFunction <| ← Term.elabTerm t none
425+
let (srcI, _tgtI) ← findModels e none
426+
mkAppM ``mvfderiv #[srcI, e]
427+
428+
open Bundle PrettyPrinter Delaborator SubExpr
429+
430+
/-- Delaborator for `mvfderiv`. -/
431+
-- There is no need to special-case any arguments which could use the T% s elaborator:
432+
-- the argument to `mvfderiv` is a vector-valued function, which a map to a total space
433+
-- can never be.
434+
@[app_delab mvfderiv] meta def delab_mvfderiv : Delab := do
435+
whenPPOption getPPNotation do
436+
withOverApp 15 do
437+
let fs ← withAppArg delab
438+
`(d% $fs) >>= annotateGoToSyntaxDef
439+
440+
section tests
441+
442+
variable {f : M → 𝕜}
443+
444+
/-- info: d% f : (x : M) → TangentSpace I x →L[𝕜] 𝕜 -/
445+
#guard_msgs in
446+
#check mvfderiv I f
447+
/-- info: d% f : (x : M) → TangentSpace I x →L[𝕜] 𝕜 -/
448+
#guard_msgs in
449+
#check d% f
450+
451+
/-- info: d% f x : TangentSpace I x →L[𝕜] 𝕜 -/
452+
#guard_msgs in
453+
#check mvfderiv I f x
454+
455+
/-- info: d% f x : TangentSpace I x →L[𝕜] 𝕜 -/
456+
#guard_msgs in
457+
#check d% f x
458+
459+
end tests
460+
461+
end Manifold
462+
463+
lemma mvfderiv_const (c : F) {x : M} : d% (fun _ : M ↦ c) x = 0 := by
464+
simp [mvfderiv, mfderiv_const]
465+
466+
@[simp, to_fun mvfderiv_fun_add]
414467
lemma mvfderiv_add {g g' : M → F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) :
415-
mvfderiv I (g + g') x = mvfderiv I g x + mvfderiv I g' x := by
468+
d% (g + g') x = d% g x + d% g' x := by
416469
simp [mvfderiv, mfderiv_add hg hg']
417-
congr
418-
470+
rfl
419471
@[deprecated (since := "2026-05-17")] alias extDerivFun_add := mvfderiv_add
420472

473+
@[simp, to_fun mvfderiv_fun_sub]
474+
lemma mvfderiv_sub {g g' : M → F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) :
475+
d% (g - g') x = d% g x - d% g' x := by
476+
simp [mvfderiv, mfderiv_sub hg hg']
477+
rfl
478+
479+
@[simp, to_fun mvfderiv_fun_neg]
480+
lemma mvfderiv_neg {g : M → F} {x : M} :
481+
d% (-g) x = -d% g x := by
482+
simp [mvfderiv, mfderiv_neg]
483+
rfl
484+
485+
@[simp, to_fun mvfderiv_fun_smul]
486+
lemma mvfderiv_smul {x : M} {a : M → 𝕜} (ha : MDiffAt a x) {g : M → F} (hg : MDiffAt g x) :
487+
d% (a • g) x = a x • d% g x + (d% a x).smulRight (g x) := by
488+
ext v
489+
simp [mvfderiv, -Pi.smul_apply', fromTangentSpace_mfderiv_smul_apply ha hg]
490+
491+
@[simp, to_fun mvfderiv_fun_mul]
492+
lemma mvfderiv_mul {f g : M → 𝕜} {x : M} (hf : MDiffAt f x) (hg : MDiffAt g x) :
493+
d% (f * g) x = f x • d% g x + (g x) • (d% f x) := by
494+
ext v
495+
simp only [mvfderiv, ← smul_eq_mul, mfderiv_smul hf hg]
496+
simp [mul_comm _ (g x)]
497+
421498
@[simp]
422-
lemma mvfderiv_zero {x : M} : mvfderiv (I := I) (0 : M → F) x = 0 := by
423-
have : mvfderiv I (0 : M → F) x + mvfderiv I (0 : M → F) x =
424-
mvfderiv I (0 : M → F) x := by
499+
lemma mvfderiv_zero {x : M} : d% (0 : M → F) x = 0 := by
500+
have : d% (0 : M → F) x + d% (0 : M → F) x = d% (0 : M → F) x := by
425501
rw [← mvfderiv_add (by exact mdifferentiable_const ..) (by exact mdifferentiable_const ..)]
426502
simp
427503
simpa using this
428-
429504
@[deprecated (since := "2026-05-17")] alias extDerivFun_zero := mvfderiv_zero

Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ structure IsCovariantDerivativeOn
9696
cov (σ + σ') x = cov σ x + cov σ' x
9797
leibniz {σ : Π x : M, V x} {g : M → 𝕜} {x}
9898
(hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial) :
99-
cov (g • σ) x = g x • cov σ x + (mvfderiv I g x).smulRight (σ x)
99+
cov (g • σ) x = g x • cov σ x + (d% g x).smulRight (σ x)
100100

101101
/--
102102
A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a
@@ -270,15 +270,14 @@ lemma finite_affine_combination {ι : Type*} {s : Finset ι}
270270
rw [← smul_add, (h i).add hσ hσ' hx]
271271
leibniz {σ g x} hσ hg hx := by
272272
calc ∑ i ∈ s, f i x • cov i (g • σ) x
273-
_ = ∑ i ∈ s, (g x • f i x • cov i σ x + f i x • (mvfderiv I g x).smulRight (σ x)) := by
273+
_ = ∑ i ∈ s, (g x • f i x • cov i σ x + f i x • (d% g x).smulRight (σ x)) := by
274274
congr! 1 with i hi
275275
rw [(h i).leibniz hσ hg]
276276
simp [mvfderiv]
277277
module
278-
_ = g x • ∑ i ∈ s, f i x • cov i σ x +
279-
(∑ i ∈ s, f i) x • (mvfderiv I g x).smulRight (σ x) := by
278+
_ = g x • ∑ i ∈ s, f i x • cov i σ x + (∑ i ∈ s, f i) x • (d% g x).smulRight (σ x) := by
280279
rw [Finset.sum_add_distrib, Finset.smul_sum, Finset.sum_apply, Finset.sum_smul]
281-
_ = g x • ∑ i ∈ s, f i x • cov i σ x + (mvfderiv I g x).smulRight (σ x) := by rw [hf]; simp
280+
_ = g x • ∑ i ∈ s, f i x • cov i σ x + (d% g x).smulRight (σ x) := by rw [hf]; simp
282281

283282
/-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/
284283
lemma _root_.ContMDiffCovariantDerivativeOn.finite_affine_combination [IsManifold I 1 M]

Mathlib/Geometry/Manifold/VectorField/LieBracket.lean

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,9 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a
390390
-/
391391
lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDiffAt f x)
392392
(hW : MDiffAt (fun x ↦ (W x : TangentBundle I M)) x) :
393-
mlieBracket I V (f • W) x =
394-
(fromTangentSpace (f x) (mfderiv% f x (V x))) • (W x)
395-
+ (f x) • mlieBracket I V W x := by
393+
mlieBracket I V (f • W) x = d% f x (V x) • (W x) + (f x) • mlieBracket I V W x := by
396394
rw [← mdifferentiableWithinAt_univ] at hf hW
397-
rw [← mlieBracketWithin_univ, ← mfderivWithin_univ]
395+
rw [← mlieBracketWithin_univ, mvfderiv, ← mfderivWithin_univ]
398396
exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I)
399397

400398
/--
@@ -417,11 +415,9 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a
417415
-/
418416
lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDiffAt f x)
419417
(hV : MDiffAt (fun x ↦ (V x : TangentBundle I M)) x) :
420-
mlieBracket I (f • V) W x =
421-
- (fromTangentSpace (f x) (mfderiv% f x (W x))) • (V x)
422-
+ (f x) • mlieBracket I V W x := by
418+
mlieBracket I (f • V) W x = - d% f x (W x) • (V x) + (f x) • mlieBracket I V W x := by
423419
rw [← mdifferentiableWithinAt_univ] at hf hV
424-
rw [← mlieBracketWithin_univ, ← mfderivWithin_univ]
420+
rw [← mlieBracketWithin_univ, mvfderiv, ← mfderivWithin_univ]
425421
exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I)
426422

427423
lemma mlieBracketWithin_const_smul_left

0 commit comments

Comments
 (0)